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/config.h> 161da177e4SLinus Torvalds #include <linux/kernel.h> 171da177e4SLinus Torvalds #include <linux/types.h> 181da177e4SLinus Torvalds #include <linux/mm.h> 191da177e4SLinus Torvalds #include <linux/sched.h> 201da177e4SLinus Torvalds #include <linux/pci.h> 211da177e4SLinus Torvalds #include <linux/init.h> 221da177e4SLinus Torvalds #include <linux/bitops.h> 231da177e4SLinus Torvalds 241da177e4SLinus Torvalds #include <asm/ptrace.h> 251da177e4SLinus Torvalds #include <asm/system.h> 261da177e4SLinus Torvalds #include <asm/dma.h> 271da177e4SLinus Torvalds #include <asm/irq.h> 281da177e4SLinus Torvalds #include <asm/mmu_context.h> 291da177e4SLinus Torvalds #include <asm/io.h> 301da177e4SLinus Torvalds #include <asm/pgtable.h> 311da177e4SLinus Torvalds #include <asm/core_tsunami.h> 321da177e4SLinus Torvalds #include <asm/hwrpb.h> 331da177e4SLinus Torvalds #include <asm/tlbflush.h> 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds #include "proto.h" 361da177e4SLinus Torvalds #include "irq_impl.h" 371da177e4SLinus Torvalds #include "pci_impl.h" 381da177e4SLinus Torvalds #include "machvec_impl.h" 391da177e4SLinus Torvalds 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds /* Note mask bit is true for ENABLED irqs. */ 421da177e4SLinus Torvalds static unsigned long cached_irq_mask; 431da177e4SLinus Torvalds /* dp264 boards handle at max four CPUs */ 441da177e4SLinus Torvalds static unsigned long cpu_irq_affinity[4] = { 0UL, 0UL, 0UL, 0UL }; 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds DEFINE_SPINLOCK(dp264_irq_lock); 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds static void 491da177e4SLinus Torvalds tsunami_update_irq_hw(unsigned long mask) 501da177e4SLinus Torvalds { 511da177e4SLinus Torvalds register tsunami_cchip *cchip = TSUNAMI_cchip; 521da177e4SLinus Torvalds unsigned long isa_enable = 1UL << 55; 531da177e4SLinus Torvalds register int bcpu = boot_cpuid; 541da177e4SLinus Torvalds 551da177e4SLinus Torvalds #ifdef CONFIG_SMP 561da177e4SLinus Torvalds volatile unsigned long *dim0, *dim1, *dim2, *dim3; 571da177e4SLinus Torvalds unsigned long mask0, mask1, mask2, mask3, dummy; 581da177e4SLinus Torvalds 591da177e4SLinus Torvalds mask &= ~isa_enable; 601da177e4SLinus Torvalds mask0 = mask & cpu_irq_affinity[0]; 611da177e4SLinus Torvalds mask1 = mask & cpu_irq_affinity[1]; 621da177e4SLinus Torvalds mask2 = mask & cpu_irq_affinity[2]; 631da177e4SLinus Torvalds mask3 = mask & cpu_irq_affinity[3]; 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds if (bcpu == 0) mask0 |= isa_enable; 661da177e4SLinus Torvalds else if (bcpu == 1) mask1 |= isa_enable; 671da177e4SLinus Torvalds else if (bcpu == 2) mask2 |= isa_enable; 681da177e4SLinus Torvalds else mask3 |= isa_enable; 691da177e4SLinus Torvalds 701da177e4SLinus Torvalds dim0 = &cchip->dim0.csr; 711da177e4SLinus Torvalds dim1 = &cchip->dim1.csr; 721da177e4SLinus Torvalds dim2 = &cchip->dim2.csr; 731da177e4SLinus Torvalds dim3 = &cchip->dim3.csr; 741da177e4SLinus Torvalds if (!cpu_possible(0)) dim0 = &dummy; 751da177e4SLinus Torvalds if (!cpu_possible(1)) dim1 = &dummy; 761da177e4SLinus Torvalds if (!cpu_possible(2)) dim2 = &dummy; 771da177e4SLinus Torvalds if (!cpu_possible(3)) dim3 = &dummy; 781da177e4SLinus Torvalds 791da177e4SLinus Torvalds *dim0 = mask0; 801da177e4SLinus Torvalds *dim1 = mask1; 811da177e4SLinus Torvalds *dim2 = mask2; 821da177e4SLinus Torvalds *dim3 = mask3; 831da177e4SLinus Torvalds mb(); 841da177e4SLinus Torvalds *dim0; 851da177e4SLinus Torvalds *dim1; 861da177e4SLinus Torvalds *dim2; 871da177e4SLinus Torvalds *dim3; 881da177e4SLinus Torvalds #else 891da177e4SLinus Torvalds volatile unsigned long *dimB; 901da177e4SLinus Torvalds if (bcpu == 0) dimB = &cchip->dim0.csr; 911da177e4SLinus Torvalds else if (bcpu == 1) dimB = &cchip->dim1.csr; 921da177e4SLinus Torvalds else if (bcpu == 2) dimB = &cchip->dim2.csr; 931da177e4SLinus Torvalds else dimB = &cchip->dim3.csr; 941da177e4SLinus Torvalds 951da177e4SLinus Torvalds *dimB = mask | isa_enable; 961da177e4SLinus Torvalds mb(); 971da177e4SLinus Torvalds *dimB; 981da177e4SLinus Torvalds #endif 991da177e4SLinus Torvalds } 1001da177e4SLinus Torvalds 1011da177e4SLinus Torvalds static void 1021da177e4SLinus Torvalds dp264_enable_irq(unsigned int irq) 1031da177e4SLinus Torvalds { 1041da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 1051da177e4SLinus Torvalds cached_irq_mask |= 1UL << irq; 1061da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1071da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1081da177e4SLinus Torvalds } 1091da177e4SLinus Torvalds 1101da177e4SLinus Torvalds static void 1111da177e4SLinus Torvalds dp264_disable_irq(unsigned int irq) 1121da177e4SLinus Torvalds { 1131da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 1141da177e4SLinus Torvalds cached_irq_mask &= ~(1UL << irq); 1151da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1161da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1171da177e4SLinus Torvalds } 1181da177e4SLinus Torvalds 1191da177e4SLinus Torvalds static unsigned int 1201da177e4SLinus Torvalds dp264_startup_irq(unsigned int irq) 1211da177e4SLinus Torvalds { 1221da177e4SLinus Torvalds dp264_enable_irq(irq); 1231da177e4SLinus Torvalds return 0; /* never anything pending */ 1241da177e4SLinus Torvalds } 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds static void 1271da177e4SLinus Torvalds dp264_end_irq(unsigned int irq) 1281da177e4SLinus Torvalds { 1291da177e4SLinus Torvalds if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 1301da177e4SLinus Torvalds dp264_enable_irq(irq); 1311da177e4SLinus Torvalds } 1321da177e4SLinus Torvalds 1331da177e4SLinus Torvalds static void 1341da177e4SLinus Torvalds clipper_enable_irq(unsigned int irq) 1351da177e4SLinus Torvalds { 1361da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 1371da177e4SLinus Torvalds cached_irq_mask |= 1UL << (irq - 16); 1381da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1391da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1401da177e4SLinus Torvalds } 1411da177e4SLinus Torvalds 1421da177e4SLinus Torvalds static void 1431da177e4SLinus Torvalds clipper_disable_irq(unsigned int irq) 1441da177e4SLinus Torvalds { 1451da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 1461da177e4SLinus Torvalds cached_irq_mask &= ~(1UL << (irq - 16)); 1471da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1481da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1491da177e4SLinus Torvalds } 1501da177e4SLinus Torvalds 1511da177e4SLinus Torvalds static unsigned int 1521da177e4SLinus Torvalds clipper_startup_irq(unsigned int irq) 1531da177e4SLinus Torvalds { 1541da177e4SLinus Torvalds clipper_enable_irq(irq); 1551da177e4SLinus Torvalds return 0; /* never anything pending */ 1561da177e4SLinus Torvalds } 1571da177e4SLinus Torvalds 1581da177e4SLinus Torvalds static void 1591da177e4SLinus Torvalds clipper_end_irq(unsigned int irq) 1601da177e4SLinus Torvalds { 1611da177e4SLinus Torvalds if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 1621da177e4SLinus Torvalds clipper_enable_irq(irq); 1631da177e4SLinus Torvalds } 1641da177e4SLinus Torvalds 1651da177e4SLinus Torvalds static void 1661da177e4SLinus Torvalds cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity) 1671da177e4SLinus Torvalds { 1681da177e4SLinus Torvalds int cpu; 1691da177e4SLinus Torvalds 1701da177e4SLinus Torvalds for (cpu = 0; cpu < 4; cpu++) { 1711da177e4SLinus Torvalds unsigned long aff = cpu_irq_affinity[cpu]; 1721da177e4SLinus Torvalds if (cpu_isset(cpu, affinity)) 1731da177e4SLinus Torvalds aff |= 1UL << irq; 1741da177e4SLinus Torvalds else 1751da177e4SLinus Torvalds aff &= ~(1UL << irq); 1761da177e4SLinus Torvalds cpu_irq_affinity[cpu] = aff; 1771da177e4SLinus Torvalds } 1781da177e4SLinus Torvalds } 1791da177e4SLinus Torvalds 1801da177e4SLinus Torvalds static void 1811da177e4SLinus Torvalds dp264_set_affinity(unsigned int irq, cpumask_t affinity) 1821da177e4SLinus Torvalds { 1831da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 1841da177e4SLinus Torvalds cpu_set_irq_affinity(irq, affinity); 1851da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1861da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1871da177e4SLinus Torvalds } 1881da177e4SLinus Torvalds 1891da177e4SLinus Torvalds static void 1901da177e4SLinus Torvalds clipper_set_affinity(unsigned int irq, cpumask_t affinity) 1911da177e4SLinus Torvalds { 1921da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 1931da177e4SLinus Torvalds cpu_set_irq_affinity(irq - 16, affinity); 1941da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1951da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1961da177e4SLinus Torvalds } 1971da177e4SLinus Torvalds 1981da177e4SLinus Torvalds static struct hw_interrupt_type dp264_irq_type = { 1991da177e4SLinus Torvalds .typename = "DP264", 2001da177e4SLinus Torvalds .startup = dp264_startup_irq, 2011da177e4SLinus Torvalds .shutdown = dp264_disable_irq, 2021da177e4SLinus Torvalds .enable = dp264_enable_irq, 2031da177e4SLinus Torvalds .disable = dp264_disable_irq, 2041da177e4SLinus Torvalds .ack = dp264_disable_irq, 2051da177e4SLinus Torvalds .end = dp264_end_irq, 2061da177e4SLinus Torvalds .set_affinity = dp264_set_affinity, 2071da177e4SLinus Torvalds }; 2081da177e4SLinus Torvalds 2091da177e4SLinus Torvalds static struct hw_interrupt_type clipper_irq_type = { 2101da177e4SLinus Torvalds .typename = "CLIPPER", 2111da177e4SLinus Torvalds .startup = clipper_startup_irq, 2121da177e4SLinus Torvalds .shutdown = clipper_disable_irq, 2131da177e4SLinus Torvalds .enable = clipper_enable_irq, 2141da177e4SLinus Torvalds .disable = clipper_disable_irq, 2151da177e4SLinus Torvalds .ack = clipper_disable_irq, 2161da177e4SLinus Torvalds .end = clipper_end_irq, 2171da177e4SLinus Torvalds .set_affinity = clipper_set_affinity, 2181da177e4SLinus Torvalds }; 2191da177e4SLinus Torvalds 2201da177e4SLinus Torvalds static void 2211da177e4SLinus Torvalds dp264_device_interrupt(unsigned long vector, struct pt_regs * regs) 2221da177e4SLinus Torvalds { 2231da177e4SLinus Torvalds #if 1 2241da177e4SLinus Torvalds printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n"); 2251da177e4SLinus Torvalds #else 2261da177e4SLinus Torvalds unsigned long pld; 2271da177e4SLinus Torvalds unsigned int i; 2281da177e4SLinus Torvalds 2291da177e4SLinus Torvalds /* Read the interrupt summary register of TSUNAMI */ 2301da177e4SLinus Torvalds pld = TSUNAMI_cchip->dir0.csr; 2311da177e4SLinus Torvalds 2321da177e4SLinus Torvalds /* 2331da177e4SLinus Torvalds * Now for every possible bit set, work through them and call 2341da177e4SLinus Torvalds * the appropriate interrupt handler. 2351da177e4SLinus Torvalds */ 2361da177e4SLinus Torvalds while (pld) { 2371da177e4SLinus Torvalds i = ffz(~pld); 2381da177e4SLinus Torvalds pld &= pld - 1; /* clear least bit set */ 2391da177e4SLinus Torvalds if (i == 55) 2401da177e4SLinus Torvalds isa_device_interrupt(vector, regs); 2411da177e4SLinus Torvalds else 2421da177e4SLinus Torvalds handle_irq(16 + i, 16 + i, regs); 2431da177e4SLinus Torvalds #if 0 2441da177e4SLinus Torvalds TSUNAMI_cchip->dir0.csr = 1UL << i; mb(); 2451da177e4SLinus Torvalds tmp = TSUNAMI_cchip->dir0.csr; 2461da177e4SLinus Torvalds #endif 2471da177e4SLinus Torvalds } 2481da177e4SLinus Torvalds #endif 2491da177e4SLinus Torvalds } 2501da177e4SLinus Torvalds 2511da177e4SLinus Torvalds static void 2521da177e4SLinus Torvalds dp264_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) 2531da177e4SLinus Torvalds { 2541da177e4SLinus Torvalds int irq; 2551da177e4SLinus Torvalds 2561da177e4SLinus Torvalds irq = (vector - 0x800) >> 4; 2571da177e4SLinus Torvalds 2581da177e4SLinus Torvalds /* 2591da177e4SLinus Torvalds * The SRM console reports PCI interrupts with a vector calculated by: 2601da177e4SLinus Torvalds * 2611da177e4SLinus Torvalds * 0x900 + (0x10 * DRIR-bit) 2621da177e4SLinus Torvalds * 2631da177e4SLinus Torvalds * So bit 16 shows up as IRQ 32, etc. 2641da177e4SLinus Torvalds * 2651da177e4SLinus Torvalds * On DP264/BRICK/MONET, we adjust it down by 16 because at least 2661da177e4SLinus Torvalds * that many of the low order bits of the DRIR are not used, and 2671da177e4SLinus Torvalds * so we don't count them. 2681da177e4SLinus Torvalds */ 2691da177e4SLinus Torvalds if (irq >= 32) 2701da177e4SLinus Torvalds irq -= 16; 2711da177e4SLinus Torvalds 2721da177e4SLinus Torvalds handle_irq(irq, regs); 2731da177e4SLinus Torvalds } 2741da177e4SLinus Torvalds 2751da177e4SLinus Torvalds static void 2761da177e4SLinus Torvalds clipper_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) 2771da177e4SLinus Torvalds { 2781da177e4SLinus Torvalds int irq; 2791da177e4SLinus Torvalds 2801da177e4SLinus Torvalds irq = (vector - 0x800) >> 4; 2811da177e4SLinus Torvalds 2821da177e4SLinus Torvalds /* 2831da177e4SLinus Torvalds * The SRM console reports PCI interrupts with a vector calculated by: 2841da177e4SLinus Torvalds * 2851da177e4SLinus Torvalds * 0x900 + (0x10 * DRIR-bit) 2861da177e4SLinus Torvalds * 2871da177e4SLinus Torvalds * So bit 16 shows up as IRQ 32, etc. 2881da177e4SLinus Torvalds * 2891da177e4SLinus Torvalds * CLIPPER uses bits 8-47 for PCI interrupts, so we do not need 2901da177e4SLinus Torvalds * to scale down the vector reported, we just use it. 2911da177e4SLinus Torvalds * 2921da177e4SLinus Torvalds * Eg IRQ 24 is DRIR bit 8, etc, etc 2931da177e4SLinus Torvalds */ 2941da177e4SLinus Torvalds handle_irq(irq, regs); 2951da177e4SLinus Torvalds } 2961da177e4SLinus Torvalds 2971da177e4SLinus Torvalds static void __init 2981da177e4SLinus Torvalds init_tsunami_irqs(struct hw_interrupt_type * ops, int imin, int imax) 2991da177e4SLinus Torvalds { 3001da177e4SLinus Torvalds long i; 3011da177e4SLinus Torvalds for (i = imin; i <= imax; ++i) { 3021da177e4SLinus Torvalds irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; 303*d1bef4edSIngo Molnar irq_desc[i].chip = ops; 3041da177e4SLinus Torvalds } 3051da177e4SLinus Torvalds } 3061da177e4SLinus Torvalds 3071da177e4SLinus Torvalds static void __init 3081da177e4SLinus Torvalds dp264_init_irq(void) 3091da177e4SLinus Torvalds { 3101da177e4SLinus Torvalds outb(0, DMA1_RESET_REG); 3111da177e4SLinus Torvalds outb(0, DMA2_RESET_REG); 3121da177e4SLinus Torvalds outb(DMA_MODE_CASCADE, DMA2_MODE_REG); 3131da177e4SLinus Torvalds outb(0, DMA2_MASK_REG); 3141da177e4SLinus Torvalds 3151da177e4SLinus Torvalds if (alpha_using_srm) 3161da177e4SLinus Torvalds alpha_mv.device_interrupt = dp264_srm_device_interrupt; 3171da177e4SLinus Torvalds 3181da177e4SLinus Torvalds tsunami_update_irq_hw(0); 3191da177e4SLinus Torvalds 3201da177e4SLinus Torvalds init_i8259a_irqs(); 3211da177e4SLinus Torvalds init_tsunami_irqs(&dp264_irq_type, 16, 47); 3221da177e4SLinus Torvalds } 3231da177e4SLinus Torvalds 3241da177e4SLinus Torvalds static void __init 3251da177e4SLinus Torvalds clipper_init_irq(void) 3261da177e4SLinus Torvalds { 3271da177e4SLinus Torvalds outb(0, DMA1_RESET_REG); 3281da177e4SLinus Torvalds outb(0, DMA2_RESET_REG); 3291da177e4SLinus Torvalds outb(DMA_MODE_CASCADE, DMA2_MODE_REG); 3301da177e4SLinus Torvalds outb(0, DMA2_MASK_REG); 3311da177e4SLinus Torvalds 3321da177e4SLinus Torvalds if (alpha_using_srm) 3331da177e4SLinus Torvalds alpha_mv.device_interrupt = clipper_srm_device_interrupt; 3341da177e4SLinus Torvalds 3351da177e4SLinus Torvalds tsunami_update_irq_hw(0); 3361da177e4SLinus Torvalds 3371da177e4SLinus Torvalds init_i8259a_irqs(); 3381da177e4SLinus Torvalds init_tsunami_irqs(&clipper_irq_type, 24, 63); 3391da177e4SLinus Torvalds } 3401da177e4SLinus Torvalds 3411da177e4SLinus Torvalds 3421da177e4SLinus Torvalds /* 3431da177e4SLinus Torvalds * PCI Fixup configuration. 3441da177e4SLinus Torvalds * 3451da177e4SLinus Torvalds * Summary @ TSUNAMI_CSR_DIM0: 3461da177e4SLinus Torvalds * Bit Meaning 3471da177e4SLinus Torvalds * 0-17 Unused 3481da177e4SLinus Torvalds *18 Interrupt SCSI B (Adaptec 7895 builtin) 3491da177e4SLinus Torvalds *19 Interrupt SCSI A (Adaptec 7895 builtin) 3501da177e4SLinus Torvalds *20 Interrupt Line D from slot 2 PCI0 3511da177e4SLinus Torvalds *21 Interrupt Line C from slot 2 PCI0 3521da177e4SLinus Torvalds *22 Interrupt Line B from slot 2 PCI0 3531da177e4SLinus Torvalds *23 Interrupt Line A from slot 2 PCI0 3541da177e4SLinus Torvalds *24 Interrupt Line D from slot 1 PCI0 3551da177e4SLinus Torvalds *25 Interrupt Line C from slot 1 PCI0 3561da177e4SLinus Torvalds *26 Interrupt Line B from slot 1 PCI0 3571da177e4SLinus Torvalds *27 Interrupt Line A from slot 1 PCI0 3581da177e4SLinus Torvalds *28 Interrupt Line D from slot 0 PCI0 3591da177e4SLinus Torvalds *29 Interrupt Line C from slot 0 PCI0 3601da177e4SLinus Torvalds *30 Interrupt Line B from slot 0 PCI0 3611da177e4SLinus Torvalds *31 Interrupt Line A from slot 0 PCI0 3621da177e4SLinus Torvalds * 3631da177e4SLinus Torvalds *32 Interrupt Line D from slot 3 PCI1 3641da177e4SLinus Torvalds *33 Interrupt Line C from slot 3 PCI1 3651da177e4SLinus Torvalds *34 Interrupt Line B from slot 3 PCI1 3661da177e4SLinus Torvalds *35 Interrupt Line A from slot 3 PCI1 3671da177e4SLinus Torvalds *36 Interrupt Line D from slot 2 PCI1 3681da177e4SLinus Torvalds *37 Interrupt Line C from slot 2 PCI1 3691da177e4SLinus Torvalds *38 Interrupt Line B from slot 2 PCI1 3701da177e4SLinus Torvalds *39 Interrupt Line A from slot 2 PCI1 3711da177e4SLinus Torvalds *40 Interrupt Line D from slot 1 PCI1 3721da177e4SLinus Torvalds *41 Interrupt Line C from slot 1 PCI1 3731da177e4SLinus Torvalds *42 Interrupt Line B from slot 1 PCI1 3741da177e4SLinus Torvalds *43 Interrupt Line A from slot 1 PCI1 3751da177e4SLinus Torvalds *44 Interrupt Line D from slot 0 PCI1 3761da177e4SLinus Torvalds *45 Interrupt Line C from slot 0 PCI1 3771da177e4SLinus Torvalds *46 Interrupt Line B from slot 0 PCI1 3781da177e4SLinus Torvalds *47 Interrupt Line A from slot 0 PCI1 3791da177e4SLinus Torvalds *48-52 Unused 3801da177e4SLinus Torvalds *53 PCI0 NMI (from Cypress) 3811da177e4SLinus Torvalds *54 PCI0 SMI INT (from Cypress) 3821da177e4SLinus Torvalds *55 PCI0 ISA Interrupt (from Cypress) 3831da177e4SLinus Torvalds *56-60 Unused 3841da177e4SLinus Torvalds *61 PCI1 Bus Error 3851da177e4SLinus Torvalds *62 PCI0 Bus Error 3861da177e4SLinus Torvalds *63 Reserved 3871da177e4SLinus Torvalds * 3881da177e4SLinus Torvalds * IdSel 3891da177e4SLinus Torvalds * 5 Cypress Bridge I/O 3901da177e4SLinus Torvalds * 6 SCSI Adaptec builtin 3911da177e4SLinus Torvalds * 7 64 bit PCI option slot 0 (all busses) 3921da177e4SLinus Torvalds * 8 64 bit PCI option slot 1 (all busses) 3931da177e4SLinus Torvalds * 9 64 bit PCI option slot 2 (all busses) 3941da177e4SLinus Torvalds * 10 64 bit PCI option slot 3 (not bus 0) 3951da177e4SLinus Torvalds */ 3961da177e4SLinus Torvalds 3971da177e4SLinus Torvalds static int __init 398997a51aeSIvan Kokshaysky isa_irq_fixup(struct pci_dev *dev, int irq) 399997a51aeSIvan Kokshaysky { 400997a51aeSIvan Kokshaysky u8 irq8; 401997a51aeSIvan Kokshaysky 402997a51aeSIvan Kokshaysky if (irq > 0) 403997a51aeSIvan Kokshaysky return irq; 404997a51aeSIvan Kokshaysky 405997a51aeSIvan Kokshaysky /* This interrupt is routed via ISA bridge, so we'll 406997a51aeSIvan Kokshaysky just have to trust whatever value the console might 407997a51aeSIvan Kokshaysky have assigned. */ 408997a51aeSIvan Kokshaysky pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8); 409997a51aeSIvan Kokshaysky 410997a51aeSIvan Kokshaysky return irq8 & 0xf; 411997a51aeSIvan Kokshaysky } 412997a51aeSIvan Kokshaysky 413997a51aeSIvan Kokshaysky static int __init 4141da177e4SLinus Torvalds dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 4151da177e4SLinus Torvalds { 4161da177e4SLinus Torvalds static char irq_tab[6][5] __initdata = { 4171da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 4181da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 5 ISA Bridge */ 4191da177e4SLinus Torvalds { 16+ 3, 16+ 3, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin*/ 4201da177e4SLinus Torvalds { 16+15, 16+15, 16+14, 16+13, 16+12}, /* IdSel 7 slot 0 */ 4211da177e4SLinus Torvalds { 16+11, 16+11, 16+10, 16+ 9, 16+ 8}, /* IdSel 8 slot 1 */ 4221da177e4SLinus Torvalds { 16+ 7, 16+ 7, 16+ 6, 16+ 5, 16+ 4}, /* IdSel 9 slot 2 */ 4231da177e4SLinus Torvalds { 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0} /* IdSel 10 slot 3 */ 4241da177e4SLinus Torvalds }; 4251da177e4SLinus Torvalds const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5; 4261da177e4SLinus Torvalds struct pci_controller *hose = dev->sysdata; 4271da177e4SLinus Torvalds int irq = COMMON_TABLE_LOOKUP; 4281da177e4SLinus Torvalds 429997a51aeSIvan Kokshaysky if (irq > 0) 4301da177e4SLinus Torvalds irq += 16 * hose->index; 4311da177e4SLinus Torvalds 432997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, irq); 4331da177e4SLinus Torvalds } 4341da177e4SLinus Torvalds 4351da177e4SLinus Torvalds static int __init 4361da177e4SLinus Torvalds monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 4371da177e4SLinus Torvalds { 4381da177e4SLinus Torvalds static char irq_tab[13][5] __initdata = { 4391da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 4401da177e4SLinus Torvalds { 45, 45, 45, 45, 45}, /* IdSel 3 21143 PCI1 */ 4411da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 4 unused */ 4421da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 5 unused */ 4431da177e4SLinus Torvalds { 47, 47, 47, 47, 47}, /* IdSel 6 SCSI PCI1 */ 4441da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 7 ISA Bridge */ 4451da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 8 P2P PCI1 */ 4461da177e4SLinus Torvalds #if 1 4471da177e4SLinus Torvalds { 28, 28, 29, 30, 31}, /* IdSel 14 slot 4 PCI2*/ 4481da177e4SLinus Torvalds { 24, 24, 25, 26, 27}, /* IdSel 15 slot 5 PCI2*/ 4491da177e4SLinus Torvalds #else 4501da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 9 unused */ 4511da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 10 unused */ 4521da177e4SLinus Torvalds #endif 4531da177e4SLinus Torvalds { 40, 40, 41, 42, 43}, /* IdSel 11 slot 1 PCI0*/ 4541da177e4SLinus Torvalds { 36, 36, 37, 38, 39}, /* IdSel 12 slot 2 PCI0*/ 4551da177e4SLinus Torvalds { 32, 32, 33, 34, 35}, /* IdSel 13 slot 3 PCI0*/ 4561da177e4SLinus Torvalds { 28, 28, 29, 30, 31}, /* IdSel 14 slot 4 PCI2*/ 4571da177e4SLinus Torvalds { 24, 24, 25, 26, 27} /* IdSel 15 slot 5 PCI2*/ 4581da177e4SLinus Torvalds }; 4591da177e4SLinus Torvalds const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5; 460997a51aeSIvan Kokshaysky 461997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP); 4621da177e4SLinus Torvalds } 4631da177e4SLinus Torvalds 4641da177e4SLinus Torvalds static u8 __init 4651da177e4SLinus Torvalds monet_swizzle(struct pci_dev *dev, u8 *pinp) 4661da177e4SLinus Torvalds { 4671da177e4SLinus Torvalds struct pci_controller *hose = dev->sysdata; 4681da177e4SLinus Torvalds int slot, pin = *pinp; 4691da177e4SLinus Torvalds 4701da177e4SLinus Torvalds if (!dev->bus->parent) { 4711da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4721da177e4SLinus Torvalds } 4731da177e4SLinus Torvalds /* Check for the built-in bridge on hose 1. */ 4741da177e4SLinus Torvalds else if (hose->index == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) { 4751da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4761da177e4SLinus Torvalds } else { 4771da177e4SLinus Torvalds /* Must be a card-based bridge. */ 4781da177e4SLinus Torvalds do { 4791da177e4SLinus Torvalds /* Check for built-in bridge on hose 1. */ 4801da177e4SLinus Torvalds if (hose->index == 1 && 4811da177e4SLinus Torvalds PCI_SLOT(dev->bus->self->devfn) == 8) { 4821da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4831da177e4SLinus Torvalds break; 4841da177e4SLinus Torvalds } 4851da177e4SLinus Torvalds pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)) ; 4861da177e4SLinus Torvalds 4871da177e4SLinus Torvalds /* Move up the chain of bridges. */ 4881da177e4SLinus Torvalds dev = dev->bus->self; 4891da177e4SLinus Torvalds /* Slot of the next bridge. */ 4901da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4911da177e4SLinus Torvalds } while (dev->bus->self); 4921da177e4SLinus Torvalds } 4931da177e4SLinus Torvalds *pinp = pin; 4941da177e4SLinus Torvalds return slot; 4951da177e4SLinus Torvalds } 4961da177e4SLinus Torvalds 4971da177e4SLinus Torvalds static int __init 4981da177e4SLinus Torvalds webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 4991da177e4SLinus Torvalds { 5001da177e4SLinus Torvalds static char irq_tab[13][5] __initdata = { 5011da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 5021da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 7 ISA Bridge */ 5031da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 8 unused */ 5041da177e4SLinus Torvalds { 29, 29, 29, 29, 29}, /* IdSel 9 21143 #1 */ 5051da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 10 unused */ 5061da177e4SLinus Torvalds { 30, 30, 30, 30, 30}, /* IdSel 11 21143 #2 */ 5071da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 12 unused */ 5081da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 13 unused */ 5091da177e4SLinus Torvalds { 35, 35, 34, 33, 32}, /* IdSel 14 slot 0 */ 5101da177e4SLinus Torvalds { 39, 39, 38, 37, 36}, /* IdSel 15 slot 1 */ 5111da177e4SLinus Torvalds { 43, 43, 42, 41, 40}, /* IdSel 16 slot 2 */ 5121da177e4SLinus Torvalds { 47, 47, 46, 45, 44}, /* IdSel 17 slot 3 */ 5131da177e4SLinus Torvalds }; 5141da177e4SLinus Torvalds const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5; 515997a51aeSIvan Kokshaysky 516997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP); 5171da177e4SLinus Torvalds } 5181da177e4SLinus Torvalds 5191da177e4SLinus Torvalds static int __init 5201da177e4SLinus Torvalds clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 5211da177e4SLinus Torvalds { 5221da177e4SLinus Torvalds static char irq_tab[7][5] __initdata = { 5231da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 5241da177e4SLinus Torvalds { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 1 slot 1 */ 5251da177e4SLinus Torvalds { 16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 2 slot 2 */ 5261da177e4SLinus Torvalds { 16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 3 slot 3 */ 5271da177e4SLinus Torvalds { 16+20, 16+20, 16+21, 16+22, 16+23}, /* IdSel 4 slot 4 */ 5281da177e4SLinus Torvalds { 16+24, 16+24, 16+25, 16+26, 16+27}, /* IdSel 5 slot 5 */ 5291da177e4SLinus Torvalds { 16+28, 16+28, 16+29, 16+30, 16+31}, /* IdSel 6 slot 6 */ 5301da177e4SLinus Torvalds { -1, -1, -1, -1, -1} /* IdSel 7 ISA Bridge */ 5311da177e4SLinus Torvalds }; 5321da177e4SLinus Torvalds const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5; 5331da177e4SLinus Torvalds struct pci_controller *hose = dev->sysdata; 5341da177e4SLinus Torvalds int irq = COMMON_TABLE_LOOKUP; 5351da177e4SLinus Torvalds 5361da177e4SLinus Torvalds if (irq > 0) 5371da177e4SLinus Torvalds irq += 16 * hose->index; 5381da177e4SLinus Torvalds 539997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, irq); 5401da177e4SLinus Torvalds } 5411da177e4SLinus Torvalds 5421da177e4SLinus Torvalds static void __init 5431da177e4SLinus Torvalds dp264_init_pci(void) 5441da177e4SLinus Torvalds { 5451da177e4SLinus Torvalds common_init_pci(); 5461da177e4SLinus Torvalds SMC669_Init(0); 5471da177e4SLinus Torvalds } 5481da177e4SLinus Torvalds 5491da177e4SLinus Torvalds static void __init 5501da177e4SLinus Torvalds monet_init_pci(void) 5511da177e4SLinus Torvalds { 5521da177e4SLinus Torvalds common_init_pci(); 5531da177e4SLinus Torvalds SMC669_Init(1); 5541da177e4SLinus Torvalds es1888_init(); 5551da177e4SLinus Torvalds } 5561da177e4SLinus Torvalds 5571da177e4SLinus Torvalds static void __init 5581da177e4SLinus Torvalds webbrick_init_arch(void) 5591da177e4SLinus Torvalds { 5601da177e4SLinus Torvalds tsunami_init_arch(); 5611da177e4SLinus Torvalds 5621da177e4SLinus Torvalds /* Tsunami caches 4 PTEs at a time; DS10 has only 1 hose. */ 5631da177e4SLinus Torvalds hose_head->sg_isa->align_entry = 4; 5641da177e4SLinus Torvalds hose_head->sg_pci->align_entry = 4; 5651da177e4SLinus Torvalds } 5661da177e4SLinus Torvalds 5671da177e4SLinus Torvalds 5681da177e4SLinus Torvalds /* 5691da177e4SLinus Torvalds * The System Vectors 5701da177e4SLinus Torvalds */ 5711da177e4SLinus Torvalds 5721da177e4SLinus Torvalds struct alpha_machine_vector dp264_mv __initmv = { 5731da177e4SLinus Torvalds .vector_name = "DP264", 5741da177e4SLinus Torvalds DO_EV6_MMU, 5751da177e4SLinus Torvalds DO_DEFAULT_RTC, 5761da177e4SLinus Torvalds DO_TSUNAMI_IO, 5771da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 5781da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 5791da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 5801da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 5811da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 5821da177e4SLinus Torvalds 5831da177e4SLinus Torvalds .nr_irqs = 64, 5841da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 5851da177e4SLinus Torvalds 5861da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 5871da177e4SLinus Torvalds .init_irq = dp264_init_irq, 5881da177e4SLinus Torvalds .init_rtc = common_init_rtc, 5891da177e4SLinus Torvalds .init_pci = dp264_init_pci, 5901da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 5911da177e4SLinus Torvalds .pci_map_irq = dp264_map_irq, 5921da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 5931da177e4SLinus Torvalds }; 5941da177e4SLinus Torvalds ALIAS_MV(dp264) 5951da177e4SLinus Torvalds 5961da177e4SLinus Torvalds struct alpha_machine_vector monet_mv __initmv = { 5971da177e4SLinus Torvalds .vector_name = "Monet", 5981da177e4SLinus Torvalds DO_EV6_MMU, 5991da177e4SLinus Torvalds DO_DEFAULT_RTC, 6001da177e4SLinus Torvalds DO_TSUNAMI_IO, 6011da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 6021da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 6031da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 6041da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 6051da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 6061da177e4SLinus Torvalds 6071da177e4SLinus Torvalds .nr_irqs = 64, 6081da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 6091da177e4SLinus Torvalds 6101da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 6111da177e4SLinus Torvalds .init_irq = dp264_init_irq, 6121da177e4SLinus Torvalds .init_rtc = common_init_rtc, 6131da177e4SLinus Torvalds .init_pci = monet_init_pci, 6141da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 6151da177e4SLinus Torvalds .pci_map_irq = monet_map_irq, 6161da177e4SLinus Torvalds .pci_swizzle = monet_swizzle, 6171da177e4SLinus Torvalds }; 6181da177e4SLinus Torvalds 6191da177e4SLinus Torvalds struct alpha_machine_vector webbrick_mv __initmv = { 6201da177e4SLinus Torvalds .vector_name = "Webbrick", 6211da177e4SLinus Torvalds DO_EV6_MMU, 6221da177e4SLinus Torvalds DO_DEFAULT_RTC, 6231da177e4SLinus Torvalds DO_TSUNAMI_IO, 6241da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 6251da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 6261da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 6271da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 6281da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 6291da177e4SLinus Torvalds 6301da177e4SLinus Torvalds .nr_irqs = 64, 6311da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 6321da177e4SLinus Torvalds 6331da177e4SLinus Torvalds .init_arch = webbrick_init_arch, 6341da177e4SLinus Torvalds .init_irq = dp264_init_irq, 6351da177e4SLinus Torvalds .init_rtc = common_init_rtc, 6361da177e4SLinus Torvalds .init_pci = common_init_pci, 6371da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 6381da177e4SLinus Torvalds .pci_map_irq = webbrick_map_irq, 6391da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 6401da177e4SLinus Torvalds }; 6411da177e4SLinus Torvalds 6421da177e4SLinus Torvalds struct alpha_machine_vector clipper_mv __initmv = { 6431da177e4SLinus Torvalds .vector_name = "Clipper", 6441da177e4SLinus Torvalds DO_EV6_MMU, 6451da177e4SLinus Torvalds DO_DEFAULT_RTC, 6461da177e4SLinus Torvalds DO_TSUNAMI_IO, 6471da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 6481da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 6491da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 6501da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 6511da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 6521da177e4SLinus Torvalds 6531da177e4SLinus Torvalds .nr_irqs = 64, 6541da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 6551da177e4SLinus Torvalds 6561da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 6571da177e4SLinus Torvalds .init_irq = clipper_init_irq, 6581da177e4SLinus Torvalds .init_rtc = common_init_rtc, 6591da177e4SLinus Torvalds .init_pci = common_init_pci, 6601da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 6611da177e4SLinus Torvalds .pci_map_irq = clipper_map_irq, 6621da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 6631da177e4SLinus Torvalds }; 6641da177e4SLinus Torvalds 6651da177e4SLinus Torvalds /* Sharks strongly resemble Clipper, at least as far 6661da177e4SLinus Torvalds * as interrupt routing, etc, so we're using the 6671da177e4SLinus Torvalds * same functions as Clipper does 6681da177e4SLinus Torvalds */ 6691da177e4SLinus Torvalds 6701da177e4SLinus Torvalds struct alpha_machine_vector shark_mv __initmv = { 6711da177e4SLinus Torvalds .vector_name = "Shark", 6721da177e4SLinus Torvalds DO_EV6_MMU, 6731da177e4SLinus Torvalds DO_DEFAULT_RTC, 6741da177e4SLinus Torvalds DO_TSUNAMI_IO, 6751da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 6761da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 6771da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 6781da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 6791da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 6801da177e4SLinus Torvalds 6811da177e4SLinus Torvalds .nr_irqs = 64, 6821da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 6831da177e4SLinus Torvalds 6841da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 6851da177e4SLinus Torvalds .init_irq = clipper_init_irq, 6861da177e4SLinus Torvalds .init_rtc = common_init_rtc, 6871da177e4SLinus Torvalds .init_pci = common_init_pci, 6881da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 6891da177e4SLinus Torvalds .pci_map_irq = clipper_map_irq, 6901da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 6911da177e4SLinus Torvalds }; 6921da177e4SLinus Torvalds 6931da177e4SLinus Torvalds /* No alpha_mv alias for webbrick/monet/clipper, since we compile them 6941da177e4SLinus Torvalds in unconditionally with DP264; setup_arch knows how to cope. */ 695