pci: layerscape: add LS2088A series SoC pcie support
authorHou Zhiqiang <Zhiqiang.Hou@nxp.com>
Fri, 3 Mar 2017 04:35:09 +0000 (12:35 +0800)
committerYork Sun <york.sun@nxp.com>
Tue, 28 Mar 2017 16:21:13 +0000 (09:21 -0700)
The LS2088A series SoCs has different physical memory map address and
CCSR registers address against LS2080A series SoCs.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: York Sun <york.sun@nxp.com>
arch/arm/cpu/armv8/fsl-layerscape/cpu.c
drivers/pci/pcie_layerscape.c
drivers/pci/pcie_layerscape.h

index 78e250c..cebbb0f 100644 (file)
@@ -89,6 +89,49 @@ static inline void early_mmu_setup(void)
        set_sctlr(get_sctlr() | CR_M);
 }
 
+static void fix_pcie_mmu_map(void)
+{
+#ifdef CONFIG_LS2080A
+       unsigned int i;
+       u32 svr, ver;
+       struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+
+       svr = gur_in32(&gur->svr);
+       ver = SVR_SOC_VER(svr);
+
+       /* Fix PCIE base and size for LS2088A */
+       if ((ver == SVR_LS2088A) || (ver == SVR_LS2084A) ||
+           (ver == SVR_LS2048A) || (ver == SVR_LS2044A)) {
+               for (i = 0; i < ARRAY_SIZE(final_map); i++) {
+                       switch (final_map[i].phys) {
+                       case CONFIG_SYS_PCIE1_PHYS_ADDR:
+                               final_map[i].phys = 0x2000000000ULL;
+                               final_map[i].virt = 0x2000000000ULL;
+                               final_map[i].size = 0x800000000ULL;
+                               break;
+                       case CONFIG_SYS_PCIE2_PHYS_ADDR:
+                               final_map[i].phys = 0x2800000000ULL;
+                               final_map[i].virt = 0x2800000000ULL;
+                               final_map[i].size = 0x800000000ULL;
+                               break;
+                       case CONFIG_SYS_PCIE3_PHYS_ADDR:
+                               final_map[i].phys = 0x3000000000ULL;
+                               final_map[i].virt = 0x3000000000ULL;
+                               final_map[i].size = 0x800000000ULL;
+                               break;
+                       case CONFIG_SYS_PCIE4_PHYS_ADDR:
+                               final_map[i].phys = 0x3800000000ULL;
+                               final_map[i].virt = 0x3800000000ULL;
+                               final_map[i].size = 0x800000000ULL;
+                               break;
+                       default:
+                               break;
+                       }
+               }
+       }
+#endif
+}
+
 /*
  * The final tables look similar to early tables, but different in detail.
  * These tables are in DRAM. Sub tables are added to enable cache for
@@ -103,6 +146,9 @@ static inline void final_mmu_setup(void)
        unsigned int el = current_el();
        int index;
 
+       /* fix the final_map before filling in the block entries */
+       fix_pcie_mmu_map();
+
        mem_map = final_map;
 
        /* Update mapping for DDR to actual size */
index 47dd806..1c5a33a 100644 (file)
@@ -167,6 +167,27 @@ static void ls_pcie_setup_atu(struct ls_pcie *pcie)
        pci_get_regions(pcie->bus, &io, &mem, &pref);
        idx = PCIE_ATU_REGION_INDEX1 + 1;
 
+       /* Fix the pcie memory map for LS2088A series SoCs */
+       svr = (svr >> SVR_VAR_PER_SHIFT) & 0xFFFFFE;
+       if (svr == SVR_LS2088A || svr == SVR_LS2084A ||
+           svr == SVR_LS2048A || svr == SVR_LS2044A) {
+               if (io)
+                       io->phys_start = (io->phys_start &
+                                        (PCIE_PHYS_SIZE - 1)) +
+                                        LS2088A_PCIE1_PHYS_ADDR +
+                                        LS2088A_PCIE_PHYS_SIZE * pcie->idx;
+               if (mem)
+                       mem->phys_start = (mem->phys_start &
+                                        (PCIE_PHYS_SIZE - 1)) +
+                                        LS2088A_PCIE1_PHYS_ADDR +
+                                        LS2088A_PCIE_PHYS_SIZE * pcie->idx;
+               if (pref)
+                       pref->phys_start = (pref->phys_start &
+                                        (PCIE_PHYS_SIZE - 1)) +
+                                        LS2088A_PCIE1_PHYS_ADDR +
+                                        LS2088A_PCIE_PHYS_SIZE * pcie->idx;
+       }
+
        if (io)
                /* ATU : OUTBOUND : IO */
                ls_pcie_atu_outbound_set(pcie, idx++,
@@ -449,6 +470,7 @@ static int ls_pcie_probe(struct udevice *dev)
        u8 header_type;
        u16 link_sta;
        bool ep_mode;
+       uint svr;
        int ret;
 
        pcie->bus = dev;
@@ -502,6 +524,19 @@ static int ls_pcie_probe(struct udevice *dev)
                return ret;
        }
 
+       /*
+        * Fix the pcie memory map address and PF control registers address
+        * for LS2088A series SoCs
+        */
+       svr = get_svr();
+       svr = (svr >> SVR_VAR_PER_SHIFT) & 0xFFFFFE;
+       if (svr == SVR_LS2088A || svr == SVR_LS2084A ||
+           svr == SVR_LS2048A || svr == SVR_LS2044A) {
+               pcie->cfg_res.start = LS2088A_PCIE1_PHYS_ADDR +
+                                       LS2088A_PCIE_PHYS_SIZE * pcie->idx;
+               pcie->ctrl = pcie->lut + 0x40000;
+       }
+
        pcie->cfg0 = map_physmem(pcie->cfg_res.start,
                                 fdt_resource_size(&pcie->cfg_res),
                                 MAP_NOCACHE);
index 0f9d2fe..e3324a5 100644 (file)
 #define CONFIG_SYS_PCI_EP_MEMORY_BASE CONFIG_SYS_LOAD_ADDR
 #endif
 
+#define PCIE_PHYS_SIZE                 0x200000000
+#define LS2088A_PCIE_PHYS_SIZE         0x800000000
+#define LS2088A_PCIE1_PHYS_ADDR                0x2000000000
+
 /* iATU registers */
 #define PCIE_ATU_VIEWPORT              0x900
 #define PCIE_ATU_REGION_INBOUND                (0x1 << 31)
 #define SVR_LS102XA            0
 #define SVR_VAR_PER_SHIFT      8
 #define SVR_LS102XA_MASK       0x700
+#define SVR_LS2088A            0x870900
+#define SVR_LS2084A            0x870910
+#define SVR_LS2048A            0x870920
+#define SVR_LS2044A            0x870930
 
 /* LS1021a PCIE space */
 #define LS1021_PCIE_SPACE_OFFSET       0x4000000000ULL