11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/arch/alpha/kernel/sys_dp264.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 1995 David A Rusling 51da177e4SLinus Torvalds * Copyright (C) 1996, 1999 Jay A Estabrook 61da177e4SLinus Torvalds * Copyright (C) 1998, 1999 Richard Henderson 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * Modified by Christopher C. Chimelis, 2001 to 91da177e4SLinus Torvalds * add support for the addition of Shark to the 101da177e4SLinus Torvalds * Tsunami family. 111da177e4SLinus Torvalds * 121da177e4SLinus Torvalds * Code supporting the DP264 (EV6+TSUNAMI). 131da177e4SLinus Torvalds */ 141da177e4SLinus Torvalds 151da177e4SLinus Torvalds #include <linux/kernel.h> 161da177e4SLinus Torvalds #include <linux/types.h> 171da177e4SLinus Torvalds #include <linux/mm.h> 181da177e4SLinus Torvalds #include <linux/sched.h> 191da177e4SLinus Torvalds #include <linux/pci.h> 201da177e4SLinus Torvalds #include <linux/init.h> 211da177e4SLinus Torvalds #include <linux/bitops.h> 221da177e4SLinus Torvalds 231da177e4SLinus Torvalds #include <asm/ptrace.h> 241da177e4SLinus Torvalds #include <asm/dma.h> 251da177e4SLinus Torvalds #include <asm/irq.h> 261da177e4SLinus Torvalds #include <asm/mmu_context.h> 271da177e4SLinus Torvalds #include <asm/io.h> 281da177e4SLinus Torvalds #include <asm/pgtable.h> 291da177e4SLinus Torvalds #include <asm/core_tsunami.h> 301da177e4SLinus Torvalds #include <asm/hwrpb.h> 311da177e4SLinus Torvalds #include <asm/tlbflush.h> 321da177e4SLinus Torvalds 331da177e4SLinus Torvalds #include "proto.h" 341da177e4SLinus Torvalds #include "irq_impl.h" 351da177e4SLinus Torvalds #include "pci_impl.h" 361da177e4SLinus Torvalds #include "machvec_impl.h" 371da177e4SLinus Torvalds 381da177e4SLinus Torvalds 391da177e4SLinus Torvalds /* Note mask bit is true for ENABLED irqs. */ 401da177e4SLinus Torvalds static unsigned long cached_irq_mask; 411da177e4SLinus Torvalds /* dp264 boards handle at max four CPUs */ 421da177e4SLinus Torvalds static unsigned long cpu_irq_affinity[4] = { 0UL, 0UL, 0UL, 0UL }; 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds DEFINE_SPINLOCK(dp264_irq_lock); 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds static void 471da177e4SLinus Torvalds tsunami_update_irq_hw(unsigned long mask) 481da177e4SLinus Torvalds { 491da177e4SLinus Torvalds register tsunami_cchip *cchip = TSUNAMI_cchip; 501da177e4SLinus Torvalds unsigned long isa_enable = 1UL << 55; 511da177e4SLinus Torvalds register int bcpu = boot_cpuid; 521da177e4SLinus Torvalds 531da177e4SLinus Torvalds #ifdef CONFIG_SMP 541da177e4SLinus Torvalds volatile unsigned long *dim0, *dim1, *dim2, *dim3; 551da177e4SLinus Torvalds unsigned long mask0, mask1, mask2, mask3, dummy; 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds mask &= ~isa_enable; 581da177e4SLinus Torvalds mask0 = mask & cpu_irq_affinity[0]; 591da177e4SLinus Torvalds mask1 = mask & cpu_irq_affinity[1]; 601da177e4SLinus Torvalds mask2 = mask & cpu_irq_affinity[2]; 611da177e4SLinus Torvalds mask3 = mask & cpu_irq_affinity[3]; 621da177e4SLinus Torvalds 631da177e4SLinus Torvalds if (bcpu == 0) mask0 |= isa_enable; 641da177e4SLinus Torvalds else if (bcpu == 1) mask1 |= isa_enable; 651da177e4SLinus Torvalds else if (bcpu == 2) mask2 |= isa_enable; 661da177e4SLinus Torvalds else mask3 |= isa_enable; 671da177e4SLinus Torvalds 681da177e4SLinus Torvalds dim0 = &cchip->dim0.csr; 691da177e4SLinus Torvalds dim1 = &cchip->dim1.csr; 701da177e4SLinus Torvalds dim2 = &cchip->dim2.csr; 711da177e4SLinus Torvalds dim3 = &cchip->dim3.csr; 721da177e4SLinus Torvalds if (!cpu_possible(0)) dim0 = &dummy; 731da177e4SLinus Torvalds if (!cpu_possible(1)) dim1 = &dummy; 741da177e4SLinus Torvalds if (!cpu_possible(2)) dim2 = &dummy; 751da177e4SLinus Torvalds if (!cpu_possible(3)) dim3 = &dummy; 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds *dim0 = mask0; 781da177e4SLinus Torvalds *dim1 = mask1; 791da177e4SLinus Torvalds *dim2 = mask2; 801da177e4SLinus Torvalds *dim3 = mask3; 811da177e4SLinus Torvalds mb(); 821da177e4SLinus Torvalds *dim0; 831da177e4SLinus Torvalds *dim1; 841da177e4SLinus Torvalds *dim2; 851da177e4SLinus Torvalds *dim3; 861da177e4SLinus Torvalds #else 871da177e4SLinus Torvalds volatile unsigned long *dimB; 881da177e4SLinus Torvalds if (bcpu == 0) dimB = &cchip->dim0.csr; 891da177e4SLinus Torvalds else if (bcpu == 1) dimB = &cchip->dim1.csr; 901da177e4SLinus Torvalds else if (bcpu == 2) dimB = &cchip->dim2.csr; 911da177e4SLinus Torvalds else dimB = &cchip->dim3.csr; 921da177e4SLinus Torvalds 931da177e4SLinus Torvalds *dimB = mask | isa_enable; 941da177e4SLinus Torvalds mb(); 951da177e4SLinus Torvalds *dimB; 961da177e4SLinus Torvalds #endif 971da177e4SLinus Torvalds } 981da177e4SLinus Torvalds 991da177e4SLinus Torvalds static void 100d677f450SThomas Gleixner dp264_enable_irq(struct irq_data *d) 1011da177e4SLinus Torvalds { 1021da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 103d677f450SThomas Gleixner cached_irq_mask |= 1UL << d->irq; 1041da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1051da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1061da177e4SLinus Torvalds } 1071da177e4SLinus Torvalds 1081da177e4SLinus Torvalds static void 109d677f450SThomas Gleixner dp264_disable_irq(struct irq_data *d) 1101da177e4SLinus Torvalds { 1111da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 112d677f450SThomas Gleixner cached_irq_mask &= ~(1UL << d->irq); 1131da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1141da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1151da177e4SLinus Torvalds } 1161da177e4SLinus Torvalds 1171da177e4SLinus Torvalds static void 118d677f450SThomas Gleixner clipper_enable_irq(struct irq_data *d) 1191da177e4SLinus Torvalds { 1201da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 121d677f450SThomas Gleixner cached_irq_mask |= 1UL << (d->irq - 16); 1221da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1231da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1241da177e4SLinus Torvalds } 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds static void 127d677f450SThomas Gleixner clipper_disable_irq(struct irq_data *d) 1281da177e4SLinus Torvalds { 1291da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 130d677f450SThomas Gleixner cached_irq_mask &= ~(1UL << (d->irq - 16)); 1311da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1321da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1331da177e4SLinus Torvalds } 1341da177e4SLinus Torvalds 1351da177e4SLinus Torvalds static void 1361da177e4SLinus Torvalds cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity) 1371da177e4SLinus Torvalds { 1381da177e4SLinus Torvalds int cpu; 1391da177e4SLinus Torvalds 1401da177e4SLinus Torvalds for (cpu = 0; cpu < 4; cpu++) { 1411da177e4SLinus Torvalds unsigned long aff = cpu_irq_affinity[cpu]; 14281740fc6SKOSAKI Motohiro if (cpumask_test_cpu(cpu, &affinity)) 1431da177e4SLinus Torvalds aff |= 1UL << irq; 1441da177e4SLinus Torvalds else 1451da177e4SLinus Torvalds aff &= ~(1UL << irq); 1461da177e4SLinus Torvalds cpu_irq_affinity[cpu] = aff; 1471da177e4SLinus Torvalds } 1481da177e4SLinus Torvalds } 1491da177e4SLinus Torvalds 150d5dedd45SYinghai Lu static int 151d677f450SThomas Gleixner dp264_set_affinity(struct irq_data *d, const struct cpumask *affinity, 152d677f450SThomas Gleixner bool force) 1531da177e4SLinus Torvalds { 1541da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 155d677f450SThomas Gleixner cpu_set_irq_affinity(d->irq, *affinity); 1561da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1571da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 158d5dedd45SYinghai Lu 159d5dedd45SYinghai Lu return 0; 1601da177e4SLinus Torvalds } 1611da177e4SLinus Torvalds 162d5dedd45SYinghai Lu static int 163d677f450SThomas Gleixner clipper_set_affinity(struct irq_data *d, const struct cpumask *affinity, 164d677f450SThomas Gleixner bool force) 1651da177e4SLinus Torvalds { 1661da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 167d677f450SThomas Gleixner cpu_set_irq_affinity(d->irq - 16, *affinity); 1681da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1691da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 170d5dedd45SYinghai Lu 171d5dedd45SYinghai Lu return 0; 1721da177e4SLinus Torvalds } 1731da177e4SLinus Torvalds 17444377f62SThomas Gleixner static struct irq_chip dp264_irq_type = { 1758ab1221cSThomas Gleixner .name = "DP264", 176d677f450SThomas Gleixner .irq_unmask = dp264_enable_irq, 177d677f450SThomas Gleixner .irq_mask = dp264_disable_irq, 178d677f450SThomas Gleixner .irq_mask_ack = dp264_disable_irq, 179d677f450SThomas Gleixner .irq_set_affinity = dp264_set_affinity, 1801da177e4SLinus Torvalds }; 1811da177e4SLinus Torvalds 18244377f62SThomas Gleixner static struct irq_chip clipper_irq_type = { 1838ab1221cSThomas Gleixner .name = "CLIPPER", 184d677f450SThomas Gleixner .irq_unmask = clipper_enable_irq, 185d677f450SThomas Gleixner .irq_mask = clipper_disable_irq, 186d677f450SThomas Gleixner .irq_mask_ack = clipper_disable_irq, 187d677f450SThomas Gleixner .irq_set_affinity = clipper_set_affinity, 1881da177e4SLinus Torvalds }; 1891da177e4SLinus Torvalds 1901da177e4SLinus Torvalds static void 1917ca56053SAl Viro dp264_device_interrupt(unsigned long vector) 1921da177e4SLinus Torvalds { 1931da177e4SLinus Torvalds unsigned long pld; 1941da177e4SLinus Torvalds unsigned int i; 1951da177e4SLinus Torvalds 1961da177e4SLinus Torvalds /* Read the interrupt summary register of TSUNAMI */ 1971da177e4SLinus Torvalds pld = TSUNAMI_cchip->dir0.csr; 1981da177e4SLinus Torvalds 1991da177e4SLinus Torvalds /* 2001da177e4SLinus Torvalds * Now for every possible bit set, work through them and call 2011da177e4SLinus Torvalds * the appropriate interrupt handler. 2021da177e4SLinus Torvalds */ 2031da177e4SLinus Torvalds while (pld) { 2041da177e4SLinus Torvalds i = ffz(~pld); 2051da177e4SLinus Torvalds pld &= pld - 1; /* clear least bit set */ 2061da177e4SLinus Torvalds if (i == 55) 2077ca56053SAl Viro isa_device_interrupt(vector); 2081da177e4SLinus Torvalds else 2093dbb8c62SAl Viro handle_irq(16 + i); 2101da177e4SLinus Torvalds } 2111da177e4SLinus Torvalds } 2121da177e4SLinus Torvalds 2131da177e4SLinus Torvalds static void 2147ca56053SAl Viro dp264_srm_device_interrupt(unsigned long vector) 2151da177e4SLinus Torvalds { 2161da177e4SLinus Torvalds int irq; 2171da177e4SLinus Torvalds 2181da177e4SLinus Torvalds irq = (vector - 0x800) >> 4; 2191da177e4SLinus Torvalds 2201da177e4SLinus Torvalds /* 2211da177e4SLinus Torvalds * The SRM console reports PCI interrupts with a vector calculated by: 2221da177e4SLinus Torvalds * 2231da177e4SLinus Torvalds * 0x900 + (0x10 * DRIR-bit) 2241da177e4SLinus Torvalds * 2251da177e4SLinus Torvalds * So bit 16 shows up as IRQ 32, etc. 2261da177e4SLinus Torvalds * 2271da177e4SLinus Torvalds * On DP264/BRICK/MONET, we adjust it down by 16 because at least 2281da177e4SLinus Torvalds * that many of the low order bits of the DRIR are not used, and 2291da177e4SLinus Torvalds * so we don't count them. 2301da177e4SLinus Torvalds */ 2311da177e4SLinus Torvalds if (irq >= 32) 2321da177e4SLinus Torvalds irq -= 16; 2331da177e4SLinus Torvalds 2343dbb8c62SAl Viro handle_irq(irq); 2351da177e4SLinus Torvalds } 2361da177e4SLinus Torvalds 2371da177e4SLinus Torvalds static void 2387ca56053SAl Viro clipper_srm_device_interrupt(unsigned long vector) 2391da177e4SLinus Torvalds { 2401da177e4SLinus Torvalds int irq; 2411da177e4SLinus Torvalds 2421da177e4SLinus Torvalds irq = (vector - 0x800) >> 4; 2431da177e4SLinus Torvalds 2441da177e4SLinus Torvalds /* 2451da177e4SLinus Torvalds * The SRM console reports PCI interrupts with a vector calculated by: 2461da177e4SLinus Torvalds * 2471da177e4SLinus Torvalds * 0x900 + (0x10 * DRIR-bit) 2481da177e4SLinus Torvalds * 2491da177e4SLinus Torvalds * So bit 16 shows up as IRQ 32, etc. 2501da177e4SLinus Torvalds * 2511da177e4SLinus Torvalds * CLIPPER uses bits 8-47 for PCI interrupts, so we do not need 2521da177e4SLinus Torvalds * to scale down the vector reported, we just use it. 2531da177e4SLinus Torvalds * 2541da177e4SLinus Torvalds * Eg IRQ 24 is DRIR bit 8, etc, etc 2551da177e4SLinus Torvalds */ 2563dbb8c62SAl Viro handle_irq(irq); 2571da177e4SLinus Torvalds } 2581da177e4SLinus Torvalds 2591da177e4SLinus Torvalds static void __init 26044377f62SThomas Gleixner init_tsunami_irqs(struct irq_chip * ops, int imin, int imax) 2611da177e4SLinus Torvalds { 2621da177e4SLinus Torvalds long i; 2631da177e4SLinus Torvalds for (i = imin; i <= imax; ++i) { 264a9eb076bSThomas Gleixner irq_set_chip_and_handler(i, ops, handle_level_irq); 265d677f450SThomas Gleixner irq_set_status_flags(i, IRQ_LEVEL); 2661da177e4SLinus Torvalds } 2671da177e4SLinus Torvalds } 2681da177e4SLinus Torvalds 2691da177e4SLinus Torvalds static void __init 2701da177e4SLinus Torvalds dp264_init_irq(void) 2711da177e4SLinus Torvalds { 2721da177e4SLinus Torvalds outb(0, DMA1_RESET_REG); 2731da177e4SLinus Torvalds outb(0, DMA2_RESET_REG); 2741da177e4SLinus Torvalds outb(DMA_MODE_CASCADE, DMA2_MODE_REG); 2751da177e4SLinus Torvalds outb(0, DMA2_MASK_REG); 2761da177e4SLinus Torvalds 2771da177e4SLinus Torvalds if (alpha_using_srm) 2781da177e4SLinus Torvalds alpha_mv.device_interrupt = dp264_srm_device_interrupt; 2791da177e4SLinus Torvalds 2801da177e4SLinus Torvalds tsunami_update_irq_hw(0); 2811da177e4SLinus Torvalds 2821da177e4SLinus Torvalds init_i8259a_irqs(); 2831da177e4SLinus Torvalds init_tsunami_irqs(&dp264_irq_type, 16, 47); 2841da177e4SLinus Torvalds } 2851da177e4SLinus Torvalds 2861da177e4SLinus Torvalds static void __init 2871da177e4SLinus Torvalds clipper_init_irq(void) 2881da177e4SLinus Torvalds { 2891da177e4SLinus Torvalds outb(0, DMA1_RESET_REG); 2901da177e4SLinus Torvalds outb(0, DMA2_RESET_REG); 2911da177e4SLinus Torvalds outb(DMA_MODE_CASCADE, DMA2_MODE_REG); 2921da177e4SLinus Torvalds outb(0, DMA2_MASK_REG); 2931da177e4SLinus Torvalds 2941da177e4SLinus Torvalds if (alpha_using_srm) 2951da177e4SLinus Torvalds alpha_mv.device_interrupt = clipper_srm_device_interrupt; 2961da177e4SLinus Torvalds 2971da177e4SLinus Torvalds tsunami_update_irq_hw(0); 2981da177e4SLinus Torvalds 2991da177e4SLinus Torvalds init_i8259a_irqs(); 3001da177e4SLinus Torvalds init_tsunami_irqs(&clipper_irq_type, 24, 63); 3011da177e4SLinus Torvalds } 3021da177e4SLinus Torvalds 3031da177e4SLinus Torvalds 3041da177e4SLinus Torvalds /* 3051da177e4SLinus Torvalds * PCI Fixup configuration. 3061da177e4SLinus Torvalds * 3071da177e4SLinus Torvalds * Summary @ TSUNAMI_CSR_DIM0: 3081da177e4SLinus Torvalds * Bit Meaning 3091da177e4SLinus Torvalds * 0-17 Unused 3101da177e4SLinus Torvalds *18 Interrupt SCSI B (Adaptec 7895 builtin) 3111da177e4SLinus Torvalds *19 Interrupt SCSI A (Adaptec 7895 builtin) 3121da177e4SLinus Torvalds *20 Interrupt Line D from slot 2 PCI0 3131da177e4SLinus Torvalds *21 Interrupt Line C from slot 2 PCI0 3141da177e4SLinus Torvalds *22 Interrupt Line B from slot 2 PCI0 3151da177e4SLinus Torvalds *23 Interrupt Line A from slot 2 PCI0 3161da177e4SLinus Torvalds *24 Interrupt Line D from slot 1 PCI0 3171da177e4SLinus Torvalds *25 Interrupt Line C from slot 1 PCI0 3181da177e4SLinus Torvalds *26 Interrupt Line B from slot 1 PCI0 3191da177e4SLinus Torvalds *27 Interrupt Line A from slot 1 PCI0 3201da177e4SLinus Torvalds *28 Interrupt Line D from slot 0 PCI0 3211da177e4SLinus Torvalds *29 Interrupt Line C from slot 0 PCI0 3221da177e4SLinus Torvalds *30 Interrupt Line B from slot 0 PCI0 3231da177e4SLinus Torvalds *31 Interrupt Line A from slot 0 PCI0 3241da177e4SLinus Torvalds * 3251da177e4SLinus Torvalds *32 Interrupt Line D from slot 3 PCI1 3261da177e4SLinus Torvalds *33 Interrupt Line C from slot 3 PCI1 3271da177e4SLinus Torvalds *34 Interrupt Line B from slot 3 PCI1 3281da177e4SLinus Torvalds *35 Interrupt Line A from slot 3 PCI1 3291da177e4SLinus Torvalds *36 Interrupt Line D from slot 2 PCI1 3301da177e4SLinus Torvalds *37 Interrupt Line C from slot 2 PCI1 3311da177e4SLinus Torvalds *38 Interrupt Line B from slot 2 PCI1 3321da177e4SLinus Torvalds *39 Interrupt Line A from slot 2 PCI1 3331da177e4SLinus Torvalds *40 Interrupt Line D from slot 1 PCI1 3341da177e4SLinus Torvalds *41 Interrupt Line C from slot 1 PCI1 3351da177e4SLinus Torvalds *42 Interrupt Line B from slot 1 PCI1 3361da177e4SLinus Torvalds *43 Interrupt Line A from slot 1 PCI1 3371da177e4SLinus Torvalds *44 Interrupt Line D from slot 0 PCI1 3381da177e4SLinus Torvalds *45 Interrupt Line C from slot 0 PCI1 3391da177e4SLinus Torvalds *46 Interrupt Line B from slot 0 PCI1 3401da177e4SLinus Torvalds *47 Interrupt Line A from slot 0 PCI1 3411da177e4SLinus Torvalds *48-52 Unused 3421da177e4SLinus Torvalds *53 PCI0 NMI (from Cypress) 3431da177e4SLinus Torvalds *54 PCI0 SMI INT (from Cypress) 3441da177e4SLinus Torvalds *55 PCI0 ISA Interrupt (from Cypress) 3451da177e4SLinus Torvalds *56-60 Unused 3461da177e4SLinus Torvalds *61 PCI1 Bus Error 3471da177e4SLinus Torvalds *62 PCI0 Bus Error 3481da177e4SLinus Torvalds *63 Reserved 3491da177e4SLinus Torvalds * 3501da177e4SLinus Torvalds * IdSel 3511da177e4SLinus Torvalds * 5 Cypress Bridge I/O 3521da177e4SLinus Torvalds * 6 SCSI Adaptec builtin 3531da177e4SLinus Torvalds * 7 64 bit PCI option slot 0 (all busses) 3541da177e4SLinus Torvalds * 8 64 bit PCI option slot 1 (all busses) 3551da177e4SLinus Torvalds * 9 64 bit PCI option slot 2 (all busses) 3561da177e4SLinus Torvalds * 10 64 bit PCI option slot 3 (not bus 0) 3571da177e4SLinus Torvalds */ 3581da177e4SLinus Torvalds 359*814eae59SLorenzo Pieralisi static int 360bf362f75SAl Viro isa_irq_fixup(const struct pci_dev *dev, int irq) 361997a51aeSIvan Kokshaysky { 362997a51aeSIvan Kokshaysky u8 irq8; 363997a51aeSIvan Kokshaysky 364997a51aeSIvan Kokshaysky if (irq > 0) 365997a51aeSIvan Kokshaysky return irq; 366997a51aeSIvan Kokshaysky 367997a51aeSIvan Kokshaysky /* This interrupt is routed via ISA bridge, so we'll 368997a51aeSIvan Kokshaysky just have to trust whatever value the console might 369997a51aeSIvan Kokshaysky have assigned. */ 370997a51aeSIvan Kokshaysky pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8); 371997a51aeSIvan Kokshaysky 372997a51aeSIvan Kokshaysky return irq8 & 0xf; 373997a51aeSIvan Kokshaysky } 374997a51aeSIvan Kokshaysky 375*814eae59SLorenzo Pieralisi static int 376d5341942SRalf Baechle dp264_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 3771da177e4SLinus Torvalds { 378*814eae59SLorenzo Pieralisi static char irq_tab[6][5] = { 3791da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 3801da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 5 ISA Bridge */ 3811da177e4SLinus Torvalds { 16+ 3, 16+ 3, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin*/ 3821da177e4SLinus Torvalds { 16+15, 16+15, 16+14, 16+13, 16+12}, /* IdSel 7 slot 0 */ 3831da177e4SLinus Torvalds { 16+11, 16+11, 16+10, 16+ 9, 16+ 8}, /* IdSel 8 slot 1 */ 3841da177e4SLinus Torvalds { 16+ 7, 16+ 7, 16+ 6, 16+ 5, 16+ 4}, /* IdSel 9 slot 2 */ 3851da177e4SLinus Torvalds { 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0} /* IdSel 10 slot 3 */ 3861da177e4SLinus Torvalds }; 3871da177e4SLinus Torvalds const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5; 3881da177e4SLinus Torvalds struct pci_controller *hose = dev->sysdata; 3891da177e4SLinus Torvalds int irq = COMMON_TABLE_LOOKUP; 3901da177e4SLinus Torvalds 391997a51aeSIvan Kokshaysky if (irq > 0) 3921da177e4SLinus Torvalds irq += 16 * hose->index; 3931da177e4SLinus Torvalds 394997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, irq); 3951da177e4SLinus Torvalds } 3961da177e4SLinus Torvalds 397*814eae59SLorenzo Pieralisi static int 398d5341942SRalf Baechle monet_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 3991da177e4SLinus Torvalds { 400*814eae59SLorenzo Pieralisi static char irq_tab[13][5] = { 4011da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 4021da177e4SLinus Torvalds { 45, 45, 45, 45, 45}, /* IdSel 3 21143 PCI1 */ 4031da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 4 unused */ 4041da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 5 unused */ 4051da177e4SLinus Torvalds { 47, 47, 47, 47, 47}, /* IdSel 6 SCSI PCI1 */ 4061da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 7 ISA Bridge */ 4071da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 8 P2P PCI1 */ 4081da177e4SLinus Torvalds #if 1 4091da177e4SLinus Torvalds { 28, 28, 29, 30, 31}, /* IdSel 14 slot 4 PCI2*/ 4101da177e4SLinus Torvalds { 24, 24, 25, 26, 27}, /* IdSel 15 slot 5 PCI2*/ 4111da177e4SLinus Torvalds #else 4121da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 9 unused */ 4131da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 10 unused */ 4141da177e4SLinus Torvalds #endif 4151da177e4SLinus Torvalds { 40, 40, 41, 42, 43}, /* IdSel 11 slot 1 PCI0*/ 4161da177e4SLinus Torvalds { 36, 36, 37, 38, 39}, /* IdSel 12 slot 2 PCI0*/ 4171da177e4SLinus Torvalds { 32, 32, 33, 34, 35}, /* IdSel 13 slot 3 PCI0*/ 4181da177e4SLinus Torvalds { 28, 28, 29, 30, 31}, /* IdSel 14 slot 4 PCI2*/ 4191da177e4SLinus Torvalds { 24, 24, 25, 26, 27} /* IdSel 15 slot 5 PCI2*/ 4201da177e4SLinus Torvalds }; 4211da177e4SLinus Torvalds const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5; 422997a51aeSIvan Kokshaysky 423997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP); 4241da177e4SLinus Torvalds } 4251da177e4SLinus Torvalds 426*814eae59SLorenzo Pieralisi static u8 4271da177e4SLinus Torvalds monet_swizzle(struct pci_dev *dev, u8 *pinp) 4281da177e4SLinus Torvalds { 4291da177e4SLinus Torvalds struct pci_controller *hose = dev->sysdata; 4301da177e4SLinus Torvalds int slot, pin = *pinp; 4311da177e4SLinus Torvalds 4321da177e4SLinus Torvalds if (!dev->bus->parent) { 4331da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4341da177e4SLinus Torvalds } 4351da177e4SLinus Torvalds /* Check for the built-in bridge on hose 1. */ 4361da177e4SLinus Torvalds else if (hose->index == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) { 4371da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4381da177e4SLinus Torvalds } else { 4391da177e4SLinus Torvalds /* Must be a card-based bridge. */ 4401da177e4SLinus Torvalds do { 4411da177e4SLinus Torvalds /* Check for built-in bridge on hose 1. */ 4421da177e4SLinus Torvalds if (hose->index == 1 && 4431da177e4SLinus Torvalds PCI_SLOT(dev->bus->self->devfn) == 8) { 4441da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4451da177e4SLinus Torvalds break; 4461da177e4SLinus Torvalds } 4471be9baa0SBjorn Helgaas pin = pci_swizzle_interrupt_pin(dev, pin); 4481da177e4SLinus Torvalds 4491da177e4SLinus Torvalds /* Move up the chain of bridges. */ 4501da177e4SLinus Torvalds dev = dev->bus->self; 4511da177e4SLinus Torvalds /* Slot of the next bridge. */ 4521da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4531da177e4SLinus Torvalds } while (dev->bus->self); 4541da177e4SLinus Torvalds } 4551da177e4SLinus Torvalds *pinp = pin; 4561da177e4SLinus Torvalds return slot; 4571da177e4SLinus Torvalds } 4581da177e4SLinus Torvalds 459*814eae59SLorenzo Pieralisi static int 460d5341942SRalf Baechle webbrick_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 4611da177e4SLinus Torvalds { 462*814eae59SLorenzo Pieralisi static char irq_tab[13][5] = { 4631da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 4641da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 7 ISA Bridge */ 4651da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 8 unused */ 4661da177e4SLinus Torvalds { 29, 29, 29, 29, 29}, /* IdSel 9 21143 #1 */ 4671da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 10 unused */ 4681da177e4SLinus Torvalds { 30, 30, 30, 30, 30}, /* IdSel 11 21143 #2 */ 4691da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 12 unused */ 4701da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 13 unused */ 4711da177e4SLinus Torvalds { 35, 35, 34, 33, 32}, /* IdSel 14 slot 0 */ 4721da177e4SLinus Torvalds { 39, 39, 38, 37, 36}, /* IdSel 15 slot 1 */ 4731da177e4SLinus Torvalds { 43, 43, 42, 41, 40}, /* IdSel 16 slot 2 */ 4741da177e4SLinus Torvalds { 47, 47, 46, 45, 44}, /* IdSel 17 slot 3 */ 4751da177e4SLinus Torvalds }; 4761da177e4SLinus Torvalds const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5; 477997a51aeSIvan Kokshaysky 478997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP); 4791da177e4SLinus Torvalds } 4801da177e4SLinus Torvalds 481*814eae59SLorenzo Pieralisi static int 482d5341942SRalf Baechle clipper_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 4831da177e4SLinus Torvalds { 484*814eae59SLorenzo Pieralisi static char irq_tab[7][5] = { 4851da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 4861da177e4SLinus Torvalds { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 1 slot 1 */ 4871da177e4SLinus Torvalds { 16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 2 slot 2 */ 4881da177e4SLinus Torvalds { 16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 3 slot 3 */ 4891da177e4SLinus Torvalds { 16+20, 16+20, 16+21, 16+22, 16+23}, /* IdSel 4 slot 4 */ 4901da177e4SLinus Torvalds { 16+24, 16+24, 16+25, 16+26, 16+27}, /* IdSel 5 slot 5 */ 4911da177e4SLinus Torvalds { 16+28, 16+28, 16+29, 16+30, 16+31}, /* IdSel 6 slot 6 */ 4921da177e4SLinus Torvalds { -1, -1, -1, -1, -1} /* IdSel 7 ISA Bridge */ 4931da177e4SLinus Torvalds }; 4941da177e4SLinus Torvalds const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5; 4951da177e4SLinus Torvalds struct pci_controller *hose = dev->sysdata; 4961da177e4SLinus Torvalds int irq = COMMON_TABLE_LOOKUP; 4971da177e4SLinus Torvalds 4981da177e4SLinus Torvalds if (irq > 0) 4991da177e4SLinus Torvalds irq += 16 * hose->index; 5001da177e4SLinus Torvalds 501997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, irq); 5021da177e4SLinus Torvalds } 5031da177e4SLinus Torvalds 5041da177e4SLinus Torvalds static void __init 5051da177e4SLinus Torvalds dp264_init_pci(void) 5061da177e4SLinus Torvalds { 5071da177e4SLinus Torvalds common_init_pci(); 5081da177e4SLinus Torvalds SMC669_Init(0); 509025a2215SJay Estabrook locate_and_init_vga(NULL); 5101da177e4SLinus Torvalds } 5111da177e4SLinus Torvalds 5121da177e4SLinus Torvalds static void __init 5131da177e4SLinus Torvalds monet_init_pci(void) 5141da177e4SLinus Torvalds { 5151da177e4SLinus Torvalds common_init_pci(); 5161da177e4SLinus Torvalds SMC669_Init(1); 5171da177e4SLinus Torvalds es1888_init(); 518025a2215SJay Estabrook locate_and_init_vga(NULL); 519025a2215SJay Estabrook } 520025a2215SJay Estabrook 521025a2215SJay Estabrook static void __init 522025a2215SJay Estabrook clipper_init_pci(void) 523025a2215SJay Estabrook { 524025a2215SJay Estabrook common_init_pci(); 525025a2215SJay Estabrook locate_and_init_vga(NULL); 5261da177e4SLinus Torvalds } 5271da177e4SLinus Torvalds 5281da177e4SLinus Torvalds static void __init 5291da177e4SLinus Torvalds webbrick_init_arch(void) 5301da177e4SLinus Torvalds { 5311da177e4SLinus Torvalds tsunami_init_arch(); 5321da177e4SLinus Torvalds 5331da177e4SLinus Torvalds /* Tsunami caches 4 PTEs at a time; DS10 has only 1 hose. */ 5341da177e4SLinus Torvalds hose_head->sg_isa->align_entry = 4; 5351da177e4SLinus Torvalds hose_head->sg_pci->align_entry = 4; 5361da177e4SLinus Torvalds } 5371da177e4SLinus Torvalds 5381da177e4SLinus Torvalds 5391da177e4SLinus Torvalds /* 5401da177e4SLinus Torvalds * The System Vectors 5411da177e4SLinus Torvalds */ 5421da177e4SLinus Torvalds 5431da177e4SLinus Torvalds struct alpha_machine_vector dp264_mv __initmv = { 5441da177e4SLinus Torvalds .vector_name = "DP264", 5451da177e4SLinus Torvalds DO_EV6_MMU, 5461da177e4SLinus Torvalds DO_DEFAULT_RTC, 5471da177e4SLinus Torvalds DO_TSUNAMI_IO, 5481da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 5491da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 5501da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 5511da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 5521da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 5531da177e4SLinus Torvalds 5541da177e4SLinus Torvalds .nr_irqs = 64, 5551da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 5561da177e4SLinus Torvalds 5571da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 5581da177e4SLinus Torvalds .init_irq = dp264_init_irq, 5591da177e4SLinus Torvalds .init_rtc = common_init_rtc, 5601da177e4SLinus Torvalds .init_pci = dp264_init_pci, 5611da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 5621da177e4SLinus Torvalds .pci_map_irq = dp264_map_irq, 5631da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 5641da177e4SLinus Torvalds }; 5651da177e4SLinus Torvalds ALIAS_MV(dp264) 5661da177e4SLinus Torvalds 5671da177e4SLinus Torvalds struct alpha_machine_vector monet_mv __initmv = { 5681da177e4SLinus Torvalds .vector_name = "Monet", 5691da177e4SLinus Torvalds DO_EV6_MMU, 5701da177e4SLinus Torvalds DO_DEFAULT_RTC, 5711da177e4SLinus Torvalds DO_TSUNAMI_IO, 5721da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 5731da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 5741da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 5751da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 5761da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 5771da177e4SLinus Torvalds 5781da177e4SLinus Torvalds .nr_irqs = 64, 5791da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 5801da177e4SLinus Torvalds 5811da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 5821da177e4SLinus Torvalds .init_irq = dp264_init_irq, 5831da177e4SLinus Torvalds .init_rtc = common_init_rtc, 5841da177e4SLinus Torvalds .init_pci = monet_init_pci, 5851da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 5861da177e4SLinus Torvalds .pci_map_irq = monet_map_irq, 5871da177e4SLinus Torvalds .pci_swizzle = monet_swizzle, 5881da177e4SLinus Torvalds }; 5891da177e4SLinus Torvalds 5901da177e4SLinus Torvalds struct alpha_machine_vector webbrick_mv __initmv = { 5911da177e4SLinus Torvalds .vector_name = "Webbrick", 5921da177e4SLinus Torvalds DO_EV6_MMU, 5931da177e4SLinus Torvalds DO_DEFAULT_RTC, 5941da177e4SLinus Torvalds DO_TSUNAMI_IO, 5951da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 5961da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 5971da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 5981da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 5991da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 6001da177e4SLinus Torvalds 6011da177e4SLinus Torvalds .nr_irqs = 64, 6021da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 6031da177e4SLinus Torvalds 6041da177e4SLinus Torvalds .init_arch = webbrick_init_arch, 6051da177e4SLinus Torvalds .init_irq = dp264_init_irq, 6061da177e4SLinus Torvalds .init_rtc = common_init_rtc, 6071da177e4SLinus Torvalds .init_pci = common_init_pci, 6081da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 6091da177e4SLinus Torvalds .pci_map_irq = webbrick_map_irq, 6101da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 6111da177e4SLinus Torvalds }; 6121da177e4SLinus Torvalds 6131da177e4SLinus Torvalds struct alpha_machine_vector clipper_mv __initmv = { 6141da177e4SLinus Torvalds .vector_name = "Clipper", 6151da177e4SLinus Torvalds DO_EV6_MMU, 6161da177e4SLinus Torvalds DO_DEFAULT_RTC, 6171da177e4SLinus Torvalds DO_TSUNAMI_IO, 6181da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 6191da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 6201da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 6211da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 6221da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 6231da177e4SLinus Torvalds 6241da177e4SLinus Torvalds .nr_irqs = 64, 6251da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 6261da177e4SLinus Torvalds 6271da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 6281da177e4SLinus Torvalds .init_irq = clipper_init_irq, 6291da177e4SLinus Torvalds .init_rtc = common_init_rtc, 630025a2215SJay Estabrook .init_pci = clipper_init_pci, 6311da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 6321da177e4SLinus Torvalds .pci_map_irq = clipper_map_irq, 6331da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 6341da177e4SLinus Torvalds }; 6351da177e4SLinus Torvalds 6361da177e4SLinus Torvalds /* Sharks strongly resemble Clipper, at least as far 6371da177e4SLinus Torvalds * as interrupt routing, etc, so we're using the 6381da177e4SLinus Torvalds * same functions as Clipper does 6391da177e4SLinus Torvalds */ 6401da177e4SLinus Torvalds 6411da177e4SLinus Torvalds struct alpha_machine_vector shark_mv __initmv = { 6421da177e4SLinus Torvalds .vector_name = "Shark", 6431da177e4SLinus Torvalds DO_EV6_MMU, 6441da177e4SLinus Torvalds DO_DEFAULT_RTC, 6451da177e4SLinus Torvalds DO_TSUNAMI_IO, 6461da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 6471da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 6481da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 6491da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 6501da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 6511da177e4SLinus Torvalds 6521da177e4SLinus Torvalds .nr_irqs = 64, 6531da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 6541da177e4SLinus Torvalds 6551da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 6561da177e4SLinus Torvalds .init_irq = clipper_init_irq, 6571da177e4SLinus Torvalds .init_rtc = common_init_rtc, 6581da177e4SLinus Torvalds .init_pci = common_init_pci, 6591da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 6601da177e4SLinus Torvalds .pci_map_irq = clipper_map_irq, 6611da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 6621da177e4SLinus Torvalds }; 6631da177e4SLinus Torvalds 6641da177e4SLinus Torvalds /* No alpha_mv alias for webbrick/monet/clipper, since we compile them 6651da177e4SLinus Torvalds in unconditionally with DP264; setup_arch knows how to cope. */ 666