11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/arch/alpha/kernel/sys_miata.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 1995 David A Rusling 51da177e4SLinus Torvalds * Copyright (C) 1996 Jay A Estabrook 61da177e4SLinus Torvalds * Copyright (C) 1998, 1999, 2000 Richard Henderson 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * Code supporting the MIATA (EV56+PYXIS). 91da177e4SLinus Torvalds */ 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds #include <linux/kernel.h> 121da177e4SLinus Torvalds #include <linux/types.h> 131da177e4SLinus Torvalds #include <linux/mm.h> 141da177e4SLinus Torvalds #include <linux/sched.h> 151da177e4SLinus Torvalds #include <linux/pci.h> 161da177e4SLinus Torvalds #include <linux/init.h> 171da177e4SLinus Torvalds #include <linux/reboot.h> 181da177e4SLinus Torvalds 191da177e4SLinus Torvalds #include <asm/ptrace.h> 201da177e4SLinus Torvalds #include <asm/system.h> 211da177e4SLinus Torvalds #include <asm/dma.h> 221da177e4SLinus Torvalds #include <asm/irq.h> 231da177e4SLinus Torvalds #include <asm/mmu_context.h> 241da177e4SLinus Torvalds #include <asm/io.h> 251da177e4SLinus Torvalds #include <asm/pgtable.h> 261da177e4SLinus Torvalds #include <asm/core_cia.h> 271da177e4SLinus Torvalds #include <asm/tlbflush.h> 281da177e4SLinus Torvalds 291da177e4SLinus Torvalds #include "proto.h" 301da177e4SLinus Torvalds #include "irq_impl.h" 311da177e4SLinus Torvalds #include "pci_impl.h" 321da177e4SLinus Torvalds #include "machvec_impl.h" 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds static void 367ca56053SAl Viro miata_srm_device_interrupt(unsigned long vector) 371da177e4SLinus Torvalds { 381da177e4SLinus Torvalds int irq; 391da177e4SLinus Torvalds 401da177e4SLinus Torvalds irq = (vector - 0x800) >> 4; 411da177e4SLinus Torvalds 421da177e4SLinus Torvalds /* 431da177e4SLinus Torvalds * I really hate to do this, but the MIATA SRM console ignores the 441da177e4SLinus Torvalds * low 8 bits in the interrupt summary register, and reports the 451da177e4SLinus Torvalds * vector 0x80 *lower* than I expected from the bit numbering in 461da177e4SLinus Torvalds * the documentation. 471da177e4SLinus Torvalds * This was done because the low 8 summary bits really aren't used 481da177e4SLinus Torvalds * for reporting any interrupts (the PCI-ISA bridge, bit 7, isn't 491da177e4SLinus Torvalds * used for this purpose, as PIC interrupts are delivered as the 501da177e4SLinus Torvalds * vectors 0x800-0x8f0). 511da177e4SLinus Torvalds * But I really don't want to change the fixup code for allocation 521da177e4SLinus Torvalds * of IRQs, nor the alpha_irq_mask maintenance stuff, both of which 531da177e4SLinus Torvalds * look nice and clean now. 541da177e4SLinus Torvalds * So, here's this grotty hack... :-( 551da177e4SLinus Torvalds */ 561da177e4SLinus Torvalds if (irq >= 16) 571da177e4SLinus Torvalds irq = irq + 8; 581da177e4SLinus Torvalds 593dbb8c62SAl Viro handle_irq(irq); 601da177e4SLinus Torvalds } 611da177e4SLinus Torvalds 621da177e4SLinus Torvalds static void __init 631da177e4SLinus Torvalds miata_init_irq(void) 641da177e4SLinus Torvalds { 651da177e4SLinus Torvalds if (alpha_using_srm) 661da177e4SLinus Torvalds alpha_mv.device_interrupt = miata_srm_device_interrupt; 671da177e4SLinus Torvalds 681da177e4SLinus Torvalds #if 0 691da177e4SLinus Torvalds /* These break on MiataGL so we'll try not to do it at all. */ 701da177e4SLinus Torvalds *(vulp)PYXIS_INT_HILO = 0x000000B2UL; mb(); /* ISA/NMI HI */ 711da177e4SLinus Torvalds *(vulp)PYXIS_RT_COUNT = 0UL; mb(); /* clear count */ 721da177e4SLinus Torvalds #endif 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds init_i8259a_irqs(); 751da177e4SLinus Torvalds 761da177e4SLinus Torvalds /* Not interested in the bogus interrupts (3,10), Fan Fault (0), 771da177e4SLinus Torvalds NMI (1), or EIDE (9). 781da177e4SLinus Torvalds 791da177e4SLinus Torvalds We also disable the risers (4,5), since we don't know how to 801da177e4SLinus Torvalds route the interrupts behind the bridge. */ 811da177e4SLinus Torvalds init_pyxis_irqs(0x63b0000); 821da177e4SLinus Torvalds 831da177e4SLinus Torvalds common_init_isa_dma(); 841da177e4SLinus Torvalds setup_irq(16+2, &halt_switch_irqaction); /* SRM only? */ 851da177e4SLinus Torvalds setup_irq(16+6, &timer_cascade_irqaction); 861da177e4SLinus Torvalds } 871da177e4SLinus Torvalds 881da177e4SLinus Torvalds 891da177e4SLinus Torvalds /* 901da177e4SLinus Torvalds * PCI Fixup configuration. 911da177e4SLinus Torvalds * 921da177e4SLinus Torvalds * Summary @ PYXIS_INT_REQ: 931da177e4SLinus Torvalds * Bit Meaning 941da177e4SLinus Torvalds * 0 Fan Fault 951da177e4SLinus Torvalds * 1 NMI 961da177e4SLinus Torvalds * 2 Halt/Reset switch 971da177e4SLinus Torvalds * 3 none 981da177e4SLinus Torvalds * 4 CID0 (Riser ID) 991da177e4SLinus Torvalds * 5 CID1 (Riser ID) 1001da177e4SLinus Torvalds * 6 Interval timer 1011da177e4SLinus Torvalds * 7 PCI-ISA Bridge 1021da177e4SLinus Torvalds * 8 Ethernet 1031da177e4SLinus Torvalds * 9 EIDE (deprecated, ISA 14/15 used) 1041da177e4SLinus Torvalds *10 none 1051da177e4SLinus Torvalds *11 USB 1061da177e4SLinus Torvalds *12 Interrupt Line A from slot 4 1071da177e4SLinus Torvalds *13 Interrupt Line B from slot 4 1081da177e4SLinus Torvalds *14 Interrupt Line C from slot 4 1091da177e4SLinus Torvalds *15 Interrupt Line D from slot 4 1101da177e4SLinus Torvalds *16 Interrupt Line A from slot 5 1111da177e4SLinus Torvalds *17 Interrupt line B from slot 5 1121da177e4SLinus Torvalds *18 Interrupt Line C from slot 5 1131da177e4SLinus Torvalds *19 Interrupt Line D from slot 5 1141da177e4SLinus Torvalds *20 Interrupt Line A from slot 1 1151da177e4SLinus Torvalds *21 Interrupt Line B from slot 1 1161da177e4SLinus Torvalds *22 Interrupt Line C from slot 1 1171da177e4SLinus Torvalds *23 Interrupt Line D from slot 1 1181da177e4SLinus Torvalds *24 Interrupt Line A from slot 2 1191da177e4SLinus Torvalds *25 Interrupt Line B from slot 2 1201da177e4SLinus Torvalds *26 Interrupt Line C from slot 2 1211da177e4SLinus Torvalds *27 Interrupt Line D from slot 2 1221da177e4SLinus Torvalds *27 Interrupt Line A from slot 3 1231da177e4SLinus Torvalds *29 Interrupt Line B from slot 3 1241da177e4SLinus Torvalds *30 Interrupt Line C from slot 3 1251da177e4SLinus Torvalds *31 Interrupt Line D from slot 3 1261da177e4SLinus Torvalds * 1271da177e4SLinus Torvalds * The device to slot mapping looks like: 1281da177e4SLinus Torvalds * 1291da177e4SLinus Torvalds * Slot Device 1301da177e4SLinus Torvalds * 3 DC21142 Ethernet 1311da177e4SLinus Torvalds * 4 EIDE CMD646 1321da177e4SLinus Torvalds * 5 none 1331da177e4SLinus Torvalds * 6 USB 1341da177e4SLinus Torvalds * 7 PCI-ISA bridge 1351da177e4SLinus Torvalds * 8 PCI-PCI Bridge (SBU Riser) 1361da177e4SLinus Torvalds * 9 none 1371da177e4SLinus Torvalds * 10 none 1381da177e4SLinus Torvalds * 11 PCI on board slot 4 (SBU Riser) 1391da177e4SLinus Torvalds * 12 PCI on board slot 5 (SBU Riser) 1401da177e4SLinus Torvalds * 1411da177e4SLinus Torvalds * These are behind the bridge, so I'm not sure what to do... 1421da177e4SLinus Torvalds * 1431da177e4SLinus Torvalds * 13 PCI on board slot 1 (SBU Riser) 1441da177e4SLinus Torvalds * 14 PCI on board slot 2 (SBU Riser) 1451da177e4SLinus Torvalds * 15 PCI on board slot 3 (SBU Riser) 1461da177e4SLinus Torvalds * 1471da177e4SLinus Torvalds * 1481da177e4SLinus Torvalds * This two layered interrupt approach means that we allocate IRQ 16 and 1491da177e4SLinus Torvalds * above for PCI interrupts. The IRQ relates to which bit the interrupt 1501da177e4SLinus Torvalds * comes in on. This makes interrupt processing much easier. 1511da177e4SLinus Torvalds */ 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds static int __init 1541da177e4SLinus Torvalds miata_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 1551da177e4SLinus Torvalds { 1561da177e4SLinus Torvalds static char irq_tab[18][5] __initdata = { 1571da177e4SLinus Torvalds /*INT INTA INTB INTC INTD */ 1581da177e4SLinus Torvalds {16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8}, /* IdSel 14, DC21142 */ 1591da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 15, EIDE */ 1601da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 16, none */ 1611da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 17, none */ 1621da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 18, PCI-ISA */ 1631da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 19, PCI-PCI */ 1641da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 20, none */ 1651da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 21, none */ 1661da177e4SLinus Torvalds {16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 22, slot 4 */ 1671da177e4SLinus Torvalds {16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 23, slot 5 */ 1681da177e4SLinus Torvalds /* the next 7 are actually on PCI bus 1, across the bridge */ 1691da177e4SLinus Torvalds {16+11, 16+11, 16+11, 16+11, 16+11}, /* IdSel 24, QLISP/GL*/ 1701da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 25, none */ 1711da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 26, none */ 1721da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 27, none */ 1731da177e4SLinus Torvalds {16+20, 16+20, 16+21, 16+22, 16+23}, /* IdSel 28, slot 1 */ 1741da177e4SLinus Torvalds {16+24, 16+24, 16+25, 16+26, 16+27}, /* IdSel 29, slot 2 */ 1751da177e4SLinus Torvalds {16+28, 16+28, 16+29, 16+30, 16+31}, /* IdSel 30, slot 3 */ 1761da177e4SLinus Torvalds /* This bridge is on the main bus of the later orig MIATA */ 1771da177e4SLinus Torvalds { -1, -1, -1, -1, -1}, /* IdSel 31, PCI-PCI */ 1781da177e4SLinus Torvalds }; 1791da177e4SLinus Torvalds const long min_idsel = 3, max_idsel = 20, irqs_per_slot = 5; 1801da177e4SLinus Torvalds 1811da177e4SLinus Torvalds /* the USB function of the 82c693 has it's interrupt connected to 1821da177e4SLinus Torvalds the 2nd 8259 controller. So we have to check for it first. */ 1831da177e4SLinus Torvalds 1841da177e4SLinus Torvalds if((slot == 7) && (PCI_FUNC(dev->devfn) == 3)) { 1851da177e4SLinus Torvalds u8 irq=0; 186074cec54SAlan Cox struct pci_dev *pdev = pci_get_slot(dev->bus, dev->devfn & ~7); 187074cec54SAlan Cox if(pdev == NULL || pci_read_config_byte(pdev, 0x40,&irq) != PCIBIOS_SUCCESSFUL) { 188074cec54SAlan Cox pci_dev_put(pdev); 1891da177e4SLinus Torvalds return -1; 190074cec54SAlan Cox } 191074cec54SAlan Cox else { 192074cec54SAlan Cox pci_dev_put(pdev); 1931da177e4SLinus Torvalds return irq; 1941da177e4SLinus Torvalds } 195074cec54SAlan Cox } 1961da177e4SLinus Torvalds 1971da177e4SLinus Torvalds return COMMON_TABLE_LOOKUP; 1981da177e4SLinus Torvalds } 1991da177e4SLinus Torvalds 2001da177e4SLinus Torvalds static u8 __init 2011da177e4SLinus Torvalds miata_swizzle(struct pci_dev *dev, u8 *pinp) 2021da177e4SLinus Torvalds { 2031da177e4SLinus Torvalds int slot, pin = *pinp; 2041da177e4SLinus Torvalds 2051da177e4SLinus Torvalds if (dev->bus->number == 0) { 2061da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 2071da177e4SLinus Torvalds } 2081da177e4SLinus Torvalds /* Check for the built-in bridge. */ 2091da177e4SLinus Torvalds else if ((PCI_SLOT(dev->bus->self->devfn) == 8) || 2101da177e4SLinus Torvalds (PCI_SLOT(dev->bus->self->devfn) == 20)) { 2111da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn) + 9; 2121da177e4SLinus Torvalds } 2131da177e4SLinus Torvalds else 2141da177e4SLinus Torvalds { 2151da177e4SLinus Torvalds /* Must be a card-based bridge. */ 2161da177e4SLinus Torvalds do { 2171da177e4SLinus Torvalds if ((PCI_SLOT(dev->bus->self->devfn) == 8) || 2181da177e4SLinus Torvalds (PCI_SLOT(dev->bus->self->devfn) == 20)) { 2191da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn) + 9; 2201da177e4SLinus Torvalds break; 2211da177e4SLinus Torvalds } 2221be9baa0SBjorn Helgaas pin = pci_swizzle_interrupt_pin(dev, pin); 2231da177e4SLinus Torvalds 2241da177e4SLinus Torvalds /* Move up the chain of bridges. */ 2251da177e4SLinus Torvalds dev = dev->bus->self; 2261da177e4SLinus Torvalds /* Slot of the next bridge. */ 2271da177e4SLinus Torvalds slot = PCI_SLOT(dev->devfn); 2281da177e4SLinus Torvalds } while (dev->bus->self); 2291da177e4SLinus Torvalds } 2301da177e4SLinus Torvalds *pinp = pin; 2311da177e4SLinus Torvalds return slot; 2321da177e4SLinus Torvalds } 2331da177e4SLinus Torvalds 2341da177e4SLinus Torvalds static void __init 2351da177e4SLinus Torvalds miata_init_pci(void) 2361da177e4SLinus Torvalds { 2371da177e4SLinus Torvalds cia_init_pci(); 2381da177e4SLinus Torvalds SMC669_Init(0); /* it might be a GL (fails harmlessly if not) */ 2391da177e4SLinus Torvalds es1888_init(); 2401da177e4SLinus Torvalds } 2411da177e4SLinus Torvalds 2421da177e4SLinus Torvalds static void 2431da177e4SLinus Torvalds miata_kill_arch(int mode) 2441da177e4SLinus Torvalds { 2451da177e4SLinus Torvalds cia_kill_arch(mode); 2461da177e4SLinus Torvalds 2471da177e4SLinus Torvalds #ifndef ALPHA_RESTORE_SRM_SETUP 2481da177e4SLinus Torvalds switch(mode) { 2491da177e4SLinus Torvalds case LINUX_REBOOT_CMD_RESTART: 2501da177e4SLinus Torvalds /* Who said DEC engineers have no sense of humor? ;-) */ 2511da177e4SLinus Torvalds if (alpha_using_srm) { 2521da177e4SLinus Torvalds *(vuip) PYXIS_RESET = 0x0000dead; 2531da177e4SLinus Torvalds mb(); 2541da177e4SLinus Torvalds } 2551da177e4SLinus Torvalds break; 2561da177e4SLinus Torvalds case LINUX_REBOOT_CMD_HALT: 2571da177e4SLinus Torvalds break; 2581da177e4SLinus Torvalds case LINUX_REBOOT_CMD_POWER_OFF: 2591da177e4SLinus Torvalds break; 2601da177e4SLinus Torvalds } 2611da177e4SLinus Torvalds 2621da177e4SLinus Torvalds halt(); 2631da177e4SLinus Torvalds #endif 2641da177e4SLinus Torvalds } 2651da177e4SLinus Torvalds 2661da177e4SLinus Torvalds 2671da177e4SLinus Torvalds /* 2681da177e4SLinus Torvalds * The System Vector 2691da177e4SLinus Torvalds */ 2701da177e4SLinus Torvalds 2711da177e4SLinus Torvalds struct alpha_machine_vector miata_mv __initmv = { 2721da177e4SLinus Torvalds .vector_name = "Miata", 2731da177e4SLinus Torvalds DO_EV5_MMU, 2741da177e4SLinus Torvalds DO_DEFAULT_RTC, 2751da177e4SLinus Torvalds DO_PYXIS_IO, 2761da177e4SLinus Torvalds .machine_check = cia_machine_check, 2771da177e4SLinus Torvalds .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 2781da177e4SLinus Torvalds .min_io_address = DEFAULT_IO_BASE, 2791da177e4SLinus Torvalds .min_mem_address = DEFAULT_MEM_BASE, 2801da177e4SLinus Torvalds .pci_dac_offset = PYXIS_DAC_OFFSET, 2811da177e4SLinus Torvalds 2821da177e4SLinus Torvalds .nr_irqs = 48, 2831da177e4SLinus Torvalds .device_interrupt = pyxis_device_interrupt, 2841da177e4SLinus Torvalds 2851da177e4SLinus Torvalds .init_arch = pyxis_init_arch, 2861da177e4SLinus Torvalds .init_irq = miata_init_irq, 2871da177e4SLinus Torvalds .init_rtc = common_init_rtc, 2881da177e4SLinus Torvalds .init_pci = miata_init_pci, 2891da177e4SLinus Torvalds .kill_arch = miata_kill_arch, 2901da177e4SLinus Torvalds .pci_map_irq = miata_map_irq, 2911da177e4SLinus Torvalds .pci_swizzle = miata_swizzle, 2921da177e4SLinus Torvalds }; 2931da177e4SLinus Torvalds ALIAS_MV(miata) 294