1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/mm.h>
18#include <linux/sched.h>
19#include <linux/pci.h>
20#include <linux/init.h>
21#include <linux/bitops.h>
22
23#include <asm/ptrace.h>
24#include <asm/system.h>
25#include <asm/dma.h>
26#include <asm/irq.h>
27#include <asm/mmu_context.h>
28#include <asm/io.h>
29#include <asm/pgtable.h>
30#include <asm/core_tsunami.h>
31#include <asm/hwrpb.h>
32#include <asm/tlbflush.h>
33
34#include "proto.h"
35#include "irq_impl.h"
36#include "pci_impl.h"
37#include "machvec_impl.h"
38
39
40
41static unsigned long cached_irq_mask;
42
43static unsigned long cpu_irq_affinity[4] = { 0UL, 0UL, 0UL, 0UL };
44
45DEFINE_SPINLOCK(dp264_irq_lock);
46
47static void
48tsunami_update_irq_hw(unsigned long mask)
49{
50 register tsunami_cchip *cchip = TSUNAMI_cchip;
51 unsigned long isa_enable = 1UL << 55;
52 register int bcpu = boot_cpuid;
53
54#ifdef CONFIG_SMP
55 volatile unsigned long *dim0, *dim1, *dim2, *dim3;
56 unsigned long mask0, mask1, mask2, mask3, dummy;
57
58 mask &= ~isa_enable;
59 mask0 = mask & cpu_irq_affinity[0];
60 mask1 = mask & cpu_irq_affinity[1];
61 mask2 = mask & cpu_irq_affinity[2];
62 mask3 = mask & cpu_irq_affinity[3];
63
64 if (bcpu == 0) mask0 |= isa_enable;
65 else if (bcpu == 1) mask1 |= isa_enable;
66 else if (bcpu == 2) mask2 |= isa_enable;
67 else mask3 |= isa_enable;
68
69 dim0 = &cchip->dim0.csr;
70 dim1 = &cchip->dim1.csr;
71 dim2 = &cchip->dim2.csr;
72 dim3 = &cchip->dim3.csr;
73 if (!cpu_possible(0)) dim0 = &dummy;
74 if (!cpu_possible(1)) dim1 = &dummy;
75 if (!cpu_possible(2)) dim2 = &dummy;
76 if (!cpu_possible(3)) dim3 = &dummy;
77
78 *dim0 = mask0;
79 *dim1 = mask1;
80 *dim2 = mask2;
81 *dim3 = mask3;
82 mb();
83 *dim0;
84 *dim1;
85 *dim2;
86 *dim3;
87#else
88 volatile unsigned long *dimB;
89 if (bcpu == 0) dimB = &cchip->dim0.csr;
90 else if (bcpu == 1) dimB = &cchip->dim1.csr;
91 else if (bcpu == 2) dimB = &cchip->dim2.csr;
92 else dimB = &cchip->dim3.csr;
93
94 *dimB = mask | isa_enable;
95 mb();
96 *dimB;
97#endif
98}
99
100static void
101dp264_enable_irq(unsigned int irq)
102{
103 spin_lock(&dp264_irq_lock);
104 cached_irq_mask |= 1UL << irq;
105 tsunami_update_irq_hw(cached_irq_mask);
106 spin_unlock(&dp264_irq_lock);
107}
108
109static void
110dp264_disable_irq(unsigned int irq)
111{
112 spin_lock(&dp264_irq_lock);
113 cached_irq_mask &= ~(1UL << irq);
114 tsunami_update_irq_hw(cached_irq_mask);
115 spin_unlock(&dp264_irq_lock);
116}
117
118static unsigned int
119dp264_startup_irq(unsigned int irq)
120{
121 dp264_enable_irq(irq);
122 return 0;
123}
124
125static void
126dp264_end_irq(unsigned int irq)
127{
128 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
129 dp264_enable_irq(irq);
130}
131
132static void
133clipper_enable_irq(unsigned int irq)
134{
135 spin_lock(&dp264_irq_lock);
136 cached_irq_mask |= 1UL << (irq - 16);
137 tsunami_update_irq_hw(cached_irq_mask);
138 spin_unlock(&dp264_irq_lock);
139}
140
141static void
142clipper_disable_irq(unsigned int irq)
143{
144 spin_lock(&dp264_irq_lock);
145 cached_irq_mask &= ~(1UL << (irq - 16));
146 tsunami_update_irq_hw(cached_irq_mask);
147 spin_unlock(&dp264_irq_lock);
148}
149
150static unsigned int
151clipper_startup_irq(unsigned int irq)
152{
153 clipper_enable_irq(irq);
154 return 0;
155}
156
157static void
158clipper_end_irq(unsigned int irq)
159{
160 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
161 clipper_enable_irq(irq);
162}
163
164static void
165cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
166{
167 int cpu;
168
169 for (cpu = 0; cpu < 4; cpu++) {
170 unsigned long aff = cpu_irq_affinity[cpu];
171 if (cpu_isset(cpu, affinity))
172 aff |= 1UL << irq;
173 else
174 aff &= ~(1UL << irq);
175 cpu_irq_affinity[cpu] = aff;
176 }
177}
178
179static int
180dp264_set_affinity(unsigned int irq, const struct cpumask *affinity)
181{
182 spin_lock(&dp264_irq_lock);
183 cpu_set_irq_affinity(irq, *affinity);
184 tsunami_update_irq_hw(cached_irq_mask);
185 spin_unlock(&dp264_irq_lock);
186
187 return 0;
188}
189
190static int
191clipper_set_affinity(unsigned int irq, const struct cpumask *affinity)
192{
193 spin_lock(&dp264_irq_lock);
194 cpu_set_irq_affinity(irq - 16, *affinity);
195 tsunami_update_irq_hw(cached_irq_mask);
196 spin_unlock(&dp264_irq_lock);
197
198 return 0;
199}
200
201static struct irq_chip dp264_irq_type = {
202 .name = "DP264",
203 .startup = dp264_startup_irq,
204 .shutdown = dp264_disable_irq,
205 .enable = dp264_enable_irq,
206 .disable = dp264_disable_irq,
207 .ack = dp264_disable_irq,
208 .end = dp264_end_irq,
209 .set_affinity = dp264_set_affinity,
210};
211
212static struct irq_chip clipper_irq_type = {
213 .name = "CLIPPER",
214 .startup = clipper_startup_irq,
215 .shutdown = clipper_disable_irq,
216 .enable = clipper_enable_irq,
217 .disable = clipper_disable_irq,
218 .ack = clipper_disable_irq,
219 .end = clipper_end_irq,
220 .set_affinity = clipper_set_affinity,
221};
222
223static void
224dp264_device_interrupt(unsigned long vector)
225{
226#if 1
227 printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n");
228#else
229 unsigned long pld;
230 unsigned int i;
231
232
233 pld = TSUNAMI_cchip->dir0.csr;
234
235
236
237
238
239 while (pld) {
240 i = ffz(~pld);
241 pld &= pld - 1;
242 if (i == 55)
243 isa_device_interrupt(vector);
244 else
245 handle_irq(16 + i);
246#if 0
247 TSUNAMI_cchip->dir0.csr = 1UL << i; mb();
248 tmp = TSUNAMI_cchip->dir0.csr;
249#endif
250 }
251#endif
252}
253
254static void
255dp264_srm_device_interrupt(unsigned long vector)
256{
257 int irq;
258
259 irq = (vector - 0x800) >> 4;
260
261
262
263
264
265
266
267
268
269
270
271
272 if (irq >= 32)
273 irq -= 16;
274
275 handle_irq(irq);
276}
277
278static void
279clipper_srm_device_interrupt(unsigned long vector)
280{
281 int irq;
282
283 irq = (vector - 0x800) >> 4;
284
285
286
287
288
289
290
291
292
293
294
295
296
297 handle_irq(irq);
298}
299
300static void __init
301init_tsunami_irqs(struct irq_chip * ops, int imin, int imax)
302{
303 long i;
304 for (i = imin; i <= imax; ++i) {
305 irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
306 irq_desc[i].chip = ops;
307 }
308}
309
310static void __init
311dp264_init_irq(void)
312{
313 outb(0, DMA1_RESET_REG);
314 outb(0, DMA2_RESET_REG);
315 outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
316 outb(0, DMA2_MASK_REG);
317
318 if (alpha_using_srm)
319 alpha_mv.device_interrupt = dp264_srm_device_interrupt;
320
321 tsunami_update_irq_hw(0);
322
323 init_i8259a_irqs();
324 init_tsunami_irqs(&dp264_irq_type, 16, 47);
325}
326
327static void __init
328clipper_init_irq(void)
329{
330 outb(0, DMA1_RESET_REG);
331 outb(0, DMA2_RESET_REG);
332 outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
333 outb(0, DMA2_MASK_REG);
334
335 if (alpha_using_srm)
336 alpha_mv.device_interrupt = clipper_srm_device_interrupt;
337
338 tsunami_update_irq_hw(0);
339
340 init_i8259a_irqs();
341 init_tsunami_irqs(&clipper_irq_type, 24, 63);
342}
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400static int __init
401isa_irq_fixup(struct pci_dev *dev, int irq)
402{
403 u8 irq8;
404
405 if (irq > 0)
406 return irq;
407
408
409
410
411 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);
412
413 return irq8 & 0xf;
414}
415
416static int __init
417dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
418{
419 static char irq_tab[6][5] __initdata = {
420
421 { -1, -1, -1, -1, -1},
422 { 16+ 3, 16+ 3, 16+ 2, 16+ 2, 16+ 2},
423 { 16+15, 16+15, 16+14, 16+13, 16+12},
424 { 16+11, 16+11, 16+10, 16+ 9, 16+ 8},
425 { 16+ 7, 16+ 7, 16+ 6, 16+ 5, 16+ 4},
426 { 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0}
427 };
428 const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;
429 struct pci_controller *hose = dev->sysdata;
430 int irq = COMMON_TABLE_LOOKUP;
431
432 if (irq > 0)
433 irq += 16 * hose->index;
434
435 return isa_irq_fixup(dev, irq);
436}
437
438static int __init
439monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
440{
441 static char irq_tab[13][5] __initdata = {
442
443 { 45, 45, 45, 45, 45},
444 { -1, -1, -1, -1, -1},
445 { -1, -1, -1, -1, -1},
446 { 47, 47, 47, 47, 47},
447 { -1, -1, -1, -1, -1},
448 { -1, -1, -1, -1, -1},
449#if 1
450 { 28, 28, 29, 30, 31},
451 { 24, 24, 25, 26, 27},
452#else
453 { -1, -1, -1, -1, -1},
454 { -1, -1, -1, -1, -1},
455#endif
456 { 40, 40, 41, 42, 43},
457 { 36, 36, 37, 38, 39},
458 { 32, 32, 33, 34, 35},
459 { 28, 28, 29, 30, 31},
460 { 24, 24, 25, 26, 27}
461 };
462 const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5;
463
464 return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
465}
466
467static u8 __init
468monet_swizzle(struct pci_dev *dev, u8 *pinp)
469{
470 struct pci_controller *hose = dev->sysdata;
471 int slot, pin = *pinp;
472
473 if (!dev->bus->parent) {
474 slot = PCI_SLOT(dev->devfn);
475 }
476
477 else if (hose->index == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) {
478 slot = PCI_SLOT(dev->devfn);
479 } else {
480
481 do {
482
483 if (hose->index == 1 &&
484 PCI_SLOT(dev->bus->self->devfn) == 8) {
485 slot = PCI_SLOT(dev->devfn);
486 break;
487 }
488 pin = pci_swizzle_interrupt_pin(dev, pin);
489
490
491 dev = dev->bus->self;
492
493 slot = PCI_SLOT(dev->devfn);
494 } while (dev->bus->self);
495 }
496 *pinp = pin;
497 return slot;
498}
499
500static int __init
501webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
502{
503 static char irq_tab[13][5] __initdata = {
504
505 { -1, -1, -1, -1, -1},
506 { -1, -1, -1, -1, -1},
507 { 29, 29, 29, 29, 29},
508 { -1, -1, -1, -1, -1},
509 { 30, 30, 30, 30, 30},
510 { -1, -1, -1, -1, -1},
511 { -1, -1, -1, -1, -1},
512 { 35, 35, 34, 33, 32},
513 { 39, 39, 38, 37, 36},
514 { 43, 43, 42, 41, 40},
515 { 47, 47, 46, 45, 44},
516 };
517 const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5;
518
519 return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
520}
521
522static int __init
523clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
524{
525 static char irq_tab[7][5] __initdata = {
526
527 { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11},
528 { 16+12, 16+12, 16+13, 16+14, 16+15},
529 { 16+16, 16+16, 16+17, 16+18, 16+19},
530 { 16+20, 16+20, 16+21, 16+22, 16+23},
531 { 16+24, 16+24, 16+25, 16+26, 16+27},
532 { 16+28, 16+28, 16+29, 16+30, 16+31},
533 { -1, -1, -1, -1, -1}
534 };
535 const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5;
536 struct pci_controller *hose = dev->sysdata;
537 int irq = COMMON_TABLE_LOOKUP;
538
539 if (irq > 0)
540 irq += 16 * hose->index;
541
542 return isa_irq_fixup(dev, irq);
543}
544
545static void __init
546dp264_init_pci(void)
547{
548 common_init_pci();
549 SMC669_Init(0);
550 locate_and_init_vga(NULL);
551}
552
553static void __init
554monet_init_pci(void)
555{
556 common_init_pci();
557 SMC669_Init(1);
558 es1888_init();
559 locate_and_init_vga(NULL);
560}
561
562static void __init
563clipper_init_pci(void)
564{
565 common_init_pci();
566 locate_and_init_vga(NULL);
567}
568
569static void __init
570webbrick_init_arch(void)
571{
572 tsunami_init_arch();
573
574
575 hose_head->sg_isa->align_entry = 4;
576 hose_head->sg_pci->align_entry = 4;
577}
578
579
580
581
582
583
584struct alpha_machine_vector dp264_mv __initmv = {
585 .vector_name = "DP264",
586 DO_EV6_MMU,
587 DO_DEFAULT_RTC,
588 DO_TSUNAMI_IO,
589 .machine_check = tsunami_machine_check,
590 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
591 .min_io_address = DEFAULT_IO_BASE,
592 .min_mem_address = DEFAULT_MEM_BASE,
593 .pci_dac_offset = TSUNAMI_DAC_OFFSET,
594
595 .nr_irqs = 64,
596 .device_interrupt = dp264_device_interrupt,
597
598 .init_arch = tsunami_init_arch,
599 .init_irq = dp264_init_irq,
600 .init_rtc = common_init_rtc,
601 .init_pci = dp264_init_pci,
602 .kill_arch = tsunami_kill_arch,
603 .pci_map_irq = dp264_map_irq,
604 .pci_swizzle = common_swizzle,
605};
606ALIAS_MV(dp264)
607
608struct alpha_machine_vector monet_mv __initmv = {
609 .vector_name = "Monet",
610 DO_EV6_MMU,
611 DO_DEFAULT_RTC,
612 DO_TSUNAMI_IO,
613 .machine_check = tsunami_machine_check,
614 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
615 .min_io_address = DEFAULT_IO_BASE,
616 .min_mem_address = DEFAULT_MEM_BASE,
617 .pci_dac_offset = TSUNAMI_DAC_OFFSET,
618
619 .nr_irqs = 64,
620 .device_interrupt = dp264_device_interrupt,
621
622 .init_arch = tsunami_init_arch,
623 .init_irq = dp264_init_irq,
624 .init_rtc = common_init_rtc,
625 .init_pci = monet_init_pci,
626 .kill_arch = tsunami_kill_arch,
627 .pci_map_irq = monet_map_irq,
628 .pci_swizzle = monet_swizzle,
629};
630
631struct alpha_machine_vector webbrick_mv __initmv = {
632 .vector_name = "Webbrick",
633 DO_EV6_MMU,
634 DO_DEFAULT_RTC,
635 DO_TSUNAMI_IO,
636 .machine_check = tsunami_machine_check,
637 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
638 .min_io_address = DEFAULT_IO_BASE,
639 .min_mem_address = DEFAULT_MEM_BASE,
640 .pci_dac_offset = TSUNAMI_DAC_OFFSET,
641
642 .nr_irqs = 64,
643 .device_interrupt = dp264_device_interrupt,
644
645 .init_arch = webbrick_init_arch,
646 .init_irq = dp264_init_irq,
647 .init_rtc = common_init_rtc,
648 .init_pci = common_init_pci,
649 .kill_arch = tsunami_kill_arch,
650 .pci_map_irq = webbrick_map_irq,
651 .pci_swizzle = common_swizzle,
652};
653
654struct alpha_machine_vector clipper_mv __initmv = {
655 .vector_name = "Clipper",
656 DO_EV6_MMU,
657 DO_DEFAULT_RTC,
658 DO_TSUNAMI_IO,
659 .machine_check = tsunami_machine_check,
660 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
661 .min_io_address = DEFAULT_IO_BASE,
662 .min_mem_address = DEFAULT_MEM_BASE,
663 .pci_dac_offset = TSUNAMI_DAC_OFFSET,
664
665 .nr_irqs = 64,
666 .device_interrupt = dp264_device_interrupt,
667
668 .init_arch = tsunami_init_arch,
669 .init_irq = clipper_init_irq,
670 .init_rtc = common_init_rtc,
671 .init_pci = clipper_init_pci,
672 .kill_arch = tsunami_kill_arch,
673 .pci_map_irq = clipper_map_irq,
674 .pci_swizzle = common_swizzle,
675};
676
677
678
679
680
681
682struct alpha_machine_vector shark_mv __initmv = {
683 .vector_name = "Shark",
684 DO_EV6_MMU,
685 DO_DEFAULT_RTC,
686 DO_TSUNAMI_IO,
687 .machine_check = tsunami_machine_check,
688 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
689 .min_io_address = DEFAULT_IO_BASE,
690 .min_mem_address = DEFAULT_MEM_BASE,
691 .pci_dac_offset = TSUNAMI_DAC_OFFSET,
692
693 .nr_irqs = 64,
694 .device_interrupt = dp264_device_interrupt,
695
696 .init_arch = tsunami_init_arch,
697 .init_irq = clipper_init_irq,
698 .init_rtc = common_init_rtc,
699 .init_pci = common_init_pci,
700 .kill_arch = tsunami_kill_arch,
701 .pci_map_irq = clipper_map_irq,
702 .pci_swizzle = common_swizzle,
703};
704
705
706
707