All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs
@ 2019-03-11  2:57 Z.q. Hou
  2019-03-11  2:57 ` [U-Boot] [PATCHv4 01/12] armv8: fsl-layerscpae: correct the PCIe controllers' region size Z.q. Hou
                   ` (11 more replies)
  0 siblings, 12 replies; 19+ messages in thread
From: Z.q. Hou @ 2019-03-11  2:57 UTC (permalink / raw)
  To: u-boot

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

Add PCIe Gen4 driver for the NXP Layerscape series SoCs.

Hou Zhiqiang (12):
  armv8: fsl-layerscpae: correct the PCIe controllers' region size
  armv8: lx2160a: add MMU table entries for PCIe
  pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs
  kconfig: add dependency PCIE_LAYERSCAPE_GEN4 for FSL_PCIE_COMPAT
  pci: ls_pcie_g4: add device tree fixups for PCI Stream IDs
  armv8: lx2160a: add PCIe controller DT nodes
  armv8: lx2160a: enable PCIe support
  pci: ls_pcie_g4: add Workaround for A-011577
  dm: pci: add APIs for capability accessors
  dm: pci: add APIs for MPS and MRRS accessors
  pci: ls_pcie_g4: Add Workaround for A-011451
  pci: ls_pcie_g4: add Workaround for A-011452

 arch/arm/cpu/armv8/fsl-layerscape/Kconfig     |   2 +-
 arch/arm/cpu/armv8/fsl-layerscape/cpu.c       |  12 +
 arch/arm/dts/fsl-lx2160a.dtsi                 |  85 +++
 .../arm/include/asm/arch-fsl-layerscape/cpu.h |   9 +
 .../asm/arch-fsl-layerscape/immap_lsch3.h     |  14 +-
 configs/lx2160aqds_tfa_SECURE_BOOT_defconfig  |   5 +
 configs/lx2160aqds_tfa_defconfig              |   6 +
 configs/lx2160ardb_tfa_SECURE_BOOT_defconfig  |   5 +
 configs/lx2160ardb_tfa_defconfig              |   6 +
 drivers/pci/Kconfig                           |   8 +
 drivers/pci/Makefile                          |   2 +
 drivers/pci/pci-uclass.c                      | 245 ++++++++
 drivers/pci/pci_auto.c                        |  35 ++
 drivers/pci/pcie_layerscape_gen4.c            | 593 ++++++++++++++++++
 drivers/pci/pcie_layerscape_gen4.h            | 273 ++++++++
 drivers/pci/pcie_layerscape_gen4_fixup.c      | 249 ++++++++
 include/pci.h                                 |  33 +
 include/pci_ids.h                             |   1 +
 18 files changed, 1581 insertions(+), 2 deletions(-)
 create mode 100644 drivers/pci/pcie_layerscape_gen4.c
 create mode 100644 drivers/pci/pcie_layerscape_gen4.h
 create mode 100644 drivers/pci/pcie_layerscape_gen4_fixup.c

