* [PATCH 1/9] pci: layerscape: Split the EP and RC driver
@ 2020-03-22 11:12 Xiaowei Bao
2020-03-22 11:12 ` [PATCH 2/9] pci_ep: Add the init function Xiaowei Bao
` (9 more replies)
0 siblings, 10 replies; 19+ messages in thread
From: Xiaowei Bao @ 2020-03-22 11:12 UTC (permalink / raw)
To: u-boot
Split the RC and EP driver, and reimplement the EP driver base on
the EP framework.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
drivers/pci/Makefile | 2 +-
drivers/pci/pcie_layerscape.c | 492 +++---------------------------------
drivers/pci/pcie_layerscape.h | 44 +++-
drivers/pci/pcie_layerscape_ep.c | 240 ++++++++++++++++++
drivers/pci/pcie_layerscape_fixup.c | 79 +++---
drivers/pci/pcie_layerscape_rc.c | 378 +++++++++++++++++++++++++++
6 files changed, 734 insertions(+), 501 deletions(-)
create mode 100644 drivers/pci/pcie_layerscape_ep.c
create mode 100644 drivers/pci/pcie_layerscape_rc.c
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index c051ecc..440b5af 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -33,7 +33,7 @@ obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o
obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o
obj-$(CONFIG_PCIE_FSL) += pcie_fsl.o pcie_fsl_fixup.o
-obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o
+obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o pcie_layerscape_rc.o pcie_layerscape_ep.o
obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o pcie_layerscape_fixup_common.o
obj-$(CONFIG_PCIE_LAYERSCAPE_GEN4) += pcie_layerscape_gen4.o \
pcie_layerscape_gen4_fixup.o \
diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
index 2ab67d1..3ca75c5 100644
--- a/drivers/pci/pcie_layerscape.c
+++ b/drivers/pci/pcie_layerscape.c
@@ -1,39 +1,32 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2017-2019 NXP
+ * Copyright 2017-2020 NXP
* Copyright 2014-2015 Freescale Semiconductor, Inc.
* Layerscape PCIe driver
*/
#include <common.h>
-#include <asm/arch/fsl_serdes.h>
-#include <pci.h>
#include <asm/io.h>
#include <errno.h>
#include <malloc.h>
-#include <dm.h>
-#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
- defined(CONFIG_ARM)
-#include <asm/arch/clock.h>
-#endif
#include "pcie_layerscape.h"
DECLARE_GLOBAL_DATA_PTR;
LIST_HEAD(ls_pcie_list);
-static unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset)
+unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset)
{
return in_le32(pcie->dbi + offset);
}
-static void dbi_writel(struct ls_pcie *pcie, unsigned int value,
- unsigned int offset)
+void dbi_writel(struct ls_pcie *pcie, unsigned int value,
+ unsigned int offset)
{
out_le32(pcie->dbi + offset, value);
}
-static unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset)
+unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset)
{
if (pcie->big_endian)
return in_be32(pcie->ctrl + offset);
@@ -41,8 +34,8 @@ static unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset)
return in_le32(pcie->ctrl + offset);
}
-static void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
- unsigned int offset)
+void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
+ unsigned int offset)
{
if (pcie->big_endian)
out_be32(pcie->ctrl + offset, value);
@@ -50,6 +43,26 @@ static void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
out_le32(pcie->ctrl + offset, value);
}
+void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie)
+{
+ u32 reg, val;
+
+ reg = PCIE_MISC_CONTROL_1_OFF;
+ val = dbi_readl(pcie, reg);
+ val |= PCIE_DBI_RO_WR_EN;
+ dbi_writel(pcie, val, reg);
+}
+
+void ls_pcie_dbi_ro_wr_dis(struct ls_pcie *pcie)
+{
+ u32 reg, val;
+
+ reg = PCIE_MISC_CONTROL_1_OFF;
+ val = dbi_readl(pcie, reg);
+ val &= ~PCIE_DBI_RO_WR_EN;
+ dbi_writel(pcie, val, reg);
+}
+
static int ls_pcie_ltssm(struct ls_pcie *pcie)
{
u32 state;
@@ -66,7 +79,7 @@ static int ls_pcie_ltssm(struct ls_pcie *pcie)
return state;
}
-static int ls_pcie_link_up(struct ls_pcie *pcie)
+int ls_pcie_link_up(struct ls_pcie *pcie)
{
int ltssm;
@@ -77,22 +90,8 @@ static int ls_pcie_link_up(struct ls_pcie *pcie)
return 1;
}
-static void ls_pcie_cfg0_set_busdev(struct ls_pcie *pcie, u32 busdev)
-{
- dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
- PCIE_ATU_VIEWPORT);
- dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET);
-}
-
-static void ls_pcie_cfg1_set_busdev(struct ls_pcie *pcie, u32 busdev)
-{
- dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
- PCIE_ATU_VIEWPORT);
- dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET);
-}
-
-static void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
- u64 phys, u64 bus_addr, pci_size_t size)
+void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
+ u64 phys, u64 bus_addr, pci_size_t size)
{
dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | idx, PCIE_ATU_VIEWPORT);
dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_BASE);
@@ -105,18 +104,18 @@ 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)
+void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, int type,
+ int bar, u64 phys)
{
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, PCIE_ATU_CR1);
+ dbi_writel(pcie, type, PCIE_ATU_CR1);
dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2);
}
-static void ls_pcie_dump_atu(struct ls_pcie *pcie)
+void ls_pcie_dump_atu(struct ls_pcie *pcie)
{
int i;
@@ -133,431 +132,10 @@ static void ls_pcie_dump_atu(struct ls_pcie *pcie)
debug("\tUPPER BUS 0x%08x\n",
dbi_readl(pcie, PCIE_ATU_UPPER_TARGET));
debug("\tLIMIT 0x%08x\n",
- readl(pcie->dbi + PCIE_ATU_LIMIT));
+ dbi_readl(pcie, PCIE_ATU_LIMIT));
debug("\tCR1 0x%08x\n",
dbi_readl(pcie, PCIE_ATU_CR1));
debug("\tCR2 0x%08x\n",
dbi_readl(pcie, PCIE_ATU_CR2));
}
}
-
-static void ls_pcie_setup_atu(struct ls_pcie *pcie)
-{
- struct pci_region *io, *mem, *pref;
- unsigned long long offset = 0;
- int idx = 0;
- uint svr;
-
- svr = get_svr();
- if (((svr >> SVR_VAR_PER_SHIFT) & SVR_LS102XA_MASK) == SVR_LS102XA) {
- offset = LS1021_PCIE_SPACE_OFFSET +
- LS1021_PCIE_SPACE_SIZE * pcie->idx;
- }
-
- /* ATU 0 : OUTBOUND : CFG0 */
- ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
- PCIE_ATU_TYPE_CFG0,
- pcie->cfg_res.start + offset,
- 0,
- fdt_resource_size(&pcie->cfg_res) / 2);
- /* ATU 1 : OUTBOUND : CFG1 */
- ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1,
- PCIE_ATU_TYPE_CFG1,
- pcie->cfg_res.start + offset +
- fdt_resource_size(&pcie->cfg_res) / 2,
- 0,
- fdt_resource_size(&pcie->cfg_res) / 2);
-
- 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 ||
- svr == SVR_LS2081A || svr == SVR_LS2041A) {
- 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++,
- PCIE_ATU_TYPE_IO,
- io->phys_start + offset,
- io->bus_start,
- io->size);
-
- if (mem)
- /* ATU : OUTBOUND : MEM */
- ls_pcie_atu_outbound_set(pcie, idx++,
- PCIE_ATU_TYPE_MEM,
- mem->phys_start + offset,
- mem->bus_start,
- mem->size);
-
- if (pref)
- /* ATU : OUTBOUND : pref */
- ls_pcie_atu_outbound_set(pcie, idx++,
- PCIE_ATU_TYPE_MEM,
- pref->phys_start + offset,
- pref->bus_start,
- pref->size);
-
- ls_pcie_dump_atu(pcie);
-}
-
-/* Return 0 if the address is valid, -errno if not valid */
-static int ls_pcie_addr_valid(struct ls_pcie *pcie, pci_dev_t bdf)
-{
- struct udevice *bus = pcie->bus;
-
- if (pcie->mode == PCI_HEADER_TYPE_NORMAL)
- return -ENODEV;
-
- if (!pcie->enabled)
- return -ENXIO;
-
- if (PCI_BUS(bdf) < bus->seq)
- return -EINVAL;
-
- if ((PCI_BUS(bdf) > bus->seq) && (!ls_pcie_link_up(pcie)))
- return -EINVAL;
-
- if (PCI_BUS(bdf) <= (bus->seq + 1) && (PCI_DEV(bdf) > 0))
- return -EINVAL;
-
- return 0;
-}
-
-int ls_pcie_conf_address(struct udevice *bus, pci_dev_t bdf,
- uint offset, void **paddress)
-{
- struct ls_pcie *pcie = dev_get_priv(bus);
- u32 busdev;
-
- if (ls_pcie_addr_valid(pcie, bdf))
- return -EINVAL;
-
- if (PCI_BUS(bdf) == bus->seq) {
- *paddress = pcie->dbi + offset;
- return 0;
- }
-
- busdev = PCIE_ATU_BUS(PCI_BUS(bdf) - bus->seq) |
- PCIE_ATU_DEV(PCI_DEV(bdf)) |
- PCIE_ATU_FUNC(PCI_FUNC(bdf));
-
- if (PCI_BUS(bdf) == bus->seq + 1) {
- ls_pcie_cfg0_set_busdev(pcie, busdev);
- *paddress = pcie->cfg0 + offset;
- } else {
- ls_pcie_cfg1_set_busdev(pcie, busdev);
- *paddress = pcie->cfg1 + offset;
- }
- return 0;
-}
-
-static int ls_pcie_read_config(struct udevice *bus, pci_dev_t bdf,
- uint offset, ulong *valuep,
- enum pci_size_t size)
-{
- return pci_generic_mmap_read_config(bus, ls_pcie_conf_address,
- bdf, offset, valuep, size);
-}
-
-static int ls_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
- uint offset, ulong value,
- enum pci_size_t size)
-{
- return pci_generic_mmap_write_config(bus, ls_pcie_conf_address,
- bdf, offset, value, size);
-}
-
-/* Clear multi-function bit */
-static void ls_pcie_clear_multifunction(struct ls_pcie *pcie)
-{
- writeb(PCI_HEADER_TYPE_BRIDGE, pcie->dbi + PCI_HEADER_TYPE);
-}
-
-/* Fix class value */
-static void ls_pcie_fix_class(struct ls_pcie *pcie)
-{
- writew(PCI_CLASS_BRIDGE_PCI, pcie->dbi + PCI_CLASS_DEVICE);
-}
-
-/* Drop MSG TLP except for Vendor MSG */
-static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie)
-{
- u32 val;
-
- val = dbi_readl(pcie, PCIE_STRFMR1);
- val &= 0xDFFFFFFF;
- dbi_writel(pcie, val, PCIE_STRFMR1);
-}
-
-/* Disable all bars in RC mode */
-static void ls_pcie_disable_bars(struct ls_pcie *pcie)
-{
- dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_0);
- dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_1);
- dbi_writel(pcie, 0xfffffffe, PCIE_CS2_OFFSET + PCI_ROM_ADDRESS1);
-}
-
-static void ls_pcie_setup_ctrl(struct ls_pcie *pcie)
-{
- ls_pcie_setup_atu(pcie);
-
- dbi_writel(pcie, 1, PCIE_DBI_RO_WR_EN);
- ls_pcie_fix_class(pcie);
- ls_pcie_clear_multifunction(pcie);
- ls_pcie_drop_msg_tlp(pcie);
- dbi_writel(pcie, 0, PCIE_DBI_RO_WR_EN);
-
- ls_pcie_disable_bars(pcie);
- pcie->stream_id_cur = 0;
-}
-
-static void ls_pcie_ep_setup_atu(struct ls_pcie *pcie)
-{
- u64 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE;
-
- /* ATU 0 : INBOUND : map BAR0 */
- ls_pcie_atu_inbound_set(pcie, 0, 0, phys);
- /* ATU 1 : INBOUND : map BAR1 */
- phys += PCIE_BAR1_SIZE;
- ls_pcie_atu_inbound_set(pcie, 1, 1, phys);
- /* ATU 2 : INBOUND : map BAR2 */
- phys += PCIE_BAR2_SIZE;
- ls_pcie_atu_inbound_set(pcie, 2, 2, phys);
- /* ATU 3 : INBOUND : map BAR4 */
- phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR4_SIZE;
- ls_pcie_atu_inbound_set(pcie, 3, 4, phys);
-
- /* ATU 0 : OUTBOUND : map MEM */
- ls_pcie_atu_outbound_set(pcie, 0,
- PCIE_ATU_TYPE_MEM,
- pcie->cfg_res.start,
- 0,
- CONFIG_SYS_PCI_MEMORY_SIZE);
-}
-
-/* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */
-static void ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size)
-{
- /* The least inbound window is 4KiB */
- if (size < 4 * 1024)
- return;
-
- switch (bar) {
- case 0:
- writel(size - 1, bar_base + PCI_BASE_ADDRESS_0);
- break;
- case 1:
- writel(size - 1, bar_base + PCI_BASE_ADDRESS_1);
- break;
- case 2:
- writel(size - 1, bar_base + PCI_BASE_ADDRESS_2);
- writel(0, bar_base + PCI_BASE_ADDRESS_3);
- break;
- case 4:
- writel(size - 1, bar_base + PCI_BASE_ADDRESS_4);
- writel(0, bar_base + PCI_BASE_ADDRESS_5);
- break;
- default:
- break;
- }
-}
-
-static void ls_pcie_ep_setup_bars(void *bar_base)
-{
- /* BAR0 - 32bit - 4K configuration */
- ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
- /* BAR1 - 32bit - 8K MSIX*/
- ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
- /* BAR2 - 64bit - 4K MEM desciptor */
- ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
- /* BAR4 - 64bit - 1M MEM*/
- ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE);
-}
-
-static void ls_pcie_ep_enable_cfg(struct ls_pcie *pcie)
-{
- u32 config;
-
- config = ctrl_readl(pcie, PCIE_PF_CONFIG);
- config |= PCIE_CONFIG_READY;
- ctrl_writel(pcie, config, PCIE_PF_CONFIG);
-}
-
-static void ls_pcie_setup_ep(struct ls_pcie *pcie)
-{
- u32 sriov;
-
- sriov = readl(pcie->dbi + PCIE_SRIOV);
- if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) {
- int pf, vf;
-
- for (pf = 0; pf < PCIE_PF_NUM; pf++) {
- for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
- ctrl_writel(pcie, PCIE_LCTRL0_VAL(pf, vf),
- PCIE_PF_VF_CTRL);
-
- ls_pcie_ep_setup_bars(pcie->dbi);
- ls_pcie_ep_setup_atu(pcie);
- }
- }
- /* Disable CFG2 */
- ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL);
- } else {
- ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE);
- ls_pcie_ep_setup_atu(pcie);
- }
-
- ls_pcie_ep_enable_cfg(pcie);
-}
-
-static int ls_pcie_probe(struct udevice *dev)
-{
- struct ls_pcie *pcie = dev_get_priv(dev);
- const void *fdt = gd->fdt_blob;
- int node = dev_of_offset(dev);
- u16 link_sta;
- uint svr;
- int ret;
- fdt_size_t cfg_size;
-
- pcie->bus = dev;
-
- ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
- "dbi", &pcie->dbi_res);
- if (ret) {
- printf("ls-pcie: resource \"dbi\" not found\n");
- return ret;
- }
-
- pcie->idx = (pcie->dbi_res.start - PCIE_SYS_BASE_ADDR) / PCIE_CCSR_SIZE;
-
- list_add(&pcie->list, &ls_pcie_list);
-
- pcie->enabled = is_serdes_configured(PCIE_SRDS_PRTCL(pcie->idx));
- if (!pcie->enabled) {
- printf("PCIe%d: %s disabled\n", pcie->idx, dev->name);
- return 0;
- }
-
- pcie->dbi = map_physmem(pcie->dbi_res.start,
- fdt_resource_size(&pcie->dbi_res),
- MAP_NOCACHE);
-
- ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
- "lut", &pcie->lut_res);
- if (!ret)
- pcie->lut = map_physmem(pcie->lut_res.start,
- fdt_resource_size(&pcie->lut_res),
- MAP_NOCACHE);
-
- ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
- "ctrl", &pcie->ctrl_res);
- if (!ret)
- pcie->ctrl = map_physmem(pcie->ctrl_res.start,
- fdt_resource_size(&pcie->ctrl_res),
- MAP_NOCACHE);
- if (!pcie->ctrl)
- pcie->ctrl = pcie->lut;
-
- if (!pcie->ctrl) {
- printf("%s: NOT find CTRL\n", dev->name);
- return -1;
- }
-
- ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
- "config", &pcie->cfg_res);
- if (ret) {
- printf("%s: resource \"config\" not found\n", dev->name);
- 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 ||
- svr == SVR_LS2081A || svr == SVR_LS2041A) {
- cfg_size = fdt_resource_size(&pcie->cfg_res);
- pcie->cfg_res.start = LS2088A_PCIE1_PHYS_ADDR +
- LS2088A_PCIE_PHYS_SIZE * pcie->idx;
- pcie->cfg_res.end = pcie->cfg_res.start + cfg_size;
- pcie->ctrl = pcie->lut + 0x40000;
- }
-
- pcie->cfg0 = map_physmem(pcie->cfg_res.start,
- fdt_resource_size(&pcie->cfg_res),
- MAP_NOCACHE);
- pcie->cfg1 = pcie->cfg0 + fdt_resource_size(&pcie->cfg_res) / 2;
-
- pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian");
-
- debug("%s dbi:%lx lut:%lx ctrl:0x%lx cfg0:0x%lx, big-endian:%d\n",
- dev->name, (unsigned long)pcie->dbi, (unsigned long)pcie->lut,
- (unsigned long)pcie->ctrl, (unsigned long)pcie->cfg0,
- pcie->big_endian);
-
- pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f;
-
- if (pcie->mode == PCI_HEADER_TYPE_NORMAL) {
- printf("PCIe%u: %s %s", pcie->idx, dev->name, "Endpoint");
- ls_pcie_setup_ep(pcie);
- } else {
- printf("PCIe%u: %s %s", pcie->idx, dev->name, "Root Complex");
- ls_pcie_setup_ctrl(pcie);
- }
-
- if (!ls_pcie_link_up(pcie)) {
- /* Let the user know there's no PCIe link */
- printf(": no link\n");
- return 0;
- }
-
- /* Print the negotiated PCIe link width */
- link_sta = readw(pcie->dbi + PCIE_LINK_STA);
- printf(": x%d gen%d\n", (link_sta & PCIE_LINK_WIDTH_MASK) >> 4,
- link_sta & PCIE_LINK_SPEED_MASK);
-
- return 0;
-}
-
-static const struct dm_pci_ops ls_pcie_ops = {
- .read_config = ls_pcie_read_config,
- .write_config = ls_pcie_write_config,
-};
-
-static const struct udevice_id ls_pcie_ids[] = {
- { .compatible = "fsl,ls-pcie" },
- { }
-};
-
-U_BOOT_DRIVER(pci_layerscape) = {
- .name = "pci_layerscape",
- .id = UCLASS_PCI,
- .of_match = ls_pcie_ids,
- .ops = &ls_pcie_ops,
- .probe = ls_pcie_probe,
- .priv_auto_alloc_size = sizeof(struct ls_pcie),
-};
diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h
index 95454bc..217dcda 100644
--- a/drivers/pci/pcie_layerscape.h
+++ b/drivers/pci/pcie_layerscape.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * Copyright 2017-2019 NXP
+ * Copyright 2017-2020 NXP
* Copyright 2014-2015 Freescale Semiconductor, Inc.
* Layerscape PCIe driver
*/
@@ -60,7 +60,8 @@
/* DBI registers */
#define PCIE_SRIOV 0x178
#define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */
-#define PCIE_DBI_RO_WR_EN 0x8bc
+#define PCIE_DBI_RO_WR_EN BIT(0)
+#define PCIE_MISC_CONTROL_1_OFF 0x8BC
#define PCIE_LINK_CAP 0x7c
#define PCIE_LINK_SPEED_MASK 0xf
@@ -82,7 +83,7 @@
PCIE_LCTRL0_CFG2_ENABLE)
#define PCIE_NO_SRIOV_BAR_BASE 0x1000
-
+#define FSL_PCIE_EP_MIN_APERTURE 4096 /* 4 Kbytes */
#define PCIE_PF_NUM 2
#define PCIE_VF_NUM 64
@@ -129,25 +130,52 @@
#define LS1021_LTSSM_STATE_SHIFT 20
struct ls_pcie {
+ void __iomem *dbi;
+ void __iomem *lut;
+ void __iomem *ctrl;
int idx;
+ bool big_endian;
+ int mode;
+};
+
+struct ls_pcie_rc {
+ struct ls_pcie *pcie;
struct list_head list;
struct udevice *bus;
struct fdt_resource dbi_res;
struct fdt_resource lut_res;
struct fdt_resource ctrl_res;
struct fdt_resource cfg_res;
- void __iomem *dbi;
- void __iomem *lut;
- void __iomem *ctrl;
void __iomem *cfg0;
void __iomem *cfg1;
- bool big_endian;
bool enabled;
int next_lut_index;
int stream_id_cur;
- int mode;
+};
+
+struct ls_pcie_ep {
+ struct fdt_resource addr_res;
+ struct ls_pcie *pcie;
+ struct udevice *bus;
+ void __iomem *addr;
+ u32 num_ib_wins;
+ u32 num_ob_wins;
+ u8 max_functions;
};
extern struct list_head ls_pcie_list;
+unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset);
+void dbi_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset);
+unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset);
+void ctrl_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset);
+void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
+ u64 phys, u64 bus_addr, pci_size_t size);
+void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, int type,
+ int bar, u64 phys);
+void ls_pcie_dump_atu(struct ls_pcie *pcie);
+int ls_pcie_link_up(struct ls_pcie *pcie);
+void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie);
+void ls_pcie_dbi_ro_wr_dis(struct ls_pcie *pcie);
+
#endif /* _PCIE_LAYERSCAPE_H_ */
diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c
new file mode 100644
index 0000000..8d0c99a
--- /dev/null
+++ b/drivers/pci/pcie_layerscape_ep.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020 NXP
+ * Layerscape PCIe EP driver
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <pci_ep.h>
+#include <asm/io.h>
+#include <linux/sizes.h>
+#include <linux/log2.h>
+#include "pcie_layerscape.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void ls_pcie_ep_enable_cfg(struct ls_pcie_ep *pcie_ep)
+{
+ struct ls_pcie *pcie = pcie_ep->pcie;
+ u32 config;
+
+ config = ctrl_readl(pcie, PCIE_PF_CONFIG);
+ config |= PCIE_CONFIG_READY;
+ ctrl_writel(pcie, config, PCIE_PF_CONFIG);
+}
+
+static int ls_ep_set_bar(struct udevice *dev, uint fn, struct pci_bar *ep_bar)
+{
+ struct ls_pcie_ep *pcie_ep = dev_get_priv(dev);
+ struct ls_pcie *pcie = pcie_ep->pcie;
+ dma_addr_t bar_phys = ep_bar->phys_addr;
+ enum pci_barno bar = ep_bar->barno;
+ u32 reg = PCI_BASE_ADDRESS_0 + (4 * bar);
+ int flags = ep_bar->flags;
+ int type, idx;
+ u64 size;
+
+ idx = bar;
+ /* BAR size is 2^(aperture + 11) */
+ size = max_t(size_t, ep_bar->size, FSL_PCIE_EP_MIN_APERTURE);
+
+ if (!(flags & PCI_BASE_ADDRESS_SPACE))
+ type = PCIE_ATU_TYPE_MEM;
+ else
+ type = PCIE_ATU_TYPE_IO;
+
+ ls_pcie_atu_inbound_set(pcie, idx, bar, bar_phys, type);
+
+ dbi_writel(pcie, lower_32_bits(size - 1), reg + PCIE_NO_SRIOV_BAR_BASE);
+ dbi_writel(pcie, flags, reg);
+
+ if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+ dbi_writel(pcie, upper_32_bits(size - 1),
+ reg + 4 + PCIE_NO_SRIOV_BAR_BASE);
+ dbi_writel(pcie, 0, reg + 4);
+ }
+
+ return 0;
+}
+
+static struct pci_ep_ops ls_pcie_ep_ops = {
+ .set_bar = ls_ep_set_bar,
+};
+
+static void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep)
+{
+ struct ls_pcie *pcie = pcie_ep->pcie;
+ u64 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE;
+
+ /* ATU 0 : INBOUND : map BAR0 */
+ ls_pcie_atu_inbound_set(pcie, 0, PCIE_ATU_TYPE_MEM, 0, phys);
+ /* ATU 1 : INBOUND : map BAR1 */
+ phys += PCIE_BAR1_SIZE;
+ ls_pcie_atu_inbound_set(pcie, 1, PCIE_ATU_TYPE_MEM, 1, phys);
+ /* ATU 2 : INBOUND : map BAR2 */
+ phys += PCIE_BAR2_SIZE;
+ ls_pcie_atu_inbound_set(pcie, 2, PCIE_ATU_TYPE_MEM, 2, phys);
+ /* ATU 3 : INBOUND : map BAR4 */
+ phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR4_SIZE;
+ ls_pcie_atu_inbound_set(pcie, 3, PCIE_ATU_TYPE_MEM, 4, phys);
+
+ /* ATU 0 : OUTBOUND : map MEM */
+ ls_pcie_atu_outbound_set(pcie, 0,
+ PCIE_ATU_TYPE_MEM,
+ pcie_ep->addr_res.start,
+ 0,
+ CONFIG_SYS_PCI_MEMORY_SIZE);
+}
+
+/* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */
+static void ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size)
+{
+ /* The least inbound window is 4KiB */
+ if (size < 4 * 1024)
+ return;
+
+ switch (bar) {
+ case 0:
+ writel(size - 1, bar_base + PCI_BASE_ADDRESS_0);
+ break;
+ case 1:
+ writel(size - 1, bar_base + PCI_BASE_ADDRESS_1);
+ break;
+ case 2:
+ writel(size - 1, bar_base + PCI_BASE_ADDRESS_2);
+ writel(0, bar_base + PCI_BASE_ADDRESS_3);
+ break;
+ case 4:
+ writel(size - 1, bar_base + PCI_BASE_ADDRESS_4);
+ writel(0, bar_base + PCI_BASE_ADDRESS_5);
+ break;
+ default:
+ break;
+ }
+}
+
+static void ls_pcie_ep_setup_bars(void *bar_base)
+{
+ /* BAR0 - 32bit - 4K configuration */
+ ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
+ /* BAR1 - 32bit - 8K MSIX */
+ ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
+ /* BAR2 - 64bit - 4K MEM descriptor */
+ ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
+ /* BAR4 - 64bit - 1M MEM */
+ ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE);
+}
+
+static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep)
+{
+ u32 sriov;
+ struct ls_pcie *pcie = pcie_ep->pcie;
+
+ sriov = readl(pcie->dbi + PCIE_SRIOV);
+ if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) {
+ int pf, vf;
+
+ for (pf = 0; pf < PCIE_PF_NUM; pf++) {
+ for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
+ ctrl_writel(pcie, PCIE_LCTRL0_VAL(pf, vf),
+ PCIE_PF_VF_CTRL);
+
+ ls_pcie_ep_setup_bars(pcie->dbi);
+ ls_pcie_ep_setup_atu(pcie_ep);
+ }
+ }
+ /* Disable CFG2 */
+ ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL);
+ } else {
+ ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE);
+ ls_pcie_ep_setup_atu(pcie_ep);
+ }
+
+ ls_pcie_ep_enable_cfg(pcie_ep);
+}
+
+static int ls_pcie_ep_probe(struct udevice *dev)
+{
+ struct ls_pcie_ep *pcie_ep = dev_get_priv(dev);
+ struct ls_pcie *pcie;
+ u16 link_sta;
+ int ret;
+
+ pcie = devm_kmalloc(dev, sizeof(*pcie), GFP_KERNEL);
+ if (!pcie)
+ return -ENOMEM;
+
+ pcie_ep->pcie = pcie;
+
+ pcie->dbi = (void __iomem *)devfdt_get_addr_index(dev, 0);
+ if (!pcie->dbi)
+ return -ENOMEM;
+
+ pcie->ctrl = (void __iomem *)devfdt_get_addr_index(dev, 1);
+ if (!pcie->ctrl)
+ return -ENOMEM;
+
+ ret = fdt_get_named_resource(gd->fdt_blob, dev_of_offset(dev),
+ "reg", "reg-names",
+ "addr_space", &pcie_ep->addr_res);
+ if (ret) {
+ printf("%s: resource \"addr_space\" not found\n", dev->name);
+ return ret;
+ }
+
+ pcie->idx = ((unsigned long)pcie->dbi - PCIE_SYS_BASE_ADDR) /
+ PCIE_CCSR_SIZE;
+
+ pcie->big_endian = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
+ "big-endian");
+
+ pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f;
+ if (pcie->mode != PCI_HEADER_TYPE_NORMAL)
+ return 0;
+
+ pcie_ep->max_functions = fdtdec_get_int(gd->fdt_blob,
+ dev_of_offset(dev),
+ "max-functions", 1);
+ pcie_ep->num_ib_wins = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+ "num-ib-windows", 8);
+ pcie_ep->num_ob_wins = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+ "num-ob-windows", 8);
+
+ printf("PCIe%u: %s %s", pcie->idx, dev->name, "Endpoint");
+ ls_pcie_setup_ep(pcie_ep);
+
+ if (!ls_pcie_link_up(pcie)) {
+ /* Let the user know there's no PCIe link */
+ printf(": no link\n");
+ return 0;
+ }
+
+ /* Print the negotiated PCIe link width */
+ link_sta = readw(pcie->dbi + PCIE_LINK_STA);
+ printf(": x%d gen%d\n", (link_sta & PCIE_LINK_WIDTH_MASK) >> 4,
+ link_sta & PCIE_LINK_SPEED_MASK);
+
+ return 0;
+}
+
+static int ls_pcie_ep_remove(struct udevice *dev)
+{
+ return 0;
+}
+
+const struct udevice_id ls_pcie_ep_ids[] = {
+ { .compatible = "fsl,ls-pcie-ep" },
+ { }
+};
+
+U_BOOT_DRIVER(pci_layerscape_ep) = {
+ .name = "pci_layerscape_ep",
+ .id = UCLASS_PCI_EP,
+ .of_match = ls_pcie_ep_ids,
+ .ops = &ls_pcie_ep_ops,
+ .probe = ls_pcie_ep_probe,
+ .remove = ls_pcie_ep_remove,
+ .priv_auto_alloc_size = sizeof(struct ls_pcie_ep),
+};
diff --git a/drivers/pci/pcie_layerscape_fixup.c b/drivers/pci/pcie_layerscape_fixup.c
index ec6acbb..a981f8c 100644
--- a/drivers/pci/pcie_layerscape_fixup.c
+++ b/drivers/pci/pcie_layerscape_fixup.c
@@ -23,17 +23,19 @@
/*
* Return next available LUT index.
*/
-static int ls_pcie_next_lut_index(struct ls_pcie *pcie)
+static int ls_pcie_next_lut_index(struct ls_pcie_rc *pcie_rc)
{
- if (pcie->next_lut_index < PCIE_LUT_ENTRY_COUNT)
- return pcie->next_lut_index++;
+ if (pcie_rc->next_lut_index < PCIE_LUT_ENTRY_COUNT)
+ return pcie_rc->next_lut_index++;
else
return -ENOSPC; /* LUT is full */
}
-static void lut_writel(struct ls_pcie *pcie, unsigned int value,
+static void lut_writel(struct ls_pcie_rc *pcie_rc, unsigned int value,
unsigned int offset)
{
+ struct ls_pcie *pcie = pcie_rc->pcie;
+
if (pcie->big_endian)
out_be32(pcie->lut + offset, value);
else
@@ -43,12 +45,12 @@ static void lut_writel(struct ls_pcie *pcie, unsigned int value,
/*
* Program a single LUT entry
*/
-static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid,
- u32 streamid)
+static void ls_pcie_lut_set_mapping(struct ls_pcie_rc *pcie_rc, int index,
+ u32 devid, u32 streamid)
{
/* leave mask as all zeroes, want to match all bits */
- lut_writel(pcie, devid << 16, PCIE_LUT_UDR(index));
- lut_writel(pcie, streamid | PCIE_LUT_ENABLE, PCIE_LUT_LDR(index));
+ lut_writel(pcie_rc, devid << 16, PCIE_LUT_UDR(index));
+ lut_writel(pcie_rc, streamid | PCIE_LUT_ENABLE, PCIE_LUT_LDR(index));
}
/*
@@ -59,7 +61,8 @@ static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid,
* msi-map = <[devid] [phandle-to-msi-ctrl] [stream-id] [count]
* [devid] [phandle-to-msi-ctrl] [stream-id] [count]>;
*/
-static void fdt_pcie_set_msi_map_entry_ls(void *blob, struct ls_pcie *pcie,
+static void fdt_pcie_set_msi_map_entry_ls(void *blob,
+ struct ls_pcie_rc *pcie_rc,
u32 devid, u32 streamid)
{
u32 *prop;
@@ -67,10 +70,11 @@ static void fdt_pcie_set_msi_map_entry_ls(void *blob, struct ls_pcie *pcie,
int nodeoffset;
uint svr;
char *compat = NULL;
+ struct ls_pcie *pcie = pcie_rc->pcie;
/* find pci controller node */
nodeoffset = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie",
- pcie->dbi_res.start);
+ pcie_rc->dbi_res.start);
if (nodeoffset < 0) {
#ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts node */
svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE;
@@ -82,7 +86,7 @@ static void fdt_pcie_set_msi_map_entry_ls(void *blob, struct ls_pcie *pcie,
compat = CONFIG_FSL_PCIE_COMPAT;
if (compat)
nodeoffset = fdt_node_offset_by_compat_reg(blob,
- compat, pcie->dbi_res.start);
+ compat, pcie_rc->dbi_res.start);
#endif
if (nodeoffset < 0)
return;
@@ -112,7 +116,8 @@ static void fdt_pcie_set_msi_map_entry_ls(void *blob, struct ls_pcie *pcie,
* iommu-map = <[devid] [phandle-to-iommu-ctrl] [stream-id] [count]
* [devid] [phandle-to-iommu-ctrl] [stream-id] [count]>;
*/
-static void fdt_pcie_set_iommu_map_entry_ls(void *blob, struct ls_pcie *pcie,
+static void fdt_pcie_set_iommu_map_entry_ls(void *blob,
+ struct ls_pcie_rc *pcie_rc,
u32 devid, u32 streamid)
{
u32 *prop;
@@ -121,10 +126,11 @@ static void fdt_pcie_set_iommu_map_entry_ls(void *blob, struct ls_pcie *pcie,
int lenp;
uint svr;
char *compat = NULL;
+ struct ls_pcie *pcie = pcie_rc->pcie;
/* find pci controller node */
nodeoffset = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie",
- pcie->dbi_res.start);
+ pcie_rc->dbi_res.start);
if (nodeoffset < 0) {
#ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts node */
svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE;
@@ -137,7 +143,7 @@ static void fdt_pcie_set_iommu_map_entry_ls(void *blob, struct ls_pcie *pcie,
if (compat)
nodeoffset = fdt_node_offset_by_compat_reg(blob,
- compat, pcie->dbi_res.start);
+ compat, pcie_rc->dbi_res.start);
#endif
if (nodeoffset < 0)
return;
@@ -168,7 +174,7 @@ static void fdt_pcie_set_iommu_map_entry_ls(void *blob, struct ls_pcie *pcie,
static void fdt_fixup_pcie_ls(void *blob)
{
struct udevice *dev, *bus;
- struct ls_pcie *pcie;
+ struct ls_pcie_rc *pcie_rc;
int streamid;
int index;
pci_dev_t bdf;
@@ -179,17 +185,18 @@ static void fdt_fixup_pcie_ls(void *blob)
pci_find_next_device(&dev)) {
for (bus = dev; device_is_on_pci_bus(bus);)
bus = bus->parent;
- pcie = dev_get_priv(bus);
+ pcie_rc = dev_get_priv(bus);
- streamid = pcie_next_streamid(pcie->stream_id_cur, pcie->idx);
+ streamid = pcie_next_streamid(pcie_rc->stream_id_cur,
+ pcie_rc->pcie->idx);
if (streamid < 0) {
debug("ERROR: no stream ids free\n");
continue;
} else {
- pcie->stream_id_cur++;
+ pcie_rc->stream_id_cur++;
}
- index = ls_pcie_next_lut_index(pcie);
+ index = ls_pcie_next_lut_index(pcie_rc);
if (index < 0) {
debug("ERROR: no LUT indexes free\n");
continue;
@@ -198,27 +205,28 @@ static void fdt_fixup_pcie_ls(void *blob)
/* the DT fixup must be relative to the hose first_busno */
bdf = dm_pci_get_bdf(dev) - PCI_BDF(bus->seq, 0, 0);
/* map PCI b.d.f to streamID in LUT */
- ls_pcie_lut_set_mapping(pcie, index, bdf >> 8,
+ ls_pcie_lut_set_mapping(pcie_rc, index, bdf >> 8,
streamid);
/* update msi-map in device tree */
- fdt_pcie_set_msi_map_entry_ls(blob, pcie, bdf >> 8,
+ fdt_pcie_set_msi_map_entry_ls(blob, pcie_rc, bdf >> 8,
streamid);
/* update iommu-map in device tree */
- fdt_pcie_set_iommu_map_entry_ls(blob, pcie, bdf >> 8,
+ fdt_pcie_set_iommu_map_entry_ls(blob, pcie_rc, bdf >> 8,
streamid);
}
pcie_board_fix_fdt(blob);
}
#endif
-static void ft_pcie_rc_fix(void *blob, struct ls_pcie *pcie)
+static void ft_pcie_rc_fix(void *blob, struct ls_pcie_rc *pcie_rc)
{
int off;
uint svr;
char *compat = NULL;
+ struct ls_pcie *pcie = pcie_rc->pcie;
off = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie",
- pcie->dbi_res.start);
+ pcie_rc->dbi_res.start);
if (off < 0) {
#ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts node */
svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE;
@@ -230,46 +238,47 @@ static void ft_pcie_rc_fix(void *blob, struct ls_pcie *pcie)
compat = CONFIG_FSL_PCIE_COMPAT;
if (compat)
off = fdt_node_offset_by_compat_reg(blob,
- compat, pcie->dbi_res.start);
+ compat, pcie_rc->dbi_res.start);
#endif
if (off < 0)
return;
}
- if (pcie->enabled && pcie->mode == PCI_HEADER_TYPE_BRIDGE)
+ if (pcie_rc->enabled && pcie->mode == PCI_HEADER_TYPE_BRIDGE)
fdt_set_node_status(blob, off, FDT_STATUS_OKAY, 0);
else
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
}
-static void ft_pcie_ep_fix(void *blob, struct ls_pcie *pcie)
+static void ft_pcie_ep_fix(void *blob, struct ls_pcie_rc *pcie_rc)
{
int off;
+ struct ls_pcie *pcie = pcie_rc->pcie;
off = fdt_node_offset_by_compat_reg(blob, CONFIG_FSL_PCIE_EP_COMPAT,
- pcie->dbi_res.start);
+ pcie_rc->dbi_res.start);
if (off < 0)
return;
- if (pcie->enabled && pcie->mode == PCI_HEADER_TYPE_NORMAL)
+ if (pcie_rc->enabled && pcie->mode == PCI_HEADER_TYPE_NORMAL)
fdt_set_node_status(blob, off, FDT_STATUS_OKAY, 0);
else
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
}
-static void ft_pcie_ls_setup(void *blob, struct ls_pcie *pcie)
+static void ft_pcie_ls_setup(void *blob, struct ls_pcie_rc *pcie_rc)
{
- ft_pcie_ep_fix(blob, pcie);
- ft_pcie_rc_fix(blob, pcie);
+ ft_pcie_ep_fix(blob, pcie_rc);
+ ft_pcie_rc_fix(blob, pcie_rc);
}
/* Fixup Kernel DT for PCIe */
void ft_pci_setup_ls(void *blob, bd_t *bd)
{
- struct ls_pcie *pcie;
+ struct ls_pcie_rc *pcie_rc;
- list_for_each_entry(pcie, &ls_pcie_list, list)
- ft_pcie_ls_setup(blob, pcie);
+ list_for_each_entry(pcie_rc, &ls_pcie_list, list)
+ ft_pcie_ls_setup(blob, pcie_rc);
#if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2)
fdt_fixup_pcie_ls(blob);
diff --git a/drivers/pci/pcie_layerscape_rc.c b/drivers/pci/pcie_layerscape_rc.c
new file mode 100644
index 0000000..927722d
--- /dev/null
+++ b/drivers/pci/pcie_layerscape_rc.c
@@ -0,0 +1,378 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020 NXP
+ * Layerscape PCIe driver
+ */
+
+#include <common.h>
+#include <asm/arch/fsl_serdes.h>
+#include <pci.h>
+#include <asm/io.h>
+#include <errno.h>
+#include <malloc.h>
+#include <dm.h>
+#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
+ defined(CONFIG_ARM)
+#include <asm/arch/clock.h>
+#endif
+#include "pcie_layerscape.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void ls_pcie_cfg0_set_busdev(struct ls_pcie_rc *pcie_rc, u32 busdev)
+{
+ struct ls_pcie *pcie = pcie_rc->pcie;
+
+ dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_VIEWPORT);
+ dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET);
+}
+
+static void ls_pcie_cfg1_set_busdev(struct ls_pcie_rc *pcie_rc, u32 busdev)
+{
+ struct ls_pcie *pcie = pcie_rc->pcie;
+
+ dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
+ PCIE_ATU_VIEWPORT);
+ dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET);
+}
+
+static void ls_pcie_setup_atu(struct ls_pcie_rc *pcie_rc)
+{
+ struct pci_region *io, *mem, *pref;
+ unsigned long long offset = 0;
+ struct ls_pcie *pcie = pcie_rc->pcie;
+ int idx = 0;
+ uint svr;
+
+ svr = get_svr();
+ if (((svr >> SVR_VAR_PER_SHIFT) & SVR_LS102XA_MASK) == SVR_LS102XA) {
+ offset = LS1021_PCIE_SPACE_OFFSET +
+ LS1021_PCIE_SPACE_SIZE * pcie->idx;
+ }
+
+ /* ATU 0 : OUTBOUND : CFG0 */
+ ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_CFG0,
+ pcie_rc->cfg_res.start + offset,
+ 0,
+ fdt_resource_size(&pcie_rc->cfg_res) / 2);
+ /* ATU 1 : OUTBOUND : CFG1 */
+ ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1,
+ PCIE_ATU_TYPE_CFG1,
+ pcie_rc->cfg_res.start + offset +
+ fdt_resource_size(&pcie_rc->cfg_res) / 2,
+ 0,
+ fdt_resource_size(&pcie_rc->cfg_res) / 2);
+
+ pci_get_regions(pcie_rc->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 ||
+ svr == SVR_LS2081A || svr == SVR_LS2041A) {
+ 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++,
+ PCIE_ATU_TYPE_IO,
+ io->phys_start + offset,
+ io->bus_start,
+ io->size);
+
+ if (mem)
+ /* ATU : OUTBOUND : MEM */
+ ls_pcie_atu_outbound_set(pcie, idx++,
+ PCIE_ATU_TYPE_MEM,
+ mem->phys_start + offset,
+ mem->bus_start,
+ mem->size);
+
+ if (pref)
+ /* ATU : OUTBOUND : pref */
+ ls_pcie_atu_outbound_set(pcie, idx++,
+ PCIE_ATU_TYPE_MEM,
+ pref->phys_start + offset,
+ pref->bus_start,
+ pref->size);
+
+ ls_pcie_dump_atu(pcie);
+}
+
+/* Return 0 if the address is valid, -errno if not valid */
+static int ls_pcie_addr_valid(struct ls_pcie_rc *pcie_rc, pci_dev_t bdf)
+{
+ struct udevice *bus = pcie_rc->bus;
+ struct ls_pcie *pcie = pcie_rc->pcie;
+
+ if (pcie->mode == PCI_HEADER_TYPE_NORMAL)
+ return -ENODEV;
+
+ if (!pcie_rc->enabled)
+ return -ENXIO;
+
+ if (PCI_BUS(bdf) < bus->seq)
+ return -EINVAL;
+
+ if ((PCI_BUS(bdf) > bus->seq) && (!ls_pcie_link_up(pcie)))
+ return -EINVAL;
+
+ if (PCI_BUS(bdf) <= (bus->seq + 1) && (PCI_DEV(bdf) > 0))
+ return -EINVAL;
+
+ return 0;
+}
+
+int ls_pcie_conf_address(struct udevice *bus, pci_dev_t bdf,
+ uint offset, void **paddress)
+{
+ struct ls_pcie_rc *pcie_rc = dev_get_priv(bus);
+ struct ls_pcie *pcie = pcie_rc->pcie;
+ u32 busdev;
+
+ if (ls_pcie_addr_valid(pcie_rc, bdf))
+ return -EINVAL;
+
+ if (PCI_BUS(bdf) == bus->seq) {
+ *paddress = pcie->dbi + offset;
+ return 0;
+ }
+
+ busdev = PCIE_ATU_BUS(PCI_BUS(bdf) - bus->seq) |
+ PCIE_ATU_DEV(PCI_DEV(bdf)) |
+ PCIE_ATU_FUNC(PCI_FUNC(bdf));
+
+ if (PCI_BUS(bdf) == bus->seq + 1) {
+ ls_pcie_cfg0_set_busdev(pcie_rc, busdev);
+ *paddress = pcie_rc->cfg0 + offset;
+ } else {
+ ls_pcie_cfg1_set_busdev(pcie_rc, busdev);
+ *paddress = pcie_rc->cfg1 + offset;
+ }
+ return 0;
+}
+
+static int ls_pcie_read_config(struct udevice *bus, pci_dev_t bdf,
+ uint offset, ulong *valuep,
+ enum pci_size_t size)
+{
+ return pci_generic_mmap_read_config(bus, ls_pcie_conf_address,
+ bdf, offset, valuep, size);
+}
+
+static int ls_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
+ uint offset, ulong value,
+ enum pci_size_t size)
+{
+ return pci_generic_mmap_write_config(bus, ls_pcie_conf_address,
+ bdf, offset, value, size);
+}
+
+/* Clear multi-function bit */
+static void ls_pcie_clear_multifunction(struct ls_pcie_rc *pcie_rc)
+{
+ struct ls_pcie *pcie = pcie_rc->pcie;
+
+ writeb(PCI_HEADER_TYPE_BRIDGE, pcie->dbi + PCI_HEADER_TYPE);
+}
+
+/* Fix class value */
+static void ls_pcie_fix_class(struct ls_pcie_rc *pcie_rc)
+{
+ struct ls_pcie *pcie = pcie_rc->pcie;
+
+ writew(PCI_CLASS_BRIDGE_PCI, pcie->dbi + PCI_CLASS_DEVICE);
+}
+
+/* Drop MSG TLP except for Vendor MSG */
+static void ls_pcie_drop_msg_tlp(struct ls_pcie_rc *pcie_rc)
+{
+ struct ls_pcie *pcie = pcie_rc->pcie;
+ u32 val;
+
+ val = dbi_readl(pcie, PCIE_STRFMR1);
+ val &= 0xDFFFFFFF;
+ dbi_writel(pcie, val, PCIE_STRFMR1);
+}
+
+/* Disable all bars in RC mode */
+static void ls_pcie_disable_bars(struct ls_pcie_rc *pcie_rc)
+{
+ struct ls_pcie *pcie = pcie_rc->pcie;
+
+ dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_0);
+ dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_1);
+ dbi_writel(pcie, 0xfffffffe, PCIE_CS2_OFFSET + PCI_ROM_ADDRESS1);
+}
+
+static void ls_pcie_setup_ctrl(struct ls_pcie_rc *pcie_rc)
+{
+ struct ls_pcie *pcie = pcie_rc->pcie;
+
+ ls_pcie_setup_atu(pcie_rc);
+
+ ls_pcie_dbi_ro_wr_en(pcie);
+ ls_pcie_fix_class(pcie_rc);
+ ls_pcie_clear_multifunction(pcie_rc);
+ ls_pcie_drop_msg_tlp(pcie_rc);
+ ls_pcie_dbi_ro_wr_dis(pcie);
+
+ ls_pcie_disable_bars(pcie_rc);
+ pcie_rc->stream_id_cur = 0;
+}
+
+static int ls_pcie_probe(struct udevice *dev)
+{
+ struct ls_pcie_rc *pcie_rc = dev_get_priv(dev);
+ const void *fdt = gd->fdt_blob;
+ int node = dev_of_offset(dev);
+ struct ls_pcie *pcie;
+ u16 link_sta;
+ uint svr;
+ int ret;
+ fdt_size_t cfg_size;
+
+ pcie_rc->bus = dev;
+
+ pcie = devm_kmalloc(dev, sizeof(*pcie), GFP_KERNEL);
+ if (!pcie)
+ return -ENOMEM;
+
+ pcie_rc->pcie = pcie;
+
+ ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
+ "dbi", &pcie_rc->dbi_res);
+ if (ret) {
+ printf("ls-pcie: resource \"dbi\" not found\n");
+ return ret;
+ }
+
+ pcie->idx = (pcie_rc->dbi_res.start - PCIE_SYS_BASE_ADDR) /
+ PCIE_CCSR_SIZE;
+
+ list_add(&pcie_rc->list, &ls_pcie_list);
+
+ pcie_rc->enabled = is_serdes_configured(PCIE_SRDS_PRTCL(pcie->idx));
+ if (!pcie_rc->enabled) {
+ printf("PCIe%d: %s disabled\n", pcie->idx, dev->name);
+ return 0;
+ }
+
+ pcie->dbi = map_physmem(pcie_rc->dbi_res.start,
+ fdt_resource_size(&pcie_rc->dbi_res),
+ MAP_NOCACHE);
+
+ pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f;
+ if (pcie->mode == PCI_HEADER_TYPE_NORMAL)
+ return 0;
+
+ ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
+ "lut", &pcie_rc->lut_res);
+ if (!ret)
+ pcie->lut = map_physmem(pcie_rc->lut_res.start,
+ fdt_resource_size(&pcie_rc->lut_res),
+ MAP_NOCACHE);
+
+ ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
+ "ctrl", &pcie_rc->ctrl_res);
+ if (!ret)
+ pcie->ctrl = map_physmem(pcie_rc->ctrl_res.start,
+ fdt_resource_size(&pcie_rc->ctrl_res),
+ MAP_NOCACHE);
+ if (!pcie->ctrl)
+ pcie->ctrl = pcie->lut;
+
+ if (!pcie->ctrl) {
+ printf("%s: NOT find CTRL\n", dev->name);
+ return -1;
+ }
+
+ ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
+ "config", &pcie_rc->cfg_res);
+ if (ret) {
+ printf("%s: resource \"config\" not found\n", dev->name);
+ 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 ||
+ svr == SVR_LS2081A || svr == SVR_LS2041A) {
+ cfg_size = fdt_resource_size(&pcie_rc->cfg_res);
+ pcie_rc->cfg_res.start = LS2088A_PCIE1_PHYS_ADDR +
+ LS2088A_PCIE_PHYS_SIZE * pcie->idx;
+ pcie_rc->cfg_res.end = pcie_rc->cfg_res.start + cfg_size;
+ pcie->ctrl = pcie->lut + 0x40000;
+ }
+
+ pcie_rc->cfg0 = map_physmem(pcie_rc->cfg_res.start,
+ fdt_resource_size(&pcie_rc->cfg_res),
+ MAP_NOCACHE);
+ pcie_rc->cfg1 = pcie_rc->cfg0 +
+ fdt_resource_size(&pcie_rc->cfg_res) / 2;
+
+ pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian");
+
+ debug("%s dbi:%lx lut:%lx ctrl:0x%lx cfg0:0x%lx, big-endian:%d\n",
+ dev->name, (unsigned long)pcie->dbi, (unsigned long)pcie->lut,
+ (unsigned long)pcie->ctrl, (unsigned long)pcie_rc->cfg0,
+ pcie->big_endian);
+
+ printf("PCIe%u: %s %s", pcie->idx, dev->name, "Root Complex");
+ ls_pcie_setup_ctrl(pcie_rc);
+
+ if (!ls_pcie_link_up(pcie)) {
+ /* Let the user know there's no PCIe link */
+ printf(": no link\n");
+ return 0;
+ }
+
+ /* Print the negotiated PCIe link width */
+ link_sta = readw(pcie->dbi + PCIE_LINK_STA);
+ printf(": x%d gen%d\n", (link_sta & PCIE_LINK_WIDTH_MASK) >> 4,
+ link_sta & PCIE_LINK_SPEED_MASK);
+
+ return 0;
+}
+
+static const struct dm_pci_ops ls_pcie_ops = {
+ .read_config = ls_pcie_read_config,
+ .write_config = ls_pcie_write_config,
+};
+
+static const struct udevice_id ls_pcie_ids[] = {
+ { .compatible = "fsl,ls-pcie" },
+ { }
+};
+
+U_BOOT_DRIVER(pci_layerscape) = {
+ .name = "pci_layerscape",
+ .id = UCLASS_PCI,
+ .of_match = ls_pcie_ids,
+ .ops = &ls_pcie_ops,
+ .probe = ls_pcie_probe,
+ .priv_auto_alloc_size = sizeof(struct ls_pcie_rc),
+};
--
2.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 2/9] pci_ep: Add the init function
2020-03-22 11:12 [PATCH 1/9] pci: layerscape: Split the EP and RC driver Xiaowei Bao
@ 2020-03-22 11:12 ` Xiaowei Bao
2020-04-28 12:23 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 3/9] armv8: dts: ls1046a: Add the PCIe EP node Xiaowei Bao
` (8 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Xiaowei Bao @ 2020-03-22 11:12 UTC (permalink / raw)
To: u-boot
Some EP deivces need to initialize before RC scan it, e.g. NXP
layerscape platform, so add the init function in pci_ep uclass.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
common/board_r.c | 12 ++++++++++++
drivers/pci_endpoint/pci_ep-uclass.c | 11 +++++++++++
include/init.h | 1 +
3 files changed, 24 insertions(+)
diff --git a/common/board_r.c b/common/board_r.c
index 0bbeaa7..856b47f 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -229,6 +229,15 @@ static int initr_unlock_ram_in_cache(void)
}
#endif
+#ifdef CONFIG_PCI_ENDPOINT
+static int initr_pci_ep(void)
+{
+ pci_ep_init();
+
+ return 0;
+}
+#endif
+
#ifdef CONFIG_PCI
static int initr_pci(void)
{
@@ -839,6 +848,9 @@ static init_fnc_t init_sequence_r[] = {
#ifdef CONFIG_BITBANGMII
initr_bbmii,
#endif
+#ifdef CONFIG_PCI_ENDPOINT
+ initr_pci_ep,
+#endif
#ifdef CONFIG_CMD_NET
INIT_FUNC_WATCHDOG_RESET
initr_net,
diff --git a/drivers/pci_endpoint/pci_ep-uclass.c b/drivers/pci_endpoint/pci_ep-uclass.c
index 9f53a9a..38a5f08 100644
--- a/drivers/pci_endpoint/pci_ep-uclass.c
+++ b/drivers/pci_endpoint/pci_ep-uclass.c
@@ -209,3 +209,14 @@ UCLASS_DRIVER(pci_ep) = {
.name = "pci_ep",
.flags = DM_UC_FLAG_SEQ_ALIAS,
};
+
+void pci_ep_init(void)
+{
+ struct udevice *dev;
+
+ for (uclass_first_device_check(UCLASS_PCI_EP, &dev);
+ dev;
+ uclass_next_device_check(&dev)) {
+ ;
+ }
+}
diff --git a/include/init.h b/include/init.h
index 2a33a3f..fbc26a8 100644
--- a/include/init.h
+++ b/include/init.h
@@ -202,6 +202,7 @@ int set_cpu_clk_info(void);
int update_flash_size(int flash_size);
int arch_early_init_r(void);
void pci_init(void);
+void pci_ep_init(void);
int misc_init_r(void);
#if defined(CONFIG_VID)
int init_func_vid(void);
--
2.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 3/9] armv8: dts: ls1046a: Add the PCIe EP node
2020-03-22 11:12 [PATCH 1/9] pci: layerscape: Split the EP and RC driver Xiaowei Bao
2020-03-22 11:12 ` [PATCH 2/9] pci_ep: Add the init function Xiaowei Bao
@ 2020-03-22 11:12 ` Xiaowei Bao
2020-04-28 12:24 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 4/9] PCI_EP: layerscape: Add the multiple function supprot Xiaowei Bao
` (7 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Xiaowei Bao @ 2020-03-22 11:12 UTC (permalink / raw)
To: u-boot
Add the PCIe EP node for ls1046a.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
arch/arm/dts/fsl-ls1046a.dtsi | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/arch/arm/dts/fsl-ls1046a.dtsi b/arch/arm/dts/fsl-ls1046a.dtsi
index fdf93fd..e4b4a8e 100644
--- a/arch/arm/dts/fsl-ls1046a.dtsi
+++ b/arch/arm/dts/fsl-ls1046a.dtsi
@@ -259,6 +259,17 @@
0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
};
+ pcie_ep at 3400000 {
+ compatible = "fsl,ls-pcie-ep";
+ reg = <0x00 0x03400000 0x0 0x80000
+ 0x00 0x034c0000 0x0 0x40000
+ 0x40 0x00000000 0x8 0x00000000>;
+ reg-names = "regs", "ctrl", "addr_space";
+ num-ib-windows = <6>;
+ num-ob-windows = <8>;
+ big-endian;
+ };
+
pcie at 3500000 {
compatible = "fsl,ls-pcie", "snps,dw-pcie";
reg = <0x00 0x03500000 0x0 0x80000 /* dbi registers */
@@ -276,6 +287,17 @@
0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
};
+ pcie_ep at 3500000 {
+ compatible = "fsl,ls-pcie-ep";
+ reg = <0x00 0x03500000 0x0 0x80000
+ 0x00 0x035c0000 0x0 0x40000
+ 0x48 0x00000000 0x8 0x00000000>;
+ reg-names = "regs", "ctrl", "addr_space";
+ num-ib-windows = <6>;
+ num-ob-windows = <8>;
+ big-endian;
+ };
+
pcie at 3600000 {
compatible = "fsl,ls-pcie", "snps,dw-pcie";
reg = <0x00 0x03600000 0x0 0x80000 /* dbi registers */
@@ -292,6 +314,17 @@
0x82000000 0x0 0x40000000 0x50 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
};
+ pcie_ep at 3600000 {
+ compatible = "fsl,ls-pcie-ep";
+ reg = <0x00 0x03600000 0x0 0x80000
+ 0x00 0x036c0000 0x0 0x40000
+ 0x50 0x00000000 0x8 0x00000000>;
+ reg-names = "regs", "ctrl", "addr_space";
+ num-ib-windows = <6>;
+ num-ob-windows = <8>;
+ big-endian;
+ };
+
sata: sata at 3200000 {
compatible = "fsl,ls1046a-ahci";
reg = <0x0 0x3200000 0x0 0x10000 /* ccsr sata base */
--
2.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 4/9] PCI_EP: layerscape: Add the multiple function supprot
2020-03-22 11:12 [PATCH 1/9] pci: layerscape: Split the EP and RC driver Xiaowei Bao
2020-03-22 11:12 ` [PATCH 2/9] pci_ep: Add the init function Xiaowei Bao
2020-03-22 11:12 ` [PATCH 3/9] armv8: dts: ls1046a: Add the PCIe EP node Xiaowei Bao
@ 2020-03-22 11:12 ` Xiaowei Bao
2020-04-28 12:24 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 5/9] pci_ep: layerscape: Add the workaround for errata A-009460 Xiaowei Bao
` (6 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Xiaowei Bao @ 2020-03-22 11:12 UTC (permalink / raw)
To: u-boot
Add the multiple function support for Layerscape platform, some PEXs
of Layerscaple platform have more than one PF.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
drivers/pci/pcie_layerscape.c | 6 +-
drivers/pci/pcie_layerscape.h | 21 +++++--
drivers/pci/pcie_layerscape_ep.c | 119 ++++++++++++++++++++++++++-------------
3 files changed, 98 insertions(+), 48 deletions(-)
diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
index 3ca75c5..88a0e8a 100644
--- a/drivers/pci/pcie_layerscape.c
+++ b/drivers/pci/pcie_layerscape.c
@@ -104,13 +104,13 @@ void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
}
/* Use bar match mode and MEM type as default */
-void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, int type,
- int bar, u64 phys)
+void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, int type,
+ int idx, int bar, u64 phys)
{
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, type, PCIE_ATU_CR1);
+ dbi_writel(pcie, type | PCIE_ATU_FUNC_NUM(pf), PCIE_ATU_CR1);
dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2);
}
diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h
index 217dcda..dabfff3 100644
--- a/drivers/pci/pcie_layerscape.h
+++ b/drivers/pci/pcie_layerscape.h
@@ -9,6 +9,7 @@
#define _PCIE_LAYERSCAPE_H_
#include <pci.h>
#include <dm.h>
+#include <linux/sizes.h>
#ifndef CONFIG_SYS_PCI_MEMORY_BUS
#define CONFIG_SYS_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE
@@ -44,6 +45,7 @@
#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)
@@ -86,11 +88,16 @@
#define FSL_PCIE_EP_MIN_APERTURE 4096 /* 4 Kbytes */
#define PCIE_PF_NUM 2
#define PCIE_VF_NUM 64
+#define BAR_NUM 4
-#define PCIE_BAR0_SIZE (4 * 1024) /* 4K */
-#define PCIE_BAR1_SIZE (8 * 1024) /* 8K for MSIX */
-#define PCIE_BAR2_SIZE (4 * 1024) /* 4K */
-#define PCIE_BAR4_SIZE (1 * 1024 * 1024) /* 1M */
+#define PCIE_BAR0_SIZE SZ_4K
+#define PCIE_BAR1_SIZE SZ_8K
+#define PCIE_BAR2_SIZE SZ_4K
+#define PCIE_BAR4_SIZE SZ_1M
+
+#define PCIE_SRIOV_VFBAR0 0x19C
+
+#define PCIE_MASK_OFFSET(flag, pf) ((flag) ? 0 : (0x1000 + 0x20000 * (pf)))
/* LUT registers */
#define PCIE_LUT_UDR(n) (0x800 + (n) * 8)
@@ -158,6 +165,8 @@ struct ls_pcie_ep {
struct ls_pcie *pcie;
struct udevice *bus;
void __iomem *addr;
+ u32 cfg2_flag;
+ u32 sriov_flag;
u32 num_ib_wins;
u32 num_ob_wins;
u8 max_functions;
@@ -171,8 +180,8 @@ unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset);
void ctrl_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset);
void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
u64 phys, u64 bus_addr, pci_size_t size);
-void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, int type,
- int bar, u64 phys);
+void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, int type,
+ int idx, int bar, u64 phys);
void ls_pcie_dump_atu(struct ls_pcie *pcie);
int ls_pcie_link_up(struct ls_pcie *pcie);
void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie);
diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c
index 8d0c99a..bec374b 100644
--- a/drivers/pci/pcie_layerscape_ep.c
+++ b/drivers/pci/pcie_layerscape_ep.c
@@ -45,7 +45,7 @@ static int ls_ep_set_bar(struct udevice *dev, uint fn, struct pci_bar *ep_bar)
else
type = PCIE_ATU_TYPE_IO;
- ls_pcie_atu_inbound_set(pcie, idx, bar, bar_phys, type);
+ ls_pcie_atu_inbound_set(pcie, fn, type, idx, bar, bar_phys);
dbi_writel(pcie, lower_32_bits(size - 1), reg + PCIE_NO_SRIOV_BAR_BASE);
dbi_writel(pcie, flags, reg);
@@ -63,51 +63,61 @@ static struct pci_ep_ops ls_pcie_ep_ops = {
.set_bar = ls_ep_set_bar,
};
-static void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep)
+static void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep, u32 pf)
{
struct ls_pcie *pcie = pcie_ep->pcie;
- u64 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE;
+ u64 phys = 0;
+ 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, PCIE_ATU_TYPE_MEM, 0, phys);
+ ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
+ 0 + pf * BAR_NUM, 0, phys);
/* ATU 1 : INBOUND : map BAR1 */
- phys += PCIE_BAR1_SIZE;
- ls_pcie_atu_inbound_set(pcie, 1, PCIE_ATU_TYPE_MEM, 1, phys);
+ phys = ALIGN(phys + PCIE_BAR0_SIZE, PCIE_BAR1_SIZE);
+ ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
+ 1 + pf * BAR_NUM, 1, phys);
/* ATU 2 : INBOUND : map BAR2 */
- phys += PCIE_BAR2_SIZE;
- ls_pcie_atu_inbound_set(pcie, 2, PCIE_ATU_TYPE_MEM, 2, phys);
- /* ATU 3 : INBOUND : map BAR4 */
- phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR4_SIZE;
- ls_pcie_atu_inbound_set(pcie, 3, PCIE_ATU_TYPE_MEM, 4, phys);
-
- /* ATU 0 : OUTBOUND : map MEM */
- ls_pcie_atu_outbound_set(pcie, 0,
- PCIE_ATU_TYPE_MEM,
- pcie_ep->addr_res.start,
- 0,
- CONFIG_SYS_PCI_MEMORY_SIZE);
+ phys = ALIGN(phys + PCIE_BAR1_SIZE, PCIE_BAR2_SIZE);
+ ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
+ 2 + pf * BAR_NUM, 2, phys);
+ /* ATU 3 : INBOUND : map BAR2 */
+ phys = ALIGN(phys + PCIE_BAR2_SIZE, PCIE_BAR4_SIZE);
+ ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
+ 3 + pf * BAR_NUM, 4, phys);
+
+ /* ATU: OUTBOUND : map MEM */
+ ls_pcie_atu_outbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
+ (u64)pcie_ep->addr_res.start +
+ pf * CONFIG_SYS_PCI_MEMORY_SIZE,
+ 0, CONFIG_SYS_PCI_MEMORY_SIZE);
}
/* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */
static void ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size)
{
+ u32 mask;
+
/* The least inbound window is 4KiB */
- if (size < 4 * 1024)
- return;
+ if (size < SZ_4K)
+ mask = 0;
+ else
+ mask = size - 1;
switch (bar) {
case 0:
- writel(size - 1, bar_base + PCI_BASE_ADDRESS_0);
+ writel(mask, bar_base + PCI_BASE_ADDRESS_0);
break;
case 1:
- writel(size - 1, bar_base + PCI_BASE_ADDRESS_1);
+ writel(mask, bar_base + PCI_BASE_ADDRESS_1);
break;
case 2:
- writel(size - 1, bar_base + PCI_BASE_ADDRESS_2);
+ writel(mask, bar_base + PCI_BASE_ADDRESS_2);
writel(0, bar_base + PCI_BASE_ADDRESS_3);
break;
case 4:
- writel(size - 1, bar_base + PCI_BASE_ADDRESS_4);
+ writel(mask, bar_base + PCI_BASE_ADDRESS_4);
writel(0, bar_base + PCI_BASE_ADDRESS_5);
break;
default:
@@ -117,39 +127,62 @@ static void ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size)
static void ls_pcie_ep_setup_bars(void *bar_base)
{
- /* BAR0 - 32bit - 4K configuration */
+ /* BAR0 - 32bit - MEM */
+ ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
+ /* BAR1 - 32bit - MEM*/
+ ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
+ /* BAR2 - 64bit - MEM */
+ ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
+ /* BAR4 - 64bit - MEM */
+ ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE);
+}
+
+static void ls_pcie_ep_setup_vf_bars(void *bar_base)
+{
+ /* VF BAR0 MASK register@offset 0x19c*/
+ bar_base += PCIE_SRIOV_VFBAR0 - PCI_BASE_ADDRESS_0;
+
+ /* VF-BAR0 - 32bit - MEM */
ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
- /* BAR1 - 32bit - 8K MSIX */
+ /* VF-BAR1 - 32bit - MEM*/
ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
- /* BAR2 - 64bit - 4K MEM descriptor */
+ /* VF-BAR2 - 64bit - MEM */
ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
- /* BAR4 - 64bit - 1M MEM */
+ /* VF-BAR4 - 64bit - MEM */
ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE);
}
static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep)
{
u32 sriov;
+ u32 pf, vf;
+ void *bar_base = NULL;
struct ls_pcie *pcie = pcie_ep->pcie;
sriov = readl(pcie->dbi + PCIE_SRIOV);
if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) {
- int pf, vf;
-
+ pcie_ep->sriov_flag = 1;
for (pf = 0; pf < PCIE_PF_NUM; pf++) {
- for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
- ctrl_writel(pcie, PCIE_LCTRL0_VAL(pf, vf),
- PCIE_PF_VF_CTRL);
-
- ls_pcie_ep_setup_bars(pcie->dbi);
- ls_pcie_ep_setup_atu(pcie_ep);
+ if (pcie_ep->cfg2_flag) {
+ for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
+ ctrl_writel(pcie,
+ PCIE_LCTRL0_VAL(pf, vf),
+ PCIE_PF_VF_CTRL);
+ }
}
+ bar_base = pcie->dbi +
+ PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf);
+ ls_pcie_ep_setup_bars(bar_base);
+ ls_pcie_ep_setup_vf_bars(bar_base);
+
+ ls_pcie_ep_setup_atu(pcie_ep, pf);
}
- /* Disable CFG2 */
- ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL);
+
+ if (pcie_ep->cfg2_flag) /* Disable CFG2 */
+ ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL);
} else {
ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE);
- ls_pcie_ep_setup_atu(pcie_ep);
+ ls_pcie_ep_setup_atu(pcie_ep, 0);
}
ls_pcie_ep_enable_cfg(pcie_ep);
@@ -161,6 +194,7 @@ static int ls_pcie_ep_probe(struct udevice *dev)
struct ls_pcie *pcie;
u16 link_sta;
int ret;
+ u32 svr;
pcie = devm_kmalloc(dev, sizeof(*pcie), GFP_KERNEL);
if (!pcie)
@@ -190,6 +224,13 @@ static int ls_pcie_ep_probe(struct udevice *dev)
pcie->big_endian = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
"big-endian");
+ svr = SVR_SOC_VER(get_svr());
+
+ if (svr == SVR_LS2080A || svr == SVR_LS2085A)
+ pcie_ep->cfg2_flag = 1;
+ else
+ pcie_ep->cfg2_flag = 0;
+
pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f;
if (pcie->mode != PCI_HEADER_TYPE_NORMAL)
return 0;
--
2.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5/9] pci_ep: layerscape: Add the workaround for errata A-009460
2020-03-22 11:12 [PATCH 1/9] pci: layerscape: Split the EP and RC driver Xiaowei Bao
` (2 preceding siblings ...)
2020-03-22 11:12 ` [PATCH 4/9] PCI_EP: layerscape: Add the multiple function supprot Xiaowei Bao
@ 2020-03-22 11:12 ` Xiaowei Bao
2020-04-28 12:25 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 6/9] pci_ep: layerscape: Add Support for ls2085a and ls2080a EP mode Xiaowei Bao
` (5 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Xiaowei Bao @ 2020-03-22 11:12 UTC (permalink / raw)
To: u-boot
The VF_BARn_REG register's Prefetchable and Type bit fields
are overwritten by a write to VF's BAR Mask register.
workaround: Before writing to the VF_BARn_MASK_REG register,
write 0b to the PCIE_MISC_CONTROL_1_OFF register.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
drivers/pci/pcie_layerscape_ep.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c
index bec374b..a2b18ad 100644
--- a/drivers/pci/pcie_layerscape_ep.c
+++ b/drivers/pci/pcie_layerscape_ep.c
@@ -163,6 +163,15 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep)
if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) {
pcie_ep->sriov_flag = 1;
for (pf = 0; pf < PCIE_PF_NUM; pf++) {
+ /*
+ * The VF_BARn_REG register's Prefetchable and Type bit
+ * fields are overwritten by a write to VF's BAR Mask
+ * register. Before writing to the VF_BARn_MASK_REG
+ * register, write 0b to the PCIE_MISC_CONTROL_1_OFF
+ * register.
+ */
+ writel(0, pcie->dbi + PCIE_MISC_CONTROL_1_OFF);
+
if (pcie_ep->cfg2_flag) {
for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
ctrl_writel(pcie,
--
2.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 6/9] pci_ep: layerscape: Add Support for ls2085a and ls2080a EP mode
2020-03-22 11:12 [PATCH 1/9] pci: layerscape: Split the EP and RC driver Xiaowei Bao
` (3 preceding siblings ...)
2020-03-22 11:12 ` [PATCH 5/9] pci_ep: layerscape: Add the workaround for errata A-009460 Xiaowei Bao
@ 2020-03-22 11:12 ` Xiaowei Bao
2020-04-28 12:25 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 7/9] pci_ep: layerscape: Add the SRIOV VFs of PF support Xiaowei Bao
` (4 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Xiaowei Bao @ 2020-03-22 11:12 UTC (permalink / raw)
To: u-boot
Due to the ls2085a and ls2080a use difference way to set the BAR size,
so add the BAR size init code here.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
drivers/pci/pcie_layerscape_ep.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c
index a2b18ad..cd7ea26 100644
--- a/drivers/pci/pcie_layerscape_ep.c
+++ b/drivers/pci/pcie_layerscape_ep.c
@@ -172,17 +172,25 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep)
*/
writel(0, pcie->dbi + PCIE_MISC_CONTROL_1_OFF);
+ bar_base = pcie->dbi +
+ PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf);
+
if (pcie_ep->cfg2_flag) {
- for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
+ ctrl_writel(pcie,
+ PCIE_LCTRL0_VAL(pf, 0),
+ PCIE_PF_VF_CTRL);
+ ls_pcie_ep_setup_bars(bar_base);
+
+ for (vf = 1; vf <= PCIE_VF_NUM; vf++) {
ctrl_writel(pcie,
PCIE_LCTRL0_VAL(pf, vf),
PCIE_PF_VF_CTRL);
+ ls_pcie_ep_setup_vf_bars(bar_base);
}
+ } else {
+ ls_pcie_ep_setup_bars(bar_base);
+ ls_pcie_ep_setup_vf_bars(bar_base);
}
- bar_base = pcie->dbi +
- PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf);
- ls_pcie_ep_setup_bars(bar_base);
- ls_pcie_ep_setup_vf_bars(bar_base);
ls_pcie_ep_setup_atu(pcie_ep, pf);
}
--
2.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 7/9] pci_ep: layerscape: Add the SRIOV VFs of PF support
2020-03-22 11:12 [PATCH 1/9] pci: layerscape: Split the EP and RC driver Xiaowei Bao
` (4 preceding siblings ...)
2020-03-22 11:12 ` [PATCH 6/9] pci_ep: layerscape: Add Support for ls2085a and ls2080a EP mode Xiaowei Bao
@ 2020-03-22 11:12 ` Xiaowei Bao
2020-04-28 12:26 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 8/9] pci: layerscaple: Modify the ls_pcie_dump_atu function Xiaowei Bao
` (3 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Xiaowei Bao @ 2020-03-22 11:12 UTC (permalink / raw)
To: u-boot
Add the INBOUND configuration for VFs of PF.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
drivers/pci/pcie_layerscape.c | 8 +++++---
drivers/pci/pcie_layerscape.h | 13 ++++++++-----
drivers/pci/pcie_layerscape_ep.c | 34 +++++++++++++++++++++++++++++-----
3 files changed, 42 insertions(+), 13 deletions(-)
diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
index 88a0e8a..c7a96ed 100644
--- a/drivers/pci/pcie_layerscape.c
+++ b/drivers/pci/pcie_layerscape.c
@@ -91,7 +91,7 @@ int ls_pcie_link_up(struct ls_pcie *pcie)
}
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);
@@ -104,14 +104,16 @@ void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
}
/* Use bar match mode and MEM type as default */
-void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, int type,
- int idx, int bar, u64 phys)
+void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag,
+ int type, int idx, int bar, u64 phys)
{
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, type | PCIE_ATU_FUNC_NUM(pf), PCIE_ATU_CR1);
dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
+ (vf_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);
}
diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h
index dabfff3..26d0177 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,6 +40,7 @@
#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)
@@ -49,6 +50,8 @@
#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 BIT(19)
+#define PCIE_ATU_VFBAR_MATCH_MODE_EN BIT(26)
#define PCIE_ATU_BAR_NUM(bar) ((bar) << 8)
#define PCIE_ATU_LOWER_BASE 0x90C
#define PCIE_ATU_UPPER_BASE 0x910
@@ -88,7 +91,7 @@
#define FSL_PCIE_EP_MIN_APERTURE 4096 /* 4 Kbytes */
#define PCIE_PF_NUM 2
#define PCIE_VF_NUM 64
-#define BAR_NUM 4
+#define BAR_NUM 8
#define PCIE_BAR0_SIZE SZ_4K
#define PCIE_BAR1_SIZE SZ_8K
@@ -179,9 +182,9 @@ void dbi_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset);
unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset);
void ctrl_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset);
void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
- u64 phys, u64 bus_addr, pci_size_t size);
-void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, int type,
- int idx, int bar, u64 phys);
+ u64 phys, u64 bus_addr, u64 size);
+void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag,
+ int type, int idx, int bar, u64 phys);
void ls_pcie_dump_atu(struct ls_pcie *pcie);
int ls_pcie_link_up(struct ls_pcie *pcie);
void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie);
diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c
index cd7ea26..67ce36c 100644
--- a/drivers/pci/pcie_layerscape_ep.c
+++ b/drivers/pci/pcie_layerscape_ep.c
@@ -45,7 +45,7 @@ static int ls_ep_set_bar(struct udevice *dev, uint fn, struct pci_bar *ep_bar)
else
type = PCIE_ATU_TYPE_IO;
- ls_pcie_atu_inbound_set(pcie, fn, type, idx, bar, bar_phys);
+ ls_pcie_atu_inbound_set(pcie, fn, 0, type, idx, bar, bar_phys);
dbi_writel(pcie, lower_32_bits(size - 1), reg + PCIE_NO_SRIOV_BAR_BASE);
dbi_writel(pcie, flags, reg);
@@ -66,27 +66,51 @@ static struct pci_ep_ops ls_pcie_ep_ops = {
static void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep, u32 pf)
{
struct ls_pcie *pcie = pcie_ep->pcie;
+ u32 vf_flag = 0;
u64 phys = 0;
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, pf, PCIE_ATU_TYPE_MEM,
+ ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
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, pf, PCIE_ATU_TYPE_MEM,
+ ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
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, pf, PCIE_ATU_TYPE_MEM,
+ ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
2 + pf * BAR_NUM, 2, phys);
/* ATU 3 : INBOUND : map BAR2 */
phys = ALIGN(phys + PCIE_BAR2_SIZE, PCIE_BAR4_SIZE);
- ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
+ ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
3 + pf * BAR_NUM, 4, phys);
+ if (pcie_ep->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, PCIE_ATU_TYPE_MEM,
+ 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, PCIE_ATU_TYPE_MEM,
+ 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, PCIE_ATU_TYPE_MEM,
+ 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, PCIE_ATU_TYPE_MEM,
+ 7 + pf * BAR_NUM, 4, phys);
+ }
+
/* ATU: OUTBOUND : map MEM */
ls_pcie_atu_outbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
(u64)pcie_ep->addr_res.start +
--
2.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 8/9] pci: layerscaple: Modify the ls_pcie_dump_atu function
2020-03-22 11:12 [PATCH 1/9] pci: layerscape: Split the EP and RC driver Xiaowei Bao
` (5 preceding siblings ...)
2020-03-22 11:12 ` [PATCH 7/9] pci_ep: layerscape: Add the SRIOV VFs of PF support Xiaowei Bao
@ 2020-03-22 11:12 ` Xiaowei Bao
2020-04-28 12:26 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 9/9] pci_ep: layerscape: Add the PCIe EP mode support for lx2160a-v2 Xiaowei Bao
` (2 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Xiaowei Bao @ 2020-03-22 11:12 UTC (permalink / raw)
To: u-boot
Modify the ls_pcie_dump_atu function, make it can print the INBOUND
windows registers.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
drivers/pci/pcie_layerscape.c | 25 +++++++++++++------------
drivers/pci/pcie_layerscape.h | 2 +-
drivers/pci/pcie_layerscape_ep.c | 3 +++
drivers/pci/pcie_layerscape_rc.c | 2 +-
4 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
index c7a96ed..4015a0d 100644
--- a/drivers/pci/pcie_layerscape.c
+++ b/drivers/pci/pcie_layerscape.c
@@ -117,24 +117,25 @@ void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag,
PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2);
}
-void ls_pcie_dump_atu(struct ls_pcie *pcie)
+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",
dbi_readl(pcie, PCIE_ATU_UPPER_BASE));
- debug("\tLOWER BUS 0x%08x\n",
- dbi_readl(pcie, PCIE_ATU_LOWER_TARGET));
- debug("\tUPPER BUS 0x%08x\n",
- dbi_readl(pcie, PCIE_ATU_UPPER_TARGET));
- debug("\tLIMIT 0x%08x\n",
- dbi_readl(pcie, PCIE_ATU_LIMIT));
+ if (type == PCIE_ATU_REGION_OUTBOUND) {
+ debug("\tLOWER BUS 0x%08x\n",
+ dbi_readl(pcie, PCIE_ATU_LOWER_TARGET));
+ debug("\tUPPER BUS 0x%08x\n",
+ dbi_readl(pcie, PCIE_ATU_UPPER_TARGET));
+ debug("\tLIMIT 0x%08x\n",
+ dbi_readl(pcie, PCIE_ATU_LIMIT));
+ }
debug("\tCR1 0x%08x\n",
dbi_readl(pcie, PCIE_ATU_CR1));
debug("\tCR2 0x%08x\n",
diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h
index 26d0177..5f5c51d 100644
--- a/drivers/pci/pcie_layerscape.h
+++ b/drivers/pci/pcie_layerscape.h
@@ -185,7 +185,7 @@ void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
u64 phys, u64 bus_addr, u64 size);
void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag,
int type, int idx, int bar, u64 phys);
-void ls_pcie_dump_atu(struct ls_pcie *pcie);
+void ls_pcie_dump_atu(struct ls_pcie *pcie, u32 win_num, u32 type);
int ls_pcie_link_up(struct ls_pcie *pcie);
void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie);
void ls_pcie_dbi_ro_wr_dis(struct ls_pcie *pcie);
diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c
index 67ce36c..ebf69ee 100644
--- a/drivers/pci/pcie_layerscape_ep.c
+++ b/drivers/pci/pcie_layerscape_ep.c
@@ -226,6 +226,9 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep)
ls_pcie_ep_setup_atu(pcie_ep, 0);
}
+ ls_pcie_dump_atu(pcie, PCIE_ATU_REGION_NUM_SRIOV,
+ PCIE_ATU_REGION_INBOUND);
+
ls_pcie_ep_enable_cfg(pcie_ep);
}
diff --git a/drivers/pci/pcie_layerscape_rc.c b/drivers/pci/pcie_layerscape_rc.c
index 927722d..b045159 100644
--- a/drivers/pci/pcie_layerscape_rc.c
+++ b/drivers/pci/pcie_layerscape_rc.c
@@ -114,7 +114,7 @@ static void ls_pcie_setup_atu(struct ls_pcie_rc *pcie_rc)
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 */
--
2.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 9/9] pci_ep: layerscape: Add the PCIe EP mode support for lx2160a-v2
2020-03-22 11:12 [PATCH 1/9] pci: layerscape: Split the EP and RC driver Xiaowei Bao
` (6 preceding siblings ...)
2020-03-22 11:12 ` [PATCH 8/9] pci: layerscaple: Modify the ls_pcie_dump_atu function Xiaowei Bao
@ 2020-03-22 11:12 ` Xiaowei Bao
2020-04-28 12:26 ` Z.q. Hou
2020-04-28 9:30 ` [PATCH 1/9] pci: layerscape: Split the EP and RC driver Priyanka Jain
2020-04-28 12:23 ` Z.q. Hou
9 siblings, 1 reply; 19+ messages in thread
From: Xiaowei Bao @ 2020-03-22 11:12 UTC (permalink / raw)
To: u-boot
Add the PCIe EP mode support for lx2160a-v2 platform.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
drivers/pci/pcie_layerscape.h | 9 ++++++++-
drivers/pci/pcie_layerscape_ep.c | 8 +++++++-
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h
index 5f5c51d..593798e 100644
--- a/drivers/pci/pcie_layerscape.h
+++ b/drivers/pci/pcie_layerscape.h
@@ -100,7 +100,7 @@
#define PCIE_SRIOV_VFBAR0 0x19C
-#define PCIE_MASK_OFFSET(flag, pf) ((flag) ? 0 : (0x1000 + 0x20000 * (pf)))
+#define PCIE_MASK_OFFSET(flag, pf, off) ((flag) ? 0 : (0x1000 + (off) * (pf)))
/* LUT registers */
#define PCIE_LUT_UDR(n) (0x800 + (n) * 8)
@@ -139,6 +139,12 @@
#define LS1021_PEXMSCPORTSR(pex_idx) (0x94 + (pex_idx) * 4)
#define LS1021_LTSSM_STATE_SHIFT 20
+/* LX2160a PF1 offset */
+#define LX2160_PCIE_PF1_OFFSET 0x8000
+
+/* layerscape PF1 offset */
+#define LS_PCIE_PF1_OFFSET 0x20000
+
struct ls_pcie {
void __iomem *dbi;
void __iomem *lut;
@@ -170,6 +176,7 @@ struct ls_pcie_ep {
void __iomem *addr;
u32 cfg2_flag;
u32 sriov_flag;
+ u32 pf1_offset;
u32 num_ib_wins;
u32 num_ob_wins;
u8 max_functions;
diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c
index ebf69ee..0228863 100644
--- a/drivers/pci/pcie_layerscape_ep.c
+++ b/drivers/pci/pcie_layerscape_ep.c
@@ -197,7 +197,8 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep)
writel(0, pcie->dbi + PCIE_MISC_CONTROL_1_OFF);
bar_base = pcie->dbi +
- PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf);
+ PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf,
+ pcie_ep->pf1_offset);
if (pcie_ep->cfg2_flag) {
ctrl_writel(pcie,
@@ -270,6 +271,11 @@ static int ls_pcie_ep_probe(struct udevice *dev)
svr = SVR_SOC_VER(get_svr());
+ if (svr == SVR_LX2160A)
+ pcie_ep->pf1_offset = LX2160_PCIE_PF1_OFFSET;
+ else
+ pcie_ep->pf1_offset = LS_PCIE_PF1_OFFSET;
+
if (svr == SVR_LS2080A || svr == SVR_LS2085A)
pcie_ep->cfg2_flag = 1;
else
--
2.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 1/9] pci: layerscape: Split the EP and RC driver
2020-03-22 11:12 [PATCH 1/9] pci: layerscape: Split the EP and RC driver Xiaowei Bao
` (7 preceding siblings ...)
2020-03-22 11:12 ` [PATCH 9/9] pci_ep: layerscape: Add the PCIe EP mode support for lx2160a-v2 Xiaowei Bao
@ 2020-04-28 9:30 ` Priyanka Jain
2020-04-28 12:23 ` Z.q. Hou
9 siblings, 0 replies; 19+ messages in thread
From: Priyanka Jain @ 2020-04-28 9:30 UTC (permalink / raw)
To: u-boot
>-----Original Message-----
>From: U-Boot <u-boot-bounces@lists.denx.de> On Behalf Of Xiaowei Bao
>Sent: Sunday, March 22, 2020 4:43 PM
>To: M.h. Lian <minghuan.lian@nxp.com>; Z.q. Hou <zhiqiang.hou@nxp.com>;
>Mingkai Hu <mingkai.hu@nxp.com>; bmeng.cn at gmail.com;
>yamada.masahiro at socionext.com; u-boot at lists.denx.de
>Cc: Xiaowei Bao <xiaowei.bao@nxp.com>
>Subject: [PATCH 1/9] pci: layerscape: Split the EP and RC driver
>
>Split the RC and EP driver, and reimplement the EP driver base on the EP
>framework.
>
>Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
>---
> drivers/pci/Makefile | 2 +-
> drivers/pci/pcie_layerscape.c | 492 +++---------------------------------
> drivers/pci/pcie_layerscape.h | 44 +++-
> drivers/pci/pcie_layerscape_ep.c | 240 ++++++++++++++++++
> drivers/pci/pcie_layerscape_fixup.c | 79 +++---
> drivers/pci/pcie_layerscape_rc.c | 378 +++++++++++++++++++++++++++
> 6 files changed, 734 insertions(+), 501 deletions(-) create mode 100644
>drivers/pci/pcie_layerscape_ep.c create mode 100644
>drivers/pci/pcie_layerscape_rc.c
>
Kindly rebase the series on top of tree
Thanks
Priyanka
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/9] pci: layerscape: Split the EP and RC driver
2020-03-22 11:12 [PATCH 1/9] pci: layerscape: Split the EP and RC driver Xiaowei Bao
` (8 preceding siblings ...)
2020-04-28 9:30 ` [PATCH 1/9] pci: layerscape: Split the EP and RC driver Priyanka Jain
@ 2020-04-28 12:23 ` Z.q. Hou
9 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2020-04-28 12:23 UTC (permalink / raw)
To: u-boot
> -----Original Message-----
> From: Xiaowei Bao <xiaowei.bao@nxp.com>
> Sent: 2020?3?22? 19:13
> To: M.h. Lian <minghuan.lian@nxp.com>; Z.q. Hou
> <zhiqiang.hou@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
> bmeng.cn at gmail.com; yamada.masahiro at socionext.com;
> u-boot at lists.denx.de
> Cc: Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: [PATCH 1/9] pci: layerscape: Split the EP and RC driver
>
> Split the RC and EP driver, and reimplement the EP driver base on the EP
> framework.
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> drivers/pci/Makefile | 2 +-
> drivers/pci/pcie_layerscape.c | 492 +++---------------------------------
> drivers/pci/pcie_layerscape.h | 44 +++-
> drivers/pci/pcie_layerscape_ep.c | 240 ++++++++++++++++++
> drivers/pci/pcie_layerscape_fixup.c | 79 +++---
> drivers/pci/pcie_layerscape_rc.c | 378
> +++++++++++++++++++++++++++
> 6 files changed, 734 insertions(+), 501 deletions(-) create mode 100644
> drivers/pci/pcie_layerscape_ep.c create mode 100644
> drivers/pci/pcie_layerscape_rc.c
>
> diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index
> c051ecc..440b5af 100644
> --- a/drivers/pci/Makefile
> +++ b/drivers/pci/Makefile
> @@ -33,7 +33,7 @@ obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o
> obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
> obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o
> obj-$(CONFIG_PCIE_FSL) += pcie_fsl.o pcie_fsl_fixup.o
> -obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o
> +obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o
> pcie_layerscape_rc.o
> +pcie_layerscape_ep.o
> obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o
> pcie_layerscape_fixup_common.o
> obj-$(CONFIG_PCIE_LAYERSCAPE_GEN4) += pcie_layerscape_gen4.o \
> pcie_layerscape_gen4_fixup.o \
> diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
> index 2ab67d1..3ca75c5 100644
> --- a/drivers/pci/pcie_layerscape.c
> +++ b/drivers/pci/pcie_layerscape.c
> @@ -1,39 +1,32 @@
> // SPDX-License-Identifier: GPL-2.0+
> /*
> - * Copyright 2017-2019 NXP
> + * Copyright 2017-2020 NXP
> * Copyright 2014-2015 Freescale Semiconductor, Inc.
> * Layerscape PCIe driver
> */
>
> #include <common.h>
> -#include <asm/arch/fsl_serdes.h>
> -#include <pci.h>
> #include <asm/io.h>
> #include <errno.h>
> #include <malloc.h>
> -#include <dm.h>
> -#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
> - defined(CONFIG_ARM)
> -#include <asm/arch/clock.h>
> -#endif
> #include "pcie_layerscape.h"
>
> DECLARE_GLOBAL_DATA_PTR;
>
> LIST_HEAD(ls_pcie_list);
>
> -static unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset)
> +unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset)
> {
> return in_le32(pcie->dbi + offset);
> }
>
> -static void dbi_writel(struct ls_pcie *pcie, unsigned int value,
> - unsigned int offset)
> +void dbi_writel(struct ls_pcie *pcie, unsigned int value,
> + unsigned int offset)
> {
> out_le32(pcie->dbi + offset, value);
> }
>
> -static unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset)
> +unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset)
> {
> if (pcie->big_endian)
> return in_be32(pcie->ctrl + offset);
> @@ -41,8 +34,8 @@ static unsigned int ctrl_readl(struct ls_pcie *pcie,
> unsigned int offset)
> return in_le32(pcie->ctrl + offset);
> }
>
> -static void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
> - unsigned int offset)
> +void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
> + unsigned int offset)
> {
> if (pcie->big_endian)
> out_be32(pcie->ctrl + offset, value); @@ -50,6 +43,26 @@ static
> void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
> out_le32(pcie->ctrl + offset, value); }
>
> +void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie) {
> + u32 reg, val;
> +
> + reg = PCIE_MISC_CONTROL_1_OFF;
> + val = dbi_readl(pcie, reg);
> + val |= PCIE_DBI_RO_WR_EN;
> + dbi_writel(pcie, val, reg);
> +}
> +
> +void ls_pcie_dbi_ro_wr_dis(struct ls_pcie *pcie) {
> + u32 reg, val;
> +
> + reg = PCIE_MISC_CONTROL_1_OFF;
> + val = dbi_readl(pcie, reg);
> + val &= ~PCIE_DBI_RO_WR_EN;
> + dbi_writel(pcie, val, reg);
> +}
> +
> static int ls_pcie_ltssm(struct ls_pcie *pcie) {
> u32 state;
> @@ -66,7 +79,7 @@ static int ls_pcie_ltssm(struct ls_pcie *pcie)
> return state;
> }
>
> -static int ls_pcie_link_up(struct ls_pcie *pcie)
> +int ls_pcie_link_up(struct ls_pcie *pcie)
> {
> int ltssm;
>
> @@ -77,22 +90,8 @@ static int ls_pcie_link_up(struct ls_pcie *pcie)
> return 1;
> }
>
> -static void ls_pcie_cfg0_set_busdev(struct ls_pcie *pcie, u32 busdev) -{
> - dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND |
> PCIE_ATU_REGION_INDEX0,
> - PCIE_ATU_VIEWPORT);
> - dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET);
> -}
> -
> -static void ls_pcie_cfg1_set_busdev(struct ls_pcie *pcie, u32 busdev) -{
> - dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND |
> PCIE_ATU_REGION_INDEX1,
> - PCIE_ATU_VIEWPORT);
> - dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET);
> -}
> -
> -static void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
> - u64 phys, u64 bus_addr, pci_size_t size)
> +void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
> + u64 phys, u64 bus_addr, pci_size_t size)
> {
> dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | idx,
> PCIE_ATU_VIEWPORT);
> dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_BASE); @@ -105,18
> +104,18 @@ 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)
> +void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, int type,
> + int bar, u64 phys)
> {
> 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, PCIE_ATU_CR1);
> + dbi_writel(pcie, type, PCIE_ATU_CR1);
> dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
> PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2); }
>
> -static void ls_pcie_dump_atu(struct ls_pcie *pcie)
> +void ls_pcie_dump_atu(struct ls_pcie *pcie)
> {
> int i;
>
> @@ -133,431 +132,10 @@ static void ls_pcie_dump_atu(struct ls_pcie
> *pcie)
> debug("\tUPPER BUS 0x%08x\n",
> dbi_readl(pcie, PCIE_ATU_UPPER_TARGET));
> debug("\tLIMIT 0x%08x\n",
> - readl(pcie->dbi + PCIE_ATU_LIMIT));
> + dbi_readl(pcie, PCIE_ATU_LIMIT));
> debug("\tCR1 0x%08x\n",
> dbi_readl(pcie, PCIE_ATU_CR1));
> debug("\tCR2 0x%08x\n",
> dbi_readl(pcie, PCIE_ATU_CR2));
> }
> }
> -
> -static void ls_pcie_setup_atu(struct ls_pcie *pcie) -{
> - struct pci_region *io, *mem, *pref;
> - unsigned long long offset = 0;
> - int idx = 0;
> - uint svr;
> -
> - svr = get_svr();
> - if (((svr >> SVR_VAR_PER_SHIFT) & SVR_LS102XA_MASK) ==
> SVR_LS102XA) {
> - offset = LS1021_PCIE_SPACE_OFFSET +
> - LS1021_PCIE_SPACE_SIZE * pcie->idx;
> - }
> -
> - /* ATU 0 : OUTBOUND : CFG0 */
> - ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
> - PCIE_ATU_TYPE_CFG0,
> - pcie->cfg_res.start + offset,
> - 0,
> - fdt_resource_size(&pcie->cfg_res) / 2);
> - /* ATU 1 : OUTBOUND : CFG1 */
> - ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1,
> - PCIE_ATU_TYPE_CFG1,
> - pcie->cfg_res.start + offset +
> - fdt_resource_size(&pcie->cfg_res) / 2,
> - 0,
> - fdt_resource_size(&pcie->cfg_res) / 2);
> -
> - 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 ||
> - svr == SVR_LS2081A || svr == SVR_LS2041A) {
> - 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++,
> - PCIE_ATU_TYPE_IO,
> - io->phys_start + offset,
> - io->bus_start,
> - io->size);
> -
> - if (mem)
> - /* ATU : OUTBOUND : MEM */
> - ls_pcie_atu_outbound_set(pcie, idx++,
> - PCIE_ATU_TYPE_MEM,
> - mem->phys_start + offset,
> - mem->bus_start,
> - mem->size);
> -
> - if (pref)
> - /* ATU : OUTBOUND : pref */
> - ls_pcie_atu_outbound_set(pcie, idx++,
> - PCIE_ATU_TYPE_MEM,
> - pref->phys_start + offset,
> - pref->bus_start,
> - pref->size);
> -
> - ls_pcie_dump_atu(pcie);
> -}
> -
> -/* Return 0 if the address is valid, -errno if not valid */ -static int
> ls_pcie_addr_valid(struct ls_pcie *pcie, pci_dev_t bdf) -{
> - struct udevice *bus = pcie->bus;
> -
> - if (pcie->mode == PCI_HEADER_TYPE_NORMAL)
> - return -ENODEV;
> -
> - if (!pcie->enabled)
> - return -ENXIO;
> -
> - if (PCI_BUS(bdf) < bus->seq)
> - return -EINVAL;
> -
> - if ((PCI_BUS(bdf) > bus->seq) && (!ls_pcie_link_up(pcie)))
> - return -EINVAL;
> -
> - if (PCI_BUS(bdf) <= (bus->seq + 1) && (PCI_DEV(bdf) > 0))
> - return -EINVAL;
> -
> - return 0;
> -}
> -
> -int ls_pcie_conf_address(struct udevice *bus, pci_dev_t bdf,
> - uint offset, void **paddress)
> -{
> - struct ls_pcie *pcie = dev_get_priv(bus);
> - u32 busdev;
> -
> - if (ls_pcie_addr_valid(pcie, bdf))
> - return -EINVAL;
> -
> - if (PCI_BUS(bdf) == bus->seq) {
> - *paddress = pcie->dbi + offset;
> - return 0;
> - }
> -
> - busdev = PCIE_ATU_BUS(PCI_BUS(bdf) - bus->seq) |
> - PCIE_ATU_DEV(PCI_DEV(bdf)) |
> - PCIE_ATU_FUNC(PCI_FUNC(bdf));
> -
> - if (PCI_BUS(bdf) == bus->seq + 1) {
> - ls_pcie_cfg0_set_busdev(pcie, busdev);
> - *paddress = pcie->cfg0 + offset;
> - } else {
> - ls_pcie_cfg1_set_busdev(pcie, busdev);
> - *paddress = pcie->cfg1 + offset;
> - }
> - return 0;
> -}
> -
> -static int ls_pcie_read_config(struct udevice *bus, pci_dev_t bdf,
> - uint offset, ulong *valuep,
> - enum pci_size_t size)
> -{
> - return pci_generic_mmap_read_config(bus, ls_pcie_conf_address,
> - bdf, offset, valuep, size);
> -}
> -
> -static int ls_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
> - uint offset, ulong value,
> - enum pci_size_t size)
> -{
> - return pci_generic_mmap_write_config(bus, ls_pcie_conf_address,
> - bdf, offset, value, size);
> -}
> -
> -/* Clear multi-function bit */
> -static void ls_pcie_clear_multifunction(struct ls_pcie *pcie) -{
> - writeb(PCI_HEADER_TYPE_BRIDGE, pcie->dbi + PCI_HEADER_TYPE);
> -}
> -
> -/* Fix class value */
> -static void ls_pcie_fix_class(struct ls_pcie *pcie) -{
> - writew(PCI_CLASS_BRIDGE_PCI, pcie->dbi + PCI_CLASS_DEVICE);
> -}
> -
> -/* Drop MSG TLP except for Vendor MSG */ -static void
> ls_pcie_drop_msg_tlp(struct ls_pcie *pcie) -{
> - u32 val;
> -
> - val = dbi_readl(pcie, PCIE_STRFMR1);
> - val &= 0xDFFFFFFF;
> - dbi_writel(pcie, val, PCIE_STRFMR1);
> -}
> -
> -/* Disable all bars in RC mode */
> -static void ls_pcie_disable_bars(struct ls_pcie *pcie) -{
> - dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_0);
> - dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_1);
> - dbi_writel(pcie, 0xfffffffe, PCIE_CS2_OFFSET + PCI_ROM_ADDRESS1);
> -}
> -
> -static void ls_pcie_setup_ctrl(struct ls_pcie *pcie) -{
> - ls_pcie_setup_atu(pcie);
> -
> - dbi_writel(pcie, 1, PCIE_DBI_RO_WR_EN);
> - ls_pcie_fix_class(pcie);
> - ls_pcie_clear_multifunction(pcie);
> - ls_pcie_drop_msg_tlp(pcie);
> - dbi_writel(pcie, 0, PCIE_DBI_RO_WR_EN);
> -
> - ls_pcie_disable_bars(pcie);
> - pcie->stream_id_cur = 0;
> -}
> -
> -static void ls_pcie_ep_setup_atu(struct ls_pcie *pcie) -{
> - u64 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE;
> -
> - /* ATU 0 : INBOUND : map BAR0 */
> - ls_pcie_atu_inbound_set(pcie, 0, 0, phys);
> - /* ATU 1 : INBOUND : map BAR1 */
> - phys += PCIE_BAR1_SIZE;
> - ls_pcie_atu_inbound_set(pcie, 1, 1, phys);
> - /* ATU 2 : INBOUND : map BAR2 */
> - phys += PCIE_BAR2_SIZE;
> - ls_pcie_atu_inbound_set(pcie, 2, 2, phys);
> - /* ATU 3 : INBOUND : map BAR4 */
> - phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR4_SIZE;
> - ls_pcie_atu_inbound_set(pcie, 3, 4, phys);
> -
> - /* ATU 0 : OUTBOUND : map MEM */
> - ls_pcie_atu_outbound_set(pcie, 0,
> - PCIE_ATU_TYPE_MEM,
> - pcie->cfg_res.start,
> - 0,
> - CONFIG_SYS_PCI_MEMORY_SIZE);
> -}
> -
> -/* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */ -static void
> ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size) -{
> - /* The least inbound window is 4KiB */
> - if (size < 4 * 1024)
> - return;
> -
> - switch (bar) {
> - case 0:
> - writel(size - 1, bar_base + PCI_BASE_ADDRESS_0);
> - break;
> - case 1:
> - writel(size - 1, bar_base + PCI_BASE_ADDRESS_1);
> - break;
> - case 2:
> - writel(size - 1, bar_base + PCI_BASE_ADDRESS_2);
> - writel(0, bar_base + PCI_BASE_ADDRESS_3);
> - break;
> - case 4:
> - writel(size - 1, bar_base + PCI_BASE_ADDRESS_4);
> - writel(0, bar_base + PCI_BASE_ADDRESS_5);
> - break;
> - default:
> - break;
> - }
> -}
> -
> -static void ls_pcie_ep_setup_bars(void *bar_base) -{
> - /* BAR0 - 32bit - 4K configuration */
> - ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
> - /* BAR1 - 32bit - 8K MSIX*/
> - ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
> - /* BAR2 - 64bit - 4K MEM desciptor */
> - ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
> - /* BAR4 - 64bit - 1M MEM*/
> - ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE);
> -}
> -
> -static void ls_pcie_ep_enable_cfg(struct ls_pcie *pcie) -{
> - u32 config;
> -
> - config = ctrl_readl(pcie, PCIE_PF_CONFIG);
> - config |= PCIE_CONFIG_READY;
> - ctrl_writel(pcie, config, PCIE_PF_CONFIG);
> -}
> -
> -static void ls_pcie_setup_ep(struct ls_pcie *pcie) -{
> - u32 sriov;
> -
> - sriov = readl(pcie->dbi + PCIE_SRIOV);
> - if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) {
> - int pf, vf;
> -
> - for (pf = 0; pf < PCIE_PF_NUM; pf++) {
> - for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
> - ctrl_writel(pcie, PCIE_LCTRL0_VAL(pf, vf),
> - PCIE_PF_VF_CTRL);
> -
> - ls_pcie_ep_setup_bars(pcie->dbi);
> - ls_pcie_ep_setup_atu(pcie);
> - }
> - }
> - /* Disable CFG2 */
> - ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL);
> - } else {
> - ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE);
> - ls_pcie_ep_setup_atu(pcie);
> - }
> -
> - ls_pcie_ep_enable_cfg(pcie);
> -}
> -
> -static int ls_pcie_probe(struct udevice *dev) -{
> - struct ls_pcie *pcie = dev_get_priv(dev);
> - const void *fdt = gd->fdt_blob;
> - int node = dev_of_offset(dev);
> - u16 link_sta;
> - uint svr;
> - int ret;
> - fdt_size_t cfg_size;
> -
> - pcie->bus = dev;
> -
> - ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
> - "dbi", &pcie->dbi_res);
> - if (ret) {
> - printf("ls-pcie: resource \"dbi\" not found\n");
> - return ret;
> - }
> -
> - pcie->idx = (pcie->dbi_res.start - PCIE_SYS_BASE_ADDR) /
> PCIE_CCSR_SIZE;
> -
> - list_add(&pcie->list, &ls_pcie_list);
> -
> - pcie->enabled = is_serdes_configured(PCIE_SRDS_PRTCL(pcie->idx));
> - if (!pcie->enabled) {
> - printf("PCIe%d: %s disabled\n", pcie->idx, dev->name);
> - return 0;
> - }
> -
> - pcie->dbi = map_physmem(pcie->dbi_res.start,
> - fdt_resource_size(&pcie->dbi_res),
> - MAP_NOCACHE);
> -
> - ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
> - "lut", &pcie->lut_res);
> - if (!ret)
> - pcie->lut = map_physmem(pcie->lut_res.start,
> - fdt_resource_size(&pcie->lut_res),
> - MAP_NOCACHE);
> -
> - ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
> - "ctrl", &pcie->ctrl_res);
> - if (!ret)
> - pcie->ctrl = map_physmem(pcie->ctrl_res.start,
> - fdt_resource_size(&pcie->ctrl_res),
> - MAP_NOCACHE);
> - if (!pcie->ctrl)
> - pcie->ctrl = pcie->lut;
> -
> - if (!pcie->ctrl) {
> - printf("%s: NOT find CTRL\n", dev->name);
> - return -1;
> - }
> -
> - ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
> - "config", &pcie->cfg_res);
> - if (ret) {
> - printf("%s: resource \"config\" not found\n", dev->name);
> - 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 ||
> - svr == SVR_LS2081A || svr == SVR_LS2041A) {
> - cfg_size = fdt_resource_size(&pcie->cfg_res);
> - pcie->cfg_res.start = LS2088A_PCIE1_PHYS_ADDR +
> - LS2088A_PCIE_PHYS_SIZE * pcie->idx;
> - pcie->cfg_res.end = pcie->cfg_res.start + cfg_size;
> - pcie->ctrl = pcie->lut + 0x40000;
> - }
> -
> - pcie->cfg0 = map_physmem(pcie->cfg_res.start,
> - fdt_resource_size(&pcie->cfg_res),
> - MAP_NOCACHE);
> - pcie->cfg1 = pcie->cfg0 + fdt_resource_size(&pcie->cfg_res) / 2;
> -
> - pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian");
> -
> - debug("%s dbi:%lx lut:%lx ctrl:0x%lx cfg0:0x%lx, big-endian:%d\n",
> - dev->name, (unsigned long)pcie->dbi, (unsigned long)pcie->lut,
> - (unsigned long)pcie->ctrl, (unsigned long)pcie->cfg0,
> - pcie->big_endian);
> -
> - pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f;
> -
> - if (pcie->mode == PCI_HEADER_TYPE_NORMAL) {
> - printf("PCIe%u: %s %s", pcie->idx, dev->name, "Endpoint");
> - ls_pcie_setup_ep(pcie);
> - } else {
> - printf("PCIe%u: %s %s", pcie->idx, dev->name, "Root Complex");
> - ls_pcie_setup_ctrl(pcie);
> - }
> -
> - if (!ls_pcie_link_up(pcie)) {
> - /* Let the user know there's no PCIe link */
> - printf(": no link\n");
> - return 0;
> - }
> -
> - /* Print the negotiated PCIe link width */
> - link_sta = readw(pcie->dbi + PCIE_LINK_STA);
> - printf(": x%d gen%d\n", (link_sta & PCIE_LINK_WIDTH_MASK) >> 4,
> - link_sta & PCIE_LINK_SPEED_MASK);
> -
> - return 0;
> -}
> -
> -static const struct dm_pci_ops ls_pcie_ops = {
> - .read_config = ls_pcie_read_config,
> - .write_config = ls_pcie_write_config,
> -};
> -
> -static const struct udevice_id ls_pcie_ids[] = {
> - { .compatible = "fsl,ls-pcie" },
> - { }
> -};
> -
> -U_BOOT_DRIVER(pci_layerscape) = {
> - .name = "pci_layerscape",
> - .id = UCLASS_PCI,
> - .of_match = ls_pcie_ids,
> - .ops = &ls_pcie_ops,
> - .probe = ls_pcie_probe,
> - .priv_auto_alloc_size = sizeof(struct ls_pcie),
> -};
> diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h
> index 95454bc..217dcda 100644
> --- a/drivers/pci/pcie_layerscape.h
> +++ b/drivers/pci/pcie_layerscape.h
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: GPL-2.0+ */
> /*
> - * Copyright 2017-2019 NXP
> + * Copyright 2017-2020 NXP
> * Copyright 2014-2015 Freescale Semiconductor, Inc.
> * Layerscape PCIe driver
> */
> @@ -60,7 +60,8 @@
> /* DBI registers */
> #define PCIE_SRIOV 0x178
> #define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask
> Register1 */
> -#define PCIE_DBI_RO_WR_EN 0x8bc
> +#define PCIE_DBI_RO_WR_EN BIT(0)
> +#define PCIE_MISC_CONTROL_1_OFF 0x8BC
>
> #define PCIE_LINK_CAP 0x7c
> #define PCIE_LINK_SPEED_MASK 0xf
> @@ -82,7 +83,7 @@
> PCIE_LCTRL0_CFG2_ENABLE)
>
> #define PCIE_NO_SRIOV_BAR_BASE 0x1000
> -
> +#define FSL_PCIE_EP_MIN_APERTURE 4096 /* 4 Kbytes */
> #define PCIE_PF_NUM 2
> #define PCIE_VF_NUM 64
>
> @@ -129,25 +130,52 @@
> #define LS1021_LTSSM_STATE_SHIFT 20
>
> struct ls_pcie {
> + void __iomem *dbi;
> + void __iomem *lut;
> + void __iomem *ctrl;
> int idx;
> + bool big_endian;
> + int mode;
> +};
> +
> +struct ls_pcie_rc {
> + struct ls_pcie *pcie;
> struct list_head list;
> struct udevice *bus;
> struct fdt_resource dbi_res;
> struct fdt_resource lut_res;
> struct fdt_resource ctrl_res;
> struct fdt_resource cfg_res;
> - void __iomem *dbi;
> - void __iomem *lut;
> - void __iomem *ctrl;
> void __iomem *cfg0;
> void __iomem *cfg1;
> - bool big_endian;
> bool enabled;
> int next_lut_index;
> int stream_id_cur;
> - int mode;
> +};
> +
> +struct ls_pcie_ep {
> + struct fdt_resource addr_res;
> + struct ls_pcie *pcie;
> + struct udevice *bus;
> + void __iomem *addr;
> + u32 num_ib_wins;
> + u32 num_ob_wins;
> + u8 max_functions;
> };
>
> extern struct list_head ls_pcie_list;
>
> +unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset); void
> +dbi_writel(struct ls_pcie *pcie, unsigned int value, unsigned int
> +offset); unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int
> +offset); void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
> +unsigned int offset); void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int
> idx, int type,
> + u64 phys, u64 bus_addr, pci_size_t size); void
> +ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, int type,
> + int bar, u64 phys);
> +void ls_pcie_dump_atu(struct ls_pcie *pcie); int ls_pcie_link_up(struct
> +ls_pcie *pcie); void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie); void
> +ls_pcie_dbi_ro_wr_dis(struct ls_pcie *pcie);
> +
> #endif /* _PCIE_LAYERSCAPE_H_ */
> diff --git a/drivers/pci/pcie_layerscape_ep.c
> b/drivers/pci/pcie_layerscape_ep.c
> new file mode 100644
> index 0000000..8d0c99a
> --- /dev/null
> +++ b/drivers/pci/pcie_layerscape_ep.c
> @@ -0,0 +1,240 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2020 NXP
> + * Layerscape PCIe EP driver
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <pci_ep.h>
> +#include <asm/io.h>
> +#include <linux/sizes.h>
> +#include <linux/log2.h>
> +#include "pcie_layerscape.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static void ls_pcie_ep_enable_cfg(struct ls_pcie_ep *pcie_ep) {
> + struct ls_pcie *pcie = pcie_ep->pcie;
> + u32 config;
> +
> + config = ctrl_readl(pcie, PCIE_PF_CONFIG);
> + config |= PCIE_CONFIG_READY;
> + ctrl_writel(pcie, config, PCIE_PF_CONFIG); }
> +
> +static int ls_ep_set_bar(struct udevice *dev, uint fn, struct pci_bar
> +*ep_bar) {
> + struct ls_pcie_ep *pcie_ep = dev_get_priv(dev);
> + struct ls_pcie *pcie = pcie_ep->pcie;
> + dma_addr_t bar_phys = ep_bar->phys_addr;
> + enum pci_barno bar = ep_bar->barno;
> + u32 reg = PCI_BASE_ADDRESS_0 + (4 * bar);
> + int flags = ep_bar->flags;
> + int type, idx;
> + u64 size;
> +
> + idx = bar;
> + /* BAR size is 2^(aperture + 11) */
> + size = max_t(size_t, ep_bar->size, FSL_PCIE_EP_MIN_APERTURE);
> +
> + if (!(flags & PCI_BASE_ADDRESS_SPACE))
> + type = PCIE_ATU_TYPE_MEM;
> + else
> + type = PCIE_ATU_TYPE_IO;
> +
> + ls_pcie_atu_inbound_set(pcie, idx, bar, bar_phys, type);
> +
> + dbi_writel(pcie, lower_32_bits(size - 1), reg +
> PCIE_NO_SRIOV_BAR_BASE);
> + dbi_writel(pcie, flags, reg);
> +
> + if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) {
> + dbi_writel(pcie, upper_32_bits(size - 1),
> + reg + 4 + PCIE_NO_SRIOV_BAR_BASE);
> + dbi_writel(pcie, 0, reg + 4);
> + }
> +
> + return 0;
> +}
> +
> +static struct pci_ep_ops ls_pcie_ep_ops = {
> + .set_bar = ls_ep_set_bar,
> +};
> +
> +static void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep) {
> + struct ls_pcie *pcie = pcie_ep->pcie;
> + u64 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE;
> +
> + /* ATU 0 : INBOUND : map BAR0 */
> + ls_pcie_atu_inbound_set(pcie, 0, PCIE_ATU_TYPE_MEM, 0, phys);
> + /* ATU 1 : INBOUND : map BAR1 */
> + phys += PCIE_BAR1_SIZE;
> + ls_pcie_atu_inbound_set(pcie, 1, PCIE_ATU_TYPE_MEM, 1, phys);
> + /* ATU 2 : INBOUND : map BAR2 */
> + phys += PCIE_BAR2_SIZE;
> + ls_pcie_atu_inbound_set(pcie, 2, PCIE_ATU_TYPE_MEM, 2, phys);
> + /* ATU 3 : INBOUND : map BAR4 */
> + phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR4_SIZE;
> + ls_pcie_atu_inbound_set(pcie, 3, PCIE_ATU_TYPE_MEM, 4, phys);
> +
> + /* ATU 0 : OUTBOUND : map MEM */
> + ls_pcie_atu_outbound_set(pcie, 0,
> + PCIE_ATU_TYPE_MEM,
> + pcie_ep->addr_res.start,
> + 0,
> + CONFIG_SYS_PCI_MEMORY_SIZE);
> +}
> +
> +/* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */ static void
> +ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size) {
> + /* The least inbound window is 4KiB */
> + if (size < 4 * 1024)
> + return;
> +
> + switch (bar) {
> + case 0:
> + writel(size - 1, bar_base + PCI_BASE_ADDRESS_0);
> + break;
> + case 1:
> + writel(size - 1, bar_base + PCI_BASE_ADDRESS_1);
> + break;
> + case 2:
> + writel(size - 1, bar_base + PCI_BASE_ADDRESS_2);
> + writel(0, bar_base + PCI_BASE_ADDRESS_3);
> + break;
> + case 4:
> + writel(size - 1, bar_base + PCI_BASE_ADDRESS_4);
> + writel(0, bar_base + PCI_BASE_ADDRESS_5);
> + break;
> + default:
> + break;
> + }
> +}
> +
> +static void ls_pcie_ep_setup_bars(void *bar_base) {
> + /* BAR0 - 32bit - 4K configuration */
> + ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
> + /* BAR1 - 32bit - 8K MSIX */
> + ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
> + /* BAR2 - 64bit - 4K MEM descriptor */
> + ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
> + /* BAR4 - 64bit - 1M MEM */
> + ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE); }
> +
> +static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep) {
> + u32 sriov;
> + struct ls_pcie *pcie = pcie_ep->pcie;
> +
> + sriov = readl(pcie->dbi + PCIE_SRIOV);
> + if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) {
> + int pf, vf;
> +
> + for (pf = 0; pf < PCIE_PF_NUM; pf++) {
> + for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
> + ctrl_writel(pcie, PCIE_LCTRL0_VAL(pf, vf),
> + PCIE_PF_VF_CTRL);
> +
> + ls_pcie_ep_setup_bars(pcie->dbi);
> + ls_pcie_ep_setup_atu(pcie_ep);
> + }
> + }
> + /* Disable CFG2 */
> + ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL);
> + } else {
> + ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE);
> + ls_pcie_ep_setup_atu(pcie_ep);
> + }
> +
> + ls_pcie_ep_enable_cfg(pcie_ep);
> +}
> +
> +static int ls_pcie_ep_probe(struct udevice *dev) {
> + struct ls_pcie_ep *pcie_ep = dev_get_priv(dev);
> + struct ls_pcie *pcie;
> + u16 link_sta;
> + int ret;
> +
> + pcie = devm_kmalloc(dev, sizeof(*pcie), GFP_KERNEL);
> + if (!pcie)
> + return -ENOMEM;
> +
> + pcie_ep->pcie = pcie;
> +
> + pcie->dbi = (void __iomem *)devfdt_get_addr_index(dev, 0);
> + if (!pcie->dbi)
> + return -ENOMEM;
> +
> + pcie->ctrl = (void __iomem *)devfdt_get_addr_index(dev, 1);
> + if (!pcie->ctrl)
> + return -ENOMEM;
> +
> + ret = fdt_get_named_resource(gd->fdt_blob, dev_of_offset(dev),
> + "reg", "reg-names",
> + "addr_space", &pcie_ep->addr_res);
> + if (ret) {
> + printf("%s: resource \"addr_space\" not found\n", dev->name);
> + return ret;
> + }
> +
> + pcie->idx = ((unsigned long)pcie->dbi - PCIE_SYS_BASE_ADDR) /
> + PCIE_CCSR_SIZE;
> +
> + pcie->big_endian = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
> + "big-endian");
> +
> + pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f;
> + if (pcie->mode != PCI_HEADER_TYPE_NORMAL)
> + return 0;
> +
> + pcie_ep->max_functions = fdtdec_get_int(gd->fdt_blob,
> + dev_of_offset(dev),
> + "max-functions", 1);
> + pcie_ep->num_ib_wins = fdtdec_get_int(gd->fdt_blob,
> dev_of_offset(dev),
> + "num-ib-windows", 8);
> + pcie_ep->num_ob_wins = fdtdec_get_int(gd->fdt_blob,
> dev_of_offset(dev),
> + "num-ob-windows", 8);
> +
> + printf("PCIe%u: %s %s", pcie->idx, dev->name, "Endpoint");
> + ls_pcie_setup_ep(pcie_ep);
> +
> + if (!ls_pcie_link_up(pcie)) {
> + /* Let the user know there's no PCIe link */
> + printf(": no link\n");
> + return 0;
> + }
> +
> + /* Print the negotiated PCIe link width */
> + link_sta = readw(pcie->dbi + PCIE_LINK_STA);
> + printf(": x%d gen%d\n", (link_sta & PCIE_LINK_WIDTH_MASK) >> 4,
> + link_sta & PCIE_LINK_SPEED_MASK);
> +
> + return 0;
> +}
> +
> +static int ls_pcie_ep_remove(struct udevice *dev) {
> + return 0;
> +}
> +
> +const struct udevice_id ls_pcie_ep_ids[] = {
> + { .compatible = "fsl,ls-pcie-ep" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(pci_layerscape_ep) = {
> + .name = "pci_layerscape_ep",
> + .id = UCLASS_PCI_EP,
> + .of_match = ls_pcie_ep_ids,
> + .ops = &ls_pcie_ep_ops,
> + .probe = ls_pcie_ep_probe,
> + .remove = ls_pcie_ep_remove,
> + .priv_auto_alloc_size = sizeof(struct ls_pcie_ep), };
> diff --git a/drivers/pci/pcie_layerscape_fixup.c
> b/drivers/pci/pcie_layerscape_fixup.c
> index ec6acbb..a981f8c 100644
> --- a/drivers/pci/pcie_layerscape_fixup.c
> +++ b/drivers/pci/pcie_layerscape_fixup.c
> @@ -23,17 +23,19 @@
> /*
> * Return next available LUT index.
> */
> -static int ls_pcie_next_lut_index(struct ls_pcie *pcie)
> +static int ls_pcie_next_lut_index(struct ls_pcie_rc *pcie_rc)
> {
> - if (pcie->next_lut_index < PCIE_LUT_ENTRY_COUNT)
> - return pcie->next_lut_index++;
> + if (pcie_rc->next_lut_index < PCIE_LUT_ENTRY_COUNT)
> + return pcie_rc->next_lut_index++;
> else
> return -ENOSPC; /* LUT is full */
> }
>
> -static void lut_writel(struct ls_pcie *pcie, unsigned int value,
> +static void lut_writel(struct ls_pcie_rc *pcie_rc, unsigned int value,
> unsigned int offset)
> {
> + struct ls_pcie *pcie = pcie_rc->pcie;
> +
> if (pcie->big_endian)
> out_be32(pcie->lut + offset, value);
> else
> @@ -43,12 +45,12 @@ static void lut_writel(struct ls_pcie *pcie, unsigned
> int value,
> /*
> * Program a single LUT entry
> */
> -static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32
> devid,
> - u32 streamid)
> +static void ls_pcie_lut_set_mapping(struct ls_pcie_rc *pcie_rc, int index,
> + u32 devid, u32 streamid)
> {
> /* leave mask as all zeroes, want to match all bits */
> - lut_writel(pcie, devid << 16, PCIE_LUT_UDR(index));
> - lut_writel(pcie, streamid | PCIE_LUT_ENABLE, PCIE_LUT_LDR(index));
> + lut_writel(pcie_rc, devid << 16, PCIE_LUT_UDR(index));
> + lut_writel(pcie_rc, streamid | PCIE_LUT_ENABLE,
> PCIE_LUT_LDR(index));
> }
>
> /*
> @@ -59,7 +61,8 @@ static void ls_pcie_lut_set_mapping(struct ls_pcie
> *pcie, int index, u32 devid,
> * msi-map = <[devid] [phandle-to-msi-ctrl] [stream-id] [count]
> * [devid] [phandle-to-msi-ctrl] [stream-id] [count]>;
> */
> -static void fdt_pcie_set_msi_map_entry_ls(void *blob, struct ls_pcie *pcie,
> +static void fdt_pcie_set_msi_map_entry_ls(void *blob,
> + struct ls_pcie_rc *pcie_rc,
> u32 devid, u32 streamid)
> {
> u32 *prop;
> @@ -67,10 +70,11 @@ static void fdt_pcie_set_msi_map_entry_ls(void
> *blob, struct ls_pcie *pcie,
> int nodeoffset;
> uint svr;
> char *compat = NULL;
> + struct ls_pcie *pcie = pcie_rc->pcie;
>
> /* find pci controller node */
> nodeoffset = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie",
> - pcie->dbi_res.start);
> + pcie_rc->dbi_res.start);
> if (nodeoffset < 0) {
> #ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts
> node */
> svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE; @@ -82,7
> +86,7 @@ static void fdt_pcie_set_msi_map_entry_ls(void *blob, struct
> ls_pcie *pcie,
> compat = CONFIG_FSL_PCIE_COMPAT;
> if (compat)
> nodeoffset = fdt_node_offset_by_compat_reg(blob,
> - compat, pcie->dbi_res.start);
> + compat, pcie_rc->dbi_res.start);
> #endif
> if (nodeoffset < 0)
> return;
> @@ -112,7 +116,8 @@ static void fdt_pcie_set_msi_map_entry_ls(void
> *blob, struct ls_pcie *pcie,
> * iommu-map = <[devid] [phandle-to-iommu-ctrl] [stream-id]
> [count]
> * [devid] [phandle-to-iommu-ctrl] [stream-id]
> [count]>;
> */
> -static void fdt_pcie_set_iommu_map_entry_ls(void *blob, struct ls_pcie
> *pcie,
> +static void fdt_pcie_set_iommu_map_entry_ls(void *blob,
> + struct ls_pcie_rc *pcie_rc,
> u32 devid, u32 streamid)
> {
> u32 *prop;
> @@ -121,10 +126,11 @@ static void
> fdt_pcie_set_iommu_map_entry_ls(void *blob, struct ls_pcie *pcie,
> int lenp;
> uint svr;
> char *compat = NULL;
> + struct ls_pcie *pcie = pcie_rc->pcie;
>
> /* find pci controller node */
> nodeoffset = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie",
> - pcie->dbi_res.start);
> + pcie_rc->dbi_res.start);
> if (nodeoffset < 0) {
> #ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts
> node */
> svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE; @@ -137,7
> +143,7 @@ static void fdt_pcie_set_iommu_map_entry_ls(void *blob, struct
> ls_pcie *pcie,
>
> if (compat)
> nodeoffset = fdt_node_offset_by_compat_reg(blob,
> - compat, pcie->dbi_res.start);
> + compat, pcie_rc->dbi_res.start);
> #endif
> if (nodeoffset < 0)
> return;
> @@ -168,7 +174,7 @@ static void fdt_pcie_set_iommu_map_entry_ls(void
> *blob, struct ls_pcie *pcie, static void fdt_fixup_pcie_ls(void *blob) {
> struct udevice *dev, *bus;
> - struct ls_pcie *pcie;
> + struct ls_pcie_rc *pcie_rc;
> int streamid;
> int index;
> pci_dev_t bdf;
> @@ -179,17 +185,18 @@ static void fdt_fixup_pcie_ls(void *blob)
> pci_find_next_device(&dev)) {
> for (bus = dev; device_is_on_pci_bus(bus);)
> bus = bus->parent;
> - pcie = dev_get_priv(bus);
> + pcie_rc = dev_get_priv(bus);
>
> - streamid = pcie_next_streamid(pcie->stream_id_cur, pcie->idx);
> + streamid = pcie_next_streamid(pcie_rc->stream_id_cur,
> + pcie_rc->pcie->idx);
> if (streamid < 0) {
> debug("ERROR: no stream ids free\n");
> continue;
> } else {
> - pcie->stream_id_cur++;
> + pcie_rc->stream_id_cur++;
> }
>
> - index = ls_pcie_next_lut_index(pcie);
> + index = ls_pcie_next_lut_index(pcie_rc);
> if (index < 0) {
> debug("ERROR: no LUT indexes free\n");
> continue;
> @@ -198,27 +205,28 @@ static void fdt_fixup_pcie_ls(void *blob)
> /* the DT fixup must be relative to the hose first_busno */
> bdf = dm_pci_get_bdf(dev) - PCI_BDF(bus->seq, 0, 0);
> /* map PCI b.d.f to streamID in LUT */
> - ls_pcie_lut_set_mapping(pcie, index, bdf >> 8,
> + ls_pcie_lut_set_mapping(pcie_rc, index, bdf >> 8,
> streamid);
> /* update msi-map in device tree */
> - fdt_pcie_set_msi_map_entry_ls(blob, pcie, bdf >> 8,
> + fdt_pcie_set_msi_map_entry_ls(blob, pcie_rc, bdf >> 8,
> streamid);
> /* update iommu-map in device tree */
> - fdt_pcie_set_iommu_map_entry_ls(blob, pcie, bdf >> 8,
> + fdt_pcie_set_iommu_map_entry_ls(blob, pcie_rc, bdf >> 8,
> streamid);
> }
> pcie_board_fix_fdt(blob);
> }
> #endif
>
> -static void ft_pcie_rc_fix(void *blob, struct ls_pcie *pcie)
> +static void ft_pcie_rc_fix(void *blob, struct ls_pcie_rc *pcie_rc)
> {
> int off;
> uint svr;
> char *compat = NULL;
> + struct ls_pcie *pcie = pcie_rc->pcie;
>
> off = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie",
> - pcie->dbi_res.start);
> + pcie_rc->dbi_res.start);
> if (off < 0) {
> #ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts
> node */
> svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE; @@ -230,46
> +238,47 @@ static void ft_pcie_rc_fix(void *blob, struct ls_pcie *pcie)
> compat = CONFIG_FSL_PCIE_COMPAT;
> if (compat)
> off = fdt_node_offset_by_compat_reg(blob,
> - compat, pcie->dbi_res.start);
> + compat, pcie_rc->dbi_res.start);
> #endif
> if (off < 0)
> return;
> }
>
> - if (pcie->enabled && pcie->mode == PCI_HEADER_TYPE_BRIDGE)
> + if (pcie_rc->enabled && pcie->mode == PCI_HEADER_TYPE_BRIDGE)
> fdt_set_node_status(blob, off, FDT_STATUS_OKAY, 0);
> else
> fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); }
>
> -static void ft_pcie_ep_fix(void *blob, struct ls_pcie *pcie)
> +static void ft_pcie_ep_fix(void *blob, struct ls_pcie_rc *pcie_rc)
> {
> int off;
> + struct ls_pcie *pcie = pcie_rc->pcie;
>
> off = fdt_node_offset_by_compat_reg(blob,
> CONFIG_FSL_PCIE_EP_COMPAT,
> - pcie->dbi_res.start);
> + pcie_rc->dbi_res.start);
> if (off < 0)
> return;
>
> - if (pcie->enabled && pcie->mode == PCI_HEADER_TYPE_NORMAL)
> + if (pcie_rc->enabled && pcie->mode == PCI_HEADER_TYPE_NORMAL)
> fdt_set_node_status(blob, off, FDT_STATUS_OKAY, 0);
> else
> fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); }
>
> -static void ft_pcie_ls_setup(void *blob, struct ls_pcie *pcie)
> +static void ft_pcie_ls_setup(void *blob, struct ls_pcie_rc *pcie_rc)
> {
> - ft_pcie_ep_fix(blob, pcie);
> - ft_pcie_rc_fix(blob, pcie);
> + ft_pcie_ep_fix(blob, pcie_rc);
> + ft_pcie_rc_fix(blob, pcie_rc);
> }
>
> /* Fixup Kernel DT for PCIe */
> void ft_pci_setup_ls(void *blob, bd_t *bd) {
> - struct ls_pcie *pcie;
> + struct ls_pcie_rc *pcie_rc;
>
> - list_for_each_entry(pcie, &ls_pcie_list, list)
> - ft_pcie_ls_setup(blob, pcie);
> + list_for_each_entry(pcie_rc, &ls_pcie_list, list)
> + ft_pcie_ls_setup(blob, pcie_rc);
>
> #if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2)
> fdt_fixup_pcie_ls(blob);
> diff --git a/drivers/pci/pcie_layerscape_rc.c
> b/drivers/pci/pcie_layerscape_rc.c
> new file mode 100644
> index 0000000..927722d
> --- /dev/null
> +++ b/drivers/pci/pcie_layerscape_rc.c
> @@ -0,0 +1,378 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2020 NXP
> + * Layerscape PCIe driver
> + */
> +
> +#include <common.h>
> +#include <asm/arch/fsl_serdes.h>
> +#include <pci.h>
> +#include <asm/io.h>
> +#include <errno.h>
> +#include <malloc.h>
> +#include <dm.h>
> +#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
> + defined(CONFIG_ARM)
> +#include <asm/arch/clock.h>
> +#endif
> +#include "pcie_layerscape.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static void ls_pcie_cfg0_set_busdev(struct ls_pcie_rc *pcie_rc, u32
> +busdev) {
> + struct ls_pcie *pcie = pcie_rc->pcie;
> +
> + dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND |
> PCIE_ATU_REGION_INDEX0,
> + PCIE_ATU_VIEWPORT);
> + dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET); }
> +
> +static void ls_pcie_cfg1_set_busdev(struct ls_pcie_rc *pcie_rc, u32
> +busdev) {
> + struct ls_pcie *pcie = pcie_rc->pcie;
> +
> + dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND |
> PCIE_ATU_REGION_INDEX1,
> + PCIE_ATU_VIEWPORT);
> + dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET); }
> +
> +static void ls_pcie_setup_atu(struct ls_pcie_rc *pcie_rc) {
> + struct pci_region *io, *mem, *pref;
> + unsigned long long offset = 0;
> + struct ls_pcie *pcie = pcie_rc->pcie;
> + int idx = 0;
> + uint svr;
> +
> + svr = get_svr();
> + if (((svr >> SVR_VAR_PER_SHIFT) & SVR_LS102XA_MASK) ==
> SVR_LS102XA) {
> + offset = LS1021_PCIE_SPACE_OFFSET +
> + LS1021_PCIE_SPACE_SIZE * pcie->idx;
> + }
> +
> + /* ATU 0 : OUTBOUND : CFG0 */
> + ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
> + PCIE_ATU_TYPE_CFG0,
> + pcie_rc->cfg_res.start + offset,
> + 0,
> + fdt_resource_size(&pcie_rc->cfg_res) / 2);
> + /* ATU 1 : OUTBOUND : CFG1 */
> + ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1,
> + PCIE_ATU_TYPE_CFG1,
> + pcie_rc->cfg_res.start + offset +
> + fdt_resource_size(&pcie_rc->cfg_res) / 2,
> + 0,
> + fdt_resource_size(&pcie_rc->cfg_res) / 2);
> +
> + pci_get_regions(pcie_rc->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 ||
> + svr == SVR_LS2081A || svr == SVR_LS2041A) {
> + 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++,
> + PCIE_ATU_TYPE_IO,
> + io->phys_start + offset,
> + io->bus_start,
> + io->size);
> +
> + if (mem)
> + /* ATU : OUTBOUND : MEM */
> + ls_pcie_atu_outbound_set(pcie, idx++,
> + PCIE_ATU_TYPE_MEM,
> + mem->phys_start + offset,
> + mem->bus_start,
> + mem->size);
> +
> + if (pref)
> + /* ATU : OUTBOUND : pref */
> + ls_pcie_atu_outbound_set(pcie, idx++,
> + PCIE_ATU_TYPE_MEM,
> + pref->phys_start + offset,
> + pref->bus_start,
> + pref->size);
> +
> + ls_pcie_dump_atu(pcie);
> +}
> +
> +/* Return 0 if the address is valid, -errno if not valid */ static int
> +ls_pcie_addr_valid(struct ls_pcie_rc *pcie_rc, pci_dev_t bdf) {
> + struct udevice *bus = pcie_rc->bus;
> + struct ls_pcie *pcie = pcie_rc->pcie;
> +
> + if (pcie->mode == PCI_HEADER_TYPE_NORMAL)
> + return -ENODEV;
> +
> + if (!pcie_rc->enabled)
> + return -ENXIO;
> +
> + if (PCI_BUS(bdf) < bus->seq)
> + return -EINVAL;
> +
> + if ((PCI_BUS(bdf) > bus->seq) && (!ls_pcie_link_up(pcie)))
> + return -EINVAL;
> +
> + if (PCI_BUS(bdf) <= (bus->seq + 1) && (PCI_DEV(bdf) > 0))
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +int ls_pcie_conf_address(struct udevice *bus, pci_dev_t bdf,
> + uint offset, void **paddress)
> +{
> + struct ls_pcie_rc *pcie_rc = dev_get_priv(bus);
> + struct ls_pcie *pcie = pcie_rc->pcie;
> + u32 busdev;
> +
> + if (ls_pcie_addr_valid(pcie_rc, bdf))
> + return -EINVAL;
> +
> + if (PCI_BUS(bdf) == bus->seq) {
> + *paddress = pcie->dbi + offset;
> + return 0;
> + }
> +
> + busdev = PCIE_ATU_BUS(PCI_BUS(bdf) - bus->seq) |
> + PCIE_ATU_DEV(PCI_DEV(bdf)) |
> + PCIE_ATU_FUNC(PCI_FUNC(bdf));
> +
> + if (PCI_BUS(bdf) == bus->seq + 1) {
> + ls_pcie_cfg0_set_busdev(pcie_rc, busdev);
> + *paddress = pcie_rc->cfg0 + offset;
> + } else {
> + ls_pcie_cfg1_set_busdev(pcie_rc, busdev);
> + *paddress = pcie_rc->cfg1 + offset;
> + }
> + return 0;
> +}
> +
> +static int ls_pcie_read_config(struct udevice *bus, pci_dev_t bdf,
> + uint offset, ulong *valuep,
> + enum pci_size_t size)
> +{
> + return pci_generic_mmap_read_config(bus, ls_pcie_conf_address,
> + bdf, offset, valuep, size);
> +}
> +
> +static int ls_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
> + uint offset, ulong value,
> + enum pci_size_t size)
> +{
> + return pci_generic_mmap_write_config(bus, ls_pcie_conf_address,
> + bdf, offset, value, size);
> +}
> +
> +/* Clear multi-function bit */
> +static void ls_pcie_clear_multifunction(struct ls_pcie_rc *pcie_rc) {
> + struct ls_pcie *pcie = pcie_rc->pcie;
> +
> + writeb(PCI_HEADER_TYPE_BRIDGE, pcie->dbi + PCI_HEADER_TYPE); }
> +
> +/* Fix class value */
> +static void ls_pcie_fix_class(struct ls_pcie_rc *pcie_rc) {
> + struct ls_pcie *pcie = pcie_rc->pcie;
> +
> + writew(PCI_CLASS_BRIDGE_PCI, pcie->dbi + PCI_CLASS_DEVICE); }
> +
> +/* Drop MSG TLP except for Vendor MSG */ static void
> +ls_pcie_drop_msg_tlp(struct ls_pcie_rc *pcie_rc) {
> + struct ls_pcie *pcie = pcie_rc->pcie;
> + u32 val;
> +
> + val = dbi_readl(pcie, PCIE_STRFMR1);
> + val &= 0xDFFFFFFF;
> + dbi_writel(pcie, val, PCIE_STRFMR1);
> +}
> +
> +/* Disable all bars in RC mode */
> +static void ls_pcie_disable_bars(struct ls_pcie_rc *pcie_rc) {
> + struct ls_pcie *pcie = pcie_rc->pcie;
> +
> + dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_0);
> + dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_1);
> + dbi_writel(pcie, 0xfffffffe, PCIE_CS2_OFFSET + PCI_ROM_ADDRESS1); }
> +
> +static void ls_pcie_setup_ctrl(struct ls_pcie_rc *pcie_rc) {
> + struct ls_pcie *pcie = pcie_rc->pcie;
> +
> + ls_pcie_setup_atu(pcie_rc);
> +
> + ls_pcie_dbi_ro_wr_en(pcie);
> + ls_pcie_fix_class(pcie_rc);
> + ls_pcie_clear_multifunction(pcie_rc);
> + ls_pcie_drop_msg_tlp(pcie_rc);
> + ls_pcie_dbi_ro_wr_dis(pcie);
> +
> + ls_pcie_disable_bars(pcie_rc);
> + pcie_rc->stream_id_cur = 0;
> +}
> +
> +static int ls_pcie_probe(struct udevice *dev) {
> + struct ls_pcie_rc *pcie_rc = dev_get_priv(dev);
> + const void *fdt = gd->fdt_blob;
> + int node = dev_of_offset(dev);
> + struct ls_pcie *pcie;
> + u16 link_sta;
> + uint svr;
> + int ret;
> + fdt_size_t cfg_size;
> +
> + pcie_rc->bus = dev;
> +
> + pcie = devm_kmalloc(dev, sizeof(*pcie), GFP_KERNEL);
> + if (!pcie)
> + return -ENOMEM;
> +
> + pcie_rc->pcie = pcie;
> +
> + ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
> + "dbi", &pcie_rc->dbi_res);
> + if (ret) {
> + printf("ls-pcie: resource \"dbi\" not found\n");
> + return ret;
> + }
> +
> + pcie->idx = (pcie_rc->dbi_res.start - PCIE_SYS_BASE_ADDR) /
> + PCIE_CCSR_SIZE;
> +
> + list_add(&pcie_rc->list, &ls_pcie_list);
> +
> + pcie_rc->enabled = is_serdes_configured(PCIE_SRDS_PRTCL(pcie->idx));
> + if (!pcie_rc->enabled) {
> + printf("PCIe%d: %s disabled\n", pcie->idx, dev->name);
> + return 0;
> + }
> +
> + pcie->dbi = map_physmem(pcie_rc->dbi_res.start,
> + fdt_resource_size(&pcie_rc->dbi_res),
> + MAP_NOCACHE);
> +
> + pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f;
> + if (pcie->mode == PCI_HEADER_TYPE_NORMAL)
> + return 0;
> +
> + ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
> + "lut", &pcie_rc->lut_res);
> + if (!ret)
> + pcie->lut = map_physmem(pcie_rc->lut_res.start,
> + fdt_resource_size(&pcie_rc->lut_res),
> + MAP_NOCACHE);
> +
> + ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
> + "ctrl", &pcie_rc->ctrl_res);
> + if (!ret)
> + pcie->ctrl = map_physmem(pcie_rc->ctrl_res.start,
> + fdt_resource_size(&pcie_rc->ctrl_res),
> + MAP_NOCACHE);
> + if (!pcie->ctrl)
> + pcie->ctrl = pcie->lut;
> +
> + if (!pcie->ctrl) {
> + printf("%s: NOT find CTRL\n", dev->name);
> + return -1;
> + }
> +
> + ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
> + "config", &pcie_rc->cfg_res);
> + if (ret) {
> + printf("%s: resource \"config\" not found\n", dev->name);
> + 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 ||
> + svr == SVR_LS2081A || svr == SVR_LS2041A) {
> + cfg_size = fdt_resource_size(&pcie_rc->cfg_res);
> + pcie_rc->cfg_res.start = LS2088A_PCIE1_PHYS_ADDR +
> + LS2088A_PCIE_PHYS_SIZE * pcie->idx;
> + pcie_rc->cfg_res.end = pcie_rc->cfg_res.start + cfg_size;
> + pcie->ctrl = pcie->lut + 0x40000;
> + }
> +
> + pcie_rc->cfg0 = map_physmem(pcie_rc->cfg_res.start,
> + fdt_resource_size(&pcie_rc->cfg_res),
> + MAP_NOCACHE);
> + pcie_rc->cfg1 = pcie_rc->cfg0 +
> + fdt_resource_size(&pcie_rc->cfg_res) / 2;
> +
> + pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian");
> +
> + debug("%s dbi:%lx lut:%lx ctrl:0x%lx cfg0:0x%lx, big-endian:%d\n",
> + dev->name, (unsigned long)pcie->dbi, (unsigned long)pcie->lut,
> + (unsigned long)pcie->ctrl, (unsigned long)pcie_rc->cfg0,
> + pcie->big_endian);
> +
> + printf("PCIe%u: %s %s", pcie->idx, dev->name, "Root Complex");
> + ls_pcie_setup_ctrl(pcie_rc);
> +
> + if (!ls_pcie_link_up(pcie)) {
> + /* Let the user know there's no PCIe link */
> + printf(": no link\n");
> + return 0;
> + }
> +
> + /* Print the negotiated PCIe link width */
> + link_sta = readw(pcie->dbi + PCIE_LINK_STA);
> + printf(": x%d gen%d\n", (link_sta & PCIE_LINK_WIDTH_MASK) >> 4,
> + link_sta & PCIE_LINK_SPEED_MASK);
> +
> + return 0;
> +}
> +
> +static const struct dm_pci_ops ls_pcie_ops = {
> + .read_config = ls_pcie_read_config,
> + .write_config = ls_pcie_write_config,
> +};
> +
> +static const struct udevice_id ls_pcie_ids[] = {
> + { .compatible = "fsl,ls-pcie" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(pci_layerscape) = {
> + .name = "pci_layerscape",
> + .id = UCLASS_PCI,
> + .of_match = ls_pcie_ids,
> + .ops = &ls_pcie_ops,
> + .probe = ls_pcie_probe,
> + .priv_auto_alloc_size = sizeof(struct ls_pcie_rc), };
> --
> 2.9.5
Reviewed-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 2/9] pci_ep: Add the init function
2020-03-22 11:12 ` [PATCH 2/9] pci_ep: Add the init function Xiaowei Bao
@ 2020-04-28 12:23 ` Z.q. Hou
0 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2020-04-28 12:23 UTC (permalink / raw)
To: u-boot
> -----Original Message-----
> From: Xiaowei Bao <xiaowei.bao@nxp.com>
> Sent: 2020?3?22? 19:13
> To: M.h. Lian <minghuan.lian@nxp.com>; Z.q. Hou
> <zhiqiang.hou@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
> bmeng.cn at gmail.com; yamada.masahiro at socionext.com;
> u-boot at lists.denx.de
> Cc: Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: [PATCH 2/9] pci_ep: Add the init function
>
> Some EP deivces need to initialize before RC scan it, e.g. NXP layerscape
> platform, so add the init function in pci_ep uclass.
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> common/board_r.c | 12 ++++++++++++
> drivers/pci_endpoint/pci_ep-uclass.c | 11 +++++++++++
> include/init.h | 1 +
> 3 files changed, 24 insertions(+)
>
> diff --git a/common/board_r.c b/common/board_r.c index
> 0bbeaa7..856b47f 100644
> --- a/common/board_r.c
> +++ b/common/board_r.c
> @@ -229,6 +229,15 @@ static int initr_unlock_ram_in_cache(void) }
> #endif
>
> +#ifdef CONFIG_PCI_ENDPOINT
> +static int initr_pci_ep(void)
> +{
> + pci_ep_init();
> +
> + return 0;
> +}
> +#endif
> +
> #ifdef CONFIG_PCI
> static int initr_pci(void)
> {
> @@ -839,6 +848,9 @@ static init_fnc_t init_sequence_r[] = { #ifdef
> CONFIG_BITBANGMII
> initr_bbmii,
> #endif
> +#ifdef CONFIG_PCI_ENDPOINT
> + initr_pci_ep,
> +#endif
> #ifdef CONFIG_CMD_NET
> INIT_FUNC_WATCHDOG_RESET
> initr_net,
> diff --git a/drivers/pci_endpoint/pci_ep-uclass.c
> b/drivers/pci_endpoint/pci_ep-uclass.c
> index 9f53a9a..38a5f08 100644
> --- a/drivers/pci_endpoint/pci_ep-uclass.c
> +++ b/drivers/pci_endpoint/pci_ep-uclass.c
> @@ -209,3 +209,14 @@ UCLASS_DRIVER(pci_ep) = {
> .name = "pci_ep",
> .flags = DM_UC_FLAG_SEQ_ALIAS,
> };
> +
> +void pci_ep_init(void)
> +{
> + struct udevice *dev;
> +
> + for (uclass_first_device_check(UCLASS_PCI_EP, &dev);
> + dev;
> + uclass_next_device_check(&dev)) {
> + ;
> + }
> +}
> diff --git a/include/init.h b/include/init.h index 2a33a3f..fbc26a8 100644
> --- a/include/init.h
> +++ b/include/init.h
> @@ -202,6 +202,7 @@ int set_cpu_clk_info(void); int
> update_flash_size(int flash_size); int arch_early_init_r(void); void
> pci_init(void);
> +void pci_ep_init(void);
> int misc_init_r(void);
> #if defined(CONFIG_VID)
> int init_func_vid(void);
> --
> 2.9.5
Reviewed-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 3/9] armv8: dts: ls1046a: Add the PCIe EP node
2020-03-22 11:12 ` [PATCH 3/9] armv8: dts: ls1046a: Add the PCIe EP node Xiaowei Bao
@ 2020-04-28 12:24 ` Z.q. Hou
0 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2020-04-28 12:24 UTC (permalink / raw)
To: u-boot
> -----Original Message-----
> From: Xiaowei Bao <xiaowei.bao@nxp.com>
> Sent: 2020?3?22? 19:13
> To: M.h. Lian <minghuan.lian@nxp.com>; Z.q. Hou
> <zhiqiang.hou@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
> bmeng.cn at gmail.com; yamada.masahiro at socionext.com;
> u-boot at lists.denx.de
> Cc: Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: [PATCH 3/9] armv8: dts: ls1046a: Add the PCIe EP node
>
> Add the PCIe EP node for ls1046a.
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> arch/arm/dts/fsl-ls1046a.dtsi | 33 +++++++++++++++++++++++++++++++++
> 1 file changed, 33 insertions(+)
>
> diff --git a/arch/arm/dts/fsl-ls1046a.dtsi b/arch/arm/dts/fsl-ls1046a.dtsi
> index fdf93fd..e4b4a8e 100644
> --- a/arch/arm/dts/fsl-ls1046a.dtsi
> +++ b/arch/arm/dts/fsl-ls1046a.dtsi
> @@ -259,6 +259,17 @@
> 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0
> 0x40000000>; /* non-prefetchable memory */
> };
>
> + pcie_ep at 3400000 {
> + compatible = "fsl,ls-pcie-ep";
> + reg = <0x00 0x03400000 0x0 0x80000
> + 0x00 0x034c0000 0x0 0x40000
> + 0x40 0x00000000 0x8 0x00000000>;
> + reg-names = "regs", "ctrl", "addr_space";
> + num-ib-windows = <6>;
> + num-ob-windows = <8>;
> + big-endian;
> + };
> +
> pcie at 3500000 {
> compatible = "fsl,ls-pcie", "snps,dw-pcie";
> reg = <0x00 0x03500000 0x0 0x80000 /* dbi registers */
> @@ -276,6 +287,17 @@
> 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0
> 0x40000000>; /* non-prefetchable memory */
> };
>
> + pcie_ep at 3500000 {
> + compatible = "fsl,ls-pcie-ep";
> + reg = <0x00 0x03500000 0x0 0x80000
> + 0x00 0x035c0000 0x0 0x40000
> + 0x48 0x00000000 0x8 0x00000000>;
> + reg-names = "regs", "ctrl", "addr_space";
> + num-ib-windows = <6>;
> + num-ob-windows = <8>;
> + big-endian;
> + };
> +
> pcie at 3600000 {
> compatible = "fsl,ls-pcie", "snps,dw-pcie";
> reg = <0x00 0x03600000 0x0 0x80000 /* dbi registers */
> @@ -292,6 +314,17 @@
> 0x82000000 0x0 0x40000000 0x50 0x40000000 0x0
> 0x40000000>; /* non-prefetchable memory */
> };
>
> + pcie_ep at 3600000 {
> + compatible = "fsl,ls-pcie-ep";
> + reg = <0x00 0x03600000 0x0 0x80000
> + 0x00 0x036c0000 0x0 0x40000
> + 0x50 0x00000000 0x8 0x00000000>;
> + reg-names = "regs", "ctrl", "addr_space";
> + num-ib-windows = <6>;
> + num-ob-windows = <8>;
> + big-endian;
> + };
> +
> sata: sata at 3200000 {
> compatible = "fsl,ls1046a-ahci";
> reg = <0x0 0x3200000 0x0 0x10000 /* ccsr sata base */
> --
> 2.9.5
Reviewed-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 4/9] PCI_EP: layerscape: Add the multiple function supprot
2020-03-22 11:12 ` [PATCH 4/9] PCI_EP: layerscape: Add the multiple function supprot Xiaowei Bao
@ 2020-04-28 12:24 ` Z.q. Hou
0 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2020-04-28 12:24 UTC (permalink / raw)
To: u-boot
> -----Original Message-----
> From: Xiaowei Bao <xiaowei.bao@nxp.com>
> Sent: 2020?3?22? 19:13
> To: M.h. Lian <minghuan.lian@nxp.com>; Z.q. Hou
> <zhiqiang.hou@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
> bmeng.cn at gmail.com; yamada.masahiro at socionext.com;
> u-boot at lists.denx.de
> Cc: Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: [PATCH 4/9] PCI_EP: layerscape: Add the multiple function supprot
>
> Add the multiple function support for Layerscape platform, some PEXs of
> Layerscaple platform have more than one PF.
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> drivers/pci/pcie_layerscape.c | 6 +-
> drivers/pci/pcie_layerscape.h | 21 +++++--
> drivers/pci/pcie_layerscape_ep.c | 119
> ++++++++++++++++++++++++++-------------
> 3 files changed, 98 insertions(+), 48 deletions(-)
>
> diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
> index 3ca75c5..88a0e8a 100644
> --- a/drivers/pci/pcie_layerscape.c
> +++ b/drivers/pci/pcie_layerscape.c
> @@ -104,13 +104,13 @@ void ls_pcie_atu_outbound_set(struct ls_pcie
> *pcie, int idx, int type, }
>
> /* Use bar match mode and MEM type as default */ -void
> ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, int type,
> - int bar, u64 phys)
> +void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, int type,
> + int idx, int bar, u64 phys)
> {
> 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, type, PCIE_ATU_CR1);
> + dbi_writel(pcie, type | PCIE_ATU_FUNC_NUM(pf), PCIE_ATU_CR1);
> dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
> PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2); } diff --git
> a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h index
> 217dcda..dabfff3 100644
> --- a/drivers/pci/pcie_layerscape.h
> +++ b/drivers/pci/pcie_layerscape.h
> @@ -9,6 +9,7 @@
> #define _PCIE_LAYERSCAPE_H_
> #include <pci.h>
> #include <dm.h>
> +#include <linux/sizes.h>
>
> #ifndef CONFIG_SYS_PCI_MEMORY_BUS
> #define CONFIG_SYS_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE @@
> -44,6 +45,7 @@
> #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)
> @@ -86,11 +88,16 @@
> #define FSL_PCIE_EP_MIN_APERTURE 4096 /* 4 Kbytes */
> #define PCIE_PF_NUM 2
> #define PCIE_VF_NUM 64
> +#define BAR_NUM 4
>
> -#define PCIE_BAR0_SIZE (4 * 1024) /* 4K */
> -#define PCIE_BAR1_SIZE (8 * 1024) /* 8K for MSIX */
> -#define PCIE_BAR2_SIZE (4 * 1024) /* 4K */
> -#define PCIE_BAR4_SIZE (1 * 1024 * 1024) /* 1M */
> +#define PCIE_BAR0_SIZE SZ_4K
> +#define PCIE_BAR1_SIZE SZ_8K
> +#define PCIE_BAR2_SIZE SZ_4K
> +#define PCIE_BAR4_SIZE SZ_1M
> +
> +#define PCIE_SRIOV_VFBAR0 0x19C
> +
> +#define PCIE_MASK_OFFSET(flag, pf) ((flag) ? 0 : (0x1000 + 0x20000 *
> +(pf)))
>
> /* LUT registers */
> #define PCIE_LUT_UDR(n) (0x800 + (n) * 8)
> @@ -158,6 +165,8 @@ struct ls_pcie_ep {
> struct ls_pcie *pcie;
> struct udevice *bus;
> void __iomem *addr;
> + u32 cfg2_flag;
> + u32 sriov_flag;
> u32 num_ib_wins;
> u32 num_ob_wins;
> u8 max_functions;
> @@ -171,8 +180,8 @@ unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned
> int offset); void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
> unsigned int offset); void ls_pcie_atu_outbound_set(struct ls_pcie *pcie,
> int idx, int type,
> u64 phys, u64 bus_addr, pci_size_t size); -void
> ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, int type,
> - int bar, u64 phys);
> +void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, int type,
> + int idx, int bar, u64 phys);
> void ls_pcie_dump_atu(struct ls_pcie *pcie); int ls_pcie_link_up(struct
> ls_pcie *pcie); void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie); diff --git
> a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c
> index 8d0c99a..bec374b 100644
> --- a/drivers/pci/pcie_layerscape_ep.c
> +++ b/drivers/pci/pcie_layerscape_ep.c
> @@ -45,7 +45,7 @@ static int ls_ep_set_bar(struct udevice *dev, uint fn,
> struct pci_bar *ep_bar)
> else
> type = PCIE_ATU_TYPE_IO;
>
> - ls_pcie_atu_inbound_set(pcie, idx, bar, bar_phys, type);
> + ls_pcie_atu_inbound_set(pcie, fn, type, idx, bar, bar_phys);
>
> dbi_writel(pcie, lower_32_bits(size - 1), reg +
> PCIE_NO_SRIOV_BAR_BASE);
> dbi_writel(pcie, flags, reg);
> @@ -63,51 +63,61 @@ static struct pci_ep_ops ls_pcie_ep_ops = {
> .set_bar = ls_ep_set_bar,
> };
>
> -static void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep)
> +static void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep, u32 pf)
> {
> struct ls_pcie *pcie = pcie_ep->pcie;
> - u64 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE;
> + u64 phys = 0;
>
> + 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, PCIE_ATU_TYPE_MEM, 0, phys);
> + ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
> + 0 + pf * BAR_NUM, 0, phys);
> /* ATU 1 : INBOUND : map BAR1 */
> - phys += PCIE_BAR1_SIZE;
> - ls_pcie_atu_inbound_set(pcie, 1, PCIE_ATU_TYPE_MEM, 1, phys);
> + phys = ALIGN(phys + PCIE_BAR0_SIZE, PCIE_BAR1_SIZE);
> + ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
> + 1 + pf * BAR_NUM, 1, phys);
> /* ATU 2 : INBOUND : map BAR2 */
> - phys += PCIE_BAR2_SIZE;
> - ls_pcie_atu_inbound_set(pcie, 2, PCIE_ATU_TYPE_MEM, 2, phys);
> - /* ATU 3 : INBOUND : map BAR4 */
> - phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR4_SIZE;
> - ls_pcie_atu_inbound_set(pcie, 3, PCIE_ATU_TYPE_MEM, 4, phys);
> -
> - /* ATU 0 : OUTBOUND : map MEM */
> - ls_pcie_atu_outbound_set(pcie, 0,
> - PCIE_ATU_TYPE_MEM,
> - pcie_ep->addr_res.start,
> - 0,
> - CONFIG_SYS_PCI_MEMORY_SIZE);
> + phys = ALIGN(phys + PCIE_BAR1_SIZE, PCIE_BAR2_SIZE);
> + ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
> + 2 + pf * BAR_NUM, 2, phys);
> + /* ATU 3 : INBOUND : map BAR2 */
> + phys = ALIGN(phys + PCIE_BAR2_SIZE, PCIE_BAR4_SIZE);
> + ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
> + 3 + pf * BAR_NUM, 4, phys);
> +
> + /* ATU: OUTBOUND : map MEM */
> + ls_pcie_atu_outbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
> + (u64)pcie_ep->addr_res.start +
> + pf * CONFIG_SYS_PCI_MEMORY_SIZE,
> + 0, CONFIG_SYS_PCI_MEMORY_SIZE);
> }
>
> /* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */ static void
> ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size) {
> + u32 mask;
> +
> /* The least inbound window is 4KiB */
> - if (size < 4 * 1024)
> - return;
> + if (size < SZ_4K)
> + mask = 0;
> + else
> + mask = size - 1;
>
> switch (bar) {
> case 0:
> - writel(size - 1, bar_base + PCI_BASE_ADDRESS_0);
> + writel(mask, bar_base + PCI_BASE_ADDRESS_0);
> break;
> case 1:
> - writel(size - 1, bar_base + PCI_BASE_ADDRESS_1);
> + writel(mask, bar_base + PCI_BASE_ADDRESS_1);
> break;
> case 2:
> - writel(size - 1, bar_base + PCI_BASE_ADDRESS_2);
> + writel(mask, bar_base + PCI_BASE_ADDRESS_2);
> writel(0, bar_base + PCI_BASE_ADDRESS_3);
> break;
> case 4:
> - writel(size - 1, bar_base + PCI_BASE_ADDRESS_4);
> + writel(mask, bar_base + PCI_BASE_ADDRESS_4);
> writel(0, bar_base + PCI_BASE_ADDRESS_5);
> break;
> default:
> @@ -117,39 +127,62 @@ static void ls_pcie_ep_setup_bar(void *bar_base,
> int bar, u32 size)
>
> static void ls_pcie_ep_setup_bars(void *bar_base) {
> - /* BAR0 - 32bit - 4K configuration */
> + /* BAR0 - 32bit - MEM */
> + ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
> + /* BAR1 - 32bit - MEM*/
> + ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
> + /* BAR2 - 64bit - MEM */
> + ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
> + /* BAR4 - 64bit - MEM */
> + ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE); }
> +
> +static void ls_pcie_ep_setup_vf_bars(void *bar_base) {
> + /* VF BAR0 MASK register at offset 0x19c*/
> + bar_base += PCIE_SRIOV_VFBAR0 - PCI_BASE_ADDRESS_0;
> +
> + /* VF-BAR0 - 32bit - MEM */
> ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
> - /* BAR1 - 32bit - 8K MSIX */
> + /* VF-BAR1 - 32bit - MEM*/
> ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
> - /* BAR2 - 64bit - 4K MEM descriptor */
> + /* VF-BAR2 - 64bit - MEM */
> ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
> - /* BAR4 - 64bit - 1M MEM */
> + /* VF-BAR4 - 64bit - MEM */
> ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE); }
>
> static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep) {
> u32 sriov;
> + u32 pf, vf;
> + void *bar_base = NULL;
> struct ls_pcie *pcie = pcie_ep->pcie;
>
> sriov = readl(pcie->dbi + PCIE_SRIOV);
> if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) {
> - int pf, vf;
> -
> + pcie_ep->sriov_flag = 1;
> for (pf = 0; pf < PCIE_PF_NUM; pf++) {
> - for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
> - ctrl_writel(pcie, PCIE_LCTRL0_VAL(pf, vf),
> - PCIE_PF_VF_CTRL);
> -
> - ls_pcie_ep_setup_bars(pcie->dbi);
> - ls_pcie_ep_setup_atu(pcie_ep);
> + if (pcie_ep->cfg2_flag) {
> + for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
> + ctrl_writel(pcie,
> + PCIE_LCTRL0_VAL(pf, vf),
> + PCIE_PF_VF_CTRL);
> + }
> }
> + bar_base = pcie->dbi +
> + PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf);
> + ls_pcie_ep_setup_bars(bar_base);
> + ls_pcie_ep_setup_vf_bars(bar_base);
> +
> + ls_pcie_ep_setup_atu(pcie_ep, pf);
> }
> - /* Disable CFG2 */
> - ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL);
> +
> + if (pcie_ep->cfg2_flag) /* Disable CFG2 */
> + ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL);
> } else {
> ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE);
> - ls_pcie_ep_setup_atu(pcie_ep);
> + ls_pcie_ep_setup_atu(pcie_ep, 0);
> }
>
> ls_pcie_ep_enable_cfg(pcie_ep);
> @@ -161,6 +194,7 @@ static int ls_pcie_ep_probe(struct udevice *dev)
> struct ls_pcie *pcie;
> u16 link_sta;
> int ret;
> + u32 svr;
>
> pcie = devm_kmalloc(dev, sizeof(*pcie), GFP_KERNEL);
> if (!pcie)
> @@ -190,6 +224,13 @@ static int ls_pcie_ep_probe(struct udevice *dev)
> pcie->big_endian = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
> "big-endian");
>
> + svr = SVR_SOC_VER(get_svr());
> +
> + if (svr == SVR_LS2080A || svr == SVR_LS2085A)
> + pcie_ep->cfg2_flag = 1;
> + else
> + pcie_ep->cfg2_flag = 0;
> +
> pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f;
> if (pcie->mode != PCI_HEADER_TYPE_NORMAL)
> return 0;
> --
> 2.9.5
Reviewed-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 5/9] pci_ep: layerscape: Add the workaround for errata A-009460
2020-03-22 11:12 ` [PATCH 5/9] pci_ep: layerscape: Add the workaround for errata A-009460 Xiaowei Bao
@ 2020-04-28 12:25 ` Z.q. Hou
0 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2020-04-28 12:25 UTC (permalink / raw)
To: u-boot
> -----Original Message-----
> From: Xiaowei Bao <xiaowei.bao@nxp.com>
> Sent: 2020?3?22? 19:13
> To: M.h. Lian <minghuan.lian@nxp.com>; Z.q. Hou
> <zhiqiang.hou@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
> bmeng.cn at gmail.com; yamada.masahiro at socionext.com;
> u-boot at lists.denx.de
> Cc: Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: [PATCH 5/9] pci_ep: layerscape: Add the workaround for errata
> A-009460
>
> The VF_BARn_REG register's Prefetchable and Type bit fields are overwritten
> by a write to VF's BAR Mask register.
> workaround: Before writing to the VF_BARn_MASK_REG register, write 0b to
> the PCIE_MISC_CONTROL_1_OFF register.
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> drivers/pci/pcie_layerscape_ep.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/pci/pcie_layerscape_ep.c
> b/drivers/pci/pcie_layerscape_ep.c
> index bec374b..a2b18ad 100644
> --- a/drivers/pci/pcie_layerscape_ep.c
> +++ b/drivers/pci/pcie_layerscape_ep.c
> @@ -163,6 +163,15 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep
> *pcie_ep)
> if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) {
> pcie_ep->sriov_flag = 1;
> for (pf = 0; pf < PCIE_PF_NUM; pf++) {
> + /*
> + * The VF_BARn_REG register's Prefetchable and Type bit
> + * fields are overwritten by a write to VF's BAR Mask
> + * register. Before writing to the VF_BARn_MASK_REG
> + * register, write 0b to the PCIE_MISC_CONTROL_1_OFF
> + * register.
> + */
> + writel(0, pcie->dbi + PCIE_MISC_CONTROL_1_OFF);
> +
> if (pcie_ep->cfg2_flag) {
> for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
> ctrl_writel(pcie,
> --
> 2.9.5
Reviewed-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 6/9] pci_ep: layerscape: Add Support for ls2085a and ls2080a EP mode
2020-03-22 11:12 ` [PATCH 6/9] pci_ep: layerscape: Add Support for ls2085a and ls2080a EP mode Xiaowei Bao
@ 2020-04-28 12:25 ` Z.q. Hou
0 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2020-04-28 12:25 UTC (permalink / raw)
To: u-boot
> -----Original Message-----
> From: Xiaowei Bao <xiaowei.bao@nxp.com>
> Sent: 2020?3?22? 19:13
> To: M.h. Lian <minghuan.lian@nxp.com>; Z.q. Hou
> <zhiqiang.hou@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
> bmeng.cn at gmail.com; yamada.masahiro at socionext.com;
> u-boot at lists.denx.de
> Cc: Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: [PATCH 6/9] pci_ep: layerscape: Add Support for ls2085a and
> ls2080a EP mode
>
> Due to the ls2085a and ls2080a use difference way to set the BAR size, so
> add the BAR size init code here.
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> drivers/pci/pcie_layerscape_ep.c | 18 +++++++++++++-----
> 1 file changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/pci/pcie_layerscape_ep.c
> b/drivers/pci/pcie_layerscape_ep.c
> index a2b18ad..cd7ea26 100644
> --- a/drivers/pci/pcie_layerscape_ep.c
> +++ b/drivers/pci/pcie_layerscape_ep.c
> @@ -172,17 +172,25 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep
> *pcie_ep)
> */
> writel(0, pcie->dbi + PCIE_MISC_CONTROL_1_OFF);
>
> + bar_base = pcie->dbi +
> + PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf);
> +
> if (pcie_ep->cfg2_flag) {
> - for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
> + ctrl_writel(pcie,
> + PCIE_LCTRL0_VAL(pf, 0),
> + PCIE_PF_VF_CTRL);
> + ls_pcie_ep_setup_bars(bar_base);
> +
> + for (vf = 1; vf <= PCIE_VF_NUM; vf++) {
> ctrl_writel(pcie,
> PCIE_LCTRL0_VAL(pf, vf),
> PCIE_PF_VF_CTRL);
> + ls_pcie_ep_setup_vf_bars(bar_base);
> }
> + } else {
> + ls_pcie_ep_setup_bars(bar_base);
> + ls_pcie_ep_setup_vf_bars(bar_base);
> }
> - bar_base = pcie->dbi +
> - PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf);
> - ls_pcie_ep_setup_bars(bar_base);
> - ls_pcie_ep_setup_vf_bars(bar_base);
>
> ls_pcie_ep_setup_atu(pcie_ep, pf);
> }
> --
> 2.9.5
Reviewed-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 7/9] pci_ep: layerscape: Add the SRIOV VFs of PF support
2020-03-22 11:12 ` [PATCH 7/9] pci_ep: layerscape: Add the SRIOV VFs of PF support Xiaowei Bao
@ 2020-04-28 12:26 ` Z.q. Hou
0 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2020-04-28 12:26 UTC (permalink / raw)
To: u-boot
> -----Original Message-----
> From: Xiaowei Bao <xiaowei.bao@nxp.com>
> Sent: 2020?3?22? 19:13
> To: M.h. Lian <minghuan.lian@nxp.com>; Z.q. Hou
> <zhiqiang.hou@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
> bmeng.cn at gmail.com; yamada.masahiro at socionext.com;
> u-boot at lists.denx.de
> Cc: Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: [PATCH 7/9] pci_ep: layerscape: Add the SRIOV VFs of PF support
>
> Add the INBOUND configuration for VFs of PF.
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> drivers/pci/pcie_layerscape.c | 8 +++++---
> drivers/pci/pcie_layerscape.h | 13 ++++++++-----
> drivers/pci/pcie_layerscape_ep.c | 34
> +++++++++++++++++++++++++++++-----
> 3 files changed, 42 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
> index 88a0e8a..c7a96ed 100644
> --- a/drivers/pci/pcie_layerscape.c
> +++ b/drivers/pci/pcie_layerscape.c
> @@ -91,7 +91,7 @@ int ls_pcie_link_up(struct ls_pcie *pcie) }
>
> 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); @@ -104,14
> +104,16 @@ void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int
> type, }
>
> /* Use bar match mode and MEM type as default */ -void
> ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, int type,
> - int idx, int bar, u64 phys)
> +void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag,
> + int type, int idx, int bar, u64 phys)
> {
> 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, type | PCIE_ATU_FUNC_NUM(pf), PCIE_ATU_CR1);
> dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
> + (vf_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); }
>
> diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h
> index dabfff3..26d0177 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,6 +40,7 @@
> #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)
> @@ -49,6 +50,8 @@
> #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 BIT(19)
> +#define PCIE_ATU_VFBAR_MATCH_MODE_EN BIT(26)
> #define PCIE_ATU_BAR_NUM(bar) ((bar) << 8)
> #define PCIE_ATU_LOWER_BASE 0x90C
> #define PCIE_ATU_UPPER_BASE 0x910
> @@ -88,7 +91,7 @@
> #define FSL_PCIE_EP_MIN_APERTURE 4096 /* 4 Kbytes */
> #define PCIE_PF_NUM 2
> #define PCIE_VF_NUM 64
> -#define BAR_NUM 4
> +#define BAR_NUM 8
>
> #define PCIE_BAR0_SIZE SZ_4K
> #define PCIE_BAR1_SIZE SZ_8K
> @@ -179,9 +182,9 @@ void dbi_writel(struct ls_pcie *pcie, unsigned int
> value, unsigned int offset); unsigned int ctrl_readl(struct ls_pcie *pcie,
> unsigned int offset); void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
> unsigned int offset); void ls_pcie_atu_outbound_set(struct ls_pcie *pcie,
> int idx, int type,
> - u64 phys, u64 bus_addr, pci_size_t size);
> -void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, int type,
> - int idx, int bar, u64 phys);
> + u64 phys, u64 bus_addr, u64 size); void
> +ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag,
> + int type, int idx, int bar, u64 phys);
> void ls_pcie_dump_atu(struct ls_pcie *pcie); int ls_pcie_link_up(struct
> ls_pcie *pcie); void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie); diff --git
> a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c
> index cd7ea26..67ce36c 100644
> --- a/drivers/pci/pcie_layerscape_ep.c
> +++ b/drivers/pci/pcie_layerscape_ep.c
> @@ -45,7 +45,7 @@ static int ls_ep_set_bar(struct udevice *dev, uint fn,
> struct pci_bar *ep_bar)
> else
> type = PCIE_ATU_TYPE_IO;
>
> - ls_pcie_atu_inbound_set(pcie, fn, type, idx, bar, bar_phys);
> + ls_pcie_atu_inbound_set(pcie, fn, 0, type, idx, bar, bar_phys);
>
> dbi_writel(pcie, lower_32_bits(size - 1), reg +
> PCIE_NO_SRIOV_BAR_BASE);
> dbi_writel(pcie, flags, reg);
> @@ -66,27 +66,51 @@ static struct pci_ep_ops ls_pcie_ep_ops = { static
> void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep, u32 pf) {
> struct ls_pcie *pcie = pcie_ep->pcie;
> + u32 vf_flag = 0;
> u64 phys = 0;
>
> 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, pf, PCIE_ATU_TYPE_MEM,
> + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
> 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, pf, PCIE_ATU_TYPE_MEM,
> + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
> 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, pf, PCIE_ATU_TYPE_MEM,
> + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
> 2 + pf * BAR_NUM, 2, phys);
> /* ATU 3 : INBOUND : map BAR2 */
> phys = ALIGN(phys + PCIE_BAR2_SIZE, PCIE_BAR4_SIZE);
> - ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
> + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
> 3 + pf * BAR_NUM, 4, phys);
>
> + if (pcie_ep->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, PCIE_ATU_TYPE_MEM,
> + 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, PCIE_ATU_TYPE_MEM,
> + 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, PCIE_ATU_TYPE_MEM,
> + 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, PCIE_ATU_TYPE_MEM,
> + 7 + pf * BAR_NUM, 4, phys);
> + }
> +
> /* ATU: OUTBOUND : map MEM */
> ls_pcie_atu_outbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
> (u64)pcie_ep->addr_res.start +
> --
> 2.9.5
Reviewed-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 8/9] pci: layerscaple: Modify the ls_pcie_dump_atu function
2020-03-22 11:12 ` [PATCH 8/9] pci: layerscaple: Modify the ls_pcie_dump_atu function Xiaowei Bao
@ 2020-04-28 12:26 ` Z.q. Hou
0 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2020-04-28 12:26 UTC (permalink / raw)
To: u-boot
> -----Original Message-----
> From: Xiaowei Bao <xiaowei.bao@nxp.com>
> Sent: 2020?3?22? 19:13
> To: M.h. Lian <minghuan.lian@nxp.com>; Z.q. Hou
> <zhiqiang.hou@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
> bmeng.cn at gmail.com; yamada.masahiro at socionext.com;
> u-boot at lists.denx.de
> Cc: Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: [PATCH 8/9] pci: layerscaple: Modify the ls_pcie_dump_atu function
>
> Modify the ls_pcie_dump_atu function, make it can print the INBOUND
> windows registers.
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> drivers/pci/pcie_layerscape.c | 25 +++++++++++++------------
> drivers/pci/pcie_layerscape.h | 2 +-
> drivers/pci/pcie_layerscape_ep.c | 3 +++
> drivers/pci/pcie_layerscape_rc.c | 2 +-
> 4 files changed, 18 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
> index c7a96ed..4015a0d 100644
> --- a/drivers/pci/pcie_layerscape.c
> +++ b/drivers/pci/pcie_layerscape.c
> @@ -117,24 +117,25 @@ void ls_pcie_atu_inbound_set(struct ls_pcie *pcie,
> u32 pf, u32 vf_flag,
> PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2); }
>
> -void ls_pcie_dump_atu(struct ls_pcie *pcie)
> +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",
> dbi_readl(pcie, PCIE_ATU_UPPER_BASE));
> - debug("\tLOWER BUS 0x%08x\n",
> - dbi_readl(pcie, PCIE_ATU_LOWER_TARGET));
> - debug("\tUPPER BUS 0x%08x\n",
> - dbi_readl(pcie, PCIE_ATU_UPPER_TARGET));
> - debug("\tLIMIT 0x%08x\n",
> - dbi_readl(pcie, PCIE_ATU_LIMIT));
> + if (type == PCIE_ATU_REGION_OUTBOUND) {
> + debug("\tLOWER BUS 0x%08x\n",
> + dbi_readl(pcie, PCIE_ATU_LOWER_TARGET));
> + debug("\tUPPER BUS 0x%08x\n",
> + dbi_readl(pcie, PCIE_ATU_UPPER_TARGET));
> + debug("\tLIMIT 0x%08x\n",
> + dbi_readl(pcie, PCIE_ATU_LIMIT));
> + }
> debug("\tCR1 0x%08x\n",
> dbi_readl(pcie, PCIE_ATU_CR1));
> debug("\tCR2 0x%08x\n",
> diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h
> index 26d0177..5f5c51d 100644
> --- a/drivers/pci/pcie_layerscape.h
> +++ b/drivers/pci/pcie_layerscape.h
> @@ -185,7 +185,7 @@ void ls_pcie_atu_outbound_set(struct ls_pcie *pcie,
> int idx, int type,
> u64 phys, u64 bus_addr, u64 size); void
> ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag,
> int type, int idx, int bar, u64 phys); -void
> ls_pcie_dump_atu(struct ls_pcie *pcie);
> +void ls_pcie_dump_atu(struct ls_pcie *pcie, u32 win_num, u32 type);
> int ls_pcie_link_up(struct ls_pcie *pcie); void ls_pcie_dbi_ro_wr_en(struct
> ls_pcie *pcie); void ls_pcie_dbi_ro_wr_dis(struct ls_pcie *pcie); diff --git
> a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c
> index 67ce36c..ebf69ee 100644
> --- a/drivers/pci/pcie_layerscape_ep.c
> +++ b/drivers/pci/pcie_layerscape_ep.c
> @@ -226,6 +226,9 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep
> *pcie_ep)
> ls_pcie_ep_setup_atu(pcie_ep, 0);
> }
>
> + ls_pcie_dump_atu(pcie, PCIE_ATU_REGION_NUM_SRIOV,
> + PCIE_ATU_REGION_INBOUND);
> +
> ls_pcie_ep_enable_cfg(pcie_ep);
> }
>
> diff --git a/drivers/pci/pcie_layerscape_rc.c
> b/drivers/pci/pcie_layerscape_rc.c
> index 927722d..b045159 100644
> --- a/drivers/pci/pcie_layerscape_rc.c
> +++ b/drivers/pci/pcie_layerscape_rc.c
> @@ -114,7 +114,7 @@ static void ls_pcie_setup_atu(struct ls_pcie_rc
> *pcie_rc)
> 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 */
> --
> 2.9.5
Reviewed-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 9/9] pci_ep: layerscape: Add the PCIe EP mode support for lx2160a-v2
2020-03-22 11:12 ` [PATCH 9/9] pci_ep: layerscape: Add the PCIe EP mode support for lx2160a-v2 Xiaowei Bao
@ 2020-04-28 12:26 ` Z.q. Hou
0 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2020-04-28 12:26 UTC (permalink / raw)
To: u-boot
> -----Original Message-----
> From: Xiaowei Bao <xiaowei.bao@nxp.com>
> Sent: 2020?3?22? 19:13
> To: M.h. Lian <minghuan.lian@nxp.com>; Z.q. Hou
> <zhiqiang.hou@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
> bmeng.cn at gmail.com; yamada.masahiro at socionext.com;
> u-boot at lists.denx.de
> Cc: Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: [PATCH 9/9] pci_ep: layerscape: Add the PCIe EP mode support for
> lx2160a-v2
>
> Add the PCIe EP mode support for lx2160a-v2 platform.
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> drivers/pci/pcie_layerscape.h | 9 ++++++++-
> drivers/pci/pcie_layerscape_ep.c | 8 +++++++-
> 2 files changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h
> index 5f5c51d..593798e 100644
> --- a/drivers/pci/pcie_layerscape.h
> +++ b/drivers/pci/pcie_layerscape.h
> @@ -100,7 +100,7 @@
>
> #define PCIE_SRIOV_VFBAR0 0x19C
>
> -#define PCIE_MASK_OFFSET(flag, pf) ((flag) ? 0 : (0x1000 + 0x20000 * (pf)))
> +#define PCIE_MASK_OFFSET(flag, pf, off) ((flag) ? 0 : (0x1000 + (off) *
> +(pf)))
>
> /* LUT registers */
> #define PCIE_LUT_UDR(n) (0x800 + (n) * 8)
> @@ -139,6 +139,12 @@
> #define LS1021_PEXMSCPORTSR(pex_idx) (0x94 + (pex_idx) * 4)
> #define LS1021_LTSSM_STATE_SHIFT 20
>
> +/* LX2160a PF1 offset */
> +#define LX2160_PCIE_PF1_OFFSET 0x8000
> +
> +/* layerscape PF1 offset */
> +#define LS_PCIE_PF1_OFFSET 0x20000
> +
> struct ls_pcie {
> void __iomem *dbi;
> void __iomem *lut;
> @@ -170,6 +176,7 @@ struct ls_pcie_ep {
> void __iomem *addr;
> u32 cfg2_flag;
> u32 sriov_flag;
> + u32 pf1_offset;
> u32 num_ib_wins;
> u32 num_ob_wins;
> u8 max_functions;
> diff --git a/drivers/pci/pcie_layerscape_ep.c
> b/drivers/pci/pcie_layerscape_ep.c
> index ebf69ee..0228863 100644
> --- a/drivers/pci/pcie_layerscape_ep.c
> +++ b/drivers/pci/pcie_layerscape_ep.c
> @@ -197,7 +197,8 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep
> *pcie_ep)
> writel(0, pcie->dbi + PCIE_MISC_CONTROL_1_OFF);
>
> bar_base = pcie->dbi +
> - PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf);
> + PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf,
> + pcie_ep->pf1_offset);
>
> if (pcie_ep->cfg2_flag) {
> ctrl_writel(pcie,
> @@ -270,6 +271,11 @@ static int ls_pcie_ep_probe(struct udevice *dev)
>
> svr = SVR_SOC_VER(get_svr());
>
> + if (svr == SVR_LX2160A)
> + pcie_ep->pf1_offset = LX2160_PCIE_PF1_OFFSET;
> + else
> + pcie_ep->pf1_offset = LS_PCIE_PF1_OFFSET;
> +
> if (svr == SVR_LS2080A || svr == SVR_LS2085A)
> pcie_ep->cfg2_flag = 1;
> else
> --
> 2.9.5
Reviewed-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2020-04-28 12:26 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-22 11:12 [PATCH 1/9] pci: layerscape: Split the EP and RC driver Xiaowei Bao
2020-03-22 11:12 ` [PATCH 2/9] pci_ep: Add the init function Xiaowei Bao
2020-04-28 12:23 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 3/9] armv8: dts: ls1046a: Add the PCIe EP node Xiaowei Bao
2020-04-28 12:24 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 4/9] PCI_EP: layerscape: Add the multiple function supprot Xiaowei Bao
2020-04-28 12:24 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 5/9] pci_ep: layerscape: Add the workaround for errata A-009460 Xiaowei Bao
2020-04-28 12:25 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 6/9] pci_ep: layerscape: Add Support for ls2085a and ls2080a EP mode Xiaowei Bao
2020-04-28 12:25 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 7/9] pci_ep: layerscape: Add the SRIOV VFs of PF support Xiaowei Bao
2020-04-28 12:26 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 8/9] pci: layerscaple: Modify the ls_pcie_dump_atu function Xiaowei Bao
2020-04-28 12:26 ` Z.q. Hou
2020-03-22 11:12 ` [PATCH 9/9] pci_ep: layerscape: Add the PCIe EP mode support for lx2160a-v2 Xiaowei Bao
2020-04-28 12:26 ` Z.q. Hou
2020-04-28 9:30 ` [PATCH 1/9] pci: layerscape: Split the EP and RC driver Priyanka Jain
2020-04-28 12:23 ` Z.q. Hou
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.