]> pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Orion: make PCIe/PCI support use mbus DRAM info
authorLennert Buytenhek <buytenh@wantstofly.org>
Thu, 27 Mar 2008 18:51:39 +0000 (14:51 -0400)
committerNicolas Pitre <nico@marvell.com>
Thu, 27 Mar 2008 18:51:39 +0000 (14:51 -0400)
Make the Orion PCIe/PCI code initialise MBUS decode windows based on
mbus_dram_target_info instead of reading the info from the Orion DDR
unit decode registers directly, and move the window code with the other
PCI code, where it can be called as part of the generic PCIe/PCI init
process.

Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Reviewed-by: Tzachi Perelstein <tzachi@marvell.com>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Nicolas Pitre <nico@marvell.com>
arch/arm/mach-orion/addr-map.c
arch/arm/mach-orion/common.c
arch/arm/mach-orion/common.h
arch/arm/mach-orion/pci.c

index ab4484cc14b770a53ccaf57d385a975ce5efb96d..69cd0876f6b9075d5a41c1ca49bb04c0285466c3 100644 (file)
 #define CPU_WIN_DEV_CS1                6
 #define CPU_WIN_DEV_CS2                7
 
-/*
- * PCIE Address Decode Windows registers
- */
-#define PCIE_BAR_CTRL(n)       ORION_PCIE_REG(0x1804 + ((n - 1) * 4))
-#define PCIE_BAR_LO(n)         ORION_PCIE_REG(0x0010 + ((n) * 8))
-#define PCIE_BAR_HI(n)         ORION_PCIE_REG(0x0014 + ((n) * 8))
-#define PCIE_WIN_CTRL(n)       (((n) < 5) ? \
-                                       ORION_PCIE_REG(0x1820 + ((n) << 4)) : \
-                                       ORION_PCIE_REG(0x1880))
-#define PCIE_WIN_BASE(n)       (((n) < 5) ? \
-                                       ORION_PCIE_REG(0x1824 + ((n) << 4)) : \
-                                       ORION_PCIE_REG(0x1884))
-#define PCIE_WIN_REMAP(n)      (((n) < 5) ? \
-                                       ORION_PCIE_REG(0x182c + ((n) << 4)) : \
-                                       ORION_PCIE_REG(0x188c))
-#define PCIE_DEFWIN_CTRL       ORION_PCIE_REG(0x18b0)
-#define PCIE_EXPROM_WIN_CTRL   ORION_PCIE_REG(0x18c0)
-#define PCIE_EXPROM_WIN_REMP   ORION_PCIE_REG(0x18c4)
-#define PCIE_MAX_BARS          3
-#define PCIE_MAX_WINS          6
-
-/*
- * Use PCIE BAR '1' for all DDR banks
- */
-#define PCIE_DRAM_BAR          1
-
-/*
- * PCI Address Decode Windows registers
- */
-#define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION_PCI_REG(0xc08) : \
-                               ((n) == 1) ? ORION_PCI_REG(0xd08) :  \
-                               ((n) == 2) ? ORION_PCI_REG(0xc0c) :  \
-                               ((n) == 3) ? ORION_PCI_REG(0xd0c) : 0)
-#define PCI_BAR_REMAP_DDR_CS(n)        (((n) ==0) ? ORION_PCI_REG(0xc48) : \
-                               ((n) == 1) ? ORION_PCI_REG(0xd48) :  \
-                               ((n) == 2) ? ORION_PCI_REG(0xc4c) :  \
-                               ((n) == 3) ? ORION_PCI_REG(0xd4c) : 0)
-#define PCI_BAR_ENABLE         ORION_PCI_REG(0xc3c)
-#define PCI_CTRL_BASE_LO(n)    ORION_PCI_REG(0x1e00 | ((n) << 4))
-#define PCI_CTRL_BASE_HI(n)    ORION_PCI_REG(0x1e04 | ((n) << 4))
-#define PCI_CTRL_SIZE(n)       ORION_PCI_REG(0x1e08 | ((n) << 4))
-#define PCI_ADDR_DECODE_CTRL   ORION_PCI_REG(0xd3c)
-
-/*
- * PCI configuration heleprs for BAR settings
- */
-#define PCI_CONF_FUNC_BAR_CS(n)                ((n) >> 1)
-#define PCI_CONF_REG_BAR_LO_CS(n)      (((n) & 1) ? 0x18 : 0x10)
-#define PCI_CONF_REG_BAR_HI_CS(n)      (((n) & 1) ? 0x1c : 0x14)
-
 /*
  * Gigabit Ethernet Address Decode Windows registers
  */
