]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/mips/pci/ops-bonito64.c
Merge branches 'metronomefb', 'pxa-cm2xx', 'pxa-gumstix', 'pxa-misc', 'pxa-mitac...
[linux-2.6-omap-h63xx.git] / arch / mips / pci / ops-bonito64.c
index 4b4e086a7eb13a8558e17f0e5a72a98351a66433..f742c51acf0d0506a18d3784ecbf87fec371a175 100644 (file)
@@ -1,6 +1,8 @@
 /*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 1999, 2000, 2004  MIPS Technologies, Inc.
+ *     All rights reserved.
+ *     Authors: Carsten Langgaard <carstenl@mips.com>
+ *              Maciej W. Rozycki <macro@mips.com>
  *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
@@ -17,7 +19,6 @@
  *
  * MIPS boards specific PCI support.
  */
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #define PCI_ACCESS_READ  0
 #define PCI_ACCESS_WRITE 1
 
-/*
- *  PCI configuration cycle AD bus definition
- */
-/* Type 0 */
-#define PCI_CFG_TYPE0_REG_SHF           0
-#define PCI_CFG_TYPE0_FUNC_SHF          8
+#ifdef CONFIG_LEMOTE_FULONG
+#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(BONITO_PCICFG_BASE | (offset))
+#define ID_SEL_BEGIN 11
+#else
+#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(_pcictrl_bonito_pcicfg + (offset))
+#define ID_SEL_BEGIN 10
+#endif
+#define MAX_DEV_NUM (31 - ID_SEL_BEGIN)
 
-/* Type 1 */
-#define PCI_CFG_TYPE1_REG_SHF           0
-#define PCI_CFG_TYPE1_FUNC_SHF          8
-#define PCI_CFG_TYPE1_DEV_SHF           11
-#define PCI_CFG_TYPE1_BUS_SHF           16
 
 static int bonito64_pcibios_config_access(unsigned char access_type,
                                      struct pci_bus *bus,
                                      unsigned int devfn, int where,
                                      u32 * data)
 {
-       unsigned char busnum = bus->number;
+       u32 busnum = bus->number;
+       u32 addr, type;
        u32 dummy;
-       u64 pci_addr;
-
-       /* Algorithmics Bonito64 system controller. */
-
-       if ((busnum == 0) && (PCI_SLOT(devfn) > 21)) {
-               /* We number bus 0 devices from 0..21 */
-               return -1;
-       }
-
-#ifdef CONFIG_MIPS_BOARDS_GEN
-       if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) {
-               /* MIPS Core boards have Bonito connected as device 17 */
-               return -1;
-       }
-#endif
-
-       /* Clear cause register bits */
-       BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
-                         BONITO_PCICMD_MTABORT_CLR);
+       void *addrp;
+       int device = PCI_SLOT(devfn);
+       int function = PCI_FUNC(devfn);
+       int reg = where & ~3;
 
-       /*
-        * Setup pattern to be used as PCI "address" for
-        * Type 0 cycle
-        */
        if (busnum == 0) {
-               /* IDSEL */
-               pci_addr = (u64) 1 << (PCI_SLOT(devfn) + 10);
-       } else {
-               /* Bus number */
-               pci_addr = busnum << PCI_CFG_TYPE1_BUS_SHF;
-
-               /* Device number */
-               pci_addr |=
-                   PCI_SLOT(devfn) << PCI_CFG_TYPE1_DEV_SHF;
-       }
-
-       /* Function (same for Type 0/1) */
-       pci_addr |= PCI_FUNC(devfn) << PCI_CFG_TYPE0_FUNC_SHF;
-
-       /* Register number (same for Type 0/1) */
-       pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF;
+               /* Type 0 configuration for onboard PCI bus */
+               if (device > MAX_DEV_NUM)
+                       return -1;
 
-       if (busnum == 0) {
-               /* Type 0 */
-               BONITO_PCIMAP_CFG = pci_addr >> 16;
+               addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg;
+               type = 0;
        } else {
-               /* Type 1 */
-               BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000;
+               /* Type 1 configuration for offboard PCI bus */
+               addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
+               type = 0x10000;
        }
 
-       pci_addr &= 0xffff;
+       /* Clear aborts */
+       BONITO_PCICMD |= BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR;
+
+       BONITO_PCIMAP_CFG = (addr >> 16) | type;
 
        /* Flush Bonito register block */
        dummy = BONITO_PCIMAP_CFG;
-       iob();          /* sync */
+       mmiowb();
 
-       /* Perform access */
+       addrp = CFG_SPACE_REG(addr & 0xffff);
        if (access_type == PCI_ACCESS_WRITE) {
-               *(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr) = *(u32 *) data;
-
+               writel(cpu_to_le32(*data), addrp);
+#ifndef CONFIG_LEMOTE_FULONG
                /* Wait till done */
                while (BONITO_PCIMSTAT & 0xF);
+#endif
        } else {
-               *(u32 *) data = *(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr);
+               *data = le32_to_cpu(readl(addrp));
        }
 
        /* Detect Master/Target abort */
@@ -127,6 +98,7 @@ static int bonito64_pcibios_config_access(unsigned char access_type,
        }
 
        return 0;
+
 }