MIPS: Octeon: Allow more than 3.75GB of memory with PCIe
[sfrench/cifs-2.6.git] / arch / mips / pci / pcie-octeon.c
index 75262247f3e482d445c677dcf6d4d2590b596727..861361e0c9afc668f5914f67ea8351134ab56ecc 100644 (file)
@@ -402,6 +402,10 @@ static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
        npei_ctl_status2.s.mps = 0;
        /* Max read request size = 128 bytes for best Octeon DMA performance */
        npei_ctl_status2.s.mrrs = 0;
+       if (pcie_port)
+               npei_ctl_status2.s.c1_b1_s = 3; /* Port1 BAR1 Size 256MB */
+       else
+               npei_ctl_status2.s.c0_b1_s = 3; /* Port0 BAR1 Size 256MB */
        cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS2, npei_ctl_status2.u64);
 
        /* ECRC Generation (PCIE*_CFG070[GE,CE]) */
@@ -666,6 +670,8 @@ static int __cvmx_pcie_rc_initialize_link(int pcie_port)
 static int cvmx_pcie_rc_initialize(int pcie_port)
 {
        int i;
+       int base;
+       u64 addr_swizzle;
        union cvmx_ciu_soft_prst ciu_soft_prst;
        union cvmx_pescx_bist_status pescx_bist_status;
        union cvmx_pescx_bist_status2 pescx_bist_status2;
@@ -674,6 +680,7 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
        union cvmx_npei_mem_access_subidx mem_access_subid;
        union cvmx_npei_dbg_data npei_dbg_data;
        union cvmx_pescx_ctl_status2 pescx_ctl_status2;
+       union cvmx_npei_bar1_indexx bar1_index;
 
        /*
         * Make sure we aren't trying to setup a target mode interface
@@ -918,12 +925,30 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
        /* Set Octeon's BAR0 to decode 0-16KB. It overlaps with Bar2 */
        cvmx_write_csr(CVMX_PESCX_P2N_BAR0_START(pcie_port), 0);
 
-       /*
-        * Disable Octeon's BAR1. It isn't needed in RC mode since
-        * BAR2 maps all of memory. BAR2 also maps 256MB-512MB into
-        * the 2nd 256MB of memory.
-        */
-       cvmx_write_csr(CVMX_PESCX_P2N_BAR1_START(pcie_port), -1);
+       /* BAR1 follows BAR2 with a gap. */
+       cvmx_write_csr(CVMX_PESCX_P2N_BAR1_START(pcie_port), CVMX_PCIE_BAR1_RC_BASE);
+
+       bar1_index.u32 = 0;
+       bar1_index.s.addr_idx = (CVMX_PCIE_BAR1_PHYS_BASE >> 22);
+       bar1_index.s.ca = 1;       /* Not Cached */
+       bar1_index.s.end_swp = 1;  /* Endian Swap mode */
+       bar1_index.s.addr_v = 1;   /* Valid entry */
+
+       base = pcie_port ? 16 : 0;
+
+       /* Big endian swizzle for 32-bit PEXP_NCB register. */
+#ifdef __MIPSEB__
+       addr_swizzle = 4;
+#else
+       addr_swizzle = 0;
+#endif
+       for (i = 0; i < 16; i++) {
+               cvmx_write64_uint32((CVMX_PEXP_NPEI_BAR1_INDEXX(base) ^ addr_swizzle),
+                                   bar1_index.u32);
+               base++;
+               /* 256MB / 16 >> 22 == 4 */
+               bar1_index.s.addr_idx += (((1ull << 28) / 16ull) >> 22);
+       }
 
        /*
         * Set Octeon's BAR2 to decode 0-2^39. Bar0 and Bar1 take
@@ -1040,19 +1065,29 @@ static inline int octeon_pcie_read_config(int pcie_port, struct pci_bus *bus,
        int bus_number = bus->number;
 
        /*
-        * We need to force the bus number to be zero on the root
-        * bus. Linux numbers the 2nd root bus to start after all
-        * buses on root 0.
+        * For the top level bus make sure our hardware bus number
+        * matches the software one.
         */
-       if (bus->parent == NULL)
-               bus_number = 0;
+       if (bus->parent == NULL) {
+               union cvmx_pciercx_cfg006 pciercx_cfg006;
+               pciercx_cfg006.u32 = cvmx_pcie_cfgx_read(pcie_port,
+                       CVMX_PCIERCX_CFG006(pcie_port));
+               if (pciercx_cfg006.s.pbnum != bus_number) {
+                       pciercx_cfg006.s.pbnum = bus_number;
+                       pciercx_cfg006.s.sbnum = bus_number;
+                       pciercx_cfg006.s.subbnum = bus_number;
+                       cvmx_pcie_cfgx_write(pcie_port,
+                               CVMX_PCIERCX_CFG006(pcie_port),
+                               pciercx_cfg006.u32);
+               }
+       }
 
        /*
         * PCIe only has a single device connected to Octeon. It is
         * always device ID 0. Don't bother doing reads for other
         * device IDs on the first segment.
         */
-       if ((bus_number == 0) && (devfn >> 3 != 0))
+       if ((bus->parent == NULL) && (devfn >> 3 != 0))
                return PCIBIOS_FUNC_NOT_SUPPORTED;
 
        /*
@@ -1070,7 +1105,7 @@ static inline int octeon_pcie_read_config(int pcie_port, struct pci_bus *bus,
                 * bridge only respondes to device ID 0, function
                 * 0-1
                 */
-               if ((bus_number == 0) && (devfn >= 2))
+               if ((bus->parent == NULL) && (devfn >= 2))
                        return PCIBIOS_FUNC_NOT_SUPPORTED;
                /*
                 * The PCI-X slots are device ID 2,3. Choose one of
@@ -1167,13 +1202,6 @@ static inline int octeon_pcie_write_config(int pcie_port, struct pci_bus *bus,
                                           int size, u32 val)
 {
        int bus_number = bus->number;
-       /*
-        * We need to force the bus number to be zero on the root
-        * bus. Linux numbers the 2nd root bus to start after all
-        * busses on root 0.
-        */
-       if (bus->parent == NULL)
-               bus_number = 0;
 
        switch (size) {
        case 4: