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