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/system.h> 251da177e4SLinus Torvalds #include <asm/dma.h> 261da177e4SLinus Torvalds #include <asm/irq.h> 271da177e4SLinus Torvalds #include <asm/mmu_context.h> 281da177e4SLinus Torvalds #include <asm/io.h> 291da177e4SLinus Torvalds #include <asm/pgtable.h> 301da177e4SLinus Torvalds #include <asm/core_tsunami.h> 311da177e4SLinus Torvalds #include <asm/hwrpb.h> 321da177e4SLinus Torvalds #include <asm/tlbflush.h> 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds #include "proto.h" 351da177e4SLinus Torvalds #include "irq_impl.h" 361da177e4SLinus Torvalds #include "pci_impl.h" 371da177e4SLinus Torvalds #include "machvec_impl.h" 381da177e4SLinus Torvalds 391da177e4SLinus Torvalds 401da177e4SLinus Torvalds /* Note mask bit is true for ENABLED irqs. */ 411da177e4SLinus Torvalds static unsigned long cached_irq_mask; 421da177e4SLinus Torvalds /* dp264 boards handle at max four CPUs */ 431da177e4SLinus Torvalds static unsigned long cpu_irq_affinity[4] = { 0UL, 0UL, 0UL, 0UL }; 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds DEFINE_SPINLOCK(dp264_irq_lock); 461da177e4SLinus Torvalds 471da177e4SLinus Torvalds static void 481da177e4SLinus Torvalds tsunami_update_irq_hw(unsigned long mask) 491da177e4SLinus Torvalds { 501da177e4SLinus Torvalds register tsunami_cchip *cchip = TSUNAMI_cchip; 511da177e4SLinus Torvalds unsigned long isa_enable = 1UL << 55; 521da177e4SLinus Torvalds register int bcpu = boot_cpuid; 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds #ifdef CONFIG_SMP 551da177e4SLinus Torvalds volatile unsigned long *dim0, *dim1, *dim2, *dim3; 561da177e4SLinus Torvalds unsigned long mask0, mask1, mask2, mask3, dummy; 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds mask &= ~isa_enable; 591da177e4SLinus Torvalds mask0 = mask & cpu_irq_affinity[0]; 601da177e4SLinus Torvalds mask1 = mask & cpu_irq_affinity[1]; 611da177e4SLinus Torvalds mask2 = mask & cpu_irq_affinity[2]; 621da177e4SLinus Torvalds mask3 = mask & cpu_irq_affinity[3]; 631da177e4SLinus Torvalds 641da177e4SLinus Torvalds if (bcpu == 0) mask0 |= isa_enable; 651da177e4SLinus Torvalds else if (bcpu == 1) mask1 |= isa_enable; 661da177e4SLinus Torvalds else if (bcpu == 2) mask2 |= isa_enable; 671da177e4SLinus Torvalds else mask3 |= isa_enable; 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds dim0 = &cchip->dim0.csr; 701da177e4SLinus Torvalds dim1 = &cchip->dim1.csr; 711da177e4SLinus Torvalds dim2 = &cchip->dim2.csr; 721da177e4SLinus Torvalds dim3 = &cchip->dim3.csr; 731da177e4SLinus Torvalds if (!cpu_possible(0)) dim0 = &dummy; 741da177e4SLinus Torvalds if (!cpu_possible(1)) dim1 = &dummy; 751da177e4SLinus Torvalds if (!cpu_possible(2)) dim2 = &dummy; 761da177e4SLinus Torvalds if (!cpu_possible(3)) dim3 = &dummy; 771da177e4SLinus Torvalds 781da177e4SLinus Torvalds *dim0 = mask0; 791da177e4SLinus Torvalds *dim1 = mask1; 801da177e4SLinus Torvalds *dim2 = mask2; 811da177e4SLinus Torvalds *dim3 = mask3; 821da177e4SLinus Torvalds mb(); 831da177e4SLinus Torvalds *dim0; 841da177e4SLinus Torvalds *dim1; 851da177e4SLinus Torvalds *dim2; 861da177e4SLinus Torvalds *dim3; 871da177e4SLinus Torvalds #else 881da177e4SLinus Torvalds volatile unsigned long *dimB; 891da177e4SLinus Torvalds if (bcpu == 0) dimB = &cchip->dim0.csr; 901da177e4SLinus Torvalds else if (bcpu == 1) dimB = &cchip->dim1.csr; 911da177e4SLinus Torvalds else if (bcpu == 2) dimB = &cchip->dim2.csr; 921da177e4SLinus Torvalds else dimB = &cchip->dim3.csr; 931da177e4SLinus Torvalds 941da177e4SLinus Torvalds *dimB = mask | isa_enable; 951da177e4SLinus Torvalds mb(); 961da177e4SLinus Torvalds *dimB; 971da177e4SLinus Torvalds #endif 981da177e4SLinus Torvalds } 991da177e4SLinus Torvalds 1001da177e4SLinus Torvalds static void 101*d677f450SThomas Gleixner dp264_enable_irq(struct irq_data *d) 1021da177e4SLinus Torvalds { 1031da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 104*d677f450SThomas Gleixner cached_irq_mask |= 1UL << d->irq; 1051da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1061da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1071da177e4SLinus Torvalds } 1081da177e4SLinus Torvalds 1091da177e4SLinus Torvalds static void 110*d677f450SThomas Gleixner dp264_disable_irq(struct irq_data *d) 1111da177e4SLinus Torvalds { 1121da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 113*d677f450SThomas Gleixner cached_irq_mask &= ~(1UL << d->irq); 1141da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1151da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1161da177e4SLinus Torvalds } 1171da177e4SLinus Torvalds 1181da177e4SLinus Torvalds static void 119*d677f450SThomas Gleixner clipper_enable_irq(struct irq_data *d) 1201da177e4SLinus Torvalds { 1211da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 122*d677f450SThomas Gleixner cached_irq_mask |= 1UL << (d->irq - 16); 1231da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1241da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1251da177e4SLinus Torvalds } 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds static void 128*d677f450SThomas Gleixner clipper_disable_irq(struct irq_data *d) 1291da177e4SLinus Torvalds { 1301da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 131*d677f450SThomas Gleixner cached_irq_mask &= ~(1UL << (d->irq - 16)); 1321da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1331da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 1341da177e4SLinus Torvalds } 1351da177e4SLinus Torvalds 1361da177e4SLinus Torvalds static void 1371da177e4SLinus Torvalds cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity) 1381da177e4SLinus Torvalds { 1391da177e4SLinus Torvalds int cpu; 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds for (cpu = 0; cpu < 4; cpu++) { 1421da177e4SLinus Torvalds unsigned long aff = cpu_irq_affinity[cpu]; 1431da177e4SLinus Torvalds if (cpu_isset(cpu, affinity)) 1441da177e4SLinus Torvalds aff |= 1UL << irq; 1451da177e4SLinus Torvalds else 1461da177e4SLinus Torvalds aff &= ~(1UL << irq); 1471da177e4SLinus Torvalds cpu_irq_affinity[cpu] = aff; 1481da177e4SLinus Torvalds } 1491da177e4SLinus Torvalds } 1501da177e4SLinus Torvalds 151d5dedd45SYinghai Lu static int 152*d677f450SThomas Gleixner dp264_set_affinity(struct irq_data *d, const struct cpumask *affinity, 153*d677f450SThomas Gleixner bool force) 1541da177e4SLinus Torvalds { 1551da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 156*d677f450SThomas Gleixner cpu_set_irq_affinity(d->irq, *affinity); 1571da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1581da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 159d5dedd45SYinghai Lu 160d5dedd45SYinghai Lu return 0; 1611da177e4SLinus Torvalds } 1621da177e4SLinus Torvalds 163d5dedd45SYinghai Lu static int 164*d677f450SThomas Gleixner clipper_set_affinity(struct irq_data *d, const struct cpumask *affinity, 165*d677f450SThomas Gleixner bool force) 1661da177e4SLinus Torvalds { 1671da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 168*d677f450SThomas Gleixner cpu_set_irq_affinity(d->irq - 16, *affinity); 1691da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1701da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 171d5dedd45SYinghai Lu 172d5dedd45SYinghai Lu return 0; 1731da177e4SLinus Torvalds } 1741da177e4SLinus Torvalds 17544377f62SThomas Gleixner static struct irq_chip dp264_irq_type = { 1768ab1221cSThomas Gleixner .name = "DP264", 177*d677f450SThomas Gleixner .irq_unmask = dp264_enable_irq, 178*d677f450SThomas Gleixner .irq_mask = dp264_disable_irq, 179*d677f450SThomas Gleixner .irq_mask_ack = dp264_disable_irq, 180*d677f450SThomas Gleixner .irq_set_affinity = dp264_set_affinity, 1811da177e4SLinus Torvalds }; 1821da177e4SLinus Torvalds 18344377f62SThomas Gleixner static struct irq_chip clipper_irq_type = { 1848ab1221cSThomas Gleixner .name = "CLIPPER", 185*d677f450SThomas Gleixner .irq_unmask = clipper_enable_irq, 186*d677f450SThomas Gleixner .irq_mask = clipper_disable_irq, 187*d677f450SThomas Gleixner .irq_mask_ack = clipper_disable_irq, 188*d677f450SThomas Gleixner .irq_set_affinity = clipper_set_affinity, 1891da177e4SLinus Torvalds }; 1901da177e4SLinus Torvalds 1911da177e4SLinus Torvalds static void 1927ca56053SAl Viro dp264_device_interrupt(unsigned long vector) 1931da177e4SLinus Torvalds { 1941da177e4SLinus Torvalds #if 1 1951da177e4SLinus Torvalds printk("dp264_device_interrupt: NOT IMPLEMENTED YET!!\n"); 1961da177e4SLinus Torvalds #else 1971da177e4SLinus Torvalds unsigned long pld; 1981da177e4SLinus Torvalds unsigned int i; 1991da177e4SLinus Torvalds 2001da177e4SLinus Torvalds /* Read the interrupt summary register of TSUNAMI */ 2011da177e4SLinus Torvalds pld = TSUNAMI_cchip->dir0.csr; 2021da177e4SLinus Torvalds 2031da177e4SLinus Torvalds /* 2041da177e4SLinus Torvalds * Now for every possible bit set, work through them and call 2051da177e4SLinus Torvalds * the appropriate interrupt handler. 2061da177e4SLinus Torvalds */ 2071da177e4SLinus Torvalds while (pld) { 2081da177e4SLinus Torvalds i = ffz(~pld); 2091da177e4SLinus Torvalds pld &= pld - 1; /* clear least bit set */ 2101da177e4SLinus Torvalds if (i == 55) 2117ca56053SAl Viro isa_device_interrupt(vector); 2121da177e4SLinus Torvalds else 2133dbb8c62SAl Viro handle_irq(16 + i); 2141da177e4SLinus Torvalds #if 0 2151da177e4SLinus Torvalds TSUNAMI_cchip->dir0.csr = 1UL << i; mb(); 2161da177e4SLinus Torvalds tmp = TSUNAMI_cchip->dir0.csr; 2171da177e4SLinus Torvalds #endif 2181da177e4SLinus Torvalds } 2191da177e4SLinus Torvalds #endif 2201da177e4SLinus Torvalds } 2211da177e4SLinus Torvalds 2221da177e4SLinus Torvalds static void 2237ca56053SAl Viro dp264_srm_device_interrupt(unsigned long vector) 2241da177e4SLinus Torvalds { 2251da177e4SLinus Torvalds int irq; 2261da177e4SLinus Torvalds 2271da177e4SLinus Torvalds irq = (vector - 0x800) >> 4; 2281da177e4SLinus Torvalds 2291da177e4SLinus Torvalds /* 2301da177e4SLinus Torvalds * The SRM console reports PCI interrupts with a vector calculated by: 2311da177e4SLinus Torvalds * 2321da177e4SLinus Torvalds * 0x900 + (0x10 * DRIR-bit) 2331da177e4SLinus Torvalds * 2341da177e4SLinus Torvalds * So bit 16 shows up as IRQ 32, etc. 2351da177e4SLinus Torvalds * 2361da177e4SLinus Torvalds * On DP264/BRICK/MONET, we adjust it down by 16 because at least 2371da177e4SLinus Torvalds * that many of the low order bits of the DRIR are not used, and 2381da177e4SLinus Torvalds * so we don't count them. 2391da177e4SLinus Torvalds */ 2401da177e4SLinus Torvalds if (irq >= 32) 2411da177e4SLinus Torvalds irq -= 16; 2421da177e4SLinus Torvalds 2433dbb8c62SAl Viro handle_irq(irq); 2441da177e4SLinus Torvalds } 2451da177e4SLinus Torvalds 2461da177e4SLinus Torvalds static void 2477ca56053SAl Viro clipper_srm_device_interrupt(unsigned long vector) 2481da177e4SLinus Torvalds { 2491da177e4SLinus Torvalds int irq; 2501da177e4SLinus Torvalds 2511da177e4SLinus Torvalds irq = (vector - 0x800) >> 4; 2521da177e4SLinus Torvalds 2531da177e4SLinus Torvalds /* 2541da177e4SLinus Torvalds * The SRM console reports PCI interrupts with a vector calculated by: 2551da177e4SLinus Torvalds * 2561da177e4SLinus Torvalds * 0x900 + (0x10 * DRIR-bit) 2571da177e4SLinus Torvalds * 2581da177e4SLinus Torvalds * So bit 16 shows up as IRQ 32, etc. 2591da177e4SLinus Torvalds * 2601da177e4SLinus Torvalds * CLIPPER uses bits 8-47 for PCI interrupts, so we do not need 2611da177e4SLinus Torvalds * to scale down the vector reported, we just use it. 2621da177e4SLinus Torvalds * 2631da177e4SLinus Torvalds * Eg IRQ 24 is DRIR bit 8, etc, etc 2641da177e4SLinus Torvalds */ 2653dbb8c62SAl Viro handle_irq(irq); 2661da177e4SLinus Torvalds } 2671da177e4SLinus Torvalds 2681da177e4SLinus Torvalds static void __init 26944377f62SThomas Gleixner init_tsunami_irqs(struct irq_chip * ops, int imin, int imax) 2701da177e4SLinus Torvalds { 2711da177e4SLinus Torvalds long i; 2721da177e4SLinus Torvalds for (i = imin; i <= imax; ++i) { 2737d209c81SKyle McMartin set_irq_chip_and_handler(i, ops, handle_level_irq); 274*d677f450SThomas Gleixner irq_set_status_flags(i, IRQ_LEVEL); 2751da177e4SLinus Torvalds } 2761da177e4SLinus Torvalds } 2771da177e4SLinus Torvalds 2781da177e4SLinus Torvalds static void __init 2791da177e4SLinus Torvalds dp264_init_irq(void) 2801da177e4SLinus Torvalds { 2811da177e4SLinus Torvalds outb(0, DMA1_RESET_REG); 2821da177e4SLinus Torvalds outb(0, DMA2_RESET_REG); 2831da177e4SLinus Torvalds outb(DMA_MODE_CASCADE, DMA2_MODE_REG); 2841da177e4SLinus Torvalds outb(0, DMA2_MASK_REG); 2851da177e4SLinus Torvalds 2861da177e4SLinus Torvalds if (alpha_using_srm) 2871da177e4SLinus Torvalds alpha_mv.device_interrupt = dp264_srm_device_interrupt; 2881da177e4SLinus Torvalds 2891da177e4SLinus Torvalds tsunami_update_irq_hw(0); 2901da177e4SLinus Torvalds 2911da177e4SLinus Torvalds init_i8259a_irqs(); 2921da177e4SLinus Torvalds init_tsunami_irqs(&dp264_irq_type, 16, 47); 2931da177e4SLinus Torvalds } 2941da177e4SLinus Torvalds 2951da177e4SLinus Torvalds static void __init 2961da177e4SLinus Torvalds clipper_init_irq(void) 2971da177e4SLinus Torvalds { 2981da177e4SLinus Torvalds outb(0, DMA1_RESET_REG); 2991da177e4SLinus Torvalds outb(0, DMA2_RESET_REG); 3001da177e4SLinus Torvalds outb(DMA_MODE_CASCADE, DMA2_MODE_REG); 3011da177e4SLinus Torvalds outb(0, DMA2_MASK_REG); 3021da177e4SLinus Torvalds 3031da177e4SLinus Torvalds if (alpha_using_srm) 3041da177e4SLinus Torvalds alpha_mv.device_interrupt = clipper_srm_device_interrupt; 3051da177e4SLinus Torvalds 3061da177e4SLinus Torvalds tsunami_update_irq_hw(0); 3071da177e4SLinus Torvalds 3081da177e4SLinus Torvalds init_i8259a_irqs(); 3091da177e4SLinus Torvalds init_tsunami_irqs(&clipper_irq_type, 24, 63); 3101da177e4SLinus Torvalds } 3111da177e4SLinus Torvalds 3121da177e4SLinus Torvalds 3131da177e4SLinus Torvalds /* 3141da177e4SLinus Torvalds * PCI Fixup configuration. 3151da177e4SLinus Torvalds * 3161da177e4SLinus Torvalds * Summary @ TSUNAMI_CSR_DIM0: 3171da177e4SLinus Torvalds * Bit Meaning 3181da177e4SLinus Torvalds * 0-17 Unused 3191da177e4SLinus Torvalds *18 Interrupt SCSI B (Adaptec 7895 builtin) 3201da177e4SLinus Torvalds *19 Interrupt SCSI A (Adaptec 7895 builtin) 3211da177e4SLinus Torvalds *20 Interrupt Line D from slot 2 PCI0 3221da177e4SLinus Torvalds *21 Interrupt Line C from slot 2 PCI0 3231da177e4SLinus Torvalds *22 Interrupt Line B from slot 2 PCI0 3241da177e4SLinus Torvalds *23 Interrupt Line A from slot 2 PCI0 3251da177e4SLinus Torvalds *24 Interrupt Line D from slot 1 PCI0 3261da177e4SLinus Torvalds *25 Interrupt Line C from slot 1 PCI0 3271da177e4SLinus Torvalds *26 Interrupt Line B from slot 1 PCI0 3281da177e4SLinus Torvalds *27 Interrupt Line A from slot 1 PCI0 3291da177e4SLinus Torvalds *28 Interrupt Line D from slot 0 PCI0 3301da177e4SLinus Torvalds *29 Interrupt Line C from slot 0 PCI0 3311da177e4SLinus Torvalds *30 Interrupt Line B from slot 0 PCI0 3321da177e4SLinus Torvalds *31 Interrupt Line A from slot 0 PCI0 3331da177e4SLinus Torvalds * 3341da177e4SLinus Torvalds *32 Interrupt Line D from slot 3 PCI1 3351da177e4SLinus Torvalds *33 Interrupt Line C from slot 3 PCI1 3361da177e4SLinus Torvalds *34 Interrupt Line B from slot 3 PCI1 3371da177e4SLinus Torvalds *35 Interrupt Line A from slot 3 PCI1 3381da177e4SLinus Torvalds *36 Interrupt Line D from slot 2 PCI1 3391da177e4SLinus Torvalds *37 Interrupt Line C from slot 2 PCI1 3401da177e4SLinus Torvalds *38 Interrupt Line B from slot 2 PCI1 3411da177e4SLinus Torvalds *39 Interrupt Line A from slot 2 PCI1 3421da177e4SLinus Torvalds *40 Interrupt Line D from slot 1 PCI1 3431da177e4SLinus Torvalds *41 Interrupt Line C from slot 1 PCI1 3441da177e4SLinus Torvalds *42 Interrupt Line B from slot 1 PCI1 3451da177e4SLinus Torvalds *43 Interrupt Line A from slot 1 PCI1 3461da177e4SLinus Torvalds *44 Interrupt Line D from slot 0 PCI1 3471da177e4SLinus Torvalds *45 Interrupt Line C from slot 0 PCI1 3481da177e4SLinus Torvalds *46 Interrupt Line B from slot 0 PCI1 3491da177e4SLinus Torvalds *47 Interrupt Line A from slot 0 PCI1 3501da177e4SLinus Torvalds *48-52 Unused 3511da177e4SLinus Torvalds *53 PCI0 NMI (from Cypress) 3521da177e4SLinus Torvalds *54 PCI0 SMI INT (from Cypress) 3531da177e4SLinus Torvalds *55 PCI0 ISA Interrupt (from Cypress) 3541da177e4SLinus Torvalds *56-60 Unused 3551da177e4SLinus Torvalds *61 PCI1 Bus Error 3561da177e4SLinus Torvalds *62 PCI0 Bus Error 3571da177e4SLinus Torvalds *63 Reserved 3581da177e4SLinus Torvalds * 3591da177e4SLinus Torvalds * IdSel 3601da177e4SLinus Torvalds * 5 Cypress Bridge I/O 3611da177e4SLinus Torvalds * 6 SCSI Adaptec builtin 3621da177e4SLinus Torvalds * 7 64 bit PCI option slot 0 (all busses) 3631da177e4SLinus Torvalds * 8 64 bit PCI option slot 1 (all busses) 3641da177e4SLinus Torvalds * 9 64 bit PCI option slot 2 (all busses) 3651da177e4SLinus Torvalds * 10 64 bit PCI option slot 3 (not bus 0) 3661da177e4SLinus Torvalds */ 3671da177e4SLinus Torvalds 3681da177e4SLinus Torvalds static int __init 369997a51aeSIvan Kokshaysky isa_irq_fixup(struct pci_dev *dev, int irq) 370997a51aeSIvan Kokshaysky { 371997a51aeSIvan Kokshaysky u8 irq8; 372997a51aeSIvan Kokshaysky 373997a51aeSIvan Kokshaysky if (irq > 0) 374997a51aeSIvan Kokshaysky return irq; 375997a51aeSIvan Kokshaysky 376997a51aeSIvan Kokshaysky /* This interrupt is routed via ISA bridge, so we'll 377997a51aeSIvan Kokshaysky just have to trust whatever value the console might 378997a51aeSIvan Kokshaysky have assigned. */ 379997a51aeSIvan Kokshaysky pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8); 380997a51aeSIvan Kokshaysky 381997a51aeSIvan Kokshaysky return irq8 & 0xf; 382997a51aeSIvan Kokshaysky } 383997a51aeSIvan Kokshaysky 384997a51aeSIvan Kokshaysky static int __init 3851da177e4SLinus Torvalds dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 3861da177e4SLinus Torvalds { 3871da177e4SLinus Torvalds static char irq_tab[6][5] __initdata = { 3881da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 3891da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 5 ISA Bridge */ 3901da177e4SLinus Torvalds { 16+ 3, 16+ 3, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin*/ 3911da177e4SLinus Torvalds { 16+15, 16+15, 16+14, 16+13, 16+12}, /* IdSel 7 slot 0 */ 3921da177e4SLinus Torvalds { 16+11, 16+11, 16+10, 16+ 9, 16+ 8}, /* IdSel 8 slot 1 */ 3931da177e4SLinus Torvalds { 16+ 7, 16+ 7, 16+ 6, 16+ 5, 16+ 4}, /* IdSel 9 slot 2 */ 3941da177e4SLinus Torvalds { 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0} /* IdSel 10 slot 3 */ 3951da177e4SLinus Torvalds }; 3961da177e4SLinus Torvalds const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5; 3971da177e4SLinus Torvalds struct pci_controller *hose = dev->sysdata; 3981da177e4SLinus Torvalds int irq = COMMON_TABLE_LOOKUP; 3991da177e4SLinus Torvalds 400997a51aeSIvan Kokshaysky if (irq > 0) 4011da177e4SLinus Torvalds irq += 16 * hose->index; 4021da177e4SLinus Torvalds 403997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, irq); 4041da177e4SLinus Torvalds } 4051da177e4SLinus Torvalds 4061da177e4SLinus Torvalds static int __init 4071da177e4SLinus Torvalds monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 4081da177e4SLinus Torvalds { 4091da177e4SLinus Torvalds static char irq_tab[13][5] __initdata = { 4101da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 4111da177e4SLinus Torvalds { 45, 45, 45, 45, 45}, /* IdSel 3 21143 PCI1 */ 4121da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 4 unused */ 4131da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 5 unused */ 4141da177e4SLinus Torvalds { 47, 47, 47, 47, 47}, /* IdSel 6 SCSI PCI1 */ 4151da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 7 ISA Bridge */ 4161da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 8 P2P PCI1 */ 4171da177e4SLinus Torvalds #if 1 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 #else 4211da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 9 unused */ 4221da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 10 unused */ 4231da177e4SLinus Torvalds #endif 4241da177e4SLinus Torvalds { 40, 40, 41, 42, 43}, /* IdSel 11 slot 1 PCI0*/ 4251da177e4SLinus Torvalds { 36, 36, 37, 38, 39}, /* IdSel 12 slot 2 PCI0*/ 4261da177e4SLinus Torvalds { 32, 32, 33, 34, 35}, /* IdSel 13 slot 3 PCI0*/ 4271da177e4SLinus Torvalds { 28, 28, 29, 30, 31}, /* IdSel 14 slot 4 PCI2*/ 4281da177e4SLinus Torvalds { 24, 24, 25, 26, 27} /* IdSel 15 slot 5 PCI2*/ 4291da177e4SLinus Torvalds }; 4301da177e4SLinus Torvalds const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5; 431997a51aeSIvan Kokshaysky 432997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP); 4331da177e4SLinus Torvalds } 4341da177e4SLinus Torvalds 4351da177e4SLinus Torvalds static u8 __init 4361da177e4SLinus Torvalds monet_swizzle(struct pci_dev *dev, u8 *pinp) 4371da177e4SLinus Torvalds { 4381da177e4SLinus Torvalds struct pci_controller *hose = dev->sysdata; 4391da177e4SLinus Torvalds int slot, pin = *pinp; 4401da177e4SLinus Torvalds 4411da177e4SLinus Torvalds if (!dev->bus->parent) { 4421da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4431da177e4SLinus Torvalds } 4441da177e4SLinus Torvalds /* Check for the built-in bridge on hose 1. */ 4451da177e4SLinus Torvalds else if (hose->index == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) { 4461da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4471da177e4SLinus Torvalds } else { 4481da177e4SLinus Torvalds /* Must be a card-based bridge. */ 4491da177e4SLinus Torvalds do { 4501da177e4SLinus Torvalds /* Check for built-in bridge on hose 1. */ 4511da177e4SLinus Torvalds if (hose->index == 1 && 4521da177e4SLinus Torvalds PCI_SLOT(dev->bus->self->devfn) == 8) { 4531da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4541da177e4SLinus Torvalds break; 4551da177e4SLinus Torvalds } 4561be9baa0SBjorn Helgaas pin = pci_swizzle_interrupt_pin(dev, pin); 4571da177e4SLinus Torvalds 4581da177e4SLinus Torvalds /* Move up the chain of bridges. */ 4591da177e4SLinus Torvalds dev = dev->bus->self; 4601da177e4SLinus Torvalds /* Slot of the next bridge. */ 4611da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4621da177e4SLinus Torvalds } while (dev->bus->self); 4631da177e4SLinus Torvalds } 4641da177e4SLinus Torvalds *pinp = pin; 4651da177e4SLinus Torvalds return slot; 4661da177e4SLinus Torvalds } 4671da177e4SLinus Torvalds 4681da177e4SLinus Torvalds static int __init 4691da177e4SLinus Torvalds webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 4701da177e4SLinus Torvalds { 4711da177e4SLinus Torvalds static char irq_tab[13][5] __initdata = { 4721da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 4731da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 7 ISA Bridge */ 4741da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 8 unused */ 4751da177e4SLinus Torvalds { 29, 29, 29, 29, 29}, /* IdSel 9 21143 #1 */ 4761da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 10 unused */ 4771da177e4SLinus Torvalds { 30, 30, 30, 30, 30}, /* IdSel 11 21143 #2 */ 4781da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 12 unused */ 4791da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 13 unused */ 4801da177e4SLinus Torvalds { 35, 35, 34, 33, 32}, /* IdSel 14 slot 0 */ 4811da177e4SLinus Torvalds { 39, 39, 38, 37, 36}, /* IdSel 15 slot 1 */ 4821da177e4SLinus Torvalds { 43, 43, 42, 41, 40}, /* IdSel 16 slot 2 */ 4831da177e4SLinus Torvalds { 47, 47, 46, 45, 44}, /* IdSel 17 slot 3 */ 4841da177e4SLinus Torvalds }; 4851da177e4SLinus Torvalds const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5; 486997a51aeSIvan Kokshaysky 487997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP); 4881da177e4SLinus Torvalds } 4891da177e4SLinus Torvalds 4901da177e4SLinus Torvalds static int __init 4911da177e4SLinus Torvalds clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 4921da177e4SLinus Torvalds { 4931da177e4SLinus Torvalds static char irq_tab[7][5] __initdata = { 4941da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 4951da177e4SLinus Torvalds { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 1 slot 1 */ 4961da177e4SLinus Torvalds { 16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 2 slot 2 */ 4971da177e4SLinus Torvalds { 16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 3 slot 3 */ 4981da177e4SLinus Torvalds { 16+20, 16+20, 16+21, 16+22, 16+23}, /* IdSel 4 slot 4 */ 4991da177e4SLinus Torvalds { 16+24, 16+24, 16+25, 16+26, 16+27}, /* IdSel 5 slot 5 */ 5001da177e4SLinus Torvalds { 16+28, 16+28, 16+29, 16+30, 16+31}, /* IdSel 6 slot 6 */ 5011da177e4SLinus Torvalds { -1, -1, -1, -1, -1} /* IdSel 7 ISA Bridge */ 5021da177e4SLinus Torvalds }; 5031da177e4SLinus Torvalds const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5; 5041da177e4SLinus Torvalds struct pci_controller *hose = dev->sysdata; 5051da177e4SLinus Torvalds int irq = COMMON_TABLE_LOOKUP; 5061da177e4SLinus Torvalds 5071da177e4SLinus Torvalds if (irq > 0) 5081da177e4SLinus Torvalds irq += 16 * hose->index; 5091da177e4SLinus Torvalds 510997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, irq); 5111da177e4SLinus Torvalds } 5121da177e4SLinus Torvalds 5131da177e4SLinus Torvalds static void __init 5141da177e4SLinus Torvalds dp264_init_pci(void) 5151da177e4SLinus Torvalds { 5161da177e4SLinus Torvalds common_init_pci(); 5171da177e4SLinus Torvalds SMC669_Init(0); 518025a2215SJay Estabrook locate_and_init_vga(NULL); 5191da177e4SLinus Torvalds } 5201da177e4SLinus Torvalds 5211da177e4SLinus Torvalds static void __init 5221da177e4SLinus Torvalds monet_init_pci(void) 5231da177e4SLinus Torvalds { 5241da177e4SLinus Torvalds common_init_pci(); 5251da177e4SLinus Torvalds SMC669_Init(1); 5261da177e4SLinus Torvalds es1888_init(); 527025a2215SJay Estabrook locate_and_init_vga(NULL); 528025a2215SJay Estabrook } 529025a2215SJay Estabrook 530025a2215SJay Estabrook static void __init 531025a2215SJay Estabrook clipper_init_pci(void) 532025a2215SJay Estabrook { 533025a2215SJay Estabrook common_init_pci(); 534025a2215SJay Estabrook locate_and_init_vga(NULL); 5351da177e4SLinus Torvalds } 5361da177e4SLinus Torvalds 5371da177e4SLinus Torvalds static void __init 5381da177e4SLinus Torvalds webbrick_init_arch(void) 5391da177e4SLinus Torvalds { 5401da177e4SLinus Torvalds tsunami_init_arch(); 5411da177e4SLinus Torvalds 5421da177e4SLinus Torvalds /* Tsunami caches 4 PTEs at a time; DS10 has only 1 hose. */ 5431da177e4SLinus Torvalds hose_head->sg_isa->align_entry = 4; 5441da177e4SLinus Torvalds hose_head->sg_pci->align_entry = 4; 5451da177e4SLinus Torvalds } 5461da177e4SLinus Torvalds 5471da177e4SLinus Torvalds 5481da177e4SLinus Torvalds /* 5491da177e4SLinus Torvalds * The System Vectors 5501da177e4SLinus Torvalds */ 5511da177e4SLinus Torvalds 5521da177e4SLinus Torvalds struct alpha_machine_vector dp264_mv __initmv = { 5531da177e4SLinus Torvalds .vector_name = "DP264", 5541da177e4SLinus Torvalds DO_EV6_MMU, 5551da177e4SLinus Torvalds DO_DEFAULT_RTC, 5561da177e4SLinus Torvalds DO_TSUNAMI_IO, 5571da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 5581da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 5591da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 5601da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 5611da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 5621da177e4SLinus Torvalds 5631da177e4SLinus Torvalds .nr_irqs = 64, 5641da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 5651da177e4SLinus Torvalds 5661da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 5671da177e4SLinus Torvalds .init_irq = dp264_init_irq, 5681da177e4SLinus Torvalds .init_rtc = common_init_rtc, 5691da177e4SLinus Torvalds .init_pci = dp264_init_pci, 5701da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 5711da177e4SLinus Torvalds .pci_map_irq = dp264_map_irq, 5721da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 5731da177e4SLinus Torvalds }; 5741da177e4SLinus Torvalds ALIAS_MV(dp264) 5751da177e4SLinus Torvalds 5761da177e4SLinus Torvalds struct alpha_machine_vector monet_mv __initmv = { 5771da177e4SLinus Torvalds .vector_name = "Monet", 5781da177e4SLinus Torvalds DO_EV6_MMU, 5791da177e4SLinus Torvalds DO_DEFAULT_RTC, 5801da177e4SLinus Torvalds DO_TSUNAMI_IO, 5811da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 5821da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 5831da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 5841da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 5851da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 5861da177e4SLinus Torvalds 5871da177e4SLinus Torvalds .nr_irqs = 64, 5881da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 5891da177e4SLinus Torvalds 5901da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 5911da177e4SLinus Torvalds .init_irq = dp264_init_irq, 5921da177e4SLinus Torvalds .init_rtc = common_init_rtc, 5931da177e4SLinus Torvalds .init_pci = monet_init_pci, 5941da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 5951da177e4SLinus Torvalds .pci_map_irq = monet_map_irq, 5961da177e4SLinus Torvalds .pci_swizzle = monet_swizzle, 5971da177e4SLinus Torvalds }; 5981da177e4SLinus Torvalds 5991da177e4SLinus Torvalds struct alpha_machine_vector webbrick_mv __initmv = { 6001da177e4SLinus Torvalds .vector_name = "Webbrick", 6011da177e4SLinus Torvalds DO_EV6_MMU, 6021da177e4SLinus Torvalds DO_DEFAULT_RTC, 6031da177e4SLinus Torvalds DO_TSUNAMI_IO, 6041da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 6051da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 6061da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 6071da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 6081da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 6091da177e4SLinus Torvalds 6101da177e4SLinus Torvalds .nr_irqs = 64, 6111da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 6121da177e4SLinus Torvalds 6131da177e4SLinus Torvalds .init_arch = webbrick_init_arch, 6141da177e4SLinus Torvalds .init_irq = dp264_init_irq, 6151da177e4SLinus Torvalds .init_rtc = common_init_rtc, 6161da177e4SLinus Torvalds .init_pci = common_init_pci, 6171da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 6181da177e4SLinus Torvalds .pci_map_irq = webbrick_map_irq, 6191da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 6201da177e4SLinus Torvalds }; 6211da177e4SLinus Torvalds 6221da177e4SLinus Torvalds struct alpha_machine_vector clipper_mv __initmv = { 6231da177e4SLinus Torvalds .vector_name = "Clipper", 6241da177e4SLinus Torvalds DO_EV6_MMU, 6251da177e4SLinus Torvalds DO_DEFAULT_RTC, 6261da177e4SLinus Torvalds DO_TSUNAMI_IO, 6271da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 6281da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 6291da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 6301da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 6311da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 6321da177e4SLinus Torvalds 6331da177e4SLinus Torvalds .nr_irqs = 64, 6341da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 6351da177e4SLinus Torvalds 6361da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 6371da177e4SLinus Torvalds .init_irq = clipper_init_irq, 6381da177e4SLinus Torvalds .init_rtc = common_init_rtc, 639025a2215SJay Estabrook .init_pci = clipper_init_pci, 6401da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 6411da177e4SLinus Torvalds .pci_map_irq = clipper_map_irq, 6421da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 6431da177e4SLinus Torvalds }; 6441da177e4SLinus Torvalds 6451da177e4SLinus Torvalds /* Sharks strongly resemble Clipper, at least as far 6461da177e4SLinus Torvalds * as interrupt routing, etc, so we're using the 6471da177e4SLinus Torvalds * same functions as Clipper does 6481da177e4SLinus Torvalds */ 6491da177e4SLinus Torvalds 6501da177e4SLinus Torvalds struct alpha_machine_vector shark_mv __initmv = { 6511da177e4SLinus Torvalds .vector_name = "Shark", 6521da177e4SLinus Torvalds DO_EV6_MMU, 6531da177e4SLinus Torvalds DO_DEFAULT_RTC, 6541da177e4SLinus Torvalds DO_TSUNAMI_IO, 6551da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 6561da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 6571da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 6581da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 6591da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 6601da177e4SLinus Torvalds 6611da177e4SLinus Torvalds .nr_irqs = 64, 6621da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 6631da177e4SLinus Torvalds 6641da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 6651da177e4SLinus Torvalds .init_irq = clipper_init_irq, 6661da177e4SLinus Torvalds .init_rtc = common_init_rtc, 6671da177e4SLinus Torvalds .init_pci = common_init_pci, 6681da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 6691da177e4SLinus Torvalds .pci_map_irq = clipper_map_irq, 6701da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 6711da177e4SLinus Torvalds }; 6721da177e4SLinus Torvalds 6731da177e4SLinus Torvalds /* No alpha_mv alias for webbrick/monet/clipper, since we compile them 6741da177e4SLinus Torvalds in unconditionally with DP264; setup_arch knows how to cope. */ 675