-- 
2.17.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 01/12] armv8: fsl-layerscpae: correct the PCIe controllers' region size
  2019-03-11  2:57 [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
@ 2019-03-11  2:57 ` Z.q. Hou
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 02/12] armv8: lx2160a: add MMU table entries for PCIe Z.q. Hou
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2019-03-11  2:57 UTC (permalink / raw)
  To: u-boot

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

The LS2080A has 8GB region for each PCIe controller, while the
other platforms have 32GB.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V4:
 - No change

 arch/arm/include/asm/arch-fsl-layerscape/cpu.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
index d62754e045..89124cdb0e 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
@@ -34,10 +34,17 @@
 #define CONFIG_SYS_FSL_QBMAN_BASE	0x818000000
 #define CONFIG_SYS_FSL_QBMAN_SIZE	0x8000000
 #define CONFIG_SYS_FSL_QBMAN_SIZE_1	0x4000000
+#ifdef CONFIG_ARCH_LS2080A
 #define CONFIG_SYS_PCIE1_PHYS_SIZE	0x200000000
 #define CONFIG_SYS_PCIE2_PHYS_SIZE	0x200000000
 #define CONFIG_SYS_PCIE3_PHYS_SIZE	0x200000000
 #define CONFIG_SYS_PCIE4_PHYS_SIZE	0x200000000
+#else
+#define CONFIG_SYS_PCIE1_PHYS_SIZE	0x800000000
+#define CONFIG_SYS_PCIE2_PHYS_SIZE	0x800000000
+#define CONFIG_SYS_PCIE3_PHYS_SIZE	0x800000000
+#define CONFIG_SYS_PCIE4_PHYS_SIZE	0x800000000
+#endif
 #define CONFIG_SYS_FSL_WRIOP1_BASE	0x4300000000
 #define CONFIG_SYS_FSL_WRIOP1_SIZE	0x100000000
 #define CONFIG_SYS_FSL_AIOP1_BASE	0x4b00000000
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 02/12] armv8: lx2160a: add MMU table entries for PCIe
  2019-03-11  2:57 [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
  2019-03-11  2:57 ` [U-Boot] [PATCHv4 01/12] armv8: fsl-layerscpae: correct the PCIe controllers' region size Z.q. Hou
@ 2019-03-11  2:58 ` Z.q. Hou
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 03/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2019-03-11  2:58 UTC (permalink / raw)
  To: u-boot

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

The lx2160a have up to 6 PCIe controllers and have different
address and size of PCIe region.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V4:
 - No change

 arch/arm/cpu/armv8/fsl-layerscape/cpu.c            | 12 ++++++++++++
 arch/arm/include/asm/arch-fsl-layerscape/cpu.h     |  2 ++
 .../include/asm/arch-fsl-layerscape/immap_lsch3.h  | 14 +++++++++++++-
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
index 978d46b32f..2805e5f6f2 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
@@ -257,6 +257,18 @@ static struct mm_region final_map[] = {
 	  PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 	  PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
 	},
+#endif
+#ifdef CONFIG_ARCH_LX2160A
+	{ SYS_PCIE5_PHYS_ADDR, SYS_PCIE5_PHYS_ADDR,
+	  SYS_PCIE5_PHYS_SIZE,
+	  PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+	  PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	},
+	{ SYS_PCIE6_PHYS_ADDR, SYS_PCIE6_PHYS_ADDR,
+	  SYS_PCIE6_PHYS_SIZE,
+	  PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+	  PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	},
 #endif
 	{ CONFIG_SYS_FSL_WRIOP1_BASE, CONFIG_SYS_FSL_WRIOP1_BASE,
 	  CONFIG_SYS_FSL_WRIOP1_SIZE,
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
index 89124cdb0e..bdeb62576c 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
@@ -44,6 +44,8 @@
 #define CONFIG_SYS_PCIE2_PHYS_SIZE	0x800000000
 #define CONFIG_SYS_PCIE3_PHYS_SIZE	0x800000000
 #define CONFIG_SYS_PCIE4_PHYS_SIZE	0x800000000
+#define SYS_PCIE5_PHYS_SIZE		0x800000000
+#define SYS_PCIE6_PHYS_SIZE		0x800000000
 #endif
 #define CONFIG_SYS_FSL_WRIOP1_BASE	0x4300000000
 #define CONFIG_SYS_FSL_WRIOP1_SIZE	0x100000000
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
index 9fab88ab2f..c9aa0cad71 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
@@ -167,7 +167,19 @@
 #define CONFIG_SYS_PCIE2_ADDR			(CONFIG_SYS_IMMR + 0x2500000)
 #define CONFIG_SYS_PCIE3_ADDR			(CONFIG_SYS_IMMR + 0x2600000)
 #define CONFIG_SYS_PCIE4_ADDR			(CONFIG_SYS_IMMR + 0x2700000)
-#ifdef CONFIG_ARCH_LS1088A
+#ifdef CONFIG_ARCH_LX2160A
+#define SYS_PCIE5_ADDR				(CONFIG_SYS_IMMR + 0x2800000)
+#define SYS_PCIE6_ADDR				(CONFIG_SYS_IMMR + 0x2900000)
+#endif
+
+#ifdef CONFIG_ARCH_LX2160A
+#define CONFIG_SYS_PCIE1_PHYS_ADDR		0x8000000000ULL
+#define CONFIG_SYS_PCIE2_PHYS_ADDR		0x8800000000ULL
+#define CONFIG_SYS_PCIE3_PHYS_ADDR		0x9000000000ULL
+#define CONFIG_SYS_PCIE4_PHYS_ADDR		0x9800000000ULL
+#define SYS_PCIE5_PHYS_ADDR			0xa000000000ULL
+#define SYS_PCIE6_PHYS_ADDR			0xa800000000ULL
+#elif CONFIG_ARCH_LS1088A
 #define CONFIG_SYS_PCIE1_PHYS_ADDR		0x2000000000ULL
 #define CONFIG_SYS_PCIE2_PHYS_ADDR		0x2800000000ULL
 #define CONFIG_SYS_PCIE3_PHYS_ADDR		0x3000000000ULL
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 03/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs
  2019-03-11  2:57 [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
  2019-03-11  2:57 ` [U-Boot] [PATCHv4 01/12] armv8: fsl-layerscpae: correct the PCIe controllers' region size Z.q. Hou
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 02/12] armv8: lx2160a: add MMU table entries for PCIe Z.q. Hou
@ 2019-03-11  2:58 ` Z.q. Hou
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 04/12] kconfig: add dependency PCIE_LAYERSCAPE_GEN4 for FSL_PCIE_COMPAT Z.q. Hou
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2019-03-11  2:58 UTC (permalink / raw)
  To: u-boot

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

Add PCIe Gen4 driver for the NXP Layerscape SoCs. This PCIe
controller is based on the Mobiveil IP, which is compatible
with the PCI Expressâ„¢ Base Specification, Revision 4.0.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Signed-off-by: Bao Xiaowei <Xiaowei.Bao@nxp.com>
---
V4:
 - No change

 drivers/pci/Kconfig                |   8 +
 drivers/pci/Makefile               |   1 +
 drivers/pci/pcie_layerscape_gen4.c | 577 +++++++++++++++++++++++++++++
 drivers/pci/pcie_layerscape_gen4.h | 264 +++++++++++++
 4 files changed, 850 insertions(+)
 create mode 100644 drivers/pci/pcie_layerscape_gen4.c
 create mode 100644 drivers/pci/pcie_layerscape_gen4.h

diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 1521885bde..2638a5a72d 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -69,6 +69,14 @@ config PCI_RCAR_GEN2
 	  Renesas RCar Gen2 SoCs. The PCIe controller on RCar Gen2 is
 	  also used to access EHCI USB controller on the SoC.
 
+config PCIE_LAYERSCAPE_GEN4
+	bool "Layerscape Gen4 PCIe support"
+	depends on DM_PCI
+	help
+	  Support PCIe Gen4 on NXP Layerscape SoCs, which may have one or
+	  several PCIe controllers. The PCIe controller can work in RC or
+	  EP mode according to RCW[HOST_AGT_PEX] setting.
+
 config PCI_SANDBOX
 	bool "Sandbox PCI support"
 	depends on SANDBOX && DM_PCI
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 4923641895..7f585aad55 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -32,5 +32,6 @@ obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
 obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o
 obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o
 obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o
+obj-$(CONFIG_PCIE_LAYERSCAPE_GEN4) += pcie_layerscape_gen4.o
 obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o
 obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o
diff --git a/drivers/pci/pcie_layerscape_gen4.c b/drivers/pci/pcie_layerscape_gen4.c
new file mode 100644
index 0000000000..fbe7d35911
--- /dev/null
+++ b/drivers/pci/pcie_layerscape_gen4.c
@@ -0,0 +1,577 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018 NXP
+ *
+ * PCIe Gen4 driver for NXP Layerscape SoCs
+ * Author: Hou Zhiqiang <Minder.Hou@gmail.com>
+ */
+
+#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>
+#include <linux/sizes.h>
+
+#include "pcie_layerscape_gen4.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+LIST_HEAD(ls_pcie_g4_list);
+
+static u64 bar_size[4] = {
+	PCIE_BAR0_SIZE,
+	PCIE_BAR1_SIZE,
+	PCIE_BAR2_SIZE,
+	PCIE_BAR4_SIZE
+};
+
+static int ls_pcie_g4_ltssm(struct ls_pcie_g4 *pcie)
+{
+	u32 state;
+
+	state = pf_ctrl_readl(pcie, PCIE_LTSSM_STA) & LTSSM_STATE_MASK;
+
+	return state;
+}
+
+static int ls_pcie_g4_link_up(struct ls_pcie_g4 *pcie)
+{
+	int ltssm;
+
+	ltssm = ls_pcie_g4_ltssm(pcie);
+	if (ltssm != LTSSM_PCIE_L0)
+		return 0;
+
+	return 1;
+}
+
+static void ls_pcie_g4_ep_enable_cfg(struct ls_pcie_g4 *pcie)
+{
+	ccsr_writel(pcie, GPEX_CFG_READY, PCIE_CONFIG_READY);
+}
+
+static void ls_pcie_g4_cfg_set_target(struct ls_pcie_g4 *pcie, u32 target)
+{
+	ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_L(0), target);
+	ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_H(0), 0);
+}
+
+static int ls_pcie_g4_outbound_win_set(struct ls_pcie_g4 *pcie, int idx,
+				       int type, u64 phys, u64 bus_addr,
+				       pci_size_t size)
+{
+	u32 val;
+	u32 size_h, size_l;
+
+	if (idx >= PAB_WINS_NUM)
+		return -EINVAL;
+
+	size_h = upper_32_bits(~(size - 1));
+	size_l = lower_32_bits(~(size - 1));
+
+	val = ccsr_readl(pcie, PAB_AXI_AMAP_CTRL(idx));
+	val &= ~((AXI_AMAP_CTRL_TYPE_MASK << AXI_AMAP_CTRL_TYPE_SHIFT) |
+		(AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT) |
+		AXI_AMAP_CTRL_EN);
+	val |= ((type & AXI_AMAP_CTRL_TYPE_MASK) << AXI_AMAP_CTRL_TYPE_SHIFT) |
+		((size_l >> AXI_AMAP_CTRL_SIZE_SHIFT) <<
+		AXI_AMAP_CTRL_SIZE_SHIFT) | AXI_AMAP_CTRL_EN;
+
+	ccsr_writel(pcie, PAB_AXI_AMAP_CTRL(idx), val);
+
+	ccsr_writel(pcie, PAB_AXI_AMAP_AXI_WIN(idx), lower_32_bits(phys));
+	ccsr_writel(pcie, PAB_EXT_AXI_AMAP_AXI_WIN(idx), upper_32_bits(phys));
+	ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_L(idx), lower_32_bits(bus_addr));
+	ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_H(idx), upper_32_bits(bus_addr));
+	ccsr_writel(pcie, PAB_EXT_AXI_AMAP_SIZE(idx), size_h);
+
+	return 0;
+}
+
+static int ls_pcie_g4_rc_inbound_win_set(struct ls_pcie_g4 *pcie, int idx,
+					 int type, u64 phys, u64 bus_addr,
+					 pci_size_t size)
+{
+	u32 val;
+	pci_size_t win_size = ~(size - 1);
+
+	val = ccsr_readl(pcie, PAB_PEX_AMAP_CTRL(idx));
+
+	val &= ~(PEX_AMAP_CTRL_TYPE_MASK << PEX_AMAP_CTRL_TYPE_SHIFT);
+	val &= ~(PEX_AMAP_CTRL_EN_MASK << PEX_AMAP_CTRL_EN_SHIFT);
+	val = (val | (type << PEX_AMAP_CTRL_TYPE_SHIFT));
+	val = (val | (1 << PEX_AMAP_CTRL_EN_SHIFT));
+
+	ccsr_writel(pcie, PAB_PEX_AMAP_CTRL(idx),
+		    val | lower_32_bits(win_size));
+
+	ccsr_writel(pcie, PAB_EXT_PEX_AMAP_SIZE(idx), upper_32_bits(win_size));
+	ccsr_writel(pcie, PAB_PEX_AMAP_AXI_WIN(idx), lower_32_bits(phys));
+	ccsr_writel(pcie, PAB_EXT_PEX_AMAP_AXI_WIN(idx), upper_32_bits(phys));
+	ccsr_writel(pcie, PAB_PEX_AMAP_PEX_WIN_L(idx), lower_32_bits(bus_addr));
+	ccsr_writel(pcie, PAB_PEX_AMAP_PEX_WIN_H(idx), upper_32_bits(bus_addr));
+
+	return 0;
+}
+
+static void ls_pcie_g4_dump_wins(struct ls_pcie_g4 *pcie, int wins)
+{
+	int i;
+
+	for (i = 0; i < wins; i++) {
+		debug("APIO Win%d:\n", i);
+		debug("\tLOWER PHYS:	0x%08x\n",
+		      ccsr_readl(pcie, PAB_AXI_AMAP_AXI_WIN(i)));
+		debug("\tUPPER PHYS:	0x%08x\n",
+		      ccsr_readl(pcie, PAB_EXT_AXI_AMAP_AXI_WIN(i)));
+		debug("\tLOWER BUS:	0x%08x\n",
+		      ccsr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_L(i)));
+		debug("\tUPPER BUS:	0x%08x\n",
+		      ccsr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_H(i)));
+		debug("\tSIZE:		0x%08x\n",
+		      ccsr_readl(pcie, PAB_AXI_AMAP_CTRL(i)) &
+		      (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT));
+		debug("\tEXT_SIZE:	0x%08x\n",
+		      ccsr_readl(pcie, PAB_EXT_AXI_AMAP_SIZE(i)));
+		debug("\tPARAM:		0x%08x\n",
+		      ccsr_readl(pcie, PAB_AXI_AMAP_PCI_HDR_PARAM(i)));
+		debug("\tCTRL:		0x%08x\n",
+		      ccsr_readl(pcie, PAB_AXI_AMAP_CTRL(i)));
+	}
+}
+
+static void ls_pcie_g4_setup_wins(struct ls_pcie_g4 *pcie)
+{
+	struct pci_region *io, *mem, *pref;
+	int idx = 1;
+
+	/* INBOUND WIN */
+	ls_pcie_g4_rc_inbound_win_set(pcie, 0, IB_TYPE_MEM_F, 0, 0, SIZE_1T);
+
+	/* OUTBOUND WIN 0: CFG */
+	ls_pcie_g4_outbound_win_set(pcie, 0, PAB_AXI_TYPE_CFG,
+				    pcie->cfg_res.start, 0,
+				    fdt_resource_size(&pcie->cfg_res));
+
+	pci_get_regions(pcie->bus, &io, &mem, &pref);
+
+	if (io)
+		/* OUTBOUND WIN: IO */
+		ls_pcie_g4_outbound_win_set(pcie, idx++, PAB_AXI_TYPE_IO,
+					    io->phys_start, io->bus_start,
+					    io->size);
+
+	if (mem)
+		/* OUTBOUND WIN: MEM */
+		ls_pcie_g4_outbound_win_set(pcie, idx++, PAB_AXI_TYPE_MEM,
+					    mem->phys_start, mem->bus_start,
+					    mem->size);
+
+	if (pref)
+		/* OUTBOUND WIN: perf MEM */
+		ls_pcie_g4_outbound_win_set(pcie, idx++, PAB_AXI_TYPE_MEM,
+					    pref->phys_start, pref->bus_start,
+					    pref->size);
+
+	ls_pcie_g4_dump_wins(pcie, idx);
+}
+
+/* Return 0 if the address is valid, -errno if not valid */
+static int ls_pcie_g4_addr_valid(struct ls_pcie_g4 *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_g4_link_up(pcie)))
+		return -EINVAL;
+
+	if (PCI_BUS(bdf) <= (bus->seq + 1) && (PCI_DEV(bdf) > 0))
+		return -EINVAL;
+
+	return 0;
+}
+
+void *ls_pcie_g4_conf_address(struct ls_pcie_g4 *pcie, pci_dev_t bdf,
+			      int offset)
+{
+	struct udevice *bus = pcie->bus;
+	u32 target;
+
+	if (PCI_BUS(bdf) == bus->seq) {
+		if (offset < INDIRECT_ADDR_BNDRY) {
+			ccsr_set_page(pcie, 0);
+			return pcie->ccsr + offset;
+		}
+
+		ccsr_set_page(pcie, OFFSET_TO_PAGE_IDX(offset));
+		return pcie->ccsr + OFFSET_TO_PAGE_ADDR(offset);
+	}
+
+	target = PAB_TARGET_BUS(PCI_BUS(bdf) - bus->seq) |
+		 PAB_TARGET_DEV(PCI_DEV(bdf)) |
+		 PAB_TARGET_FUNC(PCI_FUNC(bdf));
+
+	ls_pcie_g4_cfg_set_target(pcie, target);
+
+	return pcie->cfg + offset;
+}
+
+static int ls_pcie_g4_read_config(struct udevice *bus, pci_dev_t bdf,
+				  uint offset, ulong *valuep,
+				  enum pci_size_t size)
+{
+	struct ls_pcie_g4 *pcie = dev_get_priv(bus);
+	void *address;
+	int ret = 0;
+
+	if (ls_pcie_g4_addr_valid(pcie, bdf)) {
+		*valuep = pci_get_ff(size);
+		return 0;
+	}
+
+	address = ls_pcie_g4_conf_address(pcie, bdf, offset);
+
+	switch (size) {
+	case PCI_SIZE_8:
+		*valuep = readb(address);
+		break;
+	case PCI_SIZE_16:
+		*valuep = readw(address);
+		break;
+	case PCI_SIZE_32:
+		*valuep = readl(address);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int ls_pcie_g4_write_config(struct udevice *bus, pci_dev_t bdf,
+				   uint offset, ulong value,
+				   enum pci_size_t size)
+{
+	struct ls_pcie_g4 *pcie = dev_get_priv(bus);
+	void *address;
+
+	if (ls_pcie_g4_addr_valid(pcie, bdf))
+		return 0;
+
+	address = ls_pcie_g4_conf_address(pcie, bdf, offset);
+
+	switch (size) {
+	case PCI_SIZE_8:
+		writeb(value, address);
+		return 0;
+	case PCI_SIZE_16:
+		writew(value, address);
+		return 0;
+	case PCI_SIZE_32:
+		writel(value, address);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static void ls_pcie_g4_setup_ctrl(struct ls_pcie_g4 *pcie)
+{
+	u32 val;
+
+	/* Fix class code */
+	val = ccsr_readl(pcie, GPEX_CLASSCODE);
+	val &= ~(GPEX_CLASSCODE_MASK << GPEX_CLASSCODE_SHIFT);
+	val |= PCI_CLASS_BRIDGE_PCI << GPEX_CLASSCODE_SHIFT;
+	ccsr_writel(pcie, GPEX_CLASSCODE, val);
+
+	/* Enable APIO and Memory/IO/CFG Wins */
+	val = ccsr_readl(pcie, PAB_AXI_PIO_CTRL(0));
+	val |= APIO_EN | MEM_WIN_EN | IO_WIN_EN | CFG_WIN_EN;
+	ccsr_writel(pcie, PAB_AXI_PIO_CTRL(0), val);
+
+	ls_pcie_g4_setup_wins(pcie);
+
+	pcie->stream_id_cur = 0;
+}
+
+static void ls_pcie_g4_ep_inbound_win_set(struct ls_pcie_g4 *pcie, int pf,
+					  int bar, u64 phys)
+{
+	u32 val;
+
+	/* PF BAR1 is for MSI-X and only need to enable */
+	if (bar == 1) {
+		ccsr_writel(pcie, PAB_PEX_BAR_AMAP(pf, bar), BAR_AMAP_EN);
+		return;
+	}
+
+	val = upper_32_bits(phys);
+	ccsr_writel(pcie, PAB_EXT_PEX_BAR_AMAP(pf, bar), val);
+	val = lower_32_bits(phys) | BAR_AMAP_EN;
+	ccsr_writel(pcie, PAB_PEX_BAR_AMAP(pf, bar), val);
+}
+
+static void ls_pcie_g4_ep_setup_wins(struct ls_pcie_g4 *pcie, int pf)
+{
+	u64 phys;
+	int bar;
+	u32 val;
+
+	if ((!pcie->sriov_support && pf > LS_G4_PF0) || pf > LS_G4_PF1)
+		return;
+
+	phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR_SIZE * 4 * pf;
+	for (bar = 0; bar < PF_BAR_NUM; bar++) {
+		ls_pcie_g4_ep_inbound_win_set(pcie, pf, bar, phys);
+		phys += PCIE_BAR_SIZE;
+	}
+
+	/* OUTBOUND: map MEM */
+	ls_pcie_g4_outbound_win_set(pcie, pf, PAB_AXI_TYPE_MEM,
+				    pcie->cfg_res.start +
+				    CONFIG_SYS_PCI_MEMORY_SIZE * pf, 0x0,
+				    CONFIG_SYS_PCI_MEMORY_SIZE);
+
+	val = ccsr_readl(pcie, PAB_AXI_AMAP_PCI_HDR_PARAM(pf));
+	val &= ~FUNC_NUM_PCIE_MASK;
+	val |= pf;
+	ccsr_writel(pcie, PAB_AXI_AMAP_PCI_HDR_PARAM(pf), val);
+}
+
+static void ls_pcie_g4_ep_enable_bar(struct ls_pcie_g4 *pcie, int pf,
+				     int bar, bool vf_bar, bool enable)
+{
+	u32 val;
+	u32 bar_pos = BAR_POS(bar, pf, vf_bar);
+
+	val = ccsr_readl(pcie, GPEX_BAR_ENABLE);
+	if (enable)
+		val |= 1 << bar_pos;
+	else
+		val &= ~(1 << bar_pos);
+	ccsr_writel(pcie, GPEX_BAR_ENABLE, val);
+}
+
+static void ls_pcie_g4_ep_set_bar_size(struct ls_pcie_g4 *pcie, int pf,
+				       int bar, bool vf_bar, u64 size)
+{
+	u32 bar_pos = BAR_POS(bar, pf, vf_bar);
+	u32 mask_l = lower_32_bits(~(size - 1));
+	u32 mask_h = upper_32_bits(~(size - 1));
+
+	ccsr_writel(pcie, GPEX_BAR_SELECT, bar_pos);
+	ccsr_writel(pcie, GPEX_BAR_SIZE_LDW, mask_l);
+	ccsr_writel(pcie, GPEX_BAR_SIZE_UDW, mask_h);
+}
+
+static void ls_pcie_g4_ep_setup_bar(struct ls_pcie_g4 *pcie, int pf,
+				    int bar, bool vf_bar, u64 size)
+{
+	bool en = size ? true : false;
+
+	ls_pcie_g4_ep_enable_bar(pcie, pf, bar, vf_bar, en);
+	ls_pcie_g4_ep_set_bar_size(pcie, pf, bar, vf_bar, size);
+}
+
+static void ls_pcie_g4_ep_setup_bars(struct ls_pcie_g4 *pcie, int pf)
+{
+	int bar;
+
+	/* Setup PF BARs */
+	for (bar = 0; bar < PF_BAR_NUM; bar++)
+		ls_pcie_g4_ep_setup_bar(pcie, pf, bar, false, bar_size[bar]);
+
+	if (!pcie->sriov_support)
+		return;
+
+	/* Setup VF BARs */
+	for (bar = 0; bar < VF_BAR_NUM; bar++)
+		ls_pcie_g4_ep_setup_bar(pcie, pf, bar, true, bar_size[bar]);
+}
+
+static void ls_pcie_g4_set_sriov(struct ls_pcie_g4 *pcie, int pf)
+{
+	unsigned int val;
+
+	val =  ccsr_readl(pcie, GPEX_SRIOV_INIT_VFS_TOTAL_VF(pf));
+	val &= ~(TTL_VF_MASK << TTL_VF_SHIFT);
+	val |= PCIE_VF_NUM << TTL_VF_SHIFT;
+	val &= ~(INI_VF_MASK << INI_VF_SHIFT);
+	val |= PCIE_VF_NUM << INI_VF_SHIFT;
+	ccsr_writel(pcie, GPEX_SRIOV_INIT_VFS_TOTAL_VF(pf), val);
+
+	val =  ccsr_readl(pcie, PCIE_SRIOV_VF_OFFSET_STRIDE);
+	val += PCIE_VF_NUM * pf - pf;
+	ccsr_writel(pcie, GPEX_SRIOV_VF_OFFSET_STRIDE(pf), val);
+}
+
+static void ls_pcie_g4_setup_ep(struct ls_pcie_g4 *pcie)
+{
+	u32 pf, sriov;
+	u32 val;
+	int i;
+
+	/* Enable APIO and Memory Win */
+	val = ccsr_readl(pcie, PAB_AXI_PIO_CTRL(0));
+	val |= APIO_EN | MEM_WIN_EN;
+	ccsr_writel(pcie, PAB_AXI_PIO_CTRL(0), val);
+
+	sriov = ccsr_readl(pcie, PCIE_SRIOV_CAPABILITY);
+	if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV)
+		pcie->sriov_support = 1;
+
+	pf = pcie->sriov_support ? PCIE_PF_NUM : 1;
+
+	for (i = 0; i < pf; i++) {
+		ls_pcie_g4_ep_setup_bars(pcie, i);
+		ls_pcie_g4_ep_setup_wins(pcie, i);
+		if (pcie->sriov_support)
+			ls_pcie_g4_set_sriov(pcie, i);
+	}
+
+	ls_pcie_g4_ep_enable_cfg(pcie);
+	ls_pcie_g4_dump_wins(pcie, pf);
+}
+
+static int ls_pcie_g4_probe(struct udevice *dev)
+{
+	struct ls_pcie_g4 *pcie = dev_get_priv(dev);
+	const void *fdt = gd->fdt_blob;
+	int node = dev_of_offset(dev);
+	u32 link_ctrl_sta;
+	u32 val;
+	int ret;
+
+	pcie->bus = dev;
+
+	ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
+				     "ccsr", &pcie->ccsr_res);
+	if (ret) {
+		printf("ls-pcie-g4: resource \"ccsr\" not found\n");
+		return ret;
+	}
+
+	pcie->idx = (pcie->ccsr_res.start - PCIE_SYS_BASE_ADDR) /
+		    PCIE_CCSR_SIZE;
+
+	list_add(&pcie->list, &ls_pcie_g4_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->ccsr = map_physmem(pcie->ccsr_res.start,
+				 fdt_resource_size(&pcie->ccsr_res),
+				 MAP_NOCACHE);
+
+	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;
+	}
+
+	pcie->cfg = map_physmem(pcie->cfg_res.start,
+				fdt_resource_size(&pcie->cfg_res),
+				MAP_NOCACHE);
+
+	ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
+				     "lut", &pcie->lut_res);
+	if (ret) {
+		printf("ls-pcie-g4: resource \"lut\" not found\n");
+		return 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",
+				     "pf_ctrl", &pcie->pf_ctrl_res);
+	if (ret) {
+		printf("ls-pcie-g4: resource \"pf_ctrl\" not found\n");
+		return ret;
+	}
+
+	pcie->pf_ctrl = map_physmem(pcie->pf_ctrl_res.start,
+				    fdt_resource_size(&pcie->pf_ctrl_res),
+				    MAP_NOCACHE);
+
+	pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian");
+
+	debug("%s ccsr:%lx, cfg:0x%lx, big-endian:%d\n",
+	      dev->name, (unsigned long)pcie->ccsr, (unsigned long)pcie->cfg,
+	      pcie->big_endian);
+
+	pcie->mode = readb(pcie->ccsr + PCI_HEADER_TYPE) & 0x7f;
+
+	if (pcie->mode == PCI_HEADER_TYPE_NORMAL) {
+		printf("PCIe%u: %s %s", pcie->idx, dev->name, "Endpoint");
+		ls_pcie_g4_setup_ep(pcie);
+	} else {
+		printf("PCIe%u: %s %s", pcie->idx, dev->name, "Root Complex");
+		ls_pcie_g4_setup_ctrl(pcie);
+	}
+
+	/* Enable Amba & PEX PIO */
+	val = ccsr_readl(pcie, PAB_CTRL);
+	val |= PAB_CTRL_APIO_EN | PAB_CTRL_PPIO_EN;
+	ccsr_writel(pcie, PAB_CTRL, val);
+
+	val = ccsr_readl(pcie, PAB_PEX_PIO_CTRL(0));
+	val |= PPIO_EN;
+	ccsr_writel(pcie, PAB_PEX_PIO_CTRL(0), val);
+
+	if (!ls_pcie_g4_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_ctrl_sta = ccsr_readl(pcie, PCIE_LINK_CTRL_STA);
+	printf(": x%d gen%d\n",
+	       (link_ctrl_sta >> PCIE_LINK_WIDTH_SHIFT & PCIE_LINK_WIDTH_MASK),
+	       (link_ctrl_sta >> PCIE_LINK_SPEED_SHIFT) & PCIE_LINK_SPEED_MASK);
+
+	return 0;
+}
+
+static const struct dm_pci_ops ls_pcie_g4_ops = {
+	.read_config	= ls_pcie_g4_read_config,
+	.write_config	= ls_pcie_g4_write_config,
+};
+
+static const struct udevice_id ls_pcie_g4_ids[] = {
+	{ .compatible = "fsl,lx2160a-pcie" },
+	{ }
+};
+
+U_BOOT_DRIVER(pcie_layerscape_gen4) = {
+	.name = "pcie_layerscape_gen4",
+	.id = UCLASS_PCI,
+	.of_match = ls_pcie_g4_ids,
+	.ops = &ls_pcie_g4_ops,
+	.probe	= ls_pcie_g4_probe,
+	.priv_auto_alloc_size = sizeof(struct ls_pcie_g4),
+};
+
+/* No any fixup so far */
+void ft_pci_setup(void *blob, bd_t *bd)
+{
+}
diff --git a/drivers/pci/pcie_layerscape_gen4.h b/drivers/pci/pcie_layerscape_gen4.h
new file mode 100644
index 0000000000..356b49f9ce
--- /dev/null
+++ b/drivers/pci/pcie_layerscape_gen4.h
@@ -0,0 +1,264 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ *
+ * PCIe Gen4 driver for NXP Layerscape SoCs
+ * Author: Hou Zhiqiang <Minder.Hou@gmail.com>
+ */
+
+#ifndef _PCIE_LAYERSCAPE_GEN4_H_
+#define _PCIE_LAYERSCAPE_GEN4_H_
+#include <pci.h>
+#include <dm.h>
+
+#ifndef CONFIG_SYS_PCI_MEMORY_SIZE
+#define CONFIG_SYS_PCI_MEMORY_SIZE		(4 * 1024 * 1024 * 1024ULL)
+#endif
+
+#ifndef CONFIG_SYS_PCI_EP_MEMORY_BASE
+#define CONFIG_SYS_PCI_EP_MEMORY_BASE		CONFIG_SYS_LOAD_ADDR
+#endif
+
+#define PCIE_PF_NUM				2
+#define PCIE_VF_NUM				32
+
+#define LS_G4_PF0				0
+#define LS_G4_PF1				1
+#define PF_BAR_NUM				4
+#define VF_BAR_NUM				4
+#define PCIE_BAR_SIZE				(8 * 1024)		/* 8K */
+#define PCIE_BAR0_SIZE				PCIE_BAR_SIZE
+#define PCIE_BAR1_SIZE				PCIE_BAR_SIZE
+#define PCIE_BAR2_SIZE				PCIE_BAR_SIZE
+#define PCIE_BAR4_SIZE				PCIE_BAR_SIZE
+#define SIZE_1T					(1024 * 1024 * 1024 * 1024ULL)
+
+/* GPEX CSR */
+#define GPEX_CLASSCODE				0x474
+#define GPEX_CLASSCODE_SHIFT			16
+#define GPEX_CLASSCODE_MASK			0xffff
+
+#define GPEX_CFG_READY				0x4b0
+#define PCIE_CONFIG_READY			BIT(0)
+
+#define GPEX_BAR_ENABLE				0x4d4
+#define GPEX_BAR_SIZE_LDW			0x4d8
+#define GPEX_BAR_SIZE_UDW			0x4dC
+#define GPEX_BAR_SELECT				0x4e0
+
+#define BAR_POS(bar, pf, vf_bar)		\
+	((bar) + (pf) * PF_BAR_NUM + (vf_bar) * PCIE_PF_NUM * PF_BAR_NUM)
+
+#define GPEX_SRIOV_INIT_VFS_TOTAL_VF(pf)	(0x644 + (pf) * 4)
+#define TTL_VF_MASK				0xffff
+#define TTL_VF_SHIFT				16
+#define INI_VF_MASK				0xffff
+#define INI_VF_SHIFT				0
+#define GPEX_SRIOV_VF_OFFSET_STRIDE(pf)		(0x704 + (pf) * 4)
+
+/* PAB CSR */
+#define PAB_CTRL				0x808
+#define PAB_CTRL_APIO_EN			BIT(0)
+#define PAB_CTRL_PPIO_EN			BIT(1)
+#define PAB_CTRL_MAX_BRST_LEN_SHIFT		4
+#define PAB_CTRL_MAX_BRST_LEN_MASK		0x3
+#define PAB_CTRL_PAGE_SEL_SHIFT			13
+#define PAB_CTRL_PAGE_SEL_MASK			0x3f
+#define PAB_CTRL_FUNC_SEL_SHIFT			19
+#define PAB_CTRL_FUNC_SEL_MASK			0x1ff
+
+#define PAB_RST_CTRL				0x820
+#define PAB_BR_STAT				0x80c
+
+/* AXI PIO Engines */
+#define PAB_AXI_PIO_CTRL(idx)			(0x840 + 0x10 * (idx))
+#define APIO_EN					BIT(0)
+#define MEM_WIN_EN				BIT(1)
+#define IO_WIN_EN				BIT(2)
+#define CFG_WIN_EN				BIT(3)
+#define PAB_AXI_PIO_STAT(idx)			(0x844 + 0x10 * (idx))
+#define PAB_AXI_PIO_SL_CMD_STAT(idx)		(0x848 + 0x10 * (idx))
+#define PAB_AXI_PIO_SL_ADDR_STAT(idx)		(0x84c + 0x10 * (idx))
+#define PAB_AXI_PIO_SL_EXT_ADDR_STAT(idx)	(0xb8a0 + 0x4 * (idx))
+
+/* PEX PIO Engines */
+#define PAB_PEX_PIO_CTRL(idx)			(0x8c0 + 0x10 * (idx))
+#define PPIO_EN					BIT(0)
+#define PAB_PEX_PIO_STAT(idx)			(0x8c4 + 0x10 * (idx))
+#define PAB_PEX_PIO_MT_STAT(idx)		(0x8c8 + 0x10 * (idx))
+
+#define INDIRECT_ADDR_BNDRY			0xc00
+#define PAGE_IDX_SHIFT				10
+#define PAGE_ADDR_MASK				0x3ff
+
+#define OFFSET_TO_PAGE_IDX(off)			\
+	(((off) >> PAGE_IDX_SHIFT) & PAB_CTRL_PAGE_SEL_MASK)
+
+#define OFFSET_TO_PAGE_ADDR(off)		\
+	(((off) & PAGE_ADDR_MASK) | INDIRECT_ADDR_BNDRY)
+
+/* APIO WINs */
+#define PAB_AXI_AMAP_CTRL(idx)			(0xba0 + 0x10 * (idx))
+#define PAB_EXT_AXI_AMAP_SIZE(idx)		(0xbaf0 + 0x4 * (idx))
+#define PAB_AXI_AMAP_AXI_WIN(idx)		(0xba4 + 0x10 * (idx))
+#define PAB_EXT_AXI_AMAP_AXI_WIN(idx)		(0x80a0 + 0x4 * (idx))
+#define PAB_AXI_AMAP_PEX_WIN_L(idx)		(0xba8 + 0x10 * (idx))
+#define PAB_AXI_AMAP_PEX_WIN_H(idx)		(0xbac + 0x10 * (idx))
+#define PAB_AXI_AMAP_PCI_HDR_PARAM(idx)		(0x5ba0 + 0x4 * (idx))
+#define FUNC_NUM_PCIE_MASK			GENMASK(7, 0)
+
+#define AXI_AMAP_CTRL_EN			BIT(0)
+#define AXI_AMAP_CTRL_TYPE_SHIFT		1
+#define AXI_AMAP_CTRL_TYPE_MASK			0x3
+#define AXI_AMAP_CTRL_SIZE_SHIFT		10
+#define AXI_AMAP_CTRL_SIZE_MASK			0x3fffff
+
+#define PAB_TARGET_BUS(x)			(((x) & 0xff) << 24)
+#define PAB_TARGET_DEV(x)			(((x) & 0x1f) << 19)
+#define PAB_TARGET_FUNC(x)			(((x) & 0x7) << 16)
+
+#define PAB_AXI_TYPE_CFG			0x00
+#define PAB_AXI_TYPE_IO				0x01
+#define PAB_AXI_TYPE_MEM			0x02
+#define PAB_AXI_TYPE_ATOM			0x03
+
+#define PAB_WINS_NUM				256
+
+/* PPIO WINs RC mode */
+#define PAB_PEX_AMAP_CTRL(idx)			(0x4ba0 + 0x10 * (idx))
+#define PAB_EXT_PEX_AMAP_SIZE(idx)		(0xbef0 + 0x04 * (idx))
+#define PAB_PEX_AMAP_AXI_WIN(idx)		(0x4ba4 + 0x10 * (idx))
+#define PAB_EXT_PEX_AMAP_AXI_WIN(idx)		(0xb4a0 + 0x04 * (idx))
+#define PAB_PEX_AMAP_PEX_WIN_L(idx)		(0x4ba8 + 0x10 * (idx))
+#define PAB_PEX_AMAP_PEX_WIN_H(idx)		(0x4bac + 0x10 * (idx))
+
+#define IB_TYPE_MEM_F				0x2
+#define IB_TYPE_MEM_NF				0x3
+
+#define PEX_AMAP_CTRL_TYPE_SHIFT		0x1
+#define PEX_AMAP_CTRL_EN_SHIFT			0x0
+#define PEX_AMAP_CTRL_TYPE_MASK			0x3
+#define PEX_AMAP_CTRL_EN_MASK			0x1
+
+/* PPIO WINs EP mode */
+#define PAB_PEX_BAR_AMAP(pf, bar)		\
+	(0x1ba0 + 0x20 * (pf) + 4 * (bar))
+#define BAR_AMAP_EN				BIT(0)
+#define PAB_EXT_PEX_BAR_AMAP(pf, bar)		\
+	(0x84a0 + 0x20 * (pf) + 4 * (bar))
+
+/* CCSR registers */
+#define PCIE_LINK_CTRL_STA			0x5c
+#define PCIE_LINK_SPEED_SHIFT			16
+#define PCIE_LINK_SPEED_MASK			0x0f
+#define PCIE_LINK_WIDTH_SHIFT			20
+#define PCIE_LINK_WIDTH_MASK			0x3f
+#define PCIE_SRIOV_CAPABILITY			0x2a0
+#define PCIE_SRIOV_VF_OFFSET_STRIDE		0x2b4
+
+/* LUT registers */
+#define PCIE_LUT_UDR(n)				(0x800 + (n) * 8)
+#define PCIE_LUT_LDR(n)				(0x804 + (n) * 8)
+#define PCIE_LUT_ENABLE				BIT(31)
+#define PCIE_LUT_ENTRY_COUNT			32
+
+/* PF control registers */
+#define PCIE_LTSSM_STA				0x7fc
+#define LTSSM_STATE_MASK			0x7f
+#define LTSSM_PCIE_L0				0x2d /* L0 state */
+
+#define PCIE_SRDS_PRTCL(idx)			(PCIE1 + (idx))
+#define PCIE_SYS_BASE_ADDR			0x3400000
+#define PCIE_CCSR_SIZE				0x0100000
+
+struct ls_pcie_g4 {
+	int idx;
+	struct list_head list;
+	struct udevice *bus;
+	struct fdt_resource ccsr_res;
+	struct fdt_resource cfg_res;
+	struct fdt_resource lut_res;
+	struct fdt_resource pf_ctrl_res;
+	void __iomem *ccsr;
+	void __iomem *cfg;
+	void __iomem *lut;
+	void __iomem *pf_ctrl;
+	bool big_endian;
+	bool enabled;
+	int next_lut_index;
+	struct pci_controller hose;
+	int stream_id_cur;
+	int mode;
+	int sriov_support;
+};
+
+extern struct list_head ls_pcie_g4_list;
+
+static inline void lut_writel(struct ls_pcie_g4 *pcie, unsigned int value,
+			      unsigned int offset)
+{
+	if (pcie->big_endian)
+		out_be32(pcie->lut + offset, value);
+	else
+		out_le32(pcie->lut + offset, value);
+}
+
+static inline u32 lut_readl(struct ls_pcie_g4 *pcie, unsigned int offset)
+{
+	if (pcie->big_endian)
+		return in_be32(pcie->lut + offset);
+	else
+		return in_le32(pcie->lut + offset);
+}
+
+static inline void ccsr_set_page(struct ls_pcie_g4 *pcie, u8 pg_idx)
+{
+	u32 val;
+
+	val = in_le32(pcie->ccsr + PAB_CTRL);
+	val &= ~(PAB_CTRL_PAGE_SEL_MASK << PAB_CTRL_PAGE_SEL_SHIFT);
+	val |= (pg_idx & PAB_CTRL_PAGE_SEL_MASK) << PAB_CTRL_PAGE_SEL_SHIFT;
+
+	out_le32(pcie->ccsr + PAB_CTRL, val);
+}
+
+static inline unsigned int ccsr_readl(struct ls_pcie_g4 *pcie, u32 offset)
+{
+	if (offset < INDIRECT_ADDR_BNDRY) {
+		ccsr_set_page(pcie, 0);
+		return in_le32(pcie->ccsr + offset);
+	}
+
+	ccsr_set_page(pcie, OFFSET_TO_PAGE_IDX(offset));
+	return in_le32(pcie->ccsr + OFFSET_TO_PAGE_ADDR(offset));
+}
+
+static inline void ccsr_writel(struct ls_pcie_g4 *pcie, u32 offset, u32 value)
+{
+	if (offset < INDIRECT_ADDR_BNDRY) {
+		ccsr_set_page(pcie, 0);
+		out_le32(pcie->ccsr + offset, value);
+	} else {
+		ccsr_set_page(pcie, OFFSET_TO_PAGE_IDX(offset));
+		out_le32(pcie->ccsr + OFFSET_TO_PAGE_ADDR(offset), value);
+	}
+}
+
+static inline unsigned int pf_ctrl_readl(struct ls_pcie_g4 *pcie, u32 offset)
+{
+	if (pcie->big_endian)
+		return in_be32(pcie->pf_ctrl + offset);
+	else
+		return in_le32(pcie->pf_ctrl + offset);
+}
+
+static inline void pf_ctrl_writel(struct ls_pcie_g4 *pcie, u32 offset,
+				  u32 value)
+{
+	if (pcie->big_endian)
+		out_be32(pcie->pf_ctrl + offset, value);
+	else
+		out_le32(pcie->pf_ctrl + offset, value);
+}
+
+#endif /* _PCIE_LAYERSCAPE_GEN4_H_ */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 04/12] kconfig: add dependency PCIE_LAYERSCAPE_GEN4 for FSL_PCIE_COMPAT
  2019-03-11  2:57 [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
                   ` (2 preceding siblings ...)
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 03/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
@ 2019-03-11  2:58 ` Z.q. Hou
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 05/12] pci: ls_pcie_g4: add device tree fixups for PCI Stream IDs Z.q. Hou
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2019-03-11  2:58 UTC (permalink / raw)
  To: u-boot

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

The LX2160A PCIe is using driver PCIE_LAYERSCAPE_GEN4 instead
of PCIE_LAYERSCAPE.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V4:
 - No change

 arch/arm/cpu/armv8/fsl-layerscape/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
index f48481f465..d37e3678e7 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
@@ -242,7 +242,7 @@ config FSL_LAYERSCAPE
 
 config FSL_PCIE_COMPAT
 	string "PCIe compatible of Kernel DT"
-	depends on PCIE_LAYERSCAPE
+	depends on PCIE_LAYERSCAPE || PCIE_LAYERSCAPE_GEN4
 	default "fsl,ls1012a-pcie" if ARCH_LS1012A
 	default "fsl,ls1043a-pcie" if ARCH_LS1043A
 	default "fsl,ls1046a-pcie" if ARCH_LS1046A
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 05/12] pci: ls_pcie_g4: add device tree fixups for PCI Stream IDs
  2019-03-11  2:57 [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
                   ` (3 preceding siblings ...)
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 04/12] kconfig: add dependency PCIE_LAYERSCAPE_GEN4 for FSL_PCIE_COMPAT Z.q. Hou
@ 2019-03-11  2:58 ` Z.q. Hou
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 06/12] armv8: lx2160a: add PCIe controller DT nodes Z.q. Hou
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2019-03-11  2:58 UTC (permalink / raw)
  To: u-boot

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

Add the infrastructure for Layerscape SoCs PCIe Gen4 controller
to update device tree nodes to convey SMMU stream IDs in the
device tree.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V4:
 - No change

 drivers/pci/Makefile                     |   3 +-
 drivers/pci/pcie_layerscape_gen4.c       |   5 -
 drivers/pci/pcie_layerscape_gen4_fixup.c | 249 +++++++++++++++++++++++
 3 files changed, 251 insertions(+), 6 deletions(-)
 create mode 100644 drivers/pci/pcie_layerscape_gen4_fixup.c

diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 7f585aad55..8ee828af6d 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
 obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o
 obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o
 obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o
-obj-$(CONFIG_PCIE_LAYERSCAPE_GEN4) += pcie_layerscape_gen4.o
+obj-$(CONFIG_PCIE_LAYERSCAPE_GEN4) += pcie_layerscape_gen4.o \
+				pcie_layerscape_gen4_fixup.o
 obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o
 obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o
diff --git a/drivers/pci/pcie_layerscape_gen4.c b/drivers/pci/pcie_layerscape_gen4.c
index fbe7d35911..4e0d5b168e 100644
--- a/drivers/pci/pcie_layerscape_gen4.c
+++ b/drivers/pci/pcie_layerscape_gen4.c
@@ -570,8 +570,3 @@ U_BOOT_DRIVER(pcie_layerscape_gen4) = {
 	.probe	= ls_pcie_g4_probe,
 	.priv_auto_alloc_size = sizeof(struct ls_pcie_g4),
 };
-
-/* No any fixup so far */
-void ft_pci_setup(void *blob, bd_t *bd)
-{
-}
diff --git a/drivers/pci/pcie_layerscape_gen4_fixup.c b/drivers/pci/pcie_layerscape_gen4_fixup.c
new file mode 100644
index 0000000000..ceeea17f19
--- /dev/null
+++ b/drivers/pci/pcie_layerscape_gen4_fixup.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2018 NXP
+ *
+ * PCIe Gen4 driver for NXP Layerscape SoCs
+ * Author: Hou Zhiqiang <Minder.Hou@gmail.com>
+ *
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/io.h>
+#include <errno.h>
+#ifdef CONFIG_OF_BOARD_SETUP
+#include <linux/libfdt.h>
+#include <fdt_support.h>
+#ifdef CONFIG_ARM
+#include <asm/arch/clock.h>
+#endif
+#include "pcie_layerscape_gen4.h"
+
+#if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2)
+/*
+ * Return next available LUT index.
+ */
+static int ls_pcie_g4_next_lut_index(struct ls_pcie_g4 *pcie)
+{
+	if (pcie->next_lut_index < PCIE_LUT_ENTRY_COUNT)
+		return pcie->next_lut_index++;
+
+	return -ENOSPC;  /* LUT is full */
+}
+
+/* returns the next available streamid for pcie, -errno if failed */
+static int ls_pcie_g4_next_streamid(struct ls_pcie_g4 *pcie)
+{
+	int stream_id = pcie->stream_id_cur;
+
+	if (stream_id > FSL_PEX_STREAM_ID_NUM)
+		return -EINVAL;
+
+	pcie->stream_id_cur++;
+
+	return stream_id | ((pcie->idx + 1) << 11);
+}
+
+/*
+ * Program a single LUT entry
+ */
+static void ls_pcie_g4_lut_set_mapping(struct ls_pcie_g4 *pcie, 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));
+}
+
+/*
+ * An msi-map is a property to be added to the pci controller
+ * node.  It is a table, where each entry consists of 4 fields
+ * e.g.:
+ *
+ *      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(void *blob, struct ls_pcie_g4 *pcie,
+				       u32 devid, u32 streamid)
+{
+	u32 *prop;
+	u32 phandle;
+	int nodeoff;
+
+#ifdef CONFIG_FSL_PCIE_COMPAT
+	nodeoff = fdt_node_offset_by_compat_reg(blob, CONFIG_FSL_PCIE_COMPAT,
+						pcie->ccsr_res.start);
+#else
+#error "No CONFIG_FSL_PCIE_COMPAT defined"
+#endif
+	if (nodeoff < 0) {
+		debug("%s: ERROR: failed to find pcie compatiable\n", __func__);
+		return;
+	}
+
+	/* get phandle to MSI controller */
+	prop = (u32 *)fdt_getprop(blob, nodeoff, "msi-parent", 0);
+	if (!prop) {
+		debug("\n%s: ERROR: missing msi-parent: PCIe%d\n",
+		      __func__, pcie->idx);
+		return;
+	}
+	phandle = fdt32_to_cpu(*prop);
+
+	/* set one msi-map row */
+	fdt_appendprop_u32(blob, nodeoff, "msi-map", devid);
+	fdt_appendprop_u32(blob, nodeoff, "msi-map", phandle);
+	fdt_appendprop_u32(blob, nodeoff, "msi-map", streamid);
+	fdt_appendprop_u32(blob, nodeoff, "msi-map", 1);
+}
+
+/*
+ * An iommu-map is a property to be added to the pci controller
+ * node.  It is a table, where each entry consists of 4 fields
+ * e.g.:
+ *
+ *      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(void *blob, struct ls_pcie_g4 *pcie,
+					 u32 devid, u32 streamid)
+{
+	u32 *prop;
+	u32 iommu_map[4];
+	int nodeoff;
+	int lenp;
+
+#ifdef CONFIG_FSL_PCIE_COMPAT
+	nodeoff = fdt_node_offset_by_compat_reg(blob, CONFIG_FSL_PCIE_COMPAT,
+						pcie->ccsr_res.start);
+#else
+#error "No CONFIG_FSL_PCIE_COMPAT defined"
+#endif
+	if (nodeoff < 0) {
+		debug("%s: ERROR: failed to find pcie compatiable\n", __func__);
+		return;
+	}
+
+	/* get phandle to iommu controller */
+	prop = fdt_getprop_w(blob, nodeoff, "iommu-map", &lenp);
+	if (!prop) {
+		debug("\n%s: ERROR: missing iommu-map: PCIe%d\n",
+		      __func__, pcie->idx);
+		return;
+	}
+
+	/* set iommu-map row */
+	iommu_map[0] = cpu_to_fdt32(devid);
+	iommu_map[1] = *++prop;
+	iommu_map[2] = cpu_to_fdt32(streamid);
+	iommu_map[3] = cpu_to_fdt32(1);
+
+	if (devid == 0)
+		fdt_setprop_inplace(blob, nodeoff, "iommu-map", iommu_map, 16);
+	else
+		fdt_appendprop(blob, nodeoff, "iommu-map", iommu_map, 16);
+}
+
+static void fdt_fixup_pcie(void *blob)
+{
+	struct udevice *dev, *bus;
+	struct ls_pcie_g4 *pcie;
+	int streamid;
+	int index;
+	pci_dev_t bdf;
+
+	/* Scan all known buses */
+	for (pci_find_first_device(&dev); dev; pci_find_next_device(&dev)) {
+		for (bus = dev; device_is_on_pci_bus(bus);)
+			bus = bus->parent;
+		pcie = dev_get_priv(bus);
+
+		streamid = ls_pcie_g4_next_streamid(pcie);
+		if (streamid < 0) {
+			debug("ERROR: no stream ids free\n");
+			continue;
+		}
+
+		index = ls_pcie_g4_next_lut_index(pcie);
+		if (index < 0) {
+			debug("ERROR: no LUT indexes free\n");
+			continue;
+		}
+
+		/* 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_g4_lut_set_mapping(pcie, index, bdf >> 8, streamid);
+		/* update msi-map in device tree */
+		fdt_pcie_set_msi_map_entry(blob, pcie, bdf >> 8, streamid);
+		/* update iommu-map in device tree */
+		fdt_pcie_set_iommu_map_entry(blob, pcie, bdf >> 8, streamid);
+	}
+}
+#endif
+
+static void ft_pcie_ep_layerscape_gen4_fix(void *blob, struct ls_pcie_g4 *pcie)
+{
+	int off;
+
+	off = fdt_node_offset_by_compat_reg(blob, "fsl,lx2160a-pcie-ep",
+					    pcie->ccsr_res.start);
+
+	if (off < 0) {
+		debug("%s: ERROR: failed to find pcie compatiable\n",
+		      __func__);
+		return;
+	}
+
+	if (pcie->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_rc_layerscape_gen4_fix(void *blob, struct ls_pcie_g4 *pcie)
+{
+	int off;
+
+#ifdef CONFIG_FSL_PCIE_COMPAT
+	off = fdt_node_offset_by_compat_reg(blob, CONFIG_FSL_PCIE_COMPAT,
+					    pcie->ccsr_res.start);
+#else
+#error "No CONFIG_FSL_PCIE_COMPAT defined"
+#endif
+	if (off < 0) {
+		debug("%s: ERROR: failed to find pcie compatiable\n", __func__);
+		return;
+	}
+
+	if (pcie->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_layerscape_gen4_setup(void *blob, struct ls_pcie_g4 *pcie)
+{
+	ft_pcie_rc_layerscape_gen4_fix(blob, pcie);
+	ft_pcie_ep_layerscape_gen4_fix(blob, pcie);
+}
+
+/* Fixup Kernel DT for PCIe */
+void ft_pci_setup(void *blob, bd_t *bd)
+{
+	struct ls_pcie_g4 *pcie;
+
+	list_for_each_entry(pcie, &ls_pcie_g4_list, list)
+		ft_pcie_layerscape_gen4_setup(blob, pcie);
+
+#if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2)
+	fdt_fixup_pcie(blob);
+#endif
+}
+
+#else /* !CONFIG_OF_BOARD_SETUP */
+void ft_pci_setup(void *blob, bd_t *bd)
+{
+}
+#endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 06/12] armv8: lx2160a: add PCIe controller DT nodes
  2019-03-11  2:57 [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
                   ` (4 preceding siblings ...)
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 05/12] pci: ls_pcie_g4: add device tree fixups for PCI Stream IDs Z.q. Hou
@ 2019-03-11  2:58 ` Z.q. Hou
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 07/12] armv8: lx2160a: enable PCIe support Z.q. Hou
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2019-03-11  2:58 UTC (permalink / raw)
  To: u-boot

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

The LX2160A integrated 6 PCIe Gen4 controllers.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V4:
 - No change

 arch/arm/dts/fsl-lx2160a.dtsi | 85 +++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/arch/arm/dts/fsl-lx2160a.dtsi b/arch/arm/dts/fsl-lx2160a.dtsi
index 510b070582..cac3207985 100644
--- a/arch/arm/dts/fsl-lx2160a.dtsi
+++ b/arch/arm/dts/fsl-lx2160a.dtsi
@@ -176,4 +176,89 @@
 			status = "disabled";
 
 	};
+
+	pcie at 3400000 {
+		compatible = "fsl,lx2160a-pcie";
+		reg = <0x00 0x03400000 0x0 0x80000   /* PAB registers */
+		       0x00 0x03480000 0x0 0x40000   /* LUT registers */
+		       0x00 0x034c0000 0x0 0x40000   /* PF control registers */
+		       0x80 0x00000000 0x0 0x1000>; /* configuration space */
+		reg-names = "ccsr", "lut", "pf_ctrl", "config";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		bus-range = <0x0 0xff>;
+		ranges = <0x82000000 0x0 0x40000000 0x80 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+	};
+
+	pcie at 3500000 {
+		compatible = "fsl,lx2160a-pcie";
+		reg = <0x00 0x03500000 0x0 0x80000   /* PAB registers */
+		       0x00 0x03580000 0x0 0x40000   /* LUT registers */
+		       0x00 0x035c0000 0x0 0x40000   /* PF control registers */
+		       0x88 0x00000000 0x0 0x1000>; /* configuration space */
+		reg-names = "ccsr", "lut", "pf_ctrl", "config";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		num-lanes = <2>;
+		bus-range = <0x0 0xff>;
+		ranges = <0x82000000 0x0 0x40000000 0x88 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+	};
+
+	pcie at 3600000 {
+		compatible = "fsl,lx2160a-pcie";
+		reg = <0x00 0x03600000 0x0 0x80000   /* PAB registers */
+		       0x00 0x03680000 0x0 0x40000   /* LUT registers */
+		       0x00 0x036c0000 0x0 0x40000   /* PF control registers */
+		       0x90 0x00000000 0x0 0x1000>; /* configuration space */
+		reg-names = "ccsr", "lut", "pf_ctrl", "config";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		bus-range = <0x0 0xff>;
+		ranges = <0x82000000 0x0 0x40000000 0x90 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+	};
+
+	pcie at 3700000 {
+		compatible = "fsl,lx2160a-pcie";
+		reg = <0x00 0x03700000 0x0 0x80000   /* PAB registers */
+		       0x00 0x03780000 0x0 0x40000   /* LUT registers */
+		       0x00 0x037c0000 0x0 0x40000   /* PF control registers */
+		       0x98 0x00000000 0x0 0x1000>; /* configuration space */
+		reg-names = "ccsr", "lut", "pf_ctrl", "config";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		bus-range = <0x0 0xff>;
+		ranges = <0x82000000 0x0 0x40000000 0x98 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+	};
+
+	pcie at 3800000 {
+		compatible = "fsl,lx2160a-pcie";
+		reg = <0x00 0x03800000 0x0 0x80000   /* PAB registers */
+		       0x00 0x03880000 0x0 0x40000   /* LUT registers */
+		       0x00 0x038c0000 0x0 0x40000   /* PF control registers */
+		       0xa0 0x00000000 0x0 0x1000>; /* configuration space */
+		reg-names = "ccsr", "lut", "pf_ctrl", "config";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		bus-range = <0x0 0xff>;
+		ranges = <0x82000000 0x0 0x40000000 0xa0 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+	};
+
+	pcie at 3900000 {
+		compatible = "fsl,lx2160a-pcie";
+		reg = <0x00 0x03900000 0x0 0x80000   /* PAB registers */
+		       0x00 0x03980000 0x0 0x40000   /* LUT registers */
+		       0x00 0x039c0000 0x0 0x40000   /* PF control registers */
+		       0xa8 0x00000000 0x0 0x1000>; /* configuration space */
+		reg-names = "ccsr", "lut", "pf_ctrl", "config";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		bus-range = <0x0 0xff>;
+		ranges = <0x82000000 0x0 0x40000000 0xa8 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+	};
 };
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 07/12] armv8: lx2160a: enable PCIe support
  2019-03-11  2:57 [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
                   ` (5 preceding siblings ...)
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 06/12] armv8: lx2160a: add PCIe controller DT nodes Z.q. Hou
@ 2019-03-11  2:58 ` Z.q. Hou
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 08/12] pci: ls_pcie_g4: add Workaround for A-011577 Z.q. Hou
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2019-03-11  2:58 UTC (permalink / raw)
  To: u-boot

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

Enable the PCIe Gen4 controller driver and e1000 for LX2160ARDB
and LX2160AQDS boards.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V4:
 - Add PCI command support
 - Enable PCIe in more LX2160A defconfigs

 configs/lx2160aqds_tfa_SECURE_BOOT_defconfig | 5 +++++
 configs/lx2160aqds_tfa_defconfig             | 6 ++++++
 configs/lx2160ardb_tfa_SECURE_BOOT_defconfig | 5 +++++
 configs/lx2160ardb_tfa_defconfig             | 6 ++++++
 4 files changed, 22 insertions(+)

diff --git a/configs/lx2160aqds_tfa_SECURE_BOOT_defconfig b/configs/lx2160aqds_tfa_SECURE_BOOT_defconfig
index 58841053ec..367502da37 100644
--- a/configs/lx2160aqds_tfa_SECURE_BOOT_defconfig
+++ b/configs/lx2160aqds_tfa_SECURE_BOOT_defconfig
@@ -56,3 +56,8 @@ CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
 CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
+CONFIG_CMD_PCI=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCIE_LAYERSCAPE_GEN4=y
diff --git a/configs/lx2160aqds_tfa_defconfig b/configs/lx2160aqds_tfa_defconfig
index a0b86ae142..06ef830acd 100644
--- a/configs/lx2160aqds_tfa_defconfig
+++ b/configs/lx2160aqds_tfa_defconfig
@@ -51,3 +51,9 @@ CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
+CONFIG_CMD_PCI=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCIE_LAYERSCAPE_GEN4=y
+CONFIG_E1000=y
diff --git a/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig b/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig
index f66882d6fa..4e972cc721 100644
--- a/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig
+++ b/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig
@@ -53,3 +53,8 @@ CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
 CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
+CONFIG_CMD_PCI=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCIE_LAYERSCAPE_GEN4=y
diff --git a/configs/lx2160ardb_tfa_defconfig b/configs/lx2160ardb_tfa_defconfig
index 2dc49c7f5d..73b3b91034 100644
--- a/configs/lx2160ardb_tfa_defconfig
+++ b/configs/lx2160ardb_tfa_defconfig
@@ -51,3 +51,9 @@ CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
+CONFIG_CMD_PCI=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCIE_LAYERSCAPE_GEN4=y
+CONFIG_E1000=y
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 08/12] pci: ls_pcie_g4: add Workaround for A-011577
  2019-03-11  2:57 [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
                   ` (6 preceding siblings ...)
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 07/12] armv8: lx2160a: enable PCIe support Z.q. Hou
@ 2019-03-11  2:58 ` Z.q. Hou
  2019-03-13 14:53   ` Z.q. Hou
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 09/12] dm: pci: add APIs for capability accessors Z.q. Hou
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Z.q. Hou @ 2019-03-11  2:58 UTC (permalink / raw)
  To: u-boot

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

