1/*
2 *	linux/arch/alpha/kernel/sys_sio.c
3 *
4 *	Copyright (C) 1995 David A Rusling
5 *	Copyright (C) 1996 Jay A Estabrook
6 *	Copyright (C) 1998, 1999 Richard Henderson
7 *
8 * Code for all boards that route the PCI interrupts through the SIO
9 * PCI/ISA bridge.  This includes Noname (AXPpci33), Multia (UDB),
10 * Kenetics's Platform 2000, Avanti (AlphaStation), XL, and AlphaBook1.
11 */
12
13#include <linux/config.h>
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/mm.h>
17#include <linux/sched.h>
18#include <linux/pci.h>
19#include <linux/init.h>
20#include <linux/tty.h>
21
22#include <asm/compiler.h>
23#include <asm/ptrace.h>
24#include <asm/system.h>
25#include <asm/dma.h>
26#include <asm/irq.h>
27#include <asm/mmu_context.h>
28#include <asm/io.h>
29#include <asm/pgtable.h>
30#include <asm/core_apecs.h>
31#include <asm/core_lca.h>
32
33#include "proto.h"
34#include "irq_impl.h"
35#include "pci_impl.h"
36#include "machvec_impl.h"
37
38
39static void __init
40sio_init_irq(void)
41{
42	if (alpha_using_srm)
43		alpha_mv.device_interrupt = srm_device_interrupt;
44
45	init_i8259a_irqs();
46	common_init_isa_dma();
47}
48
49static inline void __init
50alphabook1_init_arch(void)
51{
52	/* The AlphaBook1 has LCD video fixed at 800x600,
53	   37 rows and 100 cols. */
54	screen_info.orig_y = 37;
55	screen_info.orig_video_cols = 100;
56	screen_info.orig_video_lines = 37;
57
58	lca_init_arch();
59}
60
61
62/*
63 * sio_route_tab selects irq routing in PCI/ISA bridge so that:
64 *		PIRQ0 -> irq 15
65 *		PIRQ1 -> irq  9
66 *		PIRQ2 -> irq 10
67 *		PIRQ3 -> irq 11
68 *
69 * This probably ought to be configurable via MILO.  For
70 * example, sound boards seem to like using IRQ 9.
71 *
72 * This is NOT how we should do it. PIRQ0-X should have
73 * their own IRQ's, the way intel uses the IO-APIC irq's.
74 */
75
76static void __init
77sio_pci_route(void)
78{
79	pcibios_write_config_dword(0, PCI_DEVFN(7, 0), 0x60,
80				   alpha_mv.sys.sio.route_tab);
81}
82
83static unsigned int __init
84sio_collect_irq_levels(void)
85{
86	unsigned int level_bits = 0;
87	struct pci_dev *dev;
88
89	/* Iterate through the devices, collecting IRQ levels.  */
90	pci_for_each_dev(dev) {
91		if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&
92		    (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))
93			continue;
94
95		if (dev->irq)
96			level_bits |= (1 << dev->irq);
97	}
98	return level_bits;
99}
100
101static void __init
102sio_fixup_irq_levels(unsigned int level_bits)
103{
104	unsigned int old_level_bits;
105
106	/*
107	 * Now, make all PCI interrupts level sensitive.  Notice:
108	 * these registers must be accessed byte-wise.  inw()/outw()
109	 * don't work.
110	 *
111	 * Make sure to turn off any level bits set for IRQs 9,10,11,15,
112	 *  so that the only bits getting set are for devices actually found.
113	 * Note that we do preserve the remainder of the bits, which we hope
114	 *  will be set correctly by ARC/SRM.
115	 *
116	 * Note: we at least preserve any level-set bits on AlphaBook1
117	 */
118	old_level_bits = inb(0x4d0) | (inb(0x4d1) << 8);
119
120	level_bits |= (old_level_bits & 0x71ff);
121
122	outb((level_bits >> 0) & 0xff, 0x4d0);
123	outb((level_bits >> 8) & 0xff, 0x4d1);
124}
125
126static inline int __init
127noname_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
128{
129	/*
130	 * The Noname board has 5 PCI slots with each of the 4
131	 * interrupt pins routed to different pins on the PCI/ISA
132	 * bridge (PIRQ0-PIRQ3).  The table below is based on
133	 * information available at:
134	 *
135	 *   http://ftp.digital.com/pub/DEC/axppci/ref_interrupts.txt
136	 *
137	 * I have no information on the Avanti interrupt routing, but
138	 * the routing seems to be identical to the Noname except
139	 * that the Avanti has an additional slot whose routing I'm
140	 * unsure of.
141	 *
142	 * pirq_tab[0] is a fake entry to deal with old PCI boards
143	 * that have the interrupt pin number hardwired to 0 (meaning
144	 * that they use the default INTA line, if they are interrupt
145	 * driven at all).
146	 */
147	static char irq_tab[][5] __initdata = {
148		/*INT A   B   C   D */
149		{ 3,  3,  3,  3,  3}, /* idsel  6 (53c810) */
150		{-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
151		{ 2,  2, -1, -1, -1}, /* idsel  8 (Hack: slot closest ISA) */
152		{-1, -1, -1, -1, -1}, /* idsel  9 (unused) */
153		{-1, -1, -1, -1, -1}, /* idsel 10 (unused) */
154		{ 0,  0,  2,  1,  0}, /* idsel 11 KN25_PCI_SLOT0 */
155		{ 1,  1,  0,  2,  1}, /* idsel 12 KN25_PCI_SLOT1 */
156		{ 2,  2,  1,  0,  2}, /* idsel 13 KN25_PCI_SLOT2 */
157		{ 0,  0,  0,  0,  0}, /* idsel 14 AS255 TULIP */
158	};
159	const long min_idsel = 6, max_idsel = 14, irqs_per_slot = 5;
160	int irq = COMMON_TABLE_LOOKUP, tmp;
161	tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq);
162	return irq >= 0 ? tmp : -1;
163}
164
165static inline int __init
166p2k_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
167{
168	static char irq_tab[][5] __initdata = {
169		/*INT A   B   C   D */
170		{ 0,  0, -1, -1, -1}, /* idsel  6 (53c810) */
171		{-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
172		{ 1,  1,  2,  3,  0}, /* idsel  8 (slot A) */
173		{ 2,  2,  3,  0,  1}, /* idsel  9 (slot B) */
174		{-1, -1, -1, -1, -1}, /* idsel 10 (unused) */
175		{-1, -1, -1, -1, -1}, /* idsel 11 (unused) */
176		{ 3,  3, -1, -1, -1}, /* idsel 12 (CMD0646) */
177	};
178	const long min_idsel = 6, max_idsel = 12, irqs_per_slot = 5;
179	int irq = COMMON_TABLE_LOOKUP, tmp;
180	tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq);
181	return irq >= 0 ? tmp : -1;
182}
183
184static inline void __init
185noname_init_pci(void)
186{
187	common_init_pci();
188	sio_pci_route();
189	sio_fixup_irq_levels(sio_collect_irq_levels());
190	ns87312_enable_ide(0x26e);
191}
192
193static inline void __init
194alphabook1_init_pci(void)
195{
196	struct pci_dev *dev;
197	unsigned char orig, config;
198
199	common_init_pci();
200	sio_pci_route();
201
202	/*
203	 * On the AlphaBook1, the PCMCIA chip (Cirrus 6729)
204	 * is sensitive to PCI bus bursts, so we must DISABLE
205	 * burst mode for the NCR 8xx SCSI... :-(
206	 *
207	 * Note that the NCR810 SCSI driver must preserve the
208	 * setting of the bit in order for this to work.  At the
209	 * moment (2.0.29), ncr53c8xx.c does NOT do this, but
210	 * 53c7,8xx.c DOES.
211	 */
212
213	dev = NULL;
214	while ((dev = pci_find_device(PCI_VENDOR_ID_NCR, PCI_ANY_ID, dev))) {
215                if (dev->device == PCI_DEVICE_ID_NCR_53C810
216		    || dev->device == PCI_DEVICE_ID_NCR_53C815
217		    || dev->device == PCI_DEVICE_ID_NCR_53C820
218		    || dev->device == PCI_DEVICE_ID_NCR_53C825) {
219			unsigned long io_port;
220			unsigned char ctest4;
221
222			io_port = dev->resource[0].start;
223			ctest4 = inb(io_port+0x21);
224			if (!(ctest4 & 0x80)) {
225				printk("AlphaBook1 NCR init: setting"
226				       " burst disable\n");
227				outb(ctest4 | 0x80, io_port+0x21);
228			}
229                }
230	}
231
232	/* Do not set *ANY* level triggers for AlphaBook1. */
233	sio_fixup_irq_levels(0);
234
235	outb(0x0f, 0x3ce); orig = inb(0x3cf);
236	outb(0x0f, 0x3ce); outb(0x05, 0x3cf);
237	outb(0x0b, 0x3ce); config = inb(0x3cf);
238	if ((config & 0xc0) != 0xc0) {
239		printk("AlphaBook1 VGA init: setting 1Mb memory\n");
240		config |= 0xc0;
241		outb(0x0b, 0x3ce); outb(config, 0x3cf);
242	}
243	outb(0x0f, 0x3ce); outb(orig, 0x3cf);
244}
245
246
247/*
248 * The System Vectors
249 */
250
251#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_BOOK1)
252struct alpha_machine_vector alphabook1_mv __initmv = {
253	vector_name:		"AlphaBook1",
254	DO_EV4_MMU,
255	DO_DEFAULT_RTC,
256	DO_LCA_IO,
257	DO_LCA_BUS,
258	machine_check:		lca_machine_check,
259	max_dma_address:	ALPHA_MAX_DMA_ADDRESS,
260	min_io_address:		DEFAULT_IO_BASE,
261	min_mem_address:	APECS_AND_LCA_DEFAULT_MEM_BASE,
262
263	nr_irqs:		16,
264	device_interrupt:	isa_device_interrupt,
265
266	init_arch:		alphabook1_init_arch,
267	init_irq:		sio_init_irq,
268	init_rtc:		common_init_rtc,
269	init_pci:		alphabook1_init_pci,
270	kill_arch:		NULL,
271	pci_map_irq:		noname_map_irq,
272	pci_swizzle:		common_swizzle,
273
274	sys: { sio: {
275		/* NCR810 SCSI is 14, PCMCIA controller is 15.  */
276		route_tab:	0x0e0f0a0a,
277	}}
278};
279ALIAS_MV(alphabook1)
280#endif
281
282#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_AVANTI)
283struct alpha_machine_vector avanti_mv __initmv = {
284	vector_name:		"Avanti",
285	DO_EV4_MMU,
286	DO_DEFAULT_RTC,
287	DO_APECS_IO,
288	DO_APECS_BUS,
289	machine_check:		apecs_machine_check,
290	max_dma_address:	ALPHA_MAX_DMA_ADDRESS,
291	min_io_address:		DEFAULT_IO_BASE,
292	min_mem_address:	APECS_AND_LCA_DEFAULT_MEM_BASE,
293
294	nr_irqs:		16,
295	device_interrupt:	isa_device_interrupt,
296
297	init_arch:		apecs_init_arch,
298	init_irq:		sio_init_irq,
299	init_rtc:		common_init_rtc,
300	init_pci:		noname_init_pci,
301	pci_map_irq:		noname_map_irq,
302	pci_swizzle:		common_swizzle,
303
304	sys: { sio: {
305		route_tab:	0x0b0a0e0f,
306	}}
307};
308ALIAS_MV(avanti)
309#endif
310
311#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_NONAME)
312struct alpha_machine_vector noname_mv __initmv = {
313	vector_name:		"Noname",
314	DO_EV4_MMU,
315	DO_DEFAULT_RTC,
316	DO_LCA_IO,
317	DO_LCA_BUS,
318	machine_check:		lca_machine_check,
319	max_dma_address:	ALPHA_MAX_DMA_ADDRESS,
320	min_io_address:		DEFAULT_IO_BASE,
321	min_mem_address:	APECS_AND_LCA_DEFAULT_MEM_BASE,
322
323	nr_irqs:		16,
324	device_interrupt:	srm_device_interrupt,
325
326	init_arch:		lca_init_arch,
327	init_irq:		sio_init_irq,
328	init_rtc:		common_init_rtc,
329	init_pci:		noname_init_pci,
330	pci_map_irq:		noname_map_irq,
331	pci_swizzle:		common_swizzle,
332
333	sys: { sio: {
334		/* For UDB, the only available PCI slot must not map to IRQ 9,
335		   since that's the builtin MSS sound chip. That PCI slot
336		   will map to PIRQ1 (for INTA at least), so we give it IRQ 15
337		   instead.
338
339		   Unfortunately we have to do this for NONAME as well, since
340		   they are co-indicated when the platform type "Noname" is
341		   selected... :-(  */
342
343		route_tab:	0x0b0a0f0d,
344	}}
345};
346ALIAS_MV(noname)
347#endif
348
349#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_P2K)
350struct alpha_machine_vector p2k_mv __initmv = {
351	vector_name:		"Platform2000",
352	DO_EV4_MMU,
353	DO_DEFAULT_RTC,
354	DO_LCA_IO,
355	DO_LCA_BUS,
356	machine_check:		lca_machine_check,
357	max_dma_address:	ALPHA_MAX_DMA_ADDRESS,
358	min_io_address:		DEFAULT_IO_BASE,
359	min_mem_address:	APECS_AND_LCA_DEFAULT_MEM_BASE,
360
361	nr_irqs:		16,
362	device_interrupt:	srm_device_interrupt,
363
364	init_arch:		lca_init_arch,
365	init_irq:		sio_init_irq,
366	init_rtc:		common_init_rtc,
367	init_pci:		noname_init_pci,
368	pci_map_irq:		p2k_map_irq,
369	pci_swizzle:		common_swizzle,
370
371	sys: { sio: {
372		route_tab:	0x0b0a090f,
373	}}
374};
375ALIAS_MV(p2k)
376#endif
377
378#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_XL)
379struct alpha_machine_vector xl_mv __initmv = {
380	vector_name:		"XL",
381	DO_EV4_MMU,
382	DO_DEFAULT_RTC,
383	DO_APECS_IO,
384	BUS(apecs),
385	machine_check:		apecs_machine_check,
386	max_dma_address:	ALPHA_XL_MAX_DMA_ADDRESS,
387	min_io_address:		DEFAULT_IO_BASE,
388	min_mem_address:	XL_DEFAULT_MEM_BASE,
389
390	nr_irqs:		16,
391	device_interrupt:	isa_device_interrupt,
392
393	init_arch:		apecs_init_arch,
394	init_irq:		sio_init_irq,
395	init_rtc:		common_init_rtc,
396	init_pci:		noname_init_pci,
397	pci_map_irq:		noname_map_irq,
398	pci_swizzle:		common_swizzle,
399
400	sys: { sio: {
401		route_tab:	0x0b0a090f,
402	}}
403};
404ALIAS_MV(xl)
405#endif
406