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