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 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 deactived.\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 */ 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 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 static struct pci_controller sni_controller = { 189 .pci_ops = &sni_pcimt_ops, 190 .mem_resource = &sni_mem_resource, 191 .mem_offset = 0x00000000UL, 192 .io_resource = &sni_io_resource, 193 .io_offset = 0x00000000UL, 194 .io_map_base = SNI_PORT_BASE 195 }; 196 197 static void enable_pcimt_irq(unsigned int irq) 198 { 199 unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); 200 201 *(volatile u8 *) PCIMT_IRQSEL |= mask; 202 } 203 204 void disable_pcimt_irq(unsigned int irq) 205 { 206 unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2)); 207 208 *(volatile u8 *) PCIMT_IRQSEL &= mask; 209 } 210 211 static void end_pcimt_irq(unsigned int irq) 212 { 213 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 214 enable_pcimt_irq(irq); 215 } 216 217 static struct irq_chip pcimt_irq_type = { 218 .name = "PCIMT", 219 .ack = disable_pcimt_irq, 220 .mask = disable_pcimt_irq, 221 .mask_ack = disable_pcimt_irq, 222 .unmask = enable_pcimt_irq, 223 .end = end_pcimt_irq, 224 }; 225 226 /* 227 * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug 228 * button interrupts. Later ... 229 */ 230 static void pcimt_hwint0(void) 231 { 232 panic("Received int0 but no handler yet ..."); 233 } 234 235 /* 236 * hwint 1 deals with EISA and SCSI interrupts, 237 * 238 * The EISA_INT bit in CSITPEND is high active, all others are low active. 239 */ 240 static void pcimt_hwint1(void) 241 { 242 u8 pend = *(volatile char *)PCIMT_CSITPEND; 243 unsigned long flags; 244 245 if (pend & IT_EISA) { 246 int irq; 247 /* 248 * Note: ASIC PCI's builtin interrupt acknowledge feature is 249 * broken. Using it may result in loss of some or all i8259 250 * interrupts, so don't use PCIMT_INT_ACKNOWLEDGE ... 251 */ 252 irq = i8259_irq(); 253 if (unlikely(irq < 0)) 254 return; 255 256 do_IRQ(irq); 257 } 258 259 if (!(pend & IT_SCSI)) { 260 flags = read_c0_status(); 261 clear_c0_status(ST0_IM); 262 do_IRQ(PCIMT_IRQ_SCSI); 263 write_c0_status(flags); 264 } 265 } 266 267 /* 268 * hwint 3 should deal with the PCI A - D interrupts, 269 */ 270 static void pcimt_hwint3(void) 271 { 272 u8 pend = *(volatile char *)PCIMT_CSITPEND; 273 int irq; 274 275 pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD); 276 pend ^= (IT_INTA | IT_INTB | IT_INTC | IT_INTD); 277 clear_c0_status(IE_IRQ3); 278 irq = PCIMT_IRQ_INT2 + ffs(pend) - 1; 279 do_IRQ(irq); 280 set_c0_status(IE_IRQ3); 281 } 282 283 static void sni_pcimt_hwint(void) 284 { 285 u32 pending = read_c0_cause() & read_c0_status(); 286 287 if (pending & C_IRQ5) 288 do_IRQ(MIPS_CPU_IRQ_BASE + 7); 289 else if (pending & C_IRQ4) 290 do_IRQ(MIPS_CPU_IRQ_BASE + 6); 291 else if (pending & C_IRQ3) 292 pcimt_hwint3(); 293 else if (pending & C_IRQ1) 294 pcimt_hwint1(); 295 else if (pending & C_IRQ0) { 296 pcimt_hwint0(); 297 } 298 } 299 300 void __init sni_pcimt_irq_init(void) 301 { 302 int i; 303 304 *(volatile u8 *) PCIMT_IRQSEL = IT_ETH | IT_EISA; 305 mips_cpu_irq_init(); 306 /* Actually we've got more interrupts to handle ... */ 307 for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++) 308 set_irq_chip_and_handler(i, &pcimt_irq_type, handle_level_irq); 309 sni_hwint = sni_pcimt_hwint; 310 change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3); 311 } 312 313 void __init sni_pcimt_init(void) 314 { 315 sni_pcimt_detect(); 316 sni_pcimt_sc_init(); 317 ioport_resource.end = sni_io_resource.end; 318 #ifdef CONFIG_PCI 319 PCIBIOS_MIN_IO = 0x9000; 320 register_pci_controller(&sni_controller); 321 #endif 322 sni_pcimt_resource_init(); 323 } 324 325 static int __init snirm_pcimt_setup_devinit(void) 326 { 327 switch (sni_brd_type) { 328 case SNI_BRD_PCI_MTOWER: 329 case SNI_BRD_PCI_DESKTOP: 330 case SNI_BRD_PCI_MTOWER_CPLUS: 331 platform_device_register(&pcimt_serial8250_device); 332 platform_device_register(&pcimt_cmos_device); 333 break; 334 } 335 336 return 0; 337 } 338 339 device_initcall(snirm_pcimt_setup_devinit); 340