• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/mips/sni/
1/*
2 * PCIMT specific code
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License.  See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
9 * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
10 */
11
12#include <linux/init.h>
13#include <linux/interrupt.h>
14#include <linux/pci.h>
15#include <linux/serial_8250.h>
16
17#include <asm/sni.h>
18#include <asm/time.h>
19#include <asm/i8259.h>
20#include <asm/irq_cpu.h>
21
22#define cacheconf (*(volatile unsigned int *)PCIMT_CACHECONF)
23#define invspace (*(volatile unsigned int *)PCIMT_INVSPACE)
24
25static void __init sni_pcimt_sc_init(void)
26{
27	unsigned int scsiz, sc_size;
28
29	scsiz = cacheconf & 7;
30	if (scsiz == 0) {
31		printk("Second level cache is deactived.\n");
32		return;
33	}
34	if (scsiz >= 6) {
35		printk("Invalid second level cache size configured, "
36		       "deactivating second level cache.\n");
37		cacheconf = 0;
38		return;
39	}
40
41	sc_size = 128 << scsiz;
42	printk("%dkb second level cache detected, deactivating.\n", sc_size);
43	cacheconf = 0;
44}
45
46
47/*
48 * A bit more gossip about the iron we're running on ...
49 */
50static inline void sni_pcimt_detect(void)
51{
52	char boardtype[80];
53	unsigned char csmsr;
54	char *p = boardtype;
55	unsigned int asic;
56
57	csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
58
59	p += sprintf(p, "%s PCI", (csmsr & 0x80) ? "RM200" : "RM300");
60	if ((csmsr & 0x80) == 0)
61		p += sprintf(p, ", board revision %s",
62		             (csmsr & 0x20) ? "D" : "C");
63	asic = csmsr & 0x80;
64	asic = (csmsr & 0x08) ? asic : !asic;
65	p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1");
66	printk("%s.\n", boardtype);
67}
68
69#define PORT(_base,_irq)				\
70	{						\
71		.iobase		= _base,		\
72		.irq		= _irq,			\
73		.uartclk	= 1843200,		\
74		.iotype		= UPIO_PORT,		\
75		.flags		= UPF_BOOT_AUTOCONF,	\
76	}
77
78static struct plat_serial8250_port pcimt_data[] = {
79	PORT(0x3f8, 4),
80	PORT(0x2f8, 3),
81	{ },
82};
83
84static struct platform_device pcimt_serial8250_device = {
85	.name			= "serial8250",
86	.id			= PLAT8250_DEV_PLATFORM,
87	.dev			= {
88		.platform_data	= pcimt_data,
89	},
90};
91
92static struct resource pcimt_cmos_rsrc[] = {
93        {
94                .start = 0x70,
95                .end   = 0x71,
96                .flags = IORESOURCE_IO
97        },
98        {
99                .start = 8,
100                .end   = 8,
101                .flags = IORESOURCE_IRQ
102        }
103};
104
105static struct platform_device pcimt_cmos_device = {
106        .name           = "rtc_cmos",
107        .num_resources  = ARRAY_SIZE(pcimt_cmos_rsrc),
108        .resource       = pcimt_cmos_rsrc
109};
110
111
112static struct resource sni_io_resource = {
113	.start	= 0x00000000UL,
114	.end	= 0x03bfffffUL,
115	.name	= "PCIMT IO MEM",
116	.flags	= IORESOURCE_IO,
117};
118
119static struct resource pcimt_io_resources[] = {
120	{
121		.start	= 0x00,
122		.end	= 0x1f,
123		.name	= "dma1",
124		.flags	= IORESOURCE_BUSY
125	}, {
126		.start	=  0x40,
127		.end	= 0x5f,
128		.name	= "timer",
129		.flags	= IORESOURCE_BUSY
130	}, {
131		.start	=  0x60,
132		.end	= 0x6f,
133		.name	= "keyboard",
134		.flags	= IORESOURCE_BUSY
135	}, {
136		.start	=  0x80,
137		.end	= 0x8f,
138		.name	= "dma page reg",
139		.flags	= IORESOURCE_BUSY
140	}, {
141		.start	=  0xc0,
142		.end	= 0xdf,
143		.name	= "dma2",
144		.flags	= IORESOURCE_BUSY
145	}, {
146		.start	=  0xcfc,
147		.end	= 0xcff,
148		.name	= "PCI config data",
149		.flags	= IORESOURCE_BUSY
150	}
151};
152
153static struct resource pcimt_mem_resources[] = {
154	{
155		/*
156		 * this region should only be 4 bytes long,
157		 * but it's 16MB on all RM300C I've checked
158		 */
159		.start	= 0x1a000000,
160		.end	= 0x1affffff,
161		.name	= "PCI INT ACK",
162		.flags	= IORESOURCE_BUSY
163	}
164};
165
166static struct resource sni_mem_resource = {
167	.start	= 0x18000000UL,
168	.end	= 0x1fbfffffUL,
169	.name	= "PCIMT PCI MEM",
170	.flags	= IORESOURCE_MEM
171};
172
173static void __init sni_pcimt_resource_init(void)
174{
175	int i;
176
177	/* request I/O space for devices used on all i[345]86 PCs */
178	for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++)
179		request_resource(&sni_io_resource, pcimt_io_resources + i);
180	/* request MEM space for devices used on all i[345]86 PCs */
181	for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++)
182		request_resource(&sni_mem_resource, pcimt_mem_resources + i);
183}
184
185extern struct pci_ops sni_pcimt_ops;
186
187static struct pci_controller sni_controller = {
188	.pci_ops	= &sni_pcimt_ops,
189	.mem_resource	= &sni_mem_resource,
190	.mem_offset	= 0x00000000UL,
191	.io_resource	= &sni_io_resource,
192	.io_offset	= 0x00000000UL,
193	.io_map_base    = SNI_PORT_BASE
194};
195
196static void enable_pcimt_irq(unsigned int irq)
197{
198	unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
199
200	*(volatile u8 *) PCIMT_IRQSEL |= mask;
201}
202
203void disable_pcimt_irq(unsigned int irq)
204{
205	unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2));
206
207	*(volatile u8 *) PCIMT_IRQSEL &= mask;
208}
209
210static void end_pcimt_irq(unsigned int irq)
211{
212	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
213		enable_pcimt_irq(irq);
214}
215
216static struct irq_chip pcimt_irq_type = {
217	.name = "PCIMT",
218	.ack = disable_pcimt_irq,
219	.mask = disable_pcimt_irq,
220	.mask_ack = disable_pcimt_irq,
221	.unmask = enable_pcimt_irq,
222	.end = end_pcimt_irq,
223};
224
225/*
226 * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
227 * button interrupts.  Later ...
228 */
229static void pcimt_hwint0(void)
230{
231	panic("Received int0 but no handler yet ...");
232}
233
234/*
235 * hwint 1 deals with EISA and SCSI interrupts,
236 *
237 * The EISA_INT bit in CSITPEND is high active, all others are low active.
238 */
239static void pcimt_hwint1(void)
240{
241	u8 pend = *(volatile char *)PCIMT_CSITPEND;
242	unsigned long flags;
243
244	if (pend & IT_EISA) {
245		int irq;
246		/*
247		 * Note: ASIC PCI's builtin interrupt acknowledge feature is
248		 * broken.  Using it may result in loss of some or all i8259
249		 * interrupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
250		 */
251		irq = i8259_irq();
252		if (unlikely(irq < 0))
253			return;
254
255		do_IRQ(irq);
256	}
257
258	if (!(pend & IT_SCSI)) {
259		flags = read_c0_status();
260		clear_c0_status(ST0_IM);
261		do_IRQ(PCIMT_IRQ_SCSI);
262		write_c0_status(flags);
263	}
264}
265
266/*
267 * hwint 3 should deal with the PCI A - D interrupts,
268 */
269static void pcimt_hwint3(void)
270{
271	u8 pend = *(volatile char *)PCIMT_CSITPEND;
272	int irq;
273
274	pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
275	pend ^= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
276	clear_c0_status(IE_IRQ3);
277	irq = PCIMT_IRQ_INT2 + ffs(pend) - 1;
278	do_IRQ(irq);
279	set_c0_status(IE_IRQ3);
280}
281
282static void sni_pcimt_hwint(void)
283{
284	u32 pending = read_c0_cause() & read_c0_status();
285
286	if (pending & C_IRQ5)
287		do_IRQ(MIPS_CPU_IRQ_BASE + 7);
288	else if (pending & C_IRQ4)
289		do_IRQ(MIPS_CPU_IRQ_BASE + 6);
290	else if (pending & C_IRQ3)
291		pcimt_hwint3();
292	else if (pending & C_IRQ1)
293		pcimt_hwint1();
294	else if (pending & C_IRQ0) {
295		pcimt_hwint0();
296	}
297}
298
299void __init sni_pcimt_irq_init(void)
300{
301	int i;
302
303	*(volatile u8 *) PCIMT_IRQSEL = IT_ETH | IT_EISA;
304	mips_cpu_irq_init();
305	/* Actually we've got more interrupts to handle ...  */
306	for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++)
307		set_irq_chip_and_handler(i, &pcimt_irq_type, handle_level_irq);
308	sni_hwint = sni_pcimt_hwint;
309	change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3);
310}
311
312void __init sni_pcimt_init(void)
313{
314	sni_pcimt_detect();
315	sni_pcimt_sc_init();
316	ioport_resource.end = sni_io_resource.end;
317#ifdef CONFIG_PCI
318	PCIBIOS_MIN_IO = 0x9000;
319	register_pci_controller(&sni_controller);
320#endif
321	sni_pcimt_resource_init();
322}
323
324static int __init snirm_pcimt_setup_devinit(void)
325{
326	switch (sni_brd_type) {
327	case SNI_BRD_PCI_MTOWER:
328	case SNI_BRD_PCI_DESKTOP:
329	case SNI_BRD_PCI_MTOWER_CPLUS:
330	        platform_device_register(&pcimt_serial8250_device);
331	        platform_device_register(&pcimt_cmos_device);
332	        break;
333	}
334
335	return 0;
336}
337
338device_initcall(snirm_pcimt_setup_devinit);
339