@@ -312,104 +262,6 @@ void __init orion_setup_cpu_wins(void)
        orion_mbus_dram_info.num_cs = cs;
 }
 
-/*
- * Setup PCIE BARs and Address Decode Wins:
- * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
- * WIN[0-3] -> DRAM bank[0-3]
- */
-void __init orion_setup_pcie_wins(void)
-{
-       u32 base, size, i;
-
-       /*
-        * First, disable and clear BARs and windows
-        */
-       for (i = 1; i < PCIE_MAX_BARS; i++) {
-               orion_write(PCIE_BAR_CTRL(i), 0);
-               orion_write(PCIE_BAR_LO(i), 0);
-               orion_write(PCIE_BAR_HI(i), 0);
-       }
-
-       for (i = 0; i < PCIE_MAX_WINS; i++) {
-               orion_write(PCIE_WIN_CTRL(i), 0);
-               orion_write(PCIE_WIN_BASE(i), 0);
-               orion_write(PCIE_WIN_REMAP(i), 0);
-       }
-
-       /*
-        * Setup windows for DDR banks. Count total DDR size on the fly.
-        */
-       base = DDR_REG_TO_BASE(orion_read(DDR_BASE_CS(0)));
-       size = 0;
-       for (i = 0; i < DDR_MAX_CS; i++) {
-               u32 bank_base, bank_size;
-               bank_size = orion_read(DDR_SIZE_CS(i));
-               bank_base = orion_read(DDR_BASE_CS(i));
-               if (bank_size & DDR_BANK_EN) {
-                       bank_size = DDR_REG_TO_SIZE(bank_size);
-                       bank_base = DDR_REG_TO_BASE(bank_base);
-                       orion_write(PCIE_WIN_BASE(i), bank_base & 0xffff0000);
-                       orion_write(PCIE_WIN_REMAP(i), 0);
-                       orion_write(PCIE_WIN_CTRL(i),
-                                       ((bank_size-1) & 0xffff0000) |
-                                       (ATTR_DDR_CS(i) << 8) |
-                                       (TARGET_DDR << 4) |
-                                       (PCIE_DRAM_BAR << 1) | WIN_EN);
-                       size += bank_size;
-               }
-       }
-
-       /*
-        * Setup BAR[1] to all DRAM banks
-        */
-       orion_write(PCIE_BAR_LO(PCIE_DRAM_BAR), base & 0xffff0000);
-       orion_write(PCIE_BAR_HI(PCIE_DRAM_BAR), 0);
-       orion_write(PCIE_BAR_CTRL(PCIE_DRAM_BAR),
-                               ((size - 1) & 0xffff0000) | WIN_EN);
-}
-
-void __init orion_setup_pci_wins(void)
-{
-       u32 base, size, i;
-
-       /*
-        * First, disable windows
-        */
-       orion_write(PCI_BAR_ENABLE, 0xffffffff);
-
-       /*
-        * Setup windows for DDR banks.
-        */
-       for (i = 0; i < DDR_MAX_CS; i++) {
-               base = orion_read(DDR_BASE_CS(i));
-               size = orion_read(DDR_SIZE_CS(i));
-               if (size & DDR_BANK_EN) {
-                       u32 bus, dev, func, reg, val;
-                       size = DDR_REG_TO_SIZE(size);
-                       base = DDR_REG_TO_BASE(base);
-                       bus = orion_pci_local_bus_nr();
-                       dev = orion_pci_local_dev_nr();
-                       func = PCI_CONF_FUNC_BAR_CS(i);
-                       reg = PCI_CONF_REG_BAR_LO_CS(i);
-                       orion_pci_hw_rd_conf(bus, dev, func, reg, 4, &val);
-                       orion_pci_hw_wr_conf(bus, dev, func, reg, 4,
-                                       (base & 0xfffff000) | (val & 0xfff));
-                       reg = PCI_CONF_REG_BAR_HI_CS(i);
-                       orion_pci_hw_wr_conf(bus, dev, func, reg, 4, 0);
-                       orion_write(PCI_BAR_SIZE_DDR_CS(i),
-                                       (size - 1) & 0xfffff000);
-                       orion_write(PCI_BAR_REMAP_DDR_CS(i),
-                                       base & 0xfffff000);
-                       orion_clrbits(PCI_BAR_ENABLE, (1 << i));
-               }
-       }
-
-       /*
-        * Disable automatic update of address remaping when writing to BARs
-        */
-       orion_setbits(PCI_ADDR_DECODE_CTRL, 1);
-}
-
 void __init orion_setup_usb_wins(void)
 {
        int i;
index cd9aa43bb47405549c0a576aa76a2d3dfe9bd936..cc16588e8c0c6f5778ad90c571833414d99b8d43 100644 (file)
@@ -336,8 +336,6 @@ void __init orion_init(void)
        orion_setup_cpu_wins();
        orion_setup_usb_wins();
        orion_setup_eth_wins();
-       orion_setup_pci_wins();
-       orion_setup_pcie_wins();
        if (dev == MV88F5182_DEV_ID)
                orion_setup_sata_wins();
 
index 2718245ec4ae2b8e402af272b4ae268709e34fa5..961daaa0b91bd78601469493ec970517a1cdb809 100644 (file)
@@ -34,8 +34,6 @@ void orion_setup_cpu_win(enum orion_target target, u32 base, u32 size, int remap
 void orion_setup_cpu_wins(void);
 void orion_setup_eth_wins(void);
 void orion_setup_usb_wins(void);
-void orion_setup_pci_wins(void);
-void orion_setup_pcie_wins(void);
 void orion_setup_sata_wins(void);
 
 /*
@@ -49,11 +47,8 @@ struct pci_bus;
 void orion_pcie_id(u32 *dev, u32 *rev);
 u32 orion_pcie_local_bus_nr(void);
 u32 orion_pci_local_bus_nr(void);
-u32 orion_pci_local_dev_nr(void);
 int orion_pci_sys_setup(int nr, struct pci_sys_data *sys);
 struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys);
-int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 *val);
-int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 val);
 
 /*
  * Valid GPIO pins according to MPP setup, used by machine-setup.
index b109bb46681e622fc9cff7973e7ba4f00a34d524..cfd3d064c209f7040d5c6de59e3e50599303cf63 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/mbus.h>
 #include <asm/mach/pci.h>
 #include "common.h"
 
 #define PCIE_CONF_BUS(b)               (((b) & 0xff) << 16)
 #define PCIE_CONF_ADDR_EN              (1 << 31)
 
+/*
+ * PCIE Address Decode Windows registers
+ */
+#define PCIE_BAR_CTRL(n)       ORION_PCIE_REG(0x1804 + ((n - 1) * 4))
+#define PCIE_BAR_LO(n)         ORION_PCIE_REG(0x0010 + ((n) * 8))
+#define PCIE_BAR_HI(n)         ORION_PCIE_REG(0x0014 + ((n) * 8))
+#define PCIE_WIN_CTRL(n)       (((n) < 5) ? \
+                                       ORION_PCIE_REG(0x1820 + ((n) << 4)) : \
+                                       ORION_PCIE_REG(0x1880))
+#define PCIE_WIN_BASE(n)       (((n) < 5) ? \
+                                       ORION_PCIE_REG(0x1824 + ((n) << 4)) : \
+                                       ORION_PCIE_REG(0x1884))
+#define PCIE_WIN_REMAP(n)      (((n) < 5) ? \
+                                       ORION_PCIE_REG(0x182c + ((n) << 4)) : \
+                                       ORION_PCIE_REG(0x188c))
+#define PCIE_MAX_BARS          3
+#define PCIE_MAX_WINS          6
+
+/*
+ * Use PCIE BAR '1' for all DDR banks
+ */
+#define PCIE_DRAM_BAR          1
+
 /*
  * PCIE config cycles are done by programming the PCIE_CONF_ADDR register
  * and then reading the PCIE_CONF_DATA register. Need to make sure these
@@ -95,6 +119,56 @@ static void orion_pcie_set_bus_nr(int nr)
        orion_setbits(PCIE_STAT, nr << PCIE_STAT_BUS_OFFS);
 }
 
+/*
+ * Setup PCIE BARs and Address Decode Wins:
+ * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
+ * WIN[0-3] -> DRAM bank[0-3]
+ */
+static void orion_setup_pcie_wins(struct mbus_dram_target_info *dram)
+{
+       u32 size;
+       int i;
+
+       /*
+        * First, disable and clear BARs and windows
+        */
+       for (i = 1; i < PCIE_MAX_BARS; i++) {
+               writel(0, PCIE_BAR_CTRL(i));
+               writel(0, PCIE_BAR_LO(i));
+               writel(0, PCIE_BAR_HI(i));
+       }
+
+       for (i = 0; i < PCIE_MAX_WINS; i++) {
+               writel(0, PCIE_WIN_CTRL(i));
+               writel(0, PCIE_WIN_BASE(i));
+               writel(0, PCIE_WIN_REMAP(i));
+       }
+
+       /*
+        * Setup windows for DDR banks. Count total DDR size on the fly.
+        */
+       size = 0;
+       for (i = 0; i < dram->num_cs; i++) {
+               struct mbus_dram_window *cs = dram->cs + i;
+
+               writel(cs->base & 0xffff0000, PCIE_WIN_BASE(i));
+               writel(0, PCIE_WIN_REMAP(i));
+               writel(((cs->size - 1) & 0xffff0000) |
+                       (cs->mbus_attr << 8) |
+                       (dram->mbus_dram_target_id << 4) |
+                       (PCIE_DRAM_BAR << 1) | 1, PCIE_WIN_CTRL(i));
+
+               size += cs->size;
+       }
+
+       /*
+        * Setup BAR[1] to all DRAM banks
+        */
+       writel(dram->cs[0].base, PCIE_BAR_LO(PCIE_DRAM_BAR));
+       writel(0, PCIE_BAR_HI(PCIE_DRAM_BAR));
+       writel(((size - 1) & 0xffff0000) | 1, PCIE_BAR_CTRL(PCIE_DRAM_BAR));
+}
+
 static void orion_pcie_master_slave_enable(void)
 {
        orion_setbits(PCIE_CMD_STAT, PCI_COMMAND_MASTER |
@@ -219,6 +293,11 @@ static int orion_pcie_setup(struct pci_sys_data *sys)
 {
        struct resource *res;
 
+       /*
+        * Point PCIe unit MBUS decode windows to DRAM space.
+        */
+       orion_setup_pcie_wins(&orion_mbus_dram_info);
+
        /*
         * Master + Slave enable
         */
@@ -310,6 +389,27 @@ static int orion_pcie_setup(struct pci_sys_data *sys)
 #define PCIX_STAT_BUS_OFFS             8
 #define PCIX_STAT_BUS_MASK             (0xff << PCIX_STAT_BUS_OFFS)
 
+/*
+ * PCI Address Decode Windows registers
+ */
+#define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION_PCI_REG(0xc08) : \
+                               ((n) == 1) ? ORION_PCI_REG(0xd08) :  \
+                               ((n) == 2) ? ORION_PCI_REG(0xc0c) :  \
+                               ((n) == 3) ? ORION_PCI_REG(0xd0c) : 0)
+#define PCI_BAR_REMAP_DDR_CS(n)        (((n) ==0) ? ORION_PCI_REG(0xc48) :  \
+                               ((n) == 1) ? ORION_PCI_REG(0xd48) :  \
+                               ((n) == 2) ? ORION_PCI_REG(0xc4c) :  \
+                               ((n) == 3) ? ORION_PCI_REG(0xd4c) : 0)
+#define PCI_BAR_ENABLE         ORION_PCI_REG(0xc3c)
+#define PCI_ADDR_DECODE_CTRL   ORION_PCI_REG(0xd3c)
+
+/*
+ * PCI configuration helpers for BAR settings
+ */
+#define PCI_CONF_FUNC_BAR_CS(n)                ((n) >> 1)
+#define PCI_CONF_REG_BAR_LO_CS(n)      (((n) & 1) ? 0x18 : 0x10)
+#define PCI_CONF_REG_BAR_HI_CS(n)      (((n) & 1) ? 0x1c : 0x14)
+
 /*
  * PCI config cycles are done by programming the PCI_CONF_ADDR register
  * and then reading the PCI_CONF_DATA register. Need to make sure these
@@ -323,13 +423,13 @@ u32 orion_pci_local_bus_nr(void)
        return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS);
 }
 
-u32 orion_pci_local_dev_nr(void)
+static u32 orion_pci_local_dev_nr(void)
 {
        u32 conf = orion_read(PCI_P2P_CONF);
        return((conf & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS);
 }
 
-int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func,
+static int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func,
                                        u32 where, u32 size, u32 *val)
 {
        unsigned long flags;
@@ -351,7 +451,7 @@ int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func,
        return PCIBIOS_SUCCESSFUL;
 }
 
-int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func,
+static int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func,
                                        u32 where, u32 size, u32 val)
 {
        unsigned long flags;
@@ -451,10 +551,75 @@ static void orion_pci_master_slave_enable(void)
        orion_pci_hw_wr_conf(bus_nr, dev_nr, func, reg, 4, val | 0x7);
 }
 
+static void orion_setup_pci_wins(struct mbus_dram_target_info *dram)
+{
+       u32 win_enable;
+       u32 bus;
+       u32 dev;
+       int i;
+
+       /*
+        * First, disable windows.
+        */
+       win_enable = 0xffffffff;
+       orion_write(PCI_BAR_ENABLE, win_enable);
+
+       /*
+        * Setup windows for DDR banks.
+        */
+       bus = orion_pci_local_bus_nr();
+       dev = orion_pci_local_dev_nr();
+
+       for (i = 0; i < dram->num_cs; i++) {
+               struct mbus_dram_window *cs = dram->cs + i;
+               u32 func = PCI_CONF_FUNC_BAR_CS(cs->cs_index);
+               u32 reg;
+               u32 val;
+
+               /*
+                * Write DRAM bank base address register.
+                */
+               reg = PCI_CONF_REG_BAR_LO_CS(cs->cs_index);
+               orion_pci_hw_rd_conf(bus, dev, func, reg, 4, &val);
+               val = (cs->base & 0xfffff000) | (val & 0xfff);
+               orion_pci_hw_wr_conf(bus, dev, func, reg, 4, val);
+
+               /*
+                * Write DRAM bank size register.
+                */
+               reg = PCI_CONF_REG_BAR_HI_CS(cs->cs_index);
+               orion_pci_hw_wr_conf(bus, dev, func, reg, 4, 0);
+               orion_write(PCI_BAR_SIZE_DDR_CS(cs->cs_index),
+                               (cs->size - 1) & 0xfffff000);
+               orion_write(PCI_BAR_REMAP_DDR_CS(cs->cs_index),
+                               cs->base & 0xfffff000);
+
+               /*
+                * Enable decode window for this chip select.
+                */
+               win_enable &= ~(1 << cs->cs_index);
+       }
+
+       /*
+        * Re-enable decode windows.
+        */
+       orion_write(PCI_BAR_ENABLE, win_enable);
+
+       /*
+        * Disable automatic update of address remaping when writing to BARs.
+        */
+       orion_setbits(PCI_ADDR_DECODE_CTRL, 1);
+}
+
 static int orion_pci_setup(struct pci_sys_data *sys)
 {
        struct resource *res;
 
+       /*
+        * Point PCI unit MBUS decode windows to DRAM space.
+        */
+       orion_setup_pci_wins(&orion_mbus_dram_info);
+
        /*
         * Master + Slave enable
         */