linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs
@ 2019-01-29  8:08 Z.q. Hou
  2019-01-29  8:08 ` [PATCHv3 01/27] PCI: mobiveil: uniform the register accessors Z.q. Hou
                   ` (28 more replies)
  0 siblings, 29 replies; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:08 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

This patch set is aim to refactor the Mobiveil driver and add
PCIe support for NXP Layerscape series SoCs integrated Mobiveil's
PCIe Gen4 controller.

Hou Zhiqiang (27):
  PCI: mobiveil: uniform the register accessors
  PCI: mobiveil: format the code without function change
  PCI: mobiveil: correct the returned error number
  PCI: mobiveil: remove flag MSI_FLAG_MULTI_PCI_MSI
  PCI: mobiveil: correct PCI base address in MEM/IO outbound windows
  PCI: mobiveil: replace the resource list iteration function
  PCI: mobiveil: use WIN_NUM_0 explicitly for CFG outbound window
  PCI: mobiveil: use the 1st inbound window for MEM inbound transactions
  PCI: mobiveil: correct inbound/outbound window setup routines
  PCI: mobiveil: fix the INTx process error
  PCI: mobiveil: only fix up the Class Code field
  PCI: mobiveil: move out the link up waiting from mobiveil_host_init
  PCI: mobiveil: move irq chained handler setup out of DT parse
  PCI: mobiveil: initialize Primary/Secondary/Subordinate bus number
  dt-bindings: pci: mobiveil: change gpio_slave and apb_csr to optional
  PCI: mobiveil: refactor Mobiveil PCIe Host Bridge IP driver
  PCI: mobiveil: fix the checking of valid device
  PCI: mobiveil: continue to initialize the host upon no PCIe link
  PCI: mobiveil: disabled IB and OB windows set by bootloader
  PCI: mobiveil: add Byte and Half-Word width register accessors
  PCI: mobiveil: make mobiveil_host_init can be used to re-init host
  dt-bindings: pci: Add NXP Layerscape SoCs PCIe Gen4 controller
  PCI: mobiveil: add PCIe Gen4 RC driver for NXP Layerscape SoCs
  PCI: mobiveil: ls_pcie_g4: add Workaround for A-011577
  PCI: mobiveil: ls_pcie_g4: add Workaround for A-011451
  arm64: dts: freescale: lx2160a: add pcie DT nodes
  arm64: defconfig: Enable CONFIG_PCI_LAYERSCAPE_GEN4

 .../bindings/pci/layerscape-pci-gen4.txt      |  52 ++
 .../devicetree/bindings/pci/mobiveil-pcie.txt |   2 +
 MAINTAINERS                                   |  10 +-
 .../arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 163 ++++
 arch/arm64/configs/defconfig                  |   1 +
 drivers/pci/controller/Kconfig                |  11 +-
 drivers/pci/controller/Makefile               |   2 +-
 drivers/pci/controller/mobiveil/Kconfig       |  34 +
 drivers/pci/controller/mobiveil/Makefile      |   5 +
 .../controller/mobiveil/pci-layerscape-gen4.c | 306 +++++++
 .../controller/mobiveil/pcie-mobiveil-host.c  | 640 +++++++++++++
 .../controller/mobiveil/pcie-mobiveil-plat.c  |  54 ++
 .../pci/controller/mobiveil/pcie-mobiveil.c   | 246 +++++
 .../pci/controller/mobiveil/pcie-mobiveil.h   | 229 +++++
 drivers/pci/controller/pcie-mobiveil.c        | 861 ------------------
 15 files changed, 1743 insertions(+), 873 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/layerscape-pci-gen4.txt
 create mode 100644 drivers/pci/controller/mobiveil/Kconfig
 create mode 100644 drivers/pci/controller/mobiveil/Makefile
 create mode 100644 drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
 create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
 create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
 create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.c
 create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.h
 delete mode 100644 drivers/pci/controller/pcie-mobiveil.c

-- 
2.17.1


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

* [PATCHv3 01/27] PCI: mobiveil: uniform the register accessors
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
@ 2019-01-29  8:08 ` Z.q. Hou
  2019-02-05  5:39   ` Subrahmanya Lingappa
  2019-01-29  8:08 ` [PATCHv3 02/27] PCI: mobiveil: format the code without function change Z.q. Hou
                   ` (27 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:08 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

It's confused that R/W some registers by csr_readl()/csr_writel(),
while others by read_paged_register()/write_paged_register().
Actually the low 3KB of 4KB PCIe configure space can be accessed
directly and high 1KB is paging area. So this patch uniformed the
register accessors to csr_readl() and csr_writel() by comparing
the register offset with page access boundary 3KB in the accessor
internal.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 179 +++++++++++++++++--------
 1 file changed, 124 insertions(+), 55 deletions(-)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index 77052a0712d0..d55c7e780c6e 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -47,7 +47,6 @@
 #define  PAGE_SEL_SHIFT	13
 #define  PAGE_SEL_MASK		0x3f
 #define  PAGE_LO_MASK		0x3ff
-#define  PAGE_SEL_EN		0xc00
 #define  PAGE_SEL_OFFSET_SHIFT	10
 
 #define PAB_AXI_PIO_CTRL	0x0840
@@ -117,6 +116,12 @@
 #define LINK_WAIT_MIN	90000
 #define LINK_WAIT_MAX	100000
 
+#define PAGED_ADDR_BNDRY			0xc00
+#define OFFSET_TO_PAGE_ADDR(off)		\
+	((off & PAGE_LO_MASK) | PAGED_ADDR_BNDRY)
+#define OFFSET_TO_PAGE_IDX(off)			\
+	((off >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK)
+
 struct mobiveil_msi {			/* MSI information */
 	struct mutex lock;		/* protect bitmap variable */
 	struct irq_domain *msi_domain;
@@ -145,15 +150,119 @@ struct mobiveil_pcie {
 	struct mobiveil_msi msi;
 };
 
-static inline void csr_writel(struct mobiveil_pcie *pcie, const u32 value,
-		const u32 reg)
+/*
+ * mobiveil_pcie_sel_page - routine to access paged register
+ *
+ * Registers whose address greater than PAGED_ADDR_BNDRY (0xc00) are paged,
+ * for this scheme to work extracted higher 6 bits of the offset will be
+ * written to pg_sel field of PAB_CTRL register and rest of the lower 10
+ * bits enabled with PAGED_ADDR_BNDRY are used as offset of the register.
+ */
+static void mobiveil_pcie_sel_page(struct mobiveil_pcie *pcie, u8 pg_idx)
 {
-	writel_relaxed(value, pcie->csr_axi_slave_base + reg);
+	u32 val;
+
+	val = readl(pcie->csr_axi_slave_base + PAB_CTRL);
+	val &= ~(PAGE_SEL_MASK << PAGE_SEL_SHIFT);
+	val |= (pg_idx & PAGE_SEL_MASK) << PAGE_SEL_SHIFT;
+
+	writel(val, pcie->csr_axi_slave_base + PAB_CTRL);
 }
 
-static inline u32 csr_readl(struct mobiveil_pcie *pcie, const u32 reg)
+static void *mobiveil_pcie_comp_addr(struct mobiveil_pcie *pcie, u32 off)
 {
-	return readl_relaxed(pcie->csr_axi_slave_base + reg);
+	if (off < PAGED_ADDR_BNDRY) {
+		/* For directly accessed registers, clear the pg_sel field */
+		mobiveil_pcie_sel_page(pcie, 0);
+		return pcie->csr_axi_slave_base + off;
+	}
+
+	mobiveil_pcie_sel_page(pcie, OFFSET_TO_PAGE_IDX(off));
+	return pcie->csr_axi_slave_base + OFFSET_TO_PAGE_ADDR(off);
+}
+
+static int mobiveil_pcie_read(void __iomem *addr, int size, u32 *val)
+{
+	if ((uintptr_t)addr & (size - 1)) {
+		*val = 0;
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	switch (size) {
+	case 4:
+		*val = readl(addr);
+		break;
+	case 2:
+		*val = readw(addr);
+		break;
+	case 1:
+		*val = readb(addr);
+		break;
+	default:
+		*val = 0;
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int mobiveil_pcie_write(void __iomem *addr, int size, u32 val)
+{
+	if ((uintptr_t)addr & (size - 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	switch (size) {
+	case 4:
+		writel(val, addr);
+		break;
+	case 2:
+		writew(val, addr);
+		break;
+	case 1:
+		writeb(val, addr);
+		break;
+	default:
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static u32 csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size)
+{
+	void *addr;
+	u32 val;
+	int ret;
+
+	addr = mobiveil_pcie_comp_addr(pcie, off);
+
+	ret = mobiveil_pcie_read(addr, size, &val);
+	if (ret)
+		dev_err(&pcie->pdev->dev, "read CSR address failed\n");
+
+	return val;
+}
+
+static void csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, size_t size)
+{
+	void *addr;
+	int ret;
+
+	addr = mobiveil_pcie_comp_addr(pcie, off);
+
+	ret = mobiveil_pcie_write(addr, size, val);
+	if (ret)
+		dev_err(&pcie->pdev->dev, "write CSR address failed\n");
+}
+
+static u32 csr_readl(struct mobiveil_pcie *pcie, u32 off)
+{
+	return csr_read(pcie, off, 0x4);
+}
+
+static void csr_writel(struct mobiveil_pcie *pcie, u32 val, u32 off)
+{
+	csr_write(pcie, val, off, 0x4);
 }
 
 static bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie)
@@ -342,45 +451,6 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
 	return 0;
 }
 
-/*
- * select_paged_register - routine to access paged register of root complex
- *
- * registers of RC are paged, for this scheme to work
- * extracted higher 6 bits of the offset will be written to pg_sel
- * field of PAB_CTRL register and rest of the lower 10 bits enabled with
- * PAGE_SEL_EN are used as offset of the register.
- */
-static void select_paged_register(struct mobiveil_pcie *pcie, u32 offset)
-{
-	int pab_ctrl_dw, pg_sel;
-
-	/* clear pg_sel field */
-	pab_ctrl_dw = csr_readl(pcie, PAB_CTRL);
-	pab_ctrl_dw = (pab_ctrl_dw & ~(PAGE_SEL_MASK << PAGE_SEL_SHIFT));
-
-	/* set pg_sel field */
-	pg_sel = (offset >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK;
-	pab_ctrl_dw |= ((pg_sel << PAGE_SEL_SHIFT));
-	csr_writel(pcie, pab_ctrl_dw, PAB_CTRL);
-}
-
-static void write_paged_register(struct mobiveil_pcie *pcie,
-		u32 val, u32 offset)
-{
-	u32 off = (offset & PAGE_LO_MASK) | PAGE_SEL_EN;
-
-	select_paged_register(pcie, offset);
-	csr_writel(pcie, val, off);
-}
-
-static u32 read_paged_register(struct mobiveil_pcie *pcie, u32 offset)
-{
-	u32 off = (offset & PAGE_LO_MASK) | PAGE_SEL_EN;
-
-	select_paged_register(pcie, offset);
-	return csr_readl(pcie, off);
-}
-
 static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
 		int pci_addr, u32 type, u64 size)
 {
@@ -397,19 +467,19 @@ static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
 	pio_ctrl_val = csr_readl(pcie, PAB_PEX_PIO_CTRL);
 	csr_writel(pcie,
 		pio_ctrl_val | (1 << PIO_ENABLE_SHIFT), PAB_PEX_PIO_CTRL);
-	amap_ctrl_dw = read_paged_register(pcie, PAB_PEX_AMAP_CTRL(win_num));
+	amap_ctrl_dw = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
 	amap_ctrl_dw = (amap_ctrl_dw | (type << AMAP_CTRL_TYPE_SHIFT));
 	amap_ctrl_dw = (amap_ctrl_dw | (1 << AMAP_CTRL_EN_SHIFT));
 
-	write_paged_register(pcie, amap_ctrl_dw | lower_32_bits(size64),
-				PAB_PEX_AMAP_CTRL(win_num));
+	csr_writel(pcie, amap_ctrl_dw | lower_32_bits(size64),
+		   PAB_PEX_AMAP_CTRL(win_num));
 
-	write_paged_register(pcie, upper_32_bits(size64),
-				PAB_EXT_PEX_AMAP_SIZEN(win_num));
+	csr_writel(pcie, upper_32_bits(size64),
+		   PAB_EXT_PEX_AMAP_SIZEN(win_num));
 
-	write_paged_register(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
-	write_paged_register(pcie, pci_addr, PAB_PEX_AMAP_PEX_WIN_L(win_num));
-	write_paged_register(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));
+	csr_writel(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
+	csr_writel(pcie, pci_addr, PAB_PEX_AMAP_PEX_WIN_L(win_num));
+	csr_writel(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));
 }
 
 /*
@@ -437,8 +507,7 @@ static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
 	csr_writel(pcie, 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
 			lower_32_bits(size64), PAB_AXI_AMAP_CTRL(win_num));
 
-	write_paged_register(pcie, upper_32_bits(size64),
-				PAB_EXT_AXI_AMAP_SIZE(win_num));
+	csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num));
 
 	/*
 	 * program AXI window base with appropriate value in
-- 
2.17.1


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

* [PATCHv3 02/27] PCI: mobiveil: format the code without function change
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
  2019-01-29  8:08 ` [PATCHv3 01/27] PCI: mobiveil: uniform the register accessors Z.q. Hou
@ 2019-01-29  8:08 ` Z.q. Hou
  2019-02-05  5:48   ` Subrahmanya Lingappa
  2019-01-29  8:08 ` [PATCHv3 03/27] PCI: mobiveil: correct the returned error number Z.q. Hou
                   ` (26 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:08 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

Just format the code without functionality change.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 261 +++++++++++++------------
 1 file changed, 137 insertions(+), 124 deletions(-)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index d55c7e780c6e..b87471f08a40 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -31,38 +31,40 @@
  * translation tables are grouped into windows, each window registers are
  * grouped into blocks of 4 or 16 registers each
  */
-#define PAB_REG_BLOCK_SIZE	16
-#define PAB_EXT_REG_BLOCK_SIZE	4
+#define PAB_REG_BLOCK_SIZE		16
+#define PAB_EXT_REG_BLOCK_SIZE		4
 
-#define PAB_REG_ADDR(offset, win) (offset + (win * PAB_REG_BLOCK_SIZE))
-#define PAB_EXT_REG_ADDR(offset, win) (offset + (win * PAB_EXT_REG_BLOCK_SIZE))
+#define PAB_REG_ADDR(offset, win)	\
+	(offset + (win * PAB_REG_BLOCK_SIZE))
+#define PAB_EXT_REG_ADDR(offset, win)	\
+	(offset + (win * PAB_EXT_REG_BLOCK_SIZE))
 
-#define LTSSM_STATUS		0x0404
-#define  LTSSM_STATUS_L0_MASK	0x3f
-#define  LTSSM_STATUS_L0	0x2d
+#define LTSSM_STATUS			0x0404
+#define  LTSSM_STATUS_L0_MASK		0x3f
+#define  LTSSM_STATUS_L0		0x2d
 
-#define PAB_CTRL		0x0808
-#define  AMBA_PIO_ENABLE_SHIFT	0
-#define  PEX_PIO_ENABLE_SHIFT	1
-#define  PAGE_SEL_SHIFT	13
-#define  PAGE_SEL_MASK		0x3f
-#define  PAGE_LO_MASK		0x3ff
-#define  PAGE_SEL_OFFSET_SHIFT	10
+#define PAB_CTRL			0x0808
+#define  AMBA_PIO_ENABLE_SHIFT		0
+#define  PEX_PIO_ENABLE_SHIFT		1
+#define  PAGE_SEL_SHIFT			13
+#define  PAGE_SEL_MASK			0x3f
+#define  PAGE_LO_MASK			0x3ff
+#define  PAGE_SEL_OFFSET_SHIFT		10
 
-#define PAB_AXI_PIO_CTRL	0x0840
-#define  APIO_EN_MASK		0xf
+#define PAB_AXI_PIO_CTRL		0x0840
+#define  APIO_EN_MASK			0xf
 
-#define PAB_PEX_PIO_CTRL	0x08c0
-#define  PIO_ENABLE_SHIFT	0
+#define PAB_PEX_PIO_CTRL		0x08c0
+#define  PIO_ENABLE_SHIFT		0
 
 #define PAB_INTP_AMBA_MISC_ENB		0x0b0c
-#define PAB_INTP_AMBA_MISC_STAT	0x0b1c
+#define PAB_INTP_AMBA_MISC_STAT		0x0b1c
 #define  PAB_INTP_INTX_MASK		0x01e0
 #define  PAB_INTP_MSI_MASK		0x8
 
-#define PAB_AXI_AMAP_CTRL(win)	PAB_REG_ADDR(0x0ba0, win)
-#define  WIN_ENABLE_SHIFT	0
-#define  WIN_TYPE_SHIFT	1
+#define PAB_AXI_AMAP_CTRL(win)		PAB_REG_ADDR(0x0ba0, win)
+#define  WIN_ENABLE_SHIFT		0
+#define  WIN_TYPE_SHIFT			1
 
 #define PAB_EXT_AXI_AMAP_SIZE(win)	PAB_EXT_REG_ADDR(0xbaf0, win)
 
@@ -70,16 +72,16 @@
 #define  AXI_WINDOW_ALIGN_MASK		3
 
 #define PAB_AXI_AMAP_PEX_WIN_L(win)	PAB_REG_ADDR(0x0ba8, win)
-#define  PAB_BUS_SHIFT		24
-#define  PAB_DEVICE_SHIFT	19
-#define  PAB_FUNCTION_SHIFT	16
+#define  PAB_BUS_SHIFT			24
+#define  PAB_DEVICE_SHIFT		19
+#define  PAB_FUNCTION_SHIFT		16
 
 #define PAB_AXI_AMAP_PEX_WIN_H(win)	PAB_REG_ADDR(0x0bac, win)
 #define PAB_INTP_AXI_PIO_CLASS		0x474
 
-#define PAB_PEX_AMAP_CTRL(win)	PAB_REG_ADDR(0x4ba0, win)
-#define  AMAP_CTRL_EN_SHIFT	0
-#define  AMAP_CTRL_TYPE_SHIFT	1
+#define PAB_PEX_AMAP_CTRL(win)		PAB_REG_ADDR(0x4ba0, win)
+#define  AMAP_CTRL_EN_SHIFT		0
+#define  AMAP_CTRL_TYPE_SHIFT		1
 
 #define PAB_EXT_PEX_AMAP_SIZEN(win)	PAB_EXT_REG_ADDR(0xbef0, win)
 #define PAB_PEX_AMAP_AXI_WIN(win)	PAB_REG_ADDR(0x4ba4, win)
@@ -87,39 +89,39 @@
 #define PAB_PEX_AMAP_PEX_WIN_H(win)	PAB_REG_ADDR(0x4bac, win)
 
 /* starting offset of INTX bits in status register */
-#define PAB_INTX_START	5
+#define PAB_INTX_START			5
 
 /* supported number of MSI interrupts */
-#define PCI_NUM_MSI	16
+#define PCI_NUM_MSI			16
 
 /* MSI registers */
-#define MSI_BASE_LO_OFFSET	0x04
-#define MSI_BASE_HI_OFFSET	0x08
-#define MSI_SIZE_OFFSET	0x0c
-#define MSI_ENABLE_OFFSET	0x14
-#define MSI_STATUS_OFFSET	0x18
-#define MSI_DATA_OFFSET	0x20
-#define MSI_ADDR_L_OFFSET	0x24
-#define MSI_ADDR_H_OFFSET	0x28
+#define MSI_BASE_LO_OFFSET		0x04
+#define MSI_BASE_HI_OFFSET		0x08
+#define MSI_SIZE_OFFSET			0x0c
+#define MSI_ENABLE_OFFSET		0x14
+#define MSI_STATUS_OFFSET		0x18
+#define MSI_DATA_OFFSET			0x20
+#define MSI_ADDR_L_OFFSET		0x24
+#define MSI_ADDR_H_OFFSET		0x28
 
 /* outbound and inbound window definitions */
-#define WIN_NUM_0		0
-#define WIN_NUM_1		1
-#define CFG_WINDOW_TYPE	0
-#define IO_WINDOW_TYPE		1
-#define MEM_WINDOW_TYPE	2
-#define IB_WIN_SIZE		((u64)256 * 1024 * 1024 * 1024)
-#define MAX_PIO_WINDOWS	8
+#define WIN_NUM_0			0
+#define WIN_NUM_1			1
+#define CFG_WINDOW_TYPE			0
+#define IO_WINDOW_TYPE			1
+#define MEM_WINDOW_TYPE			2
+#define IB_WIN_SIZE			((u64)256 * 1024 * 1024 * 1024)
+#define MAX_PIO_WINDOWS			8
 
 /* Parameters for the waiting for link up routine */
-#define LINK_WAIT_MAX_RETRIES	10
-#define LINK_WAIT_MIN	90000
-#define LINK_WAIT_MAX	100000
+#define LINK_WAIT_MAX_RETRIES		10
+#define LINK_WAIT_MIN			90000
+#define LINK_WAIT_MAX			100000
 
-#define PAGED_ADDR_BNDRY			0xc00
-#define OFFSET_TO_PAGE_ADDR(off)		\
+#define PAGED_ADDR_BNDRY		0xc00
+#define OFFSET_TO_PAGE_ADDR(off)	\
 	((off & PAGE_LO_MASK) | PAGED_ADDR_BNDRY)
-#define OFFSET_TO_PAGE_IDX(off)			\
+#define OFFSET_TO_PAGE_IDX(off)		\
 	((off >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK)
 
 struct mobiveil_msi {			/* MSI information */
@@ -297,14 +299,14 @@ static void __iomem *mobiveil_pcie_map_bus(struct pci_bus *bus,
 					unsigned int devfn, int where)
 {
 	struct mobiveil_pcie *pcie = bus->sysdata;
+	u32 value;
 
 	if (!mobiveil_pcie_valid_device(bus, devfn))
 		return NULL;
 
-	if (bus->number == pcie->root_bus_nr) {
-		/* RC config access */
+	/* RC config access */
+	if (bus->number == pcie->root_bus_nr)
 		return pcie->csr_axi_slave_base + where;
-	}
 
 	/*
 	 * EP config access (in Config/APIO space)
@@ -312,10 +314,12 @@ static void __iomem *mobiveil_pcie_map_bus(struct pci_bus *bus,
 	 * (BDF) in PAB_AXI_AMAP_PEX_WIN_L0 Register.
 	 * Relies on pci_lock serialization
 	 */
-	csr_writel(pcie, bus->number << PAB_BUS_SHIFT |
-			PCI_SLOT(devfn) << PAB_DEVICE_SHIFT |
-			PCI_FUNC(devfn) << PAB_FUNCTION_SHIFT,
-			PAB_AXI_AMAP_PEX_WIN_L(WIN_NUM_0));
+	value = bus->number << PAB_BUS_SHIFT |
+		PCI_SLOT(devfn) << PAB_DEVICE_SHIFT |
+		PCI_FUNC(devfn) << PAB_FUNCTION_SHIFT;
+
+	csr_writel(pcie, value, PAB_AXI_AMAP_PEX_WIN_L(WIN_NUM_0));
+
 	return pcie->config_axi_slave_base + where;
 }
 
@@ -350,22 +354,22 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
 
 	/* Handle INTx */
 	if (intr_status & PAB_INTP_INTX_MASK) {
-		shifted_status = csr_readl(pcie, PAB_INTP_AMBA_MISC_STAT) >>
-			PAB_INTX_START;
+		shifted_status = csr_readl(pcie, PAB_INTP_AMBA_MISC_STAT);
+		shifted_status >>= PAB_INTX_START;
 		do {
 			for_each_set_bit(bit, &shifted_status, PCI_NUM_INTX) {
 				virq = irq_find_mapping(pcie->intx_domain,
-						bit + 1);
+							bit + 1);
 				if (virq)
 					generic_handle_irq(virq);
 				else
-					dev_err_ratelimited(dev,
-						"unexpected IRQ, INT%d\n", bit);
+					dev_err_ratelimited(dev, "unexpected IRQ, INT%d\n",
+							    bit);
 
 				/* clear interrupt */
 				csr_writel(pcie,
-					shifted_status << PAB_INTX_START,
-					PAB_INTP_AMBA_MISC_STAT);
+					   shifted_status << PAB_INTX_START,
+					   PAB_INTP_AMBA_MISC_STAT);
 			}
 		} while ((shifted_status >> PAB_INTX_START) != 0);
 	}
@@ -375,8 +379,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
 
 	/* handle MSI interrupts */
 	while (msi_status & 1) {
-		msi_data = readl_relaxed(pcie->apb_csr_base
-				+ MSI_DATA_OFFSET);
+		msi_data = readl_relaxed(pcie->apb_csr_base + MSI_DATA_OFFSET);
 
 		/*
 		 * MSI_STATUS_OFFSET register gets updated to zero
@@ -385,18 +388,18 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
 		 * two dummy reads.
 		 */
 		msi_addr_lo = readl_relaxed(pcie->apb_csr_base +
-				MSI_ADDR_L_OFFSET);
+					    MSI_ADDR_L_OFFSET);
 		msi_addr_hi = readl_relaxed(pcie->apb_csr_base +
-				MSI_ADDR_H_OFFSET);
+					    MSI_ADDR_H_OFFSET);
 		dev_dbg(dev, "MSI registers, data: %08x, addr: %08x:%08x\n",
-				msi_data, msi_addr_hi, msi_addr_lo);
+			msi_data, msi_addr_hi, msi_addr_lo);
 
 		virq = irq_find_mapping(msi->dev_domain, msi_data);
 		if (virq)
 			generic_handle_irq(virq);
 
 		msi_status = readl_relaxed(pcie->apb_csr_base +
-				MSI_STATUS_OFFSET);
+					   MSI_STATUS_OFFSET);
 	}
 
 	/* Clear the interrupt status */
@@ -413,7 +416,7 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
 
 	/* map config resource */
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-			"config_axi_slave");
+					   "config_axi_slave");
 	pcie->config_axi_slave_base = devm_pci_remap_cfg_resource(dev, res);
 	if (IS_ERR(pcie->config_axi_slave_base))
 		return PTR_ERR(pcie->config_axi_slave_base);
@@ -421,7 +424,7 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
 
 	/* map csr resource */
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-			"csr_axi_slave");
+					   "csr_axi_slave");
 	pcie->csr_axi_slave_base = devm_pci_remap_cfg_resource(dev, res);
 	if (IS_ERR(pcie->csr_axi_slave_base))
 		return PTR_ERR(pcie->csr_axi_slave_base);
@@ -452,7 +455,7 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
 }
 
 static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
-		int pci_addr, u32 type, u64 size)
+			       int pci_addr, u32 type, u64 size)
 {
 	int pio_ctrl_val;
 	int amap_ctrl_dw;
@@ -465,19 +468,20 @@ static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
 	}
 
 	pio_ctrl_val = csr_readl(pcie, PAB_PEX_PIO_CTRL);
-	csr_writel(pcie,
-		pio_ctrl_val | (1 << PIO_ENABLE_SHIFT), PAB_PEX_PIO_CTRL);
-	amap_ctrl_dw = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
-	amap_ctrl_dw = (amap_ctrl_dw | (type << AMAP_CTRL_TYPE_SHIFT));
-	amap_ctrl_dw = (amap_ctrl_dw | (1 << AMAP_CTRL_EN_SHIFT));
+	pio_ctrl_val |= 1 << PIO_ENABLE_SHIFT;
+	csr_writel(pcie, pio_ctrl_val, PAB_PEX_PIO_CTRL);
 
-	csr_writel(pcie, amap_ctrl_dw | lower_32_bits(size64),
-		   PAB_PEX_AMAP_CTRL(win_num));
+	amap_ctrl_dw = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
+	amap_ctrl_dw |= (type << AMAP_CTRL_TYPE_SHIFT) |
+			(1 << AMAP_CTRL_EN_SHIFT) |
+			lower_32_bits(size64);
+	csr_writel(pcie, amap_ctrl_dw, PAB_PEX_AMAP_CTRL(win_num));
 
 	csr_writel(pcie, upper_32_bits(size64),
 		   PAB_EXT_PEX_AMAP_SIZEN(win_num));
 
 	csr_writel(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
+
 	csr_writel(pcie, pci_addr, PAB_PEX_AMAP_PEX_WIN_L(win_num));
 	csr_writel(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));
 }
@@ -486,7 +490,8 @@ static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
  * routine to program the outbound windows
  */
 static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
-		u64 cpu_addr, u64 pci_addr, u32 config_io_bit, u64 size)
+			       u64 cpu_addr, u64 pci_addr,
+			       u32 config_io_bit, u64 size)
 {
 
 	u32 value, type;
@@ -505,7 +510,7 @@ static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
 	type = config_io_bit;
 	value = csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num));
 	csr_writel(pcie, 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
-			lower_32_bits(size64), PAB_AXI_AMAP_CTRL(win_num));
+		   lower_32_bits(size64), PAB_AXI_AMAP_CTRL(win_num));
 
 	csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num));
 
@@ -515,14 +520,14 @@ static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
 	 */
 	value = csr_readl(pcie, PAB_AXI_AMAP_AXI_WIN(win_num));
 	csr_writel(pcie, cpu_addr & (~AXI_WINDOW_ALIGN_MASK),
-			PAB_AXI_AMAP_AXI_WIN(win_num));
+		   PAB_AXI_AMAP_AXI_WIN(win_num));
 
 	value = csr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_H(win_num));
 
 	csr_writel(pcie, lower_32_bits(pci_addr),
-			PAB_AXI_AMAP_PEX_WIN_L(win_num));
+		   PAB_AXI_AMAP_PEX_WIN_L(win_num));
 	csr_writel(pcie, upper_32_bits(pci_addr),
-			PAB_AXI_AMAP_PEX_WIN_H(win_num));
+		   PAB_AXI_AMAP_PEX_WIN_H(win_num));
 
 	pcie->ob_wins_configured++;
 }
@@ -538,7 +543,9 @@ static int mobiveil_bringup_link(struct mobiveil_pcie *pcie)
 
 		usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
 	}
+
 	dev_err(&pcie->pdev->dev, "link never came up\n");
+
 	return -ETIMEDOUT;
 }
 
@@ -551,16 +558,16 @@ static void mobiveil_pcie_enable_msi(struct mobiveil_pcie *pcie)
 	msi->msi_pages_phys = (phys_addr_t)msg_addr;
 
 	writel_relaxed(lower_32_bits(msg_addr),
-		pcie->apb_csr_base + MSI_BASE_LO_OFFSET);
+		       pcie->apb_csr_base + MSI_BASE_LO_OFFSET);
 	writel_relaxed(upper_32_bits(msg_addr),
-		pcie->apb_csr_base + MSI_BASE_HI_OFFSET);
+		       pcie->apb_csr_base + MSI_BASE_HI_OFFSET);
 	writel_relaxed(4096, pcie->apb_csr_base + MSI_SIZE_OFFSET);
 	writel_relaxed(1, pcie->apb_csr_base + MSI_ENABLE_OFFSET);
 }
 
 static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 {
-	u32 value, pab_ctrl, type = 0;
+	u32 value, pab_ctrl, type;
 	int err;
 	struct resource_entry *win, *tmp;
 
@@ -575,26 +582,27 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 	 * Space
 	 */
 	value = csr_readl(pcie, PCI_COMMAND);
-	csr_writel(pcie, value | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
-		PCI_COMMAND_MASTER, PCI_COMMAND);
+	value |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+	csr_writel(pcie, value, PCI_COMMAND);
 
 	/*
 	 * program PIO Enable Bit to 1 (and PEX PIO Enable to 1) in PAB_CTRL
 	 * register
 	 */
 	pab_ctrl = csr_readl(pcie, PAB_CTRL);
-	csr_writel(pcie, pab_ctrl | (1 << AMBA_PIO_ENABLE_SHIFT) |
-		(1 << PEX_PIO_ENABLE_SHIFT), PAB_CTRL);
+	pab_ctrl |= (1 << AMBA_PIO_ENABLE_SHIFT) | (1 << PEX_PIO_ENABLE_SHIFT);
+	csr_writel(pcie, pab_ctrl, PAB_CTRL);
 
 	csr_writel(pcie, (PAB_INTP_INTX_MASK | PAB_INTP_MSI_MASK),
-		PAB_INTP_AMBA_MISC_ENB);
+		   PAB_INTP_AMBA_MISC_ENB);
 
 	/*
 	 * program PIO Enable Bit to 1 and Config Window Enable Bit to 1 in
 	 * PAB_AXI_PIO_CTRL Register
 	 */
 	value = csr_readl(pcie, PAB_AXI_PIO_CTRL);
-	csr_writel(pcie, value | APIO_EN_MASK, PAB_AXI_PIO_CTRL);
+	value |= APIO_EN_MASK;
+	csr_writel(pcie, value, PAB_AXI_PIO_CTRL);
 
 	/*
 	 * we'll program one outbound window for config reads and
@@ -605,25 +613,25 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 
 	/* config outbound translation window */
 	program_ob_windows(pcie, pcie->ob_wins_configured,
-			pcie->ob_io_res->start, 0, CFG_WINDOW_TYPE,
-			resource_size(pcie->ob_io_res));
+			   pcie->ob_io_res->start, 0, CFG_WINDOW_TYPE,
+			   resource_size(pcie->ob_io_res));
 
 	/* memory inbound translation window */
 	program_ib_windows(pcie, WIN_NUM_1, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
 
 	/* Get the I/O and memory ranges from DT */
 	resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
-		type = 0;
 		if (resource_type(win->res) == IORESOURCE_MEM)
 			type = MEM_WINDOW_TYPE;
-		if (resource_type(win->res) == IORESOURCE_IO)
+		else if (resource_type(win->res) == IORESOURCE_IO)
 			type = IO_WINDOW_TYPE;
-		if (type) {
-			/* configure outbound translation window */
-			program_ob_windows(pcie, pcie->ob_wins_configured,
-				win->res->start, 0, type,
-				resource_size(win->res));
-		}
+		else
+			continue;
+
+		/* configure outbound translation window */
+		program_ob_windows(pcie, pcie->ob_wins_configured,
+				   win->res->start, 0, type,
+				   resource_size(win->res));
 	}
 
 	/* setup MSI hardware registers */
@@ -643,7 +651,8 @@ static void mobiveil_mask_intx_irq(struct irq_data *data)
 	mask = 1 << ((data->hwirq + PAB_INTX_START) - 1);
 	raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags);
 	shifted_val = csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB);
-	csr_writel(pcie, (shifted_val & (~mask)), PAB_INTP_AMBA_MISC_ENB);
+	shifted_val &= ~mask;
+	csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB);
 	raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags);
 }
 
@@ -658,7 +667,8 @@ static void mobiveil_unmask_intx_irq(struct irq_data *data)
 	mask = 1 << ((data->hwirq + PAB_INTX_START) - 1);
 	raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags);
 	shifted_val = csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB);
-	csr_writel(pcie, (shifted_val | mask), PAB_INTP_AMBA_MISC_ENB);
+	shifted_val |= mask;
+	csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB);
 	raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags);
 }
 
@@ -672,10 +682,11 @@ static struct irq_chip intx_irq_chip = {
 
 /* routine to setup the INTx related data */
 static int mobiveil_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
-		irq_hw_number_t hwirq)
+				  irq_hw_number_t hwirq)
 {
 	irq_set_chip_and_handler(irq, &intx_irq_chip, handle_level_irq);
 	irq_set_chip_data(irq, domain->host_data);
+
 	return 0;
 }
 
@@ -692,7 +703,7 @@ static struct irq_chip mobiveil_msi_irq_chip = {
 
 static struct msi_domain_info mobiveil_msi_domain_info = {
 	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX),
+		   MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX),
 	.chip	= &mobiveil_msi_irq_chip,
 };
 
@@ -710,7 +721,7 @@ static void mobiveil_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 }
 
 static int mobiveil_msi_set_affinity(struct irq_data *irq_data,
-		const struct cpumask *mask, bool force)
+				     const struct cpumask *mask, bool force)
 {
 	return -EINVAL;
 }
@@ -722,7 +733,8 @@ static struct irq_chip mobiveil_msi_bottom_irq_chip = {
 };
 
 static int mobiveil_irq_msi_domain_alloc(struct irq_domain *domain,
-		unsigned int virq, unsigned int nr_irqs, void *args)
+					 unsigned int virq,
+					 unsigned int nr_irqs, void *args)
 {
 	struct mobiveil_pcie *pcie = domain->host_data;
 	struct mobiveil_msi *msi = &pcie->msi;
@@ -742,13 +754,13 @@ static int mobiveil_irq_msi_domain_alloc(struct irq_domain *domain,
 	mutex_unlock(&msi->lock);
 
 	irq_domain_set_info(domain, virq, bit, &mobiveil_msi_bottom_irq_chip,
-				domain->host_data, handle_level_irq,
-				NULL, NULL);
+			    domain->host_data, handle_level_irq, NULL, NULL);
 	return 0;
 }
 
 static void mobiveil_irq_msi_domain_free(struct irq_domain *domain,
-		unsigned int virq, unsigned int nr_irqs)
+					 unsigned int virq,
+					 unsigned int nr_irqs)
 {
 	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
 	struct mobiveil_pcie *pcie = irq_data_get_irq_chip_data(d);
@@ -756,12 +768,11 @@ static void mobiveil_irq_msi_domain_free(struct irq_domain *domain,
 
 	mutex_lock(&msi->lock);
 
-	if (!test_bit(d->hwirq, msi->msi_irq_in_use)) {
+	if (!test_bit(d->hwirq, msi->msi_irq_in_use))
 		dev_err(&pcie->pdev->dev, "trying to free unused MSI#%lu\n",
 			d->hwirq);
-	} else {
+	else
 		__clear_bit(d->hwirq, msi->msi_irq_in_use);
-	}
 
 	mutex_unlock(&msi->lock);
 }
@@ -785,12 +796,14 @@ static int mobiveil_allocate_msi_domains(struct mobiveil_pcie *pcie)
 	}
 
 	msi->msi_domain = pci_msi_create_irq_domain(fwnode,
-				&mobiveil_msi_domain_info, msi->dev_domain);
+						    &mobiveil_msi_domain_info,
+						    msi->dev_domain);
 	if (!msi->msi_domain) {
 		dev_err(dev, "failed to create MSI domain\n");
 		irq_domain_remove(msi->dev_domain);
 		return -ENOMEM;
 	}
+
 	return 0;
 }
 
@@ -801,8 +814,8 @@ static int mobiveil_pcie_init_irq_domain(struct mobiveil_pcie *pcie)
 	int ret;
 
 	/* setup INTx */
-	pcie->intx_domain = irq_domain_add_linear(node,
-				PCI_NUM_INTX, &intx_domain_ops, pcie);
+	pcie->intx_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
+						  &intx_domain_ops, pcie);
 
 	if (!pcie->intx_domain) {
 		dev_err(dev, "Failed to get a INTx IRQ domain\n");
@@ -917,10 +930,10 @@ MODULE_DEVICE_TABLE(of, mobiveil_pcie_of_match);
 static struct platform_driver mobiveil_pcie_driver = {
 	.probe = mobiveil_pcie_probe,
 	.driver = {
-			.name = "mobiveil-pcie",
-			.of_match_table = mobiveil_pcie_of_match,
-			.suppress_bind_attrs = true,
-		},
+		.name = "mobiveil-pcie",
+		.of_match_table = mobiveil_pcie_of_match,
+		.suppress_bind_attrs = true,
+	},
 };
 
 builtin_platform_driver(mobiveil_pcie_driver);
-- 
2.17.1


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

* [PATCHv3 03/27] PCI: mobiveil: correct the returned error number
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
  2019-01-29  8:08 ` [PATCHv3 01/27] PCI: mobiveil: uniform the register accessors Z.q. Hou
  2019-01-29  8:08 ` [PATCHv3 02/27] PCI: mobiveil: format the code without function change Z.q. Hou
@ 2019-01-29  8:08 ` Z.q. Hou
  2019-02-05  5:53   ` Subrahmanya Lingappa
  2019-01-29  8:08 ` [PATCHv3 04/27] PCI: mobiveil: remove flag MSI_FLAG_MULTI_PCI_MSI Z.q. Hou
                   ` (25 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:08 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

This patch corrected the returned error number by convention,
and removed a unnecessary error check.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index b87471f08a40..563210e731d3 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -819,7 +819,7 @@ static int mobiveil_pcie_init_irq_domain(struct mobiveil_pcie *pcie)
 
 	if (!pcie->intx_domain) {
 		dev_err(dev, "Failed to get a INTx IRQ domain\n");
-		return -ENODEV;
+		return -ENOMEM;
 	}
 
 	raw_spin_lock_init(&pcie->intx_mask_lock);
@@ -845,11 +845,9 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
 	/* allocate the PCIe port */
 	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
 	if (!bridge)
-		return -ENODEV;
+		return -ENOMEM;
 
 	pcie = pci_host_bridge_priv(bridge);
-	if (!pcie)
-		return -ENOMEM;
 
 	pcie->pdev = pdev;
 
@@ -866,7 +864,7 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
 						    &pcie->resources, &iobase);
 	if (ret) {
 		dev_err(dev, "Getting bridge resources failed\n");
-		return -ENOMEM;
+		return ret;
 	}
 
 	/*
-- 
2.17.1


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

* [PATCHv3 04/27] PCI: mobiveil: remove flag MSI_FLAG_MULTI_PCI_MSI
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (2 preceding siblings ...)
  2019-01-29  8:08 ` [PATCHv3 03/27] PCI: mobiveil: correct the returned error number Z.q. Hou
@ 2019-01-29  8:08 ` Z.q. Hou
  2019-02-05  6:05   ` Subrahmanya Lingappa
  2019-01-29  8:09 ` [PATCHv3 05/27] PCI: mobiveil: correct PCI base address in MEM/IO outbound windows Z.q. Hou
                   ` (24 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:08 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

The current code does not support multiple MSIs, so remove
the corresponding flag from the msi_domain_info structure.

Fixes: 1e913e58335f ("PCI: mobiveil: Add MSI support")
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index 563210e731d3..a0dd337c6214 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -703,7 +703,7 @@ static struct irq_chip mobiveil_msi_irq_chip = {
 
 static struct msi_domain_info mobiveil_msi_domain_info = {
 	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		   MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX),
+		   MSI_FLAG_PCI_MSIX),
 	.chip	= &mobiveil_msi_irq_chip,
 };
 
-- 
2.17.1


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

* [PATCHv3 05/27] PCI: mobiveil: correct PCI base address in MEM/IO outbound windows
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (3 preceding siblings ...)
  2019-01-29  8:08 ` [PATCHv3 04/27] PCI: mobiveil: remove flag MSI_FLAG_MULTI_PCI_MSI Z.q. Hou
@ 2019-01-29  8:09 ` Z.q. Hou
  2019-02-05  6:06   ` Subrahmanya Lingappa
  2019-01-29  8:09 ` [PATCHv3 06/27] PCI: mobiveil: replace the resource list iteration function Z.q. Hou
                   ` (23 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:09 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

It should get PCI base address from the DT node property 'ranges'
to setup MEM/IO outbound windows instead of always zero.

Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge
IP driver")
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index a0dd337c6214..8ff873023b5f 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -630,8 +630,9 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 
 		/* configure outbound translation window */
 		program_ob_windows(pcie, pcie->ob_wins_configured,
-				   win->res->start, 0, type,
-				   resource_size(win->res));
+				   win->res->start,
+				   win->res->start - win->offset,
+				   type, resource_size(win->res));
 	}
 
 	/* setup MSI hardware registers */
-- 
2.17.1


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

* [PATCHv3 06/27] PCI: mobiveil: replace the resource list iteration function
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (4 preceding siblings ...)
  2019-01-29  8:09 ` [PATCHv3 05/27] PCI: mobiveil: correct PCI base address in MEM/IO outbound windows Z.q. Hou
@ 2019-01-29  8:09 ` Z.q. Hou
  2019-02-05  6:07   ` Subrahmanya Lingappa
  2019-01-29  8:09 ` [PATCHv3 07/27] PCI: mobiveil: use WIN_NUM_0 explicitly for CFG outbound window Z.q. Hou
                   ` (22 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:09 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

As it won't delete any node in this iteration, replaced
the function resource_list_for_each_entry_safe() with
the resource_list_for_each_entry().

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index 8ff873023b5f..b2cc9c097fc9 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -569,7 +569,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 {
 	u32 value, pab_ctrl, type;
 	int err;
-	struct resource_entry *win, *tmp;
+	struct resource_entry *win;
 
 	err = mobiveil_bringup_link(pcie);
 	if (err) {
@@ -620,7 +620,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 	program_ib_windows(pcie, WIN_NUM_1, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
 
 	/* Get the I/O and memory ranges from DT */
-	resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
+	resource_list_for_each_entry(win, &pcie->resources) {
 		if (resource_type(win->res) == IORESOURCE_MEM)
 			type = MEM_WINDOW_TYPE;
 		else if (resource_type(win->res) == IORESOURCE_IO)
-- 
2.17.1


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

* [PATCHv3 07/27] PCI: mobiveil: use WIN_NUM_0 explicitly for CFG outbound window
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (5 preceding siblings ...)
  2019-01-29  8:09 ` [PATCHv3 06/27] PCI: mobiveil: replace the resource list iteration function Z.q. Hou
@ 2019-01-29  8:09 ` Z.q. Hou
  2019-02-05  6:08   ` Subrahmanya Lingappa
  2019-01-29  8:09 ` [PATCHv3 08/27] PCI: mobiveil: use the 1st inbound window for MEM inbound transactions Z.q. Hou
                   ` (21 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:09 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

As the .map_bus() use the WIN_NUM_0 for CFG transactions,
it's better passing WIN_NUM_0 explicitly when initialize
the CFG outbound window.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index b2cc9c097fc9..df71c11b4810 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -612,9 +612,8 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 	 */
 
 	/* config outbound translation window */
-	program_ob_windows(pcie, pcie->ob_wins_configured,
-			   pcie->ob_io_res->start, 0, CFG_WINDOW_TYPE,
-			   resource_size(pcie->ob_io_res));
+	program_ob_windows(pcie, WIN_NUM_0, pcie->ob_io_res->start, 0,
+			   CFG_WINDOW_TYPE, resource_size(pcie->ob_io_res));
 
 	/* memory inbound translation window */
 	program_ib_windows(pcie, WIN_NUM_1, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
-- 
2.17.1


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

* [PATCHv3 08/27] PCI: mobiveil: use the 1st inbound window for MEM inbound transactions
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (6 preceding siblings ...)
  2019-01-29  8:09 ` [PATCHv3 07/27] PCI: mobiveil: use WIN_NUM_0 explicitly for CFG outbound window Z.q. Hou
@ 2019-01-29  8:09 ` Z.q. Hou
  2019-02-05  6:08   ` Subrahmanya Lingappa
  2019-01-29  8:09 ` [PATCHv3 09/27] PCI: mobiveil: correct inbound/outbound window setup routines Z.q. Hou
                   ` (20 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:09 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

The inbound windows have different register set with outbound windows.
This patch change the MEM inbound window to the first one.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index df71c11b4810..e88afc792a5c 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -616,7 +616,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 			   CFG_WINDOW_TYPE, resource_size(pcie->ob_io_res));
 
 	/* memory inbound translation window */
-	program_ib_windows(pcie, WIN_NUM_1, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
+	program_ib_windows(pcie, WIN_NUM_0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
 
 	/* Get the I/O and memory ranges from DT */
 	resource_list_for_each_entry(win, &pcie->resources) {
-- 
2.17.1


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

* [PATCHv3 09/27] PCI: mobiveil: correct inbound/outbound window setup routines
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (7 preceding siblings ...)
  2019-01-29  8:09 ` [PATCHv3 08/27] PCI: mobiveil: use the 1st inbound window for MEM inbound transactions Z.q. Hou
@ 2019-01-29  8:09 ` Z.q. Hou
  2019-02-05  6:10   ` Subrahmanya Lingappa
  2019-01-29  8:09 ` [PATCHv3 10/27] PCI: mobiveil: fix the INTx process error Z.q. Hou
                   ` (19 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:09 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

Outbound window routine:
 - Removed unused var definition and register read operations.
 - Added the upper 32-bit cpu address setup of the window.
 - Instead of blindly write, only change the fields specified.
 - Masked the lower bits of window size in case override the
   control bits.
 - Check if the passing window number is available, instead of
   the total number of the initialized windows.

Inbound window routine:
 - Added parameter 'u64 cpu_addr' to specify the cpu address
   of the window instead of using 'pci_addr'.
 - Changed 'int pci_addr' to 'u64 pci_addr', and added setup
   of the upper 32-bit pci address of the window.
 - Moved the PCIe PIO master enablement to mobiveil_host_init().
 - Instead of blindly write, only change the fields specified.
 - Masked the lower bits of window size in case override the
   control bits.
 - Check if the passing window number is available, instead of
   the total number of the initialized windows.
 - And added the statistic of initialized inbound windows.

Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host
Bridge IP driver")
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 70 +++++++++++++++-----------
 1 file changed, 42 insertions(+), 28 deletions(-)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index e88afc792a5c..4ba458474e42 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -65,9 +65,13 @@
 #define PAB_AXI_AMAP_CTRL(win)		PAB_REG_ADDR(0x0ba0, win)
 #define  WIN_ENABLE_SHIFT		0
 #define  WIN_TYPE_SHIFT			1
+#define  WIN_TYPE_MASK			0x3
+#define  WIN_SIZE_SHIFT			10
+#define  WIN_SIZE_MASK			0x3fffff
 
 #define PAB_EXT_AXI_AMAP_SIZE(win)	PAB_EXT_REG_ADDR(0xbaf0, win)
 
+#define PAB_EXT_AXI_AMAP_AXI_WIN(win)	PAB_EXT_REG_ADDR(0x80a0, win)
 #define PAB_AXI_AMAP_AXI_WIN(win)	PAB_REG_ADDR(0x0ba4, win)
 #define  AXI_WINDOW_ALIGN_MASK		3
 
@@ -82,8 +86,10 @@
 #define PAB_PEX_AMAP_CTRL(win)		PAB_REG_ADDR(0x4ba0, win)
 #define  AMAP_CTRL_EN_SHIFT		0
 #define  AMAP_CTRL_TYPE_SHIFT		1
+#define  AMAP_CTRL_TYPE_MASK		3
 
 #define PAB_EXT_PEX_AMAP_SIZEN(win)	PAB_EXT_REG_ADDR(0xbef0, win)
+#define PAB_EXT_PEX_AMAP_AXI_WIN(win)	PAB_EXT_REG_ADDR(0xb4a0, win)
 #define PAB_PEX_AMAP_AXI_WIN(win)	PAB_REG_ADDR(0x4ba4, win)
 #define PAB_PEX_AMAP_PEX_WIN_L(win)	PAB_REG_ADDR(0x4ba8, win)
 #define PAB_PEX_AMAP_PEX_WIN_H(win)	PAB_REG_ADDR(0x4bac, win)
@@ -455,49 +461,51 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
 }
 
 static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
-			       int pci_addr, u32 type, u64 size)
+			       u64 cpu_addr, u64 pci_addr, u32 type, u64 size)
 {
-	int pio_ctrl_val;
-	int amap_ctrl_dw;
+	u32 value;
 	u64 size64 = ~(size - 1);
 
-	if ((pcie->ib_wins_configured + 1) > pcie->ppio_wins) {
+	if (win_num >= pcie->ppio_wins) {
 		dev_err(&pcie->pdev->dev,
 			"ERROR: max inbound windows reached !\n");
 		return;
 	}
 
-	pio_ctrl_val = csr_readl(pcie, PAB_PEX_PIO_CTRL);
-	pio_ctrl_val |= 1 << PIO_ENABLE_SHIFT;
-	csr_writel(pcie, pio_ctrl_val, PAB_PEX_PIO_CTRL);
-
-	amap_ctrl_dw = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
-	amap_ctrl_dw |= (type << AMAP_CTRL_TYPE_SHIFT) |
-			(1 << AMAP_CTRL_EN_SHIFT) |
-			lower_32_bits(size64);
-	csr_writel(pcie, amap_ctrl_dw, PAB_PEX_AMAP_CTRL(win_num));
+	value = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
+	value &= ~(AMAP_CTRL_TYPE_MASK << AMAP_CTRL_TYPE_SHIFT |
+		 WIN_SIZE_MASK << WIN_SIZE_SHIFT);
+	value |= (type << AMAP_CTRL_TYPE_SHIFT) | (1 << AMAP_CTRL_EN_SHIFT) |
+		 (lower_32_bits(size64) & WIN_SIZE_MASK << WIN_SIZE_SHIFT);
+	csr_writel(pcie, value, PAB_PEX_AMAP_CTRL(win_num));
 
 	csr_writel(pcie, upper_32_bits(size64),
 		   PAB_EXT_PEX_AMAP_SIZEN(win_num));
 
-	csr_writel(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
+	csr_writel(pcie, lower_32_bits(cpu_addr),
+		   PAB_PEX_AMAP_AXI_WIN(win_num));
+	csr_writel(pcie, upper_32_bits(cpu_addr),
+		   PAB_EXT_PEX_AMAP_AXI_WIN(win_num));
+
+	csr_writel(pcie, lower_32_bits(pci_addr),
+		   PAB_PEX_AMAP_PEX_WIN_L(win_num));
+	csr_writel(pcie, upper_32_bits(pci_addr),
+		   PAB_PEX_AMAP_PEX_WIN_H(win_num));
 
-	csr_writel(pcie, pci_addr, PAB_PEX_AMAP_PEX_WIN_L(win_num));
-	csr_writel(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));
+	pcie->ib_wins_configured++;
 }
 
 /*
  * routine to program the outbound windows
  */
 static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
-			       u64 cpu_addr, u64 pci_addr,
-			       u32 config_io_bit, u64 size)
+			       u64 cpu_addr, u64 pci_addr, u32 type, u64 size)
 {
 
-	u32 value, type;
+	u32 value;
 	u64 size64 = ~(size - 1);
 
-	if ((pcie->ob_wins_configured + 1) > pcie->apio_wins) {
+	if (win_num >= pcie->apio_wins) {
 		dev_err(&pcie->pdev->dev,
 			"ERROR: max outbound windows reached !\n");
 		return;
@@ -507,10 +515,12 @@ static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
 	 * program Enable Bit to 1, Type Bit to (00) base 2, AXI Window Size Bit
 	 * to 4 KB in PAB_AXI_AMAP_CTRL register
 	 */
-	type = config_io_bit;
 	value = csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num));
-	csr_writel(pcie, 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
-		   lower_32_bits(size64), PAB_AXI_AMAP_CTRL(win_num));
+	value &= ~(WIN_TYPE_MASK << WIN_TYPE_SHIFT |
+		 WIN_SIZE_MASK << WIN_SIZE_SHIFT);
+	value |= 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
+		 (lower_32_bits(size64) & WIN_SIZE_MASK << WIN_SIZE_SHIFT);
+	csr_writel(pcie, value, PAB_AXI_AMAP_CTRL(win_num));
 
 	csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num));
 
@@ -518,11 +528,10 @@ static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
 	 * program AXI window base with appropriate value in
 	 * PAB_AXI_AMAP_AXI_WIN0 register
 	 */
-	value = csr_readl(pcie, PAB_AXI_AMAP_AXI_WIN(win_num));
-	csr_writel(pcie, cpu_addr & (~AXI_WINDOW_ALIGN_MASK),
+	csr_writel(pcie, lower_32_bits(cpu_addr) & (~AXI_WINDOW_ALIGN_MASK),
 		   PAB_AXI_AMAP_AXI_WIN(win_num));
-
-	value = csr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_H(win_num));
+	csr_writel(pcie, upper_32_bits(cpu_addr),
+		   PAB_EXT_AXI_AMAP_AXI_WIN(win_num));
 
 	csr_writel(pcie, lower_32_bits(pci_addr),
 		   PAB_AXI_AMAP_PEX_WIN_L(win_num));
@@ -604,6 +613,11 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 	value |= APIO_EN_MASK;
 	csr_writel(pcie, value, PAB_AXI_PIO_CTRL);
 
+	/* Enable PCIe PIO master */
+	value = csr_readl(pcie, PAB_PEX_PIO_CTRL);
+	value |= 1 << PIO_ENABLE_SHIFT;
+	csr_writel(pcie, value, PAB_PEX_PIO_CTRL);
+
 	/*
 	 * we'll program one outbound window for config reads and
 	 * another default inbound window for all the upstream traffic
@@ -616,7 +630,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 			   CFG_WINDOW_TYPE, resource_size(pcie->ob_io_res));
 
 	/* memory inbound translation window */
-	program_ib_windows(pcie, WIN_NUM_0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
+	program_ib_windows(pcie, WIN_NUM_0, 0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
 
 	/* Get the I/O and memory ranges from DT */
 	resource_list_for_each_entry(win, &pcie->resources) {
-- 
2.17.1


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

* [PATCHv3 10/27] PCI: mobiveil: fix the INTx process error
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (8 preceding siblings ...)
  2019-01-29  8:09 ` [PATCHv3 09/27] PCI: mobiveil: correct inbound/outbound window setup routines Z.q. Hou
@ 2019-01-29  8:09 ` Z.q. Hou
  2019-02-05  6:11   ` Subrahmanya Lingappa
  2019-01-29  8:09 ` [PATCHv3 11/27] PCI: mobiveil: only fix up the Class Code field Z.q. Hou
                   ` (18 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:09 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

In the loop block, there is not code change the loop key,
this patch updated the loop key by re-read the INTx status
register.

This patch also change to clear the handled INTx status.

Note: Need MV to test this fix.

Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host
Bridge IP driver")
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index 4ba458474e42..78e575e71f4d 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -361,6 +361,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
 	/* Handle INTx */
 	if (intr_status & PAB_INTP_INTX_MASK) {
 		shifted_status = csr_readl(pcie, PAB_INTP_AMBA_MISC_STAT);
+		shifted_status &= PAB_INTP_INTX_MASK;
 		shifted_status >>= PAB_INTX_START;
 		do {
 			for_each_set_bit(bit, &shifted_status, PCI_NUM_INTX) {
@@ -372,12 +373,16 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
 					dev_err_ratelimited(dev, "unexpected IRQ, INT%d\n",
 							    bit);
 
-				/* clear interrupt */
-				csr_writel(pcie,
-					   shifted_status << PAB_INTX_START,
+				/* clear interrupt handled */
+				csr_writel(pcie, 1 << (PAB_INTX_START + bit),
 					   PAB_INTP_AMBA_MISC_STAT);
 			}
-		} while ((shifted_status >> PAB_INTX_START) != 0);
+
+			shifted_status = csr_readl(pcie,
+						   PAB_INTP_AMBA_MISC_STAT);
+			shifted_status &= PAB_INTP_INTX_MASK;
+			shifted_status >>= PAB_INTX_START;
+		} while (shifted_status != 0);
 	}
 
 	/* read extra MSI status register */
-- 
2.17.1


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

* [PATCHv3 11/27] PCI: mobiveil: only fix up the Class Code field
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (9 preceding siblings ...)
  2019-01-29  8:09 ` [PATCHv3 10/27] PCI: mobiveil: fix the INTx process error Z.q. Hou
@ 2019-01-29  8:09 ` Z.q. Hou
  2019-02-05  6:11   ` Subrahmanya Lingappa
  2019-01-29  8:09 ` [PATCHv3 12/27] PCI: mobiveil: move out the link up waiting from mobiveil_host_init Z.q. Hou
                   ` (17 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:09 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

Fix up the Class Code to PCI bridge, do not change the Revision ID.
And move the fixup to mobiveil_host_init function.

Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge
IP driver")
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index 78e575e71f4d..8eee1ab7ee24 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -653,6 +653,12 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 				   type, resource_size(win->res));
 	}
 
+	/* fixup for PCIe class register */
+	value = csr_readl(pcie, PAB_INTP_AXI_PIO_CLASS);
+	value &= 0xff;
+	value |= (PCI_CLASS_BRIDGE_PCI << 16);
+	csr_writel(pcie, value, PAB_INTP_AXI_PIO_CLASS);
+
 	/* setup MSI hardware registers */
 	mobiveil_pcie_enable_msi(pcie);
 
@@ -896,9 +902,6 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
 		goto error;
 	}
 
-	/* fixup for PCIe class register */
-	csr_writel(pcie, 0x060402ab, PAB_INTP_AXI_PIO_CLASS);
-
 	/* initialize the IRQ domains */
 	ret = mobiveil_pcie_init_irq_domain(pcie);
 	if (ret) {
-- 
2.17.1


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

* [PATCHv3 12/27] PCI: mobiveil: move out the link up waiting from mobiveil_host_init
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (10 preceding siblings ...)
  2019-01-29  8:09 ` [PATCHv3 11/27] PCI: mobiveil: only fix up the Class Code field Z.q. Hou
@ 2019-01-29  8:09 ` Z.q. Hou
  2019-02-05  6:12   ` Subrahmanya Lingappa
  2019-01-29  8:09 ` [PATCHv3 13/27] PCI: mobiveil: move irq chained handler setup out of DT parse Z.q. Hou
                   ` (16 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:09 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

Host initial sequence does not depend on PCIe link up, so move it
to the place just before the enumeration.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index 8eee1ab7ee24..c2848c22b466 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -582,15 +582,8 @@ static void mobiveil_pcie_enable_msi(struct mobiveil_pcie *pcie)
 static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 {
 	u32 value, pab_ctrl, type;
-	int err;
 	struct resource_entry *win;
 
-	err = mobiveil_bringup_link(pcie);
-	if (err) {
-		dev_info(&pcie->pdev->dev, "link bring-up failed\n");
-		return err;
-	}
-
 	/*
 	 * program Bus Master Enable Bit in Command Register in PAB Config
 	 * Space
@@ -662,7 +655,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 	/* setup MSI hardware registers */
 	mobiveil_pcie_enable_msi(pcie);
 
-	return err;
+	return 0;
 }
 
 static void mobiveil_mask_intx_irq(struct irq_data *data)
@@ -922,6 +915,12 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
 	bridge->map_irq = of_irq_parse_and_map_pci;
 	bridge->swizzle_irq = pci_common_swizzle;
 
+	ret = mobiveil_bringup_link(pcie);
+	if (ret) {
+		dev_info(dev, "link bring-up failed\n");
+		goto error;
+	}
+
 	/* setup the kernel resources for the newly added PCIe root bus */
 	ret = pci_scan_root_bus_bridge(bridge);
 	if (ret)
-- 
2.17.1


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

* [PATCHv3 13/27] PCI: mobiveil: move irq chained handler setup out of DT parse
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (11 preceding siblings ...)
  2019-01-29  8:09 ` [PATCHv3 12/27] PCI: mobiveil: move out the link up waiting from mobiveil_host_init Z.q. Hou
@ 2019-01-29  8:09 ` Z.q. Hou
  2019-02-08 12:30   ` Subrahmanya Lingappa
  2019-01-29  8:09 ` [PATCHv3 14/27] PCI: mobiveil: initialize Primary/Secondary/Subordinate bus number Z.q. Hou
                   ` (15 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:09 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

Move irq_set_chained_handler_and_data() out of DT parse function.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index c2848c22b466..db7ecb021c63 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -460,8 +460,6 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
 		return -ENODEV;
 	}
 
-	irq_set_chained_handler_and_data(pcie->irq, mobiveil_pcie_isr, pcie);
-
 	return 0;
 }
 
@@ -902,6 +900,8 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
 		goto error;
 	}
 
+	irq_set_chained_handler_and_data(pcie->irq, mobiveil_pcie_isr, pcie);
+
 	ret = devm_request_pci_bus_resources(dev, &pcie->resources);
 	if (ret)
 		goto error;
-- 
2.17.1


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

* [PATCHv3 14/27] PCI: mobiveil: initialize Primary/Secondary/Subordinate bus number
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (12 preceding siblings ...)
  2019-01-29  8:09 ` [PATCHv3 13/27] PCI: mobiveil: move irq chained handler setup out of DT parse Z.q. Hou
@ 2019-01-29  8:09 ` Z.q. Hou
  2019-02-08 12:31   ` Subrahmanya Lingappa
  2019-01-29  8:10 ` [PATCHv3 15/27] dt-bindings: pci: mobiveil: change gpio_slave and apb_csr to optional Z.q. Hou
                   ` (14 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:09 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

The reset value is all zero, so set a workable value for Primary,
Secondary and Subordinate bus numbers.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/pcie-mobiveil.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
index db7ecb021c63..9210165fe8c0 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/pcie-mobiveil.c
@@ -582,6 +582,12 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 	u32 value, pab_ctrl, type;
 	struct resource_entry *win;
 
+	/* setup bus numbers */
+	value = csr_readl(pcie, PCI_PRIMARY_BUS);
+	value &= 0xff000000;
+	value |= 0x00ff0100;
+	csr_writel(pcie, value, PCI_PRIMARY_BUS);
+
 	/*
 	 * program Bus Master Enable Bit in Command Register in PAB Config
 	 * Space
-- 
2.17.1


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

* [PATCHv3 15/27] dt-bindings: pci: mobiveil: change gpio_slave and apb_csr to optional
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (13 preceding siblings ...)
  2019-01-29  8:09 ` [PATCHv3 14/27] PCI: mobiveil: initialize Primary/Secondary/Subordinate bus number Z.q. Hou
@ 2019-01-29  8:10 ` Z.q. Hou
  2019-02-08 12:32   ` Subrahmanya Lingappa
  2019-01-29  8:10 ` [PATCHv3 16/27] PCI: mobiveil: refactor Mobiveil PCIe Host Bridge IP driver Z.q. Hou
                   ` (13 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:10 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

Change the "gpio_slave" and "apb_csr" to optional, the "gpio_slave"
is not used in current code, and "apb_csr" is not used by some
platforms.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Acked-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 Documentation/devicetree/bindings/pci/mobiveil-pcie.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/mobiveil-pcie.txt b/Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
index a618d4787dd7..64156993e052 100644
--- a/Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
@@ -10,8 +10,10 @@ Required properties:
 	interrupt source. The value must be 1.
 - compatible: Should contain "mbvl,gpex40-pcie"
 - reg: Should contain PCIe registers location and length
+	Mandatory:
 	"config_axi_slave": PCIe controller registers
 	"csr_axi_slave"	  : Bridge config registers
+	Optional:
 	"gpio_slave"	  : GPIO registers to control slot power
 	"apb_csr"	  : MSI registers
 
-- 
2.17.1


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

* [PATCHv3 16/27] PCI: mobiveil: refactor Mobiveil PCIe Host Bridge IP driver
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (14 preceding siblings ...)
  2019-01-29  8:10 ` [PATCHv3 15/27] dt-bindings: pci: mobiveil: change gpio_slave and apb_csr to optional Z.q. Hou
@ 2019-01-29  8:10 ` Z.q. Hou
  2019-02-08 12:37   ` Subrahmanya Lingappa
  2019-01-29  8:10 ` [PATCHv3 17/27] PCI: mobiveil: fix the checking of valid device Z.q. Hou
                   ` (12 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:10 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

As the Mobiveil PCIe controller support RC&EP DAUL mode, and to
make platforms which integrated the Mobiveil PCIe IP more easy
to add their drivers, this patch moved the Mobiveil driver to
a new directory 'drivers/pci/controller/mobiveil' and refactored
it according to the abstraction of RC&EP (EP driver will be added
later).

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 MAINTAINERS                                   |   2 +-
 drivers/pci/controller/Kconfig                |  11 +-
 drivers/pci/controller/Makefile               |   2 +-
 drivers/pci/controller/mobiveil/Kconfig       |  24 +
 drivers/pci/controller/mobiveil/Makefile      |   4 +
 .../pcie-mobiveil-host.c}                     | 528 +++---------------
 .../controller/mobiveil/pcie-mobiveil-plat.c  |  54 ++
 .../pci/controller/mobiveil/pcie-mobiveil.c   | 228 ++++++++
 .../pci/controller/mobiveil/pcie-mobiveil.h   | 187 +++++++
 9 files changed, 587 insertions(+), 453 deletions(-)
 create mode 100644 drivers/pci/controller/mobiveil/Kconfig
 create mode 100644 drivers/pci/controller/mobiveil/Makefile
 rename drivers/pci/controller/{pcie-mobiveil.c => mobiveil/pcie-mobiveil-host.c} (55%)
 create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
 create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.c
 create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.h

diff --git a/MAINTAINERS b/MAINTAINERS
index ddcdc29dfe1f..3bca9642b08b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11709,7 +11709,7 @@ M:	Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
 L:	linux-pci@vger.kernel.org
 S:	Supported
 F:	Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
-F:	drivers/pci/controller/pcie-mobiveil.c
+F:	drivers/pci/controller/mobiveil/pcie-mobiveil*
 
 PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
 M:	Thomas Petazzoni <thomas.petazzoni@bootlin.com>
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 6671946dbf66..0e981ed00a75 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -241,16 +241,6 @@ config PCIE_MEDIATEK
 	  Say Y here if you want to enable PCIe controller support on
 	  MediaTek SoCs.
 
-config PCIE_MOBIVEIL
-	bool "Mobiveil AXI PCIe controller"
-	depends on ARCH_ZYNQMP || COMPILE_TEST
-	depends on OF
-	depends on PCI_MSI_IRQ_DOMAIN
-	help
-	  Say Y here if you want to enable support for the Mobiveil AXI PCIe
-	  Soft IP. It has up to 8 outbound and inbound windows
-	  for address translation and it is a PCIe Gen4 IP.
-
 config PCIE_TANGO_SMP8759
 	bool "Tango SMP8759 PCIe controller (DANGEROUS)"
 	depends on ARCH_TANGO && PCI_MSI && OF
@@ -281,4 +271,5 @@ config VMD
 	  module will be called vmd.
 
 source "drivers/pci/controller/dwc/Kconfig"
+source "drivers/pci/controller/mobiveil/Kconfig"
 endmenu
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index d56a507495c5..b79a615041a0 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -26,11 +26,11 @@ obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
 obj-$(CONFIG_PCIE_ROCKCHIP_EP) += pcie-rockchip-ep.o
 obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie-rockchip-host.o
 obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
-obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o
 obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
 obj-$(CONFIG_VMD) += vmd.o
 # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
 obj-y				+= dwc/
+obj-y				+= mobiveil/
 
 
 # The following drivers are for devices that use the generic ACPI
diff --git a/drivers/pci/controller/mobiveil/Kconfig b/drivers/pci/controller/mobiveil/Kconfig
new file mode 100644
index 000000000000..64343c07bfed
--- /dev/null
+++ b/drivers/pci/controller/mobiveil/Kconfig
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: GPL-2.0
+
+menu "Mobiveil PCIe Core Support"
+	depends on PCI
+
+config PCIE_MOBIVEIL
+	bool
+
+config PCIE_MOBIVEIL_HOST
+        bool
+	depends on PCI_MSI_IRQ_DOMAIN
+        select PCIE_MOBIVEIL
+
+config PCIE_MOBIVEIL_PLAT
+	bool "Mobiveil AXI PCIe controller"
+	depends on ARCH_ZYNQMP || COMPILE_TEST
+	depends on OF
+	select PCIE_MOBIVEIL_HOST
+	help
+	  Say Y here if you want to enable support for the Mobiveil AXI PCIe
+	  Soft IP. It has up to 8 outbound and inbound windows
+	  for address translation and it is a PCIe Gen4 IP.
+
+endmenu
diff --git a/drivers/pci/controller/mobiveil/Makefile b/drivers/pci/controller/mobiveil/Makefile
new file mode 100644
index 000000000000..9fb6d1c6504d
--- /dev/null
+++ b/drivers/pci/controller/mobiveil/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o
+obj-$(CONFIG_PCIE_MOBIVEIL_HOST) += pcie-mobiveil-host.o
+obj-$(CONFIG_PCIE_MOBIVEIL_PLAT) += pcie-mobiveil-plat.o
diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
similarity index 55%
rename from drivers/pci/controller/pcie-mobiveil.c
rename to drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
index 9210165fe8c0..dc5324d94466 100644
--- a/drivers/pci/controller/pcie-mobiveil.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
@@ -4,9 +4,9 @@
  *
  * Copyright (c) 2018 Mobiveil Inc.
  * Author: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
+ * Refactor: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
  */
 
-#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -23,275 +23,21 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
-#include "../pci.h"
-
-/* register offsets and bit positions */
-
-/*
- * translation tables are grouped into windows, each window registers are
- * grouped into blocks of 4 or 16 registers each
- */
-#define PAB_REG_BLOCK_SIZE		16
-#define PAB_EXT_REG_BLOCK_SIZE		4
-
-#define PAB_REG_ADDR(offset, win)	\
-	(offset + (win * PAB_REG_BLOCK_SIZE))
-#define PAB_EXT_REG_ADDR(offset, win)	\
-	(offset + (win * PAB_EXT_REG_BLOCK_SIZE))
-
-#define LTSSM_STATUS			0x0404
-#define  LTSSM_STATUS_L0_MASK		0x3f
-#define  LTSSM_STATUS_L0		0x2d
-
-#define PAB_CTRL			0x0808
-#define  AMBA_PIO_ENABLE_SHIFT		0
-#define  PEX_PIO_ENABLE_SHIFT		1
-#define  PAGE_SEL_SHIFT			13
-#define  PAGE_SEL_MASK			0x3f
-#define  PAGE_LO_MASK			0x3ff
-#define  PAGE_SEL_OFFSET_SHIFT		10
-
-#define PAB_AXI_PIO_CTRL		0x0840
-#define  APIO_EN_MASK			0xf
-
-#define PAB_PEX_PIO_CTRL		0x08c0
-#define  PIO_ENABLE_SHIFT		0
-
-#define PAB_INTP_AMBA_MISC_ENB		0x0b0c
-#define PAB_INTP_AMBA_MISC_STAT		0x0b1c
-#define  PAB_INTP_INTX_MASK		0x01e0
-#define  PAB_INTP_MSI_MASK		0x8
-
-#define PAB_AXI_AMAP_CTRL(win)		PAB_REG_ADDR(0x0ba0, win)
-#define  WIN_ENABLE_SHIFT		0
-#define  WIN_TYPE_SHIFT			1
-#define  WIN_TYPE_MASK			0x3
-#define  WIN_SIZE_SHIFT			10
-#define  WIN_SIZE_MASK			0x3fffff
-
-#define PAB_EXT_AXI_AMAP_SIZE(win)	PAB_EXT_REG_ADDR(0xbaf0, win)
-
-#define PAB_EXT_AXI_AMAP_AXI_WIN(win)	PAB_EXT_REG_ADDR(0x80a0, win)
-#define PAB_AXI_AMAP_AXI_WIN(win)	PAB_REG_ADDR(0x0ba4, win)
-#define  AXI_WINDOW_ALIGN_MASK		3
-
-#define PAB_AXI_AMAP_PEX_WIN_L(win)	PAB_REG_ADDR(0x0ba8, win)
-#define  PAB_BUS_SHIFT			24
-#define  PAB_DEVICE_SHIFT		19
-#define  PAB_FUNCTION_SHIFT		16
-
-#define PAB_AXI_AMAP_PEX_WIN_H(win)	PAB_REG_ADDR(0x0bac, win)
-#define PAB_INTP_AXI_PIO_CLASS		0x474
-
-#define PAB_PEX_AMAP_CTRL(win)		PAB_REG_ADDR(0x4ba0, win)
-#define  AMAP_CTRL_EN_SHIFT		0
-#define  AMAP_CTRL_TYPE_SHIFT		1
-#define  AMAP_CTRL_TYPE_MASK		3
-
-#define PAB_EXT_PEX_AMAP_SIZEN(win)	PAB_EXT_REG_ADDR(0xbef0, win)
-#define PAB_EXT_PEX_AMAP_AXI_WIN(win)	PAB_EXT_REG_ADDR(0xb4a0, win)
-#define PAB_PEX_AMAP_AXI_WIN(win)	PAB_REG_ADDR(0x4ba4, win)
-#define PAB_PEX_AMAP_PEX_WIN_L(win)	PAB_REG_ADDR(0x4ba8, win)
-#define PAB_PEX_AMAP_PEX_WIN_H(win)	PAB_REG_ADDR(0x4bac, win)
-
-/* starting offset of INTX bits in status register */
-#define PAB_INTX_START			5
-
-/* supported number of MSI interrupts */
-#define PCI_NUM_MSI			16
-
-/* MSI registers */
-#define MSI_BASE_LO_OFFSET		0x04
-#define MSI_BASE_HI_OFFSET		0x08
-#define MSI_SIZE_OFFSET			0x0c
-#define MSI_ENABLE_OFFSET		0x14
-#define MSI_STATUS_OFFSET		0x18
-#define MSI_DATA_OFFSET			0x20
-#define MSI_ADDR_L_OFFSET		0x24
-#define MSI_ADDR_H_OFFSET		0x28
-
-/* outbound and inbound window definitions */
-#define WIN_NUM_0			0
-#define WIN_NUM_1			1
-#define CFG_WINDOW_TYPE			0
-#define IO_WINDOW_TYPE			1
-#define MEM_WINDOW_TYPE			2
-#define IB_WIN_SIZE			((u64)256 * 1024 * 1024 * 1024)
-#define MAX_PIO_WINDOWS			8
-
-/* Parameters for the waiting for link up routine */
-#define LINK_WAIT_MAX_RETRIES		10
-#define LINK_WAIT_MIN			90000
-#define LINK_WAIT_MAX			100000
-
-#define PAGED_ADDR_BNDRY		0xc00
-#define OFFSET_TO_PAGE_ADDR(off)	\
-	((off & PAGE_LO_MASK) | PAGED_ADDR_BNDRY)
-#define OFFSET_TO_PAGE_IDX(off)		\
-	((off >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK)
-
-struct mobiveil_msi {			/* MSI information */
-	struct mutex lock;		/* protect bitmap variable */
-	struct irq_domain *msi_domain;
-	struct irq_domain *dev_domain;
-	phys_addr_t msi_pages_phys;
-	int num_of_vectors;
-	DECLARE_BITMAP(msi_irq_in_use, PCI_NUM_MSI);
-};
-
-struct mobiveil_pcie {
-	struct platform_device *pdev;
-	struct list_head resources;
-	void __iomem *config_axi_slave_base;	/* endpoint config base */
-	void __iomem *csr_axi_slave_base;	/* root port config base */
-	void __iomem *apb_csr_base;	/* MSI register base */
-	phys_addr_t pcie_reg_base;	/* Physical PCIe Controller Base */
-	struct irq_domain *intx_domain;
-	raw_spinlock_t intx_mask_lock;
-	int irq;
-	int apio_wins;
-	int ppio_wins;
-	int ob_wins_configured;		/* configured outbound windows */
-	int ib_wins_configured;		/* configured inbound windows */
-	struct resource *ob_io_res;
-	char root_bus_nr;
-	struct mobiveil_msi msi;
-};
-
-/*
- * mobiveil_pcie_sel_page - routine to access paged register
- *
- * Registers whose address greater than PAGED_ADDR_BNDRY (0xc00) are paged,
- * for this scheme to work extracted higher 6 bits of the offset will be
- * written to pg_sel field of PAB_CTRL register and rest of the lower 10
- * bits enabled with PAGED_ADDR_BNDRY are used as offset of the register.
- */
-static void mobiveil_pcie_sel_page(struct mobiveil_pcie *pcie, u8 pg_idx)
-{
-	u32 val;
-
-	val = readl(pcie->csr_axi_slave_base + PAB_CTRL);
-	val &= ~(PAGE_SEL_MASK << PAGE_SEL_SHIFT);
-	val |= (pg_idx & PAGE_SEL_MASK) << PAGE_SEL_SHIFT;
-
-	writel(val, pcie->csr_axi_slave_base + PAB_CTRL);
-}
-
-static void *mobiveil_pcie_comp_addr(struct mobiveil_pcie *pcie, u32 off)
-{
-	if (off < PAGED_ADDR_BNDRY) {
-		/* For directly accessed registers, clear the pg_sel field */
-		mobiveil_pcie_sel_page(pcie, 0);
-		return pcie->csr_axi_slave_base + off;
-	}
-
-	mobiveil_pcie_sel_page(pcie, OFFSET_TO_PAGE_IDX(off));
-	return pcie->csr_axi_slave_base + OFFSET_TO_PAGE_ADDR(off);
-}
-
-static int mobiveil_pcie_read(void __iomem *addr, int size, u32 *val)
-{
-	if ((uintptr_t)addr & (size - 1)) {
-		*val = 0;
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-
-	switch (size) {
-	case 4:
-		*val = readl(addr);
-		break;
-	case 2:
-		*val = readw(addr);
-		break;
-	case 1:
-		*val = readb(addr);
-		break;
-	default:
-		*val = 0;
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int mobiveil_pcie_write(void __iomem *addr, int size, u32 val)
-{
-	if ((uintptr_t)addr & (size - 1))
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	switch (size) {
-	case 4:
-		writel(val, addr);
-		break;
-	case 2:
-		writew(val, addr);
-		break;
-	case 1:
-		writeb(val, addr);
-		break;
-	default:
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static u32 csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size)
-{
-	void *addr;
-	u32 val;
-	int ret;
-
-	addr = mobiveil_pcie_comp_addr(pcie, off);
-
-	ret = mobiveil_pcie_read(addr, size, &val);
-	if (ret)
-		dev_err(&pcie->pdev->dev, "read CSR address failed\n");
-
-	return val;
-}
-
-static void csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, size_t size)
-{
-	void *addr;
-	int ret;
-
-	addr = mobiveil_pcie_comp_addr(pcie, off);
-
-	ret = mobiveil_pcie_write(addr, size, val);
-	if (ret)
-		dev_err(&pcie->pdev->dev, "write CSR address failed\n");
-}
-
-static u32 csr_readl(struct mobiveil_pcie *pcie, u32 off)
-{
-	return csr_read(pcie, off, 0x4);
-}
-
-static void csr_writel(struct mobiveil_pcie *pcie, u32 val, u32 off)
-{
-	csr_write(pcie, val, off, 0x4);
-}
-
-static bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie)
-{
-	return (csr_readl(pcie, LTSSM_STATUS) &
-		LTSSM_STATUS_L0_MASK) == LTSSM_STATUS_L0;
-}
+#include "pcie-mobiveil.h"
 
 static bool mobiveil_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
 {
 	struct mobiveil_pcie *pcie = bus->sysdata;
 
 	/* Only one device down on each root port */
-	if ((bus->number == pcie->root_bus_nr) && (devfn > 0))
+	if ((bus->number == pcie->rp.root_bus_nr) && (devfn > 0))
 		return false;
 
 	/*
 	 * Do not read more than one device on the bus directly
 	 * attached to RC
 	 */
-	if ((bus->primary == pcie->root_bus_nr) && (devfn > 0))
+	if ((bus->primary == pcie->rp.root_bus_nr) && (devfn > 0))
 		return false;
 
 	return true;
@@ -311,7 +57,7 @@ static void __iomem *mobiveil_pcie_map_bus(struct pci_bus *bus,
 		return NULL;
 
 	/* RC config access */
-	if (bus->number == pcie->root_bus_nr)
+	if (bus->number == pcie->rp.root_bus_nr)
 		return pcie->csr_axi_slave_base + where;
 
 	/*
@@ -326,7 +72,7 @@ static void __iomem *mobiveil_pcie_map_bus(struct pci_bus *bus,
 
 	csr_writel(pcie, value, PAB_AXI_AMAP_PEX_WIN_L(WIN_NUM_0));
 
-	return pcie->config_axi_slave_base + where;
+	return pcie->rp.config_axi_slave_base + where;
 }
 
 static struct pci_ops mobiveil_pcie_ops = {
@@ -340,7 +86,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	struct mobiveil_pcie *pcie = irq_desc_get_handler_data(desc);
 	struct device *dev = &pcie->pdev->dev;
-	struct mobiveil_msi *msi = &pcie->msi;
+	struct mobiveil_msi *msi = &pcie->rp.msi;
 	u32 msi_data, msi_addr_lo, msi_addr_hi;
 	u32 intr_status, msi_status;
 	unsigned long shifted_status;
@@ -365,7 +111,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
 		shifted_status >>= PAB_INTX_START;
 		do {
 			for_each_set_bit(bit, &shifted_status, PCI_NUM_INTX) {
-				virq = irq_find_mapping(pcie->intx_domain,
+				virq = irq_find_mapping(pcie->rp.intx_domain,
 							bit + 1);
 				if (virq)
 					generic_handle_irq(virq);
@@ -428,10 +174,10 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
 	/* map config resource */
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 					   "config_axi_slave");
-	pcie->config_axi_slave_base = devm_pci_remap_cfg_resource(dev, res);
-	if (IS_ERR(pcie->config_axi_slave_base))
-		return PTR_ERR(pcie->config_axi_slave_base);
-	pcie->ob_io_res = res;
+	pcie->rp.config_axi_slave_base = devm_pci_remap_cfg_resource(dev, res);
+	if (IS_ERR(pcie->rp.config_axi_slave_base))
+		return PTR_ERR(pcie->rp.config_axi_slave_base);
+	pcie->rp.ob_io_res = res;
 
 	/* map csr resource */
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
@@ -441,12 +187,6 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
 		return PTR_ERR(pcie->csr_axi_slave_base);
 	pcie->pcie_reg_base = res->start;
 
-	/* map MSI config resource */
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apb_csr");
-	pcie->apb_csr_base = devm_pci_remap_cfg_resource(dev, res);
-	if (IS_ERR(pcie->apb_csr_base))
-		return PTR_ERR(pcie->apb_csr_base);
-
 	/* read the number of windows requested */
 	if (of_property_read_u32(node, "apio-wins", &pcie->apio_wins))
 		pcie->apio_wins = MAX_PIO_WINDOWS;
@@ -454,119 +194,15 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
 	if (of_property_read_u32(node, "ppio-wins", &pcie->ppio_wins))
 		pcie->ppio_wins = MAX_PIO_WINDOWS;
 
-	pcie->irq = platform_get_irq(pdev, 0);
-	if (pcie->irq <= 0) {
-		dev_err(dev, "failed to map IRQ: %d\n", pcie->irq);
-		return -ENODEV;
-	}
-
 	return 0;
 }
 
-static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
-			       u64 cpu_addr, u64 pci_addr, u32 type, u64 size)
-{
-	u32 value;
-	u64 size64 = ~(size - 1);
-
-	if (win_num >= pcie->ppio_wins) {
-		dev_err(&pcie->pdev->dev,
-			"ERROR: max inbound windows reached !\n");
-		return;
-	}
-
-	value = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
-	value &= ~(AMAP_CTRL_TYPE_MASK << AMAP_CTRL_TYPE_SHIFT |
-		 WIN_SIZE_MASK << WIN_SIZE_SHIFT);
-	value |= (type << AMAP_CTRL_TYPE_SHIFT) | (1 << AMAP_CTRL_EN_SHIFT) |
-		 (lower_32_bits(size64) & WIN_SIZE_MASK << WIN_SIZE_SHIFT);
-	csr_writel(pcie, value, PAB_PEX_AMAP_CTRL(win_num));
-
-	csr_writel(pcie, upper_32_bits(size64),
-		   PAB_EXT_PEX_AMAP_SIZEN(win_num));
-
-	csr_writel(pcie, lower_32_bits(cpu_addr),
-		   PAB_PEX_AMAP_AXI_WIN(win_num));
-	csr_writel(pcie, upper_32_bits(cpu_addr),
-		   PAB_EXT_PEX_AMAP_AXI_WIN(win_num));
-
-	csr_writel(pcie, lower_32_bits(pci_addr),
-		   PAB_PEX_AMAP_PEX_WIN_L(win_num));
-	csr_writel(pcie, upper_32_bits(pci_addr),
-		   PAB_PEX_AMAP_PEX_WIN_H(win_num));
-
-	pcie->ib_wins_configured++;
-}
-
-/*
- * routine to program the outbound windows
- */
-static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
-			       u64 cpu_addr, u64 pci_addr, u32 type, u64 size)
-{
-
-	u32 value;
-	u64 size64 = ~(size - 1);
-
-	if (win_num >= pcie->apio_wins) {
-		dev_err(&pcie->pdev->dev,
-			"ERROR: max outbound windows reached !\n");
-		return;
-	}
-
-	/*
-	 * program Enable Bit to 1, Type Bit to (00) base 2, AXI Window Size Bit
-	 * to 4 KB in PAB_AXI_AMAP_CTRL register
-	 */
-	value = csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num));
-	value &= ~(WIN_TYPE_MASK << WIN_TYPE_SHIFT |
-		 WIN_SIZE_MASK << WIN_SIZE_SHIFT);
-	value |= 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
-		 (lower_32_bits(size64) & WIN_SIZE_MASK << WIN_SIZE_SHIFT);
-	csr_writel(pcie, value, PAB_AXI_AMAP_CTRL(win_num));
-
-	csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num));
-
-	/*
-	 * program AXI window base with appropriate value in
-	 * PAB_AXI_AMAP_AXI_WIN0 register
-	 */
-	csr_writel(pcie, lower_32_bits(cpu_addr) & (~AXI_WINDOW_ALIGN_MASK),
-		   PAB_AXI_AMAP_AXI_WIN(win_num));
-	csr_writel(pcie, upper_32_bits(cpu_addr),
-		   PAB_EXT_AXI_AMAP_AXI_WIN(win_num));
-
-	csr_writel(pcie, lower_32_bits(pci_addr),
-		   PAB_AXI_AMAP_PEX_WIN_L(win_num));
-	csr_writel(pcie, upper_32_bits(pci_addr),
-		   PAB_AXI_AMAP_PEX_WIN_H(win_num));
-
-	pcie->ob_wins_configured++;
-}
-
-static int mobiveil_bringup_link(struct mobiveil_pcie *pcie)
-{
-	int retries;
-
-	/* check if the link is up or not */
-	for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
-		if (mobiveil_pcie_link_up(pcie))
-			return 0;
-
-		usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
-	}
-
-	dev_err(&pcie->pdev->dev, "link never came up\n");
-
-	return -ETIMEDOUT;
-}
-
 static void mobiveil_pcie_enable_msi(struct mobiveil_pcie *pcie)
 {
 	phys_addr_t msg_addr = pcie->pcie_reg_base;
-	struct mobiveil_msi *msi = &pcie->msi;
+	struct mobiveil_msi *msi = &pcie->rp.msi;
 
-	pcie->msi.num_of_vectors = PCI_NUM_MSI;
+	msi->num_of_vectors = PCI_NUM_MSI;
 	msi->msi_pages_phys = (phys_addr_t)msg_addr;
 
 	writel_relaxed(lower_32_bits(msg_addr),
@@ -604,9 +240,6 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 	pab_ctrl |= (1 << AMBA_PIO_ENABLE_SHIFT) | (1 << PEX_PIO_ENABLE_SHIFT);
 	csr_writel(pcie, pab_ctrl, PAB_CTRL);
 
-	csr_writel(pcie, (PAB_INTP_INTX_MASK | PAB_INTP_MSI_MASK),
-		   PAB_INTP_AMBA_MISC_ENB);
-
 	/*
 	 * program PIO Enable Bit to 1 and Config Window Enable Bit to 1 in
 	 * PAB_AXI_PIO_CTRL Register
@@ -628,20 +261,24 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 	 */
 
 	/* config outbound translation window */
-	program_ob_windows(pcie, WIN_NUM_0, pcie->ob_io_res->start, 0,
-			   CFG_WINDOW_TYPE, resource_size(pcie->ob_io_res));
+	program_ob_windows(pcie, WIN_NUM_0, pcie->rp.ob_io_res->start, 0,
+			   CFG_WINDOW_TYPE, resource_size(pcie->rp.ob_io_res));
 
 	/* memory inbound translation window */
 	program_ib_windows(pcie, WIN_NUM_0, 0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
 
 	/* Get the I/O and memory ranges from DT */
 	resource_list_for_each_entry(win, &pcie->resources) {
-		if (resource_type(win->res) == IORESOURCE_MEM)
+		if (resource_type(win->res) == IORESOURCE_MEM) {
 			type = MEM_WINDOW_TYPE;
-		else if (resource_type(win->res) == IORESOURCE_IO)
+		} else if (resource_type(win->res) == IORESOURCE_IO) {
 			type = IO_WINDOW_TYPE;
-		else
+		} else if (resource_type(win->res) == IORESOURCE_BUS) {
+			pcie->rp.root_bus_nr = win->res->start;
+			continue;
+		} else {
 			continue;
+		}
 
 		/* configure outbound translation window */
 		program_ob_windows(pcie, pcie->ob_wins_configured,
@@ -656,9 +293,6 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 	value |= (PCI_CLASS_BRIDGE_PCI << 16);
 	csr_writel(pcie, value, PAB_INTP_AXI_PIO_CLASS);
 
-	/* setup MSI hardware registers */
-	mobiveil_pcie_enable_msi(pcie);
-
 	return 0;
 }
 
@@ -671,11 +305,11 @@ static void mobiveil_mask_intx_irq(struct irq_data *data)
 
 	pcie = irq_desc_get_chip_data(desc);
 	mask = 1 << ((data->hwirq + PAB_INTX_START) - 1);
-	raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags);
+	raw_spin_lock_irqsave(&pcie->rp.intx_mask_lock, flags);
 	shifted_val = csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB);
 	shifted_val &= ~mask;
 	csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB);
-	raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags);
+	raw_spin_unlock_irqrestore(&pcie->rp.intx_mask_lock, flags);
 }
 
 static void mobiveil_unmask_intx_irq(struct irq_data *data)
@@ -687,11 +321,11 @@ static void mobiveil_unmask_intx_irq(struct irq_data *data)
 
 	pcie = irq_desc_get_chip_data(desc);
 	mask = 1 << ((data->hwirq + PAB_INTX_START) - 1);
-	raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags);
+	raw_spin_lock_irqsave(&pcie->rp.intx_mask_lock, flags);
 	shifted_val = csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB);
 	shifted_val |= mask;
 	csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB);
-	raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags);
+	raw_spin_unlock_irqrestore(&pcie->rp.intx_mask_lock, flags);
 }
 
 static struct irq_chip intx_irq_chip = {
@@ -759,7 +393,7 @@ static int mobiveil_irq_msi_domain_alloc(struct irq_domain *domain,
 					 unsigned int nr_irqs, void *args)
 {
 	struct mobiveil_pcie *pcie = domain->host_data;
-	struct mobiveil_msi *msi = &pcie->msi;
+	struct mobiveil_msi *msi = &pcie->rp.msi;
 	unsigned long bit;
 
 	WARN_ON(nr_irqs != 1);
@@ -786,7 +420,7 @@ static void mobiveil_irq_msi_domain_free(struct irq_domain *domain,
 {
 	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
 	struct mobiveil_pcie *pcie = irq_data_get_irq_chip_data(d);
-	struct mobiveil_msi *msi = &pcie->msi;
+	struct mobiveil_msi *msi = &pcie->rp.msi;
 
 	mutex_lock(&msi->lock);
 
@@ -807,9 +441,9 @@ static int mobiveil_allocate_msi_domains(struct mobiveil_pcie *pcie)
 {
 	struct device *dev = &pcie->pdev->dev;
 	struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
-	struct mobiveil_msi *msi = &pcie->msi;
+	struct mobiveil_msi *msi = &pcie->rp.msi;
 
-	mutex_init(&pcie->msi.lock);
+	mutex_init(&msi->lock);
 	msi->dev_domain = irq_domain_add_linear(NULL, msi->num_of_vectors,
 						&msi_domain_ops, pcie);
 	if (!msi->dev_domain) {
@@ -836,15 +470,15 @@ static int mobiveil_pcie_init_irq_domain(struct mobiveil_pcie *pcie)
 	int ret;
 
 	/* setup INTx */
-	pcie->intx_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
-						  &intx_domain_ops, pcie);
+	pcie->rp.intx_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
+						     &intx_domain_ops, pcie);
 
-	if (!pcie->intx_domain) {
+	if (!pcie->rp.intx_domain) {
 		dev_err(dev, "Failed to get a INTx IRQ domain\n");
 		return -ENOMEM;
 	}
 
-	raw_spin_lock_init(&pcie->intx_mask_lock);
+	raw_spin_lock_init(&pcie->rp.intx_mask_lock);
 
 	/* setup MSI */
 	ret = mobiveil_allocate_msi_domains(pcie);
@@ -854,24 +488,58 @@ static int mobiveil_pcie_init_irq_domain(struct mobiveil_pcie *pcie)
 	return 0;
 }
 
-static int mobiveil_pcie_probe(struct platform_device *pdev)
+static int mobiveil_pcie_interrupt_init(struct mobiveil_pcie *pcie)
+{
+	struct device *dev = &pcie->pdev->dev;
+	struct resource *res;
+	int ret;
+
+	if (pcie->rp.ops->interrupt_init)
+		return pcie->rp.ops->interrupt_init(pcie);
+
+	/* map MSI config resource */
+	res = platform_get_resource_byname(pcie->pdev, IORESOURCE_MEM,
+					   "apb_csr");
+	pcie->apb_csr_base = devm_pci_remap_cfg_resource(dev, res);
+	if (IS_ERR(pcie->apb_csr_base))
+		return PTR_ERR(pcie->apb_csr_base);
+
+	/* setup MSI hardware registers */
+	mobiveil_pcie_enable_msi(pcie);
+
+	pcie->rp.irq = platform_get_irq(pcie->pdev, 0);
+	if (pcie->rp.irq <= 0) {
+		dev_err(dev, "failed to map IRQ: %d\n", pcie->rp.irq);
+		return -ENODEV;
+	}
+
+	/* initialize the IRQ domains */
+	ret = mobiveil_pcie_init_irq_domain(pcie);
+	if (ret) {
+		dev_err(dev, "Failed creating IRQ Domain\n");
+		return ret;
+	}
+
+	irq_set_chained_handler_and_data(pcie->rp.irq,
+					 mobiveil_pcie_isr, pcie);
+
+	/* Enable interrupts */
+	csr_writel(pcie, (PAB_INTP_INTX_MASK | PAB_INTP_MSI_MASK),
+		   PAB_INTP_AMBA_MISC_ENB);
+
+	return 0;
+}
+
+int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
 {
-	struct mobiveil_pcie *pcie;
 	struct pci_bus *bus;
 	struct pci_bus *child;
 	struct pci_host_bridge *bridge;
-	struct device *dev = &pdev->dev;
+	struct device *dev = &pcie->pdev->dev;
 	resource_size_t iobase;
 	int ret;
 
-	/* allocate the PCIe port */
-	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
-	if (!bridge)
-		return -ENOMEM;
-
-	pcie = pci_host_bridge_priv(bridge);
-
-	pcie->pdev = pdev;
+	INIT_LIST_HEAD(&pcie->resources);
 
 	ret = mobiveil_pcie_parse_dt(pcie);
 	if (ret) {
@@ -879,7 +547,10 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	INIT_LIST_HEAD(&pcie->resources);
+	/* allocate the PCIe port */
+	bridge = devm_pci_alloc_host_bridge(dev, 0);
+	if (!bridge)
+		return -ENOMEM;
 
 	/* parse the host bridge base addresses from the device tree file */
 	ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
@@ -899,15 +570,12 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
 		goto error;
 	}
 
-	/* initialize the IRQ domains */
-	ret = mobiveil_pcie_init_irq_domain(pcie);
+	ret = mobiveil_pcie_interrupt_init(pcie);
 	if (ret) {
-		dev_err(dev, "Failed creating IRQ Domain\n");
+		dev_err(dev, "Interrupt init failed\n");
 		goto error;
 	}
 
-	irq_set_chained_handler_and_data(pcie->irq, mobiveil_pcie_isr, pcie);
-
 	ret = devm_request_pci_bus_resources(dev, &pcie->resources);
 	if (ret)
 		goto error;
@@ -916,7 +584,7 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
 	list_splice_init(&pcie->resources, &bridge->windows);
 	bridge->dev.parent = dev;
 	bridge->sysdata = pcie;
-	bridge->busnr = pcie->root_bus_nr;
+	bridge->busnr = pcie->rp.root_bus_nr;
 	bridge->ops = &mobiveil_pcie_ops;
 	bridge->map_irq = of_irq_parse_and_map_pci;
 	bridge->swizzle_irq = pci_common_swizzle;
@@ -944,25 +612,3 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
 	pci_free_resource_list(&pcie->resources);
 	return ret;
 }
-
-static const struct of_device_id mobiveil_pcie_of_match[] = {
-	{.compatible = "mbvl,gpex40-pcie",},
-	{},
-};
-
-MODULE_DEVICE_TABLE(of, mobiveil_pcie_of_match);
-
-static struct platform_driver mobiveil_pcie_driver = {
-	.probe = mobiveil_pcie_probe,
-	.driver = {
-		.name = "mobiveil-pcie",
-		.of_match_table = mobiveil_pcie_of_match,
-		.suppress_bind_attrs = true,
-	},
-};
-
-builtin_platform_driver(mobiveil_pcie_driver);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Mobiveil PCIe host controller driver");
-MODULE_AUTHOR("Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>");
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
new file mode 100644
index 000000000000..216c62f35568
--- /dev/null
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe host controller driver for Mobiveil PCIe Host controller
+ *
+ * Copyright (c) 2018 Mobiveil Inc.
+ * Author: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
+ * Refactor: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "pcie-mobiveil.h"
+
+static int mobiveil_pcie_probe(struct platform_device *pdev)
+{
+	struct mobiveil_pcie *pcie;
+	struct device *dev = &pdev->dev;
+
+	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	pcie->pdev = pdev;
+
+	return mobiveil_pcie_host_probe(pcie);
+}
+
+static const struct of_device_id mobiveil_pcie_of_match[] = {
+	{.compatible = "mbvl,gpex40-pcie",},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, mobiveil_pcie_of_match);
+
+static struct platform_driver mobiveil_pcie_driver = {
+	.probe = mobiveil_pcie_probe,
+	.driver = {
+		.name = "mobiveil-pcie",
+		.of_match_table = mobiveil_pcie_of_match,
+		.suppress_bind_attrs = true,
+	},
+};
+
+builtin_platform_driver(mobiveil_pcie_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Mobiveil PCIe host controller driver");
+MODULE_AUTHOR("Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>");
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.c b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
new file mode 100644
index 000000000000..ee678a60825d
--- /dev/null
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe host controller driver for Mobiveil PCIe Host controller
+ *
+ * Copyright (c) 2018 Mobiveil Inc.
+ * Author: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
+ * Refactor: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+
+#include "pcie-mobiveil.h"
+
+/*
+ * mobiveil_pcie_sel_page - routine to access paged register
+ *
+ * Registers whose address greater than PAGED_ADDR_BNDRY (0xc00) are paged,
+ * for this scheme to work extracted higher 6 bits of the offset will be
+ * written to pg_sel field of PAB_CTRL register and rest of the lower 10
+ * bits enabled with PAGED_ADDR_BNDRY are used as offset of the register.
+ */
+static void mobiveil_pcie_sel_page(struct mobiveil_pcie *pcie, u8 pg_idx)
+{
+	u32 val;
+
+	val = readl(pcie->csr_axi_slave_base + PAB_CTRL);
+	val &= ~(PAGE_SEL_MASK << PAGE_SEL_SHIFT);
+	val |= (pg_idx & PAGE_SEL_MASK) << PAGE_SEL_SHIFT;
+
+	writel(val, pcie->csr_axi_slave_base + PAB_CTRL);
+}
+
+static void *mobiveil_pcie_comp_addr(struct mobiveil_pcie *pcie, u32 off)
+{
+	if (off < PAGED_ADDR_BNDRY) {
+		/* For directly accessed registers, clear the pg_sel field */
+		mobiveil_pcie_sel_page(pcie, 0);
+		return pcie->csr_axi_slave_base + off;
+	}
+
+	mobiveil_pcie_sel_page(pcie, OFFSET_TO_PAGE_IDX(off));
+	return pcie->csr_axi_slave_base + OFFSET_TO_PAGE_ADDR(off);
+}
+
+static int mobiveil_pcie_read(void __iomem *addr, int size, u32 *val)
+{
+	if ((uintptr_t)addr & (size - 1)) {
+		*val = 0;
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	switch (size) {
+	case 4:
+		*val = readl(addr);
+		break;
+	case 2:
+		*val = readw(addr);
+		break;
+	case 1:
+		*val = readb(addr);
+		break;
+	default:
+		*val = 0;
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int mobiveil_pcie_write(void __iomem *addr, int size, u32 val)
+{
+	if ((uintptr_t)addr & (size - 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	switch (size) {
+	case 4:
+		writel(val, addr);
+		break;
+	case 2:
+		writew(val, addr);
+		break;
+	case 1:
+		writeb(val, addr);
+		break;
+	default:
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+u32 csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size)
+{
+	void *addr;
+	u32 val;
+	int ret;
+
+	addr = mobiveil_pcie_comp_addr(pcie, off);
+
+	ret = mobiveil_pcie_read(addr, size, &val);
+	if (ret)
+		dev_err(&pcie->pdev->dev, "read CSR address failed\n");
+
+	return val;
+}
+
+void csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, size_t size)
+{
+	void *addr;
+	int ret;
+
+	addr = mobiveil_pcie_comp_addr(pcie, off);
+
+	ret = mobiveil_pcie_write(addr, size, val);
+	if (ret)
+		dev_err(&pcie->pdev->dev, "write CSR address failed\n");
+}
+
+bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie)
+{
+	if (pcie->ops->link_up)
+		return pcie->ops->link_up(pcie);
+
+	return (csr_readl(pcie, LTSSM_STATUS) &
+		LTSSM_STATUS_L0_MASK) == LTSSM_STATUS_L0;
+}
+
+void program_ib_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
+			u64 pci_addr, u32 type, u64 size)
+{
+	u32 value;
+	u64 size64 = ~(size - 1);
+
+	if (win_num >= pcie->ppio_wins) {
+		dev_err(&pcie->pdev->dev,
+			"ERROR: max inbound windows reached !\n");
+		return;
+	}
+
+	value = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
+	value &= ~(AMAP_CTRL_TYPE_MASK << AMAP_CTRL_TYPE_SHIFT |
+		 WIN_SIZE_MASK << WIN_SIZE_SHIFT);
+	value |= (type << AMAP_CTRL_TYPE_SHIFT) | (1 << AMAP_CTRL_EN_SHIFT) |
+		 (lower_32_bits(size64) & WIN_SIZE_MASK << WIN_SIZE_SHIFT);
+	csr_writel(pcie, value, PAB_PEX_AMAP_CTRL(win_num));
+
+	csr_writel(pcie, upper_32_bits(size64),
+		   PAB_EXT_PEX_AMAP_SIZEN(win_num));
+
+	csr_writel(pcie, lower_32_bits(cpu_addr),
+		   PAB_PEX_AMAP_AXI_WIN(win_num));
+	csr_writel(pcie, upper_32_bits(cpu_addr),
+		   PAB_EXT_PEX_AMAP_AXI_WIN(win_num));
+
+	csr_writel(pcie, lower_32_bits(pci_addr),
+		   PAB_PEX_AMAP_PEX_WIN_L(win_num));
+	csr_writel(pcie, upper_32_bits(pci_addr),
+		   PAB_PEX_AMAP_PEX_WIN_H(win_num));
+
+	pcie->ib_wins_configured++;
+}
+
+/*
+ * routine to program the outbound windows
+ */
+void program_ob_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
+			u64 pci_addr, u32 type, u64 size)
+{
+
+	u32 value;
+	u64 size64 = ~(size - 1);
+
+	if (win_num >= pcie->apio_wins) {
+		dev_err(&pcie->pdev->dev,
+			"ERROR: max outbound windows reached !\n");
+		return;
+	}
+
+	/*
+	 * program Enable Bit to 1, Type Bit to (00) base 2, AXI Window Size Bit
+	 * to 4 KB in PAB_AXI_AMAP_CTRL register
+	 */
+	value = csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num));
+	value &= ~(WIN_TYPE_MASK << WIN_TYPE_SHIFT |
+		 WIN_SIZE_MASK << WIN_SIZE_SHIFT);
+	value |= 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
+		 (lower_32_bits(size64) & WIN_SIZE_MASK << WIN_SIZE_SHIFT);
+	csr_writel(pcie, value, PAB_AXI_AMAP_CTRL(win_num));
+
+	csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num));
+
+	/*
+	 * program AXI window base with appropriate value in
+	 * PAB_AXI_AMAP_AXI_WIN0 register
+	 */
+	csr_writel(pcie, lower_32_bits(cpu_addr) & (~AXI_WINDOW_ALIGN_MASK),
+		   PAB_AXI_AMAP_AXI_WIN(win_num));
+	csr_writel(pcie, upper_32_bits(cpu_addr),
+		   PAB_EXT_AXI_AMAP_AXI_WIN(win_num));
+
+	csr_writel(pcie, lower_32_bits(pci_addr),
+		   PAB_AXI_AMAP_PEX_WIN_L(win_num));
+	csr_writel(pcie, upper_32_bits(pci_addr),
+		   PAB_AXI_AMAP_PEX_WIN_H(win_num));
+
+	pcie->ob_wins_configured++;
+}
+
+int mobiveil_bringup_link(struct mobiveil_pcie *pcie)
+{
+	int retries;
+
+	/* check if the link is up or not */
+	for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
+		if (mobiveil_pcie_link_up(pcie))
+			return 0;
+
+		usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
+	}
+
+	dev_err(&pcie->pdev->dev, "link never came up\n");
+
+	return -ETIMEDOUT;
+}
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
new file mode 100644
index 000000000000..eb4cb61291a8
--- /dev/null
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
@@ -0,0 +1,187 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PCIe host controller driver for Mobiveil PCIe Host controller
+ *
+ * Copyright (c) 2018 Mobiveil Inc.
+ * Author: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
+ * Refactor: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
+ */
+
+#ifndef _PCIE_MOBIVEIL_H
+#define _PCIE_MOBIVEIL_H
+
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/msi.h>
+#include "../../pci.h"
+
+/* register offsets and bit positions */
+
+/*
+ * translation tables are grouped into windows, each window registers are
+ * grouped into blocks of 4 or 16 registers each
+ */
+#define PAB_REG_BLOCK_SIZE		16
+#define PAB_EXT_REG_BLOCK_SIZE		4
+
+#define PAB_REG_ADDR(offset, win)	\
+	(offset + (win * PAB_REG_BLOCK_SIZE))
+#define PAB_EXT_REG_ADDR(offset, win)	\
+	(offset + (win * PAB_EXT_REG_BLOCK_SIZE))
+
+#define LTSSM_STATUS			0x0404
+#define  LTSSM_STATUS_L0_MASK		0x3f
+#define  LTSSM_STATUS_L0		0x2d
+
+#define PAB_CTRL			0x0808
+#define  AMBA_PIO_ENABLE_SHIFT		0
+#define  PEX_PIO_ENABLE_SHIFT		1
+#define  PAGE_SEL_SHIFT			13
+#define  PAGE_SEL_MASK			0x3f
+#define  PAGE_LO_MASK			0x3ff
+#define  PAGE_SEL_OFFSET_SHIFT		10
+
+#define PAB_AXI_PIO_CTRL		0x0840
+#define  APIO_EN_MASK			0xf
+
+#define PAB_PEX_PIO_CTRL		0x08c0
+#define  PIO_ENABLE_SHIFT		0
+
+#define PAB_INTP_AMBA_MISC_ENB		0x0b0c
+#define PAB_INTP_AMBA_MISC_STAT		0x0b1c
+#define  PAB_INTP_INTX_MASK		0x01e0
+#define  PAB_INTP_MSI_MASK		0x8
+
+#define PAB_AXI_AMAP_CTRL(win)		PAB_REG_ADDR(0x0ba0, win)
+#define  WIN_ENABLE_SHIFT		0
+#define  WIN_TYPE_SHIFT			1
+#define  WIN_TYPE_MASK			0x3
+#define  WIN_SIZE_SHIFT			10
+#define  WIN_SIZE_MASK			0x3fffff
+
+#define PAB_EXT_AXI_AMAP_SIZE(win)	PAB_EXT_REG_ADDR(0xbaf0, win)
+
+#define PAB_EXT_AXI_AMAP_AXI_WIN(win)	PAB_EXT_REG_ADDR(0x80a0, win)
+#define PAB_AXI_AMAP_AXI_WIN(win)	PAB_REG_ADDR(0x0ba4, win)
+#define  AXI_WINDOW_ALIGN_MASK		3
+
+#define PAB_AXI_AMAP_PEX_WIN_L(win)	PAB_REG_ADDR(0x0ba8, win)
+#define  PAB_BUS_SHIFT			24
+#define  PAB_DEVICE_SHIFT		19
+#define  PAB_FUNCTION_SHIFT		16
+
+#define PAB_AXI_AMAP_PEX_WIN_H(win)	PAB_REG_ADDR(0x0bac, win)
+#define PAB_INTP_AXI_PIO_CLASS		0x474
+
+#define PAB_PEX_AMAP_CTRL(win)		PAB_REG_ADDR(0x4ba0, win)
+#define  AMAP_CTRL_EN_SHIFT		0
+#define  AMAP_CTRL_TYPE_SHIFT		1
+#define  AMAP_CTRL_TYPE_MASK		3
+
+#define PAB_EXT_PEX_AMAP_SIZEN(win)	PAB_EXT_REG_ADDR(0xbef0, win)
+#define PAB_EXT_PEX_AMAP_AXI_WIN(win)	PAB_EXT_REG_ADDR(0xb4a0, win)
+#define PAB_PEX_AMAP_AXI_WIN(win)	PAB_REG_ADDR(0x4ba4, win)
+#define PAB_PEX_AMAP_PEX_WIN_L(win)	PAB_REG_ADDR(0x4ba8, win)
+#define PAB_PEX_AMAP_PEX_WIN_H(win)	PAB_REG_ADDR(0x4bac, win)
+
+/* starting offset of INTX bits in status register */
+#define PAB_INTX_START			5
+
+/* supported number of MSI interrupts */
+#define PCI_NUM_MSI			16
+
+/* MSI registers */
+#define MSI_BASE_LO_OFFSET		0x04
+#define MSI_BASE_HI_OFFSET		0x08
+#define MSI_SIZE_OFFSET			0x0c
+#define MSI_ENABLE_OFFSET		0x14
+#define MSI_STATUS_OFFSET		0x18
+#define MSI_DATA_OFFSET			0x20
+#define MSI_ADDR_L_OFFSET		0x24
+#define MSI_ADDR_H_OFFSET		0x28
+
+/* outbound and inbound window definitions */
+#define WIN_NUM_0			0
+#define WIN_NUM_1			1
+#define CFG_WINDOW_TYPE			0
+#define IO_WINDOW_TYPE			1
+#define MEM_WINDOW_TYPE			2
+#define IB_WIN_SIZE			((u64)256 * 1024 * 1024 * 1024)
+#define MAX_PIO_WINDOWS			8
+
+/* Parameters for the waiting for link up routine */
+#define LINK_WAIT_MAX_RETRIES		10
+#define LINK_WAIT_MIN			90000
+#define LINK_WAIT_MAX			100000
+
+#define PAGED_ADDR_BNDRY		0xc00
+#define OFFSET_TO_PAGE_ADDR(off)	\
+	((off & PAGE_LO_MASK) | PAGED_ADDR_BNDRY)
+#define OFFSET_TO_PAGE_IDX(off)		\
+	((off >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK)
+
+struct mobiveil_pcie;
+
+struct mobiveil_msi {			/* MSI information */
+	struct mutex lock;		/* protect bitmap variable */
+	struct irq_domain *msi_domain;
+	struct irq_domain *dev_domain;
+	phys_addr_t msi_pages_phys;
+	int num_of_vectors;
+	DECLARE_BITMAP(msi_irq_in_use, PCI_NUM_MSI);
+};
+
+struct mobiveil_rp_ops {
+	int (*interrupt_init)(struct mobiveil_pcie *pcie);
+};
+
+struct root_port {
+	u8 root_bus_nr;
+	void __iomem *config_axi_slave_base;	/* endpoint config base */
+	struct resource *ob_io_res;
+	struct mobiveil_rp_ops *ops;
+	int irq;
+	raw_spinlock_t intx_mask_lock;
+	struct irq_domain *intx_domain;
+	struct mobiveil_msi msi;
+};
+
+struct mobiveil_pab_ops {
+	int (*link_up)(struct mobiveil_pcie *pcie);
+};
+
+struct mobiveil_pcie {
+	struct platform_device *pdev;
+	struct list_head resources;
+	void __iomem *csr_axi_slave_base;	/* PAB registers base */
+	phys_addr_t pcie_reg_base;	/* Physical PCIe Controller Base */
+	void __iomem *apb_csr_base;	/* MSI register base */
+	u32 apio_wins;
+	u32 ppio_wins;
+	u32 ob_wins_configured;		/* configured outbound windows */
+	u32 ib_wins_configured;		/* configured inbound windows */
+	const struct mobiveil_pab_ops *ops;
+	struct root_port rp;
+};
+
+int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie);
+bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie);
+int mobiveil_bringup_link(struct mobiveil_pcie *pcie);
+void program_ob_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
+			u64 pci_addr, u32 type, u64 size);
+void program_ib_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
+			u64 pci_addr, u32 type, u64 size);
+u32 csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size);
+void csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, size_t size);
+
+static inline u32 csr_readl(struct mobiveil_pcie *pcie, u32 off)
+{
+	return csr_read(pcie, off, 0x4);
+}
+
+static inline void csr_writel(struct mobiveil_pcie *pcie, u32 val, u32 off)
+{
+	csr_write(pcie, val, off, 0x4);
+}
+
+#endif /* _PCIE_MOBIVEIL_H */
-- 
2.17.1


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

* [PATCHv3 17/27] PCI: mobiveil: fix the checking of valid device
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (15 preceding siblings ...)
  2019-01-29  8:10 ` [PATCHv3 16/27] PCI: mobiveil: refactor Mobiveil PCIe Host Bridge IP driver Z.q. Hou
@ 2019-01-29  8:10 ` Z.q. Hou
  2019-02-08 12:41   ` Subrahmanya Lingappa
  2019-01-29  8:10 ` [PATCHv3 18/27] PCI: mobiveil: continue to initialize the host upon no PCIe link Z.q. Hou
                   ` (11 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:10 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

Avoid to issue CFG transactions to link partner when the PCIe
link is not up. And allow CFG transactions to all functions of
Endpoint implemented multiple functions.

Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host
Bridge IP driver")
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/mobiveil/pcie-mobiveil-host.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
index dc5324d94466..1ae82e790562 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
@@ -29,6 +29,10 @@ static bool mobiveil_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
 {
 	struct mobiveil_pcie *pcie = bus->sysdata;
 
+	/* If there is no link, then there is no device */
+	if (bus->number > pcie->rp.root_bus_nr && !mobiveil_pcie_link_up(pcie))
+		return false;
+
 	/* Only one device down on each root port */
 	if ((bus->number == pcie->rp.root_bus_nr) && (devfn > 0))
 		return false;
@@ -37,7 +41,7 @@ static bool mobiveil_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
 	 * Do not read more than one device on the bus directly
 	 * attached to RC
 	 */
-	if ((bus->primary == pcie->rp.root_bus_nr) && (devfn > 0))
+	if ((bus->primary == pcie->rp.root_bus_nr) && (PCI_SLOT(devfn) > 0))
 		return false;
 
 	return true;
-- 
2.17.1


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

* [PATCHv3 18/27] PCI: mobiveil: continue to initialize the host upon no PCIe link
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (16 preceding siblings ...)
  2019-01-29  8:10 ` [PATCHv3 17/27] PCI: mobiveil: fix the checking of valid device Z.q. Hou
@ 2019-01-29  8:10 ` Z.q. Hou
  2019-02-08 12:41   ` Subrahmanya Lingappa
  2019-01-29  8:10 ` [PATCHv3 19/27] PCI: mobiveil: disabled IB and OB windows set by bootloader Z.q. Hou
                   ` (10 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:10 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

Sometimes there is not a PCIe Endpoint in the PCIe slot, so do
not exit when the PCIe link is not up. And degrade the print
level of link up info.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/mobiveil/pcie-mobiveil-host.c | 1 -
 drivers/pci/controller/mobiveil/pcie-mobiveil.c      | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
index 1ae82e790562..d1765d572f44 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
@@ -596,7 +596,6 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
 	ret = mobiveil_bringup_link(pcie);
 	if (ret) {
 		dev_info(dev, "link bring-up failed\n");
-		goto error;
 	}
 
 	/* setup the kernel resources for the newly added PCIe root bus */
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.c b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
index ee678a60825d..370658d6546d 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
@@ -222,7 +222,7 @@ int mobiveil_bringup_link(struct mobiveil_pcie *pcie)
 		usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
 	}
 
-	dev_err(&pcie->pdev->dev, "link never came up\n");
+	dev_info(&pcie->pdev->dev, "link never came up\n");
 
 	return -ETIMEDOUT;
 }
-- 
2.17.1


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

* [PATCHv3 19/27] PCI: mobiveil: disabled IB and OB windows set by bootloader
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (17 preceding siblings ...)
  2019-01-29  8:10 ` [PATCHv3 18/27] PCI: mobiveil: continue to initialize the host upon no PCIe link Z.q. Hou
@ 2019-01-29  8:10 ` Z.q. Hou
  2019-02-08 12:42   ` Subrahmanya Lingappa
  2019-01-29  8:10 ` [PATCHv3 20/27] PCI: mobiveil: add Byte and Half-Word width register accessors Z.q. Hou
                   ` (9 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:10 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

Disabled all inbound and outbound windows before set up the windows
in kernel, in case transactions match the window set by bootloader.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 .../controller/mobiveil/pcie-mobiveil-host.c   |  7 +++++++
 .../pci/controller/mobiveil/pcie-mobiveil.c    | 18 ++++++++++++++++++
 .../pci/controller/mobiveil/pcie-mobiveil.h    |  2 ++
 3 files changed, 27 insertions(+)

diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
index d1765d572f44..d028cdf31d0e 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
@@ -221,6 +221,13 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 {
 	u32 value, pab_ctrl, type;
 	struct resource_entry *win;
+	int i;
+
+	/* Disable all inbound/outbound windows */
+	for (i = 0; i < pcie->apio_wins; i++)
+		mobiveil_pcie_disable_ob_win(pcie, i);
+	for (i = 0; i < pcie->ppio_wins; i++)
+		mobiveil_pcie_disable_ib_win(pcie, i);
 
 	/* setup bus numbers */
 	value = csr_readl(pcie, PCI_PRIMARY_BUS);
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.c b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
index 370658d6546d..49d471b75925 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
@@ -226,3 +226,21 @@ int mobiveil_bringup_link(struct mobiveil_pcie *pcie)
 
 	return -ETIMEDOUT;
 }
+
+void mobiveil_pcie_disable_ib_win(struct mobiveil_pcie *pci, int win_num)
+{
+	u32 val;
+
+	val = csr_readl(pci, PAB_PEX_AMAP_CTRL(win_num));
+	val &= ~(1 << AMAP_CTRL_EN_SHIFT);
+	csr_writel(pci, val, PAB_PEX_AMAP_CTRL(win_num));
+}
+
+void mobiveil_pcie_disable_ob_win(struct mobiveil_pcie *pci, int win_num)
+{
+	u32 val;
+
+	val = csr_readl(pci, PAB_AXI_AMAP_CTRL(win_num));
+	val &= ~(1 << WIN_ENABLE_SHIFT);
+	csr_writel(pci, val, PAB_AXI_AMAP_CTRL(win_num));
+}
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
index eb4cb61291a8..81685840b378 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
@@ -171,6 +171,8 @@ void program_ob_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
 			u64 pci_addr, u32 type, u64 size);
 void program_ib_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
 			u64 pci_addr, u32 type, u64 size);
+void mobiveil_pcie_disable_ob_win(struct mobiveil_pcie *pci, int win_num);
+void mobiveil_pcie_disable_ib_win(struct mobiveil_pcie *pci, int win_num);
 u32 csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size);
 void csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, size_t size);
 
-- 
2.17.1


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

* [PATCHv3 20/27] PCI: mobiveil: add Byte and Half-Word width register accessors
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (18 preceding siblings ...)
  2019-01-29  8:10 ` [PATCHv3 19/27] PCI: mobiveil: disabled IB and OB windows set by bootloader Z.q. Hou
@ 2019-01-29  8:10 ` Z.q. Hou
  2019-02-08 12:44   ` Subrahmanya Lingappa
  2019-01-29  8:10 ` [PATCHv3 21/27] PCI: mobiveil: make mobiveil_host_init can be used to re-init host Z.q. Hou
                   ` (8 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:10 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

As there are some Byte and Half-Work width registers in PCIe
configuration space, add Byte and Half-Word width register
accessors.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 .../pci/controller/mobiveil/pcie-mobiveil.h   | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
index 81685840b378..933c2f34bc52 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
@@ -181,9 +181,29 @@ static inline u32 csr_readl(struct mobiveil_pcie *pcie, u32 off)
 	return csr_read(pcie, off, 0x4);
 }
 
+static inline u32 csr_readw(struct mobiveil_pcie *pcie, u32 off)
+{
+	return csr_read(pcie, off, 0x2);
+}
+
+static inline u32 csr_readb(struct mobiveil_pcie *pcie, u32 off)
+{
+	return csr_read(pcie, off, 0x1);
+}
+
 static inline void csr_writel(struct mobiveil_pcie *pcie, u32 val, u32 off)
 {
 	csr_write(pcie, val, off, 0x4);
 }
 
+static inline void csr_writew(struct mobiveil_pcie *pcie, u32 val, u32 off)
+{
+	csr_write(pcie, val, off, 0x2);
+}
+
+static inline void csr_writeb(struct mobiveil_pcie *pcie, u32 val, u32 off)
+{
+	csr_write(pcie, val, off, 0x1);
+}
+
 #endif /* _PCIE_MOBIVEIL_H */
-- 
2.17.1


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

* [PATCHv3 21/27] PCI: mobiveil: make mobiveil_host_init can be used to re-init host
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (19 preceding siblings ...)
  2019-01-29  8:10 ` [PATCHv3 20/27] PCI: mobiveil: add Byte and Half-Word width register accessors Z.q. Hou
@ 2019-01-29  8:10 ` Z.q. Hou
  2019-02-08 12:46   ` Subrahmanya Lingappa
  2019-01-29  8:10 ` [PATCHv3 22/27] dt-bindings: pci: Add NXP Layerscape SoCs PCIe Gen4 controller Z.q. Hou
                   ` (7 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:10 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

Make the mobiveil_host_init function can be used to re-init
host controller's PAB and GPEX CSR register block, as NXP
integrated Mobiveil IP has to reset and then re-init the PAB
and GPEX CSR registers upon Hot-reset.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V3:
 - Removed the duplicated free opteration of pcie->resources.

 .../controller/mobiveil/pcie-mobiveil-host.c  | 41 ++++++++++---------
 .../pci/controller/mobiveil/pcie-mobiveil.h   |  3 +-
 2 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
index d028cdf31d0e..e8d0c4989013 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
@@ -217,7 +217,7 @@ static void mobiveil_pcie_enable_msi(struct mobiveil_pcie *pcie)
 	writel_relaxed(1, pcie->apb_csr_base + MSI_ENABLE_OFFSET);
 }
 
-static int mobiveil_host_init(struct mobiveil_pcie *pcie)
+int mobiveil_host_init(struct mobiveil_pcie *pcie, bool reinit)
 {
 	u32 value, pab_ctrl, type;
 	struct resource_entry *win;
@@ -229,11 +229,16 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 	for (i = 0; i < pcie->ppio_wins; i++)
 		mobiveil_pcie_disable_ib_win(pcie, i);
 
-	/* setup bus numbers */
-	value = csr_readl(pcie, PCI_PRIMARY_BUS);
-	value &= 0xff000000;
-	value |= 0x00ff0100;
-	csr_writel(pcie, value, PCI_PRIMARY_BUS);
+	pcie->ib_wins_configured = 0;
+	pcie->ob_wins_configured = 0;
+
+	if (!reinit) {
+		/* setup bus numbers */
+		value = csr_readl(pcie, PCI_PRIMARY_BUS);
+		value &= 0xff000000;
+		value |= 0x00ff0100;
+		csr_writel(pcie, value, PCI_PRIMARY_BUS);
+	}
 
 	/*
 	 * program Bus Master Enable Bit in Command Register in PAB Config
@@ -279,7 +284,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
 	program_ib_windows(pcie, WIN_NUM_0, 0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
 
 	/* Get the I/O and memory ranges from DT */
-	resource_list_for_each_entry(win, &pcie->resources) {
+	resource_list_for_each_entry(win, pcie->resources) {
 		if (resource_type(win->res) == IORESOURCE_MEM) {
 			type = MEM_WINDOW_TYPE;
 		} else if (resource_type(win->res) == IORESOURCE_IO) {
@@ -550,8 +555,6 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
 	resource_size_t iobase;
 	int ret;
 
-	INIT_LIST_HEAD(&pcie->resources);
-
 	ret = mobiveil_pcie_parse_dt(pcie);
 	if (ret) {
 		dev_err(dev, "Parsing DT failed, ret: %x\n", ret);
@@ -565,34 +568,35 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
 
 	/* parse the host bridge base addresses from the device tree file */
 	ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
-						    &pcie->resources, &iobase);
+						    &bridge->windows, &iobase);
 	if (ret) {
 		dev_err(dev, "Getting bridge resources failed\n");
 		return ret;
 	}
 
+	pcie->resources = &bridge->windows;
+
 	/*
 	 * configure all inbound and outbound windows and prepare the RC for
 	 * config access
 	 */
-	ret = mobiveil_host_init(pcie);
+	ret = mobiveil_host_init(pcie, false);
 	if (ret) {
 		dev_err(dev, "Failed to initialize host\n");
-		goto error;
+		return ret;
 	}
 
 	ret = mobiveil_pcie_interrupt_init(pcie);
 	if (ret) {
 		dev_err(dev, "Interrupt init failed\n");
-		goto error;
+		return ret;
 	}
 
-	ret = devm_request_pci_bus_resources(dev, &pcie->resources);
+	ret = devm_request_pci_bus_resources(dev, pcie->resources);
 	if (ret)
-		goto error;
+		return ret;
 
 	/* Initialize bridge */
-	list_splice_init(&pcie->resources, &bridge->windows);
 	bridge->dev.parent = dev;
 	bridge->sysdata = pcie;
 	bridge->busnr = pcie->rp.root_bus_nr;
@@ -608,7 +612,7 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
 	/* setup the kernel resources for the newly added PCIe root bus */
 	ret = pci_scan_root_bus_bridge(bridge);
 	if (ret)
-		goto error;
+		return ret;
 
 	bus = bridge->bus;
 
@@ -618,7 +622,4 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
 	pci_bus_add_devices(bus);
 
 	return 0;
-error:
-	pci_free_resource_list(&pcie->resources);
-	return ret;
 }
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
index 933c2f34bc52..0f5303962e88 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
@@ -152,7 +152,7 @@ struct mobiveil_pab_ops {
 
 struct mobiveil_pcie {
 	struct platform_device *pdev;
-	struct list_head resources;
+	struct list_head *resources;
 	void __iomem *csr_axi_slave_base;	/* PAB registers base */
 	phys_addr_t pcie_reg_base;	/* Physical PCIe Controller Base */
 	void __iomem *apb_csr_base;	/* MSI register base */
@@ -165,6 +165,7 @@ struct mobiveil_pcie {
 };
 
 int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie);
+int mobiveil_host_init(struct mobiveil_pcie *pcie, bool reinit);
 bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie);
 int mobiveil_bringup_link(struct mobiveil_pcie *pcie);
 void program_ob_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
-- 
2.17.1


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

* [PATCHv3 22/27] dt-bindings: pci: Add NXP Layerscape SoCs PCIe Gen4 controller
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (20 preceding siblings ...)
  2019-01-29  8:10 ` [PATCHv3 21/27] PCI: mobiveil: make mobiveil_host_init can be used to re-init host Z.q. Hou
@ 2019-01-29  8:10 ` Z.q. Hou
  2019-01-30 18:49   ` Rob Herring
  2019-01-29  8:10 ` [PATCHv3 23/27] PCI: mobiveil: add PCIe Gen4 RC driver for NXP Layerscape SoCs Z.q. Hou
                   ` (6 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:10 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

Add PCIe Gen4 controller DT bindings of NXP Layerscape SoCs.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V3:
 - Change back to use an new doc for Layerscape PCIe Gen4 DT bindings.
 - Switch the order of "csr_axi_slave" and "config_axi_slave".

 .../bindings/pci/layerscape-pci-gen4.txt      | 52 +++++++++++++++++++
 MAINTAINERS                                   |  8 +++
 2 files changed, 60 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/layerscape-pci-gen4.txt

diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci-gen4.txt b/Documentation/devicetree/bindings/pci/layerscape-pci-gen4.txt
new file mode 100644
index 000000000000..b40fb5d15d3d
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/layerscape-pci-gen4.txt
@@ -0,0 +1,52 @@
+NXP Layerscape PCIe Gen4 controller
+
+This PCIe controller is based on the Mobiveil PCIe IP and thus inherits all
+the common properties defined in mobiveil-pcie.txt.
+
+Required properties:
+- compatible: should contain the platform identifier such as:
+  "fsl,lx2160a-pcie"
+- reg: base addresses and lengths of the PCIe controller register blocks.
+  "csr_axi_slave": Bridge config registers
+  "config_axi_slave": PCIe controller registers
+- interrupts: A list of interrupt outputs of the controller. Must contain an
+  entry for each entry in the interrupt-names property.
+- interrupt-names: It could include the following entries:
+  "intr": The interrupt that is asserted for controller interrupts
+  "aer": Asserted for aer interrupt when chip support the aer interrupt with
+	 none MSI/MSI-X/INTx mode,but there is interrupt line for aer.
+  "pme": Asserted for pme interrupt when chip support the pme interrupt with
+	 none MSI/MSI-X/INTx mode,but there is interrupt line for pme.
+- dma-coherent: Indicates that the hardware IP block can ensure the coherency
+  of the data transferred from/to the IP block. This can avoid the software
+  cache flush/invalid actions, and improve the performance significantly.
+- msi-parent : See the generic MSI binding described in
+  Documentation/devicetree/bindings/interrupt-controller/msi.txt.
+
+Example:
+
+	pcie@3400000 {
+		compatible = "fsl,lx2160a-pcie";
+		reg = <0x00 0x03400000 0x0 0x00100000   /* controller registers */
+		       0x80 0x00000000 0x0 0x00001000>; /* configuration space */
+		reg-names = "csr_axi_slave", "config_axi_slave";
+		interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */
+			     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */
+			     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
+		interrupt-names = "aer", "pme", "intr";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		apio-wins = <8>;
+		ppio-wins = <8>;
+		dma-coherent;
+		bus-range = <0x0 0xff>;
+		msi-parent = <&its>;
+		ranges = <0x82000000 0x0 0x40000000 0x80 0x40000000 0x0 0x40000000>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+				<0000 0 0 2 &gic 0 0 GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+				<0000 0 0 3 &gic 0 0 GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+				<0000 0 0 4 &gic 0 0 GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+	};
diff --git a/MAINTAINERS b/MAINTAINERS
index 3bca9642b08b..16b9f56fadba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11667,6 +11667,14 @@ L:	linux-arm-kernel@lists.infradead.org
 S:	Maintained
 F:	drivers/pci/controller/dwc/*layerscape*
 
+PCI DRIVER FOR NXP LAYERSCAPE GEN4 CONTROLLER
+M:	Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
+L:	linux-pci@vger.kernel.org
+L:	linux-arm-kernel@lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/pci/layerscape-pci-gen4.txt
+F:	drivers/pci/controller/mobibeil/pci-layerscape-gen4.c
+
 PCI DRIVER FOR GENERIC OF HOSTS
 M:	Will Deacon <will.deacon@arm.com>
 L:	linux-pci@vger.kernel.org
-- 
2.17.1


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

* [PATCHv3 23/27] PCI: mobiveil: add PCIe Gen4 RC driver for NXP Layerscape SoCs
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (21 preceding siblings ...)
  2019-01-29  8:10 ` [PATCHv3 22/27] dt-bindings: pci: Add NXP Layerscape SoCs PCIe Gen4 controller Z.q. Hou
@ 2019-01-29  8:10 ` Z.q. Hou
  2019-02-08 12:49   ` Subrahmanya Lingappa
  2019-01-29  8:11 ` [PATCHv3 24/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011577 Z.q. Hou
                   ` (5 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:10 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

This PCIe controller is based on the Mobiveil GPEX IP, which is
compatible with the PCI Express™ Base Specification, Revision 4.0.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 drivers/pci/controller/mobiveil/Kconfig       |  10 +
 drivers/pci/controller/mobiveil/Makefile      |   1 +
 .../controller/mobiveil/pci-layerscape-gen4.c | 254 ++++++++++++++++++
 .../pci/controller/mobiveil/pcie-mobiveil.h   |  16 +-
 4 files changed, 279 insertions(+), 2 deletions(-)
 create mode 100644 drivers/pci/controller/mobiveil/pci-layerscape-gen4.c

diff --git a/drivers/pci/controller/mobiveil/Kconfig b/drivers/pci/controller/mobiveil/Kconfig
index 64343c07bfed..3ddb7d6163a9 100644
--- a/drivers/pci/controller/mobiveil/Kconfig
+++ b/drivers/pci/controller/mobiveil/Kconfig
@@ -21,4 +21,14 @@ config PCIE_MOBIVEIL_PLAT
 	  Soft IP. It has up to 8 outbound and inbound windows
 	  for address translation and it is a PCIe Gen4 IP.
 
+config PCI_LAYERSCAPE_GEN4
+	bool "Freescale Layerscpe PCIe Gen4 controller"
+	depends on PCI
+	depends on OF && (ARM64 || ARCH_LAYERSCAPE)
+	depends on PCI_MSI_IRQ_DOMAIN
+	select PCIE_MOBIVEIL_HOST
+	help
+	  Say Y here if you want PCIe Gen4 controller support on
+	  Layerscape SoCs. The PCIe controller can work in RC or
+	  EP mode according to RCW[HOST_AGT_PEX] setting.
 endmenu
diff --git a/drivers/pci/controller/mobiveil/Makefile b/drivers/pci/controller/mobiveil/Makefile
index 9fb6d1c6504d..ff66774ccac4 100644
--- a/drivers/pci/controller/mobiveil/Makefile
+++ b/drivers/pci/controller/mobiveil/Makefile
@@ -2,3 +2,4 @@
 obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o
 obj-$(CONFIG_PCIE_MOBIVEIL_HOST) += pcie-mobiveil-host.o
 obj-$(CONFIG_PCIE_MOBIVEIL_PLAT) += pcie-mobiveil-plat.o
+obj-$(CONFIG_PCI_LAYERSCAPE_GEN4) += pci-layerscape-gen4.o
diff --git a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
new file mode 100644
index 000000000000..174cbcac4059
--- /dev/null
+++ b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
@@ -0,0 +1,254 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe host controller driver for NXP Layerscape SoCs
+ *
+ * Copyright 2018 NXP
+ *
+ * Author: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/resource.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#include "pcie-mobiveil.h"
+
+/* LUT and PF control registers */
+#define PCIE_LUT_OFF			(0x80000)
+#define PCIE_PF_OFF			(0xc0000)
+#define PCIE_PF_INT_STAT		(0x18)
+#define PF_INT_STAT_PABRST		(31)
+
+#define PCIE_PF_DBG			(0x7fc)
+#define PF_DBG_LTSSM_MASK		(0x3f)
+#define PF_DBG_WE			(31)
+#define PF_DBG_PABR			(27)
+
+#define LS_PCIE_G4_LTSSM_L0		0x2d /* L0 state */
+
+#define to_ls_pcie_g4(x)		platform_get_drvdata((x)->pdev)
+
+struct ls_pcie_g4 {
+	struct mobiveil_pcie *pci;
+	struct delayed_work dwork;
+	int irq;
+};
+
+static inline u32 ls_pcie_g4_lut_readl(struct ls_pcie_g4 *pcie, u32 off)
+{
+	return ioread32(pcie->pci->csr_axi_slave_base + PCIE_LUT_OFF + off);
+}
+
+static inline void ls_pcie_g4_lut_writel(struct ls_pcie_g4 *pcie,
+					 u32 off, u32 val)
+{
+	iowrite32(val, pcie->pci->csr_axi_slave_base + PCIE_LUT_OFF + off);
+}
+
+static inline u32 ls_pcie_g4_pf_readl(struct ls_pcie_g4 *pcie, u32 off)
+{
+	return ioread32(pcie->pci->csr_axi_slave_base + PCIE_PF_OFF + off);
+}
+
+static inline void ls_pcie_g4_pf_writel(struct ls_pcie_g4 *pcie,
+					u32 off, u32 val)
+{
+	iowrite32(val, pcie->pci->csr_axi_slave_base + PCIE_PF_OFF + off);
+}
+
+static bool ls_pcie_g4_is_bridge(struct ls_pcie_g4 *pcie)
+{
+	struct mobiveil_pcie *mv_pci = pcie->pci;
+	u32 header_type;
+
+	header_type = csr_readb(mv_pci, PCI_HEADER_TYPE);
+	header_type &= 0x7f;
+
+	return header_type == PCI_HEADER_TYPE_BRIDGE;
+}
+
+static int ls_pcie_g4_link_up(struct mobiveil_pcie *pci)
+{
+	struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
+	u32 state;
+
+	state = ls_pcie_g4_pf_readl(pcie, PCIE_PF_DBG);
+	state =	state & PF_DBG_LTSSM_MASK;
+
+	if (state == LS_PCIE_G4_LTSSM_L0)
+		return 1;
+
+	return 0;
+}
+
+static void ls_pcie_g4_reinit_hw(struct ls_pcie_g4 *pcie)
+{
+	struct mobiveil_pcie *mv_pci = pcie->pci;
+	u32 val, act_stat;
+	int to = 100;
+
+	/* Poll for pab_csb_reset to set and PAB activity to clear */
+	do {
+		usleep_range(10, 15);
+		val = ls_pcie_g4_pf_readl(pcie, PCIE_PF_INT_STAT);
+		act_stat = csr_readl(mv_pci, PAB_ACTIVITY_STAT);
+	} while (((val & 1 << PF_INT_STAT_PABRST) == 0 || act_stat) && to--);
+	if (to < 0) {
+		dev_err(&mv_pci->pdev->dev, "poll PABRST&PABACT timeout\n");
+		return;
+	}
+
+	/* clear PEX_RESET bit in PEX_PF0_DBG register */
+	val = ls_pcie_g4_pf_readl(pcie, PCIE_PF_DBG);
+	val |= 1 << PF_DBG_WE;
+	ls_pcie_g4_pf_writel(pcie, PCIE_PF_DBG, val);
+
+	val = ls_pcie_g4_pf_readl(pcie, PCIE_PF_DBG);
+	val |= 1 << PF_DBG_PABR;
+	ls_pcie_g4_pf_writel(pcie, PCIE_PF_DBG, val);
+
+	val = ls_pcie_g4_pf_readl(pcie, PCIE_PF_DBG);
+	val &= ~(1 << PF_DBG_WE);
+	ls_pcie_g4_pf_writel(pcie, PCIE_PF_DBG, val);
+
+	mobiveil_host_init(mv_pci, true);
+
+	to = 100;
+	while (!ls_pcie_g4_link_up(mv_pci) && to--)
+		usleep_range(200, 250);
+	if (to < 0)
+		dev_err(&mv_pci->pdev->dev, "PCIe link trainning timeout\n");
+}
+
+static irqreturn_t ls_pcie_g4_handler(int irq, void *dev_id)
+{
+	struct ls_pcie_g4 *pcie = (struct ls_pcie_g4 *)dev_id;
+	struct mobiveil_pcie *mv_pci = pcie->pci;
+	u32 val;
+
+	val = csr_readl(mv_pci, PAB_INTP_AMBA_MISC_STAT);
+	if (!val)
+		return IRQ_NONE;
+
+	if (val & PAB_INTP_RESET)
+		schedule_delayed_work(&pcie->dwork, msecs_to_jiffies(1));
+
+	csr_writel(mv_pci, val, PAB_INTP_AMBA_MISC_STAT);
+
+	return IRQ_HANDLED;
+}
+
+static int ls_pcie_g4_interrupt_init(struct mobiveil_pcie *mv_pci)
+{
+	struct ls_pcie_g4 *pcie = to_ls_pcie_g4(mv_pci);
+	u32 val;
+	int ret;
+
+	pcie->irq = platform_get_irq_byname(mv_pci->pdev, "intr");
+	if (pcie->irq < 0) {
+		dev_err(&mv_pci->pdev->dev, "Can't get 'intr' irq.\n");
+		return pcie->irq;
+	}
+	ret = devm_request_irq(&mv_pci->pdev->dev, pcie->irq,
+			       ls_pcie_g4_handler, IRQF_SHARED,
+			       mv_pci->pdev->name, pcie);
+	if (ret) {
+		dev_err(&mv_pci->pdev->dev, "Can't register PCIe IRQ.\n");
+		return  ret;
+	}
+
+	/* Enable interrupts */
+	val = PAB_INTP_INTX_MASK | PAB_INTP_MSI | PAB_INTP_RESET |
+	      PAB_INTP_PCIE_UE | PAB_INTP_IE_PMREDI | PAB_INTP_IE_EC;
+	csr_writel(mv_pci, val, PAB_INTP_AMBA_MISC_ENB);
+
+	return 0;
+}
+
+static void ls_pcie_g4_reset(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work, struct delayed_work,
+						  work);
+	struct ls_pcie_g4 *pcie = container_of(dwork, struct ls_pcie_g4, dwork);
+	struct mobiveil_pcie *mv_pci = pcie->pci;
+	u16 ctrl;
+
+	ctrl = csr_readw(mv_pci, PCI_BRIDGE_CONTROL);
+	ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
+	csr_writew(mv_pci, ctrl, PCI_BRIDGE_CONTROL);
+	ls_pcie_g4_reinit_hw(pcie);
+}
+
+static struct mobiveil_rp_ops ls_pcie_g4_rp_ops = {
+	.interrupt_init = ls_pcie_g4_interrupt_init,
+};
+
+static const struct mobiveil_pab_ops ls_pcie_g4_pab_ops = {
+	.link_up = ls_pcie_g4_link_up,
+};
+
+static int __init ls_pcie_g4_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mobiveil_pcie *mv_pci;
+	struct ls_pcie_g4 *pcie;
+	struct device_node *np = dev->of_node;
+	int ret;
+
+	if (!of_parse_phandle(np, "msi-parent", 0)) {
+		dev_err(dev, "failed to find msi-parent\n");
+		return -EINVAL;
+	}
+
+	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	mv_pci = devm_kzalloc(dev, sizeof(*mv_pci), GFP_KERNEL);
+	if (!mv_pci)
+		return -ENOMEM;
+
+	mv_pci->pdev = pdev;
+	mv_pci->ops = &ls_pcie_g4_pab_ops;
+	mv_pci->rp.ops = &ls_pcie_g4_rp_ops;
+	pcie->pci = mv_pci;
+
+	platform_set_drvdata(pdev, pcie);
+
+	INIT_DELAYED_WORK(&pcie->dwork, ls_pcie_g4_reset);
+
+	ret = mobiveil_pcie_host_probe(mv_pci);
+	if (ret) {
+		dev_err(dev, "fail to probe!\n");
+		return  ret;
+	}
+
+	if (!ls_pcie_g4_is_bridge(pcie))
+		return -ENODEV;
+
+	return 0;
+}
+
+static const struct of_device_id ls_pcie_g4_of_match[] = {
+	{ .compatible = "fsl,lx2160a-pcie", },
+	{ },
+};
+
+static struct platform_driver ls_pcie_g4_driver = {
+	.driver = {
+		.name = "layerscape-pcie-gen4",
+		.of_match_table = ls_pcie_g4_of_match,
+		.suppress_bind_attrs = true,
+	},
+};
+
+builtin_platform_driver_probe(ls_pcie_g4_driver, ls_pcie_g4_probe);
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
index 0f5303962e88..0ccd6cee5f8f 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
@@ -41,6 +41,8 @@
 #define  PAGE_LO_MASK			0x3ff
 #define  PAGE_SEL_OFFSET_SHIFT		10
 
+#define PAB_ACTIVITY_STAT		0x81c
+
 #define PAB_AXI_PIO_CTRL		0x0840
 #define  APIO_EN_MASK			0xf
 
@@ -49,8 +51,18 @@
 
 #define PAB_INTP_AMBA_MISC_ENB		0x0b0c
 #define PAB_INTP_AMBA_MISC_STAT		0x0b1c
-#define  PAB_INTP_INTX_MASK		0x01e0
-#define  PAB_INTP_MSI_MASK		0x8
+#define  PAB_INTP_RESET			(0x1 << 1)
+#define  PAB_INTP_MSI			(0x1 << 3)
+#define  PAB_INTP_INTA			(0x1 << 5)
+#define  PAB_INTP_INTB			(0x1 << 6)
+#define  PAB_INTP_INTC			(0x1 << 7)
+#define  PAB_INTP_INTD			(0x1 << 8)
+#define  PAB_INTP_PCIE_UE		(0x1 << 9)
+#define  PAB_INTP_IE_PMREDI		(0x1 << 29)
+#define  PAB_INTP_IE_EC			(0x1 << 30)
+#define  PAB_INTP_MSI_MASK		PAB_INTP_MSI
+#define  PAB_INTP_INTX_MASK		(PAB_INTP_INTA | PAB_INTP_INTB |\
+					PAB_INTP_INTC | PAB_INTP_INTD)
 
 #define PAB_AXI_AMAP_CTRL(win)		PAB_REG_ADDR(0x0ba0, win)
 #define  WIN_ENABLE_SHIFT		0
-- 
2.17.1


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

* [PATCHv3 24/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011577
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (22 preceding siblings ...)
  2019-01-29  8:10 ` [PATCHv3 23/27] PCI: mobiveil: add PCIe Gen4 RC driver for NXP Layerscape SoCs Z.q. Hou
@ 2019-01-29  8:11 ` Z.q. Hou
  2019-02-08 12:52   ` Subrahmanya Lingappa
  2019-01-29  8:11 ` [PATCHv3 25/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011451 Z.q. Hou
                   ` (4 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:11 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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 it will be fixed
in Rev2.0.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V3:
 - Integrated without change from http://patchwork.ozlabs.org/patch/1006790/

 .../controller/mobiveil/pci-layerscape-gen4.c | 37 +++++++++++++++++++
 .../controller/mobiveil/pcie-mobiveil-host.c  | 17 ++++++++-
 .../pci/controller/mobiveil/pcie-mobiveil.h   |  3 ++
 3 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
index 174cbcac4059..d2c5dbbd5e3c 100644
--- a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
+++ b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
@@ -22,8 +22,13 @@
 
 #include "pcie-mobiveil.h"
 
+#define REV_1_0				(0x10)
+
 /* LUT and PF control registers */
 #define PCIE_LUT_OFF			(0x80000)
+#define PCIE_LUT_GCR			(0x28)
+#define PCIE_LUT_GCR_RRE		(0)
+
 #define PCIE_PF_OFF			(0xc0000)
 #define PCIE_PF_INT_STAT		(0x18)
 #define PF_INT_STAT_PABRST		(31)
@@ -41,6 +46,7 @@ struct ls_pcie_g4 {
 	struct mobiveil_pcie *pci;
 	struct delayed_work dwork;
 	int irq;
+	u8 rev;
 };
 
 static inline u32 ls_pcie_g4_lut_readl(struct ls_pcie_g4 *pcie, u32 off)
@@ -76,6 +82,15 @@ static bool ls_pcie_g4_is_bridge(struct ls_pcie_g4 *pcie)
 	return header_type == PCI_HEADER_TYPE_BRIDGE;
 }
 
+static int ls_pcie_g4_host_init(struct mobiveil_pcie *pci)
+{
+	struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
+
+	pcie->rev = csr_readb(pci, PCI_REVISION_ID);
+
+	return 0;
+}
+
 static int ls_pcie_g4_link_up(struct mobiveil_pcie *pci)
 {
 	struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
@@ -188,12 +203,34 @@ static void ls_pcie_g4_reset(struct work_struct *work)
 	ls_pcie_g4_reinit_hw(pcie);
 }
 
+static int ls_pcie_g4_read_other_conf(struct pci_bus *bus, unsigned int devfn,
+				   int where, int size, u32 *val)
+{
+	struct mobiveil_pcie *pci = bus->sysdata;
+	struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
+	int ret;
+
+	if (pcie->rev == REV_1_0 && where == PCI_VENDOR_ID)
+		ls_pcie_g4_lut_writel(pcie, PCIE_LUT_GCR,
+				      0 << PCIE_LUT_GCR_RRE);
+
+	ret = pci_generic_config_read(bus, devfn, where, size, val);
+
+	if (pcie->rev == REV_1_0 && where == PCI_VENDOR_ID)
+		ls_pcie_g4_lut_writel(pcie, PCIE_LUT_GCR,
+				      1 << PCIE_LUT_GCR_RRE);
+
+	return ret;
+}
+
 static struct mobiveil_rp_ops ls_pcie_g4_rp_ops = {
 	.interrupt_init = ls_pcie_g4_interrupt_init,
+	.read_other_conf = ls_pcie_g4_read_other_conf,
 };
 
 static const struct mobiveil_pab_ops ls_pcie_g4_pab_ops = {
 	.link_up = ls_pcie_g4_link_up,
+	.host_init = ls_pcie_g4_host_init,
 };
 
 static int __init ls_pcie_g4_probe(struct platform_device *pdev)
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
index e8d0c4989013..5f51bc2dd6d7 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
@@ -79,9 +79,20 @@ static void __iomem *mobiveil_pcie_map_bus(struct pci_bus *bus,
 	return pcie->rp.config_axi_slave_base + where;
 }
 
+static int mobiveil_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
+				     int where, int size, u32 *val)
+{
+	struct mobiveil_pcie *pcie = bus->sysdata;
+	struct root_port *rp = &pcie->rp;
+
+	if (bus->number > rp->root_bus_nr && rp->ops->read_other_conf)
+		return rp->ops->read_other_conf(bus, devfn, where, size, val);
+
+	return pci_generic_config_read(bus, devfn, where, size, val);
+}
 static struct pci_ops mobiveil_pcie_ops = {
 	.map_bus = mobiveil_pcie_map_bus,
-	.read = pci_generic_config_read,
+	.read = mobiveil_pcie_config_read,
 	.write = pci_generic_config_write,
 };
 
@@ -309,6 +320,10 @@ int mobiveil_host_init(struct mobiveil_pcie *pcie, bool reinit)
 	value |= (PCI_CLASS_BRIDGE_PCI << 16);
 	csr_writel(pcie, value, PAB_INTP_AXI_PIO_CLASS);
 
+	/* Platform specific host init */
+	if (pcie->ops->host_init)
+		return pcie->ops->host_init(pcie);
+
 	return 0;
 }
 
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
index 0ccd6cee5f8f..ab43de5e4b2b 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
@@ -145,6 +145,8 @@ struct mobiveil_msi {			/* MSI information */
 
 struct mobiveil_rp_ops {
 	int (*interrupt_init)(struct mobiveil_pcie *pcie);
+	int (*read_other_conf)(struct pci_bus *bus, unsigned int devfn,
+			       int where, int size, u32 *val);
 };
 
 struct root_port {
@@ -160,6 +162,7 @@ struct root_port {
 
 struct mobiveil_pab_ops {
 	int (*link_up)(struct mobiveil_pcie *pcie);
+	int (*host_init)(struct mobiveil_pcie *pcie);
 };
 
 struct mobiveil_pcie {
-- 
2.17.1


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

* [PATCHv3 25/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011451
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (23 preceding siblings ...)
  2019-01-29  8:11 ` [PATCHv3 24/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011577 Z.q. Hou
@ 2019-01-29  8:11 ` Z.q. Hou
  2019-02-08 12:53   ` Subrahmanya Lingappa
  2019-01-29  8:11 ` [PATCHv3 26/27] arm64: dts: freescale: lx2160a: add pcie DT nodes Z.q. Hou
                   ` (3 subsequent siblings)
  28 siblings, 1 reply; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:11 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

When LX2 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 LX2 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 patch implemented part 1, the part 2 can be set by kernel parameter
'pci=pcie_bus_perf'

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

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V3:
 - Integrated without change from http://patchwork.ozlabs.org/patch/1006796/

 .../pci/controller/mobiveil/pci-layerscape-gen4.c | 15 +++++++++++++++
 drivers/pci/controller/mobiveil/pcie-mobiveil.h   |  4 ++++
 2 files changed, 19 insertions(+)

diff --git a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
index d2c5dbbd5e3c..20ce146788ca 100644
--- a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
+++ b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
@@ -82,12 +82,27 @@ static bool ls_pcie_g4_is_bridge(struct ls_pcie_g4 *pcie)
 	return header_type == PCI_HEADER_TYPE_BRIDGE;
 }
 
+static void workaround_A011451(struct ls_pcie_g4 *pcie)
+{
+	struct mobiveil_pcie *mv_pci = pcie->pci;
+	u32 val;
+
+	/* Set ACK latency timeout */
+	val = csr_readl(mv_pci, GPEX_ACK_REPLAY_TO);
+	val &= ~(ACK_LAT_TO_VAL_MASK << ACK_LAT_TO_VAL_SHIFT);
+	val |= (4 << ACK_LAT_TO_VAL_SHIFT);
+	csr_writel(mv_pci, val, GPEX_ACK_REPLAY_TO);
+}
+
 static int ls_pcie_g4_host_init(struct mobiveil_pcie *pci)
 {
 	struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
 
 	pcie->rev = csr_readb(pci, PCI_REVISION_ID);
 
+	if (pcie->rev == REV_1_0)
+		workaround_A011451(pcie);
+
 	return 0;
 }
 
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
index ab43de5e4b2b..f0e2e4ae09b5 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
@@ -85,6 +85,10 @@
 #define PAB_AXI_AMAP_PEX_WIN_H(win)	PAB_REG_ADDR(0x0bac, win)
 #define PAB_INTP_AXI_PIO_CLASS		0x474
 
+#define GPEX_ACK_REPLAY_TO		0x438
+#define  ACK_LAT_TO_VAL_MASK		0x1fff
+#define  ACK_LAT_TO_VAL_SHIFT		0
+
 #define PAB_PEX_AMAP_CTRL(win)		PAB_REG_ADDR(0x4ba0, win)
 #define  AMAP_CTRL_EN_SHIFT		0
 #define  AMAP_CTRL_TYPE_SHIFT		1
-- 
2.17.1


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

* [PATCHv3 26/27] arm64: dts: freescale: lx2160a: add pcie DT nodes
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (24 preceding siblings ...)
  2019-01-29  8:11 ` [PATCHv3 25/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011451 Z.q. Hou
@ 2019-01-29  8:11 ` Z.q. Hou
  2019-01-29  8:11 ` [PATCHv3 27/27] arm64: defconfig: Enable CONFIG_PCI_LAYERSCAPE_GEN4 Z.q. Hou
                   ` (2 subsequent siblings)
  28 siblings, 0 replies; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:11 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

The LX2160A integrated 6 PCIe Gen4 controllers.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 .../arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 163 ++++++++++++++++++
 1 file changed, 163 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index 3f6521c47f51..8f687a3ef185 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -882,5 +882,168 @@
 				};
 			};
 		};
+
+		pcie@3400000 {
+			compatible = "fsl,lx2160a-pcie";
+			reg = <0x00 0x03400000 0x0 0x00100000   /* controller registers */
+			       0x80 0x00000000 0x0 0x00001000>; /* configuration space */
+			reg-names = "csr_axi_slave", "config_axi_slave";
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */
+				     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */
+				     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
+			interrupt-names = "aer", "pme", "intr";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			dma-coherent;
+			apio-wins = <8>;
+			ppio-wins = <8>;
+			bus-range = <0x0 0xff>;
+			ranges = <0x82000000 0x0 0x40000000 0x80 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+			msi-parent = <&its>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 2 &gic 0 0 GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 3 &gic 0 0 GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 4 &gic 0 0 GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		pcie@3500000 {
+			compatible = "fsl,lx2160a-pcie";
+			reg = <0x00 0x03500000 0x0 0x00100000   /* controller registers */
+			       0x88 0x00000000 0x0 0x00001000>; /* configuration space */
+			reg-names = "csr_axi_slave", "config_axi_slave";
+			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */
+				     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */
+				     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
+			interrupt-names = "aer", "pme", "intr";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			dma-coherent;
+			apio-wins = <8>;
+			ppio-wins = <8>;
+			bus-range = <0x0 0xff>;
+			ranges = <0x82000000 0x0 0x40000000 0x88 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+			msi-parent = <&its>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 2 &gic 0 0 GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 3 &gic 0 0 GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 4 &gic 0 0 GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		pcie@3600000 {
+			compatible = "fsl,lx2160a-pcie";
+			reg = <0x00 0x03600000 0x0 0x00100000   /* controller registers */
+			       0x90 0x00000000 0x0 0x00001000>; /* configuration space */
+			reg-names = "csr_axi_slave", "config_axi_slave";
+			interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */
+				     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */
+				     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
+			interrupt-names = "aer", "pme", "intr";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			dma-coherent;
+			apio-wins = <256>;
+			ppio-wins = <24>;
+			bus-range = <0x0 0xff>;
+			ranges = <0x82000000 0x0 0x40000000 0x90 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+			msi-parent = <&its>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 2 &gic 0 0 GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 3 &gic 0 0 GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 4 &gic 0 0 GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		pcie@3700000 {
+			compatible = "fsl,lx2160a-pcie";
+			reg = <0x00 0x03700000 0x0 0x00100000   /* controller registers */
+			       0x98 0x00000000 0x0 0x00001000>; /* configuration space */
+			reg-names = "csr_axi_slave", "config_axi_slave";
+			interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */
+				     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */
+				     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
+			interrupt-names = "aer", "pme", "intr";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			dma-coherent;
+			apio-wins = <8>;
+			ppio-wins = <8>;
+			bus-range = <0x0 0xff>;
+			ranges = <0x82000000 0x0 0x40000000 0x98 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+			msi-parent = <&its>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 2 &gic 0 0 GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 3 &gic 0 0 GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 4 &gic 0 0 GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		pcie@3800000 {
+			compatible = "fsl,lx2160a-pcie";
+			reg = <0x00 0x03800000 0x0 0x00100000   /* controller registers */
+			       0xa0 0x00000000 0x0 0x00001000>; /* configuration space */
+			reg-names = "csr_axi_slave", "config_axi_slave";
+			interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */
+				     <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */
+				     <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
+			interrupt-names = "aer", "pme", "intr";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			dma-coherent;
+			apio-wins = <256>;
+			ppio-wins = <24>;
+			bus-range = <0x0 0xff>;
+			ranges = <0x82000000 0x0 0x40000000 0xa0 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+			msi-parent = <&its>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 2 &gic 0 0 GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 3 &gic 0 0 GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 4 &gic 0 0 GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		pcie@3900000 {
+			compatible = "fsl,lx2160a-pcie";
+			reg = <0x00 0x03900000 0x0 0x00100000   /* controller registers */
+			       0xa8 0x00000000 0x0 0x00001000>; /* configuration space */
+			reg-names = "csr_axi_slave", "config_axi_slave";
+			interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */
+				     <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */
+				     <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
+			interrupt-names = "aer", "pme", "intr";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			dma-coherent;
+			apio-wins = <8>;
+			ppio-wins = <8>;
+			bus-range = <0x0 0xff>;
+			ranges = <0x82000000 0x0 0x40000000 0xa8 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+			msi-parent = <&its>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 2 &gic 0 0 GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 3 &gic 0 0 GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+					<0000 0 0 4 &gic 0 0 GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
 	};
 };
-- 
2.17.1


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

* [PATCHv3 27/27] arm64: defconfig: Enable CONFIG_PCI_LAYERSCAPE_GEN4
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (25 preceding siblings ...)
  2019-01-29  8:11 ` [PATCHv3 26/27] arm64: dts: freescale: lx2160a: add pcie DT nodes Z.q. Hou
@ 2019-01-29  8:11 ` Z.q. Hou
  2019-01-29 11:39 ` [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Lorenzo Pieralisi
  2019-01-30 15:34 ` Bjorn Helgaas
  28 siblings, 0 replies; 68+ messages in thread
From: Z.q. Hou @ 2019-01-29  8:11 UTC (permalink / raw)
  To: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon
  Cc: Mingkai Hu, M.h. Lian, Xiaowei Bao, Z.q. Hou

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

Enable the PCIe Gen4 controller driver for Layerscape SoCs.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
V3:
 - No change

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 6e5af2563ef5..5363c1fdce2e 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -82,6 +82,7 @@ CONFIG_PCI_HOST_THUNDER_PEM=y
 CONFIG_PCI_HOST_THUNDER_ECAM=y
 CONFIG_PCIE_ROCKCHIP_HOST=m
 CONFIG_PCI_LAYERSCAPE=y
+CONFIG_PCI_LAYERSCAPE_GEN4=y
 CONFIG_PCI_HISI=y
 CONFIG_PCIE_QCOM=y
 CONFIG_PCIE_ARMADA_8K=y
-- 
2.17.1


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

* Re: [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (26 preceding siblings ...)
  2019-01-29  8:11 ` [PATCHv3 27/27] arm64: defconfig: Enable CONFIG_PCI_LAYERSCAPE_GEN4 Z.q. Hou
@ 2019-01-29 11:39 ` Lorenzo Pieralisi
       [not found]   ` <CAFZiPx002HED+YH2GysS7a7uoEDQuHGjxa_CQtwb9nSDH-XNuA@mail.gmail.com>
  2019-01-30 15:34 ` Bjorn Helgaas
  28 siblings, 1 reply; 68+ messages in thread
From: Lorenzo Pieralisi @ 2019-01-29 11:39 UTC (permalink / raw)
  To: Z.q. Hou, l.subrahmanya
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, catalin.marinas,
	will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

On Tue, Jan 29, 2019 at 08:08:28AM +0000, Z.q. Hou wrote:
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> 
> This patch set is aim to refactor the Mobiveil driver and add
> PCIe support for NXP Layerscape series SoCs integrated Mobiveil's
> PCIe Gen4 controller.
> 
> Hou Zhiqiang (27):
>   PCI: mobiveil: uniform the register accessors
>   PCI: mobiveil: format the code without function change
>   PCI: mobiveil: correct the returned error number
>   PCI: mobiveil: remove flag MSI_FLAG_MULTI_PCI_MSI
>   PCI: mobiveil: correct PCI base address in MEM/IO outbound windows
>   PCI: mobiveil: replace the resource list iteration function
>   PCI: mobiveil: use WIN_NUM_0 explicitly for CFG outbound window
>   PCI: mobiveil: use the 1st inbound window for MEM inbound transactions
>   PCI: mobiveil: correct inbound/outbound window setup routines
>   PCI: mobiveil: fix the INTx process error
>   PCI: mobiveil: only fix up the Class Code field
>   PCI: mobiveil: move out the link up waiting from mobiveil_host_init
>   PCI: mobiveil: move irq chained handler setup out of DT parse
>   PCI: mobiveil: initialize Primary/Secondary/Subordinate bus number
>   dt-bindings: pci: mobiveil: change gpio_slave and apb_csr to optional
>   PCI: mobiveil: refactor Mobiveil PCIe Host Bridge IP driver
>   PCI: mobiveil: fix the checking of valid device
>   PCI: mobiveil: continue to initialize the host upon no PCIe link
>   PCI: mobiveil: disabled IB and OB windows set by bootloader
>   PCI: mobiveil: add Byte and Half-Word width register accessors
>   PCI: mobiveil: make mobiveil_host_init can be used to re-init host
>   dt-bindings: pci: Add NXP Layerscape SoCs PCIe Gen4 controller
>   PCI: mobiveil: add PCIe Gen4 RC driver for NXP Layerscape SoCs
>   PCI: mobiveil: ls_pcie_g4: add Workaround for A-011577
>   PCI: mobiveil: ls_pcie_g4: add Workaround for A-011451
>   arm64: dts: freescale: lx2160a: add pcie DT nodes
>   arm64: defconfig: Enable CONFIG_PCI_LAYERSCAPE_GEN4

Subrahmanya,

Either you review this series or I will have to drop you from
the MAINTAINERS list for this driver, I am sorry but I asked you
before to no avail.

Thanks,
Lorenzo

>  .../bindings/pci/layerscape-pci-gen4.txt      |  52 ++
>  .../devicetree/bindings/pci/mobiveil-pcie.txt |   2 +
>  MAINTAINERS                                   |  10 +-
>  .../arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 163 ++++
>  arch/arm64/configs/defconfig                  |   1 +
>  drivers/pci/controller/Kconfig                |  11 +-
>  drivers/pci/controller/Makefile               |   2 +-
>  drivers/pci/controller/mobiveil/Kconfig       |  34 +
>  drivers/pci/controller/mobiveil/Makefile      |   5 +
>  .../controller/mobiveil/pci-layerscape-gen4.c | 306 +++++++
>  .../controller/mobiveil/pcie-mobiveil-host.c  | 640 +++++++++++++
>  .../controller/mobiveil/pcie-mobiveil-plat.c  |  54 ++
>  .../pci/controller/mobiveil/pcie-mobiveil.c   | 246 +++++
>  .../pci/controller/mobiveil/pcie-mobiveil.h   | 229 +++++
>  drivers/pci/controller/pcie-mobiveil.c        | 861 ------------------
>  15 files changed, 1743 insertions(+), 873 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pci/layerscape-pci-gen4.txt
>  create mode 100644 drivers/pci/controller/mobiveil/Kconfig
>  create mode 100644 drivers/pci/controller/mobiveil/Makefile
>  create mode 100644 drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
>  create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
>  create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
>  create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.c
>  create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.h
>  delete mode 100644 drivers/pci/controller/pcie-mobiveil.c
> 
> -- 
> 2.17.1
> 

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

* Re: [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs
  2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
                   ` (27 preceding siblings ...)
  2019-01-29 11:39 ` [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Lorenzo Pieralisi
@ 2019-01-30 15:34 ` Bjorn Helgaas
  28 siblings, 0 replies; 68+ messages in thread
From: Bjorn Helgaas @ 2019-01-30 15:34 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, robh+dt,
	mark.rutland, l.subrahmanya, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, M.h. Lian, Xiaowei Bao, Mingkai Hu

On Tue, Jan 29, 2019 at 08:08:28AM +0000, Z.q. Hou wrote:
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> 
> This patch set is aim to refactor the Mobiveil driver and add
> PCIe support for NXP Layerscape series SoCs integrated Mobiveil's
> PCIe Gen4 controller.
> 
> Hou Zhiqiang (27):
>   PCI: mobiveil: uniform the register accessors
>   PCI: mobiveil: format the code without function change
>   PCI: mobiveil: correct the returned error number
>   PCI: mobiveil: remove flag MSI_FLAG_MULTI_PCI_MSI
>   PCI: mobiveil: correct PCI base address in MEM/IO outbound windows
>   PCI: mobiveil: replace the resource list iteration function
>   PCI: mobiveil: use WIN_NUM_0 explicitly for CFG outbound window
>   PCI: mobiveil: use the 1st inbound window for MEM inbound transactions
>   PCI: mobiveil: correct inbound/outbound window setup routines
>   PCI: mobiveil: fix the INTx process error
>   PCI: mobiveil: only fix up the Class Code field
>   PCI: mobiveil: move out the link up waiting from mobiveil_host_init
>   PCI: mobiveil: move irq chained handler setup out of DT parse
>   PCI: mobiveil: initialize Primary/Secondary/Subordinate bus number
>   dt-bindings: pci: mobiveil: change gpio_slave and apb_csr to optional
>   PCI: mobiveil: refactor Mobiveil PCIe Host Bridge IP driver
>   PCI: mobiveil: fix the checking of valid device
>   PCI: mobiveil: continue to initialize the host upon no PCIe link
>   PCI: mobiveil: disabled IB and OB windows set by bootloader
>   PCI: mobiveil: add Byte and Half-Word width register accessors
>   PCI: mobiveil: make mobiveil_host_init can be used to re-init host
>   dt-bindings: pci: Add NXP Layerscape SoCs PCIe Gen4 controller
>   PCI: mobiveil: add PCIe Gen4 RC driver for NXP Layerscape SoCs
>   PCI: mobiveil: ls_pcie_g4: add Workaround for A-011577
>   PCI: mobiveil: ls_pcie_g4: add Workaround for A-011451
>   arm64: dts: freescale: lx2160a: add pcie DT nodes
>   arm64: defconfig: Enable CONFIG_PCI_LAYERSCAPE_GEN4

If/when you repost this, please pay attention to the changelog
conventions, e.g., capitalize the first word of the sentence ("Remove
flag ...", "Correct PCI base address ...", etc), capitalize acronyms
like "PCI" and "IRQ", use parentheses after function names, etc.  You
can see the conventions by running "git log --oneline
drivers/pci/controller".

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

* Re: [PATCHv3 22/27] dt-bindings: pci: Add NXP Layerscape SoCs PCIe Gen4  controller
  2019-01-29  8:10 ` [PATCHv3 22/27] dt-bindings: pci: Add NXP Layerscape SoCs PCIe Gen4 controller Z.q. Hou
@ 2019-01-30 18:49   ` Rob Herring
  0 siblings, 0 replies; 68+ messages in thread
From: Rob Herring @ 2019-01-30 18:49 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, l.subrahmanya, shawnguo, Leo Li,
	lorenzo.pieralisi, catalin.marinas, will.deacon, Mingkai Hu,
	M.h. Lian, Xiaowei Bao, Z.q. Hou

On Tue, 29 Jan 2019 08:10:49 +0000, "Z.q. Hou" wrote:
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> 
> Add PCIe Gen4 controller DT bindings of NXP Layerscape SoCs.
> 
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> ---
> V3:
>  - Change back to use an new doc for Layerscape PCIe Gen4 DT bindings.
>  - Switch the order of "csr_axi_slave" and "config_axi_slave".
> 
>  .../bindings/pci/layerscape-pci-gen4.txt      | 52 +++++++++++++++++++
>  MAINTAINERS                                   |  8 +++
>  2 files changed, 60 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/layerscape-pci-gen4.txt
> 

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs
       [not found]   ` <CAFZiPx002HED+YH2GysS7a7uoEDQuHGjxa_CQtwb9nSDH-XNuA@mail.gmail.com>
@ 2019-02-04 16:13     ` Lorenzo Pieralisi
  2019-02-04 16:51       ` Subrahmanya Lingappa
  0 siblings, 1 reply; 68+ messages in thread
From: Lorenzo Pieralisi @ 2019-02-04 16:13 UTC (permalink / raw)
  To: Subrahmanya Lingappa
  Cc: Z.q. Hou, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	bhelgaas, robh+dt, mark.rutland, shawnguo, Leo Li,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

On Mon, Feb 04, 2019 at 07:44:25PM +0530, Subrahmanya Lingappa wrote:
>    Bjorn,
>    My apologies, I was away for a while from this work.
>    I am starting to review now.

Hi,

I am not Bjorn and as I told you before you should not reply
with html context (ie use plain text, the public lists will
reject your emails otherwise) and top-post.

You are supposed to maintain this code, if you can't it is fine but I
should know because there are developers who are waiting for your
review, please understand.

Thanks,
Lorenzo

>    Thanks,
>    ~subbu
>    On Tue, Jan 29, 2019 at 5:09 PM Lorenzo Pieralisi
>    <lorenzo.pieralisi@arm.com> wrote:
> 
>      On Tue, Jan 29, 2019 at 08:08:28AM +0000, Z.q. Hou wrote:
>      > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>      >
>      > This patch set is aim to refactor the Mobiveil driver and add
>      > PCIe support for NXP Layerscape series SoCs integrated Mobiveil's
>      > PCIe Gen4 controller.
>      >
>      > Hou Zhiqiang (27):
>      >   PCI: mobiveil: uniform the register accessors
>      >   PCI: mobiveil: format the code without function change
>      >   PCI: mobiveil: correct the returned error number
>      >   PCI: mobiveil: remove flag MSI_FLAG_MULTI_PCI_MSI
>      >   PCI: mobiveil: correct PCI base address in MEM/IO outbound windows
>      >   PCI: mobiveil: replace the resource list iteration function
>      >   PCI: mobiveil: use WIN_NUM_0 explicitly for CFG outbound window
>      >   PCI: mobiveil: use the 1st inbound window for MEM inbound
>      transactions
>      >   PCI: mobiveil: correct inbound/outbound window setup routines
>      >   PCI: mobiveil: fix the INTx process error
>      >   PCI: mobiveil: only fix up the Class Code field
>      >   PCI: mobiveil: move out the link up waiting from mobiveil_host_init
>      >   PCI: mobiveil: move irq chained handler setup out of DT parse
>      >   PCI: mobiveil: initialize Primary/Secondary/Subordinate bus number
>      >   dt-bindings: pci: mobiveil: change gpio_slave and apb_csr to
>      optional
>      >   PCI: mobiveil: refactor Mobiveil PCIe Host Bridge IP driver
>      >   PCI: mobiveil: fix the checking of valid device
>      >   PCI: mobiveil: continue to initialize the host upon no PCIe link
>      >   PCI: mobiveil: disabled IB and OB windows set by bootloader
>      >   PCI: mobiveil: add Byte and Half-Word width register accessors
>      >   PCI: mobiveil: make mobiveil_host_init can be used to re-init host
>      >   dt-bindings: pci: Add NXP Layerscape SoCs PCIe Gen4 controller
>      >   PCI: mobiveil: add PCIe Gen4 RC driver for NXP Layerscape SoCs
>      >   PCI: mobiveil: ls_pcie_g4: add Workaround for A-011577
>      >   PCI: mobiveil: ls_pcie_g4: add Workaround for A-011451
>      >   arm64: dts: freescale: lx2160a: add pcie DT nodes
>      >   arm64: defconfig: Enable CONFIG_PCI_LAYERSCAPE_GEN4
> 
>      Subrahmanya,
> 
>      Either you review this series or I will have to drop you from
>      the MAINTAINERS list for this driver, I am sorry but I asked you
>      before to no avail.
> 
>      Thanks,
>      Lorenzo
> 
>      >  .../bindings/pci/layerscape-pci-gen4.txt      |  52 ++
>      >  .../devicetree/bindings/pci/mobiveil-pcie.txt |   2 +
>      >  MAINTAINERS                                   |  10 +-
>      >  .../arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 163 ++++
>      >  arch/arm64/configs/defconfig                  |   1 +
>      >  drivers/pci/controller/Kconfig                |  11 +-
>      >  drivers/pci/controller/Makefile               |   2 +-
>      >  drivers/pci/controller/mobiveil/Kconfig       |  34 +
>      >  drivers/pci/controller/mobiveil/Makefile      |   5 +
>      >  .../controller/mobiveil/pci-layerscape-gen4.c | 306 +++++++
>      >  .../controller/mobiveil/pcie-mobiveil-host.c  | 640 +++++++++++++
>      >  .../controller/mobiveil/pcie-mobiveil-plat.c  |  54 ++
>      >  .../pci/controller/mobiveil/pcie-mobiveil.c   | 246 +++++
>      >  .../pci/controller/mobiveil/pcie-mobiveil.h   | 229 +++++
>      >  drivers/pci/controller/pcie-mobiveil.c        | 861
>      ------------------
>      >  15 files changed, 1743 insertions(+), 873 deletions(-)
>      >  create mode 100644
>      Documentation/devicetree/bindings/pci/layerscape-pci-gen4.txt
>      >  create mode 100644 drivers/pci/controller/mobiveil/Kconfig
>      >  create mode 100644 drivers/pci/controller/mobiveil/Makefile
>      >  create mode 100644
>      drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
>      >  create mode 100644
>      drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
>      >  create mode 100644
>      drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
>      >  create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.c
>      >  create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.h
>      >  delete mode 100644 drivers/pci/controller/pcie-mobiveil.c
>      >
>      > --
>      > 2.17.1
>      >

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

* Re: [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs
  2019-02-04 16:13     ` Lorenzo Pieralisi
@ 2019-02-04 16:51       ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-04 16:51 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Z.q. Hou, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	bhelgaas, robh+dt, mark.rutland, shawnguo, Leo Li,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Lorenzo,
My apologies again,

I have started looking into these.

Thanks,




On Mon, Feb 4, 2019 at 9:43 PM Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
>
> On Mon, Feb 04, 2019 at 07:44:25PM +0530, Subrahmanya Lingappa wrote:
> >    Bjorn,
> >    My apologies, I was away for a while from this work.
> >    I am starting to review now.
>
> Hi,
>
> I am not Bjorn and as I told you before you should not reply
> with html context (ie use plain text, the public lists will
> reject your emails otherwise) and top-post.
>
> You are supposed to maintain this code, if you can't it is fine but I
> should know because there are developers who are waiting for your
> review, please understand.
>
> Thanks,
> Lorenzo
>
> >    Thanks,
> >    ~subbu
> >    On Tue, Jan 29, 2019 at 5:09 PM Lorenzo Pieralisi
> >    <lorenzo.pieralisi@arm.com> wrote:
> >
> >      On Tue, Jan 29, 2019 at 08:08:28AM +0000, Z.q. Hou wrote:
> >      > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> >      >
> >      > This patch set is aim to refactor the Mobiveil driver and add
> >      > PCIe support for NXP Layerscape series SoCs integrated Mobiveil's
> >      > PCIe Gen4 controller.
> >      >
> >      > Hou Zhiqiang (27):
> >      >   PCI: mobiveil: uniform the register accessors
> >      >   PCI: mobiveil: format the code without function change
> >      >   PCI: mobiveil: correct the returned error number
> >      >   PCI: mobiveil: remove flag MSI_FLAG_MULTI_PCI_MSI
> >      >   PCI: mobiveil: correct PCI base address in MEM/IO outbound windows
> >      >   PCI: mobiveil: replace the resource list iteration function
> >      >   PCI: mobiveil: use WIN_NUM_0 explicitly for CFG outbound window
> >      >   PCI: mobiveil: use the 1st inbound window for MEM inbound
> >      transactions
> >      >   PCI: mobiveil: correct inbound/outbound window setup routines
> >      >   PCI: mobiveil: fix the INTx process error
> >      >   PCI: mobiveil: only fix up the Class Code field
> >      >   PCI: mobiveil: move out the link up waiting from mobiveil_host_init
> >      >   PCI: mobiveil: move irq chained handler setup out of DT parse
> >      >   PCI: mobiveil: initialize Primary/Secondary/Subordinate bus number
> >      >   dt-bindings: pci: mobiveil: change gpio_slave and apb_csr to
> >      optional
> >      >   PCI: mobiveil: refactor Mobiveil PCIe Host Bridge IP driver
> >      >   PCI: mobiveil: fix the checking of valid device
> >      >   PCI: mobiveil: continue to initialize the host upon no PCIe link
> >      >   PCI: mobiveil: disabled IB and OB windows set by bootloader
> >      >   PCI: mobiveil: add Byte and Half-Word width register accessors
> >      >   PCI: mobiveil: make mobiveil_host_init can be used to re-init host
> >      >   dt-bindings: pci: Add NXP Layerscape SoCs PCIe Gen4 controller
> >      >   PCI: mobiveil: add PCIe Gen4 RC driver for NXP Layerscape SoCs
> >      >   PCI: mobiveil: ls_pcie_g4: add Workaround for A-011577
> >      >   PCI: mobiveil: ls_pcie_g4: add Workaround for A-011451
> >      >   arm64: dts: freescale: lx2160a: add pcie DT nodes
> >      >   arm64: defconfig: Enable CONFIG_PCI_LAYERSCAPE_GEN4
> >
> >      Subrahmanya,
> >
> >      Either you review this series or I will have to drop you from
> >      the MAINTAINERS list for this driver, I am sorry but I asked you
> >      before to no avail.
> >
> >      Thanks,
> >      Lorenzo
> >
> >      >  .../bindings/pci/layerscape-pci-gen4.txt      |  52 ++
> >      >  .../devicetree/bindings/pci/mobiveil-pcie.txt |   2 +
> >      >  MAINTAINERS                                   |  10 +-
> >      >  .../arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 163 ++++
> >      >  arch/arm64/configs/defconfig                  |   1 +
> >      >  drivers/pci/controller/Kconfig                |  11 +-
> >      >  drivers/pci/controller/Makefile               |   2 +-
> >      >  drivers/pci/controller/mobiveil/Kconfig       |  34 +
> >      >  drivers/pci/controller/mobiveil/Makefile      |   5 +
> >      >  .../controller/mobiveil/pci-layerscape-gen4.c | 306 +++++++
> >      >  .../controller/mobiveil/pcie-mobiveil-host.c  | 640 +++++++++++++
> >      >  .../controller/mobiveil/pcie-mobiveil-plat.c  |  54 ++
> >      >  .../pci/controller/mobiveil/pcie-mobiveil.c   | 246 +++++
> >      >  .../pci/controller/mobiveil/pcie-mobiveil.h   | 229 +++++
> >      >  drivers/pci/controller/pcie-mobiveil.c        | 861
> >      ------------------
> >      >  15 files changed, 1743 insertions(+), 873 deletions(-)
> >      >  create mode 100644
> >      Documentation/devicetree/bindings/pci/layerscape-pci-gen4.txt
> >      >  create mode 100644 drivers/pci/controller/mobiveil/Kconfig
> >      >  create mode 100644 drivers/pci/controller/mobiveil/Makefile
> >      >  create mode 100644
> >      drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> >      >  create mode 100644
> >      drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> >      >  create mode 100644
> >      drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
> >      >  create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.c
> >      >  create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.h
> >      >  delete mode 100644 drivers/pci/controller/pcie-mobiveil.c
> >      >
> >      > --
> >      > 2.17.1
> >      >

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

* Re: [PATCHv3 01/27] PCI: mobiveil: uniform the register accessors
  2019-01-29  8:08 ` [PATCHv3 01/27] PCI: mobiveil: uniform the register accessors Z.q. Hou
@ 2019-02-05  5:39   ` Subrahmanya Lingappa
  2019-02-05 17:43     ` Lorenzo Pieralisi
  0 siblings, 1 reply; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-05  5:39 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>



On Tue, Jan 29, 2019 at 1:38 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> It's confused that R/W some registers by csr_readl()/csr_writel(),
> while others by read_paged_register()/write_paged_register().
> Actually the low 3KB of 4KB PCIe configure space can be accessed
> directly and high 1KB is paging area. So this patch uniformed the
> register accessors to csr_readl() and csr_writel() by comparing
> the register offset with page access boundary 3KB in the accessor
> internal.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 179 +++++++++++++++++--------
>  1 file changed, 124 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index 77052a0712d0..d55c7e780c6e 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -47,7 +47,6 @@
>  #define  PAGE_SEL_SHIFT        13
>  #define  PAGE_SEL_MASK         0x3f
>  #define  PAGE_LO_MASK          0x3ff
> -#define  PAGE_SEL_EN           0xc00
>  #define  PAGE_SEL_OFFSET_SHIFT 10
>
>  #define PAB_AXI_PIO_CTRL       0x0840
> @@ -117,6 +116,12 @@
>  #define LINK_WAIT_MIN  90000
>  #define LINK_WAIT_MAX  100000
>
> +#define PAGED_ADDR_BNDRY                       0xc00
> +#define OFFSET_TO_PAGE_ADDR(off)               \
> +       ((off & PAGE_LO_MASK) | PAGED_ADDR_BNDRY)
> +#define OFFSET_TO_PAGE_IDX(off)                        \
> +       ((off >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK)
> +
>  struct mobiveil_msi {                  /* MSI information */
>         struct mutex lock;              /* protect bitmap variable */
>         struct irq_domain *msi_domain;
> @@ -145,15 +150,119 @@ struct mobiveil_pcie {
>         struct mobiveil_msi msi;
>  };
>
> -static inline void csr_writel(struct mobiveil_pcie *pcie, const u32 value,
> -               const u32 reg)
> +/*
> + * mobiveil_pcie_sel_page - routine to access paged register
> + *
> + * Registers whose address greater than PAGED_ADDR_BNDRY (0xc00) are paged,
> + * for this scheme to work extracted higher 6 bits of the offset will be
> + * written to pg_sel field of PAB_CTRL register and rest of the lower 10
> + * bits enabled with PAGED_ADDR_BNDRY are used as offset of the register.
> + */
> +static void mobiveil_pcie_sel_page(struct mobiveil_pcie *pcie, u8 pg_idx)
>  {
> -       writel_relaxed(value, pcie->csr_axi_slave_base + reg);
> +       u32 val;
> +
> +       val = readl(pcie->csr_axi_slave_base + PAB_CTRL);
> +       val &= ~(PAGE_SEL_MASK << PAGE_SEL_SHIFT);
> +       val |= (pg_idx & PAGE_SEL_MASK) << PAGE_SEL_SHIFT;
> +
> +       writel(val, pcie->csr_axi_slave_base + PAB_CTRL);
>  }
>
> -static inline u32 csr_readl(struct mobiveil_pcie *pcie, const u32 reg)
> +static void *mobiveil_pcie_comp_addr(struct mobiveil_pcie *pcie, u32 off)
>  {
> -       return readl_relaxed(pcie->csr_axi_slave_base + reg);
> +       if (off < PAGED_ADDR_BNDRY) {
> +               /* For directly accessed registers, clear the pg_sel field */
> +               mobiveil_pcie_sel_page(pcie, 0);
> +               return pcie->csr_axi_slave_base + off;
> +       }
> +
> +       mobiveil_pcie_sel_page(pcie, OFFSET_TO_PAGE_IDX(off));
> +       return pcie->csr_axi_slave_base + OFFSET_TO_PAGE_ADDR(off);
> +}
> +
> +static int mobiveil_pcie_read(void __iomem *addr, int size, u32 *val)
> +{
> +       if ((uintptr_t)addr & (size - 1)) {
> +               *val = 0;
> +               return PCIBIOS_BAD_REGISTER_NUMBER;
> +       }
> +
> +       switch (size) {
> +       case 4:
> +               *val = readl(addr);
> +               break;
> +       case 2:
> +               *val = readw(addr);
> +               break;
> +       case 1:
> +               *val = readb(addr);
> +               break;
> +       default:
> +               *val = 0;
> +               return PCIBIOS_BAD_REGISTER_NUMBER;
> +       }
> +
> +       return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static int mobiveil_pcie_write(void __iomem *addr, int size, u32 val)
> +{
> +       if ((uintptr_t)addr & (size - 1))
> +               return PCIBIOS_BAD_REGISTER_NUMBER;
> +
> +       switch (size) {
> +       case 4:
> +               writel(val, addr);
> +               break;
> +       case 2:
> +               writew(val, addr);
> +               break;
> +       case 1:
> +               writeb(val, addr);
> +               break;
> +       default:
> +               return PCIBIOS_BAD_REGISTER_NUMBER;
> +       }
> +
> +       return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static u32 csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size)
> +{
> +       void *addr;
> +       u32 val;
> +       int ret;
> +
> +       addr = mobiveil_pcie_comp_addr(pcie, off);
> +
> +       ret = mobiveil_pcie_read(addr, size, &val);
> +       if (ret)
> +               dev_err(&pcie->pdev->dev, "read CSR address failed\n");
> +
> +       return val;
> +}
> +
> +static void csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, size_t size)
> +{
> +       void *addr;
> +       int ret;
> +
> +       addr = mobiveil_pcie_comp_addr(pcie, off);
> +
> +       ret = mobiveil_pcie_write(addr, size, val);
> +       if (ret)
> +               dev_err(&pcie->pdev->dev, "write CSR address failed\n");
> +}
> +
> +static u32 csr_readl(struct mobiveil_pcie *pcie, u32 off)
> +{
> +       return csr_read(pcie, off, 0x4);
> +}
> +
> +static void csr_writel(struct mobiveil_pcie *pcie, u32 val, u32 off)
> +{
> +       csr_write(pcie, val, off, 0x4);
>  }
>
>  static bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie)
> @@ -342,45 +451,6 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
>         return 0;
>  }
>
> -/*
> - * select_paged_register - routine to access paged register of root complex
> - *
> - * registers of RC are paged, for this scheme to work
> - * extracted higher 6 bits of the offset will be written to pg_sel
> - * field of PAB_CTRL register and rest of the lower 10 bits enabled with
> - * PAGE_SEL_EN are used as offset of the register.
> - */
> -static void select_paged_register(struct mobiveil_pcie *pcie, u32 offset)
> -{
> -       int pab_ctrl_dw, pg_sel;
> -
> -       /* clear pg_sel field */
> -       pab_ctrl_dw = csr_readl(pcie, PAB_CTRL);
> -       pab_ctrl_dw = (pab_ctrl_dw & ~(PAGE_SEL_MASK << PAGE_SEL_SHIFT));
> -
> -       /* set pg_sel field */
> -       pg_sel = (offset >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK;
> -       pab_ctrl_dw |= ((pg_sel << PAGE_SEL_SHIFT));
> -       csr_writel(pcie, pab_ctrl_dw, PAB_CTRL);
> -}
> -
> -static void write_paged_register(struct mobiveil_pcie *pcie,
> -               u32 val, u32 offset)
> -{
> -       u32 off = (offset & PAGE_LO_MASK) | PAGE_SEL_EN;
> -
> -       select_paged_register(pcie, offset);
> -       csr_writel(pcie, val, off);
> -}
> -
> -static u32 read_paged_register(struct mobiveil_pcie *pcie, u32 offset)
> -{
> -       u32 off = (offset & PAGE_LO_MASK) | PAGE_SEL_EN;
> -
> -       select_paged_register(pcie, offset);
> -       return csr_readl(pcie, off);
> -}
> -
>  static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
>                 int pci_addr, u32 type, u64 size)
>  {
> @@ -397,19 +467,19 @@ static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
>         pio_ctrl_val = csr_readl(pcie, PAB_PEX_PIO_CTRL);
>         csr_writel(pcie,
>                 pio_ctrl_val | (1 << PIO_ENABLE_SHIFT), PAB_PEX_PIO_CTRL);
> -       amap_ctrl_dw = read_paged_register(pcie, PAB_PEX_AMAP_CTRL(win_num));
> +       amap_ctrl_dw = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
>         amap_ctrl_dw = (amap_ctrl_dw | (type << AMAP_CTRL_TYPE_SHIFT));
>         amap_ctrl_dw = (amap_ctrl_dw | (1 << AMAP_CTRL_EN_SHIFT));
>
> -       write_paged_register(pcie, amap_ctrl_dw | lower_32_bits(size64),
> -                               PAB_PEX_AMAP_CTRL(win_num));
> +       csr_writel(pcie, amap_ctrl_dw | lower_32_bits(size64),
> +                  PAB_PEX_AMAP_CTRL(win_num));
>
> -       write_paged_register(pcie, upper_32_bits(size64),
> -                               PAB_EXT_PEX_AMAP_SIZEN(win_num));
> +       csr_writel(pcie, upper_32_bits(size64),
> +                  PAB_EXT_PEX_AMAP_SIZEN(win_num));
>
> -       write_paged_register(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
> -       write_paged_register(pcie, pci_addr, PAB_PEX_AMAP_PEX_WIN_L(win_num));
> -       write_paged_register(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));
> +       csr_writel(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
> +       csr_writel(pcie, pci_addr, PAB_PEX_AMAP_PEX_WIN_L(win_num));
> +       csr_writel(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));
>  }
>
>  /*
> @@ -437,8 +507,7 @@ static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
>         csr_writel(pcie, 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
>                         lower_32_bits(size64), PAB_AXI_AMAP_CTRL(win_num));
>
> -       write_paged_register(pcie, upper_32_bits(size64),
> -                               PAB_EXT_AXI_AMAP_SIZE(win_num));
> +       csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num));
>
>         /*
>          * program AXI window base with appropriate value in
> --
> 2.17.1
>

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

* Re: [PATCHv3 02/27] PCI: mobiveil: format the code without function change
  2019-01-29  8:08 ` [PATCHv3 02/27] PCI: mobiveil: format the code without function change Z.q. Hou
@ 2019-02-05  5:48   ` Subrahmanya Lingappa
  2019-02-18  7:03     ` Z.q. Hou
  0 siblings, 1 reply; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-05  5:48 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Zhiqiang,

On Tue, Jan 29, 2019 at 1:38 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> Just format the code without functionality change.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 261 +++++++++++++------------
>  1 file changed, 137 insertions(+), 124 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index d55c7e780c6e..b87471f08a40 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -31,38 +31,40 @@
>   * translation tables are grouped into windows, each window registers are
>   * grouped into blocks of 4 or 16 registers each
>   */
> -#define PAB_REG_BLOCK_SIZE     16
> -#define PAB_EXT_REG_BLOCK_SIZE 4
> +#define PAB_REG_BLOCK_SIZE             16
> +#define PAB_EXT_REG_BLOCK_SIZE         4
>
> -#define PAB_REG_ADDR(offset, win) (offset + (win * PAB_REG_BLOCK_SIZE))
> -#define PAB_EXT_REG_ADDR(offset, win) (offset + (win * PAB_EXT_REG_BLOCK_SIZE))
> +#define PAB_REG_ADDR(offset, win)      \
> +       (offset + (win * PAB_REG_BLOCK_SIZE))
> +#define PAB_EXT_REG_ADDR(offset, win)  \
> +       (offset + (win * PAB_EXT_REG_BLOCK_SIZE))
>
> -#define LTSSM_STATUS           0x0404
> -#define  LTSSM_STATUS_L0_MASK  0x3f
> -#define  LTSSM_STATUS_L0       0x2d
> +#define LTSSM_STATUS                   0x0404
> +#define  LTSSM_STATUS_L0_MASK          0x3f
> +#define  LTSSM_STATUS_L0               0x2d
>
> -#define PAB_CTRL               0x0808
> -#define  AMBA_PIO_ENABLE_SHIFT 0
> -#define  PEX_PIO_ENABLE_SHIFT  1
> -#define  PAGE_SEL_SHIFT        13
> -#define  PAGE_SEL_MASK         0x3f
> -#define  PAGE_LO_MASK          0x3ff
> -#define  PAGE_SEL_OFFSET_SHIFT 10
> +#define PAB_CTRL                       0x0808
> +#define  AMBA_PIO_ENABLE_SHIFT         0
> +#define  PEX_PIO_ENABLE_SHIFT          1
> +#define  PAGE_SEL_SHIFT                        13
above line seems to have an extra tab which makes it not aligned with
lines above.

> +#define  PAGE_SEL_MASK                 0x3f
> +#define  PAGE_LO_MASK                  0x3ff
> +#define  PAGE_SEL_OFFSET_SHIFT         10
>
> -#define PAB_AXI_PIO_CTRL       0x0840
> -#define  APIO_EN_MASK          0xf
> +#define PAB_AXI_PIO_CTRL               0x0840
> +#define  APIO_EN_MASK                  0xf
>
> -#define PAB_PEX_PIO_CTRL       0x08c0
> -#define  PIO_ENABLE_SHIFT      0
> +#define PAB_PEX_PIO_CTRL               0x08c0
> +#define  PIO_ENABLE_SHIFT              0
>
>  #define PAB_INTP_AMBA_MISC_ENB         0x0b0c
> -#define PAB_INTP_AMBA_MISC_STAT        0x0b1c
> +#define PAB_INTP_AMBA_MISC_STAT                0x0b1c
>  #define  PAB_INTP_INTX_MASK            0x01e0
>  #define  PAB_INTP_MSI_MASK             0x8
>
> -#define PAB_AXI_AMAP_CTRL(win) PAB_REG_ADDR(0x0ba0, win)
> -#define  WIN_ENABLE_SHIFT      0
> -#define  WIN_TYPE_SHIFT        1
> +#define PAB_AXI_AMAP_CTRL(win)         PAB_REG_ADDR(0x0ba0, win)
> +#define  WIN_ENABLE_SHIFT              0
> +#define  WIN_TYPE_SHIFT                        1
please check the extra tab above
>
>  #define PAB_EXT_AXI_AMAP_SIZE(win)     PAB_EXT_REG_ADDR(0xbaf0, win)
>
> @@ -70,16 +72,16 @@
>  #define  AXI_WINDOW_ALIGN_MASK         3
>
>  #define PAB_AXI_AMAP_PEX_WIN_L(win)    PAB_REG_ADDR(0x0ba8, win)
> -#define  PAB_BUS_SHIFT         24
> -#define  PAB_DEVICE_SHIFT      19
> -#define  PAB_FUNCTION_SHIFT    16
> +#define  PAB_BUS_SHIFT                 24
> +#define  PAB_DEVICE_SHIFT              19
> +#define  PAB_FUNCTION_SHIFT            16
>
>  #define PAB_AXI_AMAP_PEX_WIN_H(win)    PAB_REG_ADDR(0x0bac, win)
>  #define PAB_INTP_AXI_PIO_CLASS         0x474
>
> -#define PAB_PEX_AMAP_CTRL(win) PAB_REG_ADDR(0x4ba0, win)
> -#define  AMAP_CTRL_EN_SHIFT    0
> -#define  AMAP_CTRL_TYPE_SHIFT  1
> +#define PAB_PEX_AMAP_CTRL(win)         PAB_REG_ADDR(0x4ba0, win)
> +#define  AMAP_CTRL_EN_SHIFT            0
> +#define  AMAP_CTRL_TYPE_SHIFT          1
>
>  #define PAB_EXT_PEX_AMAP_SIZEN(win)    PAB_EXT_REG_ADDR(0xbef0, win)
>  #define PAB_PEX_AMAP_AXI_WIN(win)      PAB_REG_ADDR(0x4ba4, win)
> @@ -87,39 +89,39 @@
>  #define PAB_PEX_AMAP_PEX_WIN_H(win)    PAB_REG_ADDR(0x4bac, win)
>
>  /* starting offset of INTX bits in status register */
> -#define PAB_INTX_START 5
> +#define PAB_INTX_START                 5
>
>  /* supported number of MSI interrupts */
> -#define PCI_NUM_MSI    16
> +#define PCI_NUM_MSI                    16
>
>  /* MSI registers */
> -#define MSI_BASE_LO_OFFSET     0x04
> -#define MSI_BASE_HI_OFFSET     0x08
> -#define MSI_SIZE_OFFSET        0x0c
> -#define MSI_ENABLE_OFFSET      0x14
> -#define MSI_STATUS_OFFSET      0x18
> -#define MSI_DATA_OFFSET        0x20
> -#define MSI_ADDR_L_OFFSET      0x24
> -#define MSI_ADDR_H_OFFSET      0x28
> +#define MSI_BASE_LO_OFFSET             0x04
> +#define MSI_BASE_HI_OFFSET             0x08
> +#define MSI_SIZE_OFFSET                        0x0c
> +#define MSI_ENABLE_OFFSET              0x14
> +#define MSI_STATUS_OFFSET              0x18
> +#define MSI_DATA_OFFSET                        0x20
> +#define MSI_ADDR_L_OFFSET              0x24
> +#define MSI_ADDR_H_OFFSET              0x28
size and data offset macros have extra tabs?
>
>  /* outbound and inbound window definitions */
> -#define WIN_NUM_0              0
> -#define WIN_NUM_1              1
> -#define CFG_WINDOW_TYPE        0
> -#define IO_WINDOW_TYPE         1
> -#define MEM_WINDOW_TYPE        2
> -#define IB_WIN_SIZE            ((u64)256 * 1024 * 1024 * 1024)
> -#define MAX_PIO_WINDOWS        8
> +#define WIN_NUM_0                      0
> +#define WIN_NUM_1                      1
> +#define CFG_WINDOW_TYPE                        0
> +#define IO_WINDOW_TYPE                 1
> +#define MEM_WINDOW_TYPE                        2
> +#define IB_WIN_SIZE                    ((u64)256 * 1024 * 1024 * 1024)
> +#define MAX_PIO_WINDOWS                        8
>
>  /* Parameters for the waiting for link up routine */
> -#define LINK_WAIT_MAX_RETRIES  10
> -#define LINK_WAIT_MIN  90000
> -#define LINK_WAIT_MAX  100000
> +#define LINK_WAIT_MAX_RETRIES          10
> +#define LINK_WAIT_MIN                  90000
> +#define LINK_WAIT_MAX                  100000
>
> -#define PAGED_ADDR_BNDRY                       0xc00
> -#define OFFSET_TO_PAGE_ADDR(off)               \
> +#define PAGED_ADDR_BNDRY               0xc00
> +#define OFFSET_TO_PAGE_ADDR(off)       \
>         ((off & PAGE_LO_MASK) | PAGED_ADDR_BNDRY)
> -#define OFFSET_TO_PAGE_IDX(off)                        \
> +#define OFFSET_TO_PAGE_IDX(off)                \
>         ((off >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK)
>
>  struct mobiveil_msi {                  /* MSI information */
> @@ -297,14 +299,14 @@ static void __iomem *mobiveil_pcie_map_bus(struct pci_bus *bus,
>                                         unsigned int devfn, int where)
>  {
>         struct mobiveil_pcie *pcie = bus->sysdata;
> +       u32 value;
>
>         if (!mobiveil_pcie_valid_device(bus, devfn))
>                 return NULL;
>
> -       if (bus->number == pcie->root_bus_nr) {
> -               /* RC config access */
> +       /* RC config access */
> +       if (bus->number == pcie->root_bus_nr)
>                 return pcie->csr_axi_slave_base + where;
> -       }
>
>         /*
>          * EP config access (in Config/APIO space)
> @@ -312,10 +314,12 @@ static void __iomem *mobiveil_pcie_map_bus(struct pci_bus *bus,
>          * (BDF) in PAB_AXI_AMAP_PEX_WIN_L0 Register.
>          * Relies on pci_lock serialization
>          */
> -       csr_writel(pcie, bus->number << PAB_BUS_SHIFT |
> -                       PCI_SLOT(devfn) << PAB_DEVICE_SHIFT |
> -                       PCI_FUNC(devfn) << PAB_FUNCTION_SHIFT,
> -                       PAB_AXI_AMAP_PEX_WIN_L(WIN_NUM_0));
> +       value = bus->number << PAB_BUS_SHIFT |
> +               PCI_SLOT(devfn) << PAB_DEVICE_SHIFT |
> +               PCI_FUNC(devfn) << PAB_FUNCTION_SHIFT;
> +
> +       csr_writel(pcie, value, PAB_AXI_AMAP_PEX_WIN_L(WIN_NUM_0));
> +
>         return pcie->config_axi_slave_base + where;
>  }
>
> @@ -350,22 +354,22 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
>
>         /* Handle INTx */
>         if (intr_status & PAB_INTP_INTX_MASK) {
> -               shifted_status = csr_readl(pcie, PAB_INTP_AMBA_MISC_STAT) >>
> -                       PAB_INTX_START;
> +               shifted_status = csr_readl(pcie, PAB_INTP_AMBA_MISC_STAT);
> +               shifted_status >>= PAB_INTX_START;
>                 do {
>                         for_each_set_bit(bit, &shifted_status, PCI_NUM_INTX) {
>                                 virq = irq_find_mapping(pcie->intx_domain,
> -                                               bit + 1);
> +                                                       bit + 1);
>                                 if (virq)
>                                         generic_handle_irq(virq);
>                                 else
> -                                       dev_err_ratelimited(dev,
> -                                               "unexpected IRQ, INT%d\n", bit);
> +                                       dev_err_ratelimited(dev, "unexpected IRQ, INT%d\n",
> +                                                           bit);
>
>                                 /* clear interrupt */
>                                 csr_writel(pcie,
> -                                       shifted_status << PAB_INTX_START,
> -                                       PAB_INTP_AMBA_MISC_STAT);
> +                                          shifted_status << PAB_INTX_START,
> +                                          PAB_INTP_AMBA_MISC_STAT);
>                         }
>                 } while ((shifted_status >> PAB_INTX_START) != 0);
>         }
> @@ -375,8 +379,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
>
>         /* handle MSI interrupts */
>         while (msi_status & 1) {
> -               msi_data = readl_relaxed(pcie->apb_csr_base
> -                               + MSI_DATA_OFFSET);
> +               msi_data = readl_relaxed(pcie->apb_csr_base + MSI_DATA_OFFSET);
>
>                 /*
>                  * MSI_STATUS_OFFSET register gets updated to zero
> @@ -385,18 +388,18 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
>                  * two dummy reads.
>                  */
>                 msi_addr_lo = readl_relaxed(pcie->apb_csr_base +
> -                               MSI_ADDR_L_OFFSET);
> +                                           MSI_ADDR_L_OFFSET);
>                 msi_addr_hi = readl_relaxed(pcie->apb_csr_base +
> -                               MSI_ADDR_H_OFFSET);
> +                                           MSI_ADDR_H_OFFSET);
>                 dev_dbg(dev, "MSI registers, data: %08x, addr: %08x:%08x\n",
> -                               msi_data, msi_addr_hi, msi_addr_lo);
> +                       msi_data, msi_addr_hi, msi_addr_lo);
>
>                 virq = irq_find_mapping(msi->dev_domain, msi_data);
>                 if (virq)
>                         generic_handle_irq(virq);
>
>                 msi_status = readl_relaxed(pcie->apb_csr_base +
> -                               MSI_STATUS_OFFSET);
> +                                          MSI_STATUS_OFFSET);
>         }
>
>         /* Clear the interrupt status */
> @@ -413,7 +416,7 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
>
>         /* map config resource */
>         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> -                       "config_axi_slave");
> +                                          "config_axi_slave");
>         pcie->config_axi_slave_base = devm_pci_remap_cfg_resource(dev, res);
>         if (IS_ERR(pcie->config_axi_slave_base))
>                 return PTR_ERR(pcie->config_axi_slave_base);
> @@ -421,7 +424,7 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
>
>         /* map csr resource */
>         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> -                       "csr_axi_slave");
> +                                          "csr_axi_slave");
>         pcie->csr_axi_slave_base = devm_pci_remap_cfg_resource(dev, res);
>         if (IS_ERR(pcie->csr_axi_slave_base))
>                 return PTR_ERR(pcie->csr_axi_slave_base);
> @@ -452,7 +455,7 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
>  }
>
>  static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
> -               int pci_addr, u32 type, u64 size)
> +                              int pci_addr, u32 type, u64 size)
>  {
>         int pio_ctrl_val;
>         int amap_ctrl_dw;
> @@ -465,19 +468,20 @@ static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
>         }
>
>         pio_ctrl_val = csr_readl(pcie, PAB_PEX_PIO_CTRL);
> -       csr_writel(pcie,
> -               pio_ctrl_val | (1 << PIO_ENABLE_SHIFT), PAB_PEX_PIO_CTRL);
> -       amap_ctrl_dw = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
> -       amap_ctrl_dw = (amap_ctrl_dw | (type << AMAP_CTRL_TYPE_SHIFT));
> -       amap_ctrl_dw = (amap_ctrl_dw | (1 << AMAP_CTRL_EN_SHIFT));
> +       pio_ctrl_val |= 1 << PIO_ENABLE_SHIFT;
> +       csr_writel(pcie, pio_ctrl_val, PAB_PEX_PIO_CTRL);
>
> -       csr_writel(pcie, amap_ctrl_dw | lower_32_bits(size64),
> -                  PAB_PEX_AMAP_CTRL(win_num));
> +       amap_ctrl_dw = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
> +       amap_ctrl_dw |= (type << AMAP_CTRL_TYPE_SHIFT) |
> +                       (1 << AMAP_CTRL_EN_SHIFT) |
> +                       lower_32_bits(size64);
> +       csr_writel(pcie, amap_ctrl_dw, PAB_PEX_AMAP_CTRL(win_num));
>
>         csr_writel(pcie, upper_32_bits(size64),
>                    PAB_EXT_PEX_AMAP_SIZEN(win_num));
>
>         csr_writel(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
> +
>         csr_writel(pcie, pci_addr, PAB_PEX_AMAP_PEX_WIN_L(win_num));
>         csr_writel(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));
>  }
> @@ -486,7 +490,8 @@ static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
>   * routine to program the outbound windows
>   */
>  static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
> -               u64 cpu_addr, u64 pci_addr, u32 config_io_bit, u64 size)
> +                              u64 cpu_addr, u64 pci_addr,
> +                              u32 config_io_bit, u64 size)
>  {
>
>         u32 value, type;
> @@ -505,7 +510,7 @@ static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
>         type = config_io_bit;
>         value = csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num));
>         csr_writel(pcie, 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
> -                       lower_32_bits(size64), PAB_AXI_AMAP_CTRL(win_num));
> +                  lower_32_bits(size64), PAB_AXI_AMAP_CTRL(win_num));
>
>         csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num));
>
> @@ -515,14 +520,14 @@ static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
>          */
>         value = csr_readl(pcie, PAB_AXI_AMAP_AXI_WIN(win_num));
>         csr_writel(pcie, cpu_addr & (~AXI_WINDOW_ALIGN_MASK),
> -                       PAB_AXI_AMAP_AXI_WIN(win_num));
> +                  PAB_AXI_AMAP_AXI_WIN(win_num));
>
>         value = csr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_H(win_num));
>
>         csr_writel(pcie, lower_32_bits(pci_addr),
> -                       PAB_AXI_AMAP_PEX_WIN_L(win_num));
> +                  PAB_AXI_AMAP_PEX_WIN_L(win_num));
>         csr_writel(pcie, upper_32_bits(pci_addr),
> -                       PAB_AXI_AMAP_PEX_WIN_H(win_num));
> +                  PAB_AXI_AMAP_PEX_WIN_H(win_num));
>
>         pcie->ob_wins_configured++;
>  }
> @@ -538,7 +543,9 @@ static int mobiveil_bringup_link(struct mobiveil_pcie *pcie)
>
>                 usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
>         }
> +
>         dev_err(&pcie->pdev->dev, "link never came up\n");
> +
>         return -ETIMEDOUT;
>  }
>
> @@ -551,16 +558,16 @@ static void mobiveil_pcie_enable_msi(struct mobiveil_pcie *pcie)
>         msi->msi_pages_phys = (phys_addr_t)msg_addr;
>
>         writel_relaxed(lower_32_bits(msg_addr),
> -               pcie->apb_csr_base + MSI_BASE_LO_OFFSET);
> +                      pcie->apb_csr_base + MSI_BASE_LO_OFFSET);
>         writel_relaxed(upper_32_bits(msg_addr),
> -               pcie->apb_csr_base + MSI_BASE_HI_OFFSET);
> +                      pcie->apb_csr_base + MSI_BASE_HI_OFFSET);
>         writel_relaxed(4096, pcie->apb_csr_base + MSI_SIZE_OFFSET);
>         writel_relaxed(1, pcie->apb_csr_base + MSI_ENABLE_OFFSET);
>  }
>
>  static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>  {
> -       u32 value, pab_ctrl, type = 0;
> +       u32 value, pab_ctrl, type;
>         int err;
>         struct resource_entry *win, *tmp;
>
> @@ -575,26 +582,27 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>          * Space
>          */
>         value = csr_readl(pcie, PCI_COMMAND);
> -       csr_writel(pcie, value | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
> -               PCI_COMMAND_MASTER, PCI_COMMAND);
> +       value |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
> +       csr_writel(pcie, value, PCI_COMMAND);
>
>         /*
>          * program PIO Enable Bit to 1 (and PEX PIO Enable to 1) in PAB_CTRL
>          * register
>          */
>         pab_ctrl = csr_readl(pcie, PAB_CTRL);
> -       csr_writel(pcie, pab_ctrl | (1 << AMBA_PIO_ENABLE_SHIFT) |
> -               (1 << PEX_PIO_ENABLE_SHIFT), PAB_CTRL);
> +       pab_ctrl |= (1 << AMBA_PIO_ENABLE_SHIFT) | (1 << PEX_PIO_ENABLE_SHIFT);
> +       csr_writel(pcie, pab_ctrl, PAB_CTRL);
>
>         csr_writel(pcie, (PAB_INTP_INTX_MASK | PAB_INTP_MSI_MASK),
> -               PAB_INTP_AMBA_MISC_ENB);
> +                  PAB_INTP_AMBA_MISC_ENB);
>
>         /*
>          * program PIO Enable Bit to 1 and Config Window Enable Bit to 1 in
>          * PAB_AXI_PIO_CTRL Register
>          */
>         value = csr_readl(pcie, PAB_AXI_PIO_CTRL);
> -       csr_writel(pcie, value | APIO_EN_MASK, PAB_AXI_PIO_CTRL);
> +       value |= APIO_EN_MASK;
> +       csr_writel(pcie, value, PAB_AXI_PIO_CTRL);
>
>         /*
>          * we'll program one outbound window for config reads and
> @@ -605,25 +613,25 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>
>         /* config outbound translation window */
>         program_ob_windows(pcie, pcie->ob_wins_configured,
> -                       pcie->ob_io_res->start, 0, CFG_WINDOW_TYPE,
> -                       resource_size(pcie->ob_io_res));
> +                          pcie->ob_io_res->start, 0, CFG_WINDOW_TYPE,
> +                          resource_size(pcie->ob_io_res));
>
>         /* memory inbound translation window */
>         program_ib_windows(pcie, WIN_NUM_1, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
>
>         /* Get the I/O and memory ranges from DT */
>         resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
> -               type = 0;
>                 if (resource_type(win->res) == IORESOURCE_MEM)
>                         type = MEM_WINDOW_TYPE;
> -               if (resource_type(win->res) == IORESOURCE_IO)
> +               else if (resource_type(win->res) == IORESOURCE_IO)
>                         type = IO_WINDOW_TYPE;
> -               if (type) {
> -                       /* configure outbound translation window */
> -                       program_ob_windows(pcie, pcie->ob_wins_configured,
> -                               win->res->start, 0, type,
> -                               resource_size(win->res));
> -               }
> +               else
> +                       continue;
> +
> +               /* configure outbound translation window */
> +               program_ob_windows(pcie, pcie->ob_wins_configured,
> +                                  win->res->start, 0, type,
> +                                  resource_size(win->res));
>         }
>
>         /* setup MSI hardware registers */
> @@ -643,7 +651,8 @@ static void mobiveil_mask_intx_irq(struct irq_data *data)
>         mask = 1 << ((data->hwirq + PAB_INTX_START) - 1);
>         raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags);
>         shifted_val = csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB);
> -       csr_writel(pcie, (shifted_val & (~mask)), PAB_INTP_AMBA_MISC_ENB);
> +       shifted_val &= ~mask;
> +       csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB);
>         raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags);
>  }
>
> @@ -658,7 +667,8 @@ static void mobiveil_unmask_intx_irq(struct irq_data *data)
>         mask = 1 << ((data->hwirq + PAB_INTX_START) - 1);
>         raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags);
>         shifted_val = csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB);
> -       csr_writel(pcie, (shifted_val | mask), PAB_INTP_AMBA_MISC_ENB);
> +       shifted_val |= mask;
> +       csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB);
>         raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags);
>  }
>
> @@ -672,10 +682,11 @@ static struct irq_chip intx_irq_chip = {
>
>  /* routine to setup the INTx related data */
>  static int mobiveil_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
> -               irq_hw_number_t hwirq)
> +                                 irq_hw_number_t hwirq)
>  {
>         irq_set_chip_and_handler(irq, &intx_irq_chip, handle_level_irq);
>         irq_set_chip_data(irq, domain->host_data);
> +
>         return 0;
>  }
>
> @@ -692,7 +703,7 @@ static struct irq_chip mobiveil_msi_irq_chip = {
>
>  static struct msi_domain_info mobiveil_msi_domain_info = {
>         .flags  = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
> -               MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX),
> +                  MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX),
>         .chip   = &mobiveil_msi_irq_chip,
>  };
>
> @@ -710,7 +721,7 @@ static void mobiveil_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
>  }
>
>  static int mobiveil_msi_set_affinity(struct irq_data *irq_data,
> -               const struct cpumask *mask, bool force)
> +                                    const struct cpumask *mask, bool force)
>  {
>         return -EINVAL;
>  }
> @@ -722,7 +733,8 @@ static struct irq_chip mobiveil_msi_bottom_irq_chip = {
>  };
>
>  static int mobiveil_irq_msi_domain_alloc(struct irq_domain *domain,
> -               unsigned int virq, unsigned int nr_irqs, void *args)
> +                                        unsigned int virq,
> +                                        unsigned int nr_irqs, void *args)
>  {
>         struct mobiveil_pcie *pcie = domain->host_data;
>         struct mobiveil_msi *msi = &pcie->msi;
> @@ -742,13 +754,13 @@ static int mobiveil_irq_msi_domain_alloc(struct irq_domain *domain,
>         mutex_unlock(&msi->lock);
>
>         irq_domain_set_info(domain, virq, bit, &mobiveil_msi_bottom_irq_chip,
> -                               domain->host_data, handle_level_irq,
> -                               NULL, NULL);
> +                           domain->host_data, handle_level_irq, NULL, NULL);
>         return 0;
>  }
>
>  static void mobiveil_irq_msi_domain_free(struct irq_domain *domain,
> -               unsigned int virq, unsigned int nr_irqs)
> +                                        unsigned int virq,
> +                                        unsigned int nr_irqs)
>  {
>         struct irq_data *d = irq_domain_get_irq_data(domain, virq);
>         struct mobiveil_pcie *pcie = irq_data_get_irq_chip_data(d);
> @@ -756,12 +768,11 @@ static void mobiveil_irq_msi_domain_free(struct irq_domain *domain,
>
>         mutex_lock(&msi->lock);
>
> -       if (!test_bit(d->hwirq, msi->msi_irq_in_use)) {
> +       if (!test_bit(d->hwirq, msi->msi_irq_in_use))
>                 dev_err(&pcie->pdev->dev, "trying to free unused MSI#%lu\n",
>                         d->hwirq);
> -       } else {
> +       else
>                 __clear_bit(d->hwirq, msi->msi_irq_in_use);
> -       }
>
>         mutex_unlock(&msi->lock);
>  }
> @@ -785,12 +796,14 @@ static int mobiveil_allocate_msi_domains(struct mobiveil_pcie *pcie)
>         }
>
>         msi->msi_domain = pci_msi_create_irq_domain(fwnode,
> -                               &mobiveil_msi_domain_info, msi->dev_domain);
> +                                                   &mobiveil_msi_domain_info,
> +                                                   msi->dev_domain);
>         if (!msi->msi_domain) {
>                 dev_err(dev, "failed to create MSI domain\n");
>                 irq_domain_remove(msi->dev_domain);
>                 return -ENOMEM;
>         }
> +
>         return 0;
>  }
>
> @@ -801,8 +814,8 @@ static int mobiveil_pcie_init_irq_domain(struct mobiveil_pcie *pcie)
>         int ret;
>
>         /* setup INTx */
> -       pcie->intx_domain = irq_domain_add_linear(node,
> -                               PCI_NUM_INTX, &intx_domain_ops, pcie);
> +       pcie->intx_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
> +                                                 &intx_domain_ops, pcie);
>
>         if (!pcie->intx_domain) {
>                 dev_err(dev, "Failed to get a INTx IRQ domain\n");
> @@ -917,10 +930,10 @@ MODULE_DEVICE_TABLE(of, mobiveil_pcie_of_match);
>  static struct platform_driver mobiveil_pcie_driver = {
>         .probe = mobiveil_pcie_probe,
>         .driver = {
> -                       .name = "mobiveil-pcie",
> -                       .of_match_table = mobiveil_pcie_of_match,
> -                       .suppress_bind_attrs = true,
> -               },
> +               .name = "mobiveil-pcie",
> +               .of_match_table = mobiveil_pcie_of_match,
> +               .suppress_bind_attrs = true,
> +       },
>  };
>
>  builtin_platform_driver(mobiveil_pcie_driver);
> --
> 2.17.1
>

Thanks.

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

* Re: [PATCHv3 03/27] PCI: mobiveil: correct the returned error number
  2019-01-29  8:08 ` [PATCHv3 03/27] PCI: mobiveil: correct the returned error number Z.q. Hou
@ 2019-02-05  5:53   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-05  5:53 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

On Tue, Jan 29, 2019 at 1:38 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> This patch corrected the returned error number by convention,
> and removed a unnecessary error check.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index b87471f08a40..563210e731d3 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -819,7 +819,7 @@ static int mobiveil_pcie_init_irq_domain(struct mobiveil_pcie *pcie)
>
>         if (!pcie->intx_domain) {
>                 dev_err(dev, "Failed to get a INTx IRQ domain\n");
> -               return -ENODEV;
> +               return -ENOMEM;
>         }
>
>         raw_spin_lock_init(&pcie->intx_mask_lock);
> @@ -845,11 +845,9 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
>         /* allocate the PCIe port */
>         bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
>         if (!bridge)
> -               return -ENODEV;
> +               return -ENOMEM;
>
>         pcie = pci_host_bridge_priv(bridge);
> -       if (!pcie)
> -               return -ENOMEM;
>
>         pcie->pdev = pdev;
>
> @@ -866,7 +864,7 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
>                                                     &pcie->resources, &iobase);
>         if (ret) {
>                 dev_err(dev, "Getting bridge resources failed\n");
> -               return -ENOMEM;
> +               return ret;
>         }
>
>         /*
> --
> 2.17.1
>

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

* Re: [PATCHv3 04/27] PCI: mobiveil: remove flag MSI_FLAG_MULTI_PCI_MSI
  2019-01-29  8:08 ` [PATCHv3 04/27] PCI: mobiveil: remove flag MSI_FLAG_MULTI_PCI_MSI Z.q. Hou
@ 2019-02-05  6:05   ` Subrahmanya Lingappa
  2019-02-18  7:03     ` Z.q. Hou
  0 siblings, 1 reply; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-05  6:05 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Zhiqiang,
why are we removing multi-MSI support ?
what functionality this driver is not providing to support it ?

Thanks.

On Tue, Jan 29, 2019 at 1:38 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> The current code does not support multiple MSIs, so remove
> the corresponding flag from the msi_domain_info structure.
>
> Fixes: 1e913e58335f ("PCI: mobiveil: Add MSI support")
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index 563210e731d3..a0dd337c6214 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -703,7 +703,7 @@ static struct irq_chip mobiveil_msi_irq_chip = {
>
>  static struct msi_domain_info mobiveil_msi_domain_info = {
>         .flags  = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
> -                  MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX),
> +                  MSI_FLAG_PCI_MSIX),
>         .chip   = &mobiveil_msi_irq_chip,
>  };
>
> --
> 2.17.1
>

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

* Re: [PATCHv3 05/27] PCI: mobiveil: correct PCI base address in MEM/IO outbound windows
  2019-01-29  8:09 ` [PATCHv3 05/27] PCI: mobiveil: correct PCI base address in MEM/IO outbound windows Z.q. Hou
@ 2019-02-05  6:06   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-05  6:06 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

On Tue, Jan 29, 2019 at 1:39 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> It should get PCI base address from the DT node property 'ranges'
> to setup MEM/IO outbound windows instead of always zero.
>
> Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge
> IP driver")
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index a0dd337c6214..8ff873023b5f 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -630,8 +630,9 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>
>                 /* configure outbound translation window */
>                 program_ob_windows(pcie, pcie->ob_wins_configured,
> -                                  win->res->start, 0, type,
> -                                  resource_size(win->res));
> +                                  win->res->start,
> +                                  win->res->start - win->offset,
> +                                  type, resource_size(win->res));
>         }
>
>         /* setup MSI hardware registers */
> --
> 2.17.1
>

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

* Re: [PATCHv3 06/27] PCI: mobiveil: replace the resource list iteration function
  2019-01-29  8:09 ` [PATCHv3 06/27] PCI: mobiveil: replace the resource list iteration function Z.q. Hou
@ 2019-02-05  6:07   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-05  6:07 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

On Tue, Jan 29, 2019 at 1:39 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> As it won't delete any node in this iteration, replaced
> the function resource_list_for_each_entry_safe() with
> the resource_list_for_each_entry().
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index 8ff873023b5f..b2cc9c097fc9 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -569,7 +569,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>  {
>         u32 value, pab_ctrl, type;
>         int err;
> -       struct resource_entry *win, *tmp;
> +       struct resource_entry *win;
>
>         err = mobiveil_bringup_link(pcie);
>         if (err) {
> @@ -620,7 +620,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>         program_ib_windows(pcie, WIN_NUM_1, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
>
>         /* Get the I/O and memory ranges from DT */
> -       resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
> +       resource_list_for_each_entry(win, &pcie->resources) {
>                 if (resource_type(win->res) == IORESOURCE_MEM)
>                         type = MEM_WINDOW_TYPE;
>                 else if (resource_type(win->res) == IORESOURCE_IO)
> --
> 2.17.1
>

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

* Re: [PATCHv3 07/27] PCI: mobiveil: use WIN_NUM_0 explicitly for CFG outbound window
  2019-01-29  8:09 ` [PATCHv3 07/27] PCI: mobiveil: use WIN_NUM_0 explicitly for CFG outbound window Z.q. Hou
@ 2019-02-05  6:08   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-05  6:08 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

On Tue, Jan 29, 2019 at 1:39 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> As the .map_bus() use the WIN_NUM_0 for CFG transactions,
> it's better passing WIN_NUM_0 explicitly when initialize
> the CFG outbound window.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index b2cc9c097fc9..df71c11b4810 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -612,9 +612,8 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>          */
>
>         /* config outbound translation window */
> -       program_ob_windows(pcie, pcie->ob_wins_configured,
> -                          pcie->ob_io_res->start, 0, CFG_WINDOW_TYPE,
> -                          resource_size(pcie->ob_io_res));
> +       program_ob_windows(pcie, WIN_NUM_0, pcie->ob_io_res->start, 0,
> +                          CFG_WINDOW_TYPE, resource_size(pcie->ob_io_res));
>
>         /* memory inbound translation window */
>         program_ib_windows(pcie, WIN_NUM_1, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
> --
> 2.17.1
>

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

* Re: [PATCHv3 08/27] PCI: mobiveil: use the 1st inbound window for MEM inbound transactions
  2019-01-29  8:09 ` [PATCHv3 08/27] PCI: mobiveil: use the 1st inbound window for MEM inbound transactions Z.q. Hou
@ 2019-02-05  6:08   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-05  6:08 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

On Tue, Jan 29, 2019 at 1:39 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> The inbound windows have different register set with outbound windows.
> This patch change the MEM inbound window to the first one.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index df71c11b4810..e88afc792a5c 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -616,7 +616,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>                            CFG_WINDOW_TYPE, resource_size(pcie->ob_io_res));
>
>         /* memory inbound translation window */
> -       program_ib_windows(pcie, WIN_NUM_1, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
> +       program_ib_windows(pcie, WIN_NUM_0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
>
>         /* Get the I/O and memory ranges from DT */
>         resource_list_for_each_entry(win, &pcie->resources) {
> --
> 2.17.1
>

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

* Re: [PATCHv3 09/27] PCI: mobiveil: correct inbound/outbound window setup routines
  2019-01-29  8:09 ` [PATCHv3 09/27] PCI: mobiveil: correct inbound/outbound window setup routines Z.q. Hou
@ 2019-02-05  6:10   ` Subrahmanya Lingappa
  2019-02-18  7:07     ` Z.q. Hou
  0 siblings, 1 reply; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-05  6:10 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

ZQ,
please correct the tab spacing of the macro definitions, otherwise its OK.

Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

On Tue, Jan 29, 2019 at 1:39 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> Outbound window routine:
>  - Removed unused var definition and register read operations.
>  - Added the upper 32-bit cpu address setup of the window.
>  - Instead of blindly write, only change the fields specified.
>  - Masked the lower bits of window size in case override the
>    control bits.
>  - Check if the passing window number is available, instead of
>    the total number of the initialized windows.
>
> Inbound window routine:
>  - Added parameter 'u64 cpu_addr' to specify the cpu address
>    of the window instead of using 'pci_addr'.
>  - Changed 'int pci_addr' to 'u64 pci_addr', and added setup
>    of the upper 32-bit pci address of the window.
>  - Moved the PCIe PIO master enablement to mobiveil_host_init().
>  - Instead of blindly write, only change the fields specified.
>  - Masked the lower bits of window size in case override the
>    control bits.
>  - Check if the passing window number is available, instead of
>    the total number of the initialized windows.
>  - And added the statistic of initialized inbound windows.
>
> Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host
> Bridge IP driver")
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 70 +++++++++++++++-----------
>  1 file changed, 42 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index e88afc792a5c..4ba458474e42 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -65,9 +65,13 @@
>  #define PAB_AXI_AMAP_CTRL(win)         PAB_REG_ADDR(0x0ba0, win)
>  #define  WIN_ENABLE_SHIFT              0
>  #define  WIN_TYPE_SHIFT                        1
> +#define  WIN_TYPE_MASK                 0x3
> +#define  WIN_SIZE_SHIFT                        10
> +#define  WIN_SIZE_MASK                 0x3fffff
>
>  #define PAB_EXT_AXI_AMAP_SIZE(win)     PAB_EXT_REG_ADDR(0xbaf0, win)
>
> +#define PAB_EXT_AXI_AMAP_AXI_WIN(win)  PAB_EXT_REG_ADDR(0x80a0, win)
>  #define PAB_AXI_AMAP_AXI_WIN(win)      PAB_REG_ADDR(0x0ba4, win)
>  #define  AXI_WINDOW_ALIGN_MASK         3
>
> @@ -82,8 +86,10 @@
>  #define PAB_PEX_AMAP_CTRL(win)         PAB_REG_ADDR(0x4ba0, win)
>  #define  AMAP_CTRL_EN_SHIFT            0
>  #define  AMAP_CTRL_TYPE_SHIFT          1
> +#define  AMAP_CTRL_TYPE_MASK           3
>
>  #define PAB_EXT_PEX_AMAP_SIZEN(win)    PAB_EXT_REG_ADDR(0xbef0, win)
> +#define PAB_EXT_PEX_AMAP_AXI_WIN(win)  PAB_EXT_REG_ADDR(0xb4a0, win)
>  #define PAB_PEX_AMAP_AXI_WIN(win)      PAB_REG_ADDR(0x4ba4, win)
>  #define PAB_PEX_AMAP_PEX_WIN_L(win)    PAB_REG_ADDR(0x4ba8, win)
>  #define PAB_PEX_AMAP_PEX_WIN_H(win)    PAB_REG_ADDR(0x4bac, win)
> @@ -455,49 +461,51 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
>  }
>
>  static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
> -                              int pci_addr, u32 type, u64 size)
> +                              u64 cpu_addr, u64 pci_addr, u32 type, u64 size)
>  {
> -       int pio_ctrl_val;
> -       int amap_ctrl_dw;
> +       u32 value;
>         u64 size64 = ~(size - 1);
>
> -       if ((pcie->ib_wins_configured + 1) > pcie->ppio_wins) {
> +       if (win_num >= pcie->ppio_wins) {
>                 dev_err(&pcie->pdev->dev,
>                         "ERROR: max inbound windows reached !\n");
>                 return;
>         }
>
> -       pio_ctrl_val = csr_readl(pcie, PAB_PEX_PIO_CTRL);
> -       pio_ctrl_val |= 1 << PIO_ENABLE_SHIFT;
> -       csr_writel(pcie, pio_ctrl_val, PAB_PEX_PIO_CTRL);
> -
> -       amap_ctrl_dw = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
> -       amap_ctrl_dw |= (type << AMAP_CTRL_TYPE_SHIFT) |
> -                       (1 << AMAP_CTRL_EN_SHIFT) |
> -                       lower_32_bits(size64);
> -       csr_writel(pcie, amap_ctrl_dw, PAB_PEX_AMAP_CTRL(win_num));
> +       value = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
> +       value &= ~(AMAP_CTRL_TYPE_MASK << AMAP_CTRL_TYPE_SHIFT |
> +                WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> +       value |= (type << AMAP_CTRL_TYPE_SHIFT) | (1 << AMAP_CTRL_EN_SHIFT) |
> +                (lower_32_bits(size64) & WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> +       csr_writel(pcie, value, PAB_PEX_AMAP_CTRL(win_num));
>
>         csr_writel(pcie, upper_32_bits(size64),
>                    PAB_EXT_PEX_AMAP_SIZEN(win_num));
>
> -       csr_writel(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
> +       csr_writel(pcie, lower_32_bits(cpu_addr),
> +                  PAB_PEX_AMAP_AXI_WIN(win_num));
> +       csr_writel(pcie, upper_32_bits(cpu_addr),
> +                  PAB_EXT_PEX_AMAP_AXI_WIN(win_num));
> +
> +       csr_writel(pcie, lower_32_bits(pci_addr),
> +                  PAB_PEX_AMAP_PEX_WIN_L(win_num));
> +       csr_writel(pcie, upper_32_bits(pci_addr),
> +                  PAB_PEX_AMAP_PEX_WIN_H(win_num));
>
> -       csr_writel(pcie, pci_addr, PAB_PEX_AMAP_PEX_WIN_L(win_num));
> -       csr_writel(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));
> +       pcie->ib_wins_configured++;
>  }
>
>  /*
>   * routine to program the outbound windows
>   */
>  static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
> -                              u64 cpu_addr, u64 pci_addr,
> -                              u32 config_io_bit, u64 size)
> +                              u64 cpu_addr, u64 pci_addr, u32 type, u64 size)
>  {
>
> -       u32 value, type;
> +       u32 value;
>         u64 size64 = ~(size - 1);
>
> -       if ((pcie->ob_wins_configured + 1) > pcie->apio_wins) {
> +       if (win_num >= pcie->apio_wins) {
>                 dev_err(&pcie->pdev->dev,
>                         "ERROR: max outbound windows reached !\n");
>                 return;
> @@ -507,10 +515,12 @@ static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
>          * program Enable Bit to 1, Type Bit to (00) base 2, AXI Window Size Bit
>          * to 4 KB in PAB_AXI_AMAP_CTRL register
>          */
> -       type = config_io_bit;
>         value = csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num));
> -       csr_writel(pcie, 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
> -                  lower_32_bits(size64), PAB_AXI_AMAP_CTRL(win_num));
> +       value &= ~(WIN_TYPE_MASK << WIN_TYPE_SHIFT |
> +                WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> +       value |= 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
> +                (lower_32_bits(size64) & WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> +       csr_writel(pcie, value, PAB_AXI_AMAP_CTRL(win_num));
>
>         csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num));
>
> @@ -518,11 +528,10 @@ static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
>          * program AXI window base with appropriate value in
>          * PAB_AXI_AMAP_AXI_WIN0 register
>          */
> -       value = csr_readl(pcie, PAB_AXI_AMAP_AXI_WIN(win_num));
> -       csr_writel(pcie, cpu_addr & (~AXI_WINDOW_ALIGN_MASK),
> +       csr_writel(pcie, lower_32_bits(cpu_addr) & (~AXI_WINDOW_ALIGN_MASK),
>                    PAB_AXI_AMAP_AXI_WIN(win_num));
> -
> -       value = csr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_H(win_num));
> +       csr_writel(pcie, upper_32_bits(cpu_addr),
> +                  PAB_EXT_AXI_AMAP_AXI_WIN(win_num));
>
>         csr_writel(pcie, lower_32_bits(pci_addr),
>                    PAB_AXI_AMAP_PEX_WIN_L(win_num));
> @@ -604,6 +613,11 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>         value |= APIO_EN_MASK;
>         csr_writel(pcie, value, PAB_AXI_PIO_CTRL);
>
> +       /* Enable PCIe PIO master */
> +       value = csr_readl(pcie, PAB_PEX_PIO_CTRL);
> +       value |= 1 << PIO_ENABLE_SHIFT;
> +       csr_writel(pcie, value, PAB_PEX_PIO_CTRL);
> +
>         /*
>          * we'll program one outbound window for config reads and
>          * another default inbound window for all the upstream traffic
> @@ -616,7 +630,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>                            CFG_WINDOW_TYPE, resource_size(pcie->ob_io_res));
>
>         /* memory inbound translation window */
> -       program_ib_windows(pcie, WIN_NUM_0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
> +       program_ib_windows(pcie, WIN_NUM_0, 0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
>
>         /* Get the I/O and memory ranges from DT */
>         resource_list_for_each_entry(win, &pcie->resources) {
> --
> 2.17.1
>

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

* Re: [PATCHv3 10/27] PCI: mobiveil: fix the INTx process error
  2019-01-29  8:09 ` [PATCHv3 10/27] PCI: mobiveil: fix the INTx process error Z.q. Hou
@ 2019-02-05  6:11   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-05  6:11 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

On Tue, Jan 29, 2019 at 1:39 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> In the loop block, there is not code change the loop key,
> this patch updated the loop key by re-read the INTx status
> register.
>
> This patch also change to clear the handled INTx status.
>
> Note: Need MV to test this fix.
>
> Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host
> Bridge IP driver")
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index 4ba458474e42..78e575e71f4d 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -361,6 +361,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
>         /* Handle INTx */
>         if (intr_status & PAB_INTP_INTX_MASK) {
>                 shifted_status = csr_readl(pcie, PAB_INTP_AMBA_MISC_STAT);
> +               shifted_status &= PAB_INTP_INTX_MASK;
>                 shifted_status >>= PAB_INTX_START;
>                 do {
>                         for_each_set_bit(bit, &shifted_status, PCI_NUM_INTX) {
> @@ -372,12 +373,16 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
>                                         dev_err_ratelimited(dev, "unexpected IRQ, INT%d\n",
>                                                             bit);
>
> -                               /* clear interrupt */
> -                               csr_writel(pcie,
> -                                          shifted_status << PAB_INTX_START,
> +                               /* clear interrupt handled */
> +                               csr_writel(pcie, 1 << (PAB_INTX_START + bit),
>                                            PAB_INTP_AMBA_MISC_STAT);
>                         }
> -               } while ((shifted_status >> PAB_INTX_START) != 0);
> +
> +                       shifted_status = csr_readl(pcie,
> +                                                  PAB_INTP_AMBA_MISC_STAT);
> +                       shifted_status &= PAB_INTP_INTX_MASK;
> +                       shifted_status >>= PAB_INTX_START;
> +               } while (shifted_status != 0);
>         }
>
>         /* read extra MSI status register */
> --
> 2.17.1
>

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

* Re: [PATCHv3 11/27] PCI: mobiveil: only fix up the Class Code field
  2019-01-29  8:09 ` [PATCHv3 11/27] PCI: mobiveil: only fix up the Class Code field Z.q. Hou
@ 2019-02-05  6:11   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-05  6:11 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

On Tue, Jan 29, 2019 at 1:39 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> Fix up the Class Code to PCI bridge, do not change the Revision ID.
> And move the fixup to mobiveil_host_init function.
>
> Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge
> IP driver")
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index 78e575e71f4d..8eee1ab7ee24 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -653,6 +653,12 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>                                    type, resource_size(win->res));
>         }
>
> +       /* fixup for PCIe class register */
> +       value = csr_readl(pcie, PAB_INTP_AXI_PIO_CLASS);
> +       value &= 0xff;
> +       value |= (PCI_CLASS_BRIDGE_PCI << 16);
> +       csr_writel(pcie, value, PAB_INTP_AXI_PIO_CLASS);
> +
>         /* setup MSI hardware registers */
>         mobiveil_pcie_enable_msi(pcie);
>
> @@ -896,9 +902,6 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
>                 goto error;
>         }
>
> -       /* fixup for PCIe class register */
> -       csr_writel(pcie, 0x060402ab, PAB_INTP_AXI_PIO_CLASS);
> -
>         /* initialize the IRQ domains */
>         ret = mobiveil_pcie_init_irq_domain(pcie);
>         if (ret) {
> --
> 2.17.1
>

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

* Re: [PATCHv3 12/27] PCI: mobiveil: move out the link up waiting from mobiveil_host_init
  2019-01-29  8:09 ` [PATCHv3 12/27] PCI: mobiveil: move out the link up waiting from mobiveil_host_init Z.q. Hou
@ 2019-02-05  6:12   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-05  6:12 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

On Tue, Jan 29, 2019 at 1:39 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> Host initial sequence does not depend on PCIe link up, so move it
> to the place just before the enumeration.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 15 +++++++--------
>  1 file changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index 8eee1ab7ee24..c2848c22b466 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -582,15 +582,8 @@ static void mobiveil_pcie_enable_msi(struct mobiveil_pcie *pcie)
>  static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>  {
>         u32 value, pab_ctrl, type;
> -       int err;
>         struct resource_entry *win;
>
> -       err = mobiveil_bringup_link(pcie);
> -       if (err) {
> -               dev_info(&pcie->pdev->dev, "link bring-up failed\n");
> -               return err;
> -       }
> -
>         /*
>          * program Bus Master Enable Bit in Command Register in PAB Config
>          * Space
> @@ -662,7 +655,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>         /* setup MSI hardware registers */
>         mobiveil_pcie_enable_msi(pcie);
>
> -       return err;
> +       return 0;
>  }
>
>  static void mobiveil_mask_intx_irq(struct irq_data *data)
> @@ -922,6 +915,12 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
>         bridge->map_irq = of_irq_parse_and_map_pci;
>         bridge->swizzle_irq = pci_common_swizzle;
>
> +       ret = mobiveil_bringup_link(pcie);
> +       if (ret) {
> +               dev_info(dev, "link bring-up failed\n");
> +               goto error;
> +       }
> +
>         /* setup the kernel resources for the newly added PCIe root bus */
>         ret = pci_scan_root_bus_bridge(bridge);
>         if (ret)
> --
> 2.17.1
>

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

* Re: [PATCHv3 01/27] PCI: mobiveil: uniform the register accessors
  2019-02-05  5:39   ` Subrahmanya Lingappa
@ 2019-02-05 17:43     ` Lorenzo Pieralisi
  2019-02-06 10:59       ` Subrahmanya Lingappa
  0 siblings, 1 reply; 68+ messages in thread
From: Lorenzo Pieralisi @ 2019-02-05 17:43 UTC (permalink / raw)
  To: Subrahmanya Lingappa
  Cc: Z.q. Hou, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	bhelgaas, robh+dt, mark.rutland, shawnguo, Leo Li,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

On Tue, Feb 05, 2019 at 11:09:19AM +0530, Subrahmanya Lingappa wrote:
> Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

I have a feeling you do not read what I write. Please never top-post.

Read this, especially the email etiquette section:

https://kernelnewbies.org/PatchCulture

> 
> 
> 
> On Tue, Jan 29, 2019 at 1:38 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
> >
> > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> >
> > It's confused that R/W some registers by csr_readl()/csr_writel(),
> > while others by read_paged_register()/write_paged_register().
> > Actually the low 3KB of 4KB PCIe configure space can be accessed
> > directly and high 1KB is paging area. So this patch uniformed the
> > register accessors to csr_readl() and csr_writel() by comparing
> > the register offset with page access boundary 3KB in the accessor
> > internal.
> >
> > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> > ---
> > V3:
> >  - No change
> >
> >  drivers/pci/controller/pcie-mobiveil.c | 179 +++++++++++++++++--------
> >  1 file changed, 124 insertions(+), 55 deletions(-)
> >
> > diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> > index 77052a0712d0..d55c7e780c6e 100644
> > --- a/drivers/pci/controller/pcie-mobiveil.c
> > +++ b/drivers/pci/controller/pcie-mobiveil.c
> > @@ -47,7 +47,6 @@
> >  #define  PAGE_SEL_SHIFT        13
> >  #define  PAGE_SEL_MASK         0x3f
> >  #define  PAGE_LO_MASK          0x3ff
> > -#define  PAGE_SEL_EN           0xc00
> >  #define  PAGE_SEL_OFFSET_SHIFT 10
> >
> >  #define PAB_AXI_PIO_CTRL       0x0840
> > @@ -117,6 +116,12 @@
> >  #define LINK_WAIT_MIN  90000
> >  #define LINK_WAIT_MAX  100000
> >
> > +#define PAGED_ADDR_BNDRY                       0xc00
> > +#define OFFSET_TO_PAGE_ADDR(off)               \
> > +       ((off & PAGE_LO_MASK) | PAGED_ADDR_BNDRY)
> > +#define OFFSET_TO_PAGE_IDX(off)                        \
> > +       ((off >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK)
> > +
> >  struct mobiveil_msi {                  /* MSI information */
> >         struct mutex lock;              /* protect bitmap variable */
> >         struct irq_domain *msi_domain;
> > @@ -145,15 +150,119 @@ struct mobiveil_pcie {
> >         struct mobiveil_msi msi;
> >  };
> >
> > -static inline void csr_writel(struct mobiveil_pcie *pcie, const u32 value,
> > -               const u32 reg)
> > +/*
> > + * mobiveil_pcie_sel_page - routine to access paged register
> > + *
> > + * Registers whose address greater than PAGED_ADDR_BNDRY (0xc00) are paged,
> > + * for this scheme to work extracted higher 6 bits of the offset will be
> > + * written to pg_sel field of PAB_CTRL register and rest of the lower 10
> > + * bits enabled with PAGED_ADDR_BNDRY are used as offset of the register.
> > + */
> > +static void mobiveil_pcie_sel_page(struct mobiveil_pcie *pcie, u8 pg_idx)
> >  {
> > -       writel_relaxed(value, pcie->csr_axi_slave_base + reg);
> > +       u32 val;
> > +
> > +       val = readl(pcie->csr_axi_slave_base + PAB_CTRL);
> > +       val &= ~(PAGE_SEL_MASK << PAGE_SEL_SHIFT);
> > +       val |= (pg_idx & PAGE_SEL_MASK) << PAGE_SEL_SHIFT;
> > +
> > +       writel(val, pcie->csr_axi_slave_base + PAB_CTRL);
> >  }
> >
> > -static inline u32 csr_readl(struct mobiveil_pcie *pcie, const u32 reg)
> > +static void *mobiveil_pcie_comp_addr(struct mobiveil_pcie *pcie, u32 off)
> >  {
> > -       return readl_relaxed(pcie->csr_axi_slave_base + reg);
> > +       if (off < PAGED_ADDR_BNDRY) {
> > +               /* For directly accessed registers, clear the pg_sel field */
> > +               mobiveil_pcie_sel_page(pcie, 0);
> > +               return pcie->csr_axi_slave_base + off;
> > +       }
> > +
> > +       mobiveil_pcie_sel_page(pcie, OFFSET_TO_PAGE_IDX(off));
> > +       return pcie->csr_axi_slave_base + OFFSET_TO_PAGE_ADDR(off);
> > +}
> > +
> > +static int mobiveil_pcie_read(void __iomem *addr, int size, u32 *val)
> > +{
> > +       if ((uintptr_t)addr & (size - 1)) {
> > +               *val = 0;
> > +               return PCIBIOS_BAD_REGISTER_NUMBER;
> > +       }
> > +
> > +       switch (size) {
> > +       case 4:
> > +               *val = readl(addr);
> > +               break;
> > +       case 2:
> > +               *val = readw(addr);
> > +               break;
> > +       case 1:
> > +               *val = readb(addr);
> > +               break;
> > +       default:
> > +               *val = 0;
> > +               return PCIBIOS_BAD_REGISTER_NUMBER;
> > +       }
> > +
> > +       return PCIBIOS_SUCCESSFUL;
> > +}
> > +
> > +static int mobiveil_pcie_write(void __iomem *addr, int size, u32 val)
> > +{
> > +       if ((uintptr_t)addr & (size - 1))
> > +               return PCIBIOS_BAD_REGISTER_NUMBER;
> > +
> > +       switch (size) {
> > +       case 4:
> > +               writel(val, addr);
> > +               break;
> > +       case 2:
> > +               writew(val, addr);
> > +               break;
> > +       case 1:
> > +               writeb(val, addr);
> > +               break;
> > +       default:
> > +               return PCIBIOS_BAD_REGISTER_NUMBER;
> > +       }
> > +
> > +       return PCIBIOS_SUCCESSFUL;
> > +}
> > +
> > +static u32 csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size)
> > +{
> > +       void *addr;
> > +       u32 val;
> > +       int ret;
> > +
> > +       addr = mobiveil_pcie_comp_addr(pcie, off);
> > +
> > +       ret = mobiveil_pcie_read(addr, size, &val);
> > +       if (ret)
> > +               dev_err(&pcie->pdev->dev, "read CSR address failed\n");
> > +
> > +       return val;
> > +}
> > +
> > +static void csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, size_t size)
> > +{
> > +       void *addr;
> > +       int ret;
> > +
> > +       addr = mobiveil_pcie_comp_addr(pcie, off);
> > +
> > +       ret = mobiveil_pcie_write(addr, size, val);
> > +       if (ret)
> > +               dev_err(&pcie->pdev->dev, "write CSR address failed\n");
> > +}
> > +
> > +static u32 csr_readl(struct mobiveil_pcie *pcie, u32 off)
> > +{
> > +       return csr_read(pcie, off, 0x4);
> > +}
> > +
> > +static void csr_writel(struct mobiveil_pcie *pcie, u32 val, u32 off)
> > +{
> > +       csr_write(pcie, val, off, 0x4);
> >  }
> >
> >  static bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie)
> > @@ -342,45 +451,6 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
> >         return 0;
> >  }
> >
> > -/*
> > - * select_paged_register - routine to access paged register of root complex
> > - *
> > - * registers of RC are paged, for this scheme to work
> > - * extracted higher 6 bits of the offset will be written to pg_sel
> > - * field of PAB_CTRL register and rest of the lower 10 bits enabled with
> > - * PAGE_SEL_EN are used as offset of the register.
> > - */
> > -static void select_paged_register(struct mobiveil_pcie *pcie, u32 offset)
> > -{
> > -       int pab_ctrl_dw, pg_sel;
> > -
> > -       /* clear pg_sel field */
> > -       pab_ctrl_dw = csr_readl(pcie, PAB_CTRL);
> > -       pab_ctrl_dw = (pab_ctrl_dw & ~(PAGE_SEL_MASK << PAGE_SEL_SHIFT));
> > -
> > -       /* set pg_sel field */
> > -       pg_sel = (offset >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK;
> > -       pab_ctrl_dw |= ((pg_sel << PAGE_SEL_SHIFT));
> > -       csr_writel(pcie, pab_ctrl_dw, PAB_CTRL);
> > -}
> > -
> > -static void write_paged_register(struct mobiveil_pcie *pcie,
> > -               u32 val, u32 offset)
> > -{
> > -       u32 off = (offset & PAGE_LO_MASK) | PAGE_SEL_EN;
> > -
> > -       select_paged_register(pcie, offset);
> > -       csr_writel(pcie, val, off);
> > -}
> > -
> > -static u32 read_paged_register(struct mobiveil_pcie *pcie, u32 offset)
> > -{
> > -       u32 off = (offset & PAGE_LO_MASK) | PAGE_SEL_EN;
> > -
> > -       select_paged_register(pcie, offset);
> > -       return csr_readl(pcie, off);
> > -}
> > -
> >  static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
> >                 int pci_addr, u32 type, u64 size)
> >  {
> > @@ -397,19 +467,19 @@ static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
> >         pio_ctrl_val = csr_readl(pcie, PAB_PEX_PIO_CTRL);
> >         csr_writel(pcie,
> >                 pio_ctrl_val | (1 << PIO_ENABLE_SHIFT), PAB_PEX_PIO_CTRL);
> > -       amap_ctrl_dw = read_paged_register(pcie, PAB_PEX_AMAP_CTRL(win_num));
> > +       amap_ctrl_dw = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
> >         amap_ctrl_dw = (amap_ctrl_dw | (type << AMAP_CTRL_TYPE_SHIFT));
> >         amap_ctrl_dw = (amap_ctrl_dw | (1 << AMAP_CTRL_EN_SHIFT));
> >
> > -       write_paged_register(pcie, amap_ctrl_dw | lower_32_bits(size64),
> > -                               PAB_PEX_AMAP_CTRL(win_num));
> > +       csr_writel(pcie, amap_ctrl_dw | lower_32_bits(size64),
> > +                  PAB_PEX_AMAP_CTRL(win_num));
> >
> > -       write_paged_register(pcie, upper_32_bits(size64),
> > -                               PAB_EXT_PEX_AMAP_SIZEN(win_num));
> > +       csr_writel(pcie, upper_32_bits(size64),
> > +                  PAB_EXT_PEX_AMAP_SIZEN(win_num));
> >
> > -       write_paged_register(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
> > -       write_paged_register(pcie, pci_addr, PAB_PEX_AMAP_PEX_WIN_L(win_num));
> > -       write_paged_register(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));
> > +       csr_writel(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
> > +       csr_writel(pcie, pci_addr, PAB_PEX_AMAP_PEX_WIN_L(win_num));
> > +       csr_writel(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));
> >  }
> >
> >  /*
> > @@ -437,8 +507,7 @@ static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
> >         csr_writel(pcie, 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
> >                         lower_32_bits(size64), PAB_AXI_AMAP_CTRL(win_num));
> >
> > -       write_paged_register(pcie, upper_32_bits(size64),
> > -                               PAB_EXT_AXI_AMAP_SIZE(win_num));
> > +       csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num));
> >
> >         /*
> >          * program AXI window base with appropriate value in
> > --
> > 2.17.1
> >

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

* Re: [PATCHv3 01/27] PCI: mobiveil: uniform the register accessors
  2019-02-05 17:43     ` Lorenzo Pieralisi
@ 2019-02-06 10:59       ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-06 10:59 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Z.q. Hou, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	bhelgaas, robh+dt, mark.rutland, shawnguo, Leo Li,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Lorenzo,

On Tue, Feb 5, 2019 at 11:13 PM Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
>
> On Tue, Feb 05, 2019 at 11:09:19AM +0530, Subrahmanya Lingappa wrote:
> > Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
>
> I have a feeling you do not read what I write.

My apologies, I do read. I am new to reviewing process and trying to learn here.
>
> Please never top-post.
>
I'll make sure not to top-post now on-wards.
>
> Read this, especially the email etiquette section:
>
> https://kernelnewbies.org/PatchCulture
>
I read it.

Thank you.
> >
> >
> >
> > On Tue, Jan 29, 2019 at 1:38 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
> > >
> > > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > >
> > > It's confused that R/W some registers by csr_readl()/csr_writel(),
> > > while others by read_paged_register()/write_paged_register().
> > > Actually the low 3KB of 4KB PCIe configure space can be accessed
> > > directly and high 1KB is paging area. So this patch uniformed the
> > > register accessors to csr_readl() and csr_writel() by comparing
> > > the register offset with page access boundary 3KB in the accessor
> > > internal.
> > >
> > > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > > Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> > > ---
> > > V3:
> > >  - No change
> > >
> > >  drivers/pci/controller/pcie-mobiveil.c | 179 +++++++++++++++++--------
> > >  1 file changed, 124 insertions(+), 55 deletions(-)
> > >
> > > diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> > > index 77052a0712d0..d55c7e780c6e 100644
> > > --- a/drivers/pci/controller/pcie-mobiveil.c
> > > +++ b/drivers/pci/controller/pcie-mobiveil.c
> > > @@ -47,7 +47,6 @@
> > >  #define  PAGE_SEL_SHIFT        13
> > >  #define  PAGE_SEL_MASK         0x3f
> > >  #define  PAGE_LO_MASK          0x3ff
> > > -#define  PAGE_SEL_EN           0xc00
> > >  #define  PAGE_SEL_OFFSET_SHIFT 10
> > >
> > >  #define PAB_AXI_PIO_CTRL       0x0840
> > > @@ -117,6 +116,12 @@
> > >  #define LINK_WAIT_MIN  90000
> > >  #define LINK_WAIT_MAX  100000
> > >
> > > +#define PAGED_ADDR_BNDRY                       0xc00
> > > +#define OFFSET_TO_PAGE_ADDR(off)               \
> > > +       ((off & PAGE_LO_MASK) | PAGED_ADDR_BNDRY)
> > > +#define OFFSET_TO_PAGE_IDX(off)                        \
> > > +       ((off >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK)
> > > +
> > >  struct mobiveil_msi {                  /* MSI information */
> > >         struct mutex lock;              /* protect bitmap variable */
> > >         struct irq_domain *msi_domain;
> > > @@ -145,15 +150,119 @@ struct mobiveil_pcie {
> > >         struct mobiveil_msi msi;
> > >  };
> > >
> > > -static inline void csr_writel(struct mobiveil_pcie *pcie, const u32 value,
> > > -               const u32 reg)
> > > +/*
> > > + * mobiveil_pcie_sel_page - routine to access paged register
> > > + *
> > > + * Registers whose address greater than PAGED_ADDR_BNDRY (0xc00) are paged,
> > > + * for this scheme to work extracted higher 6 bits of the offset will be
> > > + * written to pg_sel field of PAB_CTRL register and rest of the lower 10
> > > + * bits enabled with PAGED_ADDR_BNDRY are used as offset of the register.
> > > + */
> > > +static void mobiveil_pcie_sel_page(struct mobiveil_pcie *pcie, u8 pg_idx)
> > >  {
> > > -       writel_relaxed(value, pcie->csr_axi_slave_base + reg);
> > > +       u32 val;
> > > +
> > > +       val = readl(pcie->csr_axi_slave_base + PAB_CTRL);
> > > +       val &= ~(PAGE_SEL_MASK << PAGE_SEL_SHIFT);
> > > +       val |= (pg_idx & PAGE_SEL_MASK) << PAGE_SEL_SHIFT;
> > > +
> > > +       writel(val, pcie->csr_axi_slave_base + PAB_CTRL);
> > >  }
> > >
> > > -static inline u32 csr_readl(struct mobiveil_pcie *pcie, const u32 reg)
> > > +static void *mobiveil_pcie_comp_addr(struct mobiveil_pcie *pcie, u32 off)
> > >  {
> > > -       return readl_relaxed(pcie->csr_axi_slave_base + reg);
> > > +       if (off < PAGED_ADDR_BNDRY) {
> > > +               /* For directly accessed registers, clear the pg_sel field */
> > > +               mobiveil_pcie_sel_page(pcie, 0);
> > > +               return pcie->csr_axi_slave_base + off;
> > > +       }
> > > +
> > > +       mobiveil_pcie_sel_page(pcie, OFFSET_TO_PAGE_IDX(off));
> > > +       return pcie->csr_axi_slave_base + OFFSET_TO_PAGE_ADDR(off);
> > > +}
> > > +
> > > +static int mobiveil_pcie_read(void __iomem *addr, int size, u32 *val)
> > > +{
> > > +       if ((uintptr_t)addr & (size - 1)) {
> > > +               *val = 0;
> > > +               return PCIBIOS_BAD_REGISTER_NUMBER;
> > > +       }
> > > +
> > > +       switch (size) {
> > > +       case 4:
> > > +               *val = readl(addr);
> > > +               break;
> > > +       case 2:
> > > +               *val = readw(addr);
> > > +               break;
> > > +       case 1:
> > > +               *val = readb(addr);
> > > +               break;
> > > +       default:
> > > +               *val = 0;
> > > +               return PCIBIOS_BAD_REGISTER_NUMBER;
> > > +       }
> > > +
> > > +       return PCIBIOS_SUCCESSFUL;
> > > +}
> > > +
> > > +static int mobiveil_pcie_write(void __iomem *addr, int size, u32 val)
> > > +{
> > > +       if ((uintptr_t)addr & (size - 1))
> > > +               return PCIBIOS_BAD_REGISTER_NUMBER;
> > > +
> > > +       switch (size) {
> > > +       case 4:
> > > +               writel(val, addr);
> > > +               break;
> > > +       case 2:
> > > +               writew(val, addr);
> > > +               break;
> > > +       case 1:
> > > +               writeb(val, addr);
> > > +               break;
> > > +       default:
> > > +               return PCIBIOS_BAD_REGISTER_NUMBER;
> > > +       }
> > > +
> > > +       return PCIBIOS_SUCCESSFUL;
> > > +}
> > > +
> > > +static u32 csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size)
> > > +{
> > > +       void *addr;
> > > +       u32 val;
> > > +       int ret;
> > > +
> > > +       addr = mobiveil_pcie_comp_addr(pcie, off);
> > > +
> > > +       ret = mobiveil_pcie_read(addr, size, &val);
> > > +       if (ret)
> > > +               dev_err(&pcie->pdev->dev, "read CSR address failed\n");
> > > +
> > > +       return val;
> > > +}
> > > +
> > > +static void csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, size_t size)
> > > +{
> > > +       void *addr;
> > > +       int ret;
> > > +
> > > +       addr = mobiveil_pcie_comp_addr(pcie, off);
> > > +
> > > +       ret = mobiveil_pcie_write(addr, size, val);
> > > +       if (ret)
> > > +               dev_err(&pcie->pdev->dev, "write CSR address failed\n");
> > > +}
> > > +
> > > +static u32 csr_readl(struct mobiveil_pcie *pcie, u32 off)
> > > +{
> > > +       return csr_read(pcie, off, 0x4);
> > > +}
> > > +
> > > +static void csr_writel(struct mobiveil_pcie *pcie, u32 val, u32 off)
> > > +{
> > > +       csr_write(pcie, val, off, 0x4);
> > >  }
> > >
> > >  static bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie)
> > > @@ -342,45 +451,6 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
> > >         return 0;
> > >  }
> > >
> > > -/*
> > > - * select_paged_register - routine to access paged register of root complex
> > > - *
> > > - * registers of RC are paged, for this scheme to work
> > > - * extracted higher 6 bits of the offset will be written to pg_sel
> > > - * field of PAB_CTRL register and rest of the lower 10 bits enabled with
> > > - * PAGE_SEL_EN are used as offset of the register.
> > > - */
> > > -static void select_paged_register(struct mobiveil_pcie *pcie, u32 offset)
> > > -{
> > > -       int pab_ctrl_dw, pg_sel;
> > > -
> > > -       /* clear pg_sel field */
> > > -       pab_ctrl_dw = csr_readl(pcie, PAB_CTRL);
> > > -       pab_ctrl_dw = (pab_ctrl_dw & ~(PAGE_SEL_MASK << PAGE_SEL_SHIFT));
> > > -
> > > -       /* set pg_sel field */
> > > -       pg_sel = (offset >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK;
> > > -       pab_ctrl_dw |= ((pg_sel << PAGE_SEL_SHIFT));
> > > -       csr_writel(pcie, pab_ctrl_dw, PAB_CTRL);
> > > -}
> > > -
> > > -static void write_paged_register(struct mobiveil_pcie *pcie,
> > > -               u32 val, u32 offset)
> > > -{
> > > -       u32 off = (offset & PAGE_LO_MASK) | PAGE_SEL_EN;
> > > -
> > > -       select_paged_register(pcie, offset);
> > > -       csr_writel(pcie, val, off);
> > > -}
> > > -
> > > -static u32 read_paged_register(struct mobiveil_pcie *pcie, u32 offset)
> > > -{
> > > -       u32 off = (offset & PAGE_LO_MASK) | PAGE_SEL_EN;
> > > -
> > > -       select_paged_register(pcie, offset);
> > > -       return csr_readl(pcie, off);
> > > -}
> > > -
> > >  static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
> > >                 int pci_addr, u32 type, u64 size)
> > >  {
> > > @@ -397,19 +467,19 @@ static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
> > >         pio_ctrl_val = csr_readl(pcie, PAB_PEX_PIO_CTRL);
> > >         csr_writel(pcie,
> > >                 pio_ctrl_val | (1 << PIO_ENABLE_SHIFT), PAB_PEX_PIO_CTRL);
> > > -       amap_ctrl_dw = read_paged_register(pcie, PAB_PEX_AMAP_CTRL(win_num));
> > > +       amap_ctrl_dw = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
> > >         amap_ctrl_dw = (amap_ctrl_dw | (type << AMAP_CTRL_TYPE_SHIFT));
> > >         amap_ctrl_dw = (amap_ctrl_dw | (1 << AMAP_CTRL_EN_SHIFT));
> > >
> > > -       write_paged_register(pcie, amap_ctrl_dw | lower_32_bits(size64),
> > > -                               PAB_PEX_AMAP_CTRL(win_num));
> > > +       csr_writel(pcie, amap_ctrl_dw | lower_32_bits(size64),
> > > +                  PAB_PEX_AMAP_CTRL(win_num));
> > >
> > > -       write_paged_register(pcie, upper_32_bits(size64),
> > > -                               PAB_EXT_PEX_AMAP_SIZEN(win_num));
> > > +       csr_writel(pcie, upper_32_bits(size64),
> > > +                  PAB_EXT_PEX_AMAP_SIZEN(win_num));
> > >
> > > -       write_paged_register(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
> > > -       write_paged_register(pcie, pci_addr, PAB_PEX_AMAP_PEX_WIN_L(win_num));
> > > -       write_paged_register(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));
> > > +       csr_writel(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
> > > +       csr_writel(pcie, pci_addr, PAB_PEX_AMAP_PEX_WIN_L(win_num));
> > > +       csr_writel(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));
> > >  }
> > >
> > >  /*
> > > @@ -437,8 +507,7 @@ static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
> > >         csr_writel(pcie, 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
> > >                         lower_32_bits(size64), PAB_AXI_AMAP_CTRL(win_num));
> > >
> > > -       write_paged_register(pcie, upper_32_bits(size64),
> > > -                               PAB_EXT_AXI_AMAP_SIZE(win_num));
> > > +       csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num));
> > >
> > >         /*
> > >          * program AXI window base with appropriate value in
> > > --
> > > 2.17.1
> > >

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

* Re: [PATCHv3 13/27] PCI: mobiveil: move irq chained handler setup out of DT parse
  2019-01-29  8:09 ` [PATCHv3 13/27] PCI: mobiveil: move irq chained handler setup out of DT parse Z.q. Hou
@ 2019-02-08 12:30   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-08 12:30 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

On Tue, Jan 29, 2019 at 1:39 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> Move irq_set_chained_handler_and_data() out of DT parse function.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index c2848c22b466..db7ecb021c63 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -460,8 +460,6 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
>                 return -ENODEV;
>         }
>
> -       irq_set_chained_handler_and_data(pcie->irq, mobiveil_pcie_isr, pcie);
> -
>         return 0;
>  }
>
> @@ -902,6 +900,8 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
>                 goto error;
>         }
>
> +       irq_set_chained_handler_and_data(pcie->irq, mobiveil_pcie_isr, pcie);
> +
>         ret = devm_request_pci_bus_resources(dev, &pcie->resources);
>         if (ret)
>                 goto error;
> --
> 2.17.1
>
Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

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

* Re: [PATCHv3 14/27] PCI: mobiveil: initialize Primary/Secondary/Subordinate bus number
  2019-01-29  8:09 ` [PATCHv3 14/27] PCI: mobiveil: initialize Primary/Secondary/Subordinate bus number Z.q. Hou
@ 2019-02-08 12:31   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-08 12:31 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

On Tue, Jan 29, 2019 at 1:40 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> The reset value is all zero, so set a workable value for Primary,
> Secondary and Subordinate bus numbers.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/pcie-mobiveil.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c
> index db7ecb021c63..9210165fe8c0 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -582,6 +582,12 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>         u32 value, pab_ctrl, type;
>         struct resource_entry *win;
>
> +       /* setup bus numbers */
> +       value = csr_readl(pcie, PCI_PRIMARY_BUS);
> +       value &= 0xff000000;
> +       value |= 0x00ff0100;
> +       csr_writel(pcie, value, PCI_PRIMARY_BUS);
> +
>         /*
>          * program Bus Master Enable Bit in Command Register in PAB Config
>          * Space
> --
> 2.17.1
>
Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

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

* Re: [PATCHv3 15/27] dt-bindings: pci: mobiveil: change gpio_slave and apb_csr to optional
  2019-01-29  8:10 ` [PATCHv3 15/27] dt-bindings: pci: mobiveil: change gpio_slave and apb_csr to optional Z.q. Hou
@ 2019-02-08 12:32   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-08 12:32 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

On Tue, Jan 29, 2019 at 1:40 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> Change the "gpio_slave" and "apb_csr" to optional, the "gpio_slave"
> is not used in current code, and "apb_csr" is not used by some
> platforms.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Acked-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> Acked-by: Rob Herring <robh@kernel.org>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  Documentation/devicetree/bindings/pci/mobiveil-pcie.txt | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/pci/mobiveil-pcie.txt b/Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
> index a618d4787dd7..64156993e052 100644
> --- a/Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
> +++ b/Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
> @@ -10,8 +10,10 @@ Required properties:
>         interrupt source. The value must be 1.
>  - compatible: Should contain "mbvl,gpex40-pcie"
>  - reg: Should contain PCIe registers location and length
> +       Mandatory:
>         "config_axi_slave": PCIe controller registers
>         "csr_axi_slave"   : Bridge config registers
> +       Optional:
>         "gpio_slave"      : GPIO registers to control slot power
>         "apb_csr"         : MSI registers
>
> --
> 2.17.1
>
Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

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

* Re: [PATCHv3 16/27] PCI: mobiveil: refactor Mobiveil PCIe Host Bridge IP driver
  2019-01-29  8:10 ` [PATCHv3 16/27] PCI: mobiveil: refactor Mobiveil PCIe Host Bridge IP driver Z.q. Hou
@ 2019-02-08 12:37   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-08 12:37 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

On Tue, Jan 29, 2019 at 1:40 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> As the Mobiveil PCIe controller support RC&EP DAUL mode, and to
> make platforms which integrated the Mobiveil PCIe IP more easy
> to add their drivers, this patch moved the Mobiveil driver to
> a new directory 'drivers/pci/controller/mobiveil' and refactored
> it according to the abstraction of RC&EP (EP driver will be added
> later).
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  MAINTAINERS                                   |   2 +-
>  drivers/pci/controller/Kconfig                |  11 +-
>  drivers/pci/controller/Makefile               |   2 +-
>  drivers/pci/controller/mobiveil/Kconfig       |  24 +
>  drivers/pci/controller/mobiveil/Makefile      |   4 +
>  .../pcie-mobiveil-host.c}                     | 528 +++---------------
>  .../controller/mobiveil/pcie-mobiveil-plat.c  |  54 ++
>  .../pci/controller/mobiveil/pcie-mobiveil.c   | 228 ++++++++
>  .../pci/controller/mobiveil/pcie-mobiveil.h   | 187 +++++++
>  9 files changed, 587 insertions(+), 453 deletions(-)
>  create mode 100644 drivers/pci/controller/mobiveil/Kconfig
>  create mode 100644 drivers/pci/controller/mobiveil/Makefile
>  rename drivers/pci/controller/{pcie-mobiveil.c => mobiveil/pcie-mobiveil-host.c} (55%)
>  create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
>  create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.c
>  create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index ddcdc29dfe1f..3bca9642b08b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11709,7 +11709,7 @@ M:      Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
>  L:     linux-pci@vger.kernel.org
>  S:     Supported
>  F:     Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
> -F:     drivers/pci/controller/pcie-mobiveil.c
> +F:     drivers/pci/controller/mobiveil/pcie-mobiveil*
>
>  PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
>  M:     Thomas Petazzoni <thomas.petazzoni@bootlin.com>
> diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
> index 6671946dbf66..0e981ed00a75 100644
> --- a/drivers/pci/controller/Kconfig
> +++ b/drivers/pci/controller/Kconfig
> @@ -241,16 +241,6 @@ config PCIE_MEDIATEK
>           Say Y here if you want to enable PCIe controller support on
>           MediaTek SoCs.
>
> -config PCIE_MOBIVEIL
> -       bool "Mobiveil AXI PCIe controller"
> -       depends on ARCH_ZYNQMP || COMPILE_TEST
> -       depends on OF
> -       depends on PCI_MSI_IRQ_DOMAIN
> -       help
> -         Say Y here if you want to enable support for the Mobiveil AXI PCIe
> -         Soft IP. It has up to 8 outbound and inbound windows
> -         for address translation and it is a PCIe Gen4 IP.
> -
>  config PCIE_TANGO_SMP8759
>         bool "Tango SMP8759 PCIe controller (DANGEROUS)"
>         depends on ARCH_TANGO && PCI_MSI && OF
> @@ -281,4 +271,5 @@ config VMD
>           module will be called vmd.
>
>  source "drivers/pci/controller/dwc/Kconfig"
> +source "drivers/pci/controller/mobiveil/Kconfig"
>  endmenu
> diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
> index d56a507495c5..b79a615041a0 100644
> --- a/drivers/pci/controller/Makefile
> +++ b/drivers/pci/controller/Makefile
> @@ -26,11 +26,11 @@ obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
>  obj-$(CONFIG_PCIE_ROCKCHIP_EP) += pcie-rockchip-ep.o
>  obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie-rockchip-host.o
>  obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
> -obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o
>  obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
>  obj-$(CONFIG_VMD) += vmd.o
>  # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
>  obj-y                          += dwc/
> +obj-y                          += mobiveil/
>
>
>  # The following drivers are for devices that use the generic ACPI
> diff --git a/drivers/pci/controller/mobiveil/Kconfig b/drivers/pci/controller/mobiveil/Kconfig
> new file mode 100644
> index 000000000000..64343c07bfed
> --- /dev/null
> +++ b/drivers/pci/controller/mobiveil/Kconfig
> @@ -0,0 +1,24 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +menu "Mobiveil PCIe Core Support"
> +       depends on PCI
> +
> +config PCIE_MOBIVEIL
> +       bool
> +
> +config PCIE_MOBIVEIL_HOST
> +        bool
> +       depends on PCI_MSI_IRQ_DOMAIN
> +        select PCIE_MOBIVEIL
> +
> +config PCIE_MOBIVEIL_PLAT
> +       bool "Mobiveil AXI PCIe controller"
> +       depends on ARCH_ZYNQMP || COMPILE_TEST
> +       depends on OF
> +       select PCIE_MOBIVEIL_HOST
> +       help
> +         Say Y here if you want to enable support for the Mobiveil AXI PCIe
> +         Soft IP. It has up to 8 outbound and inbound windows
> +         for address translation and it is a PCIe Gen4 IP.
> +
> +endmenu
> diff --git a/drivers/pci/controller/mobiveil/Makefile b/drivers/pci/controller/mobiveil/Makefile
> new file mode 100644
> index 000000000000..9fb6d1c6504d
> --- /dev/null
> +++ b/drivers/pci/controller/mobiveil/Makefile
> @@ -0,0 +1,4 @@
> +# SPDX-License-Identifier: GPL-2.0
> +obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o
> +obj-$(CONFIG_PCIE_MOBIVEIL_HOST) += pcie-mobiveil-host.o
> +obj-$(CONFIG_PCIE_MOBIVEIL_PLAT) += pcie-mobiveil-plat.o
> diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> similarity index 55%
> rename from drivers/pci/controller/pcie-mobiveil.c
> rename to drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> index 9210165fe8c0..dc5324d94466 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> @@ -4,9 +4,9 @@
>   *
>   * Copyright (c) 2018 Mobiveil Inc.
>   * Author: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> + * Refactor: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
>   */
>
> -#include <linux/delay.h>
>  #include <linux/init.h>
>  #include <linux/interrupt.h>
>  #include <linux/irq.h>
> @@ -23,275 +23,21 @@
>  #include <linux/platform_device.h>
>  #include <linux/slab.h>
>
> -#include "../pci.h"
> -
> -/* register offsets and bit positions */
> -
> -/*
> - * translation tables are grouped into windows, each window registers are
> - * grouped into blocks of 4 or 16 registers each
> - */
> -#define PAB_REG_BLOCK_SIZE             16
> -#define PAB_EXT_REG_BLOCK_SIZE         4
> -
> -#define PAB_REG_ADDR(offset, win)      \
> -       (offset + (win * PAB_REG_BLOCK_SIZE))
> -#define PAB_EXT_REG_ADDR(offset, win)  \
> -       (offset + (win * PAB_EXT_REG_BLOCK_SIZE))
> -
> -#define LTSSM_STATUS                   0x0404
> -#define  LTSSM_STATUS_L0_MASK          0x3f
> -#define  LTSSM_STATUS_L0               0x2d
> -
> -#define PAB_CTRL                       0x0808
> -#define  AMBA_PIO_ENABLE_SHIFT         0
> -#define  PEX_PIO_ENABLE_SHIFT          1
> -#define  PAGE_SEL_SHIFT                        13
> -#define  PAGE_SEL_MASK                 0x3f
> -#define  PAGE_LO_MASK                  0x3ff
> -#define  PAGE_SEL_OFFSET_SHIFT         10
> -
> -#define PAB_AXI_PIO_CTRL               0x0840
> -#define  APIO_EN_MASK                  0xf
> -
> -#define PAB_PEX_PIO_CTRL               0x08c0
> -#define  PIO_ENABLE_SHIFT              0
> -
> -#define PAB_INTP_AMBA_MISC_ENB         0x0b0c
> -#define PAB_INTP_AMBA_MISC_STAT                0x0b1c
> -#define  PAB_INTP_INTX_MASK            0x01e0
> -#define  PAB_INTP_MSI_MASK             0x8
> -
> -#define PAB_AXI_AMAP_CTRL(win)         PAB_REG_ADDR(0x0ba0, win)
> -#define  WIN_ENABLE_SHIFT              0
> -#define  WIN_TYPE_SHIFT                        1
> -#define  WIN_TYPE_MASK                 0x3
> -#define  WIN_SIZE_SHIFT                        10
> -#define  WIN_SIZE_MASK                 0x3fffff
> -
> -#define PAB_EXT_AXI_AMAP_SIZE(win)     PAB_EXT_REG_ADDR(0xbaf0, win)
> -
> -#define PAB_EXT_AXI_AMAP_AXI_WIN(win)  PAB_EXT_REG_ADDR(0x80a0, win)
> -#define PAB_AXI_AMAP_AXI_WIN(win)      PAB_REG_ADDR(0x0ba4, win)
> -#define  AXI_WINDOW_ALIGN_MASK         3
> -
> -#define PAB_AXI_AMAP_PEX_WIN_L(win)    PAB_REG_ADDR(0x0ba8, win)
> -#define  PAB_BUS_SHIFT                 24
> -#define  PAB_DEVICE_SHIFT              19
> -#define  PAB_FUNCTION_SHIFT            16
> -
> -#define PAB_AXI_AMAP_PEX_WIN_H(win)    PAB_REG_ADDR(0x0bac, win)
> -#define PAB_INTP_AXI_PIO_CLASS         0x474
> -
> -#define PAB_PEX_AMAP_CTRL(win)         PAB_REG_ADDR(0x4ba0, win)
> -#define  AMAP_CTRL_EN_SHIFT            0
> -#define  AMAP_CTRL_TYPE_SHIFT          1
> -#define  AMAP_CTRL_TYPE_MASK           3
> -
> -#define PAB_EXT_PEX_AMAP_SIZEN(win)    PAB_EXT_REG_ADDR(0xbef0, win)
> -#define PAB_EXT_PEX_AMAP_AXI_WIN(win)  PAB_EXT_REG_ADDR(0xb4a0, win)
> -#define PAB_PEX_AMAP_AXI_WIN(win)      PAB_REG_ADDR(0x4ba4, win)
> -#define PAB_PEX_AMAP_PEX_WIN_L(win)    PAB_REG_ADDR(0x4ba8, win)
> -#define PAB_PEX_AMAP_PEX_WIN_H(win)    PAB_REG_ADDR(0x4bac, win)
> -
> -/* starting offset of INTX bits in status register */
> -#define PAB_INTX_START                 5
> -
> -/* supported number of MSI interrupts */
> -#define PCI_NUM_MSI                    16
> -
> -/* MSI registers */
> -#define MSI_BASE_LO_OFFSET             0x04
> -#define MSI_BASE_HI_OFFSET             0x08
> -#define MSI_SIZE_OFFSET                        0x0c
> -#define MSI_ENABLE_OFFSET              0x14
> -#define MSI_STATUS_OFFSET              0x18
> -#define MSI_DATA_OFFSET                        0x20
> -#define MSI_ADDR_L_OFFSET              0x24
> -#define MSI_ADDR_H_OFFSET              0x28
> -
> -/* outbound and inbound window definitions */
> -#define WIN_NUM_0                      0
> -#define WIN_NUM_1                      1
> -#define CFG_WINDOW_TYPE                        0
> -#define IO_WINDOW_TYPE                 1
> -#define MEM_WINDOW_TYPE                        2
> -#define IB_WIN_SIZE                    ((u64)256 * 1024 * 1024 * 1024)
> -#define MAX_PIO_WINDOWS                        8
> -
> -/* Parameters for the waiting for link up routine */
> -#define LINK_WAIT_MAX_RETRIES          10
> -#define LINK_WAIT_MIN                  90000
> -#define LINK_WAIT_MAX                  100000
> -
> -#define PAGED_ADDR_BNDRY               0xc00
> -#define OFFSET_TO_PAGE_ADDR(off)       \
> -       ((off & PAGE_LO_MASK) | PAGED_ADDR_BNDRY)
> -#define OFFSET_TO_PAGE_IDX(off)                \
> -       ((off >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK)
> -
> -struct mobiveil_msi {                  /* MSI information */
> -       struct mutex lock;              /* protect bitmap variable */
> -       struct irq_domain *msi_domain;
> -       struct irq_domain *dev_domain;
> -       phys_addr_t msi_pages_phys;
> -       int num_of_vectors;
> -       DECLARE_BITMAP(msi_irq_in_use, PCI_NUM_MSI);
> -};
> -
> -struct mobiveil_pcie {
> -       struct platform_device *pdev;
> -       struct list_head resources;
> -       void __iomem *config_axi_slave_base;    /* endpoint config base */
> -       void __iomem *csr_axi_slave_base;       /* root port config base */
> -       void __iomem *apb_csr_base;     /* MSI register base */
> -       phys_addr_t pcie_reg_base;      /* Physical PCIe Controller Base */
> -       struct irq_domain *intx_domain;
> -       raw_spinlock_t intx_mask_lock;
> -       int irq;
> -       int apio_wins;
> -       int ppio_wins;
> -       int ob_wins_configured;         /* configured outbound windows */
> -       int ib_wins_configured;         /* configured inbound windows */
> -       struct resource *ob_io_res;
> -       char root_bus_nr;
> -       struct mobiveil_msi msi;
> -};
> -
> -/*
> - * mobiveil_pcie_sel_page - routine to access paged register
> - *
> - * Registers whose address greater than PAGED_ADDR_BNDRY (0xc00) are paged,
> - * for this scheme to work extracted higher 6 bits of the offset will be
> - * written to pg_sel field of PAB_CTRL register and rest of the lower 10
> - * bits enabled with PAGED_ADDR_BNDRY are used as offset of the register.
> - */
> -static void mobiveil_pcie_sel_page(struct mobiveil_pcie *pcie, u8 pg_idx)
> -{
> -       u32 val;
> -
> -       val = readl(pcie->csr_axi_slave_base + PAB_CTRL);
> -       val &= ~(PAGE_SEL_MASK << PAGE_SEL_SHIFT);
> -       val |= (pg_idx & PAGE_SEL_MASK) << PAGE_SEL_SHIFT;
> -
> -       writel(val, pcie->csr_axi_slave_base + PAB_CTRL);
> -}
> -
> -static void *mobiveil_pcie_comp_addr(struct mobiveil_pcie *pcie, u32 off)
> -{
> -       if (off < PAGED_ADDR_BNDRY) {
> -               /* For directly accessed registers, clear the pg_sel field */
> -               mobiveil_pcie_sel_page(pcie, 0);
> -               return pcie->csr_axi_slave_base + off;
> -       }
> -
> -       mobiveil_pcie_sel_page(pcie, OFFSET_TO_PAGE_IDX(off));
> -       return pcie->csr_axi_slave_base + OFFSET_TO_PAGE_ADDR(off);
> -}
> -
> -static int mobiveil_pcie_read(void __iomem *addr, int size, u32 *val)
> -{
> -       if ((uintptr_t)addr & (size - 1)) {
> -               *val = 0;
> -               return PCIBIOS_BAD_REGISTER_NUMBER;
> -       }
> -
> -       switch (size) {
> -       case 4:
> -               *val = readl(addr);
> -               break;
> -       case 2:
> -               *val = readw(addr);
> -               break;
> -       case 1:
> -               *val = readb(addr);
> -               break;
> -       default:
> -               *val = 0;
> -               return PCIBIOS_BAD_REGISTER_NUMBER;
> -       }
> -
> -       return PCIBIOS_SUCCESSFUL;
> -}
> -
> -static int mobiveil_pcie_write(void __iomem *addr, int size, u32 val)
> -{
> -       if ((uintptr_t)addr & (size - 1))
> -               return PCIBIOS_BAD_REGISTER_NUMBER;
> -
> -       switch (size) {
> -       case 4:
> -               writel(val, addr);
> -               break;
> -       case 2:
> -               writew(val, addr);
> -               break;
> -       case 1:
> -               writeb(val, addr);
> -               break;
> -       default:
> -               return PCIBIOS_BAD_REGISTER_NUMBER;
> -       }
> -
> -       return PCIBIOS_SUCCESSFUL;
> -}
> -
> -static u32 csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size)
> -{
> -       void *addr;
> -       u32 val;
> -       int ret;
> -
> -       addr = mobiveil_pcie_comp_addr(pcie, off);
> -
> -       ret = mobiveil_pcie_read(addr, size, &val);
> -       if (ret)
> -               dev_err(&pcie->pdev->dev, "read CSR address failed\n");
> -
> -       return val;
> -}
> -
> -static void csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, size_t size)
> -{
> -       void *addr;
> -       int ret;
> -
> -       addr = mobiveil_pcie_comp_addr(pcie, off);
> -
> -       ret = mobiveil_pcie_write(addr, size, val);
> -       if (ret)
> -               dev_err(&pcie->pdev->dev, "write CSR address failed\n");
> -}
> -
> -static u32 csr_readl(struct mobiveil_pcie *pcie, u32 off)
> -{
> -       return csr_read(pcie, off, 0x4);
> -}
> -
> -static void csr_writel(struct mobiveil_pcie *pcie, u32 val, u32 off)
> -{
> -       csr_write(pcie, val, off, 0x4);
> -}
> -
> -static bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie)
> -{
> -       return (csr_readl(pcie, LTSSM_STATUS) &
> -               LTSSM_STATUS_L0_MASK) == LTSSM_STATUS_L0;
> -}
> +#include "pcie-mobiveil.h"
>
>  static bool mobiveil_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
>  {
>         struct mobiveil_pcie *pcie = bus->sysdata;
>
>         /* Only one device down on each root port */
> -       if ((bus->number == pcie->root_bus_nr) && (devfn > 0))
> +       if ((bus->number == pcie->rp.root_bus_nr) && (devfn > 0))
>                 return false;
>
>         /*
>          * Do not read more than one device on the bus directly
>          * attached to RC
>          */
> -       if ((bus->primary == pcie->root_bus_nr) && (devfn > 0))
> +       if ((bus->primary == pcie->rp.root_bus_nr) && (devfn > 0))
>                 return false;
>
>         return true;
> @@ -311,7 +57,7 @@ static void __iomem *mobiveil_pcie_map_bus(struct pci_bus *bus,
>                 return NULL;
>
>         /* RC config access */
> -       if (bus->number == pcie->root_bus_nr)
> +       if (bus->number == pcie->rp.root_bus_nr)
>                 return pcie->csr_axi_slave_base + where;
>
>         /*
> @@ -326,7 +72,7 @@ static void __iomem *mobiveil_pcie_map_bus(struct pci_bus *bus,
>
>         csr_writel(pcie, value, PAB_AXI_AMAP_PEX_WIN_L(WIN_NUM_0));
>
> -       return pcie->config_axi_slave_base + where;
> +       return pcie->rp.config_axi_slave_base + where;
>  }
>
>  static struct pci_ops mobiveil_pcie_ops = {
> @@ -340,7 +86,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
>         struct irq_chip *chip = irq_desc_get_chip(desc);
>         struct mobiveil_pcie *pcie = irq_desc_get_handler_data(desc);
>         struct device *dev = &pcie->pdev->dev;
> -       struct mobiveil_msi *msi = &pcie->msi;
> +       struct mobiveil_msi *msi = &pcie->rp.msi;
>         u32 msi_data, msi_addr_lo, msi_addr_hi;
>         u32 intr_status, msi_status;
>         unsigned long shifted_status;
> @@ -365,7 +111,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
>                 shifted_status >>= PAB_INTX_START;
>                 do {
>                         for_each_set_bit(bit, &shifted_status, PCI_NUM_INTX) {
> -                               virq = irq_find_mapping(pcie->intx_domain,
> +                               virq = irq_find_mapping(pcie->rp.intx_domain,
>                                                         bit + 1);
>                                 if (virq)
>                                         generic_handle_irq(virq);
> @@ -428,10 +174,10 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
>         /* map config resource */
>         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
>                                            "config_axi_slave");
> -       pcie->config_axi_slave_base = devm_pci_remap_cfg_resource(dev, res);
> -       if (IS_ERR(pcie->config_axi_slave_base))
> -               return PTR_ERR(pcie->config_axi_slave_base);
> -       pcie->ob_io_res = res;
> +       pcie->rp.config_axi_slave_base = devm_pci_remap_cfg_resource(dev, res);
> +       if (IS_ERR(pcie->rp.config_axi_slave_base))
> +               return PTR_ERR(pcie->rp.config_axi_slave_base);
> +       pcie->rp.ob_io_res = res;
>
>         /* map csr resource */
>         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> @@ -441,12 +187,6 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
>                 return PTR_ERR(pcie->csr_axi_slave_base);
>         pcie->pcie_reg_base = res->start;
>
> -       /* map MSI config resource */
> -       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apb_csr");
> -       pcie->apb_csr_base = devm_pci_remap_cfg_resource(dev, res);
> -       if (IS_ERR(pcie->apb_csr_base))
> -               return PTR_ERR(pcie->apb_csr_base);
> -
>         /* read the number of windows requested */
>         if (of_property_read_u32(node, "apio-wins", &pcie->apio_wins))
>                 pcie->apio_wins = MAX_PIO_WINDOWS;
> @@ -454,119 +194,15 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
>         if (of_property_read_u32(node, "ppio-wins", &pcie->ppio_wins))
>                 pcie->ppio_wins = MAX_PIO_WINDOWS;
>
> -       pcie->irq = platform_get_irq(pdev, 0);
> -       if (pcie->irq <= 0) {
> -               dev_err(dev, "failed to map IRQ: %d\n", pcie->irq);
> -               return -ENODEV;
> -       }
> -
>         return 0;
>  }
>
> -static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
> -                              u64 cpu_addr, u64 pci_addr, u32 type, u64 size)
> -{
> -       u32 value;
> -       u64 size64 = ~(size - 1);
> -
> -       if (win_num >= pcie->ppio_wins) {
> -               dev_err(&pcie->pdev->dev,
> -                       "ERROR: max inbound windows reached !\n");
> -               return;
> -       }
> -
> -       value = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
> -       value &= ~(AMAP_CTRL_TYPE_MASK << AMAP_CTRL_TYPE_SHIFT |
> -                WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> -       value |= (type << AMAP_CTRL_TYPE_SHIFT) | (1 << AMAP_CTRL_EN_SHIFT) |
> -                (lower_32_bits(size64) & WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> -       csr_writel(pcie, value, PAB_PEX_AMAP_CTRL(win_num));
> -
> -       csr_writel(pcie, upper_32_bits(size64),
> -                  PAB_EXT_PEX_AMAP_SIZEN(win_num));
> -
> -       csr_writel(pcie, lower_32_bits(cpu_addr),
> -                  PAB_PEX_AMAP_AXI_WIN(win_num));
> -       csr_writel(pcie, upper_32_bits(cpu_addr),
> -                  PAB_EXT_PEX_AMAP_AXI_WIN(win_num));
> -
> -       csr_writel(pcie, lower_32_bits(pci_addr),
> -                  PAB_PEX_AMAP_PEX_WIN_L(win_num));
> -       csr_writel(pcie, upper_32_bits(pci_addr),
> -                  PAB_PEX_AMAP_PEX_WIN_H(win_num));
> -
> -       pcie->ib_wins_configured++;
> -}
> -
> -/*
> - * routine to program the outbound windows
> - */
> -static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
> -                              u64 cpu_addr, u64 pci_addr, u32 type, u64 size)
> -{
> -
> -       u32 value;
> -       u64 size64 = ~(size - 1);
> -
> -       if (win_num >= pcie->apio_wins) {
> -               dev_err(&pcie->pdev->dev,
> -                       "ERROR: max outbound windows reached !\n");
> -               return;
> -       }
> -
> -       /*
> -        * program Enable Bit to 1, Type Bit to (00) base 2, AXI Window Size Bit
> -        * to 4 KB in PAB_AXI_AMAP_CTRL register
> -        */
> -       value = csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num));
> -       value &= ~(WIN_TYPE_MASK << WIN_TYPE_SHIFT |
> -                WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> -       value |= 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
> -                (lower_32_bits(size64) & WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> -       csr_writel(pcie, value, PAB_AXI_AMAP_CTRL(win_num));
> -
> -       csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num));
> -
> -       /*
> -        * program AXI window base with appropriate value in
> -        * PAB_AXI_AMAP_AXI_WIN0 register
> -        */
> -       csr_writel(pcie, lower_32_bits(cpu_addr) & (~AXI_WINDOW_ALIGN_MASK),
> -                  PAB_AXI_AMAP_AXI_WIN(win_num));
> -       csr_writel(pcie, upper_32_bits(cpu_addr),
> -                  PAB_EXT_AXI_AMAP_AXI_WIN(win_num));
> -
> -       csr_writel(pcie, lower_32_bits(pci_addr),
> -                  PAB_AXI_AMAP_PEX_WIN_L(win_num));
> -       csr_writel(pcie, upper_32_bits(pci_addr),
> -                  PAB_AXI_AMAP_PEX_WIN_H(win_num));
> -
> -       pcie->ob_wins_configured++;
> -}
> -
> -static int mobiveil_bringup_link(struct mobiveil_pcie *pcie)
> -{
> -       int retries;
> -
> -       /* check if the link is up or not */
> -       for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
> -               if (mobiveil_pcie_link_up(pcie))
> -                       return 0;
> -
> -               usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
> -       }
> -
> -       dev_err(&pcie->pdev->dev, "link never came up\n");
> -
> -       return -ETIMEDOUT;
> -}
> -
>  static void mobiveil_pcie_enable_msi(struct mobiveil_pcie *pcie)
>  {
>         phys_addr_t msg_addr = pcie->pcie_reg_base;
> -       struct mobiveil_msi *msi = &pcie->msi;
> +       struct mobiveil_msi *msi = &pcie->rp.msi;
>
> -       pcie->msi.num_of_vectors = PCI_NUM_MSI;
> +       msi->num_of_vectors = PCI_NUM_MSI;
>         msi->msi_pages_phys = (phys_addr_t)msg_addr;
>
>         writel_relaxed(lower_32_bits(msg_addr),
> @@ -604,9 +240,6 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>         pab_ctrl |= (1 << AMBA_PIO_ENABLE_SHIFT) | (1 << PEX_PIO_ENABLE_SHIFT);
>         csr_writel(pcie, pab_ctrl, PAB_CTRL);
>
> -       csr_writel(pcie, (PAB_INTP_INTX_MASK | PAB_INTP_MSI_MASK),
> -                  PAB_INTP_AMBA_MISC_ENB);
> -
>         /*
>          * program PIO Enable Bit to 1 and Config Window Enable Bit to 1 in
>          * PAB_AXI_PIO_CTRL Register
> @@ -628,20 +261,24 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>          */
>
>         /* config outbound translation window */
> -       program_ob_windows(pcie, WIN_NUM_0, pcie->ob_io_res->start, 0,
> -                          CFG_WINDOW_TYPE, resource_size(pcie->ob_io_res));
> +       program_ob_windows(pcie, WIN_NUM_0, pcie->rp.ob_io_res->start, 0,
> +                          CFG_WINDOW_TYPE, resource_size(pcie->rp.ob_io_res));
>
>         /* memory inbound translation window */
>         program_ib_windows(pcie, WIN_NUM_0, 0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
>
>         /* Get the I/O and memory ranges from DT */
>         resource_list_for_each_entry(win, &pcie->resources) {
> -               if (resource_type(win->res) == IORESOURCE_MEM)
> +               if (resource_type(win->res) == IORESOURCE_MEM) {
>                         type = MEM_WINDOW_TYPE;
> -               else if (resource_type(win->res) == IORESOURCE_IO)
> +               } else if (resource_type(win->res) == IORESOURCE_IO) {
>                         type = IO_WINDOW_TYPE;
> -               else
> +               } else if (resource_type(win->res) == IORESOURCE_BUS) {
> +                       pcie->rp.root_bus_nr = win->res->start;
> +                       continue;
> +               } else {
>                         continue;
> +               }
>
>                 /* configure outbound translation window */
>                 program_ob_windows(pcie, pcie->ob_wins_configured,
> @@ -656,9 +293,6 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>         value |= (PCI_CLASS_BRIDGE_PCI << 16);
>         csr_writel(pcie, value, PAB_INTP_AXI_PIO_CLASS);
>
> -       /* setup MSI hardware registers */
> -       mobiveil_pcie_enable_msi(pcie);
> -
>         return 0;
>  }
>
> @@ -671,11 +305,11 @@ static void mobiveil_mask_intx_irq(struct irq_data *data)
>
>         pcie = irq_desc_get_chip_data(desc);
>         mask = 1 << ((data->hwirq + PAB_INTX_START) - 1);
> -       raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags);
> +       raw_spin_lock_irqsave(&pcie->rp.intx_mask_lock, flags);
>         shifted_val = csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB);
>         shifted_val &= ~mask;
>         csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB);
> -       raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags);
> +       raw_spin_unlock_irqrestore(&pcie->rp.intx_mask_lock, flags);
>  }
>
>  static void mobiveil_unmask_intx_irq(struct irq_data *data)
> @@ -687,11 +321,11 @@ static void mobiveil_unmask_intx_irq(struct irq_data *data)
>
>         pcie = irq_desc_get_chip_data(desc);
>         mask = 1 << ((data->hwirq + PAB_INTX_START) - 1);
> -       raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags);
> +       raw_spin_lock_irqsave(&pcie->rp.intx_mask_lock, flags);
>         shifted_val = csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB);
>         shifted_val |= mask;
>         csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB);
> -       raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags);
> +       raw_spin_unlock_irqrestore(&pcie->rp.intx_mask_lock, flags);
>  }
>
>  static struct irq_chip intx_irq_chip = {
> @@ -759,7 +393,7 @@ static int mobiveil_irq_msi_domain_alloc(struct irq_domain *domain,
>                                          unsigned int nr_irqs, void *args)
>  {
>         struct mobiveil_pcie *pcie = domain->host_data;
> -       struct mobiveil_msi *msi = &pcie->msi;
> +       struct mobiveil_msi *msi = &pcie->rp.msi;
>         unsigned long bit;
>
>         WARN_ON(nr_irqs != 1);
> @@ -786,7 +420,7 @@ static void mobiveil_irq_msi_domain_free(struct irq_domain *domain,
>  {
>         struct irq_data *d = irq_domain_get_irq_data(domain, virq);
>         struct mobiveil_pcie *pcie = irq_data_get_irq_chip_data(d);
> -       struct mobiveil_msi *msi = &pcie->msi;
> +       struct mobiveil_msi *msi = &pcie->rp.msi;
>
>         mutex_lock(&msi->lock);
>
> @@ -807,9 +441,9 @@ static int mobiveil_allocate_msi_domains(struct mobiveil_pcie *pcie)
>  {
>         struct device *dev = &pcie->pdev->dev;
>         struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
> -       struct mobiveil_msi *msi = &pcie->msi;
> +       struct mobiveil_msi *msi = &pcie->rp.msi;
>
> -       mutex_init(&pcie->msi.lock);
> +       mutex_init(&msi->lock);
>         msi->dev_domain = irq_domain_add_linear(NULL, msi->num_of_vectors,
>                                                 &msi_domain_ops, pcie);
>         if (!msi->dev_domain) {
> @@ -836,15 +470,15 @@ static int mobiveil_pcie_init_irq_domain(struct mobiveil_pcie *pcie)
>         int ret;
>
>         /* setup INTx */
> -       pcie->intx_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
> -                                                 &intx_domain_ops, pcie);
> +       pcie->rp.intx_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
> +                                                    &intx_domain_ops, pcie);
>
> -       if (!pcie->intx_domain) {
> +       if (!pcie->rp.intx_domain) {
>                 dev_err(dev, "Failed to get a INTx IRQ domain\n");
>                 return -ENOMEM;
>         }
>
> -       raw_spin_lock_init(&pcie->intx_mask_lock);
> +       raw_spin_lock_init(&pcie->rp.intx_mask_lock);
>
>         /* setup MSI */
>         ret = mobiveil_allocate_msi_domains(pcie);
> @@ -854,24 +488,58 @@ static int mobiveil_pcie_init_irq_domain(struct mobiveil_pcie *pcie)
>         return 0;
>  }
>
> -static int mobiveil_pcie_probe(struct platform_device *pdev)
> +static int mobiveil_pcie_interrupt_init(struct mobiveil_pcie *pcie)
> +{
> +       struct device *dev = &pcie->pdev->dev;
> +       struct resource *res;
> +       int ret;
> +
> +       if (pcie->rp.ops->interrupt_init)
> +               return pcie->rp.ops->interrupt_init(pcie);
> +
> +       /* map MSI config resource */
> +       res = platform_get_resource_byname(pcie->pdev, IORESOURCE_MEM,
> +                                          "apb_csr");
> +       pcie->apb_csr_base = devm_pci_remap_cfg_resource(dev, res);
> +       if (IS_ERR(pcie->apb_csr_base))
> +               return PTR_ERR(pcie->apb_csr_base);
> +
> +       /* setup MSI hardware registers */
> +       mobiveil_pcie_enable_msi(pcie);
> +
> +       pcie->rp.irq = platform_get_irq(pcie->pdev, 0);
> +       if (pcie->rp.irq <= 0) {
> +               dev_err(dev, "failed to map IRQ: %d\n", pcie->rp.irq);
> +               return -ENODEV;
> +       }
> +
> +       /* initialize the IRQ domains */
> +       ret = mobiveil_pcie_init_irq_domain(pcie);
> +       if (ret) {
> +               dev_err(dev, "Failed creating IRQ Domain\n");
> +               return ret;
> +       }
> +
> +       irq_set_chained_handler_and_data(pcie->rp.irq,
> +                                        mobiveil_pcie_isr, pcie);
> +
> +       /* Enable interrupts */
> +       csr_writel(pcie, (PAB_INTP_INTX_MASK | PAB_INTP_MSI_MASK),
> +                  PAB_INTP_AMBA_MISC_ENB);
> +
> +       return 0;
> +}
> +
> +int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
>  {
> -       struct mobiveil_pcie *pcie;
>         struct pci_bus *bus;
>         struct pci_bus *child;
>         struct pci_host_bridge *bridge;
> -       struct device *dev = &pdev->dev;
> +       struct device *dev = &pcie->pdev->dev;
>         resource_size_t iobase;
>         int ret;
>
> -       /* allocate the PCIe port */
> -       bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
> -       if (!bridge)
> -               return -ENOMEM;
> -
> -       pcie = pci_host_bridge_priv(bridge);
> -
> -       pcie->pdev = pdev;
> +       INIT_LIST_HEAD(&pcie->resources);
>
>         ret = mobiveil_pcie_parse_dt(pcie);
>         if (ret) {
> @@ -879,7 +547,10 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
>                 return ret;
>         }
>
> -       INIT_LIST_HEAD(&pcie->resources);
> +       /* allocate the PCIe port */
> +       bridge = devm_pci_alloc_host_bridge(dev, 0);
> +       if (!bridge)
> +               return -ENOMEM;
>
>         /* parse the host bridge base addresses from the device tree file */
>         ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
> @@ -899,15 +570,12 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
>                 goto error;
>         }
>
> -       /* initialize the IRQ domains */
> -       ret = mobiveil_pcie_init_irq_domain(pcie);
> +       ret = mobiveil_pcie_interrupt_init(pcie);
>         if (ret) {
> -               dev_err(dev, "Failed creating IRQ Domain\n");
> +               dev_err(dev, "Interrupt init failed\n");
>                 goto error;
>         }
>
> -       irq_set_chained_handler_and_data(pcie->irq, mobiveil_pcie_isr, pcie);
> -
>         ret = devm_request_pci_bus_resources(dev, &pcie->resources);
>         if (ret)
>                 goto error;
> @@ -916,7 +584,7 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
>         list_splice_init(&pcie->resources, &bridge->windows);
>         bridge->dev.parent = dev;
>         bridge->sysdata = pcie;
> -       bridge->busnr = pcie->root_bus_nr;
> +       bridge->busnr = pcie->rp.root_bus_nr;
>         bridge->ops = &mobiveil_pcie_ops;
>         bridge->map_irq = of_irq_parse_and_map_pci;
>         bridge->swizzle_irq = pci_common_swizzle;
> @@ -944,25 +612,3 @@ static int mobiveil_pcie_probe(struct platform_device *pdev)
>         pci_free_resource_list(&pcie->resources);
>         return ret;
>  }
> -
> -static const struct of_device_id mobiveil_pcie_of_match[] = {
> -       {.compatible = "mbvl,gpex40-pcie",},
> -       {},
> -};
> -
> -MODULE_DEVICE_TABLE(of, mobiveil_pcie_of_match);
> -
> -static struct platform_driver mobiveil_pcie_driver = {
> -       .probe = mobiveil_pcie_probe,
> -       .driver = {
> -               .name = "mobiveil-pcie",
> -               .of_match_table = mobiveil_pcie_of_match,
> -               .suppress_bind_attrs = true,
> -       },
> -};
> -
> -builtin_platform_driver(mobiveil_pcie_driver);
> -
> -MODULE_LICENSE("GPL v2");
> -MODULE_DESCRIPTION("Mobiveil PCIe host controller driver");
> -MODULE_AUTHOR("Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>");
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
> new file mode 100644
> index 000000000000..216c62f35568
> --- /dev/null
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
> @@ -0,0 +1,54 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PCIe host controller driver for Mobiveil PCIe Host controller
> + *
> + * Copyright (c) 2018 Mobiveil Inc.
> + * Author: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> + * Refactor: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
> + */
> +
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_pci.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +#include "pcie-mobiveil.h"
> +
> +static int mobiveil_pcie_probe(struct platform_device *pdev)
> +{
> +       struct mobiveil_pcie *pcie;
> +       struct device *dev = &pdev->dev;
> +
> +       pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> +       if (!pcie)
> +               return -ENOMEM;
> +
> +       pcie->pdev = pdev;
> +
> +       return mobiveil_pcie_host_probe(pcie);
> +}
> +
> +static const struct of_device_id mobiveil_pcie_of_match[] = {
> +       {.compatible = "mbvl,gpex40-pcie",},
> +       {},
> +};
> +
> +MODULE_DEVICE_TABLE(of, mobiveil_pcie_of_match);
> +
> +static struct platform_driver mobiveil_pcie_driver = {
> +       .probe = mobiveil_pcie_probe,
> +       .driver = {
> +               .name = "mobiveil-pcie",
> +               .of_match_table = mobiveil_pcie_of_match,
> +               .suppress_bind_attrs = true,
> +       },
> +};
> +
> +builtin_platform_driver(mobiveil_pcie_driver);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("Mobiveil PCIe host controller driver");
> +MODULE_AUTHOR("Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>");
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.c b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
> new file mode 100644
> index 000000000000..ee678a60825d
> --- /dev/null
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
> @@ -0,0 +1,228 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PCIe host controller driver for Mobiveil PCIe Host controller
> + *
> + * Copyright (c) 2018 Mobiveil Inc.
> + * Author: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> + * Refactor: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +
> +#include "pcie-mobiveil.h"
> +
> +/*
> + * mobiveil_pcie_sel_page - routine to access paged register
> + *
> + * Registers whose address greater than PAGED_ADDR_BNDRY (0xc00) are paged,
> + * for this scheme to work extracted higher 6 bits of the offset will be
> + * written to pg_sel field of PAB_CTRL register and rest of the lower 10
> + * bits enabled with PAGED_ADDR_BNDRY are used as offset of the register.
> + */
> +static void mobiveil_pcie_sel_page(struct mobiveil_pcie *pcie, u8 pg_idx)
> +{
> +       u32 val;
> +
> +       val = readl(pcie->csr_axi_slave_base + PAB_CTRL);
> +       val &= ~(PAGE_SEL_MASK << PAGE_SEL_SHIFT);
> +       val |= (pg_idx & PAGE_SEL_MASK) << PAGE_SEL_SHIFT;
> +
> +       writel(val, pcie->csr_axi_slave_base + PAB_CTRL);
> +}
> +
> +static void *mobiveil_pcie_comp_addr(struct mobiveil_pcie *pcie, u32 off)
> +{
> +       if (off < PAGED_ADDR_BNDRY) {
> +               /* For directly accessed registers, clear the pg_sel field */
> +               mobiveil_pcie_sel_page(pcie, 0);
> +               return pcie->csr_axi_slave_base + off;
> +       }
> +
> +       mobiveil_pcie_sel_page(pcie, OFFSET_TO_PAGE_IDX(off));
> +       return pcie->csr_axi_slave_base + OFFSET_TO_PAGE_ADDR(off);
> +}
> +
> +static int mobiveil_pcie_read(void __iomem *addr, int size, u32 *val)
> +{
> +       if ((uintptr_t)addr & (size - 1)) {
> +               *val = 0;
> +               return PCIBIOS_BAD_REGISTER_NUMBER;
> +       }
> +
> +       switch (size) {
> +       case 4:
> +               *val = readl(addr);
> +               break;
> +       case 2:
> +               *val = readw(addr);
> +               break;
> +       case 1:
> +               *val = readb(addr);
> +               break;
> +       default:
> +               *val = 0;
> +               return PCIBIOS_BAD_REGISTER_NUMBER;
> +       }
> +
> +       return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static int mobiveil_pcie_write(void __iomem *addr, int size, u32 val)
> +{
> +       if ((uintptr_t)addr & (size - 1))
> +               return PCIBIOS_BAD_REGISTER_NUMBER;
> +
> +       switch (size) {
> +       case 4:
> +               writel(val, addr);
> +               break;
> +       case 2:
> +               writew(val, addr);
> +               break;
> +       case 1:
> +               writeb(val, addr);
> +               break;
> +       default:
> +               return PCIBIOS_BAD_REGISTER_NUMBER;
> +       }
> +
> +       return PCIBIOS_SUCCESSFUL;
> +}
> +
> +u32 csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size)
> +{
> +       void *addr;
> +       u32 val;
> +       int ret;
> +
> +       addr = mobiveil_pcie_comp_addr(pcie, off);
> +
> +       ret = mobiveil_pcie_read(addr, size, &val);
> +       if (ret)
> +               dev_err(&pcie->pdev->dev, "read CSR address failed\n");
> +
> +       return val;
> +}
> +
> +void csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, size_t size)
> +{
> +       void *addr;
> +       int ret;
> +
> +       addr = mobiveil_pcie_comp_addr(pcie, off);
> +
> +       ret = mobiveil_pcie_write(addr, size, val);
> +       if (ret)
> +               dev_err(&pcie->pdev->dev, "write CSR address failed\n");
> +}
> +
> +bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie)
> +{
> +       if (pcie->ops->link_up)
> +               return pcie->ops->link_up(pcie);
> +
> +       return (csr_readl(pcie, LTSSM_STATUS) &
> +               LTSSM_STATUS_L0_MASK) == LTSSM_STATUS_L0;
> +}
> +
> +void program_ib_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
> +                       u64 pci_addr, u32 type, u64 size)
> +{
> +       u32 value;
> +       u64 size64 = ~(size - 1);
> +
> +       if (win_num >= pcie->ppio_wins) {
> +               dev_err(&pcie->pdev->dev,
> +                       "ERROR: max inbound windows reached !\n");
> +               return;
> +       }
> +
> +       value = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
> +       value &= ~(AMAP_CTRL_TYPE_MASK << AMAP_CTRL_TYPE_SHIFT |
> +                WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> +       value |= (type << AMAP_CTRL_TYPE_SHIFT) | (1 << AMAP_CTRL_EN_SHIFT) |
> +                (lower_32_bits(size64) & WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> +       csr_writel(pcie, value, PAB_PEX_AMAP_CTRL(win_num));
> +
> +       csr_writel(pcie, upper_32_bits(size64),
> +                  PAB_EXT_PEX_AMAP_SIZEN(win_num));
> +
> +       csr_writel(pcie, lower_32_bits(cpu_addr),
> +                  PAB_PEX_AMAP_AXI_WIN(win_num));
> +       csr_writel(pcie, upper_32_bits(cpu_addr),
> +                  PAB_EXT_PEX_AMAP_AXI_WIN(win_num));
> +
> +       csr_writel(pcie, lower_32_bits(pci_addr),
> +                  PAB_PEX_AMAP_PEX_WIN_L(win_num));
> +       csr_writel(pcie, upper_32_bits(pci_addr),
> +                  PAB_PEX_AMAP_PEX_WIN_H(win_num));
> +
> +       pcie->ib_wins_configured++;
> +}
> +
> +/*
> + * routine to program the outbound windows
> + */
> +void program_ob_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
> +                       u64 pci_addr, u32 type, u64 size)
> +{
> +
> +       u32 value;
> +       u64 size64 = ~(size - 1);
> +
> +       if (win_num >= pcie->apio_wins) {
> +               dev_err(&pcie->pdev->dev,
> +                       "ERROR: max outbound windows reached !\n");
> +               return;
> +       }
> +
> +       /*
> +        * program Enable Bit to 1, Type Bit to (00) base 2, AXI Window Size Bit
> +        * to 4 KB in PAB_AXI_AMAP_CTRL register
> +        */
> +       value = csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num));
> +       value &= ~(WIN_TYPE_MASK << WIN_TYPE_SHIFT |
> +                WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> +       value |= 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
> +                (lower_32_bits(size64) & WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> +       csr_writel(pcie, value, PAB_AXI_AMAP_CTRL(win_num));
> +
> +       csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num));
> +
> +       /*
> +        * program AXI window base with appropriate value in
> +        * PAB_AXI_AMAP_AXI_WIN0 register
> +        */
> +       csr_writel(pcie, lower_32_bits(cpu_addr) & (~AXI_WINDOW_ALIGN_MASK),
> +                  PAB_AXI_AMAP_AXI_WIN(win_num));
> +       csr_writel(pcie, upper_32_bits(cpu_addr),
> +                  PAB_EXT_AXI_AMAP_AXI_WIN(win_num));
> +
> +       csr_writel(pcie, lower_32_bits(pci_addr),
> +                  PAB_AXI_AMAP_PEX_WIN_L(win_num));
> +       csr_writel(pcie, upper_32_bits(pci_addr),
> +                  PAB_AXI_AMAP_PEX_WIN_H(win_num));
> +
> +       pcie->ob_wins_configured++;
> +}
> +
> +int mobiveil_bringup_link(struct mobiveil_pcie *pcie)
> +{
> +       int retries;
> +
> +       /* check if the link is up or not */
> +       for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
> +               if (mobiveil_pcie_link_up(pcie))
> +                       return 0;
> +
> +               usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
> +       }
> +
> +       dev_err(&pcie->pdev->dev, "link never came up\n");
> +
> +       return -ETIMEDOUT;
> +}
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> new file mode 100644
> index 000000000000..eb4cb61291a8
> --- /dev/null
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> @@ -0,0 +1,187 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * PCIe host controller driver for Mobiveil PCIe Host controller
> + *
> + * Copyright (c) 2018 Mobiveil Inc.
> + * Author: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> + * Refactor: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
> + */
> +
> +#ifndef _PCIE_MOBIVEIL_H
> +#define _PCIE_MOBIVEIL_H
> +
> +#include <linux/pci.h>
> +#include <linux/irq.h>
> +#include <linux/msi.h>
> +#include "../../pci.h"
> +
> +/* register offsets and bit positions */
> +
> +/*
> + * translation tables are grouped into windows, each window registers are
> + * grouped into blocks of 4 or 16 registers each
> + */
> +#define PAB_REG_BLOCK_SIZE             16
> +#define PAB_EXT_REG_BLOCK_SIZE         4
> +
> +#define PAB_REG_ADDR(offset, win)      \
> +       (offset + (win * PAB_REG_BLOCK_SIZE))
> +#define PAB_EXT_REG_ADDR(offset, win)  \
> +       (offset + (win * PAB_EXT_REG_BLOCK_SIZE))
> +
> +#define LTSSM_STATUS                   0x0404
> +#define  LTSSM_STATUS_L0_MASK          0x3f
> +#define  LTSSM_STATUS_L0               0x2d
> +
> +#define PAB_CTRL                       0x0808
> +#define  AMBA_PIO_ENABLE_SHIFT         0
> +#define  PEX_PIO_ENABLE_SHIFT          1
> +#define  PAGE_SEL_SHIFT                        13
> +#define  PAGE_SEL_MASK                 0x3f
> +#define  PAGE_LO_MASK                  0x3ff
> +#define  PAGE_SEL_OFFSET_SHIFT         10
> +
> +#define PAB_AXI_PIO_CTRL               0x0840
> +#define  APIO_EN_MASK                  0xf
> +
> +#define PAB_PEX_PIO_CTRL               0x08c0
> +#define  PIO_ENABLE_SHIFT              0
> +
> +#define PAB_INTP_AMBA_MISC_ENB         0x0b0c
> +#define PAB_INTP_AMBA_MISC_STAT                0x0b1c
> +#define  PAB_INTP_INTX_MASK            0x01e0
> +#define  PAB_INTP_MSI_MASK             0x8
> +
> +#define PAB_AXI_AMAP_CTRL(win)         PAB_REG_ADDR(0x0ba0, win)
> +#define  WIN_ENABLE_SHIFT              0
> +#define  WIN_TYPE_SHIFT                        1
> +#define  WIN_TYPE_MASK                 0x3
> +#define  WIN_SIZE_SHIFT                        10
> +#define  WIN_SIZE_MASK                 0x3fffff
> +
> +#define PAB_EXT_AXI_AMAP_SIZE(win)     PAB_EXT_REG_ADDR(0xbaf0, win)
> +
> +#define PAB_EXT_AXI_AMAP_AXI_WIN(win)  PAB_EXT_REG_ADDR(0x80a0, win)
> +#define PAB_AXI_AMAP_AXI_WIN(win)      PAB_REG_ADDR(0x0ba4, win)
> +#define  AXI_WINDOW_ALIGN_MASK         3
> +
> +#define PAB_AXI_AMAP_PEX_WIN_L(win)    PAB_REG_ADDR(0x0ba8, win)
> +#define  PAB_BUS_SHIFT                 24
> +#define  PAB_DEVICE_SHIFT              19
> +#define  PAB_FUNCTION_SHIFT            16
> +
> +#define PAB_AXI_AMAP_PEX_WIN_H(win)    PAB_REG_ADDR(0x0bac, win)
> +#define PAB_INTP_AXI_PIO_CLASS         0x474
> +
> +#define PAB_PEX_AMAP_CTRL(win)         PAB_REG_ADDR(0x4ba0, win)
> +#define  AMAP_CTRL_EN_SHIFT            0
> +#define  AMAP_CTRL_TYPE_SHIFT          1
> +#define  AMAP_CTRL_TYPE_MASK           3
> +
> +#define PAB_EXT_PEX_AMAP_SIZEN(win)    PAB_EXT_REG_ADDR(0xbef0, win)
> +#define PAB_EXT_PEX_AMAP_AXI_WIN(win)  PAB_EXT_REG_ADDR(0xb4a0, win)
> +#define PAB_PEX_AMAP_AXI_WIN(win)      PAB_REG_ADDR(0x4ba4, win)
> +#define PAB_PEX_AMAP_PEX_WIN_L(win)    PAB_REG_ADDR(0x4ba8, win)
> +#define PAB_PEX_AMAP_PEX_WIN_H(win)    PAB_REG_ADDR(0x4bac, win)
> +
> +/* starting offset of INTX bits in status register */
> +#define PAB_INTX_START                 5
> +
> +/* supported number of MSI interrupts */
> +#define PCI_NUM_MSI                    16
> +
> +/* MSI registers */
> +#define MSI_BASE_LO_OFFSET             0x04
> +#define MSI_BASE_HI_OFFSET             0x08
> +#define MSI_SIZE_OFFSET                        0x0c
> +#define MSI_ENABLE_OFFSET              0x14
> +#define MSI_STATUS_OFFSET              0x18
> +#define MSI_DATA_OFFSET                        0x20
> +#define MSI_ADDR_L_OFFSET              0x24
> +#define MSI_ADDR_H_OFFSET              0x28
> +
> +/* outbound and inbound window definitions */
> +#define WIN_NUM_0                      0
> +#define WIN_NUM_1                      1
> +#define CFG_WINDOW_TYPE                        0
> +#define IO_WINDOW_TYPE                 1
> +#define MEM_WINDOW_TYPE                        2
> +#define IB_WIN_SIZE                    ((u64)256 * 1024 * 1024 * 1024)
> +#define MAX_PIO_WINDOWS                        8
> +
> +/* Parameters for the waiting for link up routine */
> +#define LINK_WAIT_MAX_RETRIES          10
> +#define LINK_WAIT_MIN                  90000
> +#define LINK_WAIT_MAX                  100000
> +
> +#define PAGED_ADDR_BNDRY               0xc00
> +#define OFFSET_TO_PAGE_ADDR(off)       \
> +       ((off & PAGE_LO_MASK) | PAGED_ADDR_BNDRY)
> +#define OFFSET_TO_PAGE_IDX(off)                \
> +       ((off >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK)
> +
> +struct mobiveil_pcie;
> +
> +struct mobiveil_msi {                  /* MSI information */
> +       struct mutex lock;              /* protect bitmap variable */
> +       struct irq_domain *msi_domain;
> +       struct irq_domain *dev_domain;
> +       phys_addr_t msi_pages_phys;
> +       int num_of_vectors;
> +       DECLARE_BITMAP(msi_irq_in_use, PCI_NUM_MSI);
> +};
> +
> +struct mobiveil_rp_ops {
> +       int (*interrupt_init)(struct mobiveil_pcie *pcie);
> +};
> +
> +struct root_port {
> +       u8 root_bus_nr;
> +       void __iomem *config_axi_slave_base;    /* endpoint config base */
> +       struct resource *ob_io_res;
> +       struct mobiveil_rp_ops *ops;
> +       int irq;
> +       raw_spinlock_t intx_mask_lock;
> +       struct irq_domain *intx_domain;
> +       struct mobiveil_msi msi;
> +};
> +
> +struct mobiveil_pab_ops {
> +       int (*link_up)(struct mobiveil_pcie *pcie);
> +};
> +
> +struct mobiveil_pcie {
> +       struct platform_device *pdev;
> +       struct list_head resources;
> +       void __iomem *csr_axi_slave_base;       /* PAB registers base */
> +       phys_addr_t pcie_reg_base;      /* Physical PCIe Controller Base */
> +       void __iomem *apb_csr_base;     /* MSI register base */
> +       u32 apio_wins;
> +       u32 ppio_wins;
> +       u32 ob_wins_configured;         /* configured outbound windows */
> +       u32 ib_wins_configured;         /* configured inbound windows */
> +       const struct mobiveil_pab_ops *ops;
> +       struct root_port rp;
> +};
> +
> +int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie);
> +bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie);
> +int mobiveil_bringup_link(struct mobiveil_pcie *pcie);
> +void program_ob_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
> +                       u64 pci_addr, u32 type, u64 size);
> +void program_ib_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
> +                       u64 pci_addr, u32 type, u64 size);
> +u32 csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size);
> +void csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, size_t size);
> +
> +static inline u32 csr_readl(struct mobiveil_pcie *pcie, u32 off)
> +{
> +       return csr_read(pcie, off, 0x4);
> +}
> +
> +static inline void csr_writel(struct mobiveil_pcie *pcie, u32 val, u32 off)
> +{
> +       csr_write(pcie, val, off, 0x4);
> +}
> +
> +#endif /* _PCIE_MOBIVEIL_H */
> --
> 2.17.1
>
Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

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

* Re: [PATCHv3 17/27] PCI: mobiveil: fix the checking of valid device
  2019-01-29  8:10 ` [PATCHv3 17/27] PCI: mobiveil: fix the checking of valid device Z.q. Hou
@ 2019-02-08 12:41   ` Subrahmanya Lingappa
  2019-02-08 14:13     ` Bjorn Helgaas
  2019-02-18  7:04     ` Z.q. Hou
  0 siblings, 2 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-08 12:41 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

ZQ,

On Tue, Jan 29, 2019 at 1:40 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> Avoid to issue CFG transactions to link partner when the PCIe
> link is not up. And allow CFG transactions to all functions of
> Endpoint implemented multiple functions.
>
> Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host
> Bridge IP driver")
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/mobiveil/pcie-mobiveil-host.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> index dc5324d94466..1ae82e790562 100644
> --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> @@ -29,6 +29,10 @@ static bool mobiveil_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
>  {
>         struct mobiveil_pcie *pcie = bus->sysdata;
>
> +       /* If there is no link, then there is no device */
> +       if (bus->number > pcie->rp.root_bus_nr && !mobiveil_pcie_link_up(pcie))
> +               return false;
> +
>         /* Only one device down on each root port */
>         if ((bus->number == pcie->rp.root_bus_nr) && (devfn > 0))
>                 return false;
> @@ -37,7 +41,7 @@ static bool mobiveil_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
>          * Do not read more than one device on the bus directly
>          * attached to RC
>          */
> -       if ((bus->primary == pcie->rp.root_bus_nr) && (devfn > 0))
> +       if ((bus->primary == pcie->rp.root_bus_nr) && (PCI_SLOT(devfn) > 0))
here change "primary" to "number", as it's a bug in the original driver too.

>                 return false;
>
>         return true;
> --
> 2.17.1
>

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

* Re: [PATCHv3 18/27] PCI: mobiveil: continue to initialize the host upon no PCIe link
  2019-01-29  8:10 ` [PATCHv3 18/27] PCI: mobiveil: continue to initialize the host upon no PCIe link Z.q. Hou
@ 2019-02-08 12:41   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-08 12:41 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

On Tue, Jan 29, 2019 at 1:40 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> Sometimes there is not a PCIe Endpoint in the PCIe slot, so do
> not exit when the PCIe link is not up. And degrade the print
> level of link up info.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/mobiveil/pcie-mobiveil-host.c | 1 -
>  drivers/pci/controller/mobiveil/pcie-mobiveil.c      | 2 +-
>  2 files changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> index 1ae82e790562..d1765d572f44 100644
> --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> @@ -596,7 +596,6 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
>         ret = mobiveil_bringup_link(pcie);
>         if (ret) {
>                 dev_info(dev, "link bring-up failed\n");
> -               goto error;
>         }
>
>         /* setup the kernel resources for the newly added PCIe root bus */
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.c b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
> index ee678a60825d..370658d6546d 100644
> --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.c
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
> @@ -222,7 +222,7 @@ int mobiveil_bringup_link(struct mobiveil_pcie *pcie)
>                 usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
>         }
>
> -       dev_err(&pcie->pdev->dev, "link never came up\n");
> +       dev_info(&pcie->pdev->dev, "link never came up\n");
>
>         return -ETIMEDOUT;
>  }
> --
> 2.17.1
>
Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

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

* Re: [PATCHv3 19/27] PCI: mobiveil: disabled IB and OB windows set by bootloader
  2019-01-29  8:10 ` [PATCHv3 19/27] PCI: mobiveil: disabled IB and OB windows set by bootloader Z.q. Hou
@ 2019-02-08 12:42   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-08 12:42 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

On Tue, Jan 29, 2019 at 1:40 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> Disabled all inbound and outbound windows before set up the windows
> in kernel, in case transactions match the window set by bootloader.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  .../controller/mobiveil/pcie-mobiveil-host.c   |  7 +++++++
>  .../pci/controller/mobiveil/pcie-mobiveil.c    | 18 ++++++++++++++++++
>  .../pci/controller/mobiveil/pcie-mobiveil.h    |  2 ++
>  3 files changed, 27 insertions(+)
>
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> index d1765d572f44..d028cdf31d0e 100644
> --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> @@ -221,6 +221,13 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>  {
>         u32 value, pab_ctrl, type;
>         struct resource_entry *win;
> +       int i;
> +
> +       /* Disable all inbound/outbound windows */
> +       for (i = 0; i < pcie->apio_wins; i++)
> +               mobiveil_pcie_disable_ob_win(pcie, i);
> +       for (i = 0; i < pcie->ppio_wins; i++)
> +               mobiveil_pcie_disable_ib_win(pcie, i);
>
>         /* setup bus numbers */
>         value = csr_readl(pcie, PCI_PRIMARY_BUS);
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.c b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
> index 370658d6546d..49d471b75925 100644
> --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.c
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
> @@ -226,3 +226,21 @@ int mobiveil_bringup_link(struct mobiveil_pcie *pcie)
>
>         return -ETIMEDOUT;
>  }
> +
> +void mobiveil_pcie_disable_ib_win(struct mobiveil_pcie *pci, int win_num)
> +{
> +       u32 val;
> +
> +       val = csr_readl(pci, PAB_PEX_AMAP_CTRL(win_num));
> +       val &= ~(1 << AMAP_CTRL_EN_SHIFT);
> +       csr_writel(pci, val, PAB_PEX_AMAP_CTRL(win_num));
> +}
> +
> +void mobiveil_pcie_disable_ob_win(struct mobiveil_pcie *pci, int win_num)
> +{
> +       u32 val;
> +
> +       val = csr_readl(pci, PAB_AXI_AMAP_CTRL(win_num));
> +       val &= ~(1 << WIN_ENABLE_SHIFT);
> +       csr_writel(pci, val, PAB_AXI_AMAP_CTRL(win_num));
> +}
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> index eb4cb61291a8..81685840b378 100644
> --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> @@ -171,6 +171,8 @@ void program_ob_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
>                         u64 pci_addr, u32 type, u64 size);
>  void program_ib_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
>                         u64 pci_addr, u32 type, u64 size);
> +void mobiveil_pcie_disable_ob_win(struct mobiveil_pcie *pci, int win_num);
> +void mobiveil_pcie_disable_ib_win(struct mobiveil_pcie *pci, int win_num);
>  u32 csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size);
>  void csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, size_t size);
>
> --
> 2.17.1
>
Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

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

* Re: [PATCHv3 20/27] PCI: mobiveil: add Byte and Half-Word width register accessors
  2019-01-29  8:10 ` [PATCHv3 20/27] PCI: mobiveil: add Byte and Half-Word width register accessors Z.q. Hou
@ 2019-02-08 12:44   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-08 12:44 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

On Tue, Jan 29, 2019 at 1:40 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> As there are some Byte and Half-Work width registers in PCIe
> configuration space, add Byte and Half-Word width register
> accessors.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  .../pci/controller/mobiveil/pcie-mobiveil.h   | 20 +++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> index 81685840b378..933c2f34bc52 100644
> --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> @@ -181,9 +181,29 @@ static inline u32 csr_readl(struct mobiveil_pcie *pcie, u32 off)
>         return csr_read(pcie, off, 0x4);
>  }
>
> +static inline u32 csr_readw(struct mobiveil_pcie *pcie, u32 off)
> +{
> +       return csr_read(pcie, off, 0x2);
> +}
> +
> +static inline u32 csr_readb(struct mobiveil_pcie *pcie, u32 off)
> +{
> +       return csr_read(pcie, off, 0x1);
> +}
> +
>  static inline void csr_writel(struct mobiveil_pcie *pcie, u32 val, u32 off)
>  {
>         csr_write(pcie, val, off, 0x4);
>  }
>
> +static inline void csr_writew(struct mobiveil_pcie *pcie, u32 val, u32 off)
> +{
> +       csr_write(pcie, val, off, 0x2);
> +}
> +
> +static inline void csr_writeb(struct mobiveil_pcie *pcie, u32 val, u32 off)
> +{
> +       csr_write(pcie, val, off, 0x1);
> +}
> +
>  #endif /* _PCIE_MOBIVEIL_H */
> --
> 2.17.1
>
Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

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

* Re: [PATCHv3 21/27] PCI: mobiveil: make mobiveil_host_init can be used to re-init host
  2019-01-29  8:10 ` [PATCHv3 21/27] PCI: mobiveil: make mobiveil_host_init can be used to re-init host Z.q. Hou
@ 2019-02-08 12:46   ` Subrahmanya Lingappa
  0 siblings, 0 replies; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-08 12:46 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

On Tue, Jan 29, 2019 at 1:40 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> Make the mobiveil_host_init function can be used to re-init
> host controller's PAB and GPEX CSR register block, as NXP
> integrated Mobiveil IP has to reset and then re-init the PAB
> and GPEX CSR registers upon Hot-reset.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> ---
> V3:
>  - Removed the duplicated free opteration of pcie->resources.
>
>  .../controller/mobiveil/pcie-mobiveil-host.c  | 41 ++++++++++---------
>  .../pci/controller/mobiveil/pcie-mobiveil.h   |  3 +-
>  2 files changed, 23 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> index d028cdf31d0e..e8d0c4989013 100644
> --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> @@ -217,7 +217,7 @@ static void mobiveil_pcie_enable_msi(struct mobiveil_pcie *pcie)
>         writel_relaxed(1, pcie->apb_csr_base + MSI_ENABLE_OFFSET);
>  }
>
> -static int mobiveil_host_init(struct mobiveil_pcie *pcie)
> +int mobiveil_host_init(struct mobiveil_pcie *pcie, bool reinit)
>  {
>         u32 value, pab_ctrl, type;
>         struct resource_entry *win;
> @@ -229,11 +229,16 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>         for (i = 0; i < pcie->ppio_wins; i++)
>                 mobiveil_pcie_disable_ib_win(pcie, i);
>
> -       /* setup bus numbers */
> -       value = csr_readl(pcie, PCI_PRIMARY_BUS);
> -       value &= 0xff000000;
> -       value |= 0x00ff0100;
> -       csr_writel(pcie, value, PCI_PRIMARY_BUS);
> +       pcie->ib_wins_configured = 0;
> +       pcie->ob_wins_configured = 0;
> +
> +       if (!reinit) {
> +               /* setup bus numbers */
> +               value = csr_readl(pcie, PCI_PRIMARY_BUS);
> +               value &= 0xff000000;
> +               value |= 0x00ff0100;
> +               csr_writel(pcie, value, PCI_PRIMARY_BUS);
> +       }
>
>         /*
>          * program Bus Master Enable Bit in Command Register in PAB Config
> @@ -279,7 +284,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>         program_ib_windows(pcie, WIN_NUM_0, 0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
>
>         /* Get the I/O and memory ranges from DT */
> -       resource_list_for_each_entry(win, &pcie->resources) {
> +       resource_list_for_each_entry(win, pcie->resources) {
>                 if (resource_type(win->res) == IORESOURCE_MEM) {
>                         type = MEM_WINDOW_TYPE;
>                 } else if (resource_type(win->res) == IORESOURCE_IO) {
> @@ -550,8 +555,6 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
>         resource_size_t iobase;
>         int ret;
>
> -       INIT_LIST_HEAD(&pcie->resources);
> -
>         ret = mobiveil_pcie_parse_dt(pcie);
>         if (ret) {
>                 dev_err(dev, "Parsing DT failed, ret: %x\n", ret);
> @@ -565,34 +568,35 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
>
>         /* parse the host bridge base addresses from the device tree file */
>         ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
> -                                                   &pcie->resources, &iobase);
> +                                                   &bridge->windows, &iobase);
>         if (ret) {
>                 dev_err(dev, "Getting bridge resources failed\n");
>                 return ret;
>         }
>
> +       pcie->resources = &bridge->windows;
> +
>         /*
>          * configure all inbound and outbound windows and prepare the RC for
>          * config access
>          */
> -       ret = mobiveil_host_init(pcie);
> +       ret = mobiveil_host_init(pcie, false);
>         if (ret) {
>                 dev_err(dev, "Failed to initialize host\n");
> -               goto error;
> +               return ret;
>         }
>
>         ret = mobiveil_pcie_interrupt_init(pcie);
>         if (ret) {
>                 dev_err(dev, "Interrupt init failed\n");
> -               goto error;
> +               return ret;
>         }
>
> -       ret = devm_request_pci_bus_resources(dev, &pcie->resources);
> +       ret = devm_request_pci_bus_resources(dev, pcie->resources);
>         if (ret)
> -               goto error;
> +               return ret;
>
>         /* Initialize bridge */
> -       list_splice_init(&pcie->resources, &bridge->windows);
>         bridge->dev.parent = dev;
>         bridge->sysdata = pcie;
>         bridge->busnr = pcie->rp.root_bus_nr;
> @@ -608,7 +612,7 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
>         /* setup the kernel resources for the newly added PCIe root bus */
>         ret = pci_scan_root_bus_bridge(bridge);
>         if (ret)
> -               goto error;
> +               return ret;
>
>         bus = bridge->bus;
>
> @@ -618,7 +622,4 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
>         pci_bus_add_devices(bus);
>
>         return 0;
> -error:
> -       pci_free_resource_list(&pcie->resources);
> -       return ret;
>  }
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> index 933c2f34bc52..0f5303962e88 100644
> --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> @@ -152,7 +152,7 @@ struct mobiveil_pab_ops {
>
>  struct mobiveil_pcie {
>         struct platform_device *pdev;
> -       struct list_head resources;
> +       struct list_head *resources;
>         void __iomem *csr_axi_slave_base;       /* PAB registers base */
>         phys_addr_t pcie_reg_base;      /* Physical PCIe Controller Base */
>         void __iomem *apb_csr_base;     /* MSI register base */
> @@ -165,6 +165,7 @@ struct mobiveil_pcie {
>  };
>
>  int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie);
> +int mobiveil_host_init(struct mobiveil_pcie *pcie, bool reinit);
>  bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie);
>  int mobiveil_bringup_link(struct mobiveil_pcie *pcie);
>  void program_ob_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
> --
> 2.17.1
>
Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>

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

* Re: [PATCHv3 23/27] PCI: mobiveil: add PCIe Gen4 RC driver for NXP Layerscape SoCs
  2019-01-29  8:10 ` [PATCHv3 23/27] PCI: mobiveil: add PCIe Gen4 RC driver for NXP Layerscape SoCs Z.q. Hou
@ 2019-02-08 12:49   ` Subrahmanya Lingappa
  2019-02-18  7:05     ` Z.q. Hou
  0 siblings, 1 reply; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-08 12:49 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

ZQ,


On Tue, Jan 29, 2019 at 1:40 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> This PCIe controller is based on the Mobiveil GPEX IP, which is
> compatible with the PCI Express™ Base Specification, Revision 4.0.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> V3:
>  - No change
>
>  drivers/pci/controller/mobiveil/Kconfig       |  10 +
>  drivers/pci/controller/mobiveil/Makefile      |   1 +
>  .../controller/mobiveil/pci-layerscape-gen4.c | 254 ++++++++++++++++++
>  .../pci/controller/mobiveil/pcie-mobiveil.h   |  16 +-
>  4 files changed, 279 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
>
> diff --git a/drivers/pci/controller/mobiveil/Kconfig b/drivers/pci/controller/mobiveil/Kconfig
> index 64343c07bfed..3ddb7d6163a9 100644
> --- a/drivers/pci/controller/mobiveil/Kconfig
> +++ b/drivers/pci/controller/mobiveil/Kconfig
> @@ -21,4 +21,14 @@ config PCIE_MOBIVEIL_PLAT
>           Soft IP. It has up to 8 outbound and inbound windows
>           for address translation and it is a PCIe Gen4 IP.
>
> +config PCI_LAYERSCAPE_GEN4
> +       bool "Freescale Layerscpe PCIe Gen4 controller"
> +       depends on PCI
> +       depends on OF && (ARM64 || ARCH_LAYERSCAPE)
> +       depends on PCI_MSI_IRQ_DOMAIN
> +       select PCIE_MOBIVEIL_HOST
> +       help
> +         Say Y here if you want PCIe Gen4 controller support on
> +         Layerscape SoCs. The PCIe controller can work in RC or
> +         EP mode according to RCW[HOST_AGT_PEX] setting.
>  endmenu
> diff --git a/drivers/pci/controller/mobiveil/Makefile b/drivers/pci/controller/mobiveil/Makefile
> index 9fb6d1c6504d..ff66774ccac4 100644
> --- a/drivers/pci/controller/mobiveil/Makefile
> +++ b/drivers/pci/controller/mobiveil/Makefile
> @@ -2,3 +2,4 @@
>  obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o
>  obj-$(CONFIG_PCIE_MOBIVEIL_HOST) += pcie-mobiveil-host.o
>  obj-$(CONFIG_PCIE_MOBIVEIL_PLAT) += pcie-mobiveil-plat.o
> +obj-$(CONFIG_PCI_LAYERSCAPE_GEN4) += pci-layerscape-gen4.o
> diff --git a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> new file mode 100644
> index 000000000000..174cbcac4059
> --- /dev/null
> +++ b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> @@ -0,0 +1,254 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PCIe host controller driver for NXP Layerscape SoCs
> + *
> + * Copyright 2018 NXP
> + *
> + * Author: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/interrupt.h>
> +#include <linux/init.h>
> +#include <linux/of_pci.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_address.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/resource.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
> +
> +#include "pcie-mobiveil.h"
> +
> +/* LUT and PF control registers */
> +#define PCIE_LUT_OFF                   (0x80000)
> +#define PCIE_PF_OFF                    (0xc0000)
> +#define PCIE_PF_INT_STAT               (0x18)
> +#define PF_INT_STAT_PABRST             (31)
> +
> +#define PCIE_PF_DBG                    (0x7fc)
> +#define PF_DBG_LTSSM_MASK              (0x3f)
> +#define PF_DBG_WE                      (31)
> +#define PF_DBG_PABR                    (27)
> +
> +#define LS_PCIE_G4_LTSSM_L0            0x2d /* L0 state */
> +
> +#define to_ls_pcie_g4(x)               platform_get_drvdata((x)->pdev)
> +
> +struct ls_pcie_g4 {
> +       struct mobiveil_pcie *pci;
> +       struct delayed_work dwork;
> +       int irq;
> +};
> +
> +static inline u32 ls_pcie_g4_lut_readl(struct ls_pcie_g4 *pcie, u32 off)
> +{
> +       return ioread32(pcie->pci->csr_axi_slave_base + PCIE_LUT_OFF + off);
> +}
> +
> +static inline void ls_pcie_g4_lut_writel(struct ls_pcie_g4 *pcie,
> +                                        u32 off, u32 val)
> +{
> +       iowrite32(val, pcie->pci->csr_axi_slave_base + PCIE_LUT_OFF + off);
> +}
> +
> +static inline u32 ls_pcie_g4_pf_readl(struct ls_pcie_g4 *pcie, u32 off)
> +{
> +       return ioread32(pcie->pci->csr_axi_slave_base + PCIE_PF_OFF + off);
> +}
> +
> +static inline void ls_pcie_g4_pf_writel(struct ls_pcie_g4 *pcie,
> +                                       u32 off, u32 val)
> +{
> +       iowrite32(val, pcie->pci->csr_axi_slave_base + PCIE_PF_OFF + off);
> +}
> +
> +static bool ls_pcie_g4_is_bridge(struct ls_pcie_g4 *pcie)
> +{
> +       struct mobiveil_pcie *mv_pci = pcie->pci;
> +       u32 header_type;
> +
> +       header_type = csr_readb(mv_pci, PCI_HEADER_TYPE);
> +       header_type &= 0x7f;
> +
> +       return header_type == PCI_HEADER_TYPE_BRIDGE;
> +}
> +
> +static int ls_pcie_g4_link_up(struct mobiveil_pcie *pci)
> +{
> +       struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
> +       u32 state;
> +
> +       state = ls_pcie_g4_pf_readl(pcie, PCIE_PF_DBG);
> +       state = state & PF_DBG_LTSSM_MASK;
> +
> +       if (state == LS_PCIE_G4_LTSSM_L0)
> +               return 1;
> +
> +       return 0;
> +}
> +
> +static void ls_pcie_g4_reinit_hw(struct ls_pcie_g4 *pcie)
> +{
> +       struct mobiveil_pcie *mv_pci = pcie->pci;
> +       u32 val, act_stat;
> +       int to = 100;
> +
> +       /* Poll for pab_csb_reset to set and PAB activity to clear */
> +       do {
> +               usleep_range(10, 15);
> +               val = ls_pcie_g4_pf_readl(pcie, PCIE_PF_INT_STAT);
> +               act_stat = csr_readl(mv_pci, PAB_ACTIVITY_STAT);
> +       } while (((val & 1 << PF_INT_STAT_PABRST) == 0 || act_stat) && to--);
> +       if (to < 0) {
> +               dev_err(&mv_pci->pdev->dev, "poll PABRST&PABACT timeout\n");
> +               return;
> +       }
> +
> +       /* clear PEX_RESET bit in PEX_PF0_DBG register */
> +       val = ls_pcie_g4_pf_readl(pcie, PCIE_PF_DBG);
> +       val |= 1 << PF_DBG_WE;
> +       ls_pcie_g4_pf_writel(pcie, PCIE_PF_DBG, val);
> +
> +       val = ls_pcie_g4_pf_readl(pcie, PCIE_PF_DBG);
> +       val |= 1 << PF_DBG_PABR;
> +       ls_pcie_g4_pf_writel(pcie, PCIE_PF_DBG, val);
> +
> +       val = ls_pcie_g4_pf_readl(pcie, PCIE_PF_DBG);
> +       val &= ~(1 << PF_DBG_WE);
> +       ls_pcie_g4_pf_writel(pcie, PCIE_PF_DBG, val);
> +
> +       mobiveil_host_init(mv_pci, true);
> +
> +       to = 100;
> +       while (!ls_pcie_g4_link_up(mv_pci) && to--)
> +               usleep_range(200, 250);
> +       if (to < 0)
> +               dev_err(&mv_pci->pdev->dev, "PCIe link trainning timeout\n");
> +}
> +
> +static irqreturn_t ls_pcie_g4_handler(int irq, void *dev_id)
> +{
> +       struct ls_pcie_g4 *pcie = (struct ls_pcie_g4 *)dev_id;
> +       struct mobiveil_pcie *mv_pci = pcie->pci;
> +       u32 val;
> +
> +       val = csr_readl(mv_pci, PAB_INTP_AMBA_MISC_STAT);
> +       if (!val)
> +               return IRQ_NONE;
> +
> +       if (val & PAB_INTP_RESET)
> +               schedule_delayed_work(&pcie->dwork, msecs_to_jiffies(1));
> +
> +       csr_writel(mv_pci, val, PAB_INTP_AMBA_MISC_STAT);
> +
> +       return IRQ_HANDLED;
> +}
> +
> +static int ls_pcie_g4_interrupt_init(struct mobiveil_pcie *mv_pci)
> +{
> +       struct ls_pcie_g4 *pcie = to_ls_pcie_g4(mv_pci);
> +       u32 val;
> +       int ret;
> +
> +       pcie->irq = platform_get_irq_byname(mv_pci->pdev, "intr");
> +       if (pcie->irq < 0) {
> +               dev_err(&mv_pci->pdev->dev, "Can't get 'intr' irq.\n");
> +               return pcie->irq;
> +       }
> +       ret = devm_request_irq(&mv_pci->pdev->dev, pcie->irq,
> +                              ls_pcie_g4_handler, IRQF_SHARED,
> +                              mv_pci->pdev->name, pcie);
> +       if (ret) {
> +               dev_err(&mv_pci->pdev->dev, "Can't register PCIe IRQ.\n");
> +               return  ret;
> +       }
> +
> +       /* Enable interrupts */
> +       val = PAB_INTP_INTX_MASK | PAB_INTP_MSI | PAB_INTP_RESET |
> +             PAB_INTP_PCIE_UE | PAB_INTP_IE_PMREDI | PAB_INTP_IE_EC;
> +       csr_writel(mv_pci, val, PAB_INTP_AMBA_MISC_ENB);
> +
> +       return 0;
> +}
> +
> +static void ls_pcie_g4_reset(struct work_struct *work)
> +{
> +       struct delayed_work *dwork = container_of(work, struct delayed_work,
> +                                                 work);
> +       struct ls_pcie_g4 *pcie = container_of(dwork, struct ls_pcie_g4, dwork);
> +       struct mobiveil_pcie *mv_pci = pcie->pci;
> +       u16 ctrl;
> +
> +       ctrl = csr_readw(mv_pci, PCI_BRIDGE_CONTROL);
> +       ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
> +       csr_writew(mv_pci, ctrl, PCI_BRIDGE_CONTROL);
> +       ls_pcie_g4_reinit_hw(pcie);
> +}
> +
> +static struct mobiveil_rp_ops ls_pcie_g4_rp_ops = {
> +       .interrupt_init = ls_pcie_g4_interrupt_init,
> +};
> +
> +static const struct mobiveil_pab_ops ls_pcie_g4_pab_ops = {
> +       .link_up = ls_pcie_g4_link_up,
> +};
> +
> +static int __init ls_pcie_g4_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct mobiveil_pcie *mv_pci;
> +       struct ls_pcie_g4 *pcie;
> +       struct device_node *np = dev->of_node;
> +       int ret;
> +
> +       if (!of_parse_phandle(np, "msi-parent", 0)) {
> +               dev_err(dev, "failed to find msi-parent\n");
> +               return -EINVAL;
> +       }
> +
> +       pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> +       if (!pcie)
> +               return -ENOMEM;
> +
> +       mv_pci = devm_kzalloc(dev, sizeof(*mv_pci), GFP_KERNEL);
> +       if (!mv_pci)
> +               return -ENOMEM;
> +
> +       mv_pci->pdev = pdev;
> +       mv_pci->ops = &ls_pcie_g4_pab_ops;
> +       mv_pci->rp.ops = &ls_pcie_g4_rp_ops;
> +       pcie->pci = mv_pci;
> +
> +       platform_set_drvdata(pdev, pcie);
> +
> +       INIT_DELAYED_WORK(&pcie->dwork, ls_pcie_g4_reset);
> +
> +       ret = mobiveil_pcie_host_probe(mv_pci);
> +       if (ret) {
> +               dev_err(dev, "fail to probe!\n");
> +               return  ret;
> +       }
> +
> +       if (!ls_pcie_g4_is_bridge(pcie))
> +               return -ENODEV;
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id ls_pcie_g4_of_match[] = {
> +       { .compatible = "fsl,lx2160a-pcie", },
> +       { },
> +};
> +
> +static struct platform_driver ls_pcie_g4_driver = {
> +       .driver = {
> +               .name = "layerscape-pcie-gen4",
> +               .of_match_table = ls_pcie_g4_of_match,
> +               .suppress_bind_attrs = true,
> +       },
> +};
> +
> +builtin_platform_driver_probe(ls_pcie_g4_driver, ls_pcie_g4_probe);
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> index 0f5303962e88..0ccd6cee5f8f 100644
> --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> @@ -41,6 +41,8 @@
>  #define  PAGE_LO_MASK                  0x3ff
>  #define  PAGE_SEL_OFFSET_SHIFT         10
>
> +#define PAB_ACTIVITY_STAT              0x81c
> +
>  #define PAB_AXI_PIO_CTRL               0x0840
>  #define  APIO_EN_MASK                  0xf
>
> @@ -49,8 +51,18 @@
>
>  #define PAB_INTP_AMBA_MISC_ENB         0x0b0c
>  #define PAB_INTP_AMBA_MISC_STAT                0x0b1c
> -#define  PAB_INTP_INTX_MASK            0x01e0
> -#define  PAB_INTP_MSI_MASK             0x8
> +#define  PAB_INTP_RESET                        (0x1 << 1)
> +#define  PAB_INTP_MSI                  (0x1 << 3)
> +#define  PAB_INTP_INTA                 (0x1 << 5)
> +#define  PAB_INTP_INTB                 (0x1 << 6)
> +#define  PAB_INTP_INTC                 (0x1 << 7)
> +#define  PAB_INTP_INTD                 (0x1 << 8)
you could use BIT(x) macros instead of these shift operations
> +#define  PAB_INTP_PCIE_UE              (0x1 << 9)
> +#define  PAB_INTP_IE_PMREDI            (0x1 << 29)
> +#define  PAB_INTP_IE_EC                        (0x1 << 30)
please fix and the the indentations
> +#define  PAB_INTP_MSI_MASK             PAB_INTP_MSI
> +#define  PAB_INTP_INTX_MASK            (PAB_INTP_INTA | PAB_INTP_INTB |\
> +                                       PAB_INTP_INTC | PAB_INTP_INTD)
>
>  #define PAB_AXI_AMAP_CTRL(win)         PAB_REG_ADDR(0x0ba0, win)
>  #define  WIN_ENABLE_SHIFT              0
> --
> 2.17.1
>

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

* Re: [PATCHv3 24/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011577
  2019-01-29  8:11 ` [PATCHv3 24/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011577 Z.q. Hou
@ 2019-02-08 12:52   ` Subrahmanya Lingappa
  2019-02-18  7:10     ` Z.q. Hou
  0 siblings, 1 reply; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-08 12:52 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

ZQ,

On Tue, Jan 29, 2019 at 1:41 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> 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 it will be fixed
> in Rev2.0.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> ---
> V3:
>  - Integrated without change from http://patchwork.ozlabs.org/patch/1006790/
>
>  .../controller/mobiveil/pci-layerscape-gen4.c | 37 +++++++++++++++++++
>  .../controller/mobiveil/pcie-mobiveil-host.c  | 17 ++++++++-
>  .../pci/controller/mobiveil/pcie-mobiveil.h   |  3 ++
>  3 files changed, 56 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> index 174cbcac4059..d2c5dbbd5e3c 100644
> --- a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> +++ b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> @@ -22,8 +22,13 @@
>
>  #include "pcie-mobiveil.h"
>
> +#define REV_1_0                                (0x10)
> +
>  /* LUT and PF control registers */
>  #define PCIE_LUT_OFF                   (0x80000)
> +#define PCIE_LUT_GCR                   (0x28)
> +#define PCIE_LUT_GCR_RRE               (0)
> +
>  #define PCIE_PF_OFF                    (0xc0000)
>  #define PCIE_PF_INT_STAT               (0x18)
>  #define PF_INT_STAT_PABRST             (31)
> @@ -41,6 +46,7 @@ struct ls_pcie_g4 {
>         struct mobiveil_pcie *pci;
>         struct delayed_work dwork;
>         int irq;
> +       u8 rev;
>  };
>
>  static inline u32 ls_pcie_g4_lut_readl(struct ls_pcie_g4 *pcie, u32 off)
> @@ -76,6 +82,15 @@ static bool ls_pcie_g4_is_bridge(struct ls_pcie_g4 *pcie)
>         return header_type == PCI_HEADER_TYPE_BRIDGE;
>  }
>
> +static int ls_pcie_g4_host_init(struct mobiveil_pcie *pci)
> +{
> +       struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
> +
> +       pcie->rev = csr_readb(pci, PCI_REVISION_ID);
> +
> +       return 0;
> +}
> +
>  static int ls_pcie_g4_link_up(struct mobiveil_pcie *pci)
>  {
>         struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
> @@ -188,12 +203,34 @@ static void ls_pcie_g4_reset(struct work_struct *work)
>         ls_pcie_g4_reinit_hw(pcie);
>  }
>
> +static int ls_pcie_g4_read_other_conf(struct pci_bus *bus, unsigned int devfn,
> +                                  int where, int size, u32 *val)
> +{
> +       struct mobiveil_pcie *pci = bus->sysdata;
> +       struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
> +       int ret;
> +
> +       if (pcie->rev == REV_1_0 && where == PCI_VENDOR_ID)
> +               ls_pcie_g4_lut_writel(pcie, PCIE_LUT_GCR,
> +                                     0 << PCIE_LUT_GCR_RRE);
> +
> +       ret = pci_generic_config_read(bus, devfn, where, size, val);
> +
> +       if (pcie->rev == REV_1_0 && where == PCI_VENDOR_ID)
> +               ls_pcie_g4_lut_writel(pcie, PCIE_LUT_GCR,
> +                                     1 << PCIE_LUT_GCR_RRE);
> +
> +       return ret;
> +}
> +
>  static struct mobiveil_rp_ops ls_pcie_g4_rp_ops = {
>         .interrupt_init = ls_pcie_g4_interrupt_init,
> +       .read_other_conf = ls_pcie_g4_read_other_conf,
>  };
>
>  static const struct mobiveil_pab_ops ls_pcie_g4_pab_ops = {
>         .link_up = ls_pcie_g4_link_up,
> +       .host_init = ls_pcie_g4_host_init,
>  };
>
>  static int __init ls_pcie_g4_probe(struct platform_device *pdev)
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> index e8d0c4989013..5f51bc2dd6d7 100644
> --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> @@ -79,9 +79,20 @@ static void __iomem *mobiveil_pcie_map_bus(struct pci_bus *bus,
>         return pcie->rp.config_axi_slave_base + where;
>  }
>
> +static int mobiveil_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
> +                                    int where, int size, u32 *val)
> +{
> +       struct mobiveil_pcie *pcie = bus->sysdata;
> +       struct root_port *rp = &pcie->rp;
> +
> +       if (bus->number > rp->root_bus_nr && rp->ops->read_other_conf)
> +               return rp->ops->read_other_conf(bus, devfn, where, size, val);
> +
> +       return pci_generic_config_read(bus, devfn, where, size, val);
> +}
>  static struct pci_ops mobiveil_pcie_ops = {
>         .map_bus = mobiveil_pcie_map_bus,
> -       .read = pci_generic_config_read,
> +       .read = mobiveil_pcie_config_read,
>         .write = pci_generic_config_write,
>  };
>
> @@ -309,6 +320,10 @@ int mobiveil_host_init(struct mobiveil_pcie *pcie, bool reinit)
>         value |= (PCI_CLASS_BRIDGE_PCI << 16);
>         csr_writel(pcie, value, PAB_INTP_AXI_PIO_CLASS);
>
> +       /* Platform specific host init */
> +       if (pcie->ops->host_init)
> +               return pcie->ops->host_init(pcie);
> +
>         return 0;
>  }
>
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> index 0ccd6cee5f8f..ab43de5e4b2b 100644
> --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> @@ -145,6 +145,8 @@ struct mobiveil_msi {                       /* MSI information */
>
>  struct mobiveil_rp_ops {
>         int (*interrupt_init)(struct mobiveil_pcie *pcie);
> +       int (*read_other_conf)(struct pci_bus *bus, unsigned int devfn,
> +                              int where, int size, u32 *val);
>  };
>
>  struct root_port {
> @@ -160,6 +162,7 @@ struct root_port {
>
>  struct mobiveil_pab_ops {
>         int (*link_up)(struct mobiveil_pcie *pcie);
> +       int (*host_init)(struct mobiveil_pcie *pcie);
>  };
>
>  struct mobiveil_pcie {
> --
> 2.17.1
>
can we have an english brief than having a internal cryptic
number:A-011577, on the patch title?

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

* Re: [PATCHv3 25/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011451
  2019-01-29  8:11 ` [PATCHv3 25/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011451 Z.q. Hou
@ 2019-02-08 12:53   ` Subrahmanya Lingappa
  2019-02-18  7:14     ` Z.q. Hou
  0 siblings, 1 reply; 68+ messages in thread
From: Subrahmanya Lingappa @ 2019-02-08 12:53 UTC (permalink / raw)
  To: Z.q. Hou
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

ZQ,

On Tue, Jan 29, 2019 at 1:41 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> When LX2 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 LX2 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 patch implemented part 1, the part 2 can be set by kernel parameter
> 'pci=pcie_bus_perf'
>
> This ERRATA is only for LX2160A Rev1.0, and it will be fixed
> in Rev2.0.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> ---
> V3:
>  - Integrated without change from http://patchwork.ozlabs.org/patch/1006796/
>
>  .../pci/controller/mobiveil/pci-layerscape-gen4.c | 15 +++++++++++++++
>  drivers/pci/controller/mobiveil/pcie-mobiveil.h   |  4 ++++
>  2 files changed, 19 insertions(+)
>
> diff --git a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> index d2c5dbbd5e3c..20ce146788ca 100644
> --- a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> +++ b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> @@ -82,12 +82,27 @@ static bool ls_pcie_g4_is_bridge(struct ls_pcie_g4 *pcie)
>         return header_type == PCI_HEADER_TYPE_BRIDGE;
>  }
>
> +static void workaround_A011451(struct ls_pcie_g4 *pcie)
> +{
> +       struct mobiveil_pcie *mv_pci = pcie->pci;
> +       u32 val;
> +
> +       /* Set ACK latency timeout */
> +       val = csr_readl(mv_pci, GPEX_ACK_REPLAY_TO);
> +       val &= ~(ACK_LAT_TO_VAL_MASK << ACK_LAT_TO_VAL_SHIFT);
> +       val |= (4 << ACK_LAT_TO_VAL_SHIFT);
> +       csr_writel(mv_pci, val, GPEX_ACK_REPLAY_TO);
> +}
> +
>  static int ls_pcie_g4_host_init(struct mobiveil_pcie *pci)
>  {
>         struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
>
>         pcie->rev = csr_readb(pci, PCI_REVISION_ID);
>
> +       if (pcie->rev == REV_1_0)
> +               workaround_A011451(pcie);
> +
>         return 0;
>  }
>
> diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> index ab43de5e4b2b..f0e2e4ae09b5 100644
> --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> @@ -85,6 +85,10 @@
>  #define PAB_AXI_AMAP_PEX_WIN_H(win)    PAB_REG_ADDR(0x0bac, win)
>  #define PAB_INTP_AXI_PIO_CLASS         0x474
>
> +#define GPEX_ACK_REPLAY_TO             0x438
> +#define  ACK_LAT_TO_VAL_MASK           0x1fff
> +#define  ACK_LAT_TO_VAL_SHIFT          0
> +
>  #define PAB_PEX_AMAP_CTRL(win)         PAB_REG_ADDR(0x4ba0, win)
>  #define  AMAP_CTRL_EN_SHIFT            0
>  #define  AMAP_CTRL_TYPE_SHIFT          1
> --
> 2.17.1
>
again, can we avoid errata number on patch title and have a brief title instead?

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

* Re: [PATCHv3 17/27] PCI: mobiveil: fix the checking of valid device
  2019-02-08 12:41   ` Subrahmanya Lingappa
@ 2019-02-08 14:13     ` Bjorn Helgaas
  2019-02-18  7:15       ` Z.q. Hou
  2019-02-18  7:04     ` Z.q. Hou
  1 sibling, 1 reply; 68+ messages in thread
From: Bjorn Helgaas @ 2019-02-08 14:13 UTC (permalink / raw)
  To: Subrahmanya Lingappa
  Cc: Z.q. Hou, mark.rutland, devicetree, lorenzo.pieralisi,
	Xiaowei Bao, linux-pci, will.deacon, linux-kernel, Leo Li,
	M.h. Lian, robh+dt, Mingkai Hu, catalin.marinas, shawnguo,
	linux-arm-kernel, Thomas Petazzoni

[+cc Thomas]

On Fri, Feb 08, 2019 at 06:11:15PM +0530, Subrahmanya Lingappa wrote:
> On Tue, Jan 29, 2019 at 1:40 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
> >
> > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> >
> > Avoid to issue CFG transactions to link partner when the PCIe
> > link is not up. And allow CFG transactions to all functions of
> > Endpoint implemented multiple functions.
> >
> > Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host
> > Bridge IP driver")
> > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> > ---
> > V3:
> >  - No change
> >
> >  drivers/pci/controller/mobiveil/pcie-mobiveil-host.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > index dc5324d94466..1ae82e790562 100644
> > --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > @@ -29,6 +29,10 @@ static bool mobiveil_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
> >  {
> >         struct mobiveil_pcie *pcie = bus->sysdata;
> >
> > +       /* If there is no link, then there is no device */
> > +       if (bus->number > pcie->rp.root_bus_nr && !mobiveil_pcie_link_up(pcie))
> > +               return false;
> > +
> >         /* Only one device down on each root port */
> >         if ((bus->number == pcie->rp.root_bus_nr) && (devfn > 0))
> >                 return false;
> > @@ -37,7 +41,7 @@ static bool mobiveil_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
> >          * Do not read more than one device on the bus directly
> >          * attached to RC
> >          */
> > -       if ((bus->primary == pcie->rp.root_bus_nr) && (devfn > 0))
> > +       if ((bus->primary == pcie->rp.root_bus_nr) && (PCI_SLOT(devfn) > 0))

> here change "primary" to "number", as it's a bug in the original driver too.

This looks like it should be split into two patches: (1) checking for
link up, and (2) checking root_bus_nr.

And if you mean "bus->primary == pcie->rp.root_bus_nr" is a bug in
pci-aardvark.c, too, it is imperative to fix that bug also (with a
separate patch).

> >                 return false;
> >
> >         return true;
> > --
> > 2.17.1
> >
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* RE: [PATCHv3 02/27] PCI: mobiveil: format the code without function change
  2019-02-05  5:48   ` Subrahmanya Lingappa
@ 2019-02-18  7:03     ` Z.q. Hou
  0 siblings, 0 replies; 68+ messages in thread
From: Z.q. Hou @ 2019-02-18  7:03 UTC (permalink / raw)
  To: Subrahmanya Lingappa
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Hi Subbu,

Thanks a lot for your comments!

> -----Original Message-----
> From: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> Sent: 2019年2月5日 13:48
> To: Z.q. Hou <zhiqiang.hou@nxp.com>
> Cc: linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> bhelgaas@google.com; robh+dt@kernel.org; mark.rutland@arm.com;
> shawnguo@kernel.org; Leo Li <leoyang.li@nxp.com>;
> lorenzo.pieralisi@arm.com; catalin.marinas@arm.com;
> will.deacon@arm.com; Mingkai Hu <mingkai.hu@nxp.com>; M.h. Lian
> <minghuan.lian@nxp.com>; Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: Re: [PATCHv3 02/27] PCI: mobiveil: format the code without function
> change
> 
> Zhiqiang,
> 
> On Tue, Jan 29, 2019 at 1:38 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
> >
> > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> >
> > Just format the code without functionality change.
> >
> > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> > ---
> > V3:
> >  - No change
> >
> >  drivers/pci/controller/pcie-mobiveil.c | 261
> > +++++++++++++------------
> >  1 file changed, 137 insertions(+), 124 deletions(-)
> >
> > diff --git a/drivers/pci/controller/pcie-mobiveil.c
> > b/drivers/pci/controller/pcie-mobiveil.c
> > index d55c7e780c6e..b87471f08a40 100644
> > --- a/drivers/pci/controller/pcie-mobiveil.c
> > +++ b/drivers/pci/controller/pcie-mobiveil.c
> > @@ -31,38 +31,40 @@
> >   * translation tables are grouped into windows, each window registers
> are
> >   * grouped into blocks of 4 or 16 registers each
> >   */
> > -#define PAB_REG_BLOCK_SIZE     16
> > -#define PAB_EXT_REG_BLOCK_SIZE 4
> > +#define PAB_REG_BLOCK_SIZE             16
> > +#define PAB_EXT_REG_BLOCK_SIZE         4
> >
> > -#define PAB_REG_ADDR(offset, win) (offset + (win *
> > PAB_REG_BLOCK_SIZE)) -#define PAB_EXT_REG_ADDR(offset, win) (offset +
> > (win * PAB_EXT_REG_BLOCK_SIZE))
> > +#define PAB_REG_ADDR(offset, win)      \
> > +       (offset + (win * PAB_REG_BLOCK_SIZE)) #define
> > +PAB_EXT_REG_ADDR(offset, win)  \
> > +       (offset + (win * PAB_EXT_REG_BLOCK_SIZE))
> >
> > -#define LTSSM_STATUS           0x0404
> > -#define  LTSSM_STATUS_L0_MASK  0x3f
> > -#define  LTSSM_STATUS_L0       0x2d
> > +#define LTSSM_STATUS                   0x0404
> > +#define  LTSSM_STATUS_L0_MASK          0x3f
> > +#define  LTSSM_STATUS_L0               0x2d
> >
> > -#define PAB_CTRL               0x0808
> > -#define  AMBA_PIO_ENABLE_SHIFT 0
> > -#define  PEX_PIO_ENABLE_SHIFT  1
> > -#define  PAGE_SEL_SHIFT        13
> > -#define  PAGE_SEL_MASK         0x3f
> > -#define  PAGE_LO_MASK          0x3ff
> > -#define  PAGE_SEL_OFFSET_SHIFT 10
> > +#define PAB_CTRL                       0x0808
> > +#define  AMBA_PIO_ENABLE_SHIFT         0
> > +#define  PEX_PIO_ENABLE_SHIFT          1
> > +#define  PAGE_SEL_SHIFT                        13
> above line seems to have an extra tab which makes it not aligned with lines
> above.

It is just a display issue in the email.

> > +#define  PAGE_SEL_MASK                 0x3f
> > +#define  PAGE_LO_MASK                  0x3ff
> > +#define  PAGE_SEL_OFFSET_SHIFT         10
> >
> > -#define PAB_AXI_PIO_CTRL       0x0840
> > -#define  APIO_EN_MASK          0xf
> > +#define PAB_AXI_PIO_CTRL               0x0840
> > +#define  APIO_EN_MASK                  0xf
> >
> > -#define PAB_PEX_PIO_CTRL       0x08c0
> > -#define  PIO_ENABLE_SHIFT      0
> > +#define PAB_PEX_PIO_CTRL               0x08c0
> > +#define  PIO_ENABLE_SHIFT              0
> >
> >  #define PAB_INTP_AMBA_MISC_ENB         0x0b0c
> > -#define PAB_INTP_AMBA_MISC_STAT        0x0b1c
> > +#define PAB_INTP_AMBA_MISC_STAT                0x0b1c
> >  #define  PAB_INTP_INTX_MASK            0x01e0
> >  #define  PAB_INTP_MSI_MASK             0x8
> >
> > -#define PAB_AXI_AMAP_CTRL(win) PAB_REG_ADDR(0x0ba0, win)
> > -#define  WIN_ENABLE_SHIFT      0
> > -#define  WIN_TYPE_SHIFT        1
> > +#define PAB_AXI_AMAP_CTRL(win)         PAB_REG_ADDR(0x0ba0,
> win)
> > +#define  WIN_ENABLE_SHIFT              0
> > +#define  WIN_TYPE_SHIFT                        1
> please check the extra tab above

Ditto

> >
> >  #define PAB_EXT_AXI_AMAP_SIZE(win)
> PAB_EXT_REG_ADDR(0xbaf0, win)
> >
> > @@ -70,16 +72,16 @@
> >  #define  AXI_WINDOW_ALIGN_MASK         3
> >
> >  #define PAB_AXI_AMAP_PEX_WIN_L(win)    PAB_REG_ADDR(0x0ba8,
> win)
> > -#define  PAB_BUS_SHIFT         24
> > -#define  PAB_DEVICE_SHIFT      19
> > -#define  PAB_FUNCTION_SHIFT    16
> > +#define  PAB_BUS_SHIFT                 24
> > +#define  PAB_DEVICE_SHIFT              19
> > +#define  PAB_FUNCTION_SHIFT            16
> >
> >  #define PAB_AXI_AMAP_PEX_WIN_H(win)    PAB_REG_ADDR(0x0bac,
> win)
> >  #define PAB_INTP_AXI_PIO_CLASS         0x474
> >
> > -#define PAB_PEX_AMAP_CTRL(win) PAB_REG_ADDR(0x4ba0, win)
> > -#define  AMAP_CTRL_EN_SHIFT    0
> > -#define  AMAP_CTRL_TYPE_SHIFT  1
> > +#define PAB_PEX_AMAP_CTRL(win)         PAB_REG_ADDR(0x4ba0,
> win)
> > +#define  AMAP_CTRL_EN_SHIFT            0
> > +#define  AMAP_CTRL_TYPE_SHIFT          1
> >
> >  #define PAB_EXT_PEX_AMAP_SIZEN(win)
> PAB_EXT_REG_ADDR(0xbef0, win)
> >  #define PAB_PEX_AMAP_AXI_WIN(win)      PAB_REG_ADDR(0x4ba4,
> win)
> > @@ -87,39 +89,39 @@
> >  #define PAB_PEX_AMAP_PEX_WIN_H(win)    PAB_REG_ADDR(0x4bac,
> win)
> >
> >  /* starting offset of INTX bits in status register */ -#define
> > PAB_INTX_START 5
> > +#define PAB_INTX_START                 5
> >
> >  /* supported number of MSI interrupts */
> > -#define PCI_NUM_MSI    16
> > +#define PCI_NUM_MSI                    16
> >
> >  /* MSI registers */
> > -#define MSI_BASE_LO_OFFSET     0x04
> > -#define MSI_BASE_HI_OFFSET     0x08
> > -#define MSI_SIZE_OFFSET        0x0c
> > -#define MSI_ENABLE_OFFSET      0x14
> > -#define MSI_STATUS_OFFSET      0x18
> > -#define MSI_DATA_OFFSET        0x20
> > -#define MSI_ADDR_L_OFFSET      0x24
> > -#define MSI_ADDR_H_OFFSET      0x28
> > +#define MSI_BASE_LO_OFFSET             0x04
> > +#define MSI_BASE_HI_OFFSET             0x08
> > +#define MSI_SIZE_OFFSET                        0x0c
> > +#define MSI_ENABLE_OFFSET              0x14
> > +#define MSI_STATUS_OFFSET              0x18
> > +#define MSI_DATA_OFFSET                        0x20
> > +#define MSI_ADDR_L_OFFSET              0x24
> > +#define MSI_ADDR_H_OFFSET              0x28
> size and data offset macros have extra tabs?

Ditto

> >
> >  /* outbound and inbound window definitions */
> > -#define WIN_NUM_0              0
> > -#define WIN_NUM_1              1
> > -#define CFG_WINDOW_TYPE        0
> > -#define IO_WINDOW_TYPE         1
> > -#define MEM_WINDOW_TYPE        2
> > -#define IB_WIN_SIZE            ((u64)256 * 1024 * 1024 * 1024)
> > -#define MAX_PIO_WINDOWS        8
> > +#define WIN_NUM_0                      0
> > +#define WIN_NUM_1                      1
> > +#define CFG_WINDOW_TYPE                        0
> > +#define IO_WINDOW_TYPE                 1
> > +#define MEM_WINDOW_TYPE                        2
> > +#define IB_WIN_SIZE                    ((u64)256 * 1024 * 1024 *
> 1024)
> > +#define MAX_PIO_WINDOWS                        8
> >
> >  /* Parameters for the waiting for link up routine */ -#define
> > LINK_WAIT_MAX_RETRIES  10 -#define LINK_WAIT_MIN  90000 -#define
> > LINK_WAIT_MAX  100000
> > +#define LINK_WAIT_MAX_RETRIES          10
> > +#define LINK_WAIT_MIN                  90000
> > +#define LINK_WAIT_MAX                  100000
> >
> > -#define PAGED_ADDR_BNDRY                       0xc00
> > -#define OFFSET_TO_PAGE_ADDR(off)               \
> > +#define PAGED_ADDR_BNDRY               0xc00
> > +#define OFFSET_TO_PAGE_ADDR(off)       \
> >         ((off & PAGE_LO_MASK) | PAGED_ADDR_BNDRY)
> > -#define OFFSET_TO_PAGE_IDX(off)                        \
> > +#define OFFSET_TO_PAGE_IDX(off)                \
> >         ((off >> PAGE_SEL_OFFSET_SHIFT) & PAGE_SEL_MASK)
> >
> >  struct mobiveil_msi {                  /* MSI information */
> > @@ -297,14 +299,14 @@ static void __iomem
> *mobiveil_pcie_map_bus(struct pci_bus *bus,
> >                                         unsigned int devfn, int
> where)
> > {
> >         struct mobiveil_pcie *pcie = bus->sysdata;
> > +       u32 value;
> >
> >         if (!mobiveil_pcie_valid_device(bus, devfn))
> >                 return NULL;
> >
> > -       if (bus->number == pcie->root_bus_nr) {
> > -               /* RC config access */
> > +       /* RC config access */
> > +       if (bus->number == pcie->root_bus_nr)
> >                 return pcie->csr_axi_slave_base + where;
> > -       }
> >
> >         /*
> >          * EP config access (in Config/APIO space) @@ -312,10 +314,12
> > @@ static void __iomem *mobiveil_pcie_map_bus(struct pci_bus *bus,
> >          * (BDF) in PAB_AXI_AMAP_PEX_WIN_L0 Register.
> >          * Relies on pci_lock serialization
> >          */
> > -       csr_writel(pcie, bus->number << PAB_BUS_SHIFT |
> > -                       PCI_SLOT(devfn) << PAB_DEVICE_SHIFT |
> > -                       PCI_FUNC(devfn) << PAB_FUNCTION_SHIFT,
> > -                       PAB_AXI_AMAP_PEX_WIN_L(WIN_NUM_0));
> > +       value = bus->number << PAB_BUS_SHIFT |
> > +               PCI_SLOT(devfn) << PAB_DEVICE_SHIFT |
> > +               PCI_FUNC(devfn) << PAB_FUNCTION_SHIFT;
> > +
> > +       csr_writel(pcie, value,
> PAB_AXI_AMAP_PEX_WIN_L(WIN_NUM_0));
> > +
> >         return pcie->config_axi_slave_base + where;  }
> >
> > @@ -350,22 +354,22 @@ static void mobiveil_pcie_isr(struct irq_desc
> > *desc)
> >
> >         /* Handle INTx */
> >         if (intr_status & PAB_INTP_INTX_MASK) {
> > -               shifted_status = csr_readl(pcie,
> PAB_INTP_AMBA_MISC_STAT) >>
> > -                       PAB_INTX_START;
> > +               shifted_status = csr_readl(pcie,
> PAB_INTP_AMBA_MISC_STAT);
> > +               shifted_status >>= PAB_INTX_START;
> >                 do {
> >                         for_each_set_bit(bit, &shifted_status,
> PCI_NUM_INTX) {
> >                                 virq =
> irq_find_mapping(pcie->intx_domain,
> > -                                               bit + 1);
> > +                                                       bit +
> 1);
> >                                 if (virq)
> >                                         generic_handle_irq(virq);
> >                                 else
> > -                                       dev_err_ratelimited(dev,
> > -                                               "unexpected
> IRQ, INT%d\n", bit);
> > +                                       dev_err_ratelimited(dev,
> "unexpected IRQ, INT%d\n",
> > +
> bit);
> >
> >                                 /* clear interrupt */
> >                                 csr_writel(pcie,
> > -                                       shifted_status <<
> PAB_INTX_START,
> > -
> PAB_INTP_AMBA_MISC_STAT);
> > +                                          shifted_status <<
> PAB_INTX_START,
> > +
> PAB_INTP_AMBA_MISC_STAT);
> >                         }
> >                 } while ((shifted_status >> PAB_INTX_START) != 0);
> >         }
> > @@ -375,8 +379,7 @@ static void mobiveil_pcie_isr(struct irq_desc
> > *desc)
> >
> >         /* handle MSI interrupts */
> >         while (msi_status & 1) {
> > -               msi_data = readl_relaxed(pcie->apb_csr_base
> > -                               + MSI_DATA_OFFSET);
> > +               msi_data = readl_relaxed(pcie->apb_csr_base +
> > + MSI_DATA_OFFSET);
> >
> >                 /*
> >                  * MSI_STATUS_OFFSET register gets updated to zero
> @@
> > -385,18 +388,18 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
> >                  * two dummy reads.
> >                  */
> >                 msi_addr_lo = readl_relaxed(pcie->apb_csr_base +
> > -                               MSI_ADDR_L_OFFSET);
> > +
> MSI_ADDR_L_OFFSET);
> >                 msi_addr_hi = readl_relaxed(pcie->apb_csr_base +
> > -                               MSI_ADDR_H_OFFSET);
> > +
> MSI_ADDR_H_OFFSET);
> >                 dev_dbg(dev, "MSI registers, data: %08x,
> addr: %08x:%08x\n",
> > -                               msi_data, msi_addr_hi,
> msi_addr_lo);
> > +                       msi_data, msi_addr_hi, msi_addr_lo);
> >
> >                 virq = irq_find_mapping(msi->dev_domain, msi_data);
> >                 if (virq)
> >                         generic_handle_irq(virq);
> >
> >                 msi_status = readl_relaxed(pcie->apb_csr_base +
> > -                               MSI_STATUS_OFFSET);
> > +
> MSI_STATUS_OFFSET);
> >         }
> >
> >         /* Clear the interrupt status */ @@ -413,7 +416,7 @@ static
> > int mobiveil_pcie_parse_dt(struct mobiveil_pcie *pcie)
> >
> >         /* map config resource */
> >         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> > -                       "config_axi_slave");
> > +                                          "config_axi_slave");
> >         pcie->config_axi_slave_base =
> devm_pci_remap_cfg_resource(dev, res);
> >         if (IS_ERR(pcie->config_axi_slave_base))
> >                 return PTR_ERR(pcie->config_axi_slave_base);
> > @@ -421,7 +424,7 @@ static int mobiveil_pcie_parse_dt(struct
> > mobiveil_pcie *pcie)
> >
> >         /* map csr resource */
> >         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> > -                       "csr_axi_slave");
> > +                                          "csr_axi_slave");
> >         pcie->csr_axi_slave_base = devm_pci_remap_cfg_resource(dev,
> res);
> >         if (IS_ERR(pcie->csr_axi_slave_base))
> >                 return PTR_ERR(pcie->csr_axi_slave_base);
> > @@ -452,7 +455,7 @@ static int mobiveil_pcie_parse_dt(struct
> > mobiveil_pcie *pcie)  }
> >
> >  static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
> > -               int pci_addr, u32 type, u64 size)
> > +                              int pci_addr, u32 type, u64 size)
> >  {
> >         int pio_ctrl_val;
> >         int amap_ctrl_dw;
> > @@ -465,19 +468,20 @@ static void program_ib_windows(struct
> mobiveil_pcie *pcie, int win_num,
> >         }
> >
> >         pio_ctrl_val = csr_readl(pcie, PAB_PEX_PIO_CTRL);
> > -       csr_writel(pcie,
> > -               pio_ctrl_val | (1 << PIO_ENABLE_SHIFT),
> PAB_PEX_PIO_CTRL);
> > -       amap_ctrl_dw = csr_readl(pcie,
> PAB_PEX_AMAP_CTRL(win_num));
> > -       amap_ctrl_dw = (amap_ctrl_dw | (type <<
> AMAP_CTRL_TYPE_SHIFT));
> > -       amap_ctrl_dw = (amap_ctrl_dw | (1 << AMAP_CTRL_EN_SHIFT));
> > +       pio_ctrl_val |= 1 << PIO_ENABLE_SHIFT;
> > +       csr_writel(pcie, pio_ctrl_val, PAB_PEX_PIO_CTRL);
> >
> > -       csr_writel(pcie, amap_ctrl_dw | lower_32_bits(size64),
> > -                  PAB_PEX_AMAP_CTRL(win_num));
> > +       amap_ctrl_dw = csr_readl(pcie,
> PAB_PEX_AMAP_CTRL(win_num));
> > +       amap_ctrl_dw |= (type << AMAP_CTRL_TYPE_SHIFT) |
> > +                       (1 << AMAP_CTRL_EN_SHIFT) |
> > +                       lower_32_bits(size64);
> > +       csr_writel(pcie, amap_ctrl_dw, PAB_PEX_AMAP_CTRL(win_num));
> >
> >         csr_writel(pcie, upper_32_bits(size64),
> >                    PAB_EXT_PEX_AMAP_SIZEN(win_num));
> >
> >         csr_writel(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
> > +
> >         csr_writel(pcie, pci_addr,
> PAB_PEX_AMAP_PEX_WIN_L(win_num));
> >         csr_writel(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));  }
> @@
> > -486,7 +490,8 @@ static void program_ib_windows(struct mobiveil_pcie
> *pcie, int win_num,
> >   * routine to program the outbound windows
> >   */
> >  static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
> > -               u64 cpu_addr, u64 pci_addr, u32 config_io_bit, u64 size)
> > +                              u64 cpu_addr, u64 pci_addr,
> > +                              u32 config_io_bit, u64 size)
> >  {
> >
> >         u32 value, type;
> > @@ -505,7 +510,7 @@ static void program_ob_windows(struct
> mobiveil_pcie *pcie, int win_num,
> >         type = config_io_bit;
> >         value = csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num));
> >         csr_writel(pcie, 1 << WIN_ENABLE_SHIFT | type <<
> WIN_TYPE_SHIFT |
> > -                       lower_32_bits(size64),
> PAB_AXI_AMAP_CTRL(win_num));
> > +                  lower_32_bits(size64),
> PAB_AXI_AMAP_CTRL(win_num));
> >
> >         csr_writel(pcie, upper_32_bits(size64),
> > PAB_EXT_AXI_AMAP_SIZE(win_num));
> >
> > @@ -515,14 +520,14 @@ static void program_ob_windows(struct
> mobiveil_pcie *pcie, int win_num,
> >          */
> >         value = csr_readl(pcie, PAB_AXI_AMAP_AXI_WIN(win_num));
> >         csr_writel(pcie, cpu_addr & (~AXI_WINDOW_ALIGN_MASK),
> > -                       PAB_AXI_AMAP_AXI_WIN(win_num));
> > +                  PAB_AXI_AMAP_AXI_WIN(win_num));
> >
> >         value = csr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_H(win_num));
> >
> >         csr_writel(pcie, lower_32_bits(pci_addr),
> > -                       PAB_AXI_AMAP_PEX_WIN_L(win_num));
> > +                  PAB_AXI_AMAP_PEX_WIN_L(win_num));
> >         csr_writel(pcie, upper_32_bits(pci_addr),
> > -                       PAB_AXI_AMAP_PEX_WIN_H(win_num));
> > +                  PAB_AXI_AMAP_PEX_WIN_H(win_num));
> >
> >         pcie->ob_wins_configured++;
> >  }
> > @@ -538,7 +543,9 @@ static int mobiveil_bringup_link(struct
> > mobiveil_pcie *pcie)
> >
> >                 usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
> >         }
> > +
> >         dev_err(&pcie->pdev->dev, "link never came up\n");
> > +
> >         return -ETIMEDOUT;
> >  }
> >
> > @@ -551,16 +558,16 @@ static void mobiveil_pcie_enable_msi(struct
> mobiveil_pcie *pcie)
> >         msi->msi_pages_phys = (phys_addr_t)msg_addr;
> >
> >         writel_relaxed(lower_32_bits(msg_addr),
> > -               pcie->apb_csr_base + MSI_BASE_LO_OFFSET);
> > +                      pcie->apb_csr_base + MSI_BASE_LO_OFFSET);
> >         writel_relaxed(upper_32_bits(msg_addr),
> > -               pcie->apb_csr_base + MSI_BASE_HI_OFFSET);
> > +                      pcie->apb_csr_base + MSI_BASE_HI_OFFSET);
> >         writel_relaxed(4096, pcie->apb_csr_base + MSI_SIZE_OFFSET);
> >         writel_relaxed(1, pcie->apb_csr_base +
> MSI_ENABLE_OFFSET);  }
> >
> >  static int mobiveil_host_init(struct mobiveil_pcie *pcie)  {
> > -       u32 value, pab_ctrl, type = 0;
> > +       u32 value, pab_ctrl, type;
> >         int err;
> >         struct resource_entry *win, *tmp;
> >
> > @@ -575,26 +582,27 @@ static int mobiveil_host_init(struct mobiveil_pcie
> *pcie)
> >          * Space
> >          */
> >         value = csr_readl(pcie, PCI_COMMAND);
> > -       csr_writel(pcie, value | PCI_COMMAND_IO |
> PCI_COMMAND_MEMORY |
> > -               PCI_COMMAND_MASTER, PCI_COMMAND);
> > +       value |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
> PCI_COMMAND_MASTER;
> > +       csr_writel(pcie, value, PCI_COMMAND);
> >
> >         /*
> >          * program PIO Enable Bit to 1 (and PEX PIO Enable to 1) in
> PAB_CTRL
> >          * register
> >          */
> >         pab_ctrl = csr_readl(pcie, PAB_CTRL);
> > -       csr_writel(pcie, pab_ctrl | (1 << AMBA_PIO_ENABLE_SHIFT) |
> > -               (1 << PEX_PIO_ENABLE_SHIFT), PAB_CTRL);
> > +       pab_ctrl |= (1 << AMBA_PIO_ENABLE_SHIFT) | (1 <<
> PEX_PIO_ENABLE_SHIFT);
> > +       csr_writel(pcie, pab_ctrl, PAB_CTRL);
> >
> >         csr_writel(pcie, (PAB_INTP_INTX_MASK |
> PAB_INTP_MSI_MASK),
> > -               PAB_INTP_AMBA_MISC_ENB);
> > +                  PAB_INTP_AMBA_MISC_ENB);
> >
> >         /*
> >          * program PIO Enable Bit to 1 and Config Window Enable Bit to
> 1 in
> >          * PAB_AXI_PIO_CTRL Register
> >          */
> >         value = csr_readl(pcie, PAB_AXI_PIO_CTRL);
> > -       csr_writel(pcie, value | APIO_EN_MASK, PAB_AXI_PIO_CTRL);
> > +       value |= APIO_EN_MASK;
> > +       csr_writel(pcie, value, PAB_AXI_PIO_CTRL);
> >
> >         /*
> >          * we'll program one outbound window for config reads and @@
> > -605,25 +613,25 @@ static int mobiveil_host_init(struct mobiveil_pcie
> > *pcie)
> >
> >         /* config outbound translation window */
> >         program_ob_windows(pcie, pcie->ob_wins_configured,
> > -                       pcie->ob_io_res->start, 0,
> CFG_WINDOW_TYPE,
> > -                       resource_size(pcie->ob_io_res));
> > +                          pcie->ob_io_res->start, 0,
> CFG_WINDOW_TYPE,
> > +                          resource_size(pcie->ob_io_res));
> >
> >         /* memory inbound translation window */
> >         program_ib_windows(pcie, WIN_NUM_1, 0,
> MEM_WINDOW_TYPE,
> > IB_WIN_SIZE);
> >
> >         /* Get the I/O and memory ranges from DT */
> >         resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
> > -               type = 0;
> >                 if (resource_type(win->res) == IORESOURCE_MEM)
> >                         type = MEM_WINDOW_TYPE;
> > -               if (resource_type(win->res) == IORESOURCE_IO)
> > +               else if (resource_type(win->res) == IORESOURCE_IO)
> >                         type = IO_WINDOW_TYPE;
> > -               if (type) {
> > -                       /* configure outbound translation window */
> > -                       program_ob_windows(pcie,
> pcie->ob_wins_configured,
> > -                               win->res->start, 0, type,
> > -                               resource_size(win->res));
> > -               }
> > +               else
> > +                       continue;
> > +
> > +               /* configure outbound translation window */
> > +               program_ob_windows(pcie, pcie->ob_wins_configured,
> > +                                  win->res->start, 0, type,
> > +                                  resource_size(win->res));
> >         }
> >
> >         /* setup MSI hardware registers */ @@ -643,7 +651,8 @@ static
> > void mobiveil_mask_intx_irq(struct irq_data *data)
> >         mask = 1 << ((data->hwirq + PAB_INTX_START) - 1);
> >         raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags);
> >         shifted_val = csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB);
> > -       csr_writel(pcie, (shifted_val & (~mask)),
> PAB_INTP_AMBA_MISC_ENB);
> > +       shifted_val &= ~mask;
> > +       csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB);
> >         raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags);  }
> >
> > @@ -658,7 +667,8 @@ static void mobiveil_unmask_intx_irq(struct
> irq_data *data)
> >         mask = 1 << ((data->hwirq + PAB_INTX_START) - 1);
> >         raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags);
> >         shifted_val = csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB);
> > -       csr_writel(pcie, (shifted_val | mask),
> PAB_INTP_AMBA_MISC_ENB);
> > +       shifted_val |= mask;
> > +       csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB);
> >         raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags);  }
> >
> > @@ -672,10 +682,11 @@ static struct irq_chip intx_irq_chip = {
> >
> >  /* routine to setup the INTx related data */  static int
> > mobiveil_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
> > -               irq_hw_number_t hwirq)
> > +                                 irq_hw_number_t hwirq)
> >  {
> >         irq_set_chip_and_handler(irq, &intx_irq_chip, handle_level_irq);
> >         irq_set_chip_data(irq, domain->host_data);
> > +
> >         return 0;
> >  }
> >
> > @@ -692,7 +703,7 @@ static struct irq_chip mobiveil_msi_irq_chip = {
> >
> >  static struct msi_domain_info mobiveil_msi_domain_info = {
> >         .flags  = (MSI_FLAG_USE_DEF_DOM_OPS |
> MSI_FLAG_USE_DEF_CHIP_OPS |
> > -               MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX),
> > +                  MSI_FLAG_MULTI_PCI_MSI |
> MSI_FLAG_PCI_MSIX),
> >         .chip   = &mobiveil_msi_irq_chip,
> >  };
> >
> > @@ -710,7 +721,7 @@ static void mobiveil_compose_msi_msg(struct
> > irq_data *data, struct msi_msg *msg)  }
> >
> >  static int mobiveil_msi_set_affinity(struct irq_data *irq_data,
> > -               const struct cpumask *mask, bool force)
> > +                                    const struct cpumask *mask,
> bool
> > + force)
> >  {
> >         return -EINVAL;
> >  }
> > @@ -722,7 +733,8 @@ static struct irq_chip
> > mobiveil_msi_bottom_irq_chip = {  };
> >
> >  static int mobiveil_irq_msi_domain_alloc(struct irq_domain *domain,
> > -               unsigned int virq, unsigned int nr_irqs, void *args)
> > +                                        unsigned int virq,
> > +                                        unsigned int nr_irqs, void
> > + *args)
> >  {
> >         struct mobiveil_pcie *pcie = domain->host_data;
> >         struct mobiveil_msi *msi = &pcie->msi; @@ -742,13 +754,13
> @@
> > static int mobiveil_irq_msi_domain_alloc(struct irq_domain *domain,
> >         mutex_unlock(&msi->lock);
> >
> >         irq_domain_set_info(domain, virq, bit,
> &mobiveil_msi_bottom_irq_chip,
> > -                               domain->host_data,
> handle_level_irq,
> > -                               NULL, NULL);
> > +                           domain->host_data, handle_level_irq,
> NULL,
> > + NULL);
> >         return 0;
> >  }
> >
> >  static void mobiveil_irq_msi_domain_free(struct irq_domain *domain,
> > -               unsigned int virq, unsigned int nr_irqs)
> > +                                        unsigned int virq,
> > +                                        unsigned int nr_irqs)
> >  {
> >         struct irq_data *d = irq_domain_get_irq_data(domain, virq);
> >         struct mobiveil_pcie *pcie = irq_data_get_irq_chip_data(d); @@
> > -756,12 +768,11 @@ static void mobiveil_irq_msi_domain_free(struct
> > irq_domain *domain,
> >
> >         mutex_lock(&msi->lock);
> >
> > -       if (!test_bit(d->hwirq, msi->msi_irq_in_use)) {
> > +       if (!test_bit(d->hwirq, msi->msi_irq_in_use))
> >                 dev_err(&pcie->pdev->dev, "trying to free unused
> MSI#%lu\n",
> >                         d->hwirq);
> > -       } else {
> > +       else
> >                 __clear_bit(d->hwirq, msi->msi_irq_in_use);
> > -       }
> >
> >         mutex_unlock(&msi->lock);
> >  }
> > @@ -785,12 +796,14 @@ static int mobiveil_allocate_msi_domains(struct
> mobiveil_pcie *pcie)
> >         }
> >
> >         msi->msi_domain = pci_msi_create_irq_domain(fwnode,
> > -                               &mobiveil_msi_domain_info,
> msi->dev_domain);
> > +
> &mobiveil_msi_domain_info,
> > +
> msi->dev_domain);
> >         if (!msi->msi_domain) {
> >                 dev_err(dev, "failed to create MSI domain\n");
> >                 irq_domain_remove(msi->dev_domain);
> >                 return -ENOMEM;
> >         }
> > +
> >         return 0;
> >  }
> >
> > @@ -801,8 +814,8 @@ static int mobiveil_pcie_init_irq_domain(struct
> mobiveil_pcie *pcie)
> >         int ret;
> >
> >         /* setup INTx */
> > -       pcie->intx_domain = irq_domain_add_linear(node,
> > -                               PCI_NUM_INTX, &intx_domain_ops,
> pcie);
> > +       pcie->intx_domain = irq_domain_add_linear(node,
> PCI_NUM_INTX,
> > +
> &intx_domain_ops,
> > + pcie);
> >
> >         if (!pcie->intx_domain) {
> >                 dev_err(dev, "Failed to get a INTx IRQ domain\n"); @@
> > -917,10 +930,10 @@ MODULE_DEVICE_TABLE(of,
> mobiveil_pcie_of_match);
> > static struct platform_driver mobiveil_pcie_driver = {
> >         .probe = mobiveil_pcie_probe,
> >         .driver = {
> > -                       .name = "mobiveil-pcie",
> > -                       .of_match_table = mobiveil_pcie_of_match,
> > -                       .suppress_bind_attrs = true,
> > -               },
> > +               .name = "mobiveil-pcie",
> > +               .of_match_table = mobiveil_pcie_of_match,
> > +               .suppress_bind_attrs = true,
> > +       },
> >  };
> >
> >  builtin_platform_driver(mobiveil_pcie_driver);
> > --
> > 2.17.1
> >
> 
> 

Thanks,
Zhiqiang

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

* RE: [PATCHv3 04/27] PCI: mobiveil: remove flag MSI_FLAG_MULTI_PCI_MSI
  2019-02-05  6:05   ` Subrahmanya Lingappa
@ 2019-02-18  7:03     ` Z.q. Hou
  0 siblings, 0 replies; 68+ messages in thread
From: Z.q. Hou @ 2019-02-18  7:03 UTC (permalink / raw)
  To: Subrahmanya Lingappa
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Hi Subbu,

Thanks a lot for your comments!

> -----Original Message-----
> From: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> Sent: 2019年2月5日 14:05
> To: Z.q. Hou <zhiqiang.hou@nxp.com>
> Cc: linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> bhelgaas@google.com; robh+dt@kernel.org; mark.rutland@arm.com;
> shawnguo@kernel.org; Leo Li <leoyang.li@nxp.com>;
> lorenzo.pieralisi@arm.com; catalin.marinas@arm.com;
> will.deacon@arm.com; Mingkai Hu <mingkai.hu@nxp.com>; M.h. Lian
> <minghuan.lian@nxp.com>; Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: Re: [PATCHv3 04/27] PCI: mobiveil: remove flag
> MSI_FLAG_MULTI_PCI_MSI
> 
> Zhiqiang,
> why are we removing multi-MSI support ?
> what functionality this driver is not providing to support it ?

In the function mobiveil_irq_msi_domain_alloc() there is a check about the number of IRQs to allocate: WARN_ON(nr_irqs != 1);
This is a paradox against the flag "MSI_FLAG_MULTI_PCI_MSI".

> 
> Thanks.
> 
> On Tue, Jan 29, 2019 at 1:38 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
> >
> > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> >
> > The current code does not support multiple MSIs, so remove the
> > corresponding flag from the msi_domain_info structure.
> >
> > Fixes: 1e913e58335f ("PCI: mobiveil: Add MSI support")
> > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> > ---
> > V3:
> >  - No change
> >
> >  drivers/pci/controller/pcie-mobiveil.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/pcie-mobiveil.c
> > b/drivers/pci/controller/pcie-mobiveil.c
> > index 563210e731d3..a0dd337c6214 100644
> > --- a/drivers/pci/controller/pcie-mobiveil.c
> > +++ b/drivers/pci/controller/pcie-mobiveil.c
> > @@ -703,7 +703,7 @@ static struct irq_chip mobiveil_msi_irq_chip = {
> >
> >  static struct msi_domain_info mobiveil_msi_domain_info = {
> >         .flags  = (MSI_FLAG_USE_DEF_DOM_OPS |
> MSI_FLAG_USE_DEF_CHIP_OPS |
> > -                  MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX),
> > +                  MSI_FLAG_PCI_MSIX),
> >         .chip   = &mobiveil_msi_irq_chip,
> >  };
> >
> > --
> > 2.17.1
> >
Thanks,
Zhiqiang

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

* RE: [PATCHv3 17/27] PCI: mobiveil: fix the checking of valid device
  2019-02-08 12:41   ` Subrahmanya Lingappa
  2019-02-08 14:13     ` Bjorn Helgaas
@ 2019-02-18  7:04     ` Z.q. Hou
  1 sibling, 0 replies; 68+ messages in thread
From: Z.q. Hou @ 2019-02-18  7:04 UTC (permalink / raw)
  To: Subrahmanya Lingappa
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Hi Subbu,

Thanks a lot for your comments!

> -----Original Message-----
> From: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> Sent: 2019年2月8日 20:41
> To: Z.q. Hou <zhiqiang.hou@nxp.com>
> Cc: linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> bhelgaas@google.com; robh+dt@kernel.org; mark.rutland@arm.com;
> shawnguo@kernel.org; Leo Li <leoyang.li@nxp.com>;
> lorenzo.pieralisi@arm.com; catalin.marinas@arm.com;
> will.deacon@arm.com; Mingkai Hu <mingkai.hu@nxp.com>; M.h. Lian
> <minghuan.lian@nxp.com>; Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: Re: [PATCHv3 17/27] PCI: mobiveil: fix the checking of valid device
> 
> ZQ,
> 
> On Tue, Jan 29, 2019 at 1:40 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
> >
> > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> >
> > Avoid to issue CFG transactions to link partner when the PCIe link is
> > not up. And allow CFG transactions to all functions of Endpoint
> > implemented multiple functions.
> >
> > Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge IP
> > driver")
> > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> > ---
> > V3:
> >  - No change
> >
> >  drivers/pci/controller/mobiveil/pcie-mobiveil-host.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > index dc5324d94466..1ae82e790562 100644
> > --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > @@ -29,6 +29,10 @@ static bool mobiveil_pcie_valid_device(struct
> > pci_bus *bus, unsigned int devfn)  {
> >         struct mobiveil_pcie *pcie = bus->sysdata;
> >
> > +       /* If there is no link, then there is no device */
> > +       if (bus->number > pcie->rp.root_bus_nr
> && !mobiveil_pcie_link_up(pcie))
> > +               return false;
> > +
> >         /* Only one device down on each root port */
> >         if ((bus->number == pcie->rp.root_bus_nr) && (devfn > 0))
> >                 return false;
> > @@ -37,7 +41,7 @@ static bool mobiveil_pcie_valid_device(struct pci_bus
> *bus, unsigned int devfn)
> >          * Do not read more than one device on the bus directly
> >          * attached to RC
> >          */
> > -       if ((bus->primary == pcie->rp.root_bus_nr) && (devfn > 0))
> > +       if ((bus->primary == pcie->rp.root_bus_nr) && (PCI_SLOT(devfn)
> > + > 0))
> here change "primary" to "number", as it's a bug in the original driver too.

No, I think it should not change to "number", as this is to check the EP directly attached to RC, so if we change it to "bus->number", the "pcie->rp.root_bus_nr" should be changed to "pcie->rp.root_bus_nr +1" correspondingly.

> 
> >                 return false;
> >
> >         return true;
> > --
> > 2.17.1
> >

Thanks,
Zhiqiang

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

* RE: [PATCHv3 23/27] PCI: mobiveil: add PCIe Gen4 RC driver for NXP Layerscape SoCs
  2019-02-08 12:49   ` Subrahmanya Lingappa
@ 2019-02-18  7:05     ` Z.q. Hou
  0 siblings, 0 replies; 68+ messages in thread
From: Z.q. Hou @ 2019-02-18  7:05 UTC (permalink / raw)
  To: Subrahmanya Lingappa
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Hi Subbu,

Thanks a lot for your comments!

> -----Original Message-----
> From: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> Sent: 2019年2月8日 20:50
> To: Z.q. Hou <zhiqiang.hou@nxp.com>
> Cc: linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> bhelgaas@google.com; robh+dt@kernel.org; mark.rutland@arm.com;
> shawnguo@kernel.org; Leo Li <leoyang.li@nxp.com>;
> lorenzo.pieralisi@arm.com; catalin.marinas@arm.com;
> will.deacon@arm.com; Mingkai Hu <mingkai.hu@nxp.com>; M.h. Lian
> <minghuan.lian@nxp.com>; Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: Re: [PATCHv3 23/27] PCI: mobiveil: add PCIe Gen4 RC driver for NXP
> Layerscape SoCs
> 
> ZQ,
> 
> 
> On Tue, Jan 29, 2019 at 1:40 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
> >
> > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> >
> > This PCIe controller is based on the Mobiveil GPEX IP, which is
> > compatible with the PCI Express™ Base Specification, Revision 4.0.
> >
> > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> > ---
> > V3:
> >  - No change
> >
> >  drivers/pci/controller/mobiveil/Kconfig       |  10 +
> >  drivers/pci/controller/mobiveil/Makefile      |   1 +
> >  .../controller/mobiveil/pci-layerscape-gen4.c | 254 ++++++++++++++++++
> >  .../pci/controller/mobiveil/pcie-mobiveil.h   |  16 +-
> >  4 files changed, 279 insertions(+), 2 deletions(-)  create mode
> > 100644 drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> >
> > diff --git a/drivers/pci/controller/mobiveil/Kconfig
> > b/drivers/pci/controller/mobiveil/Kconfig
> > index 64343c07bfed..3ddb7d6163a9 100644
> > --- a/drivers/pci/controller/mobiveil/Kconfig
> > +++ b/drivers/pci/controller/mobiveil/Kconfig
> > @@ -21,4 +21,14 @@ config PCIE_MOBIVEIL_PLAT
> >           Soft IP. It has up to 8 outbound and inbound windows
> >           for address translation and it is a PCIe Gen4 IP.
> >
> > +config PCI_LAYERSCAPE_GEN4
> > +       bool "Freescale Layerscpe PCIe Gen4 controller"
> > +       depends on PCI
> > +       depends on OF && (ARM64 || ARCH_LAYERSCAPE)
> > +       depends on PCI_MSI_IRQ_DOMAIN
> > +       select PCIE_MOBIVEIL_HOST
> > +       help
> > +         Say Y here if you want PCIe Gen4 controller support on
> > +         Layerscape SoCs. The PCIe controller can work in RC or
> > +         EP mode according to RCW[HOST_AGT_PEX] setting.
> >  endmenu
> > diff --git a/drivers/pci/controller/mobiveil/Makefile
> > b/drivers/pci/controller/mobiveil/Makefile
> > index 9fb6d1c6504d..ff66774ccac4 100644
> > --- a/drivers/pci/controller/mobiveil/Makefile
> > +++ b/drivers/pci/controller/mobiveil/Makefile
> > @@ -2,3 +2,4 @@
> >  obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o
> >  obj-$(CONFIG_PCIE_MOBIVEIL_HOST) += pcie-mobiveil-host.o
> >  obj-$(CONFIG_PCIE_MOBIVEIL_PLAT) += pcie-mobiveil-plat.o
> > +obj-$(CONFIG_PCI_LAYERSCAPE_GEN4) += pci-layerscape-gen4.o
> > diff --git a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> > b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> > new file mode 100644
> > index 000000000000..174cbcac4059
> > --- /dev/null
> > +++ b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> > @@ -0,0 +1,254 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * PCIe host controller driver for NXP Layerscape SoCs
> > + *
> > + * Copyright 2018 NXP
> > + *
> > + * Author: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>  */
> > +
> > +#include <linux/kernel.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/init.h>
> > +#include <linux/of_pci.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_address.h>
> > +#include <linux/pci.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/resource.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/regmap.h>
> > +
> > +#include "pcie-mobiveil.h"
> > +
> > +/* LUT and PF control registers */
> > +#define PCIE_LUT_OFF                   (0x80000)
> > +#define PCIE_PF_OFF                    (0xc0000)
> > +#define PCIE_PF_INT_STAT               (0x18)
> > +#define PF_INT_STAT_PABRST             (31)
> > +
> > +#define PCIE_PF_DBG                    (0x7fc)
> > +#define PF_DBG_LTSSM_MASK              (0x3f)
> > +#define PF_DBG_WE                      (31)
> > +#define PF_DBG_PABR                    (27)
> > +
> > +#define LS_PCIE_G4_LTSSM_L0            0x2d /* L0 state */
> > +
> > +#define to_ls_pcie_g4(x)
> platform_get_drvdata((x)->pdev)
> > +
> > +struct ls_pcie_g4 {
> > +       struct mobiveil_pcie *pci;
> > +       struct delayed_work dwork;
> > +       int irq;
> > +};
> > +
> > +static inline u32 ls_pcie_g4_lut_readl(struct ls_pcie_g4 *pcie, u32
> > +off) {
> > +       return ioread32(pcie->pci->csr_axi_slave_base + PCIE_LUT_OFF +
> > +off); }
> > +
> > +static inline void ls_pcie_g4_lut_writel(struct ls_pcie_g4 *pcie,
> > +                                        u32 off, u32 val) {
> > +       iowrite32(val, pcie->pci->csr_axi_slave_base + PCIE_LUT_OFF +
> > +off); }
> > +
> > +static inline u32 ls_pcie_g4_pf_readl(struct ls_pcie_g4 *pcie, u32
> > +off) {
> > +       return ioread32(pcie->pci->csr_axi_slave_base + PCIE_PF_OFF +
> > +off); }
> > +
> > +static inline void ls_pcie_g4_pf_writel(struct ls_pcie_g4 *pcie,
> > +                                       u32 off, u32 val) {
> > +       iowrite32(val, pcie->pci->csr_axi_slave_base + PCIE_PF_OFF +
> > +off); }
> > +
> > +static bool ls_pcie_g4_is_bridge(struct ls_pcie_g4 *pcie) {
> > +       struct mobiveil_pcie *mv_pci = pcie->pci;
> > +       u32 header_type;
> > +
> > +       header_type = csr_readb(mv_pci, PCI_HEADER_TYPE);
> > +       header_type &= 0x7f;
> > +
> > +       return header_type == PCI_HEADER_TYPE_BRIDGE; }
> > +
> > +static int ls_pcie_g4_link_up(struct mobiveil_pcie *pci) {
> > +       struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
> > +       u32 state;
> > +
> > +       state = ls_pcie_g4_pf_readl(pcie, PCIE_PF_DBG);
> > +       state = state & PF_DBG_LTSSM_MASK;
> > +
> > +       if (state == LS_PCIE_G4_LTSSM_L0)
> > +               return 1;
> > +
> > +       return 0;
> > +}
> > +
> > +static void ls_pcie_g4_reinit_hw(struct ls_pcie_g4 *pcie) {
> > +       struct mobiveil_pcie *mv_pci = pcie->pci;
> > +       u32 val, act_stat;
> > +       int to = 100;
> > +
> > +       /* Poll for pab_csb_reset to set and PAB activity to clear */
> > +       do {
> > +               usleep_range(10, 15);
> > +               val = ls_pcie_g4_pf_readl(pcie, PCIE_PF_INT_STAT);
> > +               act_stat = csr_readl(mv_pci, PAB_ACTIVITY_STAT);
> > +       } while (((val & 1 << PF_INT_STAT_PABRST) == 0 || act_stat) &&
> to--);
> > +       if (to < 0) {
> > +               dev_err(&mv_pci->pdev->dev, "poll PABRST&PABACT
> timeout\n");
> > +               return;
> > +       }
> > +
> > +       /* clear PEX_RESET bit in PEX_PF0_DBG register */
> > +       val = ls_pcie_g4_pf_readl(pcie, PCIE_PF_DBG);
> > +       val |= 1 << PF_DBG_WE;
> > +       ls_pcie_g4_pf_writel(pcie, PCIE_PF_DBG, val);
> > +
> > +       val = ls_pcie_g4_pf_readl(pcie, PCIE_PF_DBG);
> > +       val |= 1 << PF_DBG_PABR;
> > +       ls_pcie_g4_pf_writel(pcie, PCIE_PF_DBG, val);
> > +
> > +       val = ls_pcie_g4_pf_readl(pcie, PCIE_PF_DBG);
> > +       val &= ~(1 << PF_DBG_WE);
> > +       ls_pcie_g4_pf_writel(pcie, PCIE_PF_DBG, val);
> > +
> > +       mobiveil_host_init(mv_pci, true);
> > +
> > +       to = 100;
> > +       while (!ls_pcie_g4_link_up(mv_pci) && to--)
> > +               usleep_range(200, 250);
> > +       if (to < 0)
> > +               dev_err(&mv_pci->pdev->dev, "PCIe link trainning
> > +timeout\n"); }
> > +
> > +static irqreturn_t ls_pcie_g4_handler(int irq, void *dev_id) {
> > +       struct ls_pcie_g4 *pcie = (struct ls_pcie_g4 *)dev_id;
> > +       struct mobiveil_pcie *mv_pci = pcie->pci;
> > +       u32 val;
> > +
> > +       val = csr_readl(mv_pci, PAB_INTP_AMBA_MISC_STAT);
> > +       if (!val)
> > +               return IRQ_NONE;
> > +
> > +       if (val & PAB_INTP_RESET)
> > +               schedule_delayed_work(&pcie->dwork,
> > + msecs_to_jiffies(1));
> > +
> > +       csr_writel(mv_pci, val, PAB_INTP_AMBA_MISC_STAT);
> > +
> > +       return IRQ_HANDLED;
> > +}
> > +
> > +static int ls_pcie_g4_interrupt_init(struct mobiveil_pcie *mv_pci) {
> > +       struct ls_pcie_g4 *pcie = to_ls_pcie_g4(mv_pci);
> > +       u32 val;
> > +       int ret;
> > +
> > +       pcie->irq = platform_get_irq_byname(mv_pci->pdev, "intr");
> > +       if (pcie->irq < 0) {
> > +               dev_err(&mv_pci->pdev->dev, "Can't get 'intr' irq.\n");
> > +               return pcie->irq;
> > +       }
> > +       ret = devm_request_irq(&mv_pci->pdev->dev, pcie->irq,
> > +                              ls_pcie_g4_handler, IRQF_SHARED,
> > +                              mv_pci->pdev->name, pcie);
> > +       if (ret) {
> > +               dev_err(&mv_pci->pdev->dev, "Can't register PCIe
> IRQ.\n");
> > +               return  ret;
> > +       }
> > +
> > +       /* Enable interrupts */
> > +       val = PAB_INTP_INTX_MASK | PAB_INTP_MSI | PAB_INTP_RESET
> |
> > +             PAB_INTP_PCIE_UE | PAB_INTP_IE_PMREDI |
> PAB_INTP_IE_EC;
> > +       csr_writel(mv_pci, val, PAB_INTP_AMBA_MISC_ENB);
> > +
> > +       return 0;
> > +}
> > +
> > +static void ls_pcie_g4_reset(struct work_struct *work) {
> > +       struct delayed_work *dwork = container_of(work, struct
> delayed_work,
> > +                                                 work);
> > +       struct ls_pcie_g4 *pcie = container_of(dwork, struct ls_pcie_g4,
> dwork);
> > +       struct mobiveil_pcie *mv_pci = pcie->pci;
> > +       u16 ctrl;
> > +
> > +       ctrl = csr_readw(mv_pci, PCI_BRIDGE_CONTROL);
> > +       ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
> > +       csr_writew(mv_pci, ctrl, PCI_BRIDGE_CONTROL);
> > +       ls_pcie_g4_reinit_hw(pcie);
> > +}
> > +
> > +static struct mobiveil_rp_ops ls_pcie_g4_rp_ops = {
> > +       .interrupt_init = ls_pcie_g4_interrupt_init, };
> > +
> > +static const struct mobiveil_pab_ops ls_pcie_g4_pab_ops = {
> > +       .link_up = ls_pcie_g4_link_up, };
> > +
> > +static int __init ls_pcie_g4_probe(struct platform_device *pdev) {
> > +       struct device *dev = &pdev->dev;
> > +       struct mobiveil_pcie *mv_pci;
> > +       struct ls_pcie_g4 *pcie;
> > +       struct device_node *np = dev->of_node;
> > +       int ret;
> > +
> > +       if (!of_parse_phandle(np, "msi-parent", 0)) {
> > +               dev_err(dev, "failed to find msi-parent\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> > +       if (!pcie)
> > +               return -ENOMEM;
> > +
> > +       mv_pci = devm_kzalloc(dev, sizeof(*mv_pci), GFP_KERNEL);
> > +       if (!mv_pci)
> > +               return -ENOMEM;
> > +
> > +       mv_pci->pdev = pdev;
> > +       mv_pci->ops = &ls_pcie_g4_pab_ops;
> > +       mv_pci->rp.ops = &ls_pcie_g4_rp_ops;
> > +       pcie->pci = mv_pci;
> > +
> > +       platform_set_drvdata(pdev, pcie);
> > +
> > +       INIT_DELAYED_WORK(&pcie->dwork, ls_pcie_g4_reset);
> > +
> > +       ret = mobiveil_pcie_host_probe(mv_pci);
> > +       if (ret) {
> > +               dev_err(dev, "fail to probe!\n");
> > +               return  ret;
> > +       }
> > +
> > +       if (!ls_pcie_g4_is_bridge(pcie))
> > +               return -ENODEV;
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct of_device_id ls_pcie_g4_of_match[] = {
> > +       { .compatible = "fsl,lx2160a-pcie", },
> > +       { },
> > +};
> > +
> > +static struct platform_driver ls_pcie_g4_driver = {
> > +       .driver = {
> > +               .name = "layerscape-pcie-gen4",
> > +               .of_match_table = ls_pcie_g4_of_match,
> > +               .suppress_bind_attrs = true,
> > +       },
> > +};
> > +
> > +builtin_platform_driver_probe(ls_pcie_g4_driver, ls_pcie_g4_probe);
> > diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> > b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> > index 0f5303962e88..0ccd6cee5f8f 100644
> > --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> > +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> > @@ -41,6 +41,8 @@
> >  #define  PAGE_LO_MASK                  0x3ff
> >  #define  PAGE_SEL_OFFSET_SHIFT         10
> >
> > +#define PAB_ACTIVITY_STAT              0x81c
> > +
> >  #define PAB_AXI_PIO_CTRL               0x0840
> >  #define  APIO_EN_MASK                  0xf
> >
> > @@ -49,8 +51,18 @@
> >
> >  #define PAB_INTP_AMBA_MISC_ENB         0x0b0c
> >  #define PAB_INTP_AMBA_MISC_STAT                0x0b1c
> > -#define  PAB_INTP_INTX_MASK            0x01e0
> > -#define  PAB_INTP_MSI_MASK             0x8
> > +#define  PAB_INTP_RESET                        (0x1 << 1)
> > +#define  PAB_INTP_MSI                  (0x1 << 3)
> > +#define  PAB_INTP_INTA                 (0x1 << 5)
> > +#define  PAB_INTP_INTB                 (0x1 << 6)
> > +#define  PAB_INTP_INTC                 (0x1 << 7)
> > +#define  PAB_INTP_INTD                 (0x1 << 8)
> you could use BIT(x) macros instead of these shift operations

Ok, will change in next version.

> > +#define  PAB_INTP_PCIE_UE              (0x1 << 9)
> > +#define  PAB_INTP_IE_PMREDI            (0x1 << 29)
> > +#define  PAB_INTP_IE_EC                        (0x1 << 30)
> please fix and the the indentations

It is just a display issue in the email.

> > +#define  PAB_INTP_MSI_MASK             PAB_INTP_MSI
> > +#define  PAB_INTP_INTX_MASK            (PAB_INTP_INTA |
> PAB_INTP_INTB |\
> > +                                       PAB_INTP_INTC |
> PAB_INTP_INTD)
> >
> >  #define PAB_AXI_AMAP_CTRL(win)         PAB_REG_ADDR(0x0ba0,
> win)
> >  #define  WIN_ENABLE_SHIFT              0
> > --
> > 2.17.1
> >

Thanks,
Zhiqiang

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

* RE: [PATCHv3 09/27] PCI: mobiveil: correct inbound/outbound window setup routines
  2019-02-05  6:10   ` Subrahmanya Lingappa
@ 2019-02-18  7:07     ` Z.q. Hou
  0 siblings, 0 replies; 68+ messages in thread
From: Z.q. Hou @ 2019-02-18  7:07 UTC (permalink / raw)
  To: Subrahmanya Lingappa
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Hi Subbu,

Thanks a lot for your comments!

> -----Original Message-----
> From: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> Sent: 2019年2月5日 14:10
> To: Z.q. Hou <zhiqiang.hou@nxp.com>
> Cc: linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> bhelgaas@google.com; robh+dt@kernel.org; mark.rutland@arm.com;
> shawnguo@kernel.org; Leo Li <leoyang.li@nxp.com>;
> lorenzo.pieralisi@arm.com; catalin.marinas@arm.com;
> will.deacon@arm.com; Mingkai Hu <mingkai.hu@nxp.com>; M.h. Lian
> <minghuan.lian@nxp.com>; Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: Re: [PATCHv3 09/27] PCI: mobiveil: correct inbound/outbound
> window setup routines
> 
> ZQ,
> please correct the tab spacing of the macro definitions, otherwise its OK.

It is just a display issue in the email.

> Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> 
> On Tue, Jan 29, 2019 at 1:39 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
> >
> > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> >
> > Outbound window routine:
> >  - Removed unused var definition and register read operations.
> >  - Added the upper 32-bit cpu address setup of the window.
> >  - Instead of blindly write, only change the fields specified.
> >  - Masked the lower bits of window size in case override the
> >    control bits.
> >  - Check if the passing window number is available, instead of
> >    the total number of the initialized windows.
> >
> > Inbound window routine:
> >  - Added parameter 'u64 cpu_addr' to specify the cpu address
> >    of the window instead of using 'pci_addr'.
> >  - Changed 'int pci_addr' to 'u64 pci_addr', and added setup
> >    of the upper 32-bit pci address of the window.
> >  - Moved the PCIe PIO master enablement to mobiveil_host_init().
> >  - Instead of blindly write, only change the fields specified.
> >  - Masked the lower bits of window size in case override the
> >    control bits.
> >  - Check if the passing window number is available, instead of
> >    the total number of the initialized windows.
> >  - And added the statistic of initialized inbound windows.
> >
> > Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge IP
> > driver")
> > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> > ---
> > V3:
> >  - No change
> >
> >  drivers/pci/controller/pcie-mobiveil.c | 70
> > +++++++++++++++-----------
> >  1 file changed, 42 insertions(+), 28 deletions(-)
> >
> > diff --git a/drivers/pci/controller/pcie-mobiveil.c
> > b/drivers/pci/controller/pcie-mobiveil.c
> > index e88afc792a5c..4ba458474e42 100644
> > --- a/drivers/pci/controller/pcie-mobiveil.c
> > +++ b/drivers/pci/controller/pcie-mobiveil.c
> > @@ -65,9 +65,13 @@
> >  #define PAB_AXI_AMAP_CTRL(win)         PAB_REG_ADDR(0x0ba0,
> win)
> >  #define  WIN_ENABLE_SHIFT              0
> >  #define  WIN_TYPE_SHIFT                        1
> > +#define  WIN_TYPE_MASK                 0x3
> > +#define  WIN_SIZE_SHIFT                        10
> > +#define  WIN_SIZE_MASK                 0x3fffff
> >
> >  #define PAB_EXT_AXI_AMAP_SIZE(win)
> PAB_EXT_REG_ADDR(0xbaf0, win)
> >
> > +#define PAB_EXT_AXI_AMAP_AXI_WIN(win)
> PAB_EXT_REG_ADDR(0x80a0, win)
> >  #define PAB_AXI_AMAP_AXI_WIN(win)      PAB_REG_ADDR(0x0ba4,
> win)
> >  #define  AXI_WINDOW_ALIGN_MASK         3
> >
> > @@ -82,8 +86,10 @@
> >  #define PAB_PEX_AMAP_CTRL(win)         PAB_REG_ADDR(0x4ba0,
> win)
> >  #define  AMAP_CTRL_EN_SHIFT            0
> >  #define  AMAP_CTRL_TYPE_SHIFT          1
> > +#define  AMAP_CTRL_TYPE_MASK           3
> >
> >  #define PAB_EXT_PEX_AMAP_SIZEN(win)
> PAB_EXT_REG_ADDR(0xbef0, win)
> > +#define PAB_EXT_PEX_AMAP_AXI_WIN(win)
> PAB_EXT_REG_ADDR(0xb4a0, win)
> >  #define PAB_PEX_AMAP_AXI_WIN(win)      PAB_REG_ADDR(0x4ba4,
> win)
> >  #define PAB_PEX_AMAP_PEX_WIN_L(win)    PAB_REG_ADDR(0x4ba8,
> win)
> >  #define PAB_PEX_AMAP_PEX_WIN_H(win)    PAB_REG_ADDR(0x4bac,
> win)
> > @@ -455,49 +461,51 @@ static int mobiveil_pcie_parse_dt(struct
> > mobiveil_pcie *pcie)  }
> >
> >  static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
> > -                              int pci_addr, u32 type, u64 size)
> > +                              u64 cpu_addr, u64 pci_addr, u32
> type,
> > + u64 size)
> >  {
> > -       int pio_ctrl_val;
> > -       int amap_ctrl_dw;
> > +       u32 value;
> >         u64 size64 = ~(size - 1);
> >
> > -       if ((pcie->ib_wins_configured + 1) > pcie->ppio_wins) {
> > +       if (win_num >= pcie->ppio_wins) {
> >                 dev_err(&pcie->pdev->dev,
> >                         "ERROR: max inbound windows
> reached !\n");
> >                 return;
> >         }
> >
> > -       pio_ctrl_val = csr_readl(pcie, PAB_PEX_PIO_CTRL);
> > -       pio_ctrl_val |= 1 << PIO_ENABLE_SHIFT;
> > -       csr_writel(pcie, pio_ctrl_val, PAB_PEX_PIO_CTRL);
> > -
> > -       amap_ctrl_dw = csr_readl(pcie,
> PAB_PEX_AMAP_CTRL(win_num));
> > -       amap_ctrl_dw |= (type << AMAP_CTRL_TYPE_SHIFT) |
> > -                       (1 << AMAP_CTRL_EN_SHIFT) |
> > -                       lower_32_bits(size64);
> > -       csr_writel(pcie, amap_ctrl_dw, PAB_PEX_AMAP_CTRL(win_num));
> > +       value = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
> > +       value &= ~(AMAP_CTRL_TYPE_MASK <<
> AMAP_CTRL_TYPE_SHIFT |
> > +                WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> > +       value |= (type << AMAP_CTRL_TYPE_SHIFT) | (1 <<
> AMAP_CTRL_EN_SHIFT) |
> > +                (lower_32_bits(size64) & WIN_SIZE_MASK <<
> WIN_SIZE_SHIFT);
> > +       csr_writel(pcie, value, PAB_PEX_AMAP_CTRL(win_num));
> >
> >         csr_writel(pcie, upper_32_bits(size64),
> >                    PAB_EXT_PEX_AMAP_SIZEN(win_num));
> >
> > -       csr_writel(pcie, pci_addr, PAB_PEX_AMAP_AXI_WIN(win_num));
> > +       csr_writel(pcie, lower_32_bits(cpu_addr),
> > +                  PAB_PEX_AMAP_AXI_WIN(win_num));
> > +       csr_writel(pcie, upper_32_bits(cpu_addr),
> > +                  PAB_EXT_PEX_AMAP_AXI_WIN(win_num));
> > +
> > +       csr_writel(pcie, lower_32_bits(pci_addr),
> > +                  PAB_PEX_AMAP_PEX_WIN_L(win_num));
> > +       csr_writel(pcie, upper_32_bits(pci_addr),
> > +                  PAB_PEX_AMAP_PEX_WIN_H(win_num));
> >
> > -       csr_writel(pcie, pci_addr,
> PAB_PEX_AMAP_PEX_WIN_L(win_num));
> > -       csr_writel(pcie, 0, PAB_PEX_AMAP_PEX_WIN_H(win_num));
> > +       pcie->ib_wins_configured++;
> >  }
> >
> >  /*
> >   * routine to program the outbound windows
> >   */
> >  static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
> > -                              u64 cpu_addr, u64 pci_addr,
> > -                              u32 config_io_bit, u64 size)
> > +                              u64 cpu_addr, u64 pci_addr, u32
> type,
> > + u64 size)
> >  {
> >
> > -       u32 value, type;
> > +       u32 value;
> >         u64 size64 = ~(size - 1);
> >
> > -       if ((pcie->ob_wins_configured + 1) > pcie->apio_wins) {
> > +       if (win_num >= pcie->apio_wins) {
> >                 dev_err(&pcie->pdev->dev,
> >                         "ERROR: max outbound windows
> reached !\n");
> >                 return;
> > @@ -507,10 +515,12 @@ static void program_ob_windows(struct
> mobiveil_pcie *pcie, int win_num,
> >          * program Enable Bit to 1, Type Bit to (00) base 2, AXI Window
> Size Bit
> >          * to 4 KB in PAB_AXI_AMAP_CTRL register
> >          */
> > -       type = config_io_bit;
> >         value = csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num));
> > -       csr_writel(pcie, 1 << WIN_ENABLE_SHIFT | type <<
> WIN_TYPE_SHIFT |
> > -                  lower_32_bits(size64),
> PAB_AXI_AMAP_CTRL(win_num));
> > +       value &= ~(WIN_TYPE_MASK << WIN_TYPE_SHIFT |
> > +                WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> > +       value |= 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
> > +                (lower_32_bits(size64) & WIN_SIZE_MASK <<
> WIN_SIZE_SHIFT);
> > +       csr_writel(pcie, value, PAB_AXI_AMAP_CTRL(win_num));
> >
> >         csr_writel(pcie, upper_32_bits(size64),
> > PAB_EXT_AXI_AMAP_SIZE(win_num));
> >
> > @@ -518,11 +528,10 @@ static void program_ob_windows(struct
> mobiveil_pcie *pcie, int win_num,
> >          * program AXI window base with appropriate value in
> >          * PAB_AXI_AMAP_AXI_WIN0 register
> >          */
> > -       value = csr_readl(pcie, PAB_AXI_AMAP_AXI_WIN(win_num));
> > -       csr_writel(pcie, cpu_addr & (~AXI_WINDOW_ALIGN_MASK),
> > +       csr_writel(pcie, lower_32_bits(cpu_addr) &
> > + (~AXI_WINDOW_ALIGN_MASK),
> >                    PAB_AXI_AMAP_AXI_WIN(win_num));
> > -
> > -       value = csr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_H(win_num));
> > +       csr_writel(pcie, upper_32_bits(cpu_addr),
> > +                  PAB_EXT_AXI_AMAP_AXI_WIN(win_num));
> >
> >         csr_writel(pcie, lower_32_bits(pci_addr),
> >                    PAB_AXI_AMAP_PEX_WIN_L(win_num)); @@
> -604,6 +613,11
> > @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
> >         value |= APIO_EN_MASK;
> >         csr_writel(pcie, value, PAB_AXI_PIO_CTRL);
> >
> > +       /* Enable PCIe PIO master */
> > +       value = csr_readl(pcie, PAB_PEX_PIO_CTRL);
> > +       value |= 1 << PIO_ENABLE_SHIFT;
> > +       csr_writel(pcie, value, PAB_PEX_PIO_CTRL);
> > +
> >         /*
> >          * we'll program one outbound window for config reads and
> >          * another default inbound window for all the upstream traffic
> > @@ -616,7 +630,7 @@ static int mobiveil_host_init(struct mobiveil_pcie
> *pcie)
> >                            CFG_WINDOW_TYPE,
> > resource_size(pcie->ob_io_res));
> >
> >         /* memory inbound translation window */
> > -       program_ib_windows(pcie, WIN_NUM_0, 0,
> MEM_WINDOW_TYPE, IB_WIN_SIZE);
> > +       program_ib_windows(pcie, WIN_NUM_0, 0, 0,
> MEM_WINDOW_TYPE,
> > + IB_WIN_SIZE);
> >
> >         /* Get the I/O and memory ranges from DT */
> >         resource_list_for_each_entry(win, &pcie->resources) {
> > --
> > 2.17.1
> >
Thanks,
Zhiqiang

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

* RE: [PATCHv3 24/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011577
  2019-02-08 12:52   ` Subrahmanya Lingappa
@ 2019-02-18  7:10     ` Z.q. Hou
  0 siblings, 0 replies; 68+ messages in thread
From: Z.q. Hou @ 2019-02-18  7:10 UTC (permalink / raw)
  To: Subrahmanya Lingappa
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Hi Subbu,

Thanks a lot for your comments!

> -----Original Message-----
> From: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> Sent: 2019年2月8日 20:52
> To: Z.q. Hou <zhiqiang.hou@nxp.com>
> Cc: linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> bhelgaas@google.com; robh+dt@kernel.org; mark.rutland@arm.com;
> shawnguo@kernel.org; Leo Li <leoyang.li@nxp.com>;
> lorenzo.pieralisi@arm.com; catalin.marinas@arm.com;
> will.deacon@arm.com; Mingkai Hu <mingkai.hu@nxp.com>; M.h. Lian
> <minghuan.lian@nxp.com>; Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: Re: [PATCHv3 24/27] PCI: mobiveil: ls_pcie_g4: add Workaround for
> A-011577
> 
> ZQ,
> 
> On Tue, Jan 29, 2019 at 1:41 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
> >
> > 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 it will be fixed in
> > Rev2.0.
> >
> > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > ---
> > V3:
> >  - Integrated without change from
> >
> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatc
> >
> hwork.ozlabs.org%2Fpatch%2F1006790%2F&amp;data=02%7C01%7Czhiqian
> g.hou%
> >
> 40nxp.com%7C122074f0ac6d4b46ca8208d68dc3e7ac%7C686ea1d3bc2b4c6f
> a92cd99
> >
> c5c301635%7C0%7C0%7C636852269885449903&amp;sdata=IfAadaAfHuGS
> %2FJCyH4X
> > TQEnPV1HM3huKjRVDK%2BAbv8M%3D&amp;reserved=0
> >
> >  .../controller/mobiveil/pci-layerscape-gen4.c | 37
> > +++++++++++++++++++  .../controller/mobiveil/pcie-mobiveil-host.c  |
> 17 ++++++++-
> >  .../pci/controller/mobiveil/pcie-mobiveil.h   |  3 ++
> >  3 files changed, 56 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> > b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> > index 174cbcac4059..d2c5dbbd5e3c 100644
> > --- a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> > +++ b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> > @@ -22,8 +22,13 @@
> >
> >  #include "pcie-mobiveil.h"
> >
> > +#define REV_1_0                                (0x10)
> > +
> >  /* LUT and PF control registers */
> >  #define PCIE_LUT_OFF                   (0x80000)
> > +#define PCIE_LUT_GCR                   (0x28)
> > +#define PCIE_LUT_GCR_RRE               (0)
> > +
> >  #define PCIE_PF_OFF                    (0xc0000)
> >  #define PCIE_PF_INT_STAT               (0x18)
> >  #define PF_INT_STAT_PABRST             (31)
> > @@ -41,6 +46,7 @@ struct ls_pcie_g4 {
> >         struct mobiveil_pcie *pci;
> >         struct delayed_work dwork;
> >         int irq;
> > +       u8 rev;
> >  };
> >
> >  static inline u32 ls_pcie_g4_lut_readl(struct ls_pcie_g4 *pcie, u32
> > off) @@ -76,6 +82,15 @@ static bool ls_pcie_g4_is_bridge(struct
> ls_pcie_g4 *pcie)
> >         return header_type == PCI_HEADER_TYPE_BRIDGE;  }
> >
> > +static int ls_pcie_g4_host_init(struct mobiveil_pcie *pci) {
> > +       struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
> > +
> > +       pcie->rev = csr_readb(pci, PCI_REVISION_ID);
> > +
> > +       return 0;
> > +}
> > +
> >  static int ls_pcie_g4_link_up(struct mobiveil_pcie *pci)  {
> >         struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci); @@ -188,12
> > +203,34 @@ static void ls_pcie_g4_reset(struct work_struct *work)
> >         ls_pcie_g4_reinit_hw(pcie);
> >  }
> >
> > +static int ls_pcie_g4_read_other_conf(struct pci_bus *bus, unsigned int
> devfn,
> > +                                  int where, int size, u32 *val) {
> > +       struct mobiveil_pcie *pci = bus->sysdata;
> > +       struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
> > +       int ret;
> > +
> > +       if (pcie->rev == REV_1_0 && where == PCI_VENDOR_ID)
> > +               ls_pcie_g4_lut_writel(pcie, PCIE_LUT_GCR,
> > +                                     0 << PCIE_LUT_GCR_RRE);
> > +
> > +       ret = pci_generic_config_read(bus, devfn, where, size, val);
> > +
> > +       if (pcie->rev == REV_1_0 && where == PCI_VENDOR_ID)
> > +               ls_pcie_g4_lut_writel(pcie, PCIE_LUT_GCR,
> > +                                     1 << PCIE_LUT_GCR_RRE);
> > +
> > +       return ret;
> > +}
> > +
> >  static struct mobiveil_rp_ops ls_pcie_g4_rp_ops = {
> >         .interrupt_init = ls_pcie_g4_interrupt_init,
> > +       .read_other_conf = ls_pcie_g4_read_other_conf,
> >  };
> >
> >  static const struct mobiveil_pab_ops ls_pcie_g4_pab_ops = {
> >         .link_up = ls_pcie_g4_link_up,
> > +       .host_init = ls_pcie_g4_host_init,
> >  };
> >
> >  static int __init ls_pcie_g4_probe(struct platform_device *pdev) diff
> > --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > index e8d0c4989013..5f51bc2dd6d7 100644
> > --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > @@ -79,9 +79,20 @@ static void __iomem *mobiveil_pcie_map_bus(struct
> pci_bus *bus,
> >         return pcie->rp.config_axi_slave_base + where;  }
> >
> > +static int mobiveil_pcie_config_read(struct pci_bus *bus, unsigned int
> devfn,
> > +                                    int where, int size, u32 *val) {
> > +       struct mobiveil_pcie *pcie = bus->sysdata;
> > +       struct root_port *rp = &pcie->rp;
> > +
> > +       if (bus->number > rp->root_bus_nr &&
> rp->ops->read_other_conf)
> > +               return rp->ops->read_other_conf(bus, devfn, where,
> > + size, val);
> > +
> > +       return pci_generic_config_read(bus, devfn, where, size, val);
> > +}
> >  static struct pci_ops mobiveil_pcie_ops = {
> >         .map_bus = mobiveil_pcie_map_bus,
> > -       .read = pci_generic_config_read,
> > +       .read = mobiveil_pcie_config_read,
> >         .write = pci_generic_config_write,  };
> >
> > @@ -309,6 +320,10 @@ int mobiveil_host_init(struct mobiveil_pcie *pcie,
> bool reinit)
> >         value |= (PCI_CLASS_BRIDGE_PCI << 16);
> >         csr_writel(pcie, value, PAB_INTP_AXI_PIO_CLASS);
> >
> > +       /* Platform specific host init */
> > +       if (pcie->ops->host_init)
> > +               return pcie->ops->host_init(pcie);
> > +
> >         return 0;
> >  }
> >
> > diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> > b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> > index 0ccd6cee5f8f..ab43de5e4b2b 100644
> > --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> > +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> > @@ -145,6 +145,8 @@ struct mobiveil_msi
> {                       /* MSI information */
> >
> >  struct mobiveil_rp_ops {
> >         int (*interrupt_init)(struct mobiveil_pcie *pcie);
> > +       int (*read_other_conf)(struct pci_bus *bus, unsigned int devfn,
> > +                              int where, int size, u32 *val);
> >  };
> >
> >  struct root_port {
> > @@ -160,6 +162,7 @@ struct root_port {
> >
> >  struct mobiveil_pab_ops {
> >         int (*link_up)(struct mobiveil_pcie *pcie);
> > +       int (*host_init)(struct mobiveil_pcie *pcie);
> >  };
> >
> >  struct mobiveil_pcie {
> > --
> > 2.17.1
> >
> can we have an english brief than having a internal cryptic number:A-011577,
> on the patch title?

I think it is unnecessary to make a redundant title for the ERRATA patch and the commit message has the ERRATA description.

Thanks,
Zhiqiang

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

* RE: [PATCHv3 25/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011451
  2019-02-08 12:53   ` Subrahmanya Lingappa
@ 2019-02-18  7:14     ` Z.q. Hou
  0 siblings, 0 replies; 68+ messages in thread
From: Z.q. Hou @ 2019-02-18  7:14 UTC (permalink / raw)
  To: Subrahmanya Lingappa
  Cc: linux-pci, linux-arm-kernel, devicetree, linux-kernel, bhelgaas,
	robh+dt, mark.rutland, shawnguo, Leo Li, lorenzo.pieralisi,
	catalin.marinas, will.deacon, Mingkai Hu, M.h. Lian, Xiaowei Bao

Hi Subbu,

Thanks a lot for your comments!

> -----Original Message-----
> From: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> Sent: 2019年2月8日 20:53
> To: Z.q. Hou <zhiqiang.hou@nxp.com>
> Cc: linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> bhelgaas@google.com; robh+dt@kernel.org; mark.rutland@arm.com;
> shawnguo@kernel.org; Leo Li <leoyang.li@nxp.com>;
> lorenzo.pieralisi@arm.com; catalin.marinas@arm.com;
> will.deacon@arm.com; Mingkai Hu <mingkai.hu@nxp.com>; M.h. Lian
> <minghuan.lian@nxp.com>; Xiaowei Bao <xiaowei.bao@nxp.com>
> Subject: Re: [PATCHv3 25/27] PCI: mobiveil: ls_pcie_g4: add Workaround for
> A-011451
> 
> ZQ,
> 
> On Tue, Jan 29, 2019 at 1:41 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
> >
> > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> >
> > When LX2 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 LX2 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 patch implemented part 1, the part 2 can be set by kernel
> > parameter 'pci=pcie_bus_perf'
> >
> > This ERRATA is only for LX2160A Rev1.0, and it will be fixed in
> > Rev2.0.
> >
> > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > ---
> > V3:
> >  - Integrated without change from
> >
> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatc
> >
> hwork.ozlabs.org%2Fpatch%2F1006796%2F&amp;data=02%7C01%7Czhiqian
> g.hou%
> >
> 40nxp.com%7C90064d58a826432072c108d68dc4079d%7C686ea1d3bc2b4c
> 6fa92cd99
> >
> c5c301635%7C0%7C0%7C636852270415444442&amp;sdata=f0PrEf9%2Ff%2
> F%2B%2Fh
> > TpacZYps7HHodXwMYPLN3MB8vaqUf4%3D&amp;reserved=0
> >
> >  .../pci/controller/mobiveil/pci-layerscape-gen4.c | 15 +++++++++++++++
> >  drivers/pci/controller/mobiveil/pcie-mobiveil.h   |  4 ++++
> >  2 files changed, 19 insertions(+)
> >
> > diff --git a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> > b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> > index d2c5dbbd5e3c..20ce146788ca 100644
> > --- a/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> > +++ b/drivers/pci/controller/mobiveil/pci-layerscape-gen4.c
> > @@ -82,12 +82,27 @@ static bool ls_pcie_g4_is_bridge(struct ls_pcie_g4
> *pcie)
> >         return header_type == PCI_HEADER_TYPE_BRIDGE;  }
> >
> > +static void workaround_A011451(struct ls_pcie_g4 *pcie) {
> > +       struct mobiveil_pcie *mv_pci = pcie->pci;
> > +       u32 val;
> > +
> > +       /* Set ACK latency timeout */
> > +       val = csr_readl(mv_pci, GPEX_ACK_REPLAY_TO);
> > +       val &= ~(ACK_LAT_TO_VAL_MASK << ACK_LAT_TO_VAL_SHIFT);
> > +       val |= (4 << ACK_LAT_TO_VAL_SHIFT);
> > +       csr_writel(mv_pci, val, GPEX_ACK_REPLAY_TO); }
> > +
> >  static int ls_pcie_g4_host_init(struct mobiveil_pcie *pci)  {
> >         struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
> >
> >         pcie->rev = csr_readb(pci, PCI_REVISION_ID);
> >
> > +       if (pcie->rev == REV_1_0)
> > +               workaround_A011451(pcie);
> > +
> >         return 0;
> >  }
> >
> > diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> > b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> > index ab43de5e4b2b..f0e2e4ae09b5 100644
> > --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> > +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
> > @@ -85,6 +85,10 @@
> >  #define PAB_AXI_AMAP_PEX_WIN_H(win)    PAB_REG_ADDR(0x0bac,
> win)
> >  #define PAB_INTP_AXI_PIO_CLASS         0x474
> >
> > +#define GPEX_ACK_REPLAY_TO             0x438
> > +#define  ACK_LAT_TO_VAL_MASK           0x1fff
> > +#define  ACK_LAT_TO_VAL_SHIFT          0
> > +
> >  #define PAB_PEX_AMAP_CTRL(win)         PAB_REG_ADDR(0x4ba0,
> win)
> >  #define  AMAP_CTRL_EN_SHIFT            0
> >  #define  AMAP_CTRL_TYPE_SHIFT          1
> > --
> > 2.17.1
> >
> again, can we avoid errata number on patch title and have a brief title
> instead?

Generally we do not put the ERRATA description but only the ERRATA number into the ERRATA patch subject.

Thanks,
Zhiqiang

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

* RE: [PATCHv3 17/27] PCI: mobiveil: fix the checking of valid device
  2019-02-08 14:13     ` Bjorn Helgaas
@ 2019-02-18  7:15       ` Z.q. Hou
  0 siblings, 0 replies; 68+ messages in thread
From: Z.q. Hou @ 2019-02-18  7:15 UTC (permalink / raw)
  To: Bjorn Helgaas, Subrahmanya Lingappa
  Cc: mark.rutland, devicetree, lorenzo.pieralisi, Xiaowei Bao,
	linux-pci, will.deacon, linux-kernel, Leo Li, M.h. Lian, robh+dt,
	Mingkai Hu, catalin.marinas, shawnguo, linux-arm-kernel,
	Thomas Petazzoni

Hi Bjorn,

Thanks a lot for your comments!

> -----Original Message-----
> From: Bjorn Helgaas <helgaas@kernel.org>
> Sent: 2019年2月8日 22:13
> To: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
> Cc: Z.q. Hou <zhiqiang.hou@nxp.com>; mark.rutland@arm.com;
> devicetree@vger.kernel.org; lorenzo.pieralisi@arm.com; Xiaowei Bao
> <xiaowei.bao@nxp.com>; linux-pci@vger.kernel.org; will.deacon@arm.com;
> linux-kernel@vger.kernel.org; Leo Li <leoyang.li@nxp.com>; M.h. Lian
> <minghuan.lian@nxp.com>; robh+dt@kernel.org; Mingkai Hu
> <mingkai.hu@nxp.com>; catalin.marinas@arm.com; shawnguo@kernel.org;
> linux-arm-kernel@lists.infradead.org; Thomas Petazzoni
> <thomas.petazzoni@bootlin.com>
> Subject: Re: [PATCHv3 17/27] PCI: mobiveil: fix the checking of valid device
> 
> [+cc Thomas]
> 
> On Fri, Feb 08, 2019 at 06:11:15PM +0530, Subrahmanya Lingappa wrote:
> > On Tue, Jan 29, 2019 at 1:40 PM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
> > >
> > > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > >
> > > Avoid to issue CFG transactions to link partner when the PCIe link
> > > is not up. And allow CFG transactions to all functions of Endpoint
> > > implemented multiple functions.
> > >
> > > Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge
> > > IP driver")
> > > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > > Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> > > ---
> > > V3:
> > >  - No change
> > >
> > >  drivers/pci/controller/mobiveil/pcie-mobiveil-host.c | 6 +++++-
> > >  1 file changed, 5 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > > b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > > index dc5324d94466..1ae82e790562 100644
> > > --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > > +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > > @@ -29,6 +29,10 @@ static bool mobiveil_pcie_valid_device(struct
> > > pci_bus *bus, unsigned int devfn)  {
> > >         struct mobiveil_pcie *pcie = bus->sysdata;
> > >
> > > +       /* If there is no link, then there is no device */
> > > +       if (bus->number > pcie->rp.root_bus_nr
> && !mobiveil_pcie_link_up(pcie))
> > > +               return false;
> > > +
> > >         /* Only one device down on each root port */
> > >         if ((bus->number == pcie->rp.root_bus_nr) && (devfn > 0))
> > >                 return false;
> > > @@ -37,7 +41,7 @@ static bool mobiveil_pcie_valid_device(struct
> pci_bus *bus, unsigned int devfn)
> > >          * Do not read more than one device on the bus directly
> > >          * attached to RC
> > >          */
> > > -       if ((bus->primary == pcie->rp.root_bus_nr) && (devfn > 0))
> > > +       if ((bus->primary == pcie->rp.root_bus_nr) &&
> > > + (PCI_SLOT(devfn) > 0))
> 
> > here change "primary" to "number", as it's a bug in the original driver too.
> 
> This looks like it should be split into two patches: (1) checking for link up, and
> (2) checking root_bus_nr.

Yes, will split this patch in next version.

> 
> And if you mean "bus->primary == pcie->rp.root_bus_nr" is a bug in
> pci-aardvark.c, too, it is imperative to fix that bug also (with a separate patch).

It is not a bug, but the bug is to limit multiple function EP (devfn > 0).

Thanks,
Zhiqiang

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

end of thread, other threads:[~2019-02-18  7:15 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-29  8:08 [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Z.q. Hou
2019-01-29  8:08 ` [PATCHv3 01/27] PCI: mobiveil: uniform the register accessors Z.q. Hou
2019-02-05  5:39   ` Subrahmanya Lingappa
2019-02-05 17:43     ` Lorenzo Pieralisi
2019-02-06 10:59       ` Subrahmanya Lingappa
2019-01-29  8:08 ` [PATCHv3 02/27] PCI: mobiveil: format the code without function change Z.q. Hou
2019-02-05  5:48   ` Subrahmanya Lingappa
2019-02-18  7:03     ` Z.q. Hou
2019-01-29  8:08 ` [PATCHv3 03/27] PCI: mobiveil: correct the returned error number Z.q. Hou
2019-02-05  5:53   ` Subrahmanya Lingappa
2019-01-29  8:08 ` [PATCHv3 04/27] PCI: mobiveil: remove flag MSI_FLAG_MULTI_PCI_MSI Z.q. Hou
2019-02-05  6:05   ` Subrahmanya Lingappa
2019-02-18  7:03     ` Z.q. Hou
2019-01-29  8:09 ` [PATCHv3 05/27] PCI: mobiveil: correct PCI base address in MEM/IO outbound windows Z.q. Hou
2019-02-05  6:06   ` Subrahmanya Lingappa
2019-01-29  8:09 ` [PATCHv3 06/27] PCI: mobiveil: replace the resource list iteration function Z.q. Hou
2019-02-05  6:07   ` Subrahmanya Lingappa
2019-01-29  8:09 ` [PATCHv3 07/27] PCI: mobiveil: use WIN_NUM_0 explicitly for CFG outbound window Z.q. Hou
2019-02-05  6:08   ` Subrahmanya Lingappa
2019-01-29  8:09 ` [PATCHv3 08/27] PCI: mobiveil: use the 1st inbound window for MEM inbound transactions Z.q. Hou
2019-02-05  6:08   ` Subrahmanya Lingappa
2019-01-29  8:09 ` [PATCHv3 09/27] PCI: mobiveil: correct inbound/outbound window setup routines Z.q. Hou
2019-02-05  6:10   ` Subrahmanya Lingappa
2019-02-18  7:07     ` Z.q. Hou
2019-01-29  8:09 ` [PATCHv3 10/27] PCI: mobiveil: fix the INTx process error Z.q. Hou
2019-02-05  6:11   ` Subrahmanya Lingappa
2019-01-29  8:09 ` [PATCHv3 11/27] PCI: mobiveil: only fix up the Class Code field Z.q. Hou
2019-02-05  6:11   ` Subrahmanya Lingappa
2019-01-29  8:09 ` [PATCHv3 12/27] PCI: mobiveil: move out the link up waiting from mobiveil_host_init Z.q. Hou
2019-02-05  6:12   ` Subrahmanya Lingappa
2019-01-29  8:09 ` [PATCHv3 13/27] PCI: mobiveil: move irq chained handler setup out of DT parse Z.q. Hou
2019-02-08 12:30   ` Subrahmanya Lingappa
2019-01-29  8:09 ` [PATCHv3 14/27] PCI: mobiveil: initialize Primary/Secondary/Subordinate bus number Z.q. Hou
2019-02-08 12:31   ` Subrahmanya Lingappa
2019-01-29  8:10 ` [PATCHv3 15/27] dt-bindings: pci: mobiveil: change gpio_slave and apb_csr to optional Z.q. Hou
2019-02-08 12:32   ` Subrahmanya Lingappa
2019-01-29  8:10 ` [PATCHv3 16/27] PCI: mobiveil: refactor Mobiveil PCIe Host Bridge IP driver Z.q. Hou
2019-02-08 12:37   ` Subrahmanya Lingappa
2019-01-29  8:10 ` [PATCHv3 17/27] PCI: mobiveil: fix the checking of valid device Z.q. Hou
2019-02-08 12:41   ` Subrahmanya Lingappa
2019-02-08 14:13     ` Bjorn Helgaas
2019-02-18  7:15       ` Z.q. Hou
2019-02-18  7:04     ` Z.q. Hou
2019-01-29  8:10 ` [PATCHv3 18/27] PCI: mobiveil: continue to initialize the host upon no PCIe link Z.q. Hou
2019-02-08 12:41   ` Subrahmanya Lingappa
2019-01-29  8:10 ` [PATCHv3 19/27] PCI: mobiveil: disabled IB and OB windows set by bootloader Z.q. Hou
2019-02-08 12:42   ` Subrahmanya Lingappa
2019-01-29  8:10 ` [PATCHv3 20/27] PCI: mobiveil: add Byte and Half-Word width register accessors Z.q. Hou
2019-02-08 12:44   ` Subrahmanya Lingappa
2019-01-29  8:10 ` [PATCHv3 21/27] PCI: mobiveil: make mobiveil_host_init can be used to re-init host Z.q. Hou
2019-02-08 12:46   ` Subrahmanya Lingappa
2019-01-29  8:10 ` [PATCHv3 22/27] dt-bindings: pci: Add NXP Layerscape SoCs PCIe Gen4 controller Z.q. Hou
2019-01-30 18:49   ` Rob Herring
2019-01-29  8:10 ` [PATCHv3 23/27] PCI: mobiveil: add PCIe Gen4 RC driver for NXP Layerscape SoCs Z.q. Hou
2019-02-08 12:49   ` Subrahmanya Lingappa
2019-02-18  7:05     ` Z.q. Hou
2019-01-29  8:11 ` [PATCHv3 24/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011577 Z.q. Hou
2019-02-08 12:52   ` Subrahmanya Lingappa
2019-02-18  7:10     ` Z.q. Hou
2019-01-29  8:11 ` [PATCHv3 25/27] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011451 Z.q. Hou
2019-02-08 12:53   ` Subrahmanya Lingappa
2019-02-18  7:14     ` Z.q. Hou
2019-01-29  8:11 ` [PATCHv3 26/27] arm64: dts: freescale: lx2160a: add pcie DT nodes Z.q. Hou
2019-01-29  8:11 ` [PATCHv3 27/27] arm64: defconfig: Enable CONFIG_PCI_LAYERSCAPE_GEN4 Z.q. Hou
2019-01-29 11:39 ` [PATCHv3 00/27] PCI: refactor Mobiveil driver and add PCIe Gen4 driver for NXP Layerscape SoCs Lorenzo Pieralisi
     [not found]   ` <CAFZiPx002HED+YH2GysS7a7uoEDQuHGjxa_CQtwb9nSDH-XNuA@mail.gmail.com>
2019-02-04 16:13     ` Lorenzo Pieralisi
2019-02-04 16:51       ` Subrahmanya Lingappa
2019-01-30 15:34 ` Bjorn Helgaas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).