
Add the INBOUND configuration for PF1 and VFs of PF1 and PF0, Modify the outbound configuration for PF0 and PF1.
Signed-off-by: Xiaowei Bao xiaowei.bao@nxp.com --- drivers/pci/pcie_layerscape.c | 95 +++++++++++++++++++++++++++---------------- drivers/pci/pcie_layerscape.h | 9 ++-- 2 files changed, 65 insertions(+), 39 deletions(-)
diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index 845efda..e17a23c 100644 --- a/drivers/pci/pcie_layerscape.c +++ b/drivers/pci/pcie_layerscape.c @@ -93,7 +93,7 @@ static void ls_pcie_cfg1_set_busdev(struct ls_pcie *pcie, u32 busdev) }
static void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type, - u64 phys, u64 bus_addr, pci_size_t size) + u64 phys, u64 bus_addr, u64 size) { dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | idx, PCIE_ATU_VIEWPORT); dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_BASE); @@ -106,30 +106,27 @@ static void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type, }
/* Use bar match mode and MEM type as default */ -static void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, - int bar, u64 phys, u32 pf) +static void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag, + int idx, int bar, u64 phys) { - u32 cr1 = 0; - - if (pf) - cr1 |= PCIE_CTRL1_FUNC_NUM; - dbi_writel(pcie, PCIE_ATU_REGION_INBOUND | idx, PCIE_ATU_VIEWPORT); dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_TARGET); dbi_writel(pcie, phys >> 32, PCIE_ATU_UPPER_TARGET); - dbi_writel(pcie, PCIE_ATU_TYPE_MEM | cr1, PCIE_ATU_CR1); + dbi_writel(pcie, PCIE_ATU_TYPE_MEM | PCIE_ATU_FUNC_NUM(pf), + PCIE_ATU_CR1); dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE | + (pcie->sriov_flag ? PCIE_ATU_FUNC_NUM_MATCH_EN : 0) | + (vf_flag ? PCIE_ATU_VFBAR_MATCH_MODE_EN : 0) | PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2); }
-static void ls_pcie_dump_atu(struct ls_pcie *pcie) +static void ls_pcie_dump_atu(struct ls_pcie *pcie, u32 win_num, u32 type) { - int i; + int win_idx;
- for (i = 0; i < PCIE_ATU_REGION_NUM; i++) { - dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | i, - PCIE_ATU_VIEWPORT); - debug("iATU%d:\n", i); + for (win_idx = 0; win_idx < win_num; win_idx++) { + dbi_writel(pcie, type | win_idx, PCIE_ATU_VIEWPORT); + debug("iATU%d:\n", win_idx); debug("\tLOWER PHYS 0x%08x\n", dbi_readl(pcie, PCIE_ATU_LOWER_BASE)); debug("\tUPPER PHYS 0x%08x\n", @@ -225,7 +222,7 @@ static void ls_pcie_setup_atu(struct ls_pcie *pcie) pref->bus_start, pref->size);
- ls_pcie_dump_atu(pcie); + ls_pcie_dump_atu(pcie, PCIE_ATU_REGION_NUM, PCIE_ATU_REGION_OUTBOUND); }
/* Return 0 if the address is valid, -errno if not valid */ @@ -352,33 +349,52 @@ static void ls_pcie_setup_ctrl(struct ls_pcie *pcie)
static void ls_pcie_ep_setup_atu(struct ls_pcie *pcie, u32 pf) { - pci_size_t atu_size = CONFIG_SYS_PCI_MEMORY_SIZE; u64 phys = 0; + u32 vf_flag = 0;
- phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + pf * SZ_2M; + phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + pf * SZ_64M;
- phys = ALIGN(phys, PCIE_BAR0_SIZE); /* ATU 0 : INBOUND : map BAR0 */ - ls_pcie_atu_inbound_set(pcie, 0 + pf * BAR_NUM, 0, phys, pf); + phys = ALIGN(phys, PCIE_BAR0_SIZE); + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, 0 + pf * BAR_NUM, 0, phys); /* ATU 1 : INBOUND : map BAR1 */ phys = ALIGN(phys + PCIE_BAR0_SIZE, PCIE_BAR1_SIZE); - ls_pcie_atu_inbound_set(pcie, 1 + pf * BAR_NUM, 1, phys, pf); + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, 1 + pf * BAR_NUM, 1, phys); /* ATU 2 : INBOUND : map BAR2 */ phys = ALIGN(phys + PCIE_BAR1_SIZE, PCIE_BAR2_SIZE); - ls_pcie_atu_inbound_set(pcie, 2 + pf * BAR_NUM, 2, phys, pf); - /* ATU 3 : INBOUND : map BAR2 */ - phys = ALIGN(phys + PCIE_BAR2_SIZE, PCIE_BAR2_SIZE); - ls_pcie_atu_inbound_set(pcie, 3 + pf * BAR_NUM, 4, phys, pf); - - /* ATU 0 : OUTBOUND : map MEM */ - ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0, - PCIE_ATU_TYPE_MEM, (u64)pcie->cfg_res.start, - 0, atu_size); + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, 2 + pf * BAR_NUM, 2, phys); + /* ATU 3 : INBOUND : map BAR4 */ + phys = ALIGN(phys + PCIE_BAR2_SIZE, PCIE_BAR4_SIZE); + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, 3 + pf * BAR_NUM, 4, phys); + + if (pcie->sriov_flag) { + vf_flag = 1; + /* ATU 4 : INBOUND : map BAR0 */ + phys = ALIGN(phys + PCIE_BAR4_SIZE, PCIE_BAR0_SIZE); + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, + 4 + pf * BAR_NUM, 0, phys); + /* ATU 5 : INBOUND : map BAR1 */ + phys = ALIGN(phys + PCIE_BAR0_SIZE * PCIE_VF_NUM, + PCIE_BAR1_SIZE); + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, + 5 + pf * BAR_NUM, 1, phys); + /* ATU 6 : INBOUND : map BAR2 */ + phys = ALIGN(phys + PCIE_BAR1_SIZE * PCIE_VF_NUM, + PCIE_BAR2_SIZE); + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, + 6 + pf * BAR_NUM, 2, phys); + /* ATU 7 : INBOUND : map BAR4 */ + phys = ALIGN(phys + PCIE_BAR2_SIZE * PCIE_VF_NUM, + PCIE_BAR4_SIZE); + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, + 7 + pf * BAR_NUM, 4, phys); + }
- /* ATU 1 : OUTBOUND : map MEM */ - ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1, - PCIE_ATU_TYPE_MEM, (u64)pcie->cfg_res.start - + atu_size, atu_size, atu_size); + /* ATU: OUTBOUND : map MEM */ + ls_pcie_atu_outbound_set(pcie, pf, PCIE_ATU_TYPE_MEM, + (u64)pcie->cfg_res.start + + pf * CONFIG_SYS_PCI_MEMORY_SIZE, + 0, CONFIG_SYS_PCI_MEMORY_SIZE); }
/* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */ @@ -491,9 +507,13 @@ static void ls_pcie_setup_ep(struct ls_pcie *pcie)
if (pcie->cfg2_flag) /* Disable CFG2 */ ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL); + ls_pcie_dump_atu(pcie, PCIE_ATU_REGION_NUM_SRIOV, + PCIE_ATU_REGION_INBOUND); } else { ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE); ls_pcie_ep_setup_atu(pcie, 0); + ls_pcie_dump_atu(pcie, PCIE_ATU_REGION_NUM, + PCIE_ATU_REGION_INBOUND); }
ls_pcie_ep_enable_cfg(pcie); @@ -566,7 +586,6 @@ static int ls_pcie_probe(struct udevice *dev) * Fix the pcie memory map address and PF control registers address * for LS2088A series SoCs */ - pcie->cfg2_flag = 1; if (svr == SVR_LS2088A || svr == SVR_LS2084A || svr == SVR_LS2048A || svr == SVR_LS2044A || svr == SVR_LS2081A || svr == SVR_LS2041A) { @@ -575,8 +594,12 @@ static int ls_pcie_probe(struct udevice *dev) LS2088A_PCIE_PHYS_SIZE * pcie->idx; pcie->cfg_res.end = pcie->cfg_res.start + cfg_size; pcie->ctrl = pcie->lut + 0x40000; - pcie->cfg2_flag = 0; } + + if (svr == SVR_LS2080A || svr == SVR_LS2085A) + pcie->cfg2_flag = 1; + else + pcie->cfg2_flag = 0; #endif /* CONFIG_FSL_LAYERSCAPE */
pcie->cfg0 = map_physmem(pcie->cfg_res.start, diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h index fe5b99d..0ba06e9 100644 --- a/drivers/pci/pcie_layerscape.h +++ b/drivers/pci/pcie_layerscape.h @@ -20,7 +20,7 @@ #endif
#ifndef CONFIG_SYS_PCI_MEMORY_SIZE -#define CONFIG_SYS_PCI_MEMORY_SIZE (2 * 1024 * 1024 * 1024UL) /* 2G */ +#define CONFIG_SYS_PCI_MEMORY_SIZE SZ_4G #endif
#ifndef CONFIG_SYS_PCI_EP_MEMORY_BASE @@ -40,14 +40,18 @@ #define PCIE_ATU_REGION_INDEX2 (0x2 << 0) #define PCIE_ATU_REGION_INDEX3 (0x3 << 0) #define PCIE_ATU_REGION_NUM 6 +#define PCIE_ATU_REGION_NUM_SRIOV 24 #define PCIE_ATU_CR1 0x904 #define PCIE_ATU_TYPE_MEM (0x0 << 0) #define PCIE_ATU_TYPE_IO (0x2 << 0) #define PCIE_ATU_TYPE_CFG0 (0x4 << 0) #define PCIE_ATU_TYPE_CFG1 (0x5 << 0) +#define PCIE_ATU_FUNC_NUM(pf) (pf << 20) #define PCIE_ATU_CR2 0x908 #define PCIE_ATU_ENABLE (0x1 << 31) #define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) +#define PCIE_ATU_FUNC_NUM_MATCH_EN (1 << 19) +#define PCIE_ATU_VFBAR_MATCH_MODE_EN (1 << 26) #define PCIE_ATU_BAR_NUM(bar) ((bar) << 8) #define PCIE_ATU_LOWER_BASE 0x90C #define PCIE_ATU_UPPER_BASE 0x910 @@ -86,7 +90,7 @@
#define PCIE_PF_NUM 2 #define PCIE_VF_NUM 64 -#define BAR_NUM 4 +#define BAR_NUM 8
#define PCIE_BAR0_SIZE SZ_4K /* 4K */ #define PCIE_BAR1_SIZE SZ_8K /* 8K for MSIX */ @@ -95,7 +99,6 @@
#define PCIE_SRIOV_VFBAR0 0x19C #define PCIE_MISC_CONTROL_1_OFF 0x8BC -#define PCIE_CTRL1_FUNC_NUM 0x00100000
#define PCIE_MASK_OFFSET(flag, pf) ((flag) ? 0 : (0x1000 + 0x20000 * (pf)))