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/mc146818-time.h> 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 sni_io_resource = { 94 .start = 0x00000000UL, 95 .end = 0x03bfffffUL, 96 .name = "PCIMT IO MEM", 97 .flags = IORESOURCE_IO, 98 }; 99 100 static struct resource pcimt_io_resources[] = { 101 { 102 .start = 0x00, 103 .end = 0x1f, 104 .name = "dma1", 105 .flags = IORESOURCE_BUSY 106 }, { 107 .start = 0x40, 108 .end = 0x5f, 109 .name = "timer", 110 .flags = IORESOURCE_BUSY 111 }, { 112 .start = 0x60, 113 .end = 0x6f, 114 .name = "keyboard", 115 .flags = IORESOURCE_BUSY 116 }, { 117 .start = 0x80, 118 .end = 0x8f, 119 .name = "dma page reg", 120 .flags = IORESOURCE_BUSY 121 }, { 122 .start = 0xc0, 123 .end = 0xdf, 124 .name = "dma2", 125 .flags = IORESOURCE_BUSY 126 }, { 127 .start = 0xcfc, 128 .end = 0xcff, 129 .name = "PCI config data", 130 .flags = IORESOURCE_BUSY 131 } 132 }; 133 134 static struct resource pcimt_mem_resources[] = { 135 { 136 /* 137 * this region should only be 4 bytes long, 138 * but it's 16MB on all RM300C I've checked 139 */ 140 .start = 0x1a000000, 141 .end = 0x1affffff, 142 .name = "PCI INT ACK", 143 .flags = IORESOURCE_BUSY 144 } 145 }; 146 147 static struct resource sni_mem_resource = { 148 .start = 0x18000000UL, 149 .end = 0x1fbfffffUL, 150 .name = "PCIMT PCI MEM", 151 .flags = IORESOURCE_MEM 152 }; 153 154 static void __init sni_pcimt_resource_init(void) 155 { 156 int i; 157 158 /* request I/O space for devices used on all i[345]86 PCs */ 159 for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++) 160 request_resource(&sni_io_resource, pcimt_io_resources + i); 161 /* request MEM space for devices used on all i[345]86 PCs */ 162 for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++) 163 request_resource(&sni_mem_resource, pcimt_mem_resources + i); 164 } 165 166 extern struct pci_ops sni_pcimt_ops; 167 168 static struct pci_controller sni_controller = { 169 .pci_ops = &sni_pcimt_ops, 170 .mem_resource = &sni_mem_resource, 171 .mem_offset = 0x00000000UL, 172 .io_resource = &sni_io_resource, 173 .io_offset = 0x00000000UL, 174 .io_map_base = SNI_PORT_BASE 175 }; 176 177 static void enable_pcimt_irq(unsigned int irq) 178 { 179 unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); 180 181 *(volatile u8 *) PCIMT_IRQSEL |= mask; 182 } 183 184 void disable_pcimt_irq(unsigned int irq) 185 { 186 unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2)); 187 188 *(volatile u8 *) PCIMT_IRQSEL &= mask; 189 } 190 191 static void end_pcimt_irq(unsigned int irq) 192 { 193 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 194 enable_pcimt_irq(irq); 195 } 196 197 static struct irq_chip pcimt_irq_type = { 198 .typename = "PCIMT", 199 .ack = disable_pcimt_irq, 200 .mask = disable_pcimt_irq, 201 .mask_ack = disable_pcimt_irq, 202 .unmask = enable_pcimt_irq, 203 .end = end_pcimt_irq, 204 }; 205 206 /* 207 * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug 208 * button interrupts. Later ... 209 */ 210 static void pcimt_hwint0(void) 211 { 212 panic("Received int0 but no handler yet ..."); 213 } 214 215 /* 216 * hwint 1 deals with EISA and SCSI interrupts, 217 * 218 * The EISA_INT bit in CSITPEND is high active, all others are low active. 219 */ 220 static void pcimt_hwint1(void) 221 { 222 u8 pend = *(volatile char *)PCIMT_CSITPEND; 223 unsigned long flags; 224 225 if (pend & IT_EISA) { 226 int irq; 227 /* 228 * Note: ASIC PCI's builtin interrupt achknowledge feature is 229 * broken. Using it may result in loss of some or all i8259 230 * interupts, so don't use PCIMT_INT_ACKNOWLEDGE ... 231 */ 232 irq = i8259_irq(); 233 if (unlikely(irq < 0)) 234 return; 235 236 do_IRQ(irq); 237 } 238 239 if (!(pend & IT_SCSI)) { 240 flags = read_c0_status(); 241 clear_c0_status(ST0_IM); 242 do_IRQ(PCIMT_IRQ_SCSI); 243 write_c0_status(flags); 244 } 245 } 246 247 /* 248 * hwint 3 should deal with the PCI A - D interrupts, 249 */ 250 static void pcimt_hwint3(void) 251 { 252 u8 pend = *(volatile char *)PCIMT_CSITPEND; 253 int irq; 254 255 pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD); 256 pend ^= (IT_INTA | IT_INTB | IT_INTC | IT_INTD); 257 clear_c0_status(IE_IRQ3); 258 irq = PCIMT_IRQ_INT2 + ffs(pend) - 1; 259 do_IRQ(irq); 260 set_c0_status(IE_IRQ3); 261 } 262 263 static void sni_pcimt_hwint(void) 264 { 265 u32 pending = read_c0_cause() & read_c0_status(); 266 267 if (pending & C_IRQ5) 268 do_IRQ (MIPS_CPU_IRQ_BASE + 7); 269 else if (pending & C_IRQ4) 270 do_IRQ (MIPS_CPU_IRQ_BASE + 6); 271 else if (pending & C_IRQ3) 272 pcimt_hwint3(); 273 else if (pending & C_IRQ1) 274 pcimt_hwint1(); 275 else if (pending & C_IRQ0) { 276 pcimt_hwint0(); 277 } 278 } 279 280 void __init sni_pcimt_irq_init(void) 281 { 282 int i; 283 284 *(volatile u8 *) PCIMT_IRQSEL = IT_ETH | IT_EISA; 285 mips_cpu_irq_init(); 286 /* Actually we've got more interrupts to handle ... */ 287 for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++) 288 set_irq_chip(i, &pcimt_irq_type); 289 sni_hwint = sni_pcimt_hwint; 290 change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3); 291 } 292 293 void sni_pcimt_init(void) 294 { 295 sni_pcimt_detect(); 296 sni_pcimt_sc_init(); 297 rtc_mips_get_time = mc146818_get_cmos_time; 298 rtc_mips_set_time = mc146818_set_rtc_mmss; 299 board_time_init = sni_cpu_time_init; 300 ioport_resource.end = sni_io_resource.end; 301 #ifdef CONFIG_PCI 302 PCIBIOS_MIN_IO = 0x9000; 303 register_pci_controller(&sni_controller); 304 #endif 305 sni_pcimt_resource_init(); 306 } 307 308 static int __init snirm_pcimt_setup_devinit(void) 309 { 310 switch (sni_brd_type) { 311 case SNI_BRD_PCI_MTOWER: 312 case SNI_BRD_PCI_DESKTOP: 313 case SNI_BRD_PCI_MTOWER_CPLUS: 314 platform_device_register(&pcimt_serial8250_device); 315 break; 316 } 317 318 return 0; 319 } 320 321 device_initcall(snirm_pcimt_setup_devinit); 322