PCIe configuration access to non-existent function triggered
SERROR interrupt exception.

Workaround:
Disable error reporting on AXI bus during the Vendor ID read
transactions in enumeration.

This ERRATA is only for LX2160A Rev1.0 and will be fixed in Rev2.0.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V4:
 - No change

 drivers/pci/pcie_layerscape_gen4.c | 8 ++++++++
 drivers/pci/pcie_layerscape_gen4.h | 5 +++++
 2 files changed, 13 insertions(+)

diff --git a/drivers/pci/pcie_layerscape_gen4.c b/drivers/pci/pcie_layerscape_gen4.c
index 4e0d5b168e..799da2f7df 100644
--- a/drivers/pci/pcie_layerscape_gen4.c
+++ b/drivers/pci/pcie_layerscape_gen4.c
@@ -242,6 +242,9 @@ static int ls_pcie_g4_read_config(struct udevice *bus, pci_dev_t bdf,
 
 	address = ls_pcie_g4_conf_address(pcie, bdf, offset);
 
+	if (pcie->rev == REV_1_0 && offset == PCI_VENDOR_ID)
+		lut_writel(pcie, 0x0 << PCIE_LUT_GCR_RRE, PCIE_LUT_GCR);
+
 	switch (size) {
 	case PCI_SIZE_8:
 		*valuep = readb(address);
@@ -257,6 +260,9 @@ static int ls_pcie_g4_read_config(struct udevice *bus, pci_dev_t bdf,
 		break;
 	}
 
+	if (pcie->rev == REV_1_0 && offset == PCI_VENDOR_ID)
+		lut_writel(pcie, 0x1 << PCIE_LUT_GCR_RRE, PCIE_LUT_GCR);
+
 	return ret;
 }
 
@@ -518,6 +524,8 @@ static int ls_pcie_g4_probe(struct udevice *dev)
 	      dev->name, (unsigned long)pcie->ccsr, (unsigned long)pcie->cfg,
 	      pcie->big_endian);
 
