Discussion:
[U-Boot] [PATCHv3 1/2] pci: layerscape: add LS2088A series SoC pcie support
Zhiqiang Hou
2017-03-03 04:35:09 UTC
Permalink
From: Hou Zhiqiang <***@nxp.com>

The LS2088A series SoCs has different physical memory map address and
CCSR registers address against LS2080A series SoCs.

Signed-off-by: Hou Zhiqiang <***@nxp.com>
---
V3:
- no change

arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 46 +++++++++++++++++++++++++++++++++
drivers/pci/pcie_layerscape.c | 35 +++++++++++++++++++++++++
drivers/pci/pcie_layerscape.h | 8 ++++++
3 files changed, 89 insertions(+)

diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
index 335f225..6afb40f 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
@@ -89,6 +89,49 @@ static inline void early_mmu_setup(void)
set_sctlr(get_sctlr() | CR_M);
}

+static void fix_final_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
@@ -105,6 +148,9 @@ static inline void final_mmu_setup(void)
int index;
#endif

+ /* fix the final_map before filling in the block entries */
+ fix_final_mmu_map();
+
mem_map = final_map;

#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
index 90b9fe2..9a49898 100644
--- a/drivers/pci/pcie_layerscape.c
+++ b/drivers/pci/pcie_layerscape.c
@@ -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++,
@@ -442,6 +463,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;
@@ -495,6 +517,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);
diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h
index 1e635ef..029695d 100644
--- a/drivers/pci/pcie_layerscape.h
+++ b/drivers/pci/pcie_layerscape.h
@@ -26,6 +26,10 @@
#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)
@@ -107,6 +111,10 @@
#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
--
2.1.0.27.g96db324
Zhiqiang Hou
2017-03-03 04:35:10 UTC
Permalink
From: Hou Zhiqiang <***@nxp.com>

There isn't LS2088A DT file, actually it reuse LS2080A DT file
under u-boot, while under kernel there are DT files for LS2080A
and LS2088A respectively with different PCIe node compatible
string.

Signed-off-by: Hou Zhiqiang <***@nxp.com>
---
V3:
- removed unused variable.

drivers/pci/pcie_layerscape_fixup.c | 35 ++++++++++++++++++++++++-----------
1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/pcie_layerscape_fixup.c b/drivers/pci/pcie_layerscape_fixup.c
index 19ede2f..64e461e 100644
--- a/drivers/pci/pcie_layerscape_fixup.c
+++ b/drivers/pci/pcie_layerscape_fixup.c
@@ -72,19 +72,26 @@ static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie *pcie,
u32 *prop;
u32 phandle;
int nodeoffset;
+ uint svr;
+ char *compat = NULL;

/* find pci controller node */
nodeoffset = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie",
pcie->dbi_res.start);
if (nodeoffset < 0) {
#ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts node */
- nodeoffset = fdt_node_offset_by_compat_reg(blob,
- CONFIG_FSL_PCIE_COMPAT, pcie->dbi_res.start);
+ svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE;
+ if (svr == SVR_LS2088A || svr == SVR_LS2084A ||
+ svr == SVR_LS2048A || svr == SVR_LS2044A)
+ compat = "fsl,ls2088a-pcie";
+ else
+ compat = CONFIG_FSL_PCIE_COMPAT;
+ if (compat)
+ nodeoffset = fdt_node_offset_by_compat_reg(blob,
+ compat, pcie->dbi_res.start);
+#endif
if (nodeoffset < 0)
return;
-#else
- return;
-#endif
}

/* get phandle to MSI controller */
@@ -146,19 +153,25 @@ static void fdt_fixup_pcie(void *blob)
static void ft_pcie_ls_setup(void *blob, struct ls_pcie *pcie)
{
int off;
+ uint svr;
+ char *compat = NULL;

off = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie",
pcie->dbi_res.start);
if (off < 0) {
#ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts node */
- off = fdt_node_offset_by_compat_reg(blob,
- CONFIG_FSL_PCIE_COMPAT,
- pcie->dbi_res.start);
+ svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE;
+ if (svr == SVR_LS2088A || svr == SVR_LS2084A ||
+ svr == SVR_LS2048A || svr == SVR_LS2044A)
+ compat = "fsl,ls2088a-pcie";
+ else
+ compat = CONFIG_FSL_PCIE_COMPAT;
+ if (compat)
+ off = fdt_node_offset_by_compat_reg(blob,
+ compat, pcie->dbi_res.start);
+#endif
if (off < 0)
return;
-#else
- return;
-#endif
}

if (pcie->enabled)
--
2.1.0.27.g96db324
york sun
2017-03-28 17:59:19 UTC
Permalink
Post by Zhiqiang Hou
There isn't LS2088A DT file, actually it reuse LS2080A DT file
under u-boot, while under kernel there are DT files for LS2080A
and LS2088A respectively with different PCIe node compatible
string.
---
- removed unused variable.
Reformat commit message. Applied to fsl-qoriq master, awaiting upstream.
Thanks.

York
york sun
2017-03-28 17:59:16 UTC
Permalink
Post by Zhiqiang Hou
The LS2088A series SoCs has different physical memory map address and
CCSR registers address against LS2080A series SoCs.
---
- no change
Applied to fsl-qoriq master, awaiting upstream. Thanks.

York

Loading...