Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * PCIMT specific code
0003  *
0004  * This file is subject to the terms and conditions of the GNU General Public
0005  * License.  See the file "COPYING" in the main directory of this archive
0006  * for more details.
0007  *
0008  * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
0009  * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
0010  */
0011 
0012 #include <linux/init.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/irq.h>
0015 #include <linux/pci.h>
0016 #include <linux/serial_8250.h>
0017 
0018 #include <asm/sni.h>
0019 #include <asm/time.h>
0020 #include <asm/i8259.h>
0021 #include <asm/irq_cpu.h>
0022 
0023 #define cacheconf (*(volatile unsigned int *)PCIMT_CACHECONF)
0024 #define invspace (*(volatile unsigned int *)PCIMT_INVSPACE)
0025 
0026 static void __init sni_pcimt_sc_init(void)
0027 {
0028     unsigned int scsiz, sc_size;
0029 
0030     scsiz = cacheconf & 7;
0031     if (scsiz == 0) {
0032         printk("Second level cache is deactivated.\n");
0033         return;
0034     }
0035     if (scsiz >= 6) {
0036         printk("Invalid second level cache size configured, "
0037                "deactivating second level cache.\n");
0038         cacheconf = 0;
0039         return;
0040     }
0041 
0042     sc_size = 128 << scsiz;
0043     printk("%dkb second level cache detected, deactivating.\n", sc_size);
0044     cacheconf = 0;
0045 }
0046 
0047 
0048 /*
0049  * A bit more gossip about the iron we're running on ...
0050  */
0051 static inline void sni_pcimt_detect(void)
0052 {
0053     char boardtype[80];
0054     unsigned char csmsr;
0055     char *p = boardtype;
0056     unsigned int asic;
0057 
0058     csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
0059 
0060     p += sprintf(p, "%s PCI", (csmsr & 0x80) ? "RM200" : "RM300");
0061     if ((csmsr & 0x80) == 0)
0062         p += sprintf(p, ", board revision %s",
0063                  (csmsr & 0x20) ? "D" : "C");
0064     asic = csmsr & 0x80;
0065     asic = (csmsr & 0x08) ? asic : !asic;
0066     p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1");
0067     printk("%s.\n", boardtype);
0068 }
0069 
0070 #define PORT(_base,_irq)                \
0071     {                       \
0072         .iobase     = _base,        \
0073         .irq        = _irq,         \
0074         .uartclk    = 1843200,      \
0075         .iotype     = UPIO_PORT,        \
0076         .flags      = UPF_BOOT_AUTOCONF,    \
0077     }
0078 
0079 static struct plat_serial8250_port pcimt_data[] = {
0080     PORT(0x3f8, 4),
0081     PORT(0x2f8, 3),
0082     { },
0083 };
0084 
0085 static struct platform_device pcimt_serial8250_device = {
0086     .name           = "serial8250",
0087     .id         = PLAT8250_DEV_PLATFORM,
0088     .dev            = {
0089         .platform_data  = pcimt_data,
0090     },
0091 };
0092 
0093 static struct resource pcimt_cmos_rsrc[] = {
0094     {
0095         .start = 0x70,
0096         .end   = 0x71,
0097         .flags = IORESOURCE_IO
0098     },
0099     {
0100         .start = 8,
0101         .end   = 8,
0102         .flags = IORESOURCE_IRQ
0103     }
0104 };
0105 
0106 static struct platform_device pcimt_cmos_device = {
0107     .name       = "rtc_cmos",
0108     .num_resources  = ARRAY_SIZE(pcimt_cmos_rsrc),
0109     .resource   = pcimt_cmos_rsrc
0110 };
0111 
0112 
0113 static struct resource sni_io_resource = {
0114     .start  = 0x00000000UL,
0115     .end    = 0x03bfffffUL,
0116     .name   = "PCIMT IO MEM",
0117     .flags  = IORESOURCE_IO,
0118 };
0119 
0120 static struct resource pcimt_io_resources[] = {
0121     {
0122         .start  = 0x00,
0123         .end    = 0x1f,
0124         .name   = "dma1",
0125         .flags  = IORESOURCE_BUSY
0126     }, {
0127         .start  =  0x40,
0128         .end    = 0x5f,
0129         .name   = "timer",
0130         .flags  = IORESOURCE_BUSY
0131     }, {
0132         .start  =  0x60,
0133         .end    = 0x6f,
0134         .name   = "keyboard",
0135         .flags  = IORESOURCE_BUSY
0136     }, {
0137         .start  =  0x80,
0138         .end    = 0x8f,
0139         .name   = "dma page reg",
0140         .flags  = IORESOURCE_BUSY
0141     }, {
0142         .start  =  0xc0,
0143         .end    = 0xdf,
0144         .name   = "dma2",
0145         .flags  = IORESOURCE_BUSY
0146     }, {
0147         .start  =  0xcfc,
0148         .end    = 0xcff,
0149         .name   = "PCI config data",
0150         .flags  = IORESOURCE_BUSY
0151     }
0152 };
0153 
0154 static struct resource pcimt_mem_resources[] = {
0155     {
0156         /*
0157          * this region should only be 4 bytes long,
0158          * but it's 16MB on all RM300C I've checked
0159          */
0160         .start  = 0x1a000000,
0161         .end    = 0x1affffff,
0162         .name   = "PCI INT ACK",
0163         .flags  = IORESOURCE_BUSY
0164     }
0165 };
0166 
0167 static struct resource sni_mem_resource = {
0168     .start  = 0x18000000UL,
0169     .end    = 0x1fbfffffUL,
0170     .name   = "PCIMT PCI MEM",
0171     .flags  = IORESOURCE_MEM
0172 };
0173 
0174 static void __init sni_pcimt_resource_init(void)
0175 {
0176     int i;
0177 
0178     /* request I/O space for devices used on all i[345]86 PCs */
0179     for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++)
0180         request_resource(&sni_io_resource, pcimt_io_resources + i);
0181     /* request MEM space for devices used on all i[345]86 PCs */
0182     for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++)
0183         request_resource(&sni_mem_resource, pcimt_mem_resources + i);
0184 }
0185 
0186 extern struct pci_ops sni_pcimt_ops;
0187 
0188 #ifdef CONFIG_PCI
0189 static struct pci_controller sni_controller = {
0190     .pci_ops    = &sni_pcimt_ops,
0191     .mem_resource   = &sni_mem_resource,
0192     .mem_offset = 0x00000000UL,
0193     .io_resource    = &sni_io_resource,
0194     .io_offset  = 0x00000000UL,
0195     .io_map_base    = SNI_PORT_BASE
0196 };
0197 #endif
0198 
0199 static void enable_pcimt_irq(struct irq_data *d)
0200 {
0201     unsigned int mask = 1 << (d->irq - PCIMT_IRQ_INT2);
0202 
0203     *(volatile u8 *) PCIMT_IRQSEL |= mask;
0204 }
0205 
0206 void disable_pcimt_irq(struct irq_data *d)
0207 {
0208     unsigned int mask = ~(1 << (d->irq - PCIMT_IRQ_INT2));
0209 
0210     *(volatile u8 *) PCIMT_IRQSEL &= mask;
0211 }
0212 
0213 static struct irq_chip pcimt_irq_type = {
0214     .name = "PCIMT",
0215     .irq_mask = disable_pcimt_irq,
0216     .irq_unmask = enable_pcimt_irq,
0217 };
0218 
0219 /*
0220  * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
0221  * button interrupts.  Later ...
0222  */
0223 static void pcimt_hwint0(void)
0224 {
0225     panic("Received int0 but no handler yet ...");
0226 }
0227 
0228 /*
0229  * hwint 1 deals with EISA and SCSI interrupts,
0230  *
0231  * The EISA_INT bit in CSITPEND is high active, all others are low active.
0232  */
0233 static void pcimt_hwint1(void)
0234 {
0235     u8 pend = *(volatile char *)PCIMT_CSITPEND;
0236     unsigned long flags;
0237 
0238     if (pend & IT_EISA) {
0239         int irq;
0240         /*
0241          * Note: ASIC PCI's builtin interrupt acknowledge feature is
0242          * broken.  Using it may result in loss of some or all i8259
0243          * interrupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
0244          */
0245         irq = i8259_irq();
0246         if (unlikely(irq < 0))
0247             return;
0248 
0249         do_IRQ(irq);
0250     }
0251 
0252     if (!(pend & IT_SCSI)) {
0253         flags = read_c0_status();
0254         clear_c0_status(ST0_IM);
0255         do_IRQ(PCIMT_IRQ_SCSI);
0256         write_c0_status(flags);
0257     }
0258 }
0259 
0260 /*
0261  * hwint 3 should deal with the PCI A - D interrupts,
0262  */
0263 static void pcimt_hwint3(void)
0264 {
0265     u8 pend = *(volatile char *)PCIMT_CSITPEND;
0266     int irq;
0267 
0268     pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
0269     pend ^= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
0270     clear_c0_status(IE_IRQ3);
0271     irq = PCIMT_IRQ_INT2 + ffs(pend) - 1;
0272     do_IRQ(irq);
0273     set_c0_status(IE_IRQ3);
0274 }
0275 
0276 static void sni_pcimt_hwint(void)
0277 {
0278     u32 pending = read_c0_cause() & read_c0_status();
0279 
0280     if (pending & C_IRQ5)
0281         do_IRQ(MIPS_CPU_IRQ_BASE + 7);
0282     else if (pending & C_IRQ4)
0283         do_IRQ(MIPS_CPU_IRQ_BASE + 6);
0284     else if (pending & C_IRQ3)
0285         pcimt_hwint3();
0286     else if (pending & C_IRQ1)
0287         pcimt_hwint1();
0288     else if (pending & C_IRQ0) {
0289         pcimt_hwint0();
0290     }
0291 }
0292 
0293 void __init sni_pcimt_irq_init(void)
0294 {
0295     int i;
0296 
0297     *(volatile u8 *) PCIMT_IRQSEL = IT_ETH | IT_EISA;
0298     mips_cpu_irq_init();
0299     /* Actually we've got more interrupts to handle ...  */
0300     for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++)
0301         irq_set_chip_and_handler(i, &pcimt_irq_type, handle_level_irq);
0302     sni_hwint = sni_pcimt_hwint;
0303     change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3);
0304 }
0305 
0306 void __init sni_pcimt_init(void)
0307 {
0308     sni_pcimt_detect();
0309     sni_pcimt_sc_init();
0310     ioport_resource.end = sni_io_resource.end;
0311 #ifdef CONFIG_PCI
0312     PCIBIOS_MIN_IO = 0x9000;
0313     register_pci_controller(&sni_controller);
0314 #endif
0315     sni_pcimt_resource_init();
0316 }
0317 
0318 static int __init snirm_pcimt_setup_devinit(void)
0319 {
0320     switch (sni_brd_type) {
0321     case SNI_BRD_PCI_MTOWER:
0322     case SNI_BRD_PCI_DESKTOP:
0323     case SNI_BRD_PCI_MTOWER_CPLUS:
0324         platform_device_register(&pcimt_serial8250_device);
0325         platform_device_register(&pcimt_cmos_device);
0326         break;
0327     }
0328 
0329     return 0;
0330 }
0331 
0332 device_initcall(snirm_pcimt_setup_devinit);