+	pcie->rev = readb(pcie->ccsr + PCI_REVISION_ID);
+
 	pcie->mode = readb(pcie->ccsr + PCI_HEADER_TYPE) & 0x7f;
 
 	if (pcie->mode == PCI_HEADER_TYPE_NORMAL) {
diff --git a/drivers/pci/pcie_layerscape_gen4.h b/drivers/pci/pcie_layerscape_gen4.h
index 356b49f9ce..137768cae7 100644
--- a/drivers/pci/pcie_layerscape_gen4.h
+++ b/drivers/pci/pcie_layerscape_gen4.h
@@ -11,6 +11,8 @@
 #include <pci.h>
 #include <dm.h>
 
+#define REV_1_0					(0x10)
+
 #ifndef CONFIG_SYS_PCI_MEMORY_SIZE
 #define CONFIG_SYS_PCI_MEMORY_SIZE		(4 * 1024 * 1024 * 1024ULL)
 #endif
@@ -161,6 +163,8 @@
 #define PCIE_LUT_LDR(n)				(0x804 + (n) * 8)
 #define PCIE_LUT_ENABLE				BIT(31)
 #define PCIE_LUT_ENTRY_COUNT			32
+#define PCIE_LUT_GCR				(0x28)
+#define PCIE_LUT_GCR_RRE			(0)
 
 /* PF control registers */
 #define PCIE_LTSSM_STA				0x7fc
@@ -190,6 +194,7 @@ struct ls_pcie_g4 {
 	int stream_id_cur;
 	int mode;
 	int sriov_support;
+	u8 rev;
 };
 
 extern struct list_head ls_pcie_g4_list;
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 09/12] dm: pci: add APIs for capability accessors
  2019-03-11  2:57 [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
                   ` (7 preceding siblings ...)
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 08/12] pci: ls_pcie_g4: add Workaround for A-011577 Z.q. Hou
@ 2019-03-11  2:58 ` Z.q. Hou
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 10/12] dm: pci: add APIs for MPS and MRRS accessors Z.q. Hou
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2019-03-11  2:58 UTC (permalink / raw)
  To: u-boot

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

