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