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