This patch introduce a set of PCI/PCIe capability accessors,
including 16-bit and 32-bit read, write and clear_and_set
operations.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V4:
 - New patch

 drivers/pci/pci-uclass.c | 153 +++++++++++++++++++++++++++++++++++++++
 include/pci.h            |  20 +++++
 2 files changed, 173 insertions(+)

diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 824fa11907..4bb30f5d2b 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -1443,6 +1443,159 @@ int dm_pci_find_ext_capability(struct udevice *dev, int cap)
 	return dm_pci_find_next_ext_capability(dev, 0, cap);
 }
 
+/**
+ * dm_pci_capability_read() - PCI capability register read
+ *
+ * @dev:	PCI device to read
+ * @cap:	capability code
+ * @pos:	register offset
+ * @val:	pointer to keep the read value
+ * @size:	register width
+ *
+ * Returns 0 if OK or appropriate error value.
+ */
+int dm_pci_capability_read(struct udevice *dev, int cap, int pos,
+			   ulong *val, enum pci_size_t size)
+{
+	u32 off;
+
+	switch (size) {
+	case PCI_SIZE_16:
+		if (pos & 1)
+			return -EINVAL;
+		break;
+	case PCI_SIZE_32:
+		if (pos & 3)
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	off = dm_pci_find_capability(dev, cap);
+	if (off)
+		return dm_pci_read_config(dev, off + pos, val, size);
+
+	return -EINVAL;
+}
+
+/**
+ * dm_pci_capability_write() - PCI capability register write
+ *
+ * @dev:	PCI device to write
+ * @cap:	capability code
+ * @pos:	register offset
+ * @val:	value to write
+ * @size:	register width
+ *
+ * Returns 0 if OK or appropriate error value.
+ */
+int dm_pci_capability_write(struct udevice *dev, int cap, int pos,
+			    ulong val, enum pci_size_t size)
+{
+	u32 off;
+
+	switch (size) {
+	case PCI_SIZE_16:
+		if (pos & 1)
+			return -EINVAL;
+		break;
+	case PCI_SIZE_32:
+		if (pos & 3)
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	off = dm_pci_find_capability(dev, cap);
+	if (off)
+		return dm_pci_write_config(dev, off + pos, val, size);
+
+	return -EINVAL;
+}
+
+int dm_pci_capability_read_word(struct udevice *dev, int cap, int pos, u16 *val)
+{
+	ulong value;
+	int ret;
+
+	ret = dm_pci_capability_read(dev, cap, pos, &value, PCI_SIZE_16);
+	if (ret)
+		return ret;
+	*val = value;
+
+	return 0;
+}
+
+int dm_pci_capability_write_word(struct udevice *dev, int cap, int pos, u16 val)
+{
+	return dm_pci_capability_write(dev, cap, pos, val, PCI_SIZE_16);
+}
+
+int dm_pci_capability_read_dword(struct udevice *dev, int cap,
+				 int pos, u32 *val)
+{
+	ulong value;
+	int ret;
+
+	return dm_pci_capability_read(dev, cap, pos, &value, PCI_SIZE_32);
+	if (ret)
+		return ret;
+	*val = value;
+
+	return 0;
+}
+
+int dm_pci_capability_write_dword(struct udevice *dev, int cap,
+				  int pos, u32 val)
+{
+	return dm_pci_capability_write(dev, cap, pos, val, PCI_SIZE_32);
+}
+
+/**
+ * dm_pci_capability_clear_and_set() - PCI capability register update
+ *
+ * @dev:	PCI device to update
+ * @cap:	capability code
+ * @pos:	register offset
+ * @clear:	bits to clear
+ * @set:	bits to set
+ * @size:	register width
+ *
+ * Returns 0 if OK or appropriate error value.
+ */
+int dm_pci_capability_clear_and_set(struct udevice *dev, int cap, int pos,
+				    ulong clear, ulong set,
+				    enum pci_size_t size)
+{
+	int ret;
+	ulong val;
+
+	ret = dm_pci_capability_read(dev, cap, pos, &val, size);
+	if (!ret) {
+		val &= ~clear;
+		val |= set;
+		ret = dm_pci_capability_write(dev, cap, pos, val, size);
+	}
+
+	return ret;
+}
+
+int dm_pci_capability_clear_and_set_word(struct udevice *dev, int cap,
+					 int pos, u16 clear, u16 set)
+{
+	return dm_pci_capability_clear_and_set(dev, cap, pos, clear,
+					       set, PCI_SIZE_16);
+}
+
+int dm_pci_capability_clear_and_set_dword(struct udevice *dev, int cap,
+					  int pos, u32 clear, u32 set)
+{
+	return dm_pci_capability_clear_and_set(dev, cap, pos, clear,
+					       set, PCI_SIZE_32);
+}
+
 UCLASS_DRIVER(pci) = {
 	.id		= UCLASS_PCI,
 	.name		= "pci",
diff --git a/include/pci.h b/include/pci.h
index 041f8e3747..d7b6d9f4ff 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -1405,6 +1405,26 @@ int dm_pci_find_next_ext_capability(struct udevice *dev, int start, int cap);
  */
 int dm_pci_find_ext_capability(struct udevice *dev, int cap);
 
+int dm_pci_capability_read(struct udevice *dev, int cap, int pos,
+			   ulong *val, enum pci_size_t size);
+int dm_pci_capability_write(struct udevice *dev, int cap, int pos,
+			    ulong val, enum pci_size_t size);
+int dm_pci_capability_read_word(struct udevice *dev, int cap,
+				int pos, u16 *val);
+int dm_pci_capability_write_word(struct udevice *dev, int cap,
+				 int pos, u16 val);
+int dm_pci_capability_read_dword(struct udevice *dev, int cap,
+				 int pos, u32 *val);
+int dm_pci_capability_write_dword(struct udevice *dev, int cap,
+				  int pos, u32 val);
+int dm_pci_capability_clear_and_set(struct udevice *dev, int cap, int pos,
+				    ulong clear, ulong set,
+				    enum pci_size_t size);
+int dm_pci_capability_clear_and_set_word(struct udevice *dev, int cap,
+					 int pos, u16 clear, u16 set);
+int dm_pci_capability_clear_and_set_dword(struct udevice *dev, int cap,
+					  int pos, u32 clear, u32 set);
+
 #define dm_pci_virt_to_bus(dev, addr, flags) \
 	dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags))
 #define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 10/12] dm: pci: add APIs for MPS and MRRS accessors
  2019-03-11  2:57 [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
                   ` (8 preceding siblings ...)
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 09/12] dm: pci: add APIs for capability accessors Z.q. Hou
@ 2019-03-11  2:58 ` Z.q. Hou
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 11/12] pci: ls_pcie_g4: Add Workaround for A-011451 Z.q. Hou
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 12/12] pci: ls_pcie_g4: add Workaround for A-011452 Z.q. Hou
  11 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2019-03-11  2:58 UTC (permalink / raw)
  To: u-boot

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

