xref: /openbmc/linux/arch/alpha/kernel/sys_miata.c (revision 1da177e4)
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
361da177e4SLinus Torvalds miata_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
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 
591da177e4SLinus Torvalds 	handle_irq(irq, regs);
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;
1861da177e4SLinus Torvalds 
1871da177e4SLinus Torvalds 		if(pci_read_config_byte(pci_find_slot(dev->bus->number, dev->devfn & ~(7)), 0x40,&irq)!=PCIBIOS_SUCCESSFUL)
1881da177e4SLinus Torvalds 			return -1;
1891da177e4SLinus Torvalds 		else
1901da177e4SLinus Torvalds 			return irq;
1911da177e4SLinus Torvalds 	}
1921da177e4SLinus Torvalds 
1931da177e4SLinus Torvalds 	return COMMON_TABLE_LOOKUP;
1941da177e4SLinus Torvalds }
1951da177e4SLinus Torvalds 
1961da177e4SLinus Torvalds static u8 __init
1971da177e4SLinus Torvalds miata_swizzle(struct pci_dev *dev, u8 *pinp)
1981da177e4SLinus Torvalds {
1991da177e4SLinus Torvalds 	int slot, pin = *pinp;
2001da177e4SLinus Torvalds 
2011da177e4SLinus Torvalds 	if (dev->bus->number == 0) {
2021da177e4SLinus Torvalds 		slot = PCI_SLOT(dev->devfn);
2031da177e4SLinus Torvalds 	}
2041da177e4SLinus Torvalds 	/* Check for the built-in bridge.  */
2051da177e4SLinus Torvalds 	else if ((PCI_SLOT(dev->bus->self->devfn) == 8) ||
2061da177e4SLinus Torvalds 		 (PCI_SLOT(dev->bus->self->devfn) == 20)) {
2071da177e4SLinus Torvalds 		slot = PCI_SLOT(dev->devfn) + 9;
2081da177e4SLinus Torvalds 	}
2091da177e4SLinus Torvalds 	else
2101da177e4SLinus Torvalds 	{
2111da177e4SLinus Torvalds 		/* Must be a card-based bridge.  */
2121da177e4SLinus Torvalds 		do {
2131da177e4SLinus Torvalds 			if ((PCI_SLOT(dev->bus->self->devfn) == 8) ||
2141da177e4SLinus Torvalds 			    (PCI_SLOT(dev->bus->self->devfn) == 20)) {
2151da177e4SLinus Torvalds 				slot = PCI_SLOT(dev->devfn) + 9;
2161da177e4SLinus Torvalds 				break;
2171da177e4SLinus Torvalds 			}
2181da177e4SLinus Torvalds 			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
2191da177e4SLinus Torvalds 
2201da177e4SLinus Torvalds 			/* Move up the chain of bridges.  */
2211da177e4SLinus Torvalds 			dev = dev->bus->self;
2221da177e4SLinus Torvalds 			/* Slot of the next bridge.  */
2231da177e4SLinus Torvalds 			slot = PCI_SLOT(dev->devfn);
2241da177e4SLinus Torvalds 		} while (dev->bus->self);
2251da177e4SLinus Torvalds 	}
2261da177e4SLinus Torvalds 	*pinp = pin;
2271da177e4SLinus Torvalds 	return slot;
2281da177e4SLinus Torvalds }
2291da177e4SLinus Torvalds 
2301da177e4SLinus Torvalds static void __init
2311da177e4SLinus Torvalds miata_init_pci(void)
2321da177e4SLinus Torvalds {
2331da177e4SLinus Torvalds 	cia_init_pci();
2341da177e4SLinus Torvalds 	SMC669_Init(0); /* it might be a GL (fails harmlessly if not) */
2351da177e4SLinus Torvalds 	es1888_init();
2361da177e4SLinus Torvalds }
2371da177e4SLinus Torvalds 
2381da177e4SLinus Torvalds static void
2391da177e4SLinus Torvalds miata_kill_arch(int mode)
2401da177e4SLinus Torvalds {
2411da177e4SLinus Torvalds 	cia_kill_arch(mode);
2421da177e4SLinus Torvalds 
2431da177e4SLinus Torvalds #ifndef ALPHA_RESTORE_SRM_SETUP
2441da177e4SLinus Torvalds 	switch(mode) {
2451da177e4SLinus Torvalds 	case LINUX_REBOOT_CMD_RESTART:
2461da177e4SLinus Torvalds 		/* Who said DEC engineers have no sense of humor? ;-)  */
2471da177e4SLinus Torvalds 		if (alpha_using_srm) {
2481da177e4SLinus Torvalds 			*(vuip) PYXIS_RESET = 0x0000dead;
2491da177e4SLinus Torvalds 			mb();
2501da177e4SLinus Torvalds 		}
2511da177e4SLinus Torvalds 		break;
2521da177e4SLinus Torvalds 	case LINUX_REBOOT_CMD_HALT:
2531da177e4SLinus Torvalds 		break;
2541da177e4SLinus Torvalds 	case LINUX_REBOOT_CMD_POWER_OFF:
2551da177e4SLinus Torvalds 		break;
2561da177e4SLinus Torvalds 	}
2571da177e4SLinus Torvalds 
2581da177e4SLinus Torvalds 	halt();
2591da177e4SLinus Torvalds #endif
2601da177e4SLinus Torvalds }
2611da177e4SLinus Torvalds 
2621da177e4SLinus Torvalds 
2631da177e4SLinus Torvalds /*
2641da177e4SLinus Torvalds  * The System Vector
2651da177e4SLinus Torvalds  */
2661da177e4SLinus Torvalds 
2671da177e4SLinus Torvalds struct alpha_machine_vector miata_mv __initmv = {
2681da177e4SLinus Torvalds 	.vector_name		= "Miata",
2691da177e4SLinus Torvalds 	DO_EV5_MMU,
2701da177e4SLinus Torvalds 	DO_DEFAULT_RTC,
2711da177e4SLinus Torvalds 	DO_PYXIS_IO,
2721da177e4SLinus Torvalds 	.machine_check		= cia_machine_check,
2731da177e4SLinus Torvalds 	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
2741da177e4SLinus Torvalds 	.min_io_address		= DEFAULT_IO_BASE,
2751da177e4SLinus Torvalds 	.min_mem_address	= DEFAULT_MEM_BASE,
2761da177e4SLinus Torvalds 	.pci_dac_offset		= PYXIS_DAC_OFFSET,
2771da177e4SLinus Torvalds 
2781da177e4SLinus Torvalds 	.nr_irqs		= 48,
2791da177e4SLinus Torvalds 	.device_interrupt	= pyxis_device_interrupt,
2801da177e4SLinus Torvalds 
2811da177e4SLinus Torvalds 	.init_arch		= pyxis_init_arch,
2821da177e4SLinus Torvalds 	.init_irq		= miata_init_irq,
2831da177e4SLinus Torvalds 	.init_rtc		= common_init_rtc,
2841da177e4SLinus Torvalds 	.init_pci		= miata_init_pci,
2851da177e4SLinus Torvalds 	.kill_arch		= miata_kill_arch,
2861da177e4SLinus Torvalds 	.pci_map_irq		= miata_map_irq,
2871da177e4SLinus Torvalds 	.pci_swizzle		= miata_swizzle,
2881da177e4SLinus Torvalds };
2891da177e4SLinus Torvalds ALIAS_MV(miata)
290