root/arch/mips/sni/pcimt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sni_pcimt_sc_init
  2. sni_pcimt_detect
  3. sni_pcimt_resource_init
  4. enable_pcimt_irq
  5. disable_pcimt_irq
  6. pcimt_hwint0
  7. pcimt_hwint1
  8. pcimt_hwint3
  9. sni_pcimt_hwint
  10. sni_pcimt_irq_init
  11. sni_pcimt_init
  12. snirm_pcimt_setup_devinit

   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 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  */
  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 #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 
 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 
 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  */
 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  */
 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  */
 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 
 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 
 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 
 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 
 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);

/* [<][>][^][v][top][bottom][index][help] */