pci_hades.c revision 1.1.10.3 1 1.1.10.3 nathanw /* $NetBSD: pci_hades.c,v 1.1.10.3 2002/02/28 04:08:27 nathanw Exp $ */
2 1.1.10.2 nathanw
3 1.1.10.2 nathanw /*
4 1.1.10.2 nathanw * Copyright (c) 1996 Leo Weppelman. All rights reserved.
5 1.1.10.2 nathanw * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
6 1.1.10.2 nathanw * Copyright (c) 1994 Charles M. Hannum. All rights reserved.
7 1.1.10.2 nathanw *
8 1.1.10.2 nathanw * Redistribution and use in source and binary forms, with or without
9 1.1.10.2 nathanw * modification, are permitted provided that the following conditions
10 1.1.10.2 nathanw * are met:
11 1.1.10.2 nathanw * 1. Redistributions of source code must retain the above copyright
12 1.1.10.2 nathanw * notice, this list of conditions and the following disclaimer.
13 1.1.10.2 nathanw * 2. Redistributions in binary form must reproduce the above copyright
14 1.1.10.2 nathanw * notice, this list of conditions and the following disclaimer in the
15 1.1.10.2 nathanw * documentation and/or other materials provided with the distribution.
16 1.1.10.2 nathanw * 3. All advertising materials mentioning features or use of this software
17 1.1.10.2 nathanw * must display the following acknowledgement:
18 1.1.10.2 nathanw * This product includes software developed by Charles M. Hannum.
19 1.1.10.2 nathanw * 4. The name of the author may not be used to endorse or promote products
20 1.1.10.2 nathanw * derived from this software without specific prior written permission.
21 1.1.10.2 nathanw *
22 1.1.10.2 nathanw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 1.1.10.2 nathanw * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 1.1.10.2 nathanw * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 1.1.10.2 nathanw * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 1.1.10.2 nathanw * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 1.1.10.2 nathanw * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 1.1.10.2 nathanw * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 1.1.10.2 nathanw * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 1.1.10.2 nathanw * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 1.1.10.2 nathanw * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 1.1.10.2 nathanw */
33 1.1.10.2 nathanw
34 1.1.10.2 nathanw #include <sys/types.h>
35 1.1.10.2 nathanw #include <sys/param.h>
36 1.1.10.2 nathanw #include <sys/systm.h>
37 1.1.10.2 nathanw #include <sys/device.h>
38 1.1.10.2 nathanw
39 1.1.10.2 nathanw #include <machine/bus.h>
40 1.1.10.2 nathanw
41 1.1.10.2 nathanw #include <dev/pci/pcivar.h>
42 1.1.10.2 nathanw #include <dev/pci/pcireg.h>
43 1.1.10.2 nathanw
44 1.1.10.2 nathanw #include <machine/cpu.h>
45 1.1.10.2 nathanw #include <machine/iomap.h>
46 1.1.10.2 nathanw #include <machine/mfp.h>
47 1.1.10.2 nathanw #include <machine/bswap.h>
48 1.1.10.2 nathanw
49 1.1.10.2 nathanw #include <atari/atari/device.h>
50 1.1.10.2 nathanw #include <atari/pci/pci_vga.h>
51 1.1.10.2 nathanw #include <atari/dev/grf_etreg.h>
52 1.1.10.2 nathanw
53 1.1.10.2 nathanw int
54 1.1.10.2 nathanw pci_bus_maxdevs(pc, busno)
55 1.1.10.2 nathanw pci_chipset_tag_t pc;
56 1.1.10.2 nathanw int busno;
57 1.1.10.2 nathanw {
58 1.1.10.2 nathanw return (4);
59 1.1.10.2 nathanw }
60 1.1.10.2 nathanw
61 1.1.10.2 nathanw static int pci_config_offset __P((pcitag_t));
62 1.1.10.2 nathanw
63 1.1.10.2 nathanw /*
64 1.1.10.2 nathanw * Atari_init.c maps the config areas NBPG bytes apart....
65 1.1.10.2 nathanw */
66 1.1.10.2 nathanw static int pci_config_offset(tag)
67 1.1.10.2 nathanw pcitag_t tag;
68 1.1.10.2 nathanw {
69 1.1.10.2 nathanw int device;
70 1.1.10.2 nathanw
71 1.1.10.2 nathanw device = (tag >> 11) & 0x1f;
72 1.1.10.2 nathanw return(device * NBPG);
73 1.1.10.2 nathanw }
74 1.1.10.2 nathanw
75 1.1.10.2 nathanw pcireg_t
76 1.1.10.2 nathanw pci_conf_read(pc, tag, reg)
77 1.1.10.2 nathanw pci_chipset_tag_t pc;
78 1.1.10.2 nathanw pcitag_t tag;
79 1.1.10.2 nathanw int reg;
80 1.1.10.2 nathanw {
81 1.1.10.2 nathanw u_long data;
82 1.1.10.2 nathanw
83 1.1.10.2 nathanw data = *(u_long *)(pci_conf_addr + pci_config_offset(tag) + reg);
84 1.1.10.2 nathanw return (bswap32(data));
85 1.1.10.2 nathanw }
86 1.1.10.2 nathanw
87 1.1.10.2 nathanw void
88 1.1.10.2 nathanw pci_conf_write(pc, tag, reg, data)
89 1.1.10.2 nathanw pci_chipset_tag_t pc;
90 1.1.10.2 nathanw pcitag_t tag;
91 1.1.10.2 nathanw int reg;
92 1.1.10.2 nathanw pcireg_t data;
93 1.1.10.2 nathanw {
94 1.1.10.2 nathanw *((u_long *)(pci_conf_addr + pci_config_offset(tag) + reg))
95 1.1.10.2 nathanw = bswap32(data);
96 1.1.10.2 nathanw }
97 1.1.10.2 nathanw
98 1.1.10.2 nathanw /*
99 1.1.10.2 nathanw * The interrupt stuff is rather ugly. On the Hades, all interrupt lines
100 1.1.10.2 nathanw * for a slot are wired together and connected to IO 0,1,2 or 5 (slots:
101 1.1.10.2 nathanw * (0-3) on the TT-MFP. The Pci-config code initializes the irq. number
102 1.1.10.2 nathanw * to the slot position.
103 1.1.10.2 nathanw */
104 1.1.10.2 nathanw static pci_intr_info_t iinfo[4] = { { -1 }, { -1 }, { -1 }, { -1 } };
105 1.1.10.2 nathanw
106 1.1.10.2 nathanw static int iifun __P((int, int));
107 1.1.10.2 nathanw
108 1.1.10.2 nathanw static int
109 1.1.10.2 nathanw iifun(slot, sr)
110 1.1.10.2 nathanw int slot;
111 1.1.10.2 nathanw int sr;
112 1.1.10.2 nathanw {
113 1.1.10.2 nathanw pci_intr_info_t *iinfo_p;
114 1.1.10.2 nathanw int s;
115 1.1.10.2 nathanw
116 1.1.10.2 nathanw iinfo_p = &iinfo[slot];
117 1.1.10.2 nathanw
118 1.1.10.2 nathanw /*
119 1.1.10.2 nathanw * Disable the interrupts
120 1.1.10.2 nathanw */
121 1.1.10.2 nathanw MFP2->mf_imrb &= ~iinfo_p->imask;
122 1.1.10.2 nathanw
123 1.1.10.2 nathanw if ((sr & PSL_IPL) >= (iinfo_p->ipl & PSL_IPL)) {
124 1.1.10.2 nathanw /*
125 1.1.10.2 nathanw * We're running at a too high priority now.
126 1.1.10.2 nathanw */
127 1.1.10.2 nathanw add_sicallback((si_farg)iifun, (void*)slot, 0);
128 1.1.10.2 nathanw }
129 1.1.10.2 nathanw else {
130 1.1.10.2 nathanw s = splx(iinfo_p->ipl);
131 1.1.10.2 nathanw (void) (iinfo_p->ifunc)(iinfo_p->iarg);
132 1.1.10.2 nathanw splx(s);
133 1.1.10.2 nathanw
134 1.1.10.2 nathanw /*
135 1.1.10.2 nathanw * Re-enable interrupts after handling
136 1.1.10.2 nathanw */
137 1.1.10.2 nathanw MFP2->mf_imrb |= iinfo_p->imask;
138 1.1.10.2 nathanw }
139 1.1.10.2 nathanw return 1;
140 1.1.10.2 nathanw }
141 1.1.10.2 nathanw
142 1.1.10.2 nathanw void *
143 1.1.10.2 nathanw pci_intr_establish(pc, ih, level, ih_fun, ih_arg)
144 1.1.10.2 nathanw pci_chipset_tag_t pc;
145 1.1.10.2 nathanw pci_intr_handle_t ih;
146 1.1.10.2 nathanw int level;
147 1.1.10.2 nathanw int (*ih_fun) __P((void *));
148 1.1.10.2 nathanw void *ih_arg;
149 1.1.10.2 nathanw {
150 1.1.10.2 nathanw pci_intr_info_t *iinfo_p;
151 1.1.10.2 nathanw struct intrhand *ihand;
152 1.1.10.2 nathanw int slot;
153 1.1.10.2 nathanw
154 1.1.10.2 nathanw slot = ih;
155 1.1.10.2 nathanw iinfo_p = &iinfo[slot];
156 1.1.10.2 nathanw
157 1.1.10.2 nathanw if (iinfo_p->ipl > 0)
158 1.1.10.2 nathanw panic("pci_intr_establish: interrupt was already established\n");
159 1.1.10.2 nathanw
160 1.1.10.2 nathanw ihand = intr_establish((slot == 3) ? 23 : 16 + slot, USER_VEC, 0,
161 1.1.10.2 nathanw (hw_ifun_t)iifun, (void *)slot);
162 1.1.10.2 nathanw if (ihand != NULL) {
163 1.1.10.2 nathanw iinfo_p->ipl = level;
164 1.1.10.2 nathanw iinfo_p->imask = (slot == 3) ? 0x80 : (0x01 << slot);
165 1.1.10.2 nathanw iinfo_p->ifunc = ih_fun;
166 1.1.10.2 nathanw iinfo_p->iarg = ih_arg;
167 1.1.10.2 nathanw iinfo_p->ihand = ihand;
168 1.1.10.2 nathanw
169 1.1.10.2 nathanw /*
170 1.1.10.2 nathanw * Enable (unmask) the interrupt
171 1.1.10.2 nathanw */
172 1.1.10.2 nathanw MFP2->mf_imrb |= iinfo_p->imask;
173 1.1.10.2 nathanw MFP2->mf_ierb |= iinfo_p->imask;
174 1.1.10.2 nathanw return(iinfo_p);
175 1.1.10.2 nathanw }
176 1.1.10.2 nathanw return NULL;
177 1.1.10.2 nathanw }
178 1.1.10.2 nathanw
179 1.1.10.2 nathanw void
180 1.1.10.2 nathanw pci_intr_disestablish(pc, cookie)
181 1.1.10.2 nathanw pci_chipset_tag_t pc;
182 1.1.10.2 nathanw void *cookie;
183 1.1.10.2 nathanw {
184 1.1.10.2 nathanw pci_intr_info_t *iinfo_p = (pci_intr_info_t *)cookie;
185 1.1.10.2 nathanw
186 1.1.10.2 nathanw if (iinfo->ipl < 0)
187 1.1.10.2 nathanw panic("pci_intr_disestablish: interrupt was not established\n");
188 1.1.10.2 nathanw
189 1.1.10.2 nathanw MFP2->mf_imrb &= ~iinfo->imask;
190 1.1.10.2 nathanw MFP2->mf_ierb &= ~iinfo->imask;
191 1.1.10.2 nathanw (void) intr_disestablish(iinfo_p->ihand);
192 1.1.10.2 nathanw iinfo_p->ipl = -1;
193 1.1.10.2 nathanw }
194 1.1.10.2 nathanw
195 1.1.10.2 nathanw /*
196 1.1.10.2 nathanw * XXX: Why are we repeating this everywhere! (Leo)
197 1.1.10.2 nathanw */
198 1.1.10.2 nathanw #define PCI_LINMEMBASE 0x0e000000
199 1.1.10.2 nathanw
200 1.1.10.2 nathanw static u_char crt_tab[] = {
201 1.1.10.2 nathanw 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
202 1.1.10.2 nathanw 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
203 1.1.10.2 nathanw 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
204 1.1.10.2 nathanw 0xff };
205 1.1.10.2 nathanw
206 1.1.10.2 nathanw static u_char seq_tab[] = {
207 1.1.10.2 nathanw 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00 };
208 1.1.10.2 nathanw
209 1.1.10.2 nathanw static u_char attr_tab[] = {
210 1.1.10.2 nathanw 0x0c, 0x00, 0x0f, 0x08, 0x00, 0x00, 0x00, 0x00 };
211 1.1.10.2 nathanw
212 1.1.10.2 nathanw static u_char gdc_tab[] = {
213 1.1.10.2 nathanw 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff };
214 1.1.10.2 nathanw
215 1.1.10.2 nathanw void
216 1.1.10.2 nathanw ati_vga_init(pc, tag, id, ba, fb)
217 1.1.10.2 nathanw pci_chipset_tag_t pc;
218 1.1.10.2 nathanw pcitag_t tag;
219 1.1.10.2 nathanw int id;
220 1.1.10.2 nathanw volatile u_char *ba;
221 1.1.10.2 nathanw u_char *fb;
222 1.1.10.2 nathanw {
223 1.1.10.2 nathanw int i, csr;
224 1.1.10.2 nathanw
225 1.1.10.2 nathanw /* Turn on the card */
226 1.1.10.2 nathanw pci_conf_write(pc, tag, PCI_MAPREG_START, PCI_LINMEMBASE);
227 1.1.10.2 nathanw csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
228 1.1.10.2 nathanw csr |= (PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_IO_ENABLE);
229 1.1.10.2 nathanw csr |= PCI_COMMAND_MASTER_ENABLE;
230 1.1.10.2 nathanw pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr);
231 1.1.10.2 nathanw
232 1.1.10.2 nathanw /*
233 1.1.10.2 nathanw * Make sure we're allowed to write all crt-registers and reload them.
234 1.1.10.2 nathanw */
235 1.1.10.2 nathanw WCrt(ba, CRT_ID_END_VER_RETR, (RCrt(ba, CRT_ID_END_VER_RETR) & 0x7f));
236 1.1.10.2 nathanw
237 1.1.10.2 nathanw for (i = 0; i < 0x18; i++)
238 1.1.10.2 nathanw WCrt(ba, i, crt_tab[i]);
239 1.1.10.2 nathanw for (i = 0; i < 8; i++)
240 1.1.10.2 nathanw WSeq(ba, i, seq_tab[i]);
241 1.1.10.2 nathanw for (i = 0; i < 9; i++)
242 1.1.10.2 nathanw WGfx(ba, i, gdc_tab[i]);
243 1.1.10.2 nathanw for (i = 0x10; i < 0x18; i++)
244 1.1.10.2 nathanw WAttr(ba, i, attr_tab[i - 0x10]);
245 1.1.10.2 nathanw WAttr(ba, 0x20, 0);
246 1.1.10.2 nathanw }
247