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