diff options
Diffstat (limited to 'arch/ppc/platforms/prep_pci.c')
-rw-r--r-- | arch/ppc/platforms/prep_pci.c | 1336 |
1 files changed, 1336 insertions, 0 deletions
diff --git a/arch/ppc/platforms/prep_pci.c b/arch/ppc/platforms/prep_pci.c new file mode 100644 index 00000000000..8cd80eb447b --- /dev/null +++ b/arch/ppc/platforms/prep_pci.c | |||
@@ -0,0 +1,1336 @@ | |||
1 | /* | ||
2 | * PReP pci functions. | ||
3 | * Originally by Gary Thomas | ||
4 | * rewritten and updated by Cort Dougan (cort@cs.nmt.edu) | ||
5 | * | ||
6 | * The motherboard routes/maps will disappear shortly. -- Cort | ||
7 | */ | ||
8 | |||
9 | #include <linux/config.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/pci.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | |||
15 | #include <asm/sections.h> | ||
16 | #include <asm/byteorder.h> | ||
17 | #include <asm/io.h> | ||
18 | #include <asm/ptrace.h> | ||
19 | #include <asm/prom.h> | ||
20 | #include <asm/pci-bridge.h> | ||
21 | #include <asm/residual.h> | ||
22 | #include <asm/irq.h> | ||
23 | #include <asm/machdep.h> | ||
24 | #include <asm/open_pic.h> | ||
25 | |||
26 | extern void (*setup_ibm_pci)(char *irq_lo, char *irq_hi); | ||
27 | |||
28 | /* Which PCI interrupt line does a given device [slot] use? */ | ||
29 | /* Note: This really should be two dimensional based in slot/pin used */ | ||
30 | static unsigned char *Motherboard_map; | ||
31 | unsigned char *Motherboard_map_name; | ||
32 | |||
33 | /* How is the 82378 PIRQ mapping setup? */ | ||
34 | static unsigned char *Motherboard_routes; | ||
35 | |||
36 | static void (*Motherboard_non0)(struct pci_dev *); | ||
37 | |||
38 | static void Powerplus_Map_Non0(struct pci_dev *); | ||
39 | |||
40 | /* Used for Motorola to store system config register */ | ||
41 | static unsigned long *ProcInfo; | ||
42 | |||
43 | /* Tables for known hardware */ | ||
44 | |||
45 | /* Motorola PowerStackII - Utah */ | ||
46 | static char Utah_pci_IRQ_map[23] __prepdata = | ||
47 | { | ||
48 | 0, /* Slot 0 - unused */ | ||
49 | 0, /* Slot 1 - unused */ | ||
50 | 5, /* Slot 2 - SCSI - NCR825A */ | ||
51 | 0, /* Slot 3 - unused */ | ||
52 | 3, /* Slot 4 - Ethernet - DEC2114x */ | ||
53 | 0, /* Slot 5 - unused */ | ||
54 | 2, /* Slot 6 - PCI Card slot #1 */ | ||
55 | 3, /* Slot 7 - PCI Card slot #2 */ | ||
56 | 5, /* Slot 8 - PCI Card slot #3 */ | ||
57 | 5, /* Slot 9 - PCI Bridge */ | ||
58 | /* added here in case we ever support PCI bridges */ | ||
59 | /* Secondary PCI bus cards are at slot-9,6 & slot-9,7 */ | ||
60 | 0, /* Slot 10 - unused */ | ||
61 | 0, /* Slot 11 - unused */ | ||
62 | 5, /* Slot 12 - SCSI - NCR825A */ | ||
63 | 0, /* Slot 13 - unused */ | ||
64 | 3, /* Slot 14 - enet */ | ||
65 | 0, /* Slot 15 - unused */ | ||
66 | 2, /* Slot 16 - unused */ | ||
67 | 3, /* Slot 17 - unused */ | ||
68 | 5, /* Slot 18 - unused */ | ||
69 | 0, /* Slot 19 - unused */ | ||
70 | 0, /* Slot 20 - unused */ | ||
71 | 0, /* Slot 21 - unused */ | ||
72 | 0, /* Slot 22 - unused */ | ||
73 | }; | ||
74 | |||
75 | static char Utah_pci_IRQ_routes[] __prepdata = | ||
76 | { | ||
77 | 0, /* Line 0 - Unused */ | ||
78 | 9, /* Line 1 */ | ||
79 | 10, /* Line 2 */ | ||
80 | 11, /* Line 3 */ | ||
81 | 14, /* Line 4 */ | ||
82 | 15, /* Line 5 */ | ||
83 | }; | ||
84 | |||
85 | /* Motorola PowerStackII - Omaha */ | ||
86 | /* no integrated SCSI or ethernet */ | ||
87 | static char Omaha_pci_IRQ_map[23] __prepdata = | ||
88 | { | ||
89 | 0, /* Slot 0 - unused */ | ||
90 | 0, /* Slot 1 - unused */ | ||
91 | 3, /* Slot 2 - Winbond EIDE */ | ||
92 | 0, /* Slot 3 - unused */ | ||
93 | 0, /* Slot 4 - unused */ | ||
94 | 0, /* Slot 5 - unused */ | ||
95 | 1, /* Slot 6 - PCI slot 1 */ | ||
96 | 2, /* Slot 7 - PCI slot 2 */ | ||
97 | 3, /* Slot 8 - PCI slot 3 */ | ||
98 | 4, /* Slot 9 - PCI slot 4 */ /* needs indirect access */ | ||
99 | 0, /* Slot 10 - unused */ | ||
100 | 0, /* Slot 11 - unused */ | ||
101 | 0, /* Slot 12 - unused */ | ||
102 | 0, /* Slot 13 - unused */ | ||
103 | 0, /* Slot 14 - unused */ | ||
104 | 0, /* Slot 15 - unused */ | ||
105 | 1, /* Slot 16 - PCI slot 1 */ | ||
106 | 2, /* Slot 17 - PCI slot 2 */ | ||
107 | 3, /* Slot 18 - PCI slot 3 */ | ||
108 | 4, /* Slot 19 - PCI slot 4 */ /* needs indirect access */ | ||
109 | 0, | ||
110 | 0, | ||
111 | 0, | ||
112 | }; | ||
113 | |||
114 | static char Omaha_pci_IRQ_routes[] __prepdata = | ||
115 | { | ||
116 | 0, /* Line 0 - Unused */ | ||
117 | 9, /* Line 1 */ | ||
118 | 11, /* Line 2 */ | ||
119 | 14, /* Line 3 */ | ||
120 | 15 /* Line 4 */ | ||
121 | }; | ||
122 | |||
123 | /* Motorola PowerStack */ | ||
124 | static char Blackhawk_pci_IRQ_map[19] __prepdata = | ||
125 | { | ||
126 | 0, /* Slot 0 - unused */ | ||
127 | 0, /* Slot 1 - unused */ | ||
128 | 0, /* Slot 2 - unused */ | ||
129 | 0, /* Slot 3 - unused */ | ||
130 | 0, /* Slot 4 - unused */ | ||
131 | 0, /* Slot 5 - unused */ | ||
132 | 0, /* Slot 6 - unused */ | ||
133 | 0, /* Slot 7 - unused */ | ||
134 | 0, /* Slot 8 - unused */ | ||
135 | 0, /* Slot 9 - unused */ | ||
136 | 0, /* Slot 10 - unused */ | ||
137 | 0, /* Slot 11 - unused */ | ||
138 | 3, /* Slot 12 - SCSI */ | ||
139 | 0, /* Slot 13 - unused */ | ||
140 | 1, /* Slot 14 - Ethernet */ | ||
141 | 0, /* Slot 15 - unused */ | ||
142 | 1, /* Slot P7 */ | ||
143 | 2, /* Slot P6 */ | ||
144 | 3, /* Slot P5 */ | ||
145 | }; | ||
146 | |||
147 | static char Blackhawk_pci_IRQ_routes[] __prepdata = | ||
148 | { | ||
149 | 0, /* Line 0 - Unused */ | ||
150 | 9, /* Line 1 */ | ||
151 | 11, /* Line 2 */ | ||
152 | 15, /* Line 3 */ | ||
153 | 15 /* Line 4 */ | ||
154 | }; | ||
155 | |||
156 | /* Motorola Mesquite */ | ||
157 | static char Mesquite_pci_IRQ_map[23] __prepdata = | ||
158 | { | ||
159 | 0, /* Slot 0 - unused */ | ||
160 | 0, /* Slot 1 - unused */ | ||
161 | 0, /* Slot 2 - unused */ | ||
162 | 0, /* Slot 3 - unused */ | ||
163 | 0, /* Slot 4 - unused */ | ||
164 | 0, /* Slot 5 - unused */ | ||
165 | 0, /* Slot 6 - unused */ | ||
166 | 0, /* Slot 7 - unused */ | ||
167 | 0, /* Slot 8 - unused */ | ||
168 | 0, /* Slot 9 - unused */ | ||
169 | 0, /* Slot 10 - unused */ | ||
170 | 0, /* Slot 11 - unused */ | ||
171 | 0, /* Slot 12 - unused */ | ||
172 | 0, /* Slot 13 - unused */ | ||
173 | 2, /* Slot 14 - Ethernet */ | ||
174 | 0, /* Slot 15 - unused */ | ||
175 | 3, /* Slot 16 - PMC */ | ||
176 | 0, /* Slot 17 - unused */ | ||
177 | 0, /* Slot 18 - unused */ | ||
178 | 0, /* Slot 19 - unused */ | ||
179 | 0, /* Slot 20 - unused */ | ||
180 | 0, /* Slot 21 - unused */ | ||
181 | 0, /* Slot 22 - unused */ | ||
182 | }; | ||
183 | |||
184 | /* Motorola Sitka */ | ||
185 | static char Sitka_pci_IRQ_map[21] __prepdata = | ||
186 | { | ||
187 | 0, /* Slot 0 - unused */ | ||
188 | 0, /* Slot 1 - unused */ | ||
189 | 0, /* Slot 2 - unused */ | ||
190 | 0, /* Slot 3 - unused */ | ||
191 | 0, /* Slot 4 - unused */ | ||
192 | 0, /* Slot 5 - unused */ | ||
193 | 0, /* Slot 6 - unused */ | ||
194 | 0, /* Slot 7 - unused */ | ||
195 | 0, /* Slot 8 - unused */ | ||
196 | 0, /* Slot 9 - unused */ | ||
197 | 0, /* Slot 10 - unused */ | ||
198 | 0, /* Slot 11 - unused */ | ||
199 | 0, /* Slot 12 - unused */ | ||
200 | 0, /* Slot 13 - unused */ | ||
201 | 2, /* Slot 14 - Ethernet */ | ||
202 | 0, /* Slot 15 - unused */ | ||
203 | 9, /* Slot 16 - PMC 1 */ | ||
204 | 12, /* Slot 17 - PMC 2 */ | ||
205 | 0, /* Slot 18 - unused */ | ||
206 | 0, /* Slot 19 - unused */ | ||
207 | 4, /* Slot 20 - NT P2P bridge */ | ||
208 | }; | ||
209 | |||
210 | /* Motorola MTX */ | ||
211 | static char MTX_pci_IRQ_map[23] __prepdata = | ||
212 | { | ||
213 | 0, /* Slot 0 - unused */ | ||
214 | 0, /* Slot 1 - unused */ | ||
215 | 0, /* Slot 2 - unused */ | ||
216 | 0, /* Slot 3 - unused */ | ||
217 | 0, /* Slot 4 - unused */ | ||
218 | 0, /* Slot 5 - unused */ | ||
219 | 0, /* Slot 6 - unused */ | ||
220 | 0, /* Slot 7 - unused */ | ||
221 | 0, /* Slot 8 - unused */ | ||
222 | 0, /* Slot 9 - unused */ | ||
223 | 0, /* Slot 10 - unused */ | ||
224 | 0, /* Slot 11 - unused */ | ||
225 | 3, /* Slot 12 - SCSI */ | ||
226 | 0, /* Slot 13 - unused */ | ||
227 | 2, /* Slot 14 - Ethernet */ | ||
228 | 0, /* Slot 15 - unused */ | ||
229 | 9, /* Slot 16 - PCI/PMC slot 1 */ | ||
230 | 10, /* Slot 17 - PCI/PMC slot 2 */ | ||
231 | 11, /* Slot 18 - PCI slot 3 */ | ||
232 | 0, /* Slot 19 - unused */ | ||
233 | 0, /* Slot 20 - unused */ | ||
234 | 0, /* Slot 21 - unused */ | ||
235 | 0, /* Slot 22 - unused */ | ||
236 | }; | ||
237 | |||
238 | /* Motorola MTX Plus */ | ||
239 | /* Secondary bus interrupt routing is not supported yet */ | ||
240 | static char MTXplus_pci_IRQ_map[23] __prepdata = | ||
241 | { | ||
242 | 0, /* Slot 0 - unused */ | ||
243 | 0, /* Slot 1 - unused */ | ||
244 | 0, /* Slot 2 - unused */ | ||
245 | 0, /* Slot 3 - unused */ | ||
246 | 0, /* Slot 4 - unused */ | ||
247 | 0, /* Slot 5 - unused */ | ||
248 | 0, /* Slot 6 - unused */ | ||
249 | 0, /* Slot 7 - unused */ | ||
250 | 0, /* Slot 8 - unused */ | ||
251 | 0, /* Slot 9 - unused */ | ||
252 | 0, /* Slot 10 - unused */ | ||
253 | 0, /* Slot 11 - unused */ | ||
254 | 3, /* Slot 12 - SCSI */ | ||
255 | 0, /* Slot 13 - unused */ | ||
256 | 2, /* Slot 14 - Ethernet 1 */ | ||
257 | 0, /* Slot 15 - unused */ | ||
258 | 9, /* Slot 16 - PCI slot 1P */ | ||
259 | 10, /* Slot 17 - PCI slot 2P */ | ||
260 | 11, /* Slot 18 - PCI slot 3P */ | ||
261 | 10, /* Slot 19 - Ethernet 2 */ | ||
262 | 0, /* Slot 20 - P2P Bridge */ | ||
263 | 0, /* Slot 21 - unused */ | ||
264 | 0, /* Slot 22 - unused */ | ||
265 | }; | ||
266 | |||
267 | static char Raven_pci_IRQ_routes[] __prepdata = | ||
268 | { | ||
269 | 0, /* This is a dummy structure */ | ||
270 | }; | ||
271 | |||
272 | /* Motorola MVME16xx */ | ||
273 | static char Genesis_pci_IRQ_map[16] __prepdata = | ||
274 | { | ||
275 | 0, /* Slot 0 - unused */ | ||
276 | 0, /* Slot 1 - unused */ | ||
277 | 0, /* Slot 2 - unused */ | ||
278 | 0, /* Slot 3 - unused */ | ||
279 | 0, /* Slot 4 - unused */ | ||
280 | 0, /* Slot 5 - unused */ | ||
281 | 0, /* Slot 6 - unused */ | ||
282 | 0, /* Slot 7 - unused */ | ||
283 | 0, /* Slot 8 - unused */ | ||
284 | 0, /* Slot 9 - unused */ | ||
285 | 0, /* Slot 10 - unused */ | ||
286 | 0, /* Slot 11 - unused */ | ||
287 | 3, /* Slot 12 - SCSI */ | ||
288 | 0, /* Slot 13 - unused */ | ||
289 | 1, /* Slot 14 - Ethernet */ | ||
290 | 0, /* Slot 15 - unused */ | ||
291 | }; | ||
292 | |||
293 | static char Genesis_pci_IRQ_routes[] __prepdata = | ||
294 | { | ||
295 | 0, /* Line 0 - Unused */ | ||
296 | 10, /* Line 1 */ | ||
297 | 11, /* Line 2 */ | ||
298 | 14, /* Line 3 */ | ||
299 | 15 /* Line 4 */ | ||
300 | }; | ||
301 | |||
302 | static char Genesis2_pci_IRQ_map[23] __prepdata = | ||
303 | { | ||
304 | 0, /* Slot 0 - unused */ | ||
305 | 0, /* Slot 1 - unused */ | ||
306 | 0, /* Slot 2 - unused */ | ||
307 | 0, /* Slot 3 - unused */ | ||
308 | 0, /* Slot 4 - unused */ | ||
309 | 0, /* Slot 5 - unused */ | ||
310 | 0, /* Slot 6 - unused */ | ||
311 | 0, /* Slot 7 - unused */ | ||
312 | 0, /* Slot 8 - unused */ | ||
313 | 0, /* Slot 9 - unused */ | ||
314 | 0, /* Slot 10 - unused */ | ||
315 | 0, /* Slot 11 - IDE */ | ||
316 | 3, /* Slot 12 - SCSI */ | ||
317 | 5, /* Slot 13 - Universe PCI - VME Bridge */ | ||
318 | 2, /* Slot 14 - Ethernet */ | ||
319 | 0, /* Slot 15 - unused */ | ||
320 | 9, /* Slot 16 - PMC 1 */ | ||
321 | 12, /* Slot 17 - pci */ | ||
322 | 11, /* Slot 18 - pci */ | ||
323 | 10, /* Slot 19 - pci */ | ||
324 | 0, /* Slot 20 - pci */ | ||
325 | 0, /* Slot 21 - unused */ | ||
326 | 0, /* Slot 22 - unused */ | ||
327 | }; | ||
328 | |||
329 | /* Motorola Series-E */ | ||
330 | static char Comet_pci_IRQ_map[23] __prepdata = | ||
331 | { | ||
332 | 0, /* Slot 0 - unused */ | ||
333 | 0, /* Slot 1 - unused */ | ||
334 | 0, /* Slot 2 - unused */ | ||
335 | 0, /* Slot 3 - unused */ | ||
336 | 0, /* Slot 4 - unused */ | ||
337 | 0, /* Slot 5 - unused */ | ||
338 | 0, /* Slot 6 - unused */ | ||
339 | 0, /* Slot 7 - unused */ | ||
340 | 0, /* Slot 8 - unused */ | ||
341 | 0, /* Slot 9 - unused */ | ||
342 | 0, /* Slot 10 - unused */ | ||
343 | 0, /* Slot 11 - unused */ | ||
344 | 3, /* Slot 12 - SCSI */ | ||
345 | 0, /* Slot 13 - unused */ | ||
346 | 1, /* Slot 14 - Ethernet */ | ||
347 | 0, /* Slot 15 - unused */ | ||
348 | 1, /* Slot 16 - PCI slot 1 */ | ||
349 | 2, /* Slot 17 - PCI slot 2 */ | ||
350 | 3, /* Slot 18 - PCI slot 3 */ | ||
351 | 4, /* Slot 19 - PCI bridge */ | ||
352 | 0, | ||
353 | 0, | ||
354 | 0, | ||
355 | }; | ||
356 | |||
357 | static char Comet_pci_IRQ_routes[] __prepdata = | ||
358 | { | ||
359 | 0, /* Line 0 - Unused */ | ||
360 | 10, /* Line 1 */ | ||
361 | 11, /* Line 2 */ | ||
362 | 14, /* Line 3 */ | ||
363 | 15 /* Line 4 */ | ||
364 | }; | ||
365 | |||
366 | /* Motorola Series-EX */ | ||
367 | static char Comet2_pci_IRQ_map[23] __prepdata = | ||
368 | { | ||
369 | 0, /* Slot 0 - unused */ | ||
370 | 0, /* Slot 1 - unused */ | ||
371 | 3, /* Slot 2 - SCSI - NCR825A */ | ||
372 | 0, /* Slot 3 - unused */ | ||
373 | 1, /* Slot 4 - Ethernet - DEC2104X */ | ||
374 | 0, /* Slot 5 - unused */ | ||
375 | 1, /* Slot 6 - PCI slot 1 */ | ||
376 | 2, /* Slot 7 - PCI slot 2 */ | ||
377 | 3, /* Slot 8 - PCI slot 3 */ | ||
378 | 4, /* Slot 9 - PCI bridge */ | ||
379 | 0, /* Slot 10 - unused */ | ||
380 | 0, /* Slot 11 - unused */ | ||
381 | 3, /* Slot 12 - SCSI - NCR825A */ | ||
382 | 0, /* Slot 13 - unused */ | ||
383 | 1, /* Slot 14 - Ethernet - DEC2104X */ | ||
384 | 0, /* Slot 15 - unused */ | ||
385 | 1, /* Slot 16 - PCI slot 1 */ | ||
386 | 2, /* Slot 17 - PCI slot 2 */ | ||
387 | 3, /* Slot 18 - PCI slot 3 */ | ||
388 | 4, /* Slot 19 - PCI bridge */ | ||
389 | 0, | ||
390 | 0, | ||
391 | 0, | ||
392 | }; | ||
393 | |||
394 | static char Comet2_pci_IRQ_routes[] __prepdata = | ||
395 | { | ||
396 | 0, /* Line 0 - Unused */ | ||
397 | 10, /* Line 1 */ | ||
398 | 11, /* Line 2 */ | ||
399 | 14, /* Line 3 */ | ||
400 | 15, /* Line 4 */ | ||
401 | }; | ||
402 | |||
403 | /* | ||
404 | * ibm 830 (and 850?). | ||
405 | * This is actually based on the Carolina motherboard | ||
406 | * -- Cort | ||
407 | */ | ||
408 | static char ibm8xx_pci_IRQ_map[23] __prepdata = { | ||
409 | 0, /* Slot 0 - unused */ | ||
410 | 0, /* Slot 1 - unused */ | ||
411 | 0, /* Slot 2 - unused */ | ||
412 | 0, /* Slot 3 - unused */ | ||
413 | 0, /* Slot 4 - unused */ | ||
414 | 0, /* Slot 5 - unused */ | ||
415 | 0, /* Slot 6 - unused */ | ||
416 | 0, /* Slot 7 - unused */ | ||
417 | 0, /* Slot 8 - unused */ | ||
418 | 0, /* Slot 9 - unused */ | ||
419 | 0, /* Slot 10 - unused */ | ||
420 | 0, /* Slot 11 - FireCoral */ | ||
421 | 4, /* Slot 12 - Ethernet PCIINTD# */ | ||
422 | 2, /* Slot 13 - PCI Slot #2 */ | ||
423 | 2, /* Slot 14 - S3 Video PCIINTD# */ | ||
424 | 0, /* Slot 15 - onboard SCSI (INDI) [1] */ | ||
425 | 3, /* Slot 16 - NCR58C810 RS6000 Only PCIINTC# */ | ||
426 | 0, /* Slot 17 - unused */ | ||
427 | 2, /* Slot 18 - PCI Slot 2 PCIINTx# (See below) */ | ||
428 | 0, /* Slot 19 - unused */ | ||
429 | 0, /* Slot 20 - unused */ | ||
430 | 0, /* Slot 21 - unused */ | ||
431 | 2, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */ | ||
432 | }; | ||
433 | |||
434 | static char ibm8xx_pci_IRQ_routes[] __prepdata = { | ||
435 | 0, /* Line 0 - unused */ | ||
436 | 15, /* Line 1 */ | ||
437 | 15, /* Line 2 */ | ||
438 | 15, /* Line 3 */ | ||
439 | 15, /* Line 4 */ | ||
440 | }; | ||
441 | |||
442 | /* | ||
443 | * a 6015 ibm board | ||
444 | * -- Cort | ||
445 | */ | ||
446 | static char ibm6015_pci_IRQ_map[23] __prepdata = { | ||
447 | 0, /* Slot 0 - unused */ | ||
448 | 0, /* Slot 1 - unused */ | ||
449 | 0, /* Slot 2 - unused */ | ||
450 | 0, /* Slot 3 - unused */ | ||
451 | 0, /* Slot 4 - unused */ | ||
452 | 0, /* Slot 5 - unused */ | ||
453 | 0, /* Slot 6 - unused */ | ||
454 | 0, /* Slot 7 - unused */ | ||
455 | 0, /* Slot 8 - unused */ | ||
456 | 0, /* Slot 9 - unused */ | ||
457 | 0, /* Slot 10 - unused */ | ||
458 | 0, /* Slot 11 - */ | ||
459 | 1, /* Slot 12 - SCSI */ | ||
460 | 2, /* Slot 13 - */ | ||
461 | 2, /* Slot 14 - */ | ||
462 | 1, /* Slot 15 - */ | ||
463 | 1, /* Slot 16 - */ | ||
464 | 0, /* Slot 17 - */ | ||
465 | 2, /* Slot 18 - */ | ||
466 | 0, /* Slot 19 - */ | ||
467 | 0, /* Slot 20 - */ | ||
468 | 0, /* Slot 21 - */ | ||
469 | 2, /* Slot 22 - */ | ||
470 | }; | ||
471 | |||
472 | static char ibm6015_pci_IRQ_routes[] __prepdata = { | ||
473 | 0, /* Line 0 - unused */ | ||
474 | 13, /* Line 1 */ | ||
475 | 15, /* Line 2 */ | ||
476 | 15, /* Line 3 */ | ||
477 | 15, /* Line 4 */ | ||
478 | }; | ||
479 | |||
480 | |||
481 | /* IBM Nobis and Thinkpad 850 */ | ||
482 | static char Nobis_pci_IRQ_map[23] __prepdata ={ | ||
483 | 0, /* Slot 0 - unused */ | ||
484 | 0, /* Slot 1 - unused */ | ||
485 | 0, /* Slot 2 - unused */ | ||
486 | 0, /* Slot 3 - unused */ | ||
487 | 0, /* Slot 4 - unused */ | ||
488 | 0, /* Slot 5 - unused */ | ||
489 | 0, /* Slot 6 - unused */ | ||
490 | 0, /* Slot 7 - unused */ | ||
491 | 0, /* Slot 8 - unused */ | ||
492 | 0, /* Slot 9 - unused */ | ||
493 | 0, /* Slot 10 - unused */ | ||
494 | 0, /* Slot 11 - unused */ | ||
495 | 3, /* Slot 12 - SCSI */ | ||
496 | 0, /* Slot 13 - unused */ | ||
497 | 0, /* Slot 14 - unused */ | ||
498 | 0, /* Slot 15 - unused */ | ||
499 | }; | ||
500 | |||
501 | static char Nobis_pci_IRQ_routes[] __prepdata = { | ||
502 | 0, /* Line 0 - Unused */ | ||
503 | 13, /* Line 1 */ | ||
504 | 13, /* Line 2 */ | ||
505 | 13, /* Line 3 */ | ||
506 | 13 /* Line 4 */ | ||
507 | }; | ||
508 | |||
509 | /* | ||
510 | * IBM RS/6000 43p/140 -- paulus | ||
511 | * XXX we should get all this from the residual data | ||
512 | */ | ||
513 | static char ibm43p_pci_IRQ_map[23] __prepdata = { | ||
514 | 0, /* Slot 0 - unused */ | ||
515 | 0, /* Slot 1 - unused */ | ||
516 | 0, /* Slot 2 - unused */ | ||
517 | 0, /* Slot 3 - unused */ | ||
518 | 0, /* Slot 4 - unused */ | ||
519 | 0, /* Slot 5 - unused */ | ||
520 | 0, /* Slot 6 - unused */ | ||
521 | 0, /* Slot 7 - unused */ | ||
522 | 0, /* Slot 8 - unused */ | ||
523 | 0, /* Slot 9 - unused */ | ||
524 | 0, /* Slot 10 - unused */ | ||
525 | 0, /* Slot 11 - FireCoral ISA bridge */ | ||
526 | 6, /* Slot 12 - Ethernet */ | ||
527 | 0, /* Slot 13 - openpic */ | ||
528 | 0, /* Slot 14 - unused */ | ||
529 | 0, /* Slot 15 - unused */ | ||
530 | 7, /* Slot 16 - NCR58C825a onboard scsi */ | ||
531 | 0, /* Slot 17 - unused */ | ||
532 | 2, /* Slot 18 - PCI Slot 2 PCIINTx# (See below) */ | ||
533 | 0, /* Slot 19 - unused */ | ||
534 | 0, /* Slot 20 - unused */ | ||
535 | 0, /* Slot 21 - unused */ | ||
536 | 1, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */ | ||
537 | }; | ||
538 | |||
539 | static char ibm43p_pci_IRQ_routes[] __prepdata = { | ||
540 | 0, /* Line 0 - unused */ | ||
541 | 15, /* Line 1 */ | ||
542 | 15, /* Line 2 */ | ||
543 | 15, /* Line 3 */ | ||
544 | 15, /* Line 4 */ | ||
545 | }; | ||
546 | |||
547 | /* Motorola PowerPlus architecture PCI IRQ tables */ | ||
548 | /* Interrupt line values for INTA-D on primary/secondary MPIC inputs */ | ||
549 | |||
550 | struct powerplus_irq_list | ||
551 | { | ||
552 | unsigned char primary[4]; /* INT A-D */ | ||
553 | unsigned char secondary[4]; /* INT A-D */ | ||
554 | }; | ||
555 | |||
556 | /* | ||
557 | * For standard PowerPlus boards, bus 0 PCI INTs A-D are routed to | ||
558 | * OpenPIC inputs 9-12. PCI INTs A-D from the on board P2P bridge | ||
559 | * are routed to OpenPIC inputs 5-8. These values are offset by | ||
560 | * 16 in the table to reflect the Linux kernel interrupt value. | ||
561 | */ | ||
562 | struct powerplus_irq_list Powerplus_pci_IRQ_list __prepdata = | ||
563 | { | ||
564 | {25, 26, 27, 28}, | ||
565 | {21, 22, 23, 24} | ||
566 | }; | ||
567 | |||
568 | /* | ||
569 | * For the MCP750 (system slot board), cPCI INTs A-D are routed to | ||
570 | * OpenPIC inputs 8-11 and the PMC INTs A-D are routed to OpenPIC | ||
571 | * input 3. On a hot swap MCP750, the companion card PCI INTs A-D | ||
572 | * are routed to OpenPIC inputs 12-15. These values are offset by | ||
573 | * 16 in the table to reflect the Linux kernel interrupt value. | ||
574 | */ | ||
575 | struct powerplus_irq_list Mesquite_pci_IRQ_list __prepdata = | ||
576 | { | ||
577 | {24, 25, 26, 27}, | ||
578 | {28, 29, 30, 31} | ||
579 | }; | ||
580 | |||
581 | /* | ||
582 | * This table represents the standard PCI swizzle defined in the | ||
583 | * PCI bus specification. | ||
584 | */ | ||
585 | static unsigned char prep_pci_intpins[4][4] __prepdata = | ||
586 | { | ||
587 | { 1, 2, 3, 4}, /* Buses 0, 4, 8, ... */ | ||
588 | { 2, 3, 4, 1}, /* Buses 1, 5, 9, ... */ | ||
589 | { 3, 4, 1, 2}, /* Buses 2, 6, 10 ... */ | ||
590 | { 4, 1, 2, 3}, /* Buses 3, 7, 11 ... */ | ||
591 | }; | ||
592 | |||
593 | /* We have to turn on LEVEL mode for changed IRQ's */ | ||
594 | /* All PCI IRQ's need to be level mode, so this should be something | ||
595 | * other than hard-coded as well... IRQ's are individually mappable | ||
596 | * to either edge or level. | ||
597 | */ | ||
598 | |||
599 | /* | ||
600 | * 8259 edge/level control definitions | ||
601 | */ | ||
602 | #define ISA8259_M_ELCR 0x4d0 | ||
603 | #define ISA8259_S_ELCR 0x4d1 | ||
604 | |||
605 | #define ELCRS_INT15_LVL 0x80 | ||
606 | #define ELCRS_INT14_LVL 0x40 | ||
607 | #define ELCRS_INT12_LVL 0x10 | ||
608 | #define ELCRS_INT11_LVL 0x08 | ||
609 | #define ELCRS_INT10_LVL 0x04 | ||
610 | #define ELCRS_INT9_LVL 0x02 | ||
611 | #define ELCRS_INT8_LVL 0x01 | ||
612 | #define ELCRM_INT7_LVL 0x80 | ||
613 | #define ELCRM_INT5_LVL 0x20 | ||
614 | |||
615 | #if 0 | ||
616 | /* | ||
617 | * PCI config space access. | ||
618 | */ | ||
619 | #define CFGADDR(dev) ((1<<(dev>>3)) | ((dev&7)<<8)) | ||
620 | #define DEVNO(dev) (dev>>3) | ||
621 | |||
622 | #define MIN_DEVNR 11 | ||
623 | #define MAX_DEVNR 22 | ||
624 | |||
625 | static int __prep | ||
626 | prep_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
627 | int len, u32 *val) | ||
628 | { | ||
629 | struct pci_controller *hose = bus->sysdata; | ||
630 | volatile void __iomem *cfg_data; | ||
631 | |||
632 | if (bus->number != 0 || DEVNO(devfn) < MIN_DEVNR | ||
633 | || DEVNO(devfn) > MAX_DEVNR) | ||
634 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
635 | |||
636 | /* | ||
637 | * Note: the caller has already checked that offset is | ||
638 | * suitably aligned and that len is 1, 2 or 4. | ||
639 | */ | ||
640 | cfg_data = hose->cfg_data + CFGADDR(devfn) + offset; | ||
641 | switch (len) { | ||
642 | case 1: | ||
643 | *val = in_8(cfg_data); | ||
644 | break; | ||
645 | case 2: | ||
646 | *val = in_le16(cfg_data); | ||
647 | break; | ||
648 | default: | ||
649 | *val = in_le32(cfg_data); | ||
650 | break; | ||
651 | } | ||
652 | return PCIBIOS_SUCCESSFUL; | ||
653 | } | ||
654 | |||
655 | static int __prep | ||
656 | prep_write_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
657 | int len, u32 val) | ||
658 | { | ||
659 | struct pci_controller *hose = bus->sysdata; | ||
660 | volatile void __iomem *cfg_data; | ||
661 | |||
662 | if (bus->number != 0 || DEVNO(devfn) < MIN_DEVNR | ||
663 | || DEVNO(devfn) > MAX_DEVNR) | ||
664 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
665 | |||
666 | /* | ||
667 | * Note: the caller has already checked that offset is | ||
668 | * suitably aligned and that len is 1, 2 or 4. | ||
669 | */ | ||
670 | cfg_data = hose->cfg_data + CFGADDR(devfn) + offset; | ||
671 | switch (len) { | ||
672 | case 1: | ||
673 | out_8(cfg_data, val); | ||
674 | break; | ||
675 | case 2: | ||
676 | out_le16(cfg_data, val); | ||
677 | break; | ||
678 | default: | ||
679 | out_le32(cfg_data, val); | ||
680 | break; | ||
681 | } | ||
682 | return PCIBIOS_SUCCESSFUL; | ||
683 | } | ||
684 | |||
685 | static struct pci_ops prep_pci_ops = | ||
686 | { | ||
687 | prep_read_config, | ||
688 | prep_write_config | ||
689 | }; | ||
690 | #endif | ||
691 | |||
692 | #define MOTOROLA_CPUTYPE_REG 0x800 | ||
693 | #define MOTOROLA_BASETYPE_REG 0x803 | ||
694 | #define MPIC_RAVEN_ID 0x48010000 | ||
695 | #define MPIC_HAWK_ID 0x48030000 | ||
696 | #define MOT_PROC2_BIT 0x800 | ||
697 | |||
698 | static u_char prep_openpic_initsenses[] __initdata = { | ||
699 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* MVME2600_INT_SIO */ | ||
700 | (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_FALCN_ECC_ERR */ | ||
701 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_ETHERNET */ | ||
702 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_SCSI */ | ||
703 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_GRAPHICS */ | ||
704 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME0 */ | ||
705 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME1 */ | ||
706 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME2 */ | ||
707 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME3 */ | ||
708 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTA */ | ||
709 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTB */ | ||
710 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTC */ | ||
711 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTD */ | ||
712 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_LM_SIG0 */ | ||
713 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_LM_SIG1 */ | ||
714 | }; | ||
715 | |||
716 | #define MOT_RAVEN_PRESENT 0x1 | ||
717 | #define MOT_HAWK_PRESENT 0x2 | ||
718 | |||
719 | int mot_entry = -1; | ||
720 | int prep_keybd_present = 1; | ||
721 | int MotMPIC; | ||
722 | int mot_multi; | ||
723 | |||
724 | int __init | ||
725 | raven_init(void) | ||
726 | { | ||
727 | unsigned int devid; | ||
728 | unsigned int pci_membase; | ||
729 | unsigned char base_mod; | ||
730 | |||
731 | /* Check to see if the Raven chip exists. */ | ||
732 | if ( _prep_type != _PREP_Motorola) { | ||
733 | OpenPIC_Addr = NULL; | ||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | /* Check to see if this board is a type that might have a Raven. */ | ||
738 | if ((inb(MOTOROLA_CPUTYPE_REG) & 0xF0) != 0xE0) { | ||
739 | OpenPIC_Addr = NULL; | ||
740 | return 0; | ||
741 | } | ||
742 | |||
743 | /* Check the first PCI device to see if it is a Raven. */ | ||
744 | early_read_config_dword(NULL, 0, 0, PCI_VENDOR_ID, &devid); | ||
745 | |||
746 | switch (devid & 0xffff0000) { | ||
747 | case MPIC_RAVEN_ID: | ||
748 | MotMPIC = MOT_RAVEN_PRESENT; | ||
749 | break; | ||
750 | case MPIC_HAWK_ID: | ||
751 | MotMPIC = MOT_HAWK_PRESENT; | ||
752 | break; | ||
753 | default: | ||
754 | OpenPIC_Addr = NULL; | ||
755 | return 0; | ||
756 | } | ||
757 | |||
758 | |||
759 | /* Read the memory base register. */ | ||
760 | early_read_config_dword(NULL, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase); | ||
761 | |||
762 | if (pci_membase == 0) { | ||
763 | OpenPIC_Addr = NULL; | ||
764 | return 0; | ||
765 | } | ||
766 | |||
767 | /* Map the Raven MPIC registers to virtual memory. */ | ||
768 | OpenPIC_Addr = ioremap(pci_membase+0xC0000000, 0x22000); | ||
769 | |||
770 | OpenPIC_InitSenses = prep_openpic_initsenses; | ||
771 | OpenPIC_NumInitSenses = sizeof(prep_openpic_initsenses); | ||
772 | |||
773 | ppc_md.get_irq = openpic_get_irq; | ||
774 | |||
775 | /* If raven is present on Motorola store the system config register | ||
776 | * for later use. | ||
777 | */ | ||
778 | ProcInfo = (unsigned long *)ioremap(0xfef80400, 4); | ||
779 | |||
780 | /* Indicate to system if this is a multiprocessor board */ | ||
781 | if (!(*ProcInfo & MOT_PROC2_BIT)) { | ||
782 | mot_multi = 1; | ||
783 | } | ||
784 | |||
785 | /* This is a hack. If this is a 2300 or 2400 mot board then there is | ||
786 | * no keyboard controller and we have to indicate that. | ||
787 | */ | ||
788 | base_mod = inb(MOTOROLA_BASETYPE_REG); | ||
789 | if ((MotMPIC == MOT_HAWK_PRESENT) || (base_mod == 0xF9) || | ||
790 | (base_mod == 0xFA) || (base_mod == 0xE1)) | ||
791 | prep_keybd_present = 0; | ||
792 | |||
793 | return 1; | ||
794 | } | ||
795 | |||
796 | struct mot_info { | ||
797 | int cpu_type; /* 0x100 mask assumes for Raven and Hawk boards that the level/edge are set */ | ||
798 | /* 0x200 if this board has a Hawk chip. */ | ||
799 | int base_type; | ||
800 | int max_cpu; /* ored with 0x80 if this board should be checked for multi CPU */ | ||
801 | const char *name; | ||
802 | unsigned char *map; | ||
803 | unsigned char *routes; | ||
804 | void (*map_non0_bus)(struct pci_dev *); /* For boards with more than bus 0 devices. */ | ||
805 | struct powerplus_irq_list *pci_irq_list; /* List of PCI MPIC inputs */ | ||
806 | unsigned char secondary_bridge_devfn; /* devfn of secondary bus transparent bridge */ | ||
807 | } mot_info[] __prepdata = { | ||
808 | {0x300, 0x00, 0x00, "MVME 2400", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, | ||
809 | {0x010, 0x00, 0x00, "Genesis", Genesis_pci_IRQ_map, Genesis_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00}, | ||
810 | {0x020, 0x00, 0x00, "Powerstack (Series E)", Comet_pci_IRQ_map, Comet_pci_IRQ_routes, NULL, NULL, 0x00}, | ||
811 | {0x040, 0x00, 0x00, "Blackhawk (Powerstack)", Blackhawk_pci_IRQ_map, Blackhawk_pci_IRQ_routes, NULL, NULL, 0x00}, | ||
812 | {0x050, 0x00, 0x00, "Omaha (PowerStack II Pro3000)", Omaha_pci_IRQ_map, Omaha_pci_IRQ_routes, NULL, NULL, 0x00}, | ||
813 | {0x060, 0x00, 0x00, "Utah (Powerstack II Pro4000)", Utah_pci_IRQ_map, Utah_pci_IRQ_routes, NULL, NULL, 0x00}, | ||
814 | {0x0A0, 0x00, 0x00, "Powerstack (Series EX)", Comet2_pci_IRQ_map, Comet2_pci_IRQ_routes, NULL, NULL, 0x00}, | ||
815 | {0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Mesquite_pci_IRQ_list, 0xFF}, | ||
816 | {0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)", Sitka_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, | ||
817 | {0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Mesquite_pci_IRQ_list, 0xC0}, | ||
818 | {0x1E0, 0xF6, 0x80, "MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xA0}, | ||
819 | {0x1E0, 0xF6, 0x81, "Dual MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xA0}, | ||
820 | {0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00}, | ||
821 | {0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00}, | ||
822 | {0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00}, | ||
823 | {0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00}, | ||
824 | {0x1E0, 0xF9, 0x00, "MVME 2300", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, | ||
825 | {0x1E0, 0xFA, 0x00, "MVME 2300SC/2600", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, | ||
826 | {0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, | ||
827 | {0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, | ||
828 | {0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00}, | ||
829 | {0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, | ||
830 | {0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, | ||
831 | {0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, | ||
832 | {0x1E0, 0xFF, 0x00, "MVME 1600-001 or 1600-011", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, | ||
833 | {0x000, 0x00, 0x00, "", NULL, NULL, NULL, NULL, 0x00} | ||
834 | }; | ||
835 | |||
836 | void __init | ||
837 | ibm_prep_init(void) | ||
838 | { | ||
839 | if (have_residual_data) { | ||
840 | u32 addr, real_addr, len, offset; | ||
841 | PPC_DEVICE *mpic; | ||
842 | PnP_TAG_PACKET *pkt; | ||
843 | |||
844 | /* Use the PReP residual data to determine if an OpenPIC is | ||
845 | * present. If so, get the large vendor packet which will | ||
846 | * tell us the base address and length in memory. | ||
847 | * If we are successful, ioremap the memory area and set | ||
848 | * OpenPIC_Addr (this indicates that the OpenPIC was found). | ||
849 | */ | ||
850 | mpic = residual_find_device(-1, NULL, SystemPeripheral, | ||
851 | ProgrammableInterruptController, MPIC, 0); | ||
852 | if (!mpic) | ||
853 | return; | ||
854 | |||
855 | pkt = PnP_find_large_vendor_packet(res->DevicePnPHeap + | ||
856 | mpic->AllocatedOffset, 9, 0); | ||
857 | |||
858 | if (!pkt) | ||
859 | return; | ||
860 | |||
861 | #define p pkt->L4_Pack.L4_Data.L4_PPCPack | ||
862 | if (p.PPCData[1] == 32) { | ||
863 | switch (p.PPCData[0]) { | ||
864 | case 1: offset = PREP_ISA_IO_BASE; break; | ||
865 | case 2: offset = PREP_ISA_MEM_BASE; break; | ||
866 | default: return; /* Not I/O or memory?? */ | ||
867 | } | ||
868 | } | ||
869 | else | ||
870 | return; /* Not a 32-bit address */ | ||
871 | |||
872 | real_addr = ld_le32((unsigned int *) (p.PPCData + 4)); | ||
873 | if (real_addr == 0xffffffff) | ||
874 | return; | ||
875 | |||
876 | /* Adjust address to be as seen by CPU */ | ||
877 | addr = real_addr + offset; | ||
878 | |||
879 | len = ld_le32((unsigned int *) (p.PPCData + 12)); | ||
880 | if (!len) | ||
881 | return; | ||
882 | #undef p | ||
883 | OpenPIC_Addr = ioremap(addr, len); | ||
884 | ppc_md.get_irq = openpic_get_irq; | ||
885 | |||
886 | OpenPIC_InitSenses = prep_openpic_initsenses; | ||
887 | OpenPIC_NumInitSenses = sizeof(prep_openpic_initsenses); | ||
888 | |||
889 | printk(KERN_INFO "MPIC at 0x%08x (0x%08x), length 0x%08x " | ||
890 | "mapped to 0x%p\n", addr, real_addr, len, OpenPIC_Addr); | ||
891 | } | ||
892 | } | ||
893 | |||
894 | static void __init | ||
895 | ibm43p_pci_map_non0(struct pci_dev *dev) | ||
896 | { | ||
897 | unsigned char intpin; | ||
898 | static unsigned char bridge_intrs[4] = { 3, 4, 5, 8 }; | ||
899 | |||
900 | if (dev == NULL) | ||
901 | return; | ||
902 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &intpin); | ||
903 | if (intpin < 1 || intpin > 4) | ||
904 | return; | ||
905 | intpin = (PCI_SLOT(dev->devfn) + intpin - 1) & 3; | ||
906 | dev->irq = openpic_to_irq(bridge_intrs[intpin]); | ||
907 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
908 | } | ||
909 | |||
910 | void __init | ||
911 | prep_residual_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi) | ||
912 | { | ||
913 | if (have_residual_data) { | ||
914 | Motherboard_map_name = res->VitalProductData.PrintableModel; | ||
915 | Motherboard_map = NULL; | ||
916 | Motherboard_routes = NULL; | ||
917 | residual_irq_mask(irq_edge_mask_lo, irq_edge_mask_hi); | ||
918 | } | ||
919 | } | ||
920 | |||
921 | void __init | ||
922 | prep_sandalfoot_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi) | ||
923 | { | ||
924 | Motherboard_map_name = "IBM 6015/7020 (Sandalfoot/Sandalbow)"; | ||
925 | Motherboard_map = ibm6015_pci_IRQ_map; | ||
926 | Motherboard_routes = ibm6015_pci_IRQ_routes; | ||
927 | *irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */ | ||
928 | *irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */ | ||
929 | } | ||
930 | |||
931 | void __init | ||
932 | prep_thinkpad_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi) | ||
933 | { | ||
934 | Motherboard_map_name = "IBM Thinkpad 850/860"; | ||
935 | Motherboard_map = Nobis_pci_IRQ_map; | ||
936 | Motherboard_routes = Nobis_pci_IRQ_routes; | ||
937 | *irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */ | ||
938 | *irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */ | ||
939 | } | ||
940 | |||
941 | void __init | ||
942 | prep_carolina_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi) | ||
943 | { | ||
944 | Motherboard_map_name = "IBM 7248, PowerSeries 830/850 (Carolina)"; | ||
945 | Motherboard_map = ibm8xx_pci_IRQ_map; | ||
946 | Motherboard_routes = ibm8xx_pci_IRQ_routes; | ||
947 | *irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */ | ||
948 | *irq_edge_mask_hi = 0xA4; /* irq's 10, 13, 15 level-triggered */ | ||
949 | } | ||
950 | |||
951 | void __init | ||
952 | prep_tiger1_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi) | ||
953 | { | ||
954 | Motherboard_map_name = "IBM 43P-140 (Tiger1)"; | ||
955 | Motherboard_map = ibm43p_pci_IRQ_map; | ||
956 | Motherboard_routes = ibm43p_pci_IRQ_routes; | ||
957 | Motherboard_non0 = ibm43p_pci_map_non0; | ||
958 | *irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */ | ||
959 | *irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */ | ||
960 | } | ||
961 | |||
962 | void __init | ||
963 | prep_route_pci_interrupts(void) | ||
964 | { | ||
965 | unsigned char *ibc_pirq = (unsigned char *)0x80800860; | ||
966 | unsigned char *ibc_pcicon = (unsigned char *)0x80800840; | ||
967 | int i; | ||
968 | |||
969 | if ( _prep_type == _PREP_Motorola) | ||
970 | { | ||
971 | unsigned short irq_mode; | ||
972 | unsigned char cpu_type; | ||
973 | unsigned char base_mod; | ||
974 | int entry; | ||
975 | |||
976 | cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0; | ||
977 | base_mod = inb(MOTOROLA_BASETYPE_REG); | ||
978 | |||
979 | for (entry = 0; mot_info[entry].cpu_type != 0; entry++) { | ||
980 | if (mot_info[entry].cpu_type & 0x200) { /* Check for Hawk chip */ | ||
981 | if (!(MotMPIC & MOT_HAWK_PRESENT)) | ||
982 | continue; | ||
983 | } else { /* Check non hawk boards */ | ||
984 | if ((mot_info[entry].cpu_type & 0xff) != cpu_type) | ||
985 | continue; | ||
986 | |||
987 | if (mot_info[entry].base_type == 0) { | ||
988 | mot_entry = entry; | ||
989 | break; | ||
990 | } | ||
991 | |||
992 | if (mot_info[entry].base_type != base_mod) | ||
993 | continue; | ||
994 | } | ||
995 | |||
996 | if (!(mot_info[entry].max_cpu & 0x80)) { | ||
997 | mot_entry = entry; | ||
998 | break; | ||
999 | } | ||
1000 | |||
1001 | /* processor 1 not present and max processor zero indicated */ | ||
1002 | if ((*ProcInfo & MOT_PROC2_BIT) && !(mot_info[entry].max_cpu & 0x7f)) { | ||
1003 | mot_entry = entry; | ||
1004 | break; | ||
1005 | } | ||
1006 | |||
1007 | /* processor 1 present and max processor zero indicated */ | ||
1008 | if (!(*ProcInfo & MOT_PROC2_BIT) && (mot_info[entry].max_cpu & 0x7f)) { | ||
1009 | mot_entry = entry; | ||
1010 | break; | ||
1011 | } | ||
1012 | } | ||
1013 | |||
1014 | if (mot_entry == -1) /* No particular cpu type found - assume Blackhawk */ | ||
1015 | mot_entry = 3; | ||
1016 | |||
1017 | Motherboard_map_name = (unsigned char *)mot_info[mot_entry].name; | ||
1018 | Motherboard_map = mot_info[mot_entry].map; | ||
1019 | Motherboard_routes = mot_info[mot_entry].routes; | ||
1020 | Motherboard_non0 = mot_info[mot_entry].map_non0_bus; | ||
1021 | |||
1022 | if (!(mot_info[entry].cpu_type & 0x100)) { | ||
1023 | /* AJF adjust level/edge control according to routes */ | ||
1024 | irq_mode = 0; | ||
1025 | for (i = 1; i <= 4; i++) | ||
1026 | irq_mode |= ( 1 << Motherboard_routes[i] ); | ||
1027 | outb( irq_mode & 0xff, 0x4d0 ); | ||
1028 | outb( (irq_mode >> 8) & 0xff, 0x4d1 ); | ||
1029 | } | ||
1030 | } else if ( _prep_type == _PREP_IBM ) { | ||
1031 | unsigned char irq_edge_mask_lo, irq_edge_mask_hi; | ||
1032 | unsigned short irq_edge_mask; | ||
1033 | int i; | ||
1034 | |||
1035 | setup_ibm_pci(&irq_edge_mask_lo, &irq_edge_mask_hi); | ||
1036 | |||
1037 | outb(inb(0x04d0)|irq_edge_mask_lo, 0x4d0); /* primary 8259 */ | ||
1038 | outb(inb(0x04d1)|irq_edge_mask_hi, 0x4d1); /* cascaded 8259 */ | ||
1039 | |||
1040 | irq_edge_mask = (irq_edge_mask_hi << 8) | irq_edge_mask_lo; | ||
1041 | for (i = 0; i < 16; ++i, irq_edge_mask >>= 1) | ||
1042 | if (irq_edge_mask & 1) | ||
1043 | irq_desc[i].status |= IRQ_LEVEL; | ||
1044 | } else { | ||
1045 | printk("No known machine pci routing!\n"); | ||
1046 | return; | ||
1047 | } | ||
1048 | |||
1049 | /* Set up mapping from slots */ | ||
1050 | if (Motherboard_routes) { | ||
1051 | for (i = 1; i <= 4; i++) | ||
1052 | ibc_pirq[i-1] = Motherboard_routes[i]; | ||
1053 | |||
1054 | /* Enable PCI interrupts */ | ||
1055 | *ibc_pcicon |= 0x20; | ||
1056 | } | ||
1057 | } | ||
1058 | |||
1059 | void __init | ||
1060 | prep_pib_init(void) | ||
1061 | { | ||
1062 | unsigned char reg; | ||
1063 | unsigned short short_reg; | ||
1064 | |||
1065 | struct pci_dev *dev = NULL; | ||
1066 | |||
1067 | if (( _prep_type == _PREP_Motorola) && (OpenPIC_Addr)) { | ||
1068 | /* | ||
1069 | * Perform specific configuration for the Via Tech or | ||
1070 | * or Winbond PCI-ISA-Bridge part. | ||
1071 | */ | ||
1072 | if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, | ||
1073 | PCI_DEVICE_ID_VIA_82C586_1, dev))) { | ||
1074 | /* | ||
1075 | * PPCBUG does not set the enable bits | ||
1076 | * for the IDE device. Force them on here. | ||
1077 | */ | ||
1078 | pci_read_config_byte(dev, 0x40, ®); | ||
1079 | |||
1080 | reg |= 0x03; /* IDE: Chip Enable Bits */ | ||
1081 | pci_write_config_byte(dev, 0x40, reg); | ||
1082 | } | ||
1083 | if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, | ||
1084 | PCI_DEVICE_ID_VIA_82C586_2, | ||
1085 | dev)) && (dev->devfn = 0x5a)) { | ||
1086 | /* Force correct USB interrupt */ | ||
1087 | dev->irq = 11; | ||
1088 | pci_write_config_byte(dev, | ||
1089 | PCI_INTERRUPT_LINE, | ||
1090 | dev->irq); | ||
1091 | } | ||
1092 | if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND, | ||
1093 | PCI_DEVICE_ID_WINBOND_83C553, dev))) { | ||
1094 | /* Clear PCI Interrupt Routing Control Register. */ | ||
1095 | short_reg = 0x0000; | ||
1096 | pci_write_config_word(dev, 0x44, short_reg); | ||
1097 | if (OpenPIC_Addr){ | ||
1098 | /* Route IDE interrupts to IRQ 14 */ | ||
1099 | reg = 0xEE; | ||
1100 | pci_write_config_byte(dev, 0x43, reg); | ||
1101 | } | ||
1102 | } | ||
1103 | pci_dev_put(dev); | ||
1104 | } | ||
1105 | |||
1106 | if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND, | ||
1107 | PCI_DEVICE_ID_WINBOND_82C105, dev))){ | ||
1108 | if (OpenPIC_Addr){ | ||
1109 | /* | ||
1110 | * Disable LEGIRQ mode so PCI INTS are routed | ||
1111 | * directly to the 8259 and enable both channels | ||
1112 | */ | ||
1113 | pci_write_config_dword(dev, 0x40, 0x10ff0033); | ||
1114 | |||
1115 | /* Force correct IDE interrupt */ | ||
1116 | dev->irq = 14; | ||
1117 | pci_write_config_byte(dev, | ||
1118 | PCI_INTERRUPT_LINE, | ||
1119 | dev->irq); | ||
1120 | } else { | ||
1121 | /* Enable LEGIRQ for PCI INT -> 8259 IRQ routing */ | ||
1122 | pci_write_config_dword(dev, 0x40, 0x10ff08a1); | ||
1123 | } | ||
1124 | } | ||
1125 | pci_dev_put(dev); | ||
1126 | } | ||
1127 | |||
1128 | static void __init | ||
1129 | Powerplus_Map_Non0(struct pci_dev *dev) | ||
1130 | { | ||
1131 | struct pci_bus *pbus; /* Parent bus structure pointer */ | ||
1132 | struct pci_dev *tdev = dev; /* Temporary device structure */ | ||
1133 | unsigned int devnum; /* Accumulated device number */ | ||
1134 | unsigned char intline; /* Linux interrupt value */ | ||
1135 | unsigned char intpin; /* PCI interrupt pin */ | ||
1136 | |||
1137 | /* Check for valid PCI dev pointer */ | ||
1138 | if (dev == NULL) return; | ||
1139 | |||
1140 | /* Initialize bridge IDSEL variable */ | ||
1141 | devnum = PCI_SLOT(tdev->devfn); | ||
1142 | |||
1143 | /* Read the interrupt pin of the device and adjust for indexing */ | ||
1144 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &intpin); | ||
1145 | |||
1146 | /* If device doesn't request an interrupt, return */ | ||
1147 | if ( (intpin < 1) || (intpin > 4) ) | ||
1148 | return; | ||
1149 | |||
1150 | intpin--; | ||
1151 | |||
1152 | /* | ||
1153 | * Walk up to bus 0, adjusting the interrupt pin for the standard | ||
1154 | * PCI bus swizzle. | ||
1155 | */ | ||
1156 | do { | ||
1157 | intpin = (prep_pci_intpins[devnum % 4][intpin]) - 1; | ||
1158 | pbus = tdev->bus; /* up one level */ | ||
1159 | tdev = pbus->self; | ||
1160 | devnum = PCI_SLOT(tdev->devfn); | ||
1161 | } while(tdev->bus->number); | ||
1162 | |||
1163 | /* Use the primary interrupt inputs by default */ | ||
1164 | intline = mot_info[mot_entry].pci_irq_list->primary[intpin]; | ||
1165 | |||
1166 | /* | ||
1167 | * If the board has secondary interrupt inputs, walk the bus and | ||
1168 | * note the devfn of the bridge from bus 0. If it is the same as | ||
1169 | * the devfn of the bus bridge with secondary inputs, use those. | ||
1170 | * Otherwise, assume it's a PMC site and get the interrupt line | ||
1171 | * value from the interrupt routing table. | ||
1172 | */ | ||
1173 | if (mot_info[mot_entry].secondary_bridge_devfn) { | ||
1174 | pbus = dev->bus; | ||
1175 | |||
1176 | while (pbus->primary != 0) | ||
1177 | pbus = pbus->parent; | ||
1178 | |||
1179 | if ((pbus->self)->devfn != 0xA0) { | ||
1180 | if ((pbus->self)->devfn == mot_info[mot_entry].secondary_bridge_devfn) | ||
1181 | intline = mot_info[mot_entry].pci_irq_list->secondary[intpin]; | ||
1182 | else { | ||
1183 | if ((char *)(mot_info[mot_entry].map) == (char *)Mesquite_pci_IRQ_map) | ||
1184 | intline = mot_info[mot_entry].map[((pbus->self)->devfn)/8] + 16; | ||
1185 | else { | ||
1186 | int i; | ||
1187 | for (i=0;i<3;i++) | ||
1188 | intpin = (prep_pci_intpins[devnum % 4][intpin]) - 1; | ||
1189 | intline = mot_info[mot_entry].pci_irq_list->primary[intpin]; | ||
1190 | } | ||
1191 | } | ||
1192 | } | ||
1193 | } | ||
1194 | |||
1195 | /* Write calculated interrupt value to header and device list */ | ||
1196 | dev->irq = intline; | ||
1197 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, (u8)dev->irq); | ||
1198 | } | ||
1199 | |||
1200 | void __init | ||
1201 | prep_pcibios_fixup(void) | ||
1202 | { | ||
1203 | struct pci_dev *dev = NULL; | ||
1204 | int irq; | ||
1205 | int have_openpic = (OpenPIC_Addr != NULL); | ||
1206 | |||
1207 | prep_route_pci_interrupts(); | ||
1208 | |||
1209 | printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name); | ||
1210 | |||
1211 | /* Iterate through all the PCI devices, setting the IRQ */ | ||
1212 | for_each_pci_dev(dev) { | ||
1213 | /* | ||
1214 | * If we have residual data, then this is easy: query the | ||
1215 | * residual data for the IRQ line allocated to the device. | ||
1216 | * This works the same whether we have an OpenPic or not. | ||
1217 | */ | ||
1218 | if (have_residual_data) { | ||
1219 | irq = residual_pcidev_irq(dev); | ||
1220 | dev->irq = have_openpic ? openpic_to_irq(irq) : irq; | ||
1221 | } | ||
1222 | /* | ||
1223 | * If we don't have residual data, then we need to use | ||
1224 | * tables to determine the IRQ. The table organisation | ||
1225 | * is different depending on whether there is an OpenPIC | ||
1226 | * or not. The tables are only used for bus 0, so check | ||
1227 | * this first. | ||
1228 | */ | ||
1229 | else if (dev->bus->number == 0) { | ||
1230 | irq = Motherboard_map[PCI_SLOT(dev->devfn)]; | ||
1231 | dev->irq = have_openpic ? openpic_to_irq(irq) | ||
1232 | : Motherboard_routes[irq]; | ||
1233 | } | ||
1234 | /* | ||
1235 | * Finally, if we don't have residual data and the bus is | ||
1236 | * non-zero, use the callback (if provided) | ||
1237 | */ | ||
1238 | else { | ||
1239 | if (Motherboard_non0 != NULL) | ||
1240 | Motherboard_non0(dev); | ||
1241 | |||
1242 | continue; | ||
1243 | } | ||
1244 | |||
1245 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
1246 | } | ||
1247 | |||
1248 | /* Setup the Winbond or Via PIB */ | ||
1249 | prep_pib_init(); | ||
1250 | } | ||
1251 | |||
1252 | static void __init | ||
1253 | prep_pcibios_after_init(void) | ||
1254 | { | ||
1255 | #if 0 | ||
1256 | struct pci_dev *dev; | ||
1257 | |||
1258 | /* If there is a WD 90C, reset the IO BAR to 0x0 (it started that | ||
1259 | * way, but the PCI layer relocated it because it thought 0x0 was | ||
1260 | * invalid for a BAR). | ||
1261 | * If you don't do this, the card's VGA base will be <IO BAR>+0xc0000 | ||
1262 | * instead of 0xc0000. vgacon.c (for example) is completely unaware of | ||
1263 | * this little quirk. | ||
1264 | */ | ||
1265 | dev = pci_get_device(PCI_VENDOR_ID_WD, PCI_DEVICE_ID_WD_90C, NULL); | ||
1266 | if (dev) { | ||
1267 | dev->resource[1].end -= dev->resource[1].start; | ||
1268 | dev->resource[1].start = 0; | ||
1269 | /* tell the hardware */ | ||
1270 | pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0x0); | ||
1271 | pci_dev_put(dev); | ||
1272 | } | ||
1273 | #endif | ||
1274 | } | ||
1275 | |||
1276 | static void __init | ||
1277 | prep_init_resource(struct resource *res, unsigned long start, | ||
1278 | unsigned long end, int flags) | ||
1279 | { | ||
1280 | res->flags = flags; | ||
1281 | res->start = start; | ||
1282 | res->end = end; | ||
1283 | res->name = "PCI host bridge"; | ||
1284 | res->parent = NULL; | ||
1285 | res->sibling = NULL; | ||
1286 | res->child = NULL; | ||
1287 | } | ||
1288 | |||
1289 | void __init | ||
1290 | prep_find_bridges(void) | ||
1291 | { | ||
1292 | struct pci_controller* hose; | ||
1293 | |||
1294 | hose = pcibios_alloc_controller(); | ||
1295 | if (!hose) | ||
1296 | return; | ||
1297 | |||
1298 | hose->first_busno = 0; | ||
1299 | hose->last_busno = 0xff; | ||
1300 | hose->pci_mem_offset = PREP_ISA_MEM_BASE; | ||
1301 | hose->io_base_phys = PREP_ISA_IO_BASE; | ||
1302 | hose->io_base_virt = ioremap(PREP_ISA_IO_BASE, 0x800000); | ||
1303 | prep_init_resource(&hose->io_resource, 0, 0x007fffff, IORESOURCE_IO); | ||
1304 | prep_init_resource(&hose->mem_resources[0], 0xc0000000, 0xfeffffff, | ||
1305 | IORESOURCE_MEM); | ||
1306 | setup_indirect_pci(hose, PREP_ISA_IO_BASE + 0xcf8, | ||
1307 | PREP_ISA_IO_BASE + 0xcfc); | ||
1308 | |||
1309 | printk("PReP architecture\n"); | ||
1310 | |||
1311 | if (have_residual_data) { | ||
1312 | PPC_DEVICE *hostbridge; | ||
1313 | |||
1314 | hostbridge = residual_find_device(PROCESSORDEVICE, NULL, | ||
1315 | BridgeController, PCIBridge, -1, 0); | ||
1316 | if (hostbridge && | ||
1317 | ((hostbridge->DeviceId.Interface == PCIBridgeIndirect) || | ||
1318 | (hostbridge->DeviceId.Interface == PCIBridgeRS6K))) { | ||
1319 | PnP_TAG_PACKET * pkt; | ||
1320 | pkt = PnP_find_large_vendor_packet( | ||
1321 | res->DevicePnPHeap+hostbridge->AllocatedOffset, | ||
1322 | 3, 0); | ||
1323 | if(pkt) { | ||
1324 | #define p pkt->L4_Pack.L4_Data.L4_PPCPack | ||
1325 | setup_indirect_pci(hose, | ||
1326 | ld_le32((unsigned *) (p.PPCData)), | ||
1327 | ld_le32((unsigned *) (p.PPCData+8))); | ||
1328 | #undef p | ||
1329 | } else | ||
1330 | setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc); | ||
1331 | } | ||
1332 | } | ||
1333 | |||
1334 | ppc_md.pcibios_fixup = prep_pcibios_fixup; | ||
1335 | ppc_md.pcibios_after_init = prep_pcibios_after_init; | ||
1336 | } | ||