This patch introduce APIs for getting and updating the MPS
and MRRS fields of Device capability Device control register.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V4:
 - New patch

 drivers/pci/pci-uclass.c | 92 ++++++++++++++++++++++++++++++++++++++++
 include/pci.h            | 13 ++++++
 2 files changed, 105 insertions(+)

diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 4bb30f5d2b..b2d295435a 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -7,6 +7,7 @@
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
+#include <linux/log2.h>
 #include <pci.h>
 #include <asm/io.h>
 #include <dm/device-internal.h>
@@ -1596,6 +1597,97 @@ int dm_pci_capability_clear_and_set_dword(struct udevice *dev, int cap,
 					       set, PCI_SIZE_32);
 }
 
+/**
+ * dm_pci_get_readrq - get PCI Express read request size
+ * @dev: PCI device to query
+ *
+ * Returns maximum memory read request in bytes
+ *    or appropriate error value.
+ */
+int dm_pci_get_readrq(struct udevice *dev)
+{
+	u16 ctl;
+	int ret;
+
+	ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
+					  PCI_EXP_DEVCTL, &ctl);
+	if (ret)
+		return ret;
+
+	return 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+}
+
+/**
+ * dm_pci_set_readrq - set PCI Express maximum memory read request
+ * @dev: PCI device to query
+ * @rq: maximum memory read count in bytes
+ *    valid values are 128, 256, 512, 1024, 2048, 4096
+ */
+int dm_pci_set_readrq(struct udevice *dev, int rq)
+{
+	u16 val;
+
+	if (rq < 128 || rq > 4096 || !is_power_of_2(rq))
+		return -EINVAL;
+
+	val = (ffs(rq) - 8) << 12;
+
+	return dm_pci_capability_clear_and_set_word(dev, PCI_CAP_ID_EXP,
+						    PCI_EXP_DEVCTL,
+						    PCI_EXP_DEVCTL_READRQ,
+						    val);
+}
+
+/**
+ * dm_pci_get_mps - get PCI Express maximum payload size
+ * @dev: PCI device to query
+ *
+ * Returns maximum payload size in bytes
+ */
+int dm_pci_get_mps(struct udevice *dev)
+{
+	u16 ctl;
+	int ret;
+
+	ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
+					  PCI_EXP_DEVCTL, &ctl);
+	if (ret)
+		return ret;
+
+	return 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+}
+
+/**
+ * dm_pci_set_mps - set PCI Express maximum payload size
+ * @dev: PCI device to query
+ * @mps: maximum payload size in bytes
+ *    valid values are 128, 256, 512, 1024, 2048, 4096
+ */
+int dm_pci_set_mps(struct udevice *dev, int mps)
+{
+	u16 val, cap;
+	int ret;
+
+	if (mps < 128 || mps > 4096 || !is_power_of_2(mps))
+		return -EINVAL;
+
+	ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
+					  PCI_EXP_DEVCAP, &cap);
+	if (ret)
+		return ret;
+
+	val = ffs(mps) - 8;
+	if (val > (cap & PCI_EXP_DEVCAP_PAYLOAD))
+		return -EINVAL;
+
+	val <<= 5;
+
+	return dm_pci_capability_clear_and_set_word(dev, PCI_CAP_ID_EXP,
+						    PCI_EXP_DEVCTL,
+						    PCI_EXP_DEVCTL_PAYLOAD,
+						    val);
+}
+
 UCLASS_DRIVER(pci) = {
 	.id		= UCLASS_PCI,
 	.name		= "pci",
diff --git a/include/pci.h b/include/pci.h
index d7b6d9f4ff..b48df8a363 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -414,6 +414,14 @@
 #define PCI_MAX_PCI_DEVICES	32
 #define PCI_MAX_PCI_FUNCTIONS	8
 
+/* PCI Express capability registers */
+#define PCI_EXP_DEVCAP			4	/* Device capabilities */
+#define  PCI_EXP_DEVCAP_PAYLOAD		0x0007	/* Max_Payload_Size */
+
+#define PCI_EXP_DEVCTL			8	/* Device Control */
+#define  PCI_EXP_DEVCTL_PAYLOAD		0x00e0	/* Max_Payload_Size */
+#define  PCI_EXP_DEVCTL_READRQ		0x7000	/* Max_Read_Request_Size */
+
 #define PCI_FIND_CAP_TTL 0x48
 #define CAP_START_POS 0x40
 
@@ -1425,6 +1433,11 @@ int dm_pci_capability_clear_and_set_word(struct udevice *dev, int cap,
 int dm_pci_capability_clear_and_set_dword(struct udevice *dev, int cap,
 					  int pos, u32 clear, u32 set);
 
+int dm_pci_get_readrq(struct udevice *dev);
+int dm_pci_set_readrq(struct udevice *dev, int rq);
+int dm_pci_get_mps(struct udevice *dev);
+int dm_pci_set_mps(struct udevice *dev, int mps);
+
 #define dm_pci_virt_to_bus(dev, addr, flags) \
 	dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags))
 #define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 11/12] pci: ls_pcie_g4: Add Workaround for A-011451
  2019-03-11  2:57 [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
                   ` (9 preceding siblings ...)
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 10/12] dm: pci: add APIs for MPS and MRRS accessors Z.q. Hou
@ 2019-03-11  2:58 ` Z.q. Hou
  2019-03-13 14:54   ` Z.q. Hou
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 12/12] pci: ls_pcie_g4: add Workaround for A-011452 Z.q. Hou
  11 siblings, 1 reply; 19+ messages in thread
From: Z.q. Hou @ 2019-03-11  2:58 UTC (permalink / raw)
  To: u-boot

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

When LAYERSCAPE Gen4 PCIe controller is sending multiple split
completions and ACK latency expires indicating that ACK should
be send at priority. But because of large number of split
completions and FC update DLLP, the controller does not give
priority to ACK transmission. This results into ACK latency
timer timeout error at the link partner and the pending TLPs
are replayed by the link partner again.

Workaround:
1. Reduce the ACK latency timeout value to a very small value.
2. Restrict the number of completions from the PCIe controller
   to 1, by changing the Max Read Request Size (MRRS) of link
   partner to the same value as Max Packet size (MPS).

This ERRATA is only for LX2160A Rev1.0 and will be fixed in Rev2.0.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V4:
 - V3 patch find root port wrongly, fix it in V4.
 - Change to use the MPS and MRRS accessors.

 drivers/pci/pci_auto.c             | 35 ++++++++++++++++++++++++++++++
 drivers/pci/pcie_layerscape_gen4.c |  8 +++++++
 drivers/pci/pcie_layerscape_gen4.h |  4 ++++
 include/pci_ids.h                  |  1 +
 4 files changed, 48 insertions(+)

diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
index d7237f6eee..611462d1d4 100644
--- a/drivers/pci/pci_auto.c
+++ b/drivers/pci/pci_auto.c
@@ -22,6 +22,8 @@ void dm_pciauto_setup_device(struct udevice *dev, int bars_num,
 			     struct pci_region *prefetch, struct pci_region *io,
 			     bool enum_only)
 {
+	struct udevice *ctrl = pci_get_controller(dev);
+	struct udevice *rp;
 	u32 bar_response;
 	pci_size_t bar_size;
 	u16 cmdstat = 0;
@@ -32,6 +34,8 @@ void dm_pciauto_setup_device(struct udevice *dev, int bars_num,
 	struct pci_region *bar_res = NULL;
 	int found_mem64 = 0;
 	u16 class;
+	u16 vendor, dev_id;
+	u8 rev;
 
 	dm_pci_read_config16(dev, PCI_COMMAND, &cmdstat);
 	cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) |
@@ -161,6 +165,37 @@ void dm_pciauto_setup_device(struct udevice *dev, int bars_num,
 	dm_pci_write_config8(dev, PCI_CACHE_LINE_SIZE,
 			     CONFIG_SYS_PCI_CACHE_LINE_SIZE);
 	dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x80);
+
+	/*
+	 * When NXP LAYERSCAPE Gen4 PCIe controller is sending multiple split
+	 * completions and ACK latency expires indicating that ACK should be
+	 * send at priority. But because of large number of split completions
+	 * and FC update DLLP, the controller does not give priority to ACK
+	 * transmission. This results into ACK latency timer timeout error at
+	 * the link partner and the pending TLPs are replayed by the link
+	 * partner again.
+	 *
+	 * The workaround:
+	 * Restrict the number of completions from the PCIe controller to 1,
+	 * by changing the Max Read Request Size (MRRS) of link partner to the
+	 * same value as Max Packet size (MPS).
+	 *
+	 * So, set both the MPS and MRRS to the minimum 128B.
+	 */
+	device_find_first_child(ctrl, &rp);
+	if (!rp) {
+		debug("%s: Host: %s, RP is NULL\n", __func__, ctrl->name);
+		return;
+	}
+
+	dm_pci_read_config16(rp, PCI_VENDOR_ID, &vendor);
+	dm_pci_read_config16(rp, PCI_DEVICE_ID, &dev_id);
+	dm_pci_read_config8(rp, PCI_REVISION_ID, &rev);
+	if (vendor == PCI_VENDOR_ID_FREESCALE &&
+	    dev_id == PCI_DEVICE_ID_LX2160A && rev == 0x10) {
+		dm_pci_set_mps(dev, 128);
+		dm_pci_set_readrq(dev, 128);
+	}
 }
 
 void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus)
diff --git a/drivers/pci/pcie_layerscape_gen4.c b/drivers/pci/pcie_layerscape_gen4.c
index 799da2f7df..b530a9979c 100644
--- a/drivers/pci/pcie_layerscape_gen4.c
+++ b/drivers/pci/pcie_layerscape_gen4.c
@@ -526,6 +526,14 @@ static int ls_pcie_g4_probe(struct udevice *dev)
 
 	pcie->rev = readb(pcie->ccsr + PCI_REVISION_ID);
 
+	/* Set ACK latency timeout */
+	if (pcie->rev == REV_1_0) {
+		val = ccsr_readl(pcie, GPEX_ACK_REPLAY_TO);
+		val &= ~(ACK_LAT_TO_VAL_MASK << ACK_LAT_TO_VAL_SHIFT);
+		val |= (4 << ACK_LAT_TO_VAL_SHIFT);
+		ccsr_writel(pcie, GPEX_ACK_REPLAY_TO, val);
+	}
+
 	pcie->mode = readb(pcie->ccsr + PCI_HEADER_TYPE) & 0x7f;
 
 	if (pcie->mode == PCI_HEADER_TYPE_NORMAL) {
diff --git a/drivers/pci/pcie_layerscape_gen4.h b/drivers/pci/pcie_layerscape_gen4.h
index 137768cae7..ebde52e49a 100644
--- a/drivers/pci/pcie_layerscape_gen4.h
+++ b/drivers/pci/pcie_layerscape_gen4.h
@@ -58,6 +58,10 @@
 #define INI_VF_SHIFT				0
 #define GPEX_SRIOV_VF_OFFSET_STRIDE(pf)		(0x704 + (pf) * 4)
 
+#define GPEX_ACK_REPLAY_TO			0x438
+#define ACK_LAT_TO_VAL_SHIFT			0
+#define ACK_LAT_TO_VAL_MASK			0x1fff
+
 /* PAB CSR */
 #define PAB_CTRL				0x808
 #define PAB_CTRL_APIO_EN			BIT(0)
diff --git a/include/pci_ids.h b/include/pci_ids.h
index fdda679cc0..92a4339e3e 100644
--- a/include/pci_ids.h
+++ b/include/pci_ids.h
@@ -2481,6 +2481,7 @@
 #define PCI_DEVICE_ID_MPC8641		0x7010
 #define PCI_DEVICE_ID_MPC8641D		0x7011
 #define PCI_DEVICE_ID_MPC8610		0x7018
+#define PCI_DEVICE_ID_LX2160A		0x8D80
 
 #define PCI_VENDOR_ID_PASEMI		0x1959
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 12/12] pci: ls_pcie_g4: add Workaround for A-011452
  2019-03-11  2:57 [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
                   ` (10 preceding siblings ...)
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 11/12] pci: ls_pcie_g4: Add Workaround for A-011451 Z.q. Hou
@ 2019-03-11  2:58 ` Z.q. Hou
  2019-03-13 14:54   ` Z.q. Hou
  11 siblings, 1 reply; 19+ messages in thread
