xref: /OK3568_Linux_fs/kernel/arch/alpha/kernel/sys_miata.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *	linux/arch/alpha/kernel/sys_miata.c
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *	Copyright (C) 1995 David A Rusling
6*4882a593Smuzhiyun  *	Copyright (C) 1996 Jay A Estabrook
7*4882a593Smuzhiyun  *	Copyright (C) 1998, 1999, 2000 Richard Henderson
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * Code supporting the MIATA (EV56+PYXIS).
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/kernel.h>
13*4882a593Smuzhiyun #include <linux/types.h>
14*4882a593Smuzhiyun #include <linux/mm.h>
15*4882a593Smuzhiyun #include <linux/sched.h>
16*4882a593Smuzhiyun #include <linux/pci.h>
17*4882a593Smuzhiyun #include <linux/init.h>
18*4882a593Smuzhiyun #include <linux/reboot.h>
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include <asm/ptrace.h>
21*4882a593Smuzhiyun #include <asm/dma.h>
22*4882a593Smuzhiyun #include <asm/irq.h>
23*4882a593Smuzhiyun #include <asm/mmu_context.h>
24*4882a593Smuzhiyun #include <asm/io.h>
25*4882a593Smuzhiyun #include <asm/core_cia.h>
26*4882a593Smuzhiyun #include <asm/tlbflush.h>
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #include "proto.h"
29*4882a593Smuzhiyun #include "irq_impl.h"
30*4882a593Smuzhiyun #include "pci_impl.h"
31*4882a593Smuzhiyun #include "machvec_impl.h"
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun static void
miata_srm_device_interrupt(unsigned long vector)35*4882a593Smuzhiyun miata_srm_device_interrupt(unsigned long vector)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun 	int irq;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun 	irq = (vector - 0x800) >> 4;
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 	/*
42*4882a593Smuzhiyun 	 * I really hate to do this, but the MIATA SRM console ignores the
43*4882a593Smuzhiyun 	 *  low 8 bits in the interrupt summary register, and reports the
44*4882a593Smuzhiyun 	 *  vector 0x80 *lower* than I expected from the bit numbering in
45*4882a593Smuzhiyun 	 *  the documentation.
46*4882a593Smuzhiyun 	 * This was done because the low 8 summary bits really aren't used
47*4882a593Smuzhiyun 	 *  for reporting any interrupts (the PCI-ISA bridge, bit 7, isn't
48*4882a593Smuzhiyun 	 *  used for this purpose, as PIC interrupts are delivered as the
49*4882a593Smuzhiyun 	 *  vectors 0x800-0x8f0).
50*4882a593Smuzhiyun 	 * But I really don't want to change the fixup code for allocation
51*4882a593Smuzhiyun 	 *  of IRQs, nor the alpha_irq_mask maintenance stuff, both of which
52*4882a593Smuzhiyun 	 *  look nice and clean now.
53*4882a593Smuzhiyun 	 * So, here's this grotty hack... :-(
54*4882a593Smuzhiyun 	 */
55*4882a593Smuzhiyun 	if (irq >= 16)
56*4882a593Smuzhiyun 		irq = irq + 8;
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	handle_irq(irq);
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun static void __init
miata_init_irq(void)62*4882a593Smuzhiyun miata_init_irq(void)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun 	if (alpha_using_srm)
65*4882a593Smuzhiyun 		alpha_mv.device_interrupt = miata_srm_device_interrupt;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun #if 0
68*4882a593Smuzhiyun 	/* These break on MiataGL so we'll try not to do it at all.  */
69*4882a593Smuzhiyun 	*(vulp)PYXIS_INT_HILO = 0x000000B2UL; mb();	/* ISA/NMI HI */
70*4882a593Smuzhiyun 	*(vulp)PYXIS_RT_COUNT = 0UL; mb();		/* clear count */
71*4882a593Smuzhiyun #endif
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	init_i8259a_irqs();
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	/* Not interested in the bogus interrupts (3,10), Fan Fault (0),
76*4882a593Smuzhiyun            NMI (1), or EIDE (9).
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	   We also disable the risers (4,5), since we don't know how to
79*4882a593Smuzhiyun 	   route the interrupts behind the bridge.  */
80*4882a593Smuzhiyun 	init_pyxis_irqs(0x63b0000);
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	common_init_isa_dma();
83*4882a593Smuzhiyun 	if (request_irq(16 + 2, no_action, 0, "halt-switch", NULL))
84*4882a593Smuzhiyun 		pr_err("Failed to register halt-switch interrupt\n");
85*4882a593Smuzhiyun 	if (request_irq(16 + 6, no_action, 0, "timer-cascade", NULL))
86*4882a593Smuzhiyun 		pr_err("Failed to register timer-cascade interrupt\n");
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun /*
91*4882a593Smuzhiyun  * PCI Fixup configuration.
92*4882a593Smuzhiyun  *
93*4882a593Smuzhiyun  * Summary @ PYXIS_INT_REQ:
94*4882a593Smuzhiyun  * Bit      Meaning
95*4882a593Smuzhiyun  * 0        Fan Fault
96*4882a593Smuzhiyun  * 1        NMI
97*4882a593Smuzhiyun  * 2        Halt/Reset switch
98*4882a593Smuzhiyun  * 3        none
99*4882a593Smuzhiyun  * 4        CID0 (Riser ID)
100*4882a593Smuzhiyun  * 5        CID1 (Riser ID)
101*4882a593Smuzhiyun  * 6        Interval timer
102*4882a593Smuzhiyun  * 7        PCI-ISA Bridge
103*4882a593Smuzhiyun  * 8        Ethernet
104*4882a593Smuzhiyun  * 9        EIDE (deprecated, ISA 14/15 used)
105*4882a593Smuzhiyun  *10        none
106*4882a593Smuzhiyun  *11        USB
107*4882a593Smuzhiyun  *12        Interrupt Line A from slot 4
108*4882a593Smuzhiyun  *13        Interrupt Line B from slot 4
109*4882a593Smuzhiyun  *14        Interrupt Line C from slot 4
110*4882a593Smuzhiyun  *15        Interrupt Line D from slot 4
111*4882a593Smuzhiyun  *16        Interrupt Line A from slot 5
112*4882a593Smuzhiyun  *17        Interrupt line B from slot 5
113*4882a593Smuzhiyun  *18        Interrupt Line C from slot 5
114*4882a593Smuzhiyun  *19        Interrupt Line D from slot 5
115*4882a593Smuzhiyun  *20        Interrupt Line A from slot 1
116*4882a593Smuzhiyun  *21        Interrupt Line B from slot 1
117*4882a593Smuzhiyun  *22        Interrupt Line C from slot 1
118*4882a593Smuzhiyun  *23        Interrupt Line D from slot 1
119*4882a593Smuzhiyun  *24        Interrupt Line A from slot 2
120*4882a593Smuzhiyun  *25        Interrupt Line B from slot 2
121*4882a593Smuzhiyun  *26        Interrupt Line C from slot 2
122*4882a593Smuzhiyun  *27        Interrupt Line D from slot 2
123*4882a593Smuzhiyun  *27        Interrupt Line A from slot 3
124*4882a593Smuzhiyun  *29        Interrupt Line B from slot 3
125*4882a593Smuzhiyun  *30        Interrupt Line C from slot 3
126*4882a593Smuzhiyun  *31        Interrupt Line D from slot 3
127*4882a593Smuzhiyun  *
128*4882a593Smuzhiyun  * The device to slot mapping looks like:
129*4882a593Smuzhiyun  *
130*4882a593Smuzhiyun  * Slot     Device
131*4882a593Smuzhiyun  *  3       DC21142 Ethernet
132*4882a593Smuzhiyun  *  4       EIDE CMD646
133*4882a593Smuzhiyun  *  5       none
134*4882a593Smuzhiyun  *  6       USB
135*4882a593Smuzhiyun  *  7       PCI-ISA bridge
136*4882a593Smuzhiyun  *  8       PCI-PCI Bridge      (SBU Riser)
137*4882a593Smuzhiyun  *  9       none
138*4882a593Smuzhiyun  * 10       none
139*4882a593Smuzhiyun  * 11       PCI on board slot 4 (SBU Riser)
140*4882a593Smuzhiyun  * 12       PCI on board slot 5 (SBU Riser)
141*4882a593Smuzhiyun  *
142*4882a593Smuzhiyun  *  These are behind the bridge, so I'm not sure what to do...
143*4882a593Smuzhiyun  *
144*4882a593Smuzhiyun  * 13       PCI on board slot 1 (SBU Riser)
145*4882a593Smuzhiyun  * 14       PCI on board slot 2 (SBU Riser)
146*4882a593Smuzhiyun  * 15       PCI on board slot 3 (SBU Riser)
147*4882a593Smuzhiyun  *
148*4882a593Smuzhiyun  *
149*4882a593Smuzhiyun  * This two layered interrupt approach means that we allocate IRQ 16 and
150*4882a593Smuzhiyun  * above for PCI interrupts.  The IRQ relates to which bit the interrupt
151*4882a593Smuzhiyun  * comes in on.  This makes interrupt processing much easier.
152*4882a593Smuzhiyun  */
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun static int
miata_map_irq(const struct pci_dev * dev,u8 slot,u8 pin)155*4882a593Smuzhiyun miata_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun         static char irq_tab[18][5] = {
158*4882a593Smuzhiyun 		/*INT    INTA   INTB   INTC   INTD */
159*4882a593Smuzhiyun 		{16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8},  /* IdSel 14,  DC21142 */
160*4882a593Smuzhiyun 		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 15,  EIDE    */
161*4882a593Smuzhiyun 		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 16,  none    */
162*4882a593Smuzhiyun 		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 17,  none    */
163*4882a593Smuzhiyun 		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 18,  PCI-ISA */
164*4882a593Smuzhiyun 		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 19,  PCI-PCI */
165*4882a593Smuzhiyun 		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 20,  none    */
166*4882a593Smuzhiyun 		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 21,  none    */
167*4882a593Smuzhiyun 		{16+12, 16+12, 16+13, 16+14, 16+15},  /* IdSel 22,  slot 4  */
168*4882a593Smuzhiyun 		{16+16, 16+16, 16+17, 16+18, 16+19},  /* IdSel 23,  slot 5  */
169*4882a593Smuzhiyun 		/* the next 7 are actually on PCI bus 1, across the bridge */
170*4882a593Smuzhiyun 		{16+11, 16+11, 16+11, 16+11, 16+11},  /* IdSel 24,  QLISP/GL*/
171*4882a593Smuzhiyun 		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 25,  none    */
172*4882a593Smuzhiyun 		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 26,  none    */
173*4882a593Smuzhiyun 		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 27,  none    */
174*4882a593Smuzhiyun 		{16+20, 16+20, 16+21, 16+22, 16+23},  /* IdSel 28,  slot 1  */
175*4882a593Smuzhiyun 		{16+24, 16+24, 16+25, 16+26, 16+27},  /* IdSel 29,  slot 2  */
176*4882a593Smuzhiyun 		{16+28, 16+28, 16+29, 16+30, 16+31},  /* IdSel 30,  slot 3  */
177*4882a593Smuzhiyun 		/* This bridge is on the main bus of the later orig MIATA */
178*4882a593Smuzhiyun 		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 31,  PCI-PCI */
179*4882a593Smuzhiyun         };
180*4882a593Smuzhiyun 	const long min_idsel = 3, max_idsel = 20, irqs_per_slot = 5;
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	/* the USB function of the 82c693 has it's interrupt connected to
183*4882a593Smuzhiyun            the 2nd 8259 controller. So we have to check for it first. */
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	if((slot == 7) && (PCI_FUNC(dev->devfn) == 3)) {
186*4882a593Smuzhiyun 		u8 irq=0;
187*4882a593Smuzhiyun 		struct pci_dev *pdev = pci_get_slot(dev->bus, dev->devfn & ~7);
188*4882a593Smuzhiyun 		if(pdev == NULL || pci_read_config_byte(pdev, 0x40,&irq) != PCIBIOS_SUCCESSFUL) {
189*4882a593Smuzhiyun 			pci_dev_put(pdev);
190*4882a593Smuzhiyun 			return -1;
191*4882a593Smuzhiyun 		}
192*4882a593Smuzhiyun 		else	{
193*4882a593Smuzhiyun 			pci_dev_put(pdev);
194*4882a593Smuzhiyun 			return irq;
195*4882a593Smuzhiyun 		}
196*4882a593Smuzhiyun 	}
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	return COMMON_TABLE_LOOKUP;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun static u8
miata_swizzle(struct pci_dev * dev,u8 * pinp)202*4882a593Smuzhiyun miata_swizzle(struct pci_dev *dev, u8 *pinp)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	int slot, pin = *pinp;
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	if (dev->bus->number == 0) {
207*4882a593Smuzhiyun 		slot = PCI_SLOT(dev->devfn);
208*4882a593Smuzhiyun 	}
209*4882a593Smuzhiyun 	/* Check for the built-in bridge.  */
210*4882a593Smuzhiyun 	else if ((PCI_SLOT(dev->bus->self->devfn) == 8) ||
211*4882a593Smuzhiyun 		 (PCI_SLOT(dev->bus->self->devfn) == 20)) {
212*4882a593Smuzhiyun 		slot = PCI_SLOT(dev->devfn) + 9;
213*4882a593Smuzhiyun 	}
214*4882a593Smuzhiyun 	else
215*4882a593Smuzhiyun 	{
216*4882a593Smuzhiyun 		/* Must be a card-based bridge.  */
217*4882a593Smuzhiyun 		do {
218*4882a593Smuzhiyun 			if ((PCI_SLOT(dev->bus->self->devfn) == 8) ||
219*4882a593Smuzhiyun 			    (PCI_SLOT(dev->bus->self->devfn) == 20)) {
220*4882a593Smuzhiyun 				slot = PCI_SLOT(dev->devfn) + 9;
221*4882a593Smuzhiyun 				break;
222*4882a593Smuzhiyun 			}
223*4882a593Smuzhiyun 			pin = pci_swizzle_interrupt_pin(dev, pin);
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 			/* Move up the chain of bridges.  */
226*4882a593Smuzhiyun 			dev = dev->bus->self;
227*4882a593Smuzhiyun 			/* Slot of the next bridge.  */
228*4882a593Smuzhiyun 			slot = PCI_SLOT(dev->devfn);
229*4882a593Smuzhiyun 		} while (dev->bus->self);
230*4882a593Smuzhiyun 	}
231*4882a593Smuzhiyun 	*pinp = pin;
232*4882a593Smuzhiyun 	return slot;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun static void __init
miata_init_pci(void)236*4882a593Smuzhiyun miata_init_pci(void)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun 	cia_init_pci();
239*4882a593Smuzhiyun 	SMC669_Init(0); /* it might be a GL (fails harmlessly if not) */
240*4882a593Smuzhiyun 	es1888_init();
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun static void
miata_kill_arch(int mode)244*4882a593Smuzhiyun miata_kill_arch(int mode)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun 	cia_kill_arch(mode);
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun #ifndef ALPHA_RESTORE_SRM_SETUP
249*4882a593Smuzhiyun 	switch(mode) {
250*4882a593Smuzhiyun 	case LINUX_REBOOT_CMD_RESTART:
251*4882a593Smuzhiyun 		/* Who said DEC engineers have no sense of humor? ;-)  */
252*4882a593Smuzhiyun 		if (alpha_using_srm) {
253*4882a593Smuzhiyun 			*(vuip) PYXIS_RESET = 0x0000dead;
254*4882a593Smuzhiyun 			mb();
255*4882a593Smuzhiyun 		}
256*4882a593Smuzhiyun 		break;
257*4882a593Smuzhiyun 	case LINUX_REBOOT_CMD_HALT:
258*4882a593Smuzhiyun 		break;
259*4882a593Smuzhiyun 	case LINUX_REBOOT_CMD_POWER_OFF:
260*4882a593Smuzhiyun 		break;
261*4882a593Smuzhiyun 	}
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	halt();
264*4882a593Smuzhiyun #endif
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun /*
269*4882a593Smuzhiyun  * The System Vector
270*4882a593Smuzhiyun  */
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun struct alpha_machine_vector miata_mv __initmv = {
273*4882a593Smuzhiyun 	.vector_name		= "Miata",
274*4882a593Smuzhiyun 	DO_EV5_MMU,
275*4882a593Smuzhiyun 	DO_DEFAULT_RTC,
276*4882a593Smuzhiyun 	DO_PYXIS_IO,
277*4882a593Smuzhiyun 	.machine_check		= cia_machine_check,
278*4882a593Smuzhiyun 	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
279*4882a593Smuzhiyun 	.min_io_address		= DEFAULT_IO_BASE,
280*4882a593Smuzhiyun 	.min_mem_address	= DEFAULT_MEM_BASE,
281*4882a593Smuzhiyun 	.pci_dac_offset		= PYXIS_DAC_OFFSET,
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	.nr_irqs		= 48,
284*4882a593Smuzhiyun 	.device_interrupt	= pyxis_device_interrupt,
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	.init_arch		= pyxis_init_arch,
287*4882a593Smuzhiyun 	.init_irq		= miata_init_irq,
288*4882a593Smuzhiyun 	.init_rtc		= common_init_rtc,
289*4882a593Smuzhiyun 	.init_pci		= miata_init_pci,
290*4882a593Smuzhiyun 	.kill_arch		= miata_kill_arch,
291*4882a593Smuzhiyun 	.pci_map_irq		= miata_map_irq,
292*4882a593Smuzhiyun 	.pci_swizzle		= miata_swizzle,
293*4882a593Smuzhiyun };
294*4882a593Smuzhiyun ALIAS_MV(miata)
295