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