From: Z.q. Hou @ 2019-03-11  2:58 UTC (permalink / raw)
  To: u-boot

From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

For PCIe controllers with SRIOV, MSIx table entries of all the VFs
are not accessible if BAR size is set to less than 8MB.

This ERRATA is only for LX2160A Rev1.0 and will be fixed in Rev2.0.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V4:
 - No change

 drivers/pci/pcie_layerscape_gen4.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/pci/pcie_layerscape_gen4.c b/drivers/pci/pcie_layerscape_gen4.c
index b530a9979c..3792dbdf55 100644
--- a/drivers/pci/pcie_layerscape_gen4.c
+++ b/drivers/pci/pcie_layerscape_gen4.c
@@ -378,6 +378,11 @@ static void ls_pcie_g4_ep_set_bar_size(struct ls_pcie_g4 *pcie, int pf,
 	u32 mask_l = lower_32_bits(~(size - 1));
 	u32 mask_h = upper_32_bits(~(size - 1));
 
+	/* A-011452 workaround: set the VF BAR1 to 8MB */
+	if (pcie->rev == REV_1_0 && vf_bar && bar == 1) {
+		mask_l = lower_32_bits(~(SZ_8M - 1));
+		mask_h = upper_32_bits(~(SZ_8M - 1));
+	}
 	ccsr_writel(pcie, GPEX_BAR_SELECT, bar_pos);
 	ccsr_writel(pcie, GPEX_BAR_SIZE_LDW, mask_l);
 	ccsr_writel(pcie, GPEX_BAR_SIZE_UDW, mask_h);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 08/12] pci: ls_pcie_g4: add Workaround for A-011577
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 08/12] pci: ls_pcie_g4: add Workaround for A-011577 Z.q. Hou
@ 2019-03-13 14:53   ` Z.q. Hou
  0 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2019-03-13 14:53 UTC (permalink / raw)
  To: u-boot

Hi All,

Please ignore this patch, rev1.0 will not be production.

Thanks,
Zhiqiang


> -----Original Message-----
> From: Z.q. Hou
> Sent: 2019年3月11日 10:58
> To: u-boot at lists.denx.de; bmeng.cn at gmail.com; albert.u.boot at aribaud.net;
> Priyanka Jain <priyanka.jain@nxp.com>; York Sun <york.sun@nxp.com>;
> sriram.dash at nxp.com; yamada.masahiro at socionext.com; Prabhakar
> Kushwaha <prabhakar.kushwaha@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; M.h. Lian <minghuan.lian@nxp.com>
> Cc: Z.q. Hou <zhiqiang.hou@nxp.com>
> Subject: [PATCHv4 08/12] pci: ls_pcie_g4: add Workaround for A-011577
> 
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> 
> PCIe configuration access to non-existent function triggered SERROR interrupt
> exception.
> 
> Workaround:
> Disable error reporting on AXI bus during the Vendor ID read transactions in
> enumeration.
> 
> This ERRATA is only for LX2160A Rev1.0 and will be fixed in Rev2.0.
> 
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> ---
> V4:
>  - No change
> 
>  drivers/pci/pcie_layerscape_gen4.c | 8 ++++++++
> drivers/pci/pcie_layerscape_gen4.h | 5 +++++
>  2 files changed, 13 insertions(+)
> 
> diff --git a/drivers/pci/pcie_layerscape_gen4.c
> b/drivers/pci/pcie_layerscape_gen4.c
> index 4e0d5b168e..799da2f7df 100644
> --- a/drivers/pci/pcie_layerscape_gen4.c
> +++ b/drivers/pci/pcie_layerscape_gen4.c
> @@ -242,6 +242,9 @@ static int ls_pcie_g4_read_config(struct udevice *bus,
> pci_dev_t bdf,
> 
>  	address = ls_pcie_g4_conf_address(pcie, bdf, offset);
> 
> +	if (pcie->rev == REV_1_0 && offset == PCI_VENDOR_ID)
> +		lut_writel(pcie, 0x0 << PCIE_LUT_GCR_RRE, PCIE_LUT_GCR);
> +
>  	switch (size) {
>  	case PCI_SIZE_8:
>  		*valuep = readb(address);
> @@ -257,6 +260,9 @@ static int ls_pcie_g4_read_config(struct udevice *bus,
> pci_dev_t bdf,
>  		break;
>  	}
> 
> +	if (pcie->rev == REV_1_0 && offset == PCI_VENDOR_ID)
> +		lut_writel(pcie, 0x1 << PCIE_LUT_GCR_RRE, PCIE_LUT_GCR);
> +
>  	return ret;
>  }
> 
> @@ -518,6 +524,8 @@ static int ls_pcie_g4_probe(struct udevice *dev)
>  	      dev->name, (unsigned long)pcie->ccsr, (unsigned long)pcie->cfg,
>  	      pcie->big_endian);
> 
> +	pcie->rev = readb(pcie->ccsr + PCI_REVISION_ID);
> +
>  	pcie->mode = readb(pcie->ccsr + PCI_HEADER_TYPE) & 0x7f;
> 
>  	if (pcie->mode == PCI_HEADER_TYPE_NORMAL) { diff --git
> a/drivers/pci/pcie_layerscape_gen4.h b/drivers/pci/pcie_layerscape_gen4.h
> index 356b49f9ce..137768cae7 100644
> --- a/drivers/pci/pcie_layerscape_gen4.h
> +++ b/drivers/pci/pcie_layerscape_gen4.h
> @@ -11,6 +11,8 @@
>  #include <pci.h>
>  #include <dm.h>
> 
> +#define REV_1_0					(0x10)
> +
>  #ifndef CONFIG_SYS_PCI_MEMORY_SIZE
>  #define CONFIG_SYS_PCI_MEMORY_SIZE		(4 * 1024 * 1024 * 1024ULL)
>  #endif
> @@ -161,6 +163,8 @@
>  #define PCIE_LUT_LDR(n)				(0x804 + (n) * 8)
>  #define PCIE_LUT_ENABLE				BIT(31)
>  #define PCIE_LUT_ENTRY_COUNT			32
> +#define PCIE_LUT_GCR				(0x28)
> +#define PCIE_LUT_GCR_RRE			(0)
> 
>  /* PF control registers */
>  #define PCIE_LTSSM_STA				0x7fc
> @@ -190,6 +194,7 @@ struct ls_pcie_g4 {
>  	int stream_id_cur;
>  	int mode;
>  	int sriov_support;
> +	u8 rev;
>  };
> 
>  extern struct list_head ls_pcie_g4_list;
> --
> 2.17.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 11/12] pci: ls_pcie_g4: Add Workaround for A-011451
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 11/12] pci: ls_pcie_g4: Add Workaround for A-011451 Z.q. Hou
@ 2019-03-13 14:54   ` Z.q. Hou
  2019-03-29  9:36     ` Bin Meng
  0 siblings, 1 reply; 19+ messages in thread
From: Z.q. Hou @ 2019-03-13 14:54 UTC (permalink / raw)
  To: u-boot

Hi All,

Please ignore this patch, rev1.0 will not be production.

Thanks,
Zhiqiang


> -----Original Message-----
> From: Z.q. Hou
> Sent: 2019年3月11日 10:59
> To: u-boot at lists.denx.de; bmeng.cn at gmail.com; albert.u.boot at aribaud.net;
> Priyanka Jain <priyanka.jain@nxp.com>; York Sun <york.sun@nxp.com>;
> sriram.dash at nxp.com; yamada.masahiro at socionext.com; Prabhakar
> Kushwaha <prabhakar.kushwaha@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; M.h. Lian <minghuan.lian@nxp.com>
> Cc: Z.q. Hou <zhiqiang.hou@nxp.com>
> Subject: [PATCHv4 11/12] pci: ls_pcie_g4: Add Workaround for A-011451
> 
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> 
> When LAYERSCAPE Gen4 PCIe controller is sending multiple split completions
> and ACK latency expires indicating that ACK should be send at priority. But
> because of large number of split completions and FC update DLLP, the
> controller does not give priority to ACK transmission. This results into ACK
> latency timer timeout error at the link partner and the pending TLPs are
> replayed by the link partner again.
> 
> Workaround:
> 1. Reduce the ACK latency timeout value to a very small value.
> 2. Restrict the number of completions from the PCIe controller
>    to 1, by changing the Max Read Request Size (MRRS) of link
>    partner to the same value as Max Packet size (MPS).
> 
> This ERRATA is only for LX2160A Rev1.0 and will be fixed in Rev2.0.
> 
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> ---
> V4:
>  - V3 patch find root port wrongly, fix it in V4.
>  - Change to use the MPS and MRRS accessors.
> 
>  drivers/pci/pci_auto.c             | 35
> ++++++++++++++++++++++++++++++
>  drivers/pci/pcie_layerscape_gen4.c |  8 +++++++
> drivers/pci/pcie_layerscape_gen4.h |  4 ++++
>  include/pci_ids.h                  |  1 +
>  4 files changed, 48 insertions(+)
> 
> diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index
> d7237f6eee..611462d1d4 100644
> --- a/drivers/pci/pci_auto.c
> +++ b/drivers/pci/pci_auto.c
> @@ -22,6 +22,8 @@ void dm_pciauto_setup_device(struct udevice *dev, int
> bars_num,
>  			     struct pci_region *prefetch, struct pci_region *io,
>  			     bool enum_only)
>  {
> +	struct udevice *ctrl = pci_get_controller(dev);
> +	struct udevice *rp;
>  	u32 bar_response;
>  	pci_size_t bar_size;
>  	u16 cmdstat = 0;
> @@ -32,6 +34,8 @@ void dm_pciauto_setup_device(struct udevice *dev, int
> bars_num,
>  	struct pci_region *bar_res = NULL;
>  	int found_mem64 = 0;
>  	u16 class;
> +	u16 vendor, dev_id;
> +	u8 rev;
> 
>  	dm_pci_read_config16(dev, PCI_COMMAND, &cmdstat);
>  	cmdstat = (cmdstat & ~(PCI_COMMAND_IO |
> PCI_COMMAND_MEMORY)) | @@ -161,6 +165,37 @@ void
> dm_pciauto_setup_device(struct udevice *dev, int bars_num,
>  	dm_pci_write_config8(dev, PCI_CACHE_LINE_SIZE,
>  			     CONFIG_SYS_PCI_CACHE_LINE_SIZE);
>  	dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x80);
> +
> +	/*
> +	 * When NXP LAYERSCAPE Gen4 PCIe controller is sending multiple split
> +	 * completions and ACK latency expires indicating that ACK should be
> +	 * send at priority. But because of large number of split completions
> +	 * and FC update DLLP, the controller does not give priority to ACK
> +	 * transmission. This results into ACK latency timer timeout error at
> +	 * the link partner and the pending TLPs are replayed by the link
> +	 * partner again.
> +	 *
> +	 * The workaround:
> +	 * Restrict the number of completions from the PCIe controller to 1,
> +	 * by changing the Max Read Request Size (MRRS) of link partner to the
> +	 * same value as Max Packet size (MPS).
> +	 *
> +	 * So, set both the MPS and MRRS to the minimum 128B.
> +	 */
> +	device_find_first_child(ctrl, &rp);
> +	if (!rp) {
> +		debug("%s: Host: %s, RP is NULL\n", __func__, ctrl->name);
> +		return;
> +	}
> +
> +	dm_pci_read_config16(rp, PCI_VENDOR_ID, &vendor);
> +	dm_pci_read_config16(rp, PCI_DEVICE_ID, &dev_id);
> +	dm_pci_read_config8(rp, PCI_REVISION_ID, &rev);
> +	if (vendor == PCI_VENDOR_ID_FREESCALE &&
> +	    dev_id == PCI_DEVICE_ID_LX2160A && rev == 0x10) {
> +		dm_pci_set_mps(dev, 128);
> +		dm_pci_set_readrq(dev, 128);
> +	}
>  }
> 
>  void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus)
> diff --git a/drivers/pci/pcie_layerscape_gen4.c
> b/drivers/pci/pcie_layerscape_gen4.c
> index 799da2f7df..b530a9979c 100644
> --- a/drivers/pci/pcie_layerscape_gen4.c
> +++ b/drivers/pci/pcie_layerscape_gen4.c
> @@ -526,6 +526,14 @@ static int ls_pcie_g4_probe(struct udevice *dev)
> 
>  	pcie->rev = readb(pcie->ccsr + PCI_REVISION_ID);
> 
> +	/* Set ACK latency timeout */
> +	if (pcie->rev == REV_1_0) {
> +		val = ccsr_readl(pcie, GPEX_ACK_REPLAY_TO);
> +		val &= ~(ACK_LAT_TO_VAL_MASK << ACK_LAT_TO_VAL_SHIFT);
> +		val |= (4 << ACK_LAT_TO_VAL_SHIFT);
> +		ccsr_writel(pcie, GPEX_ACK_REPLAY_TO, val);
> +	}
> +
>  	pcie->mode = readb(pcie->ccsr + PCI_HEADER_TYPE) & 0x7f;
> 
>  	if (pcie->mode == PCI_HEADER_TYPE_NORMAL) { diff --git
> a/drivers/pci/pcie_layerscape_gen4.h b/drivers/pci/pcie_layerscape_gen4.h
> index 137768cae7..ebde52e49a 100644
> --- a/drivers/pci/pcie_layerscape_gen4.h
> +++ b/drivers/pci/pcie_layerscape_gen4.h
> @@ -58,6 +58,10 @@
>  #define INI_VF_SHIFT				0
>  #define GPEX_SRIOV_VF_OFFSET_STRIDE(pf)		(0x704 + (pf) * 4)
> 
> +#define GPEX_ACK_REPLAY_TO			0x438
> +#define ACK_LAT_TO_VAL_SHIFT			0
> +#define ACK_LAT_TO_VAL_MASK			0x1fff
> +
>  /* PAB CSR */
>  #define PAB_CTRL				0x808
>  #define PAB_CTRL_APIO_EN			BIT(0)
> diff --git a/include/pci_ids.h b/include/pci_ids.h index
> fdda679cc0..92a4339e3e 100644
> --- a/include/pci_ids.h
> +++ b/include/pci_ids.h
> @@ -2481,6 +2481,7 @@
>  #define PCI_DEVICE_ID_MPC8641		0x7010
>  #define PCI_DEVICE_ID_MPC8641D		0x7011
>  #define PCI_DEVICE_ID_MPC8610		0x7018
> +#define PCI_DEVICE_ID_LX2160A		0x8D80
> 
>  #define PCI_VENDOR_ID_PASEMI		0x1959
> 
> --
> 2.17.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 12/12] pci: ls_pcie_g4: add Workaround for A-011452
  2019-03-11  2:58 ` [U-Boot] [PATCHv4 12/12] pci: ls_pcie_g4: add Workaround for A-011452 Z.q. Hou
@ 2019-03-13 14:54   ` Z.q. Hou
  2019-03-17  3:28     ` Prabhakar Kushwaha
  0 siblings, 1 reply; 19+ messages in thread
From: Z.q. Hou @ 2019-03-13 14:54 UTC (permalink / raw)
  To: u-boot

Hi All,

Please ignore this patch, rev1.0 will not be production.

Thanks,
Zhiqiang


> -----Original Message-----
> From: Z.q. Hou
> Sent: 2019年3月11日 10:59
> To: u-boot at lists.denx.de; bmeng.cn at gmail.com; albert.u.boot at aribaud.net;
> Priyanka Jain <priyanka.jain@nxp.com>; York Sun <york.sun@nxp.com>;
> sriram.dash at nxp.com; yamada.masahiro at socionext.com; Prabhakar
> Kushwaha <prabhakar.kushwaha@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; M.h. Lian <minghuan.lian@nxp.com>
> Cc: Z.q. Hou <zhiqiang.hou@nxp.com>
> Subject: [PATCHv4 12/12] pci: ls_pcie_g4: add Workaround for A-011452
> 
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> 
> For PCIe controllers with SRIOV, MSIx table entries of all the VFs are not
> accessible if BAR size is set to less than 8MB.
> 
> This ERRATA is only for LX2160A Rev1.0 and will be fixed in Rev2.0.
> 
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> ---
> V4:
>  - No change
> 
>  drivers/pci/pcie_layerscape_gen4.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/pci/pcie_layerscape_gen4.c
> b/drivers/pci/pcie_layerscape_gen4.c
> index b530a9979c..3792dbdf55 100644
> --- a/drivers/pci/pcie_layerscape_gen4.c
> +++ b/drivers/pci/pcie_layerscape_gen4.c
> @@ -378,6 +378,11 @@ static void ls_pcie_g4_ep_set_bar_size(struct
> ls_pcie_g4 *pcie, int pf,
>  	u32 mask_l = lower_32_bits(~(size - 1));
>  	u32 mask_h = upper_32_bits(~(size - 1));
> 
> +	/* A-011452 workaround: set the VF BAR1 to 8MB */
> +	if (pcie->rev == REV_1_0 && vf_bar && bar == 1) {
> +		mask_l = lower_32_bits(~(SZ_8M - 1));
> +		mask_h = upper_32_bits(~(SZ_8M - 1));
> +	}
>  	ccsr_writel(pcie, GPEX_BAR_SELECT, bar_pos);
>  	ccsr_writel(pcie, GPEX_BAR_SIZE_LDW, mask_l);
>  	ccsr_writel(pcie, GPEX_BAR_SIZE_UDW, mask_h);
> --
> 2.17.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 12/12] pci: ls_pcie_g4: add Workaround for A-011452
  2019-03-13 14:54   ` Z.q. Hou
@ 2019-03-17  3:28     ` Prabhakar Kushwaha
  2019-03-25  2:28       ` Z.q. Hou
  0 siblings, 1 reply; 19+ messages in thread
From: Prabhakar Kushwaha @ 2019-03-17  3:28 UTC (permalink / raw)
  To: u-boot


> -----Original Message-----
> From: Z.q. Hou
> Sent: Wednesday, March 13, 2019 8:25 PM
> To: u-boot at lists.denx.de; bmeng.cn at gmail.com; albert.u.boot at aribaud.net;
> Priyanka Jain <priyanka.jain@nxp.com>; York Sun <york.sun@nxp.com>;
> sriram.dash at nxp.com; yamada.masahiro at socionext.com; Prabhakar
> Kushwaha <prabhakar.kushwaha@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; M.h. Lian <minghuan.lian@nxp.com>
> Subject: RE: [PATCHv4 12/12] pci: ls_pcie_g4: add Workaround for A-011452
> 
> Hi All,
> 
> Please ignore this patch, rev1.0 will not be production.
> 

I request you to resend your patch-set with the patches which you want to reviewed and accepted.
Please use [RESEND] in subject.

--pk 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 12/12] pci: ls_pcie_g4: add Workaround for A-011452
  2019-03-17  3:28     ` Prabhakar Kushwaha
@ 2019-03-25  2:28       ` Z.q. Hou
  0 siblings, 0 replies; 19+ messages in thread
From: Z.q. Hou @ 2019-03-25  2:28 UTC (permalink / raw)
  To: u-boot

Hi Prabhakar,

Thanks a lot for your comments!

> -----Original Message-----
> From: Prabhakar Kushwaha
> Sent: 2019年3月17日 11:28
> To: Z.q. Hou <zhiqiang.hou@nxp.com>; u-boot at lists.denx.de;
> bmeng.cn at gmail.com; albert.u.boot at aribaud.net; Priyanka Jain
> <priyanka.jain@nxp.com>; York Sun <york.sun@nxp.com>;
> sriram.dash at nxp.com; yamada.masahiro at socionext.com; Mingkai Hu
> <mingkai.hu@nxp.com>; M.h. Lian <minghuan.lian@nxp.com>
> Subject: RE: [PATCHv4 12/12] pci: ls_pcie_g4: add Workaround for A-011452
> 
> 
> > -----Original Message-----
> > From: Z.q. Hou
> > Sent: Wednesday, March 13, 2019 8:25 PM
> > To: u-boot at lists.denx.de; bmeng.cn at gmail.com;
> > albert.u.boot at aribaud.net; Priyanka Jain <priyanka.jain@nxp.com>; York
> > Sun <york.sun@nxp.com>; sriram.dash at nxp.com;
> > yamada.masahiro at socionext.com; Prabhakar Kushwaha
> > <prabhakar.kushwaha@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
> M.h.
> > Lian <minghuan.lian@nxp.com>
> > Subject: RE: [PATCHv4 12/12] pci: ls_pcie_g4: add Workaround for
> > A-011452
> >
> > Hi All,
> >
> > Please ignore this patch, rev1.0 will not be production.
> >
> 
> I request you to resend your patch-set with the patches which you want to
> reviewed and accepted.
> Please use [RESEND] in subject.

Resent the patch set with the workaround patches removed.
Thanks,
Zhiqiang

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCHv4 11/12] pci: ls_pcie_g4: Add Workaround for A-011451
  2019-03-13 14:54   ` Z.q. Hou
@ 2019-03-29  9:36     ` Bin Meng
  0 siblings, 0 replies; 19+ messages in thread
From: Bin Meng @ 2019-03-29  9:36 UTC (permalink / raw)
  To: u-boot

Hi Zhiqiang,

On Wed, Mar 13, 2019 at 10:54 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> Hi All,
>
> Please ignore this patch, rev1.0 will not be production.
>

OK, thanks for the update.

So let's not touch the generic PCI codes this time.

Regards,
Bin

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2019-03-29  9:36 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-11  2:57 [U-Boot] [PATCHv4 00/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
2019-03-11  2:57 ` [U-Boot] [PATCHv4 01/12] armv8: fsl-layerscpae: correct the PCIe controllers' region size Z.q. Hou
2019-03-11  2:58 ` [U-Boot] [PATCHv4 02/12] armv8: lx2160a: add MMU table entries for PCIe Z.q. Hou
2019-03-11  2:58 ` [U-Boot] [PATCHv4 03/12] pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs Z.q. Hou
2019-03-11  2:58 ` [U-Boot] [PATCHv4 04/12] kconfig: add dependency PCIE_LAYERSCAPE_GEN4 for FSL_PCIE_COMPAT Z.q. Hou
2019-03-11  2:58 ` [U-Boot] [PATCHv4 05/12] pci: ls_pcie_g4: add device tree fixups for PCI Stream IDs Z.q. Hou
2019-03-11  2:58 ` [U-Boot] [PATCHv4 06/12] armv8: lx2160a: add PCIe controller DT nodes Z.q. Hou
2019-03-11  2:58 ` [U-Boot] [PATCHv4 07/12] armv8: lx2160a: enable PCIe support Z.q. Hou
2019-03-11  2:58 ` [U-Boot] [PATCHv4 08/12] pci: ls_pcie_g4: add Workaround for A-011577 Z.q. Hou
2019-03-13 14:53   ` Z.q. Hou
2019-03-11  2:58 ` [U-Boot] [PATCHv4 09/12] dm: pci: add APIs for capability accessors Z.q. Hou
2019-03-11  2:58 ` [U-Boot] [PATCHv4 10/12] dm: pci: add APIs for MPS and MRRS accessors Z.q. Hou
2019-03-11  2:58 ` [U-Boot] [PATCHv4 11/12] pci: ls_pcie_g4: Add Workaround for A-011451 Z.q. Hou
2019-03-13 14:54   ` Z.q. Hou
2019-03-29  9:36     ` Bin Meng
2019-03-11  2:58 ` [U-Boot] [PATCHv4 12/12] pci: ls_pcie_g4: add Workaround for A-011452 Z.q. Hou
2019-03-13 14:54   ` Z.q. Hou
2019-03-17  3:28     ` Prabhakar Kushwaha
2019-03-25  2:28       ` 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.