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 1011da177e4SLinus Torvalds dp264_enable_irq(unsigned int irq) 1021da177e4SLinus Torvalds { 1031da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 1041da177e4SLinus Torvalds cached_irq_mask |= 1UL << 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 1101da177e4SLinus Torvalds dp264_disable_irq(unsigned int irq) 1111da177e4SLinus Torvalds { 1121da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 1131da177e4SLinus Torvalds cached_irq_mask &= ~(1UL << 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 1191da177e4SLinus Torvalds clipper_enable_irq(unsigned int irq) 1201da177e4SLinus Torvalds { 1211da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 1221da177e4SLinus Torvalds cached_irq_mask |= 1UL << (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 1281da177e4SLinus Torvalds clipper_disable_irq(unsigned int irq) 1291da177e4SLinus Torvalds { 1301da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 1311da177e4SLinus Torvalds cached_irq_mask &= ~(1UL << (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 1520de26520SRusty Russell dp264_set_affinity(unsigned int irq, const struct cpumask *affinity) 1531da177e4SLinus Torvalds { 1541da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 1550de26520SRusty Russell cpu_set_irq_affinity(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 1630de26520SRusty Russell clipper_set_affinity(unsigned int irq, const struct cpumask *affinity) 1641da177e4SLinus Torvalds { 1651da177e4SLinus Torvalds spin_lock(&dp264_irq_lock); 1660de26520SRusty Russell cpu_set_irq_affinity(irq - 16, *affinity); 1671da177e4SLinus Torvalds tsunami_update_irq_hw(cached_irq_mask); 1681da177e4SLinus Torvalds spin_unlock(&dp264_irq_lock); 169d5dedd45SYinghai Lu 170d5dedd45SYinghai Lu return 0; 1711da177e4SLinus Torvalds } 1721da177e4SLinus Torvalds 17344377f62SThomas Gleixner static struct irq_chip dp264_irq_type = { 1748ab1221cSThomas Gleixner .name = "DP264", 175*7d209c81SKyle McMartin .unmask = dp264_enable_irq, 176*7d209c81SKyle McMartin .mask = dp264_disable_irq, 177*7d209c81SKyle McMartin .mask_ack = dp264_disable_irq, 1781da177e4SLinus Torvalds .set_affinity = dp264_set_affinity, 1791da177e4SLinus Torvalds }; 1801da177e4SLinus Torvalds 18144377f62SThomas Gleixner static struct irq_chip clipper_irq_type = { 1828ab1221cSThomas Gleixner .name = "CLIPPER", 183*7d209c81SKyle McMartin .unmask = clipper_enable_irq, 184*7d209c81SKyle McMartin .mask = clipper_disable_irq, 185*7d209c81SKyle McMartin .mask_ack = clipper_disable_irq, 1861da177e4SLinus Torvalds .set_affinity = clipper_set_affinity, 1871da177e4SLinus Torvalds }; 1881da177e4SLinus Torvalds 1891da177e4SLinus Torvalds static void 1907ca56053SAl Viro dp264_device_interrupt(unsigned long vector) 1911da177e4SLinus Torvalds { 1921da177e4SLinus Torvalds #if 1 1931da177e4SLinus Torvalds printk("dp264_device_interrupt: NOT IMPLEMENTED YET!!\n"); 1941da177e4SLinus Torvalds #else 1951da177e4SLinus Torvalds unsigned long pld; 1961da177e4SLinus Torvalds unsigned int i; 1971da177e4SLinus Torvalds 1981da177e4SLinus Torvalds /* Read the interrupt summary register of TSUNAMI */ 1991da177e4SLinus Torvalds pld = TSUNAMI_cchip->dir0.csr; 2001da177e4SLinus Torvalds 2011da177e4SLinus Torvalds /* 2021da177e4SLinus Torvalds * Now for every possible bit set, work through them and call 2031da177e4SLinus Torvalds * the appropriate interrupt handler. 2041da177e4SLinus Torvalds */ 2051da177e4SLinus Torvalds while (pld) { 2061da177e4SLinus Torvalds i = ffz(~pld); 2071da177e4SLinus Torvalds pld &= pld - 1; /* clear least bit set */ 2081da177e4SLinus Torvalds if (i == 55) 2097ca56053SAl Viro isa_device_interrupt(vector); 2101da177e4SLinus Torvalds else 2113dbb8c62SAl Viro handle_irq(16 + i); 2121da177e4SLinus Torvalds #if 0 2131da177e4SLinus Torvalds TSUNAMI_cchip->dir0.csr = 1UL << i; mb(); 2141da177e4SLinus Torvalds tmp = TSUNAMI_cchip->dir0.csr; 2151da177e4SLinus Torvalds #endif 2161da177e4SLinus Torvalds } 2171da177e4SLinus Torvalds #endif 2181da177e4SLinus Torvalds } 2191da177e4SLinus Torvalds 2201da177e4SLinus Torvalds static void 2217ca56053SAl Viro dp264_srm_device_interrupt(unsigned long vector) 2221da177e4SLinus Torvalds { 2231da177e4SLinus Torvalds int irq; 2241da177e4SLinus Torvalds 2251da177e4SLinus Torvalds irq = (vector - 0x800) >> 4; 2261da177e4SLinus Torvalds 2271da177e4SLinus Torvalds /* 2281da177e4SLinus Torvalds * The SRM console reports PCI interrupts with a vector calculated by: 2291da177e4SLinus Torvalds * 2301da177e4SLinus Torvalds * 0x900 + (0x10 * DRIR-bit) 2311da177e4SLinus Torvalds * 2321da177e4SLinus Torvalds * So bit 16 shows up as IRQ 32, etc. 2331da177e4SLinus Torvalds * 2341da177e4SLinus Torvalds * On DP264/BRICK/MONET, we adjust it down by 16 because at least 2351da177e4SLinus Torvalds * that many of the low order bits of the DRIR are not used, and 2361da177e4SLinus Torvalds * so we don't count them. 2371da177e4SLinus Torvalds */ 2381da177e4SLinus Torvalds if (irq >= 32) 2391da177e4SLinus Torvalds irq -= 16; 2401da177e4SLinus Torvalds 2413dbb8c62SAl Viro handle_irq(irq); 2421da177e4SLinus Torvalds } 2431da177e4SLinus Torvalds 2441da177e4SLinus Torvalds static void 2457ca56053SAl Viro clipper_srm_device_interrupt(unsigned long vector) 2461da177e4SLinus Torvalds { 2471da177e4SLinus Torvalds int irq; 2481da177e4SLinus Torvalds 2491da177e4SLinus Torvalds irq = (vector - 0x800) >> 4; 2501da177e4SLinus Torvalds 2511da177e4SLinus Torvalds /* 2521da177e4SLinus Torvalds * The SRM console reports PCI interrupts with a vector calculated by: 2531da177e4SLinus Torvalds * 2541da177e4SLinus Torvalds * 0x900 + (0x10 * DRIR-bit) 2551da177e4SLinus Torvalds * 2561da177e4SLinus Torvalds * So bit 16 shows up as IRQ 32, etc. 2571da177e4SLinus Torvalds * 2581da177e4SLinus Torvalds * CLIPPER uses bits 8-47 for PCI interrupts, so we do not need 2591da177e4SLinus Torvalds * to scale down the vector reported, we just use it. 2601da177e4SLinus Torvalds * 2611da177e4SLinus Torvalds * Eg IRQ 24 is DRIR bit 8, etc, etc 2621da177e4SLinus Torvalds */ 2633dbb8c62SAl Viro handle_irq(irq); 2641da177e4SLinus Torvalds } 2651da177e4SLinus Torvalds 2661da177e4SLinus Torvalds static void __init 26744377f62SThomas Gleixner init_tsunami_irqs(struct irq_chip * ops, int imin, int imax) 2681da177e4SLinus Torvalds { 2691da177e4SLinus Torvalds long i; 2701da177e4SLinus Torvalds for (i = imin; i <= imax; ++i) { 271a891b393SKyle McMartin irq_to_desc(i)->status |= IRQ_LEVEL; 272*7d209c81SKyle McMartin set_irq_chip_and_handler(i, ops, handle_level_irq); 2731da177e4SLinus Torvalds } 2741da177e4SLinus Torvalds } 2751da177e4SLinus Torvalds 2761da177e4SLinus Torvalds static void __init 2771da177e4SLinus Torvalds dp264_init_irq(void) 2781da177e4SLinus Torvalds { 2791da177e4SLinus Torvalds outb(0, DMA1_RESET_REG); 2801da177e4SLinus Torvalds outb(0, DMA2_RESET_REG); 2811da177e4SLinus Torvalds outb(DMA_MODE_CASCADE, DMA2_MODE_REG); 2821da177e4SLinus Torvalds outb(0, DMA2_MASK_REG); 2831da177e4SLinus Torvalds 2841da177e4SLinus Torvalds if (alpha_using_srm) 2851da177e4SLinus Torvalds alpha_mv.device_interrupt = dp264_srm_device_interrupt; 2861da177e4SLinus Torvalds 2871da177e4SLinus Torvalds tsunami_update_irq_hw(0); 2881da177e4SLinus Torvalds 2891da177e4SLinus Torvalds init_i8259a_irqs(); 2901da177e4SLinus Torvalds init_tsunami_irqs(&dp264_irq_type, 16, 47); 2911da177e4SLinus Torvalds } 2921da177e4SLinus Torvalds 2931da177e4SLinus Torvalds static void __init 2941da177e4SLinus Torvalds clipper_init_irq(void) 2951da177e4SLinus Torvalds { 2961da177e4SLinus Torvalds outb(0, DMA1_RESET_REG); 2971da177e4SLinus Torvalds outb(0, DMA2_RESET_REG); 2981da177e4SLinus Torvalds outb(DMA_MODE_CASCADE, DMA2_MODE_REG); 2991da177e4SLinus Torvalds outb(0, DMA2_MASK_REG); 3001da177e4SLinus Torvalds 3011da177e4SLinus Torvalds if (alpha_using_srm) 3021da177e4SLinus Torvalds alpha_mv.device_interrupt = clipper_srm_device_interrupt; 3031da177e4SLinus Torvalds 3041da177e4SLinus Torvalds tsunami_update_irq_hw(0); 3051da177e4SLinus Torvalds 3061da177e4SLinus Torvalds init_i8259a_irqs(); 3071da177e4SLinus Torvalds init_tsunami_irqs(&clipper_irq_type, 24, 63); 3081da177e4SLinus Torvalds } 3091da177e4SLinus Torvalds 3101da177e4SLinus Torvalds 3111da177e4SLinus Torvalds /* 3121da177e4SLinus Torvalds * PCI Fixup configuration. 3131da177e4SLinus Torvalds * 3141da177e4SLinus Torvalds * Summary @ TSUNAMI_CSR_DIM0: 3151da177e4SLinus Torvalds * Bit Meaning 3161da177e4SLinus Torvalds * 0-17 Unused 3171da177e4SLinus Torvalds *18 Interrupt SCSI B (Adaptec 7895 builtin) 3181da177e4SLinus Torvalds *19 Interrupt SCSI A (Adaptec 7895 builtin) 3191da177e4SLinus Torvalds *20 Interrupt Line D from slot 2 PCI0 3201da177e4SLinus Torvalds *21 Interrupt Line C from slot 2 PCI0 3211da177e4SLinus Torvalds *22 Interrupt Line B from slot 2 PCI0 3221da177e4SLinus Torvalds *23 Interrupt Line A from slot 2 PCI0 3231da177e4SLinus Torvalds *24 Interrupt Line D from slot 1 PCI0 3241da177e4SLinus Torvalds *25 Interrupt Line C from slot 1 PCI0 3251da177e4SLinus Torvalds *26 Interrupt Line B from slot 1 PCI0 3261da177e4SLinus Torvalds *27 Interrupt Line A from slot 1 PCI0 3271da177e4SLinus Torvalds *28 Interrupt Line D from slot 0 PCI0 3281da177e4SLinus Torvalds *29 Interrupt Line C from slot 0 PCI0 3291da177e4SLinus Torvalds *30 Interrupt Line B from slot 0 PCI0 3301da177e4SLinus Torvalds *31 Interrupt Line A from slot 0 PCI0 3311da177e4SLinus Torvalds * 3321da177e4SLinus Torvalds *32 Interrupt Line D from slot 3 PCI1 3331da177e4SLinus Torvalds *33 Interrupt Line C from slot 3 PCI1 3341da177e4SLinus Torvalds *34 Interrupt Line B from slot 3 PCI1 3351da177e4SLinus Torvalds *35 Interrupt Line A from slot 3 PCI1 3361da177e4SLinus Torvalds *36 Interrupt Line D from slot 2 PCI1 3371da177e4SLinus Torvalds *37 Interrupt Line C from slot 2 PCI1 3381da177e4SLinus Torvalds *38 Interrupt Line B from slot 2 PCI1 3391da177e4SLinus Torvalds *39 Interrupt Line A from slot 2 PCI1 3401da177e4SLinus Torvalds *40 Interrupt Line D from slot 1 PCI1 3411da177e4SLinus Torvalds *41 Interrupt Line C from slot 1 PCI1 3421da177e4SLinus Torvalds *42 Interrupt Line B from slot 1 PCI1 3431da177e4SLinus Torvalds *43 Interrupt Line A from slot 1 PCI1 3441da177e4SLinus Torvalds *44 Interrupt Line D from slot 0 PCI1 3451da177e4SLinus Torvalds *45 Interrupt Line C from slot 0 PCI1 3461da177e4SLinus Torvalds *46 Interrupt Line B from slot 0 PCI1 3471da177e4SLinus Torvalds *47 Interrupt Line A from slot 0 PCI1 3481da177e4SLinus Torvalds *48-52 Unused 3491da177e4SLinus Torvalds *53 PCI0 NMI (from Cypress) 3501da177e4SLinus Torvalds *54 PCI0 SMI INT (from Cypress) 3511da177e4SLinus Torvalds *55 PCI0 ISA Interrupt (from Cypress) 3521da177e4SLinus Torvalds *56-60 Unused 3531da177e4SLinus Torvalds *61 PCI1 Bus Error 3541da177e4SLinus Torvalds *62 PCI0 Bus Error 3551da177e4SLinus Torvalds *63 Reserved 3561da177e4SLinus Torvalds * 3571da177e4SLinus Torvalds * IdSel 3581da177e4SLinus Torvalds * 5 Cypress Bridge I/O 3591da177e4SLinus Torvalds * 6 SCSI Adaptec builtin 3601da177e4SLinus Torvalds * 7 64 bit PCI option slot 0 (all busses) 3611da177e4SLinus Torvalds * 8 64 bit PCI option slot 1 (all busses) 3621da177e4SLinus Torvalds * 9 64 bit PCI option slot 2 (all busses) 3631da177e4SLinus Torvalds * 10 64 bit PCI option slot 3 (not bus 0) 3641da177e4SLinus Torvalds */ 3651da177e4SLinus Torvalds 3661da177e4SLinus Torvalds static int __init 367997a51aeSIvan Kokshaysky isa_irq_fixup(struct pci_dev *dev, int irq) 368997a51aeSIvan Kokshaysky { 369997a51aeSIvan Kokshaysky u8 irq8; 370997a51aeSIvan Kokshaysky 371997a51aeSIvan Kokshaysky if (irq > 0) 372997a51aeSIvan Kokshaysky return irq; 373997a51aeSIvan Kokshaysky 374997a51aeSIvan Kokshaysky /* This interrupt is routed via ISA bridge, so we'll 375997a51aeSIvan Kokshaysky just have to trust whatever value the console might 376997a51aeSIvan Kokshaysky have assigned. */ 377997a51aeSIvan Kokshaysky pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8); 378997a51aeSIvan Kokshaysky 379997a51aeSIvan Kokshaysky return irq8 & 0xf; 380997a51aeSIvan Kokshaysky } 381997a51aeSIvan Kokshaysky 382997a51aeSIvan Kokshaysky static int __init 3831da177e4SLinus Torvalds dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 3841da177e4SLinus Torvalds { 3851da177e4SLinus Torvalds static char irq_tab[6][5] __initdata = { 3861da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 3871da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 5 ISA Bridge */ 3881da177e4SLinus Torvalds { 16+ 3, 16+ 3, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin*/ 3891da177e4SLinus Torvalds { 16+15, 16+15, 16+14, 16+13, 16+12}, /* IdSel 7 slot 0 */ 3901da177e4SLinus Torvalds { 16+11, 16+11, 16+10, 16+ 9, 16+ 8}, /* IdSel 8 slot 1 */ 3911da177e4SLinus Torvalds { 16+ 7, 16+ 7, 16+ 6, 16+ 5, 16+ 4}, /* IdSel 9 slot 2 */ 3921da177e4SLinus Torvalds { 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0} /* IdSel 10 slot 3 */ 3931da177e4SLinus Torvalds }; 3941da177e4SLinus Torvalds const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5; 3951da177e4SLinus Torvalds struct pci_controller *hose = dev->sysdata; 3961da177e4SLinus Torvalds int irq = COMMON_TABLE_LOOKUP; 3971da177e4SLinus Torvalds 398997a51aeSIvan Kokshaysky if (irq > 0) 3991da177e4SLinus Torvalds irq += 16 * hose->index; 4001da177e4SLinus Torvalds 401997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, irq); 4021da177e4SLinus Torvalds } 4031da177e4SLinus Torvalds 4041da177e4SLinus Torvalds static int __init 4051da177e4SLinus Torvalds monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 4061da177e4SLinus Torvalds { 4071da177e4SLinus Torvalds static char irq_tab[13][5] __initdata = { 4081da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 4091da177e4SLinus Torvalds { 45, 45, 45, 45, 45}, /* IdSel 3 21143 PCI1 */ 4101da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 4 unused */ 4111da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 5 unused */ 4121da177e4SLinus Torvalds { 47, 47, 47, 47, 47}, /* IdSel 6 SCSI PCI1 */ 4131da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 7 ISA Bridge */ 4141da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 8 P2P PCI1 */ 4151da177e4SLinus Torvalds #if 1 4161da177e4SLinus Torvalds { 28, 28, 29, 30, 31}, /* IdSel 14 slot 4 PCI2*/ 4171da177e4SLinus Torvalds { 24, 24, 25, 26, 27}, /* IdSel 15 slot 5 PCI2*/ 4181da177e4SLinus Torvalds #else 4191da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 9 unused */ 4201da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 10 unused */ 4211da177e4SLinus Torvalds #endif 4221da177e4SLinus Torvalds { 40, 40, 41, 42, 43}, /* IdSel 11 slot 1 PCI0*/ 4231da177e4SLinus Torvalds { 36, 36, 37, 38, 39}, /* IdSel 12 slot 2 PCI0*/ 4241da177e4SLinus Torvalds { 32, 32, 33, 34, 35}, /* IdSel 13 slot 3 PCI0*/ 4251da177e4SLinus Torvalds { 28, 28, 29, 30, 31}, /* IdSel 14 slot 4 PCI2*/ 4261da177e4SLinus Torvalds { 24, 24, 25, 26, 27} /* IdSel 15 slot 5 PCI2*/ 4271da177e4SLinus Torvalds }; 4281da177e4SLinus Torvalds const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5; 429997a51aeSIvan Kokshaysky 430997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP); 4311da177e4SLinus Torvalds } 4321da177e4SLinus Torvalds 4331da177e4SLinus Torvalds static u8 __init 4341da177e4SLinus Torvalds monet_swizzle(struct pci_dev *dev, u8 *pinp) 4351da177e4SLinus Torvalds { 4361da177e4SLinus Torvalds struct pci_controller *hose = dev->sysdata; 4371da177e4SLinus Torvalds int slot, pin = *pinp; 4381da177e4SLinus Torvalds 4391da177e4SLinus Torvalds if (!dev->bus->parent) { 4401da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4411da177e4SLinus Torvalds } 4421da177e4SLinus Torvalds /* Check for the built-in bridge on hose 1. */ 4431da177e4SLinus Torvalds else if (hose->index == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) { 4441da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4451da177e4SLinus Torvalds } else { 4461da177e4SLinus Torvalds /* Must be a card-based bridge. */ 4471da177e4SLinus Torvalds do { 4481da177e4SLinus Torvalds /* Check for built-in bridge on hose 1. */ 4491da177e4SLinus Torvalds if (hose->index == 1 && 4501da177e4SLinus Torvalds PCI_SLOT(dev->bus->self->devfn) == 8) { 4511da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4521da177e4SLinus Torvalds break; 4531da177e4SLinus Torvalds } 4541be9baa0SBjorn Helgaas pin = pci_swizzle_interrupt_pin(dev, pin); 4551da177e4SLinus Torvalds 4561da177e4SLinus Torvalds /* Move up the chain of bridges. */ 4571da177e4SLinus Torvalds dev = dev->bus->self; 4581da177e4SLinus Torvalds /* Slot of the next bridge. */ 4591da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 4601da177e4SLinus Torvalds } while (dev->bus->self); 4611da177e4SLinus Torvalds } 4621da177e4SLinus Torvalds *pinp = pin; 4631da177e4SLinus Torvalds return slot; 4641da177e4SLinus Torvalds } 4651da177e4SLinus Torvalds 4661da177e4SLinus Torvalds static int __init 4671da177e4SLinus Torvalds webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 4681da177e4SLinus Torvalds { 4691da177e4SLinus Torvalds static char irq_tab[13][5] __initdata = { 4701da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 4711da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 7 ISA Bridge */ 4721da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 8 unused */ 4731da177e4SLinus Torvalds { 29, 29, 29, 29, 29}, /* IdSel 9 21143 #1 */ 4741da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 10 unused */ 4751da177e4SLinus Torvalds { 30, 30, 30, 30, 30}, /* IdSel 11 21143 #2 */ 4761da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 12 unused */ 4771da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 13 unused */ 4781da177e4SLinus Torvalds { 35, 35, 34, 33, 32}, /* IdSel 14 slot 0 */ 4791da177e4SLinus Torvalds { 39, 39, 38, 37, 36}, /* IdSel 15 slot 1 */ 4801da177e4SLinus Torvalds { 43, 43, 42, 41, 40}, /* IdSel 16 slot 2 */ 4811da177e4SLinus Torvalds { 47, 47, 46, 45, 44}, /* IdSel 17 slot 3 */ 4821da177e4SLinus Torvalds }; 4831da177e4SLinus Torvalds const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5; 484997a51aeSIvan Kokshaysky 485997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP); 4861da177e4SLinus Torvalds } 4871da177e4SLinus Torvalds 4881da177e4SLinus Torvalds static int __init 4891da177e4SLinus Torvalds clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 4901da177e4SLinus Torvalds { 4911da177e4SLinus Torvalds static char irq_tab[7][5] __initdata = { 4921da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 4931da177e4SLinus Torvalds { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 1 slot 1 */ 4941da177e4SLinus Torvalds { 16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 2 slot 2 */ 4951da177e4SLinus Torvalds { 16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 3 slot 3 */ 4961da177e4SLinus Torvalds { 16+20, 16+20, 16+21, 16+22, 16+23}, /* IdSel 4 slot 4 */ 4971da177e4SLinus Torvalds { 16+24, 16+24, 16+25, 16+26, 16+27}, /* IdSel 5 slot 5 */ 4981da177e4SLinus Torvalds { 16+28, 16+28, 16+29, 16+30, 16+31}, /* IdSel 6 slot 6 */ 4991da177e4SLinus Torvalds { -1, -1, -1, -1, -1} /* IdSel 7 ISA Bridge */ 5001da177e4SLinus Torvalds }; 5011da177e4SLinus Torvalds const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5; 5021da177e4SLinus Torvalds struct pci_controller *hose = dev->sysdata; 5031da177e4SLinus Torvalds int irq = COMMON_TABLE_LOOKUP; 5041da177e4SLinus Torvalds 5051da177e4SLinus Torvalds if (irq > 0) 5061da177e4SLinus Torvalds irq += 16 * hose->index; 5071da177e4SLinus Torvalds 508997a51aeSIvan Kokshaysky return isa_irq_fixup(dev, irq); 5091da177e4SLinus Torvalds } 5101da177e4SLinus Torvalds 5111da177e4SLinus Torvalds static void __init 5121da177e4SLinus Torvalds dp264_init_pci(void) 5131da177e4SLinus Torvalds { 5141da177e4SLinus Torvalds common_init_pci(); 5151da177e4SLinus Torvalds SMC669_Init(0); 516025a2215SJay Estabrook locate_and_init_vga(NULL); 5171da177e4SLinus Torvalds } 5181da177e4SLinus Torvalds 5191da177e4SLinus Torvalds static void __init 5201da177e4SLinus Torvalds monet_init_pci(void) 5211da177e4SLinus Torvalds { 5221da177e4SLinus Torvalds common_init_pci(); 5231da177e4SLinus Torvalds SMC669_Init(1); 5241da177e4SLinus Torvalds es1888_init(); 525025a2215SJay Estabrook locate_and_init_vga(NULL); 526025a2215SJay Estabrook } 527025a2215SJay Estabrook 528025a2215SJay Estabrook static void __init 529025a2215SJay Estabrook clipper_init_pci(void) 530025a2215SJay Estabrook { 531025a2215SJay Estabrook common_init_pci(); 532025a2215SJay Estabrook locate_and_init_vga(NULL); 5331da177e4SLinus Torvalds } 5341da177e4SLinus Torvalds 5351da177e4SLinus Torvalds static void __init 5361da177e4SLinus Torvalds webbrick_init_arch(void) 5371da177e4SLinus Torvalds { 5381da177e4SLinus Torvalds tsunami_init_arch(); 5391da177e4SLinus Torvalds 5401da177e4SLinus Torvalds /* Tsunami caches 4 PTEs at a time; DS10 has only 1 hose. */ 5411da177e4SLinus Torvalds hose_head->sg_isa->align_entry = 4; 5421da177e4SLinus Torvalds hose_head->sg_pci->align_entry = 4; 5431da177e4SLinus Torvalds } 5441da177e4SLinus Torvalds 5451da177e4SLinus Torvalds 5461da177e4SLinus Torvalds /* 5471da177e4SLinus Torvalds * The System Vectors 5481da177e4SLinus Torvalds */ 5491da177e4SLinus Torvalds 5501da177e4SLinus Torvalds struct alpha_machine_vector dp264_mv __initmv = { 5511da177e4SLinus Torvalds .vector_name = "DP264", 5521da177e4SLinus Torvalds DO_EV6_MMU, 5531da177e4SLinus Torvalds DO_DEFAULT_RTC, 5541da177e4SLinus Torvalds DO_TSUNAMI_IO, 5551da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 5561da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 5571da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 5581da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 5591da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 5601da177e4SLinus Torvalds 5611da177e4SLinus Torvalds .nr_irqs = 64, 5621da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 5631da177e4SLinus Torvalds 5641da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 5651da177e4SLinus Torvalds .init_irq = dp264_init_irq, 5661da177e4SLinus Torvalds .init_rtc = common_init_rtc, 5671da177e4SLinus Torvalds .init_pci = dp264_init_pci, 5681da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 5691da177e4SLinus Torvalds .pci_map_irq = dp264_map_irq, 5701da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 5711da177e4SLinus Torvalds }; 5721da177e4SLinus Torvalds ALIAS_MV(dp264) 5731da177e4SLinus Torvalds 5741da177e4SLinus Torvalds struct alpha_machine_vector monet_mv __initmv = { 5751da177e4SLinus Torvalds .vector_name = "Monet", 5761da177e4SLinus Torvalds DO_EV6_MMU, 5771da177e4SLinus Torvalds DO_DEFAULT_RTC, 5781da177e4SLinus Torvalds DO_TSUNAMI_IO, 5791da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 5801da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 5811da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 5821da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 5831da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 5841da177e4SLinus Torvalds 5851da177e4SLinus Torvalds .nr_irqs = 64, 5861da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 5871da177e4SLinus Torvalds 5881da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 5891da177e4SLinus Torvalds .init_irq = dp264_init_irq, 5901da177e4SLinus Torvalds .init_rtc = common_init_rtc, 5911da177e4SLinus Torvalds .init_pci = monet_init_pci, 5921da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 5931da177e4SLinus Torvalds .pci_map_irq = monet_map_irq, 5941da177e4SLinus Torvalds .pci_swizzle = monet_swizzle, 5951da177e4SLinus Torvalds }; 5961da177e4SLinus Torvalds 5971da177e4SLinus Torvalds struct alpha_machine_vector webbrick_mv __initmv = { 5981da177e4SLinus Torvalds .vector_name = "Webbrick", 5991da177e4SLinus Torvalds DO_EV6_MMU, 6001da177e4SLinus Torvalds DO_DEFAULT_RTC, 6011da177e4SLinus Torvalds DO_TSUNAMI_IO, 6021da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 6031da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 6041da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 6051da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 6061da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 6071da177e4SLinus Torvalds 6081da177e4SLinus Torvalds .nr_irqs = 64, 6091da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 6101da177e4SLinus Torvalds 6111da177e4SLinus Torvalds .init_arch = webbrick_init_arch, 6121da177e4SLinus Torvalds .init_irq = dp264_init_irq, 6131da177e4SLinus Torvalds .init_rtc = common_init_rtc, 6141da177e4SLinus Torvalds .init_pci = common_init_pci, 6151da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 6161da177e4SLinus Torvalds .pci_map_irq = webbrick_map_irq, 6171da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 6181da177e4SLinus Torvalds }; 6191da177e4SLinus Torvalds 6201da177e4SLinus Torvalds struct alpha_machine_vector clipper_mv __initmv = { 6211da177e4SLinus Torvalds .vector_name = "Clipper", 6221da177e4SLinus Torvalds DO_EV6_MMU, 6231da177e4SLinus Torvalds DO_DEFAULT_RTC, 6241da177e4SLinus Torvalds DO_TSUNAMI_IO, 6251da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 6261da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 6271da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 6281da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 6291da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 6301da177e4SLinus Torvalds 6311da177e4SLinus Torvalds .nr_irqs = 64, 6321da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 6331da177e4SLinus Torvalds 6341da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 6351da177e4SLinus Torvalds .init_irq = clipper_init_irq, 6361da177e4SLinus Torvalds .init_rtc = common_init_rtc, 637025a2215SJay Estabrook .init_pci = clipper_init_pci, 6381da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 6391da177e4SLinus Torvalds .pci_map_irq = clipper_map_irq, 6401da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 6411da177e4SLinus Torvalds }; 6421da177e4SLinus Torvalds 6431da177e4SLinus Torvalds /* Sharks strongly resemble Clipper, at least as far 6441da177e4SLinus Torvalds * as interrupt routing, etc, so we're using the 6451da177e4SLinus Torvalds * same functions as Clipper does 6461da177e4SLinus Torvalds */ 6471da177e4SLinus Torvalds 6481da177e4SLinus Torvalds struct alpha_machine_vector shark_mv __initmv = { 6491da177e4SLinus Torvalds .vector_name = "Shark", 6501da177e4SLinus Torvalds DO_EV6_MMU, 6511da177e4SLinus Torvalds DO_DEFAULT_RTC, 6521da177e4SLinus Torvalds DO_TSUNAMI_IO, 6531da177e4SLinus Torvalds .machine_check = tsunami_machine_check, 6541da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 6551da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 6561da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 6571da177e4SLinus Torvalds .pci_dac_offset = TSUNAMI_DAC_OFFSET, 6581da177e4SLinus Torvalds 6591da177e4SLinus Torvalds .nr_irqs = 64, 6601da177e4SLinus Torvalds .device_interrupt = dp264_device_interrupt, 6611da177e4SLinus Torvalds 6621da177e4SLinus Torvalds .init_arch = tsunami_init_arch, 6631da177e4SLinus Torvalds .init_irq = clipper_init_irq, 6641da177e4SLinus Torvalds .init_rtc = common_init_rtc, 6651da177e4SLinus Torvalds .init_pci = common_init_pci, 6661da177e4SLinus Torvalds .kill_arch = tsunami_kill_arch, 6671da177e4SLinus Torvalds .pci_map_irq = clipper_map_irq, 6681da177e4SLinus Torvalds .pci_swizzle = common_swizzle, 6691da177e4SLinus Torvalds }; 6701da177e4SLinus Torvalds 6711da177e4SLinus Torvalds /* No alpha_mv alias for webbrick/monet/clipper, since we compile them 6721da177e4SLinus Torvalds in unconditionally with DP264; setup_arch knows how to cope. */ 673