1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/mm.h>
17#include <linux/sched.h>
18#include <linux/pci.h>
19#include <linux/init.h>
20#include <linux/screen_info.h>
21
22#include <asm/compiler.h>
23#include <asm/ptrace.h>
24#include <asm/dma.h>
25#include <asm/irq.h>
26#include <asm/mmu_context.h>
27#include <asm/io.h>
28#include <asm/core_apecs.h>
29#include <asm/core_lca.h>
30#include <asm/tlbflush.h>
31
32#include "proto.h"
33#include "irq_impl.h"
34#include "pci_impl.h"
35#include "machvec_impl.h"
36#include "pc873xx.h"
37
38#if defined(ALPHA_RESTORE_SRM_SETUP)
39
40struct
41{
42 unsigned int orig_route_tab;
43} saved_config __attribute((common));
44#endif
45
46
47static void __init
48sio_init_irq(void)
49{
50 if (alpha_using_srm)
51 alpha_mv.device_interrupt = srm_device_interrupt;
52
53 init_i8259a_irqs();
54 common_init_isa_dma();
55}
56
57static inline void __init
58alphabook1_init_arch(void)
59{
60
61
62 screen_info.orig_y = 37;
63 screen_info.orig_video_cols = 100;
64 screen_info.orig_video_lines = 37;
65
66 lca_init_arch();
67}
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84static void __init
85sio_pci_route(void)
86{
87 unsigned int orig_route_tab;
88
89
90 pci_bus_read_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
91 &orig_route_tab);
92 printk("%s: PIRQ original 0x%x new 0x%x\n", __func__,
93 orig_route_tab, alpha_mv.sys.sio.route_tab);
94
95#if defined(ALPHA_RESTORE_SRM_SETUP)
96 saved_config.orig_route_tab = orig_route_tab;
97#endif
98
99
100 pci_bus_write_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
101 alpha_mv.sys.sio.route_tab);
102}
103
104static bool sio_pci_dev_irq_needs_level(const struct pci_dev *dev)
105{
106 if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&
107 (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))
108 return false;
109
110 return true;
111}
112
113static unsigned int __init
114sio_collect_irq_levels(void)
115{
116 unsigned int level_bits = 0;
117 struct pci_dev *dev = NULL;
118
119
120 for_each_pci_dev(dev) {
121 if (!sio_pci_dev_irq_needs_level(dev))
122 continue;
123
124 if (dev->irq)
125 level_bits |= (1 << dev->irq);
126 }
127 return level_bits;
128}
129
130static void __sio_fixup_irq_levels(unsigned int level_bits, bool reset)
131{
132 unsigned int old_level_bits;
133
134
135
136
137
138
139
140
141
142
143
144
145
146 old_level_bits = inb(0x4d0) | (inb(0x4d1) << 8);
147
148 if (reset)
149 old_level_bits &= 0x71ff;
150
151 level_bits |= old_level_bits;
152
153 outb((level_bits >> 0) & 0xff, 0x4d0);
154 outb((level_bits >> 8) & 0xff, 0x4d1);
155}
156
157static inline void
158sio_fixup_irq_levels(unsigned int level_bits)
159{
160 __sio_fixup_irq_levels(level_bits, true);
161}
162
163static inline int
164noname_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
165{
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184 static char irq_tab[][5] = {
185
186 { 3, 3, 3, 3, 3},
187 {-1, -1, -1, -1, -1},
188 { 2, 2, -1, -1, -1},
189 {-1, -1, -1, -1, -1},
190 {-1, -1, -1, -1, -1},
191 { 0, 0, 2, 1, 0},
192 { 1, 1, 0, 2, 1},
193 { 2, 2, 1, 0, 2},
194 { 0, 0, 0, 0, 0},
195 };
196 const long min_idsel = 6, max_idsel = 14, irqs_per_slot = 5;
197 int irq = COMMON_TABLE_LOOKUP, tmp;
198 tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq);
199
200 irq = irq >= 0 ? tmp : -1;
201
202
203 if (sio_pci_dev_irq_needs_level(dev) && irq >= 0)
204 __sio_fixup_irq_levels(1 << irq, false);
205
206 return irq;
207}
208
209static inline int
210p2k_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
211{
212 static char irq_tab[][5] = {
213
214 { 0, 0, -1, -1, -1},
215 {-1, -1, -1, -1, -1},
216 { 1, 1, 2, 3, 0},
217 { 2, 2, 3, 0, 1},
218 {-1, -1, -1, -1, -1},
219 {-1, -1, -1, -1, -1},
220 { 3, 3, -1, -1, -1},
221 };
222 const long min_idsel = 6, max_idsel = 12, irqs_per_slot = 5;
223 int irq = COMMON_TABLE_LOOKUP, tmp;
224 tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq);
225 return irq >= 0 ? tmp : -1;
226}
227
228static inline void __init
229noname_init_pci(void)
230{
231 common_init_pci();
232 sio_pci_route();
233 sio_fixup_irq_levels(sio_collect_irq_levels());
234
235 if (pc873xx_probe() == -1) {
236 printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n");
237 } else {
238 printk(KERN_INFO "Found %s Super IO chip at 0x%x\n",
239 pc873xx_get_model(), pc873xx_get_base());
240
241
242
243
244
245
246
247#if !defined(CONFIG_ALPHA_AVANTI)
248
249
250
251 pc873xx_enable_ide();
252#endif
253 pc873xx_enable_epp19();
254 }
255}
256
257static inline void __init
258alphabook1_init_pci(void)
259{
260 struct pci_dev *dev;
261 unsigned char orig, config;
262
263 common_init_pci();
264 sio_pci_route();
265
266
267
268
269
270
271
272
273
274
275
276
277 dev = NULL;
278 while ((dev = pci_get_device(PCI_VENDOR_ID_NCR, PCI_ANY_ID, dev))) {
279 if (dev->device == PCI_DEVICE_ID_NCR_53C810
280 || dev->device == PCI_DEVICE_ID_NCR_53C815
281 || dev->device == PCI_DEVICE_ID_NCR_53C820
282 || dev->device == PCI_DEVICE_ID_NCR_53C825) {
283 unsigned long io_port;
284 unsigned char ctest4;
285
286 io_port = dev->resource[0].start;
287 ctest4 = inb(io_port+0x21);
288 if (!(ctest4 & 0x80)) {
289 printk("AlphaBook1 NCR init: setting"
290 " burst disable\n");
291 outb(ctest4 | 0x80, io_port+0x21);
292 }
293 }
294 }
295
296
297 sio_fixup_irq_levels(0);
298
299
300 outb(0x0f, 0x3ce); orig = inb(0x3cf);
301 outb(0x0f, 0x3ce); outb(0x05, 0x3cf);
302 outb(0x0b, 0x3ce); config = inb(0x3cf);
303 if ((config & 0xc0) != 0xc0) {
304 printk("AlphaBook1 VGA init: setting 1Mb memory\n");
305 config |= 0xc0;
306 outb(0x0b, 0x3ce); outb(config, 0x3cf);
307 }
308 outb(0x0f, 0x3ce); outb(orig, 0x3cf);
309}
310
311void
312sio_kill_arch(int mode)
313{
314#if defined(ALPHA_RESTORE_SRM_SETUP)
315
316
317
318
319
320
321 pci_bus_write_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
322 saved_config.orig_route_tab);
323#endif
324}
325
326
327
328
329
330
331#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_BOOK1)
332struct alpha_machine_vector alphabook1_mv __initmv = {
333 .vector_name = "AlphaBook1",
334 DO_EV4_MMU,
335 DO_DEFAULT_RTC,
336 DO_LCA_IO,
337 .machine_check = lca_machine_check,
338 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
339 .min_io_address = DEFAULT_IO_BASE,
340 .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
341
342 .nr_irqs = 16,
343 .device_interrupt = isa_device_interrupt,
344
345 .init_arch = alphabook1_init_arch,
346 .init_irq = sio_init_irq,
347 .init_rtc = common_init_rtc,
348 .init_pci = alphabook1_init_pci,
349 .kill_arch = sio_kill_arch,
350 .pci_map_irq = noname_map_irq,
351 .pci_swizzle = common_swizzle,
352
353 .sys = { .sio = {
354
355 .route_tab = 0x0e0f0a0a,
356 }}
357};
358ALIAS_MV(alphabook1)
359#endif
360
361#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_AVANTI)
362struct alpha_machine_vector avanti_mv __initmv = {
363 .vector_name = "Avanti",
364 DO_EV4_MMU,
365 DO_DEFAULT_RTC,
366 DO_APECS_IO,
367 .machine_check = apecs_machine_check,
368 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
369 .min_io_address = DEFAULT_IO_BASE,
370 .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
371
372 .nr_irqs = 16,
373 .device_interrupt = isa_device_interrupt,
374
375 .init_arch = apecs_init_arch,
376 .init_irq = sio_init_irq,
377 .init_rtc = common_init_rtc,
378 .init_pci = noname_init_pci,
379 .kill_arch = sio_kill_arch,
380 .pci_map_irq = noname_map_irq,
381 .pci_swizzle = common_swizzle,
382
383 .sys = { .sio = {
384 .route_tab = 0x0b0a050f,
385 }}
386};
387ALIAS_MV(avanti)
388#endif
389
390#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_NONAME)
391struct alpha_machine_vector noname_mv __initmv = {
392 .vector_name = "Noname",
393 DO_EV4_MMU,
394 DO_DEFAULT_RTC,
395 DO_LCA_IO,
396 .machine_check = lca_machine_check,
397 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
398 .min_io_address = DEFAULT_IO_BASE,
399 .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
400
401 .nr_irqs = 16,
402 .device_interrupt = srm_device_interrupt,
403
404 .init_arch = lca_init_arch,
405 .init_irq = sio_init_irq,
406 .init_rtc = common_init_rtc,
407 .init_pci = noname_init_pci,
408 .kill_arch = sio_kill_arch,
409 .pci_map_irq = noname_map_irq,
410 .pci_swizzle = common_swizzle,
411
412 .sys = { .sio = {
413
414
415
416
417
418
419
420
421
422 .route_tab = 0x0b0a0f0d,
423 }}
424};
425ALIAS_MV(noname)
426#endif
427
428#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_P2K)
429struct alpha_machine_vector p2k_mv __initmv = {
430 .vector_name = "Platform2000",
431 DO_EV4_MMU,
432 DO_DEFAULT_RTC,
433 DO_LCA_IO,
434 .machine_check = lca_machine_check,
435 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
436 .min_io_address = DEFAULT_IO_BASE,
437 .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
438
439 .nr_irqs = 16,
440 .device_interrupt = srm_device_interrupt,
441
442 .init_arch = lca_init_arch,
443 .init_irq = sio_init_irq,
444 .init_rtc = common_init_rtc,
445 .init_pci = noname_init_pci,
446 .kill_arch = sio_kill_arch,
447 .pci_map_irq = p2k_map_irq,
448 .pci_swizzle = common_swizzle,
449
450 .sys = { .sio = {
451 .route_tab = 0x0b0a090f,
452 }}
453};
454ALIAS_MV(p2k)
455#endif
456
457#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_XL)
458struct alpha_machine_vector xl_mv __initmv = {
459 .vector_name = "XL",
460 DO_EV4_MMU,
461 DO_DEFAULT_RTC,
462 DO_APECS_IO,
463 .machine_check = apecs_machine_check,
464 .max_isa_dma_address = ALPHA_XL_MAX_ISA_DMA_ADDRESS,
465 .min_io_address = DEFAULT_IO_BASE,
466 .min_mem_address = XL_DEFAULT_MEM_BASE,
467
468 .nr_irqs = 16,
469 .device_interrupt = isa_device_interrupt,
470
471 .init_arch = apecs_init_arch,
472 .init_irq = sio_init_irq,
473 .init_rtc = common_init_rtc,
474 .init_pci = noname_init_pci,
475 .kill_arch = sio_kill_arch,
476 .pci_map_irq = noname_map_irq,
477 .pci_swizzle = common_swizzle,
478
479 .sys = { .sio = {
480 .route_tab = 0x0b0a090f,
481 }}
482};
483ALIAS_MV(xl)
484#endif
485