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