linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs
@ 2020-02-28 15:41 Lad Prabhakar
  2020-02-28 15:41 ` [PATCH v5 1/7] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c Lad Prabhakar
                   ` (7 more replies)
  0 siblings, 8 replies; 26+ messages in thread
From: Lad Prabhakar @ 2020-02-28 15:41 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Yoshihiro Shimoda, Shawn Lin, Heiko Stuebner
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Lad Prabhakar

This patch series adds support for PCIe controller on rcar to work in
endpoint mode, this also extends the epf framework to handle base region
for mapping PCI address locally.

Note:
The cadence/rockchip/designware endpoint drivers are build tested only.

Changes for v5:
1] Rebased the patches on next branch of https://git.kernel.org/pub/scm/
   linux/kernel/git/helgaas/pci.git
2] Fixed review comments reported by Kishon while fetching the matching
   window in function pci_epc_get_matching_window()
3] Fixed review comments reported by Bjorn
   a] Split patch up first patch so that its easier to review and incremental
   b] Fixed typos
4] Included Reviewed tag from Rob for the dt-binding patch
5] Fixed issue reported by Nathan for assigning variable to itself

Changes for v4:
1] Fixed dtb_check error reported by Rob
2] Fixed review comments reported by Kishon
   a] Dropped pci_epc_find_best_fit_window()
   b] Fixed initializing mem ptr in __pci_epc_mem_init()
   c] Dropped map_size from pci_epc_mem_window structure

Changes for v3:
1] Fixed review comments from Bjorn and Kishon.
3] Converted to DT schema

Changes for v2:
1] Fixed review comments from Biju for dt-bindings to include an example
   for a tested platform.
2] Fixed review comments from Kishon to extend the features of outbound
   regions in epf framework.
3] Added support to parse outbound-ranges in OF.

Lad Prabhakar (7):
  PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c
  PCI: rcar: Move shareable code to a common file
  PCI: rcar: Fix calculating mask for PCIEPAMR register
  PCI: endpoint: Add support to handle multiple base for mapping
    outbound memory
  dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint
    controller
  PCI: rcar: Add support for rcar PCIe controller in endpoint mode
  misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller

 .../devicetree/bindings/pci/rcar-pci-ep.yaml       |   76 ++
 arch/arm64/configs/defconfig                       |    2 +-
 drivers/misc/pci_endpoint_test.c                   |    3 +
 drivers/pci/controller/Kconfig                     |   15 +-
 drivers/pci/controller/Makefile                    |    3 +-
 drivers/pci/controller/cadence/pcie-cadence-ep.c   |    7 +-
 drivers/pci/controller/dwc/pcie-designware-ep.c    |   29 +-
 drivers/pci/controller/pcie-rcar-ep.c              |  490 ++++++++
 drivers/pci/controller/pcie-rcar-host.c            | 1053 +++++++++++++++++
 drivers/pci/controller/pcie-rcar.c                 | 1229 +-------------------
 drivers/pci/controller/pcie-rcar.h                 |  129 ++
 drivers/pci/controller/pcie-rockchip-ep.c          |    7 +-
 drivers/pci/endpoint/pci-epc-mem.c                 |  167 ++-
 include/linux/pci-epc.h                            |   39 +-
 14 files changed, 1985 insertions(+), 1264 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/rcar-pci-ep.yaml
 create mode 100644 drivers/pci/controller/pcie-rcar-ep.c
 create mode 100644 drivers/pci/controller/pcie-rcar-host.c
 create mode 100644 drivers/pci/controller/pcie-rcar.h

-- 
2.7.4


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

* [PATCH v5 1/7] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c
  2020-02-28 15:41 [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
@ 2020-02-28 15:41 ` Lad Prabhakar
  2020-03-17  6:59   ` Yoshihiro Shimoda
  2020-02-28 15:41 ` [PATCH v5 2/7] PCI: rcar: Move shareable code to a common file Lad Prabhakar
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 26+ messages in thread
From: Lad Prabhakar @ 2020-02-28 15:41 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Yoshihiro Shimoda, Shawn Lin, Heiko Stuebner
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Lad Prabhakar

This commit renames pcie-rcar.c to pcie-rcar-host.c in preparation for
adding support for endpoint mode. CONFIG_PCIE_RCAR is also renamed to
CONFIG_PCIE_RCAR_HOST to match the driver name accordingly.

In addition to this defconfig file has also been updated to match the new
config option.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
 arch/arm64/configs/defconfig                             | 2 +-
 drivers/pci/controller/Kconfig                           | 7 ++++---
 drivers/pci/controller/Makefile                          | 2 +-
 drivers/pci/controller/{pcie-rcar.c => pcie-rcar-host.c} | 0
 4 files changed, 6 insertions(+), 5 deletions(-)
 rename drivers/pci/controller/{pcie-rcar.c => pcie-rcar-host.c} (100%)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 0f21288..7a34fce 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -185,7 +185,7 @@ CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_ACPI=y
 CONFIG_PCI_AARDVARK=y
 CONFIG_PCI_TEGRA=y
-CONFIG_PCIE_RCAR=y
+CONFIG_PCIE_RCAR_HOST=y
 CONFIG_PCI_HOST_GENERIC=y
 CONFIG_PCI_XGENE=y
 CONFIG_PCIE_ALTERA=y
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index f84e5ff..37e0ea7 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -54,12 +54,13 @@ config PCI_RCAR_GEN2
 	  There are 3 internal PCI controllers available with a single
 	  built-in EHCI/OHCI host controller present on each one.
 
-config PCIE_RCAR
-	bool "Renesas R-Car PCIe controller"
+config PCIE_RCAR_HOST
+	bool "Renesas R-Car PCIe host controller"
 	depends on ARCH_RENESAS || COMPILE_TEST
 	depends on PCI_MSI_IRQ_DOMAIN
 	help
-	  Say Y here if you want PCIe controller support on R-Car SoCs.
+	  Say Y here if you want PCIe controller support on R-Car SoCs in host
+	  mode.
 
 config PCI_HOST_COMMON
 	bool
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index 01b2502..4ca2da6 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
-obj-$(CONFIG_PCIE_RCAR) += pcie-rcar.o
+obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar-host.o
 obj-$(CONFIG_PCI_HOST_COMMON) += pci-host-common.o
 obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
 obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar-host.c
similarity index 100%
rename from drivers/pci/controller/pcie-rcar.c
rename to drivers/pci/controller/pcie-rcar-host.c
-- 
2.7.4


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

* [PATCH v5 2/7] PCI: rcar: Move shareable code to a common file
  2020-02-28 15:41 [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
  2020-02-28 15:41 ` [PATCH v5 1/7] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c Lad Prabhakar
@ 2020-02-28 15:41 ` Lad Prabhakar
  2020-03-17  7:23   ` Yoshihiro Shimoda
  2020-02-28 15:41 ` [PATCH v5 3/7] PCI: rcar: Fix calculating mask for PCIEPAMR register Lad Prabhakar
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 26+ messages in thread
From: Lad Prabhakar @ 2020-02-28 15:41 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Yoshihiro Shimoda, Shawn Lin, Heiko Stuebner
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Lad Prabhakar

This patch moves sharable code to common file pcie-rcar.c and the #defines
to pcie-rcar.h so that the common code can be reused with endpoint driver.
There are no functional changes with this patch for the host controller
driver.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
 drivers/pci/controller/Makefile         |   2 +-
 drivers/pci/controller/pcie-rcar-host.c | 358 ++++++++------------------------
 drivers/pci/controller/pcie-rcar.c      | 117 +++++++++++
 drivers/pci/controller/pcie-rcar.h      | 125 +++++++++++
 4 files changed, 324 insertions(+), 278 deletions(-)
 create mode 100644 drivers/pci/controller/pcie-rcar.c
 create mode 100644 drivers/pci/controller/pcie-rcar.h

diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index 4ca2da6..b4ada32 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
-obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar-host.o
+obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar.o pcie-rcar-host.o
 obj-$(CONFIG_PCI_HOST_COMMON) += pci-host-common.o
 obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
 obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c
index 759c654..93f22d8 100644
--- a/drivers/pci/controller/pcie-rcar-host.c
+++ b/drivers/pci/controller/pcie-rcar-host.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe driver for Renesas R-Car SoCs
- *  Copyright (C) 2014 Renesas Electronics Europe Ltd
+ *  Copyright (C) 2014-2020 Renesas Electronics Europe Ltd
  *
  * Based on:
  *  arch/sh/drivers/pci/pcie-sh7786.c
@@ -30,104 +30,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
-#define PCIECAR			0x000010
-#define PCIECCTLR		0x000018
-#define  CONFIG_SEND_ENABLE	BIT(31)
-#define  TYPE0			(0 << 8)
-#define  TYPE1			BIT(8)
-#define PCIECDR			0x000020
-#define PCIEMSR			0x000028
-#define PCIEINTXR		0x000400
-#define PCIEPHYSR		0x0007f0
-#define  PHYRDY			BIT(0)
-#define PCIEMSITXR		0x000840
-
-/* Transfer control */
-#define PCIETCTLR		0x02000
-#define  DL_DOWN		BIT(3)
-#define  CFINIT			BIT(0)
-#define PCIETSTR		0x02004
-#define  DATA_LINK_ACTIVE	BIT(0)
-#define PCIEERRFR		0x02020
-#define  UNSUPPORTED_REQUEST	BIT(4)
-#define PCIEMSIFR		0x02044
-#define PCIEMSIALR		0x02048
-#define  MSIFE			BIT(0)
-#define PCIEMSIAUR		0x0204c
-#define PCIEMSIIER		0x02050
-
-/* root port address */
-#define PCIEPRAR(x)		(0x02080 + ((x) * 0x4))
-
-/* local address reg & mask */
-#define PCIELAR(x)		(0x02200 + ((x) * 0x20))
-#define PCIELAMR(x)		(0x02208 + ((x) * 0x20))
-#define  LAM_PREFETCH		BIT(3)
-#define  LAM_64BIT		BIT(2)
-#define  LAR_ENABLE		BIT(1)
-
-/* PCIe address reg & mask */
-#define PCIEPALR(x)		(0x03400 + ((x) * 0x20))
-#define PCIEPAUR(x)		(0x03404 + ((x) * 0x20))
-#define PCIEPAMR(x)		(0x03408 + ((x) * 0x20))
-#define PCIEPTCTLR(x)		(0x0340c + ((x) * 0x20))
-#define  PAR_ENABLE		BIT(31)
-#define  IO_SPACE		BIT(8)
-
-/* Configuration */
-#define PCICONF(x)		(0x010000 + ((x) * 0x4))
-#define PMCAP(x)		(0x010040 + ((x) * 0x4))
-#define EXPCAP(x)		(0x010070 + ((x) * 0x4))
-#define VCCAP(x)		(0x010100 + ((x) * 0x4))
-
-/* link layer */
-#define IDSETR1			0x011004
-#define TLCTLR			0x011048
-#define MACSR			0x011054
-#define  SPCHGFIN		BIT(4)
-#define  SPCHGFAIL		BIT(6)
-#define  SPCHGSUC		BIT(7)
-#define  LINK_SPEED		(0xf << 16)
-#define  LINK_SPEED_2_5GTS	(1 << 16)
-#define  LINK_SPEED_5_0GTS	(2 << 16)
-#define MACCTLR			0x011058
-#define  MACCTLR_NFTS_MASK	GENMASK(23, 16)	/* The name is from SH7786 */
-#define  SPEED_CHANGE		BIT(24)
-#define  SCRAMBLE_DISABLE	BIT(27)
-#define  LTSMDIS		BIT(31)
-#define  MACCTLR_INIT_VAL	(LTSMDIS | MACCTLR_NFTS_MASK)
-#define PMSR			0x01105c
-#define MACS2R			0x011078
-#define MACCGSPSETR		0x011084
-#define  SPCNGRSN		BIT(31)
-
-/* R-Car H1 PHY */
-#define H1_PCIEPHYADRR		0x04000c
-#define  WRITE_CMD		BIT(16)
-#define  PHY_ACK		BIT(24)
-#define  RATE_POS		12
-#define  LANE_POS		8
-#define  ADR_POS		0
-#define H1_PCIEPHYDOUTR		0x040014
-
-/* R-Car Gen2 PHY */
-#define GEN2_PCIEPHYADDR	0x780
-#define GEN2_PCIEPHYDATA	0x784
-#define GEN2_PCIEPHYCTRL	0x78c
-
-#define INT_PCI_MSI_NR		32
-
-#define RCONF(x)		(PCICONF(0) + (x))
-#define RPMCAP(x)		(PMCAP(0) + (x))
-#define REXPCAP(x)		(EXPCAP(0) + (x))
-#define RVCCAP(x)		(VCCAP(0) + (x))
-
-#define PCIE_CONF_BUS(b)	(((b) & 0xff) << 24)
-#define PCIE_CONF_DEV(d)	(((d) & 0x1f) << 19)
-#define PCIE_CONF_FUNC(f)	(((f) & 0x7) << 16)
-
-#define RCAR_PCI_MAX_RESOURCES	4
-#define MAX_NR_INBOUND_MAPS	6
+#include "pcie-rcar.h"
 
 struct rcar_msi {
 	DECLARE_BITMAP(used, INT_PCI_MSI_NR);
@@ -155,36 +58,10 @@ struct rcar_pcie {
 	struct			rcar_msi msi;
 };
 
-static void rcar_pci_write_reg(struct rcar_pcie *pcie, u32 val,
-			       unsigned int reg)
-{
-	writel(val, pcie->base + reg);
-}
-
-static u32 rcar_pci_read_reg(struct rcar_pcie *pcie, unsigned int reg)
-{
-	return readl(pcie->base + reg);
-}
-
-enum {
-	RCAR_PCI_ACCESS_READ,
-	RCAR_PCI_ACCESS_WRITE,
-};
-
-static void rcar_rmw32(struct rcar_pcie *pcie, int where, u32 mask, u32 data)
-{
-	unsigned int shift = BITS_PER_BYTE * (where & 3);
-	u32 val = rcar_pci_read_reg(pcie, where & ~3);
-
-	val &= ~(mask << shift);
-	val |= data << shift;
-	rcar_pci_write_reg(pcie, val, where & ~3);
-}
-
 static u32 rcar_read_conf(struct rcar_pcie *pcie, int where)
 {
 	unsigned int shift = BITS_PER_BYTE * (where & 3);
-	u32 val = rcar_pci_read_reg(pcie, where & ~3);
+	u32 val = rcar_pci_read_reg(pcie->base, where & ~3);
 
 	return val >> shift;
 }
@@ -221,13 +98,13 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie,
 			return PCIBIOS_DEVICE_NOT_FOUND;
 
 		if (access_type == RCAR_PCI_ACCESS_READ) {
-			*data = rcar_pci_read_reg(pcie, PCICONF(index));
+			*data = rcar_pci_read_reg(pcie->base, PCICONF(index));
 		} else {
 			/* Keep an eye out for changes to the root bus number */
 			if (pci_is_root_bus(bus) && (reg == PCI_PRIMARY_BUS))
 				pcie->root_bus_nr = *data & 0xff;
 
-			rcar_pci_write_reg(pcie, *data, PCICONF(index));
+			rcar_pci_write_reg(pcie->base, *data, PCICONF(index));
 		}
 
 		return PCIBIOS_SUCCESSFUL;
@@ -237,20 +114,23 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie,
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	/* Clear errors */
-	rcar_pci_write_reg(pcie, rcar_pci_read_reg(pcie, PCIEERRFR), PCIEERRFR);
+	rcar_pci_write_reg(pcie->base, rcar_pci_read_reg(pcie->base, PCIEERRFR),
+			   PCIEERRFR);
 
 	/* Set the PIO address */
-	rcar_pci_write_reg(pcie, PCIE_CONF_BUS(bus->number) |
+	rcar_pci_write_reg(pcie->base, PCIE_CONF_BUS(bus->number) |
 		PCIE_CONF_DEV(dev) | PCIE_CONF_FUNC(func) | reg, PCIECAR);
 
 	/* Enable the configuration access */
 	if (bus->parent->number == pcie->root_bus_nr)
-		rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE0, PCIECCTLR);
+		rcar_pci_write_reg(pcie->base, CONFIG_SEND_ENABLE | TYPE0,
+				   PCIECCTLR);
 	else
-		rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE1, PCIECCTLR);
+		rcar_pci_write_reg(pcie->base, CONFIG_SEND_ENABLE | TYPE1,
+				   PCIECCTLR);
 
 	/* Check for errors */
-	if (rcar_pci_read_reg(pcie, PCIEERRFR) & UNSUPPORTED_REQUEST)
+	if (rcar_pci_read_reg(pcie->base, PCIEERRFR) & UNSUPPORTED_REQUEST)
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	/* Check for master and target aborts */
@@ -259,12 +139,12 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie,
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	if (access_type == RCAR_PCI_ACCESS_READ)
-		*data = rcar_pci_read_reg(pcie, PCIECDR);
+		*data = rcar_pci_read_reg(pcie->base, PCIECDR);
 	else
-		rcar_pci_write_reg(pcie, *data, PCIECDR);
+		rcar_pci_write_reg(pcie->base, *data, PCIECDR);
 
 	/* Disable the configuration access */
-	rcar_pci_write_reg(pcie, 0, PCIECCTLR);
+	rcar_pci_write_reg(pcie->base, 0, PCIECCTLR);
 
 	return PCIBIOS_SUCCESSFUL;
 }
@@ -332,41 +212,6 @@ static struct pci_ops rcar_pcie_ops = {
 	.write	= rcar_pcie_write_conf,
 };
 
-static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie,
-				   struct resource *res)
-{
-	/* Setup PCIe address space mappings for each resource */
-	resource_size_t size;
-	resource_size_t res_start;
-	u32 mask;
-
-	rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
-
-	/*
-	 * The PAMR mask is calculated in units of 128Bytes, which
-	 * keeps things pretty simple.
-	 */
-	size = resource_size(res);
-	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
-	rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
-
-	if (res->flags & IORESOURCE_IO)
-		res_start = pci_pio_to_address(res->start);
-	else
-		res_start = res->start;
-
-	rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPAUR(win));
-	rcar_pci_write_reg(pcie, lower_32_bits(res_start) & ~0x7F,
-			   PCIEPALR(win));
-
-	/* First resource is for IO */
-	mask = PAR_ENABLE;
-	if (res->flags & IORESOURCE_IO)
-		mask |= IO_SPACE;
-
-	rcar_pci_write_reg(pcie, mask, PCIEPTCTLR(win));
-}
-
 static int rcar_pcie_setup(struct list_head *resource, struct rcar_pcie *pci)
 {
 	struct resource_entry *win;
@@ -382,7 +227,7 @@ static int rcar_pcie_setup(struct list_head *resource, struct rcar_pcie *pci)
 		switch (resource_type(res)) {
 		case IORESOURCE_IO:
 		case IORESOURCE_MEM:
-			rcar_pcie_setup_window(i, pci, res);
+			rcar_pcie_set_outbound(i, pci->base, res);
 			i++;
 			break;
 		case IORESOURCE_BUS:
@@ -404,37 +249,38 @@ static void rcar_pcie_force_speedup(struct rcar_pcie *pcie)
 	unsigned int timeout = 1000;
 	u32 macsr;
 
-	if ((rcar_pci_read_reg(pcie, MACS2R) & LINK_SPEED) != LINK_SPEED_5_0GTS)
+	if ((rcar_pci_read_reg(pcie->base, MACS2R) & LINK_SPEED) !=
+		LINK_SPEED_5_0GTS)
 		return;
 
-	if (rcar_pci_read_reg(pcie, MACCTLR) & SPEED_CHANGE) {
+	if (rcar_pci_read_reg(pcie->base, MACCTLR) & SPEED_CHANGE) {
 		dev_err(dev, "Speed change already in progress\n");
 		return;
 	}
 
-	macsr = rcar_pci_read_reg(pcie, MACSR);
+	macsr = rcar_pci_read_reg(pcie->base, MACSR);
 	if ((macsr & LINK_SPEED) == LINK_SPEED_5_0GTS)
 		goto done;
 
 	/* Set target link speed to 5.0 GT/s */
-	rcar_rmw32(pcie, EXPCAP(12), PCI_EXP_LNKSTA_CLS,
+	rcar_rmw32(pcie->base, EXPCAP(12), PCI_EXP_LNKSTA_CLS,
 		   PCI_EXP_LNKSTA_CLS_5_0GB);
 
 	/* Set speed change reason as intentional factor */
-	rcar_rmw32(pcie, MACCGSPSETR, SPCNGRSN, 0);
+	rcar_rmw32(pcie->base, MACCGSPSETR, SPCNGRSN, 0);
 
 	/* Clear SPCHGFIN, SPCHGSUC, and SPCHGFAIL */
 	if (macsr & (SPCHGFIN | SPCHGSUC | SPCHGFAIL))
-		rcar_pci_write_reg(pcie, macsr, MACSR);
+		rcar_pci_write_reg(pcie->base, macsr, MACSR);
 
 	/* Start link speed change */
-	rcar_rmw32(pcie, MACCTLR, SPEED_CHANGE, SPEED_CHANGE);
+	rcar_rmw32(pcie->base, MACCTLR, SPEED_CHANGE, SPEED_CHANGE);
 
 	while (timeout--) {
-		macsr = rcar_pci_read_reg(pcie, MACSR);
+		macsr = rcar_pci_read_reg(pcie->base, MACSR);
 		if (macsr & SPCHGFIN) {
 			/* Clear the interrupt bits */
-			rcar_pci_write_reg(pcie, macsr, MACSR);
+			rcar_pci_write_reg(pcie->base, macsr, MACSR);
 
 			if (macsr & SPCHGFAIL)
 				dev_err(dev, "Speed change failed\n");
@@ -498,7 +344,7 @@ static int phy_wait_for_ack(struct rcar_pcie *pcie)
 	unsigned int timeout = 100;
 
 	while (timeout--) {
-		if (rcar_pci_read_reg(pcie, H1_PCIEPHYADRR) & PHY_ACK)
+		if (rcar_pci_read_reg(pcie->base, H1_PCIEPHYADRR) & PHY_ACK)
 			return 0;
 
 		udelay(100);
@@ -521,60 +367,31 @@ static void phy_write_reg(struct rcar_pcie *pcie,
 		((addr & 0xff) << ADR_POS);
 
 	/* Set write data */
-	rcar_pci_write_reg(pcie, data, H1_PCIEPHYDOUTR);
-	rcar_pci_write_reg(pcie, phyaddr, H1_PCIEPHYADRR);
+	rcar_pci_write_reg(pcie->base, data, H1_PCIEPHYDOUTR);
+	rcar_pci_write_reg(pcie->base, phyaddr, H1_PCIEPHYADRR);
 
 	/* Ignore errors as they will be dealt with if the data link is down */
 	phy_wait_for_ack(pcie);
 
 	/* Clear command */
-	rcar_pci_write_reg(pcie, 0, H1_PCIEPHYDOUTR);
-	rcar_pci_write_reg(pcie, 0, H1_PCIEPHYADRR);
+	rcar_pci_write_reg(pcie->base, 0, H1_PCIEPHYDOUTR);
+	rcar_pci_write_reg(pcie->base, 0, H1_PCIEPHYADRR);
 
 	/* Ignore errors as they will be dealt with if the data link is down */
 	phy_wait_for_ack(pcie);
 }
 
-static int rcar_pcie_wait_for_phyrdy(struct rcar_pcie *pcie)
-{
-	unsigned int timeout = 10;
-
-	while (timeout--) {
-		if (rcar_pci_read_reg(pcie, PCIEPHYSR) & PHYRDY)
-			return 0;
-
-		msleep(5);
-	}
-
-	return -ETIMEDOUT;
-}
-
-static int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie)
-{
-	unsigned int timeout = 10000;
-
-	while (timeout--) {
-		if ((rcar_pci_read_reg(pcie, PCIETSTR) & DATA_LINK_ACTIVE))
-			return 0;
-
-		udelay(5);
-		cpu_relax();
-	}
-
-	return -ETIMEDOUT;
-}
-
 static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
 {
 	int err;
 
 	/* Begin initialization */
-	rcar_pci_write_reg(pcie, 0, PCIETCTLR);
+	rcar_pci_write_reg(pcie->base, 0, PCIETCTLR);
 
 	/* Set mode */
-	rcar_pci_write_reg(pcie, 1, PCIEMSR);
+	rcar_pci_write_reg(pcie->base, 1, PCIEMSR);
 
-	err = rcar_pcie_wait_for_phyrdy(pcie);
+	err = rcar_pcie_wait_for_phyrdy(pcie->base);
 	if (err)
 		return err;
 
@@ -583,51 +400,51 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
 	 * class to match. Hardware takes care of propagating the IDSETR
 	 * settings, so there is no need to bother with a quirk.
 	 */
-	rcar_pci_write_reg(pcie, PCI_CLASS_BRIDGE_PCI << 16, IDSETR1);
+	rcar_pci_write_reg(pcie->base, PCI_CLASS_BRIDGE_PCI << 16, IDSETR1);
 
 	/*
 	 * Setup Secondary Bus Number & Subordinate Bus Number, even though
 	 * they aren't used, to avoid bridge being detected as broken.
 	 */
-	rcar_rmw32(pcie, RCONF(PCI_SECONDARY_BUS), 0xff, 1);
-	rcar_rmw32(pcie, RCONF(PCI_SUBORDINATE_BUS), 0xff, 1);
+	rcar_rmw32(pcie->base, RCONF(PCI_SECONDARY_BUS), 0xff, 1);
+	rcar_rmw32(pcie->base, RCONF(PCI_SUBORDINATE_BUS), 0xff, 1);
 
 	/* Initialize default capabilities. */
-	rcar_rmw32(pcie, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
-	rcar_rmw32(pcie, REXPCAP(PCI_EXP_FLAGS),
-		PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ROOT_PORT << 4);
-	rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
-		PCI_HEADER_TYPE_BRIDGE);
+	rcar_rmw32(pcie->base, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
+	rcar_rmw32(pcie->base, REXPCAP(PCI_EXP_FLAGS),
+		   PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ROOT_PORT << 4);
+	rcar_rmw32(pcie->base, RCONF(PCI_HEADER_TYPE), 0x7f,
+		   PCI_HEADER_TYPE_BRIDGE);
 
 	/* Enable data link layer active state reporting */
-	rcar_rmw32(pcie, REXPCAP(PCI_EXP_LNKCAP), PCI_EXP_LNKCAP_DLLLARC,
-		PCI_EXP_LNKCAP_DLLLARC);
+	rcar_rmw32(pcie->base, REXPCAP(PCI_EXP_LNKCAP), PCI_EXP_LNKCAP_DLLLARC,
+		   PCI_EXP_LNKCAP_DLLLARC);
 
 	/* Write out the physical slot number = 0 */
-	rcar_rmw32(pcie, REXPCAP(PCI_EXP_SLTCAP), PCI_EXP_SLTCAP_PSN, 0);
+	rcar_rmw32(pcie->base, REXPCAP(PCI_EXP_SLTCAP), PCI_EXP_SLTCAP_PSN, 0);
 
 	/* Set the completion timer timeout to the maximum 50ms. */
-	rcar_rmw32(pcie, TLCTLR + 1, 0x3f, 50);
+	rcar_rmw32(pcie->base, TLCTLR + 1, 0x3f, 50);
 
 	/* Terminate list of capabilities (Next Capability Offset=0) */
-	rcar_rmw32(pcie, RVCCAP(0), 0xfff00000, 0);
+	rcar_rmw32(pcie->base, RVCCAP(0), 0xfff00000, 0);
 
 	/* Enable MSI */
 	if (IS_ENABLED(CONFIG_PCI_MSI))
-		rcar_pci_write_reg(pcie, 0x801f0000, PCIEMSITXR);
+		rcar_pci_write_reg(pcie->base, 0x801f0000, PCIEMSITXR);
 
-	rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR);
+	rcar_pci_write_reg(pcie->base, MACCTLR_INIT_VAL, MACCTLR);
 
 	/* Finish initialization - establish a PCI Express link */
-	rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR);
+	rcar_pci_write_reg(pcie->base, CFINIT, PCIETCTLR);
 
 	/* This will timeout if we don't have a link. */
-	err = rcar_pcie_wait_for_dl(pcie);
+	err = rcar_pcie_wait_for_dl(pcie->base);
 	if (err)
 		return err;
 
 	/* Enable INTx interrupts */
-	rcar_rmw32(pcie, PCIEINTXR, 0, 0xF << 8);
+	rcar_rmw32(pcie->base, PCIEINTXR, 0, 0xF << 8);
 
 	wmb();
 
@@ -663,16 +480,16 @@ static int rcar_pcie_phy_init_gen2(struct rcar_pcie *pcie)
 	 * These settings come from the R-Car Series, 2nd Generation User's
 	 * Manual, section 50.3.1 (2) Initialization of the physical layer.
 	 */
-	rcar_pci_write_reg(pcie, 0x000f0030, GEN2_PCIEPHYADDR);
-	rcar_pci_write_reg(pcie, 0x00381203, GEN2_PCIEPHYDATA);
-	rcar_pci_write_reg(pcie, 0x00000001, GEN2_PCIEPHYCTRL);
-	rcar_pci_write_reg(pcie, 0x00000006, GEN2_PCIEPHYCTRL);
+	rcar_pci_write_reg(pcie->base, 0x000f0030, GEN2_PCIEPHYADDR);
+	rcar_pci_write_reg(pcie->base, 0x00381203, GEN2_PCIEPHYDATA);
+	rcar_pci_write_reg(pcie->base, 0x00000001, GEN2_PCIEPHYCTRL);
+	rcar_pci_write_reg(pcie->base, 0x00000006, GEN2_PCIEPHYCTRL);
 
-	rcar_pci_write_reg(pcie, 0x000f0054, GEN2_PCIEPHYADDR);
+	rcar_pci_write_reg(pcie->base, 0x000f0054, GEN2_PCIEPHYADDR);
 	/* The following value is for DC connection, no termination resistor */
-	rcar_pci_write_reg(pcie, 0x13802007, GEN2_PCIEPHYDATA);
-	rcar_pci_write_reg(pcie, 0x00000001, GEN2_PCIEPHYCTRL);
-	rcar_pci_write_reg(pcie, 0x00000006, GEN2_PCIEPHYCTRL);
+	rcar_pci_write_reg(pcie->base, 0x13802007, GEN2_PCIEPHYDATA);
+	rcar_pci_write_reg(pcie->base, 0x00000001, GEN2_PCIEPHYCTRL);
+	rcar_pci_write_reg(pcie->base, 0x00000006, GEN2_PCIEPHYCTRL);
 
 	return 0;
 }
@@ -735,7 +552,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
 	struct device *dev = pcie->dev;
 	unsigned long reg;
 
-	reg = rcar_pci_read_reg(pcie, PCIEMSIFR);
+	reg = rcar_pci_read_reg(pcie->base, PCIEMSIFR);
 
 	/* MSI & INTx share an interrupt - we only handle MSI here */
 	if (!reg)
@@ -746,7 +563,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
 		unsigned int msi_irq;
 
 		/* clear the interrupt */
-		rcar_pci_write_reg(pcie, 1 << index, PCIEMSIFR);
+		rcar_pci_write_reg(pcie->base, 1 << index, PCIEMSIFR);
 
 		msi_irq = irq_find_mapping(msi->domain, index);
 		if (msi_irq) {
@@ -760,7 +577,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
 		}
 
 		/* see if there's any more pending in this vector */
-		reg = rcar_pci_read_reg(pcie, PCIEMSIFR);
+		reg = rcar_pci_read_reg(pcie->base, PCIEMSIFR);
 	}
 
 	return IRQ_HANDLED;
@@ -787,8 +604,8 @@ static int rcar_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
 
 	irq_set_msi_desc(irq, desc);
 
-	msg.address_lo = rcar_pci_read_reg(pcie, PCIEMSIALR) & ~MSIFE;
-	msg.address_hi = rcar_pci_read_reg(pcie, PCIEMSIAUR);
+	msg.address_lo = rcar_pci_read_reg(pcie->base, PCIEMSIALR) & ~MSIFE;
+	msg.address_hi = rcar_pci_read_reg(pcie->base, PCIEMSIAUR);
 	msg.data = hwirq;
 
 	pci_write_msi_msg(irq, &msg);
@@ -839,8 +656,8 @@ static int rcar_msi_setup_irqs(struct msi_controller *chip,
 	desc->nvec_used = nvec;
 	desc->msi_attrib.multiple = order_base_2(nvec);
 
-	msg.address_lo = rcar_pci_read_reg(pcie, PCIEMSIALR) & ~MSIFE;
-	msg.address_hi = rcar_pci_read_reg(pcie, PCIEMSIAUR);
+	msg.address_lo = rcar_pci_read_reg(pcie->base, PCIEMSIALR) & ~MSIFE;
+	msg.address_hi = rcar_pci_read_reg(pcie->base, PCIEMSIAUR);
 	msg.data = hwirq;
 
 	pci_write_msi_msg(irq, &msg);
@@ -940,11 +757,11 @@ static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)
 	}
 	base = virt_to_phys((void *)msi->pages);
 
-	rcar_pci_write_reg(pcie, lower_32_bits(base) | MSIFE, PCIEMSIALR);
-	rcar_pci_write_reg(pcie, upper_32_bits(base), PCIEMSIAUR);
+	rcar_pci_write_reg(pcie->base, lower_32_bits(base) | MSIFE, PCIEMSIALR);
+	rcar_pci_write_reg(pcie->base, upper_32_bits(base), PCIEMSIAUR);
 
 	/* enable all MSI interrupts */
-	rcar_pci_write_reg(pcie, 0xffffffff, PCIEMSIIER);
+	rcar_pci_write_reg(pcie->base, 0xffffffff, PCIEMSIIER);
 
 	return 0;
 
@@ -958,10 +775,10 @@ static void rcar_pcie_teardown_msi(struct rcar_pcie *pcie)
 	struct rcar_msi *msi = &pcie->msi;
 
 	/* Disable all MSI interrupts */
-	rcar_pci_write_reg(pcie, 0, PCIEMSIIER);
+	rcar_pci_write_reg(pcie->base, 0, PCIEMSIIER);
 
 	/* Disable address decoding of the MSI interrupt, MSIFE */
-	rcar_pci_write_reg(pcie, 0, PCIEMSIALR);
+	rcar_pci_write_reg(pcie->base, 0, PCIEMSIALR);
 
 	free_pages(msi->pages, 0);
 
@@ -1054,21 +871,8 @@ static int rcar_pcie_inbound_ranges(struct rcar_pcie *pcie,
 		mask = roundup_pow_of_two(size) - 1;
 		mask &= ~0xf;
 
-		/*
-		 * Set up 64-bit inbound regions as the range parser doesn't
-		 * distinguish between 32 and 64-bit types.
-		 */
-		rcar_pci_write_reg(pcie, lower_32_bits(pci_addr),
-				   PCIEPRAR(idx));
-		rcar_pci_write_reg(pcie, lower_32_bits(cpu_addr), PCIELAR(idx));
-		rcar_pci_write_reg(pcie, lower_32_bits(mask) | flags,
-				   PCIELAMR(idx));
-
-		rcar_pci_write_reg(pcie, upper_32_bits(pci_addr),
-				   PCIEPRAR(idx + 1));
-		rcar_pci_write_reg(pcie, upper_32_bits(cpu_addr),
-				   PCIELAR(idx + 1));
-		rcar_pci_write_reg(pcie, 0, PCIELAMR(idx + 1));
+		rcar_pcie_set_inbound(pcie->base, cpu_addr, pci_addr,
+				      lower_32_bits(mask) | flags, idx, true);
 
 		pci_addr += size;
 		cpu_addr += size;
@@ -1170,7 +974,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 		goto err_phy_shutdown;
 	}
 
-	data = rcar_pci_read_reg(pcie, MACSR);
+	data = rcar_pci_read_reg(pcie->base, MACSR);
 	dev_info(dev, "PCIe x%d: link up\n", (data >> 20) & 0x3f);
 
 	if (IS_ENABLED(CONFIG_PCI_MSI)) {
@@ -1223,14 +1027,14 @@ static int rcar_pcie_resume_noirq(struct device *dev)
 {
 	struct rcar_pcie *pcie = dev_get_drvdata(dev);
 
-	if (rcar_pci_read_reg(pcie, PMSR) &&
-	    !(rcar_pci_read_reg(pcie, PCIETCTLR) & DL_DOWN))
+	if (rcar_pci_read_reg(pcie->base, PMSR) &&
+	    !(rcar_pci_read_reg(pcie->base, PCIETCTLR) & DL_DOWN))
 		return 0;
 
 	/* Re-establish the PCIe link */
-	rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR);
-	rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR);
-	return rcar_pcie_wait_for_dl(pcie);
+	rcar_pci_write_reg(pcie->base, MACCTLR_INIT_VAL, MACCTLR);
+	rcar_pci_write_reg(pcie->base, CFINIT, PCIETCTLR);
+	return rcar_pcie_wait_for_dl(pcie->base);
 }
 
 static const struct dev_pm_ops rcar_pcie_pm_ops = {
diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c
new file mode 100644
index 0000000..41275f9
--- /dev/null
+++ b/drivers/pci/controller/pcie-rcar.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe driver for Renesas R-Car SoCs
+ *  Copyright (C) 2014-2020 Renesas Electronics Europe Ltd
+ *
+ * Author: Phil Edworthy <phil.edworthy@renesas.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include "pcie-rcar.h"
+
+void rcar_pci_write_reg(void __iomem *base, u32 val, unsigned int reg)
+{
+	writel(val, base + reg);
+}
+
+u32 rcar_pci_read_reg(void __iomem *base, unsigned int reg)
+{
+	return readl(base + reg);
+}
+
+void rcar_rmw32(void __iomem *base, int where, u32 mask, u32 data)
+{
+	unsigned int shift = BITS_PER_BYTE * (where & 3);
+	u32 val = rcar_pci_read_reg(base, where & ~3);
+
+	val &= ~(mask << shift);
+	val |= data << shift;
+	rcar_pci_write_reg(base, val, where & ~3);
+}
+
+int rcar_pcie_wait_for_phyrdy(void __iomem *base)
+{
+	unsigned int timeout = 10;
+
+	while (timeout--) {
+		if (rcar_pci_read_reg(base, PCIEPHYSR) & PHYRDY)
+			return 0;
+
+		msleep(5);
+	}
+
+	return -ETIMEDOUT;
+}
+
+int rcar_pcie_wait_for_dl(void __iomem *base)
+{
+	unsigned int timeout = 10000;
+
+	while (timeout--) {
+		if ((rcar_pci_read_reg(base, PCIETSTR) & DATA_LINK_ACTIVE))
+			return 0;
+
+		udelay(5);
+		cpu_relax();
+	}
+
+	return -ETIMEDOUT;
+}
+
+void rcar_pcie_set_outbound(int win, void __iomem *base,
+			    struct resource *res)
+{
+	/* Setup PCIe address space mappings for each resource */
+	resource_size_t res_start;
+	resource_size_t size;
+	u32 mask;
+
+	rcar_pci_write_reg(base, 0x00000000, PCIEPTCTLR(win));
+
+	/*
+	 * The PAMR mask is calculated in units of 128Bytes, which
+	 * keeps things pretty simple.
+	 */
+	size = resource_size(res);
+	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
+	rcar_pci_write_reg(base, mask << 7, PCIEPAMR(win));
+
+	if (res->flags & IORESOURCE_IO)
+		res_start = pci_pio_to_address(res->start);
+	else
+		res_start = res->start;
+
+	rcar_pci_write_reg(base, upper_32_bits(res_start), PCIEPAUR(win));
+	rcar_pci_write_reg(base, lower_32_bits(res_start) & ~0x7F,
+			   PCIEPALR(win));
+
+	/* First resource is for IO */
+	mask = PAR_ENABLE;
+	if (res->flags & IORESOURCE_IO)
+		mask |= IO_SPACE;
+
+	rcar_pci_write_reg(base, mask, PCIEPTCTLR(win));
+}
+
+void rcar_pcie_set_inbound(void __iomem *base,
+			   u64 cpu_addr, u64 pci_addr,
+			   u64 flags, int idx, bool host)
+{
+	/*
+	 * Set up 64-bit inbound regions as the range parser doesn't
+	 * distinguish between 32 and 64-bit types.
+	 */
+	if (host)
+		rcar_pci_write_reg(base, lower_32_bits(pci_addr),
+				   PCIEPRAR(idx));
+	rcar_pci_write_reg(base, lower_32_bits(cpu_addr), PCIELAR(idx));
+	rcar_pci_write_reg(base, flags, PCIELAMR(idx));
+
+	if (host)
+		rcar_pci_write_reg(base, upper_32_bits(pci_addr),
+				   PCIEPRAR(idx + 1));
+	rcar_pci_write_reg(base, upper_32_bits(cpu_addr), PCIELAR(idx + 1));
+	rcar_pci_write_reg(base, 0, PCIELAMR(idx + 1));
+}
diff --git a/drivers/pci/controller/pcie-rcar.h b/drivers/pci/controller/pcie-rcar.h
new file mode 100644
index 0000000..b529d806
--- /dev/null
+++ b/drivers/pci/controller/pcie-rcar.h
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PCIe driver for Renesas R-Car SoCs
+ *  Copyright (C) 2014-2020 Renesas Electronics Europe Ltd
+ *
+ * Author: Phil Edworthy <phil.edworthy@renesas.com>
+ */
+
+#ifndef _PCIE_RCAR_H
+#define _PCIE_RCAR_H
+
+#define PCIECAR			0x000010
+#define PCIECCTLR		0x000018
+#define  CONFIG_SEND_ENABLE	BIT(31)
+#define  TYPE0			(0 << 8)
+#define  TYPE1			BIT(8)
+#define PCIECDR			0x000020
+#define PCIEMSR			0x000028
+#define PCIEINTXR		0x000400
+#define PCIEPHYSR		0x0007f0
+#define  PHYRDY			BIT(0)
+#define PCIEMSITXR		0x000840
+
+/* Transfer control */
+#define PCIETCTLR		0x02000
+#define  DL_DOWN		BIT(3)
+#define  CFINIT			BIT(0)
+#define PCIETSTR		0x02004
+#define  DATA_LINK_ACTIVE	BIT(0)
+#define PCIEERRFR		0x02020
+#define  UNSUPPORTED_REQUEST	BIT(4)
+#define PCIEMSIFR		0x02044
+#define PCIEMSIALR		0x02048
+#define  MSIFE			BIT(0)
+#define PCIEMSIAUR		0x0204c
+#define PCIEMSIIER		0x02050
+
+/* root port address */
+#define PCIEPRAR(x)		(0x02080 + ((x) * 0x4))
+
+/* local address reg & mask */
+#define PCIELAR(x)		(0x02200 + ((x) * 0x20))
+#define PCIELAMR(x)		(0x02208 + ((x) * 0x20))
+#define  LAM_PREFETCH		BIT(3)
+#define  LAM_64BIT		BIT(2)
+#define  LAR_ENABLE		BIT(1)
+
+/* PCIe address reg & mask */
+#define PCIEPALR(x)		(0x03400 + ((x) * 0x20))
+#define PCIEPAUR(x)		(0x03404 + ((x) * 0x20))
+#define PCIEPAMR(x)		(0x03408 + ((x) * 0x20))
+#define PCIEPTCTLR(x)		(0x0340c + ((x) * 0x20))
+#define  PAR_ENABLE		BIT(31)
+#define  IO_SPACE		BIT(8)
+
+/* Configuration */
+#define PCICONF(x)		(0x010000 + ((x) * 0x4))
+#define PMCAP(x)		(0x010040 + ((x) * 0x4))
+#define EXPCAP(x)		(0x010070 + ((x) * 0x4))
+#define VCCAP(x)		(0x010100 + ((x) * 0x4))
+
+/* link layer */
+#define IDSETR1			0x011004
+#define TLCTLR			0x011048
+#define MACSR			0x011054
+#define  SPCHGFIN		BIT(4)
+#define  SPCHGFAIL		BIT(6)
+#define  SPCHGSUC		BIT(7)
+#define  LINK_SPEED		(0xf << 16)
+#define  LINK_SPEED_2_5GTS	(1 << 16)
+#define  LINK_SPEED_5_0GTS	(2 << 16)
+#define MACCTLR			0x011058
+#define  MACCTLR_NFTS_MASK	GENMASK(23, 16)	/* The name is from SH7786 */
+#define  SPEED_CHANGE		BIT(24)
+#define  SCRAMBLE_DISABLE	BIT(27)
+#define  LTSMDIS		BIT(31)
+#define  MACCTLR_INIT_VAL	(LTSMDIS | MACCTLR_NFTS_MASK)
+#define PMSR			0x01105c
+#define MACS2R			0x011078
+#define MACCGSPSETR		0x011084
+#define  SPCNGRSN		BIT(31)
+
+/* R-Car H1 PHY */
+#define H1_PCIEPHYADRR		0x04000c
+#define  WRITE_CMD		BIT(16)
+#define  PHY_ACK		BIT(24)
+#define  RATE_POS		12
+#define  LANE_POS		8
+#define  ADR_POS		0
+#define H1_PCIEPHYDOUTR		0x040014
+
+/* R-Car Gen2 PHY */
+#define GEN2_PCIEPHYADDR	0x780
+#define GEN2_PCIEPHYDATA	0x784
+#define GEN2_PCIEPHYCTRL	0x78c
+
+#define INT_PCI_MSI_NR		32
+
+#define RCONF(x)		(PCICONF(0) + (x))
+#define RPMCAP(x)		(PMCAP(0) + (x))
+#define REXPCAP(x)		(EXPCAP(0) + (x))
+#define RVCCAP(x)		(VCCAP(0) + (x))
+
+#define PCIE_CONF_BUS(b)	(((b) & 0xff) << 24)
+#define PCIE_CONF_DEV(d)	(((d) & 0x1f) << 19)
+#define PCIE_CONF_FUNC(f)	(((f) & 0x7) << 16)
+
+#define RCAR_PCI_MAX_RESOURCES	4
+#define MAX_NR_INBOUND_MAPS	6
+
+enum {
+	RCAR_PCI_ACCESS_READ,
+	RCAR_PCI_ACCESS_WRITE,
+};
+
+void rcar_pci_write_reg(void __iomem *base, u32 val, unsigned int reg);
+u32 rcar_pci_read_reg(void __iomem *base, unsigned int reg);
+void rcar_rmw32(void __iomem *base, int where, u32 mask, u32 data);
+int rcar_pcie_wait_for_phyrdy(void __iomem *base);
+int rcar_pcie_wait_for_dl(void __iomem *base);
+void rcar_pcie_set_outbound(int win, void __iomem *base, struct resource *res);
+void rcar_pcie_set_inbound(void __iomem *base, u64 cpu_addr, u64 pci_addr,
+			   u64 mask, int idx, bool host);
+
+#endif
-- 
2.7.4


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

* [PATCH v5 3/7] PCI: rcar: Fix calculating mask for PCIEPAMR register
  2020-02-28 15:41 [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
  2020-02-28 15:41 ` [PATCH v5 1/7] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c Lad Prabhakar
  2020-02-28 15:41 ` [PATCH v5 2/7] PCI: rcar: Move shareable code to a common file Lad Prabhakar
@ 2020-02-28 15:41 ` Lad Prabhakar
  2020-03-17  7:31   ` Yoshihiro Shimoda
  2020-02-28 15:41 ` [PATCH v5 4/7] PCI: endpoint: Add support to handle multiple base for mapping outbound memory Lad Prabhakar
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 26+ messages in thread
From: Lad Prabhakar @ 2020-02-28 15:41 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Yoshihiro Shimoda, Shawn Lin, Heiko Stuebner
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Lad Prabhakar

The mask value was calculated incorrectly for PCIEPAMR register if the
size was less than 128 bytes. Fix this issue by adding a check on size.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
 drivers/pci/controller/pcie-rcar.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c
index 41275f9..90d47b21 100644
--- a/drivers/pci/controller/pcie-rcar.c
+++ b/drivers/pci/controller/pcie-rcar.c
@@ -75,7 +75,10 @@ void rcar_pcie_set_outbound(int win, void __iomem *base,
 	 * keeps things pretty simple.
 	 */
 	size = resource_size(res);
-	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
+	if (size > 128)
+		mask = (roundup_pow_of_two(size) / SZ_128) - 1;
+	else
+		mask = 0x0;
 	rcar_pci_write_reg(base, mask << 7, PCIEPAMR(win));
 
 	if (res->flags & IORESOURCE_IO)
-- 
2.7.4


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

* [PATCH v5 4/7] PCI: endpoint: Add support to handle multiple base for mapping outbound memory
  2020-02-28 15:41 [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
                   ` (2 preceding siblings ...)
  2020-02-28 15:41 ` [PATCH v5 3/7] PCI: rcar: Fix calculating mask for PCIEPAMR register Lad Prabhakar
@ 2020-02-28 15:41 ` Lad Prabhakar
  2020-03-17  8:11   ` Yoshihiro Shimoda
  2020-02-28 15:41 ` [PATCH v5 5/7] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller Lad Prabhakar
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 26+ messages in thread
From: Lad Prabhakar @ 2020-02-28 15:41 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Yoshihiro Shimoda, Shawn Lin, Heiko Stuebner
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Lad Prabhakar

R-Car PCIe controller has support to map multiple memory regions for
mapping the outbound memory in local system also the controller limits
single allocation for each region (that is, once a chunk is used from the
region it cannot be used to allocate a new one). This features inspires to
add support for handling multiple memory bases in endpoint framework.

With this patch pci_epc_mem_init() now accepts multiple regions, also
page_size for each memory region is passed during initialization so as
to handle single allocation for each region by setting the page_size to
window_size.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
 drivers/pci/controller/cadence/pcie-cadence-ep.c |   7 +-
 drivers/pci/controller/dwc/pcie-designware-ep.c  |  29 ++--
 drivers/pci/controller/pcie-rockchip-ep.c        |   7 +-
 drivers/pci/endpoint/pci-epc-mem.c               | 167 ++++++++++++++++-------
 include/linux/pci-epc.h                          |  39 ++++--
 5 files changed, 169 insertions(+), 80 deletions(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 1c173da..90e32438 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -401,6 +401,7 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 	struct device *dev = ep->pcie.dev;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct device_node *np = dev->of_node;
+	struct pci_epc_mem_window mem_window;
 	struct cdns_pcie *pcie = &ep->pcie;
 	struct resource *res;
 	struct pci_epc *epc;
@@ -449,8 +450,10 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 	if (of_property_read_u8(np, "max-functions", &epc->max_functions) < 0)
 		epc->max_functions = 1;
 
-	ret = pci_epc_mem_init(epc, pcie->mem_res->start,
-			       resource_size(pcie->mem_res));
+	mem_window.phys_base = pcie->mem_res->start;
+	mem_window.size = resource_size(pcie->mem_res);
+	mem_window.page_size = PAGE_SIZE;
+	ret = pci_epc_mem_init(epc, &mem_window, 1);
 	if (ret < 0) {
 		dev_err(dev, "failed to initialize the memory space\n");
 		goto err_init;
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index cfeccd7..b150ef3 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -195,8 +195,7 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
 }
 
 static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
-			       phys_addr_t addr,
-			       u64 pci_addr, size_t size)
+			       phys_addr_t addr, u64 pci_addr, size_t size)
 {
 	int ret;
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -367,6 +366,7 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 	unsigned int aligned_offset;
 	u16 msg_ctrl, msg_data;
 	u32 msg_addr_lower, msg_addr_upper, reg;
+	int window = PCI_EPC_DEFAULT_WINDOW;
 	u64 msg_addr;
 	bool has_upper;
 	int ret;
@@ -390,11 +390,11 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 		reg = ep->msi_cap + PCI_MSI_DATA_32;
 		msg_data = dw_pcie_readw_dbi(pci, reg);
 	}
-	aligned_offset = msg_addr_lower & (epc->mem->page_size - 1);
+	aligned_offset = msg_addr_lower & (epc->mem[window]->page_size - 1);
 	msg_addr = ((u64)msg_addr_upper) << 32 |
 			(msg_addr_lower & ~aligned_offset);
-	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
-				  epc->mem->page_size);
+	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys,
+				  msg_addr, epc->mem[window]->page_size);
 	if (ret)
 		return ret;
 
@@ -416,6 +416,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 	u32 reg, msg_data, vec_ctrl;
 	u64 tbl_addr, msg_addr, reg_u64;
 	void __iomem *msix_tbl;
+	int window = PCI_EPC_DEFAULT_WINDOW;
 	int ret;
 
 	reg = ep->msix_cap + PCI_MSIX_TABLE;
@@ -452,8 +453,8 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 		return -EPERM;
 	}
 
-	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
-				  epc->mem->page_size);
+	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys,
+				  msg_addr, epc->mem[window]->page_size);
 	if (ret)
 		return ret;
 
@@ -466,10 +467,11 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 
 void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
 {
+	int window = PCI_EPC_DEFAULT_WINDOW;
 	struct pci_epc *epc = ep->epc;
 
 	pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
-			      epc->mem->page_size);
+			      epc->mem[window]->page_size);
 
 	pci_epc_mem_exit(epc);
 }
@@ -502,6 +504,8 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 	unsigned int nbars;
 	unsigned int offset;
 	struct pci_epc *epc;
+	size_t msi_page_size;
+	struct pci_epc_mem_window mem_window;
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 	struct device *dev = pci->dev;
 	struct device_node *np = dev->of_node;
@@ -574,15 +578,18 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 	if (ret < 0)
 		epc->max_functions = 1;
 
-	ret = __pci_epc_mem_init(epc, ep->phys_base, ep->addr_size,
-				 ep->page_size);
+	mem_window.phys_base = ep->phys_base;
+	mem_window.size = ep->addr_size;
+	mem_window.page_size = ep->page_size;
+	ret = __pci_epc_mem_init(epc, &mem_window, 1);
 	if (ret < 0) {
 		dev_err(dev, "Failed to initialize address space\n");
 		return ret;
 	}
 
+	msi_page_size = epc->mem[PCI_EPC_DEFAULT_WINDOW]->page_size;
 	ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
-					     epc->mem->page_size);
+					     msi_page_size);
 	if (!ep->msi_mem) {
 		dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n");
 		return -ENOMEM;
diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
index d743b0a..5a97390 100644
--- a/drivers/pci/controller/pcie-rockchip-ep.c
+++ b/drivers/pci/controller/pcie-rockchip-ep.c
@@ -562,6 +562,7 @@ static const struct of_device_id rockchip_pcie_ep_of_match[] = {
 
 static int rockchip_pcie_ep_probe(struct platform_device *pdev)
 {
+	struct pci_epc_mem_window mem_window;
 	struct device *dev = &pdev->dev;
 	struct rockchip_pcie_ep *ep;
 	struct rockchip_pcie *rockchip;
@@ -614,8 +615,10 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)
 	/* Only enable function 0 by default */
 	rockchip_pcie_write(rockchip, BIT(0), PCIE_CORE_PHY_FUNC_CFG);
 
-	err = pci_epc_mem_init(epc, rockchip->mem_res->start,
-			       resource_size(rockchip->mem_res));
+	mem_window.phys_base = rockchip->mem_res->start;
+	mem_window.size = resource_size(rockchip->mem_res);
+	mem_window.page_size = PAGE_SIZE;
+	err = pci_epc_mem_init(epc, &mem_window, 1);
 	if (err < 0) {
 		dev_err(dev, "failed to initialize the memory space\n");
 		goto err_uninit_port;
diff --git a/drivers/pci/endpoint/pci-epc-mem.c b/drivers/pci/endpoint/pci-epc-mem.c
index d2b174c..6c21957 100644
--- a/drivers/pci/endpoint/pci-epc-mem.c
+++ b/drivers/pci/endpoint/pci-epc-mem.c
@@ -38,57 +38,76 @@ static int pci_epc_mem_get_order(struct pci_epc_mem *mem, size_t size)
 /**
  * __pci_epc_mem_init() - initialize the pci_epc_mem structure
  * @epc: the EPC device that invoked pci_epc_mem_init
- * @phys_base: the physical address of the base
- * @size: the size of the address space
- * @page_size: size of each page
+ * @windows: pointer to windows supported by the device
+ * @num_windows: number of windows device supports
  *
  * Invoke to initialize the pci_epc_mem structure used by the
  * endpoint functions to allocate mapped PCI address.
  */
-int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size,
-		       size_t page_size)
+int __pci_epc_mem_init(struct pci_epc *epc, struct pci_epc_mem_window *windows,
+		       int num_windows)
 {
-	int ret;
-	struct pci_epc_mem *mem;
-	unsigned long *bitmap;
+	struct pci_epc_mem *mem = NULL;
+	unsigned long *bitmap = NULL;
 	unsigned int page_shift;
-	int pages;
+	size_t page_size;
 	int bitmap_size;
-
-	if (page_size < PAGE_SIZE)
-		page_size = PAGE_SIZE;
-
-	page_shift = ilog2(page_size);
-	pages = size >> page_shift;
-	bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
-
-	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
-	if (!mem) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	bitmap = kzalloc(bitmap_size, GFP_KERNEL);
-	if (!bitmap) {
-		ret = -ENOMEM;
-		goto err_mem;
+	int pages;
+	int ret;
+	int i;
+
+	epc->mem_windows = 0;
+
+	if (!windows)
+		return -EINVAL;
+
+	if (num_windows <= 0)
+		return -EINVAL;
+
+	epc->mem = kcalloc(num_windows, sizeof(*mem), GFP_KERNEL);
+	if (!epc->mem)
+		return -EINVAL;
+
+	for (i = 0; i < num_windows; i++) {
+		page_size = windows[i].page_size;
+		if (page_size < PAGE_SIZE)
+			page_size = PAGE_SIZE;
+		page_shift = ilog2(page_size);
+		pages = windows[i].size >> page_shift;
+		bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
+
+		mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+		if (!mem) {
+			ret = -ENOMEM;
+			goto err_mem;
+		}
+
+		bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+		if (!bitmap) {
+			ret = -ENOMEM;
+			goto err_mem;
+		}
+
+		mem->bitmap = bitmap;
+		mem->window.phys_base = windows[i].phys_base;
+		mem->page_size = page_size;
+		mem->pages = pages;
+		mem->window.size = windows[i].size;
+		epc->mem[i] = mem;
 	}
-
-	mem->bitmap = bitmap;
-	mem->phys_base = phys_base;
-	mem->page_size = page_size;
-	mem->pages = pages;
-	mem->size = size;
-
-	epc->mem = mem;
+	epc->mem_windows = num_windows;
 
 	return 0;
 
 err_mem:
-	kfree(mem);
+	for (; i >= 0; i--) {
+		mem = epc->mem[i];
+		kfree(mem->bitmap);
+		kfree(mem);
+	}
+	kfree(epc->mem);
 
-err:
-return ret;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(__pci_epc_mem_init);
 
@@ -101,11 +120,21 @@ EXPORT_SYMBOL_GPL(__pci_epc_mem_init);
  */
 void pci_epc_mem_exit(struct pci_epc *epc)
 {
-	struct pci_epc_mem *mem = epc->mem;
+	struct pci_epc_mem *mem;
+	int i;
+
+	if (!epc->mem_windows)
+		return;
+
+	for (i = 0; i <= epc->mem_windows; i++) {
+		mem = epc->mem[i];
+		kfree(mem->bitmap);
+		kfree(mem);
+	}
+	kfree(epc->mem);
 
 	epc->mem = NULL;
-	kfree(mem->bitmap);
-	kfree(mem);
+	epc->mem_windows = 0;
 }
 EXPORT_SYMBOL_GPL(pci_epc_mem_exit);
 
@@ -121,20 +150,30 @@ EXPORT_SYMBOL_GPL(pci_epc_mem_exit);
 void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
 				     phys_addr_t *phys_addr, size_t size)
 {
-	int pageno;
-	void __iomem *virt_addr;
-	struct pci_epc_mem *mem = epc->mem;
-	unsigned int page_shift = ilog2(mem->page_size);
+	void __iomem *virt_addr = NULL;
+	struct pci_epc_mem *mem;
+	unsigned int page_shift;
+	int pageno = -EINVAL;
 	int order;
+	int i;
 
-	size = ALIGN(size, mem->page_size);
-	order = pci_epc_mem_get_order(mem, size);
+	for (i = 0; i < epc->mem_windows; i++) {
+		mem = epc->mem[i];
+		size = ALIGN(size, mem->page_size);
+		order = pci_epc_mem_get_order(mem, size);
+
+		pageno = bitmap_find_free_region(mem->bitmap, mem->pages,
+						 order);
+		if (pageno >= 0)
+			break;
+	}
 
-	pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);
 	if (pageno < 0)
 		return NULL;
 
-	*phys_addr = mem->phys_base + ((phys_addr_t)pageno << page_shift);
+	page_shift = ilog2(mem->page_size);
+	*phys_addr = mem->window.phys_base +
+		     ((phys_addr_t)pageno << page_shift);
 	virt_addr = ioremap(*phys_addr, size);
 	if (!virt_addr)
 		bitmap_release_region(mem->bitmap, pageno, order);
@@ -143,6 +182,23 @@ void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
 }
 EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);
 
+struct pci_epc_mem *pci_epc_get_matching_window(struct pci_epc *epc,
+						phys_addr_t phys_addr)
+{
+	struct pci_epc_mem *mem;
+	int i;
+
+	for (i = 0; i < epc->mem_windows; i++) {
+		mem = epc->mem[i];
+
+		if (phys_addr >= mem->window.phys_base &&
+		    phys_addr < (mem->window.phys_base + mem->window.size))
+			return mem;
+	}
+
+	return NULL;
+}
+
 /**
  * pci_epc_mem_free_addr() - free the allocated memory address
  * @epc: the EPC device on which memory was allocated
@@ -155,13 +211,20 @@ EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);
 void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr,
 			   void __iomem *virt_addr, size_t size)
 {
+	struct pci_epc_mem *mem;
+	unsigned int page_shift;
 	int pageno;
-	struct pci_epc_mem *mem = epc->mem;
-	unsigned int page_shift = ilog2(mem->page_size);
 	int order;
 
+	mem = pci_epc_get_matching_window(epc, phys_addr);
+	if (!mem) {
+		pr_err("failed to get matching window\n");
+		return;
+	}
+
+	page_shift = ilog2(mem->page_size);
 	iounmap(virt_addr);
-	pageno = (phys_addr - mem->phys_base) >> page_shift;
+	pageno = (phys_addr - mem->window.phys_base) >> page_shift;
 	size = ALIGN(size, mem->page_size);
 	order = pci_epc_mem_get_order(mem, size);
 	bitmap_release_region(mem->bitmap, pageno, order);
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 56f1846..dde42e5 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -64,17 +64,29 @@ struct pci_epc_ops {
 	struct module *owner;
 };
 
+#define PCI_EPC_DEFAULT_WINDOW         0
+
+/**
+ * struct pci_epc_mem_window - address window of the endpoint controller
+ * @phys_base: physical base address of the PCI address window
+ * @size: the size of the PCI address window
+ * @page_size: size of each page
+ */
+struct pci_epc_mem_window {
+	phys_addr_t	phys_base;
+	size_t		size;
+	size_t		page_size;
+};
+
 /**
  * struct pci_epc_mem - address space of the endpoint controller
- * @phys_base: physical base address of the PCI address space
- * @size: the size of the PCI address space
+ * @window: address window of the endpoint controller
  * @bitmap: bitmap to manage the PCI address space
- * @pages: number of bits representing the address region
  * @page_size: size of each page
+ * @pages: number of bits representing the address region
  */
 struct pci_epc_mem {
-	phys_addr_t	phys_base;
-	size_t		size;
+	struct pci_epc_mem_window window;
 	unsigned long	*bitmap;
 	size_t		page_size;
 	int		pages;
@@ -85,7 +97,8 @@ struct pci_epc_mem {
  * @dev: PCI EPC device
  * @pci_epf: list of endpoint functions present in this EPC device
  * @ops: function pointers for performing endpoint operations
- * @mem: address space of the endpoint controller
+ * @mem: array of address space of the endpoint controller
+ * @mem_windows: number of windows supported by device
  * @max_functions: max number of functions that can be configured in this EPC
  * @group: configfs group representing the PCI EPC device
  * @lock: spinlock to protect pci_epc ops
@@ -94,7 +107,8 @@ struct pci_epc {
 	struct device			dev;
 	struct list_head		pci_epf;
 	const struct pci_epc_ops	*ops;
-	struct pci_epc_mem		*mem;
+	struct pci_epc_mem		**mem;
+	unsigned int			mem_windows;
 	u8				max_functions;
 	struct config_group		*group;
 	/* spinlock to protect against concurrent access of EP controller */
@@ -128,8 +142,8 @@ struct pci_epc_features {
 #define devm_pci_epc_create(dev, ops)    \
 		__devm_pci_epc_create((dev), (ops), THIS_MODULE)
 
-#define pci_epc_mem_init(epc, phys_addr, size)	\
-		__pci_epc_mem_init((epc), (phys_addr), (size), PAGE_SIZE)
+#define pci_epc_mem_init(epc, windows, num_windows)	\
+		__pci_epc_mem_init((epc), windows, num_windows)
 
 static inline void epc_set_drvdata(struct pci_epc *epc, void *data)
 {
@@ -159,8 +173,7 @@ int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
 void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,
 		       struct pci_epf_bar *epf_bar);
 int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
-		     phys_addr_t phys_addr,
-		     u64 pci_addr, size_t size);
+		     phys_addr_t phys_addr, u64 pci_addr, size_t size);
 void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
 			phys_addr_t phys_addr);
 int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts);
@@ -178,8 +191,8 @@ unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
 struct pci_epc *pci_epc_get(const char *epc_name);
 void pci_epc_put(struct pci_epc *epc);
 
-int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr, size_t size,
-		       size_t page_size);
+int __pci_epc_mem_init(struct pci_epc *epc, struct pci_epc_mem_window *window,
+		       int num_windows);
 void pci_epc_mem_exit(struct pci_epc *epc);
 void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
 				     phys_addr_t *phys_addr, size_t size);
-- 
2.7.4


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

* [PATCH v5 5/7] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller
  2020-02-28 15:41 [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
                   ` (3 preceding siblings ...)
  2020-02-28 15:41 ` [PATCH v5 4/7] PCI: endpoint: Add support to handle multiple base for mapping outbound memory Lad Prabhakar
@ 2020-02-28 15:41 ` Lad Prabhakar
  2020-03-17  8:26   ` Yoshihiro Shimoda
  2020-02-28 15:41 ` [PATCH v5 6/7] PCI: rcar: Add support for rcar PCIe controller in endpoint mode Lad Prabhakar
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 26+ messages in thread
From: Lad Prabhakar @ 2020-02-28 15:41 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Yoshihiro Shimoda, Shawn Lin, Heiko Stuebner
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Lad Prabhakar,
	Rob Herring

This patch adds the bindings for the R-Car PCIe endpoint driver.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/pci/rcar-pci-ep.yaml       | 76 ++++++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/rcar-pci-ep.yaml

diff --git a/Documentation/devicetree/bindings/pci/rcar-pci-ep.yaml b/Documentation/devicetree/bindings/pci/rcar-pci-ep.yaml
new file mode 100644
index 0000000..07cd5a7
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/rcar-pci-ep.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2020 Renesas Electronics Europe GmbH - https://www.renesas.com/eu/en/
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/rcar-pci-ep.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas R-Car PCIe Endpoint
+
+maintainers:
+  - Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+properties:
+  compatible:
+    items:
+      - const: renesas,r8a774c0-pcie-ep
+      - const: renesas,rcar-gen3-pcie-ep
+
+  reg:
+    maxItems: 5
+
+  reg-names:
+    items:
+      - const: apb-base
+      - const: memory0
+      - const: memory1
+      - const: memory2
+      - const: memory3
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: pcie
+
+  max-functions:
+    minimum: 1
+    maximum: 6
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - resets
+  - power-domains
+  - clocks
+  - clock-names
+  - max-functions
+
+examples:
+  - |
+    #include <dt-bindings/clock/r8a774c0-cpg-mssr.h>
+    #include <dt-bindings/power/r8a774c0-sysc.h>
+
+     pcie0_ep: pcie-ep@fe000000 {
+            compatible = "renesas,r8a774c0-pcie-ep",
+                         "renesas,rcar-gen3-pcie-ep";
+            reg = <0 0xfe000000 0 0x80000>,
+                  <0x0 0xfe100000 0 0x100000>,
+                  <0x0 0xfe200000 0 0x200000>,
+                  <0x0 0x30000000 0 0x8000000>,
+                  <0x0 0x38000000 0 0x8000000>;
+            reg-names = "apb-base", "memory0", "memory1", "memory2", "memory3";
+            resets = <&cpg 319>;
+            power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+            clocks = <&cpg CPG_MOD 319>;
+            clock-names = "pcie";
+            max-functions = /bits/ 8 <1>;
+    };
-- 
2.7.4


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

* [PATCH v5 6/7] PCI: rcar: Add support for rcar PCIe controller in endpoint mode
  2020-02-28 15:41 [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
                   ` (4 preceding siblings ...)
  2020-02-28 15:41 ` [PATCH v5 5/7] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller Lad Prabhakar
@ 2020-02-28 15:41 ` Lad Prabhakar
  2020-03-17  9:59   ` Yoshihiro Shimoda
  2020-02-28 15:41 ` [PATCH v5 7/7] misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller Lad Prabhakar
  2020-03-13 15:46 ` [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad, Prabhakar
  7 siblings, 1 reply; 26+ messages in thread
From: Lad Prabhakar @ 2020-02-28 15:41 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Yoshihiro Shimoda, Shawn Lin, Heiko Stuebner
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Lad Prabhakar

This patch adds support for rcar PCIe controller to work in endpoint mode.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
 drivers/pci/controller/Kconfig        |   8 +
 drivers/pci/controller/Makefile       |   1 +
 drivers/pci/controller/pcie-rcar-ep.c | 490 ++++++++++++++++++++++++++++++++++
 drivers/pci/controller/pcie-rcar.h    |   4 +
 4 files changed, 503 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-rcar-ep.c

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 37e0ea7..9bf4b02 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -62,6 +62,14 @@ config PCIE_RCAR_HOST
 	  Say Y here if you want PCIe controller support on R-Car SoCs in host
 	  mode.
 
+config PCIE_RCAR_EP
+	bool "Renesas R-Car PCIe endpoint controller"
+	depends on ARCH_RENESAS || COMPILE_TEST
+	depends on PCI_ENDPOINT
+	help
+	  Say Y here if you want PCIe controller support on R-Car SoCs in
+	  endpoint mode.
+
 config PCI_HOST_COMMON
 	bool
 	select PCI_ECAM
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index b4ada32..067bd33 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
 obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar.o pcie-rcar-host.o
+obj-$(CONFIG_PCIE_RCAR_EP) += pcie-rcar.o pcie-rcar-ep.o
 obj-$(CONFIG_PCI_HOST_COMMON) += pci-host-common.o
 obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
 obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c
new file mode 100644
index 0000000..db89bbe
--- /dev/null
+++ b/drivers/pci/controller/pcie-rcar-ep.c
@@ -0,0 +1,490 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe endpoint driver for Renesas R-Car SoCs
+ *  Copyright (c) 2020 Renesas Electronics Europe GmbH
+ *
+ * Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/pci.h>
+#include <linux/pci-epc.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+#include "pcie-rcar.h"
+
+/* Structure representing the PCIe interface */
+struct rcar_pcie {
+	phys_addr_t		*ob_addr;
+	struct pci_epc_mem_window *ob_window;
+	struct pci_epc		*epc;
+	struct device		*dev;
+	void __iomem		*base;
+	u8			max_functions;
+	unsigned int		bar_to_atu[MAX_NR_INBOUND_MAPS];
+	unsigned long		*ib_window_map;
+	u32			num_ib_windows;
+	u32			num_ob_windows;
+};
+
+static void rcar_pcie_ep_hw_init(struct rcar_pcie *pcie)
+{
+	u32 val;
+
+	rcar_pci_write_reg(pcie->base, 0, PCIETCTLR);
+
+	/* Set endpoint mode */
+	rcar_pci_write_reg(pcie->base, 0, PCIEMSR);
+
+	/* Initialize default capabilities. */
+	rcar_rmw32(pcie->base, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
+	rcar_rmw32(pcie->base, REXPCAP(PCI_EXP_FLAGS),
+		   PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ENDPOINT << 4);
+	rcar_rmw32(pcie->base, RCONF(PCI_HEADER_TYPE), 0x7f,
+		   PCI_HEADER_TYPE_NORMAL);
+
+	/* Write out the physical slot number = 0 */
+	rcar_rmw32(pcie->base, REXPCAP(PCI_EXP_SLTCAP), PCI_EXP_SLTCAP_PSN, 0);
+
+	val = rcar_pci_read_reg(pcie->base, EXPCAP(1));
+	/* device supports fixed 128 bytes MPSS */
+	val &= ~GENMASK(2, 0);
+	rcar_pci_write_reg(pcie->base, val, EXPCAP(1));
+
+	val = rcar_pci_read_reg(pcie->base, EXPCAP(2));
+	/* read requests size 128 bytes */
+	val &= ~GENMASK(14, 12);
+	/* payload size 128 bytes */
+	val &= ~GENMASK(7, 5);
+	rcar_pci_write_reg(pcie->base, val, EXPCAP(2));
+
+	/* Set target link speed to 5.0 GT/s */
+	rcar_rmw32(pcie->base, EXPCAP(12), PCI_EXP_LNKSTA_CLS,
+		   PCI_EXP_LNKSTA_CLS_5_0GB);
+
+	/* Set the completion timer timeout to the maximum 50ms. */
+	rcar_rmw32(pcie->base, TLCTLR + 1, 0x3f, 50);
+
+	/* Terminate list of capabilities (Next Capability Offset=0) */
+	rcar_rmw32(pcie->base, RVCCAP(0), 0xfff00000, 0);
+
+	/* flush modifications */
+	wmb();
+}
+
+static int rcar_pcie_ep_get_window(struct rcar_pcie *pcie, phys_addr_t addr)
+{
+	int i;
+
+	for (i = 0; i < pcie->num_ob_windows; i++)
+		if (pcie->ob_window[i].phys_base == addr)
+			return i;
+
+	return -EINVAL;
+}
+
+static int rcar_pcie_parse_outbound_ranges(struct rcar_pcie *pcie,
+					   struct platform_device *pdev)
+{
+	char outbound_name[10];
+	struct resource *res;
+	unsigned int i = 0;
+
+	pcie->num_ob_windows = 0;
+	for (i = 0; i < RCAR_PCI_MAX_RESOURCES; i++) {
+		sprintf(outbound_name, "memory%u", i);
+		res = platform_get_resource_byname(pdev,
+						   IORESOURCE_MEM,
+						   outbound_name);
+		if (!res) {
+			dev_err(pcie->dev, "missing outbound window %u\n", i);
+			return -EINVAL;
+		}
+		if (!devm_request_mem_region(&pdev->dev, res->start,
+					     resource_size(res),
+					     outbound_name)) {
+			dev_err(pcie->dev, "Cannot request memory region %s.\n",
+				outbound_name);
+			return -EIO;
+		}
+
+		pcie->ob_window[i].phys_base = res->start;
+		pcie->ob_window[i].size = resource_size(res);
+		/* controller doesn't support multiple allocation
+		 * from same window, so set page_size to window size
+		 */
+		pcie->ob_window[i].page_size = resource_size(res);
+	}
+	pcie->num_ob_windows = i;
+
+	return 0;
+}
+
+static int rcar_pcie_ep_get_pdata(struct rcar_pcie *pcie,
+				  struct platform_device *pdev)
+{
+	struct pci_epc_mem_window *window;
+	struct device *dev = pcie->dev;
+	struct resource res;
+	int err;
+
+	err = of_address_to_resource(dev->of_node, 0, &res);
+	if (err)
+		return err;
+	pcie->base = devm_ioremap_resource(dev, &res);
+	if (IS_ERR(pcie->base))
+		return PTR_ERR(pcie->base);
+
+	pcie->ob_window = devm_kcalloc(dev, RCAR_PCI_MAX_RESOURCES,
+				       sizeof(*window), GFP_KERNEL);
+	if (!pcie->ob_window)
+		return -ENOMEM;
+
+	rcar_pcie_parse_outbound_ranges(pcie, pdev);
+
+	err = of_property_read_u8(dev->of_node, "max-functions",
+				  &pcie->max_functions);
+	if (err < 0)
+		pcie->max_functions = 1;
+
+	return 0;
+}
+
+static int rcar_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
+				     struct pci_epf_header *hdr)
+{
+	struct rcar_pcie *ep = epc_get_drvdata(epc);
+	u32 val;
+
+	if (!fn)
+		val = hdr->vendorid;
+	else
+		val = rcar_pci_read_reg(ep->base, IDSETR0);
+	val |= hdr->deviceid << 16;
+	rcar_pci_write_reg(ep->base, val, IDSETR0);
+
+	val = hdr->revid;
+	val |= hdr->progif_code << 8;
+	val |= hdr->subclass_code << 16;
+	val |= hdr->baseclass_code << 24;
+	rcar_pci_write_reg(ep->base, val, IDSETR1);
+
+	if (!fn)
+		val = hdr->subsys_vendor_id;
+	else
+		val = rcar_pci_read_reg(ep->base, SUBIDSETR);
+	val |= hdr->subsys_id << 16;
+	rcar_pci_write_reg(ep->base, val, SUBIDSETR);
+
+	if (hdr->interrupt_pin > PCI_INTERRUPT_INTA)
+		return -EINVAL;
+	val = rcar_pci_read_reg(ep->base, PCICONF(15));
+	val |= (hdr->interrupt_pin << 8);
+	rcar_pci_write_reg(ep->base, val, PCICONF(15));
+
+	return 0;
+}
+
+static int rcar_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
+				struct pci_epf_bar *epf_bar)
+{
+	struct rcar_pcie *ep = epc_get_drvdata(epc);
+	dma_addr_t cpu_addr = epf_bar->phys_addr;
+	int flags = epf_bar->flags | LAR_ENABLE | LAM_64BIT;
+	enum pci_barno bar = epf_bar->barno;
+	u64 size = 1ULL << fls64(epf_bar->size - 1);
+	u32 mask;
+	int idx;
+	int err;
+
+	idx = find_first_zero_bit(ep->ib_window_map, ep->num_ib_windows);
+	if (idx >= ep->num_ib_windows) {
+		dev_err(ep->dev, "no free inbound window\n");
+		return -EINVAL;
+	}
+
+	if ((flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
+		flags |= IO_SPACE;
+
+	ep->bar_to_atu[bar] = idx;
+	/* use 64 bit bars */
+	set_bit(idx, ep->ib_window_map);
+	set_bit(idx + 1, ep->ib_window_map);
+
+	if (cpu_addr > 0) {
+		unsigned long nr_zeros = __ffs64(cpu_addr);
+		u64 alignment = 1ULL << nr_zeros;
+
+		size = min(size, alignment);
+	}
+
+	size = min(size, 1ULL << 32);
+
+	mask = roundup_pow_of_two(size) - 1;
+	mask &= ~0xf;
+
+	rcar_pcie_set_inbound(ep->base, cpu_addr,
+			      0x0, mask | flags, idx, false);
+
+	err = rcar_pcie_wait_for_phyrdy(ep->base);
+	if (err) {
+		dev_err(ep->dev, "phy not ready\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void rcar_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
+				   struct pci_epf_bar *epf_bar)
+{
+	struct rcar_pcie *ep = epc_get_drvdata(epc);
+	enum pci_barno bar = epf_bar->barno;
+	u32 atu_index = ep->bar_to_atu[bar];
+
+	rcar_pcie_set_inbound(ep->base, 0x0, 0x0, 0x0, bar, false);
+
+	clear_bit(atu_index, ep->ib_window_map);
+	clear_bit(atu_index + 1, ep->ib_window_map);
+}
+
+static int rcar_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
+				 phys_addr_t addr, u64 pci_addr, size_t size)
+{
+	struct rcar_pcie *ep = epc_get_drvdata(epc);
+	struct resource res;
+	int window;
+	int err;
+
+	/* check if we have a link. */
+	err = rcar_pcie_wait_for_dl(ep->base);
+	if (err) {
+		dev_err(ep->dev, "link not up\n");
+		return err;
+	}
+
+	window = rcar_pcie_ep_get_window(ep, addr);
+	if (window < 0) {
+		dev_err(ep->dev, "failed to get corresponding window\n");
+		return -EINVAL;
+	}
+
+	memset(&res, 0x0, sizeof(res));
+	res.start = pci_addr;
+	res.end = pci_addr + size - 1;
+	res.flags = IORESOURCE_MEM;
+
+	rcar_pcie_set_outbound(window, ep->base, &res);
+
+	ep->ob_addr[window] = addr;
+
+	return 0;
+}
+
+static void rcar_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
+				    phys_addr_t addr)
+{
+	struct rcar_pcie *ep = epc_get_drvdata(epc);
+	struct resource res;
+	int idx;
+
+	for (idx = 0; idx < ep->num_ob_windows; idx++)
+		if (ep->ob_addr[idx] == addr)
+			break;
+
+	if (idx >= ep->num_ob_windows)
+		return;
+
+	memset(&res, 0x0, sizeof(res));
+	rcar_pcie_set_outbound(idx, ep->base, &res);
+
+	ep->ob_addr[idx] = 0;
+}
+
+static int rcar_pcie_ep_assert_intx(struct rcar_pcie *ep, u8 fn, u8 intx)
+{
+	u32 val;
+
+	val = rcar_pci_read_reg(ep->base, PCIEMSITXR);
+	if ((val & PCI_MSI_FLAGS_ENABLE)) {
+		dev_err(ep->dev, "MSI is enabled, cannot assert INTx\n");
+		return -EINVAL;
+	}
+
+	val = rcar_pci_read_reg(ep->base, PCICONF(1));
+	if ((val & INTDIS_SHIFT)) {
+		dev_err(ep->dev, "INTx message transmission is disabled\n");
+		return -EINVAL;
+	}
+
+	val = rcar_pci_read_reg(ep->base, PCIEINTXR);
+	if ((val & ASTINTX_SHIFT)) {
+		dev_err(ep->dev, "INTx is already asserted\n");
+		return -EINVAL;
+	}
+
+	val |= ASTINTX_SHIFT;
+	rcar_pci_write_reg(ep->base, val, PCIEINTXR);
+	mdelay(1);
+	val = rcar_pci_read_reg(ep->base, PCIEINTXR);
+	val &= ~ASTINTX_SHIFT;
+	rcar_pci_write_reg(ep->base, val, PCIEINTXR);
+
+	return 0;
+}
+
+static int rcar_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
+				  enum pci_epc_irq_type type,
+				  u16 interrupt_num)
+{
+	struct rcar_pcie *ep = epc_get_drvdata(epc);
+
+	switch (type) {
+	case PCI_EPC_IRQ_LEGACY:
+		return rcar_pcie_ep_assert_intx(ep, fn, 0);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int rcar_pcie_ep_start(struct pci_epc *epc)
+{
+	struct rcar_pcie *ep = epc_get_drvdata(epc);
+
+	rcar_pci_write_reg(ep->base, CFINIT, PCIETCTLR);
+
+	return 0;
+}
+
+static void rcar_pcie_ep_stop(struct pci_epc *epc)
+{
+	struct rcar_pcie *ep = epc_get_drvdata(epc);
+
+	rcar_pci_write_reg(ep->base, 0, PCIETCTLR);
+}
+
+static const struct pci_epc_features rcar_pcie_epc_features = {
+	.linkup_notifier = false,
+	.msi_capable = false,
+	.msix_capable = false,
+	/* use 64-bit bars so mark bar1/3/5 as reserved */
+	.reserved_bar = 1 << BAR_1 | 1 << BAR_3 | 1 << BAR_5,
+	.bar_fixed_64bit =  (1 << BAR_0) | (1 << BAR_2) | (1 << BAR_4),
+	.bar_fixed_size[0] = 128,
+	.bar_fixed_size[2] = 256,
+	.bar_fixed_size[4] = 256,
+};
+
+static const struct pci_epc_features*
+rcar_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+{
+	return &rcar_pcie_epc_features;
+}
+
+static const struct pci_epc_ops rcar_pcie_epc_ops = {
+	.write_header	= rcar_pcie_ep_write_header,
+	.set_bar	= rcar_pcie_ep_set_bar,
+	.clear_bar	= rcar_pcie_ep_clear_bar,
+	.map_addr	= rcar_pcie_ep_map_addr,
+	.unmap_addr	= rcar_pcie_ep_unmap_addr,
+	.raise_irq	= rcar_pcie_ep_raise_irq,
+	.start		= rcar_pcie_ep_start,
+	.stop		= rcar_pcie_ep_stop,
+	.get_features	= rcar_pcie_ep_get_features,
+};
+
+static const struct of_device_id rcar_pcie_ep_of_match[] = {
+	{ .compatible = "renesas,r8a774c0-pcie-ep", },
+	{ .compatible = "renesas,rcar-gen3-pcie-ep" },
+	{ },
+};
+
+static int rcar_pcie_ep_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rcar_pcie *pcie;
+	struct pci_epc *epc;
+	int err;
+
+	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	pcie->dev = dev;
+
+	pm_runtime_enable(pcie->dev);
+	err = pm_runtime_get_sync(pcie->dev);
+	if (err < 0) {
+		dev_err(pcie->dev, "pm_runtime_get_sync failed\n");
+		goto err_pm_disable;
+	}
+
+	err = rcar_pcie_ep_get_pdata(pcie, pdev);
+	if (err < 0) {
+		dev_err(dev, "failed to request resources: %d\n", err);
+		goto err_pm_put;
+	}
+
+	pcie->num_ib_windows = MAX_NR_INBOUND_MAPS;
+	pcie->ib_window_map =
+			devm_kcalloc(dev, BITS_TO_LONGS(pcie->num_ib_windows),
+				     sizeof(long), GFP_KERNEL);
+	if (!pcie->ib_window_map) {
+		err = -ENOMEM;
+		dev_err(dev, "failed to allocate memory for inbound map\n");
+		goto err_pm_put;
+	}
+
+	pcie->ob_addr = devm_kcalloc(dev, pcie->num_ob_windows,
+				     sizeof(*pcie->ob_addr), GFP_KERNEL);
+	if (!pcie->ob_addr) {
+		err = -ENOMEM;
+		dev_err(dev, "failed to allocate memory for outbound memory pointers\n");
+		goto err_pm_put;
+	}
+
+	epc = devm_pci_epc_create(dev, &rcar_pcie_epc_ops);
+	if (IS_ERR(epc)) {
+		dev_err(dev, "failed to create epc device\n");
+		err = PTR_ERR(epc);
+		goto err_pm_put;
+	}
+
+	epc->max_functions = pcie->max_functions;
+	pcie->epc = epc;
+	epc_set_drvdata(epc, pcie);
+
+	err = pci_epc_mem_init(epc, pcie->ob_window, pcie->num_ob_windows);
+	if (err < 0) {
+		dev_err(dev, "failed to initialize the epc memory space\n");
+		goto err_pm_put;
+	}
+
+	rcar_pcie_ep_hw_init(pcie);
+
+	return 0;
+
+err_pm_put:
+	pm_runtime_put(dev);
+
+err_pm_disable:
+	pm_runtime_disable(dev);
+
+	return err;
+}
+
+static struct platform_driver rcar_pcie_ep_driver = {
+	.driver = {
+		.name = "rcar-pcie-ep",
+		.of_match_table = rcar_pcie_ep_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = rcar_pcie_ep_probe,
+};
+builtin_platform_driver(rcar_pcie_ep_driver);
diff --git a/drivers/pci/controller/pcie-rcar.h b/drivers/pci/controller/pcie-rcar.h
index b529d806..5564ca8 100644
--- a/drivers/pci/controller/pcie-rcar.h
+++ b/drivers/pci/controller/pcie-rcar.h
@@ -17,6 +17,7 @@
 #define PCIECDR			0x000020
 #define PCIEMSR			0x000028
 #define PCIEINTXR		0x000400
+#define  ASTINTX_SHIFT		BIT(16)
 #define PCIEPHYSR		0x0007f0
 #define  PHYRDY			BIT(0)
 #define PCIEMSITXR		0x000840
@@ -55,12 +56,15 @@
 
 /* Configuration */
 #define PCICONF(x)		(0x010000 + ((x) * 0x4))
+#define  INTDIS_SHIFT		BIT(10)
 #define PMCAP(x)		(0x010040 + ((x) * 0x4))
 #define EXPCAP(x)		(0x010070 + ((x) * 0x4))
 #define VCCAP(x)		(0x010100 + ((x) * 0x4))
 
 /* link layer */
+#define IDSETR0			0x011000
 #define IDSETR1			0x011004
+#define SUBIDSETR		0x011024
 #define TLCTLR			0x011048
 #define MACSR			0x011054
 #define  SPCHGFIN		BIT(4)
-- 
2.7.4


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

* [PATCH v5 7/7] misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller
  2020-02-28 15:41 [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
                   ` (5 preceding siblings ...)
  2020-02-28 15:41 ` [PATCH v5 6/7] PCI: rcar: Add support for rcar PCIe controller in endpoint mode Lad Prabhakar
@ 2020-02-28 15:41 ` Lad Prabhakar
  2020-03-17 10:31   ` Yoshihiro Shimoda
  2020-03-13 15:46 ` [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad, Prabhakar
  7 siblings, 1 reply; 26+ messages in thread
From: Lad Prabhakar @ 2020-02-28 15:41 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Yoshihiro Shimoda, Shawn Lin, Heiko Stuebner
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Lad Prabhakar

Add RZ/G2E in pci_device_id table so that pci-epf-test can be used for
testing PCIe EP in RZ/G2E.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
 drivers/misc/pci_endpoint_test.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index a5e3170..3c84e9a 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -66,6 +66,8 @@
 
 #define PCI_DEVICE_ID_TI_AM654			0xb00c
 
+#define PCI_DEVICE_ID_RENESAS_RZG2E		0x002d
+
 #define is_am654_pci_dev(pdev)		\
 		((pdev)->device == PCI_DEVICE_ID_TI_AM654)
 
@@ -797,6 +799,7 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),
 	  .driver_data = (kernel_ulong_t)&am654_data
 	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_RZG2E) },
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
-- 
2.7.4


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

* Re: [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs
  2020-02-28 15:41 [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
                   ` (6 preceding siblings ...)
  2020-02-28 15:41 ` [PATCH v5 7/7] misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller Lad Prabhakar
@ 2020-03-13 15:46 ` Lad, Prabhakar
  2020-03-16 12:18   ` Lorenzo Pieralisi
  7 siblings, 1 reply; 26+ messages in thread
From: Lad, Prabhakar @ 2020-03-13 15:46 UTC (permalink / raw)
  To: Bjorn Helgaas, Kishon Vijay Abraham I, Yoshihiro Shimoda
  Cc: Andrew Murray, linux-pci, LAK, Rob Herring, Linux-Renesas,
	open list:ARM/Rockchip SoC...,
	LKML, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Lorenzo Pieralisi, Marek Vasut, Gustavo Pimentel, Heiko Stuebner,
	Will Deacon, Catalin Marinas, Mark Rutland, Lad Prabhakar,
	Shawn Lin, Jingoo Han, Greg Kroah-Hartman, Arnd Bergmann

Hi Bjorn/Kishon,

On Fri, Feb 28, 2020 at 3:41 PM Lad Prabhakar
<prabhakar.csengg@gmail.com> wrote:
>
> This patch series adds support for PCIe controller on rcar to work in
> endpoint mode, this also extends the epf framework to handle base region
> for mapping PCI address locally.
>
> Note:
> The cadence/rockchip/designware endpoint drivers are build tested only.
>
> Changes for v5:
> 1] Rebased the patches on next branch of https://git.kernel.org/pub/scm/
>    linux/kernel/git/helgaas/pci.git
> 2] Fixed review comments reported by Kishon while fetching the matching
>    window in function pci_epc_get_matching_window()
> 3] Fixed review comments reported by Bjorn
>    a] Split patch up first patch so that its easier to review and incremental
>    b] Fixed typos
> 4] Included Reviewed tag from Rob for the dt-binding patch
> 5] Fixed issue reported by Nathan for assigning variable to itself
>
> Changes for v4:
> 1] Fixed dtb_check error reported by Rob
> 2] Fixed review comments reported by Kishon
>    a] Dropped pci_epc_find_best_fit_window()
>    b] Fixed initializing mem ptr in __pci_epc_mem_init()
>    c] Dropped map_size from pci_epc_mem_window structure
>
> Changes for v3:
> 1] Fixed review comments from Bjorn and Kishon.
> 3] Converted to DT schema
>
> Changes for v2:
> 1] Fixed review comments from Biju for dt-bindings to include an example
>    for a tested platform.
> 2] Fixed review comments from Kishon to extend the features of outbound
>    regions in epf framework.
> 3] Added support to parse outbound-ranges in OF.
>
> Lad Prabhakar (7):
>   PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c
>   PCI: rcar: Move shareable code to a common file
>   PCI: rcar: Fix calculating mask for PCIEPAMR register
>   PCI: endpoint: Add support to handle multiple base for mapping
>     outbound memory
>   dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint
>     controller
>   PCI: rcar: Add support for rcar PCIe controller in endpoint mode
>   misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller
>
Gentle ping.

Cheers,
--Prabhakar Lad

>  .../devicetree/bindings/pci/rcar-pci-ep.yaml       |   76 ++
>  arch/arm64/configs/defconfig                       |    2 +-
>  drivers/misc/pci_endpoint_test.c                   |    3 +
>  drivers/pci/controller/Kconfig                     |   15 +-
>  drivers/pci/controller/Makefile                    |    3 +-
>  drivers/pci/controller/cadence/pcie-cadence-ep.c   |    7 +-
>  drivers/pci/controller/dwc/pcie-designware-ep.c    |   29 +-
>  drivers/pci/controller/pcie-rcar-ep.c              |  490 ++++++++
>  drivers/pci/controller/pcie-rcar-host.c            | 1053 +++++++++++++++++
>  drivers/pci/controller/pcie-rcar.c                 | 1229 +-------------------
>  drivers/pci/controller/pcie-rcar.h                 |  129 ++
>  drivers/pci/controller/pcie-rockchip-ep.c          |    7 +-
>  drivers/pci/endpoint/pci-epc-mem.c                 |  167 ++-
>  include/linux/pci-epc.h                            |   39 +-
>  14 files changed, 1985 insertions(+), 1264 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pci/rcar-pci-ep.yaml
>  create mode 100644 drivers/pci/controller/pcie-rcar-ep.c
>  create mode 100644 drivers/pci/controller/pcie-rcar-host.c
>  create mode 100644 drivers/pci/controller/pcie-rcar.h
>
> --
> 2.7.4
>

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

* Re: [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs
  2020-03-13 15:46 ` [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad, Prabhakar
@ 2020-03-16 12:18   ` Lorenzo Pieralisi
  2020-03-16 12:33     ` Lad, Prabhakar
  0 siblings, 1 reply; 26+ messages in thread
From: Lorenzo Pieralisi @ 2020-03-16 12:18 UTC (permalink / raw)
  To: Lad, Prabhakar
  Cc: Bjorn Helgaas, Kishon Vijay Abraham I, Yoshihiro Shimoda,
	Andrew Murray, linux-pci, LAK, Rob Herring, Linux-Renesas,
	open list:ARM/Rockchip SoC...,
	LKML, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Marek Vasut, Gustavo Pimentel, Heiko Stuebner, Will Deacon,
	Catalin Marinas, Mark Rutland, Lad Prabhakar, Shawn Lin,
	Jingoo Han, Greg Kroah-Hartman, Arnd Bergmann

On Fri, Mar 13, 2020 at 03:46:42PM +0000, Lad, Prabhakar wrote:
> Hi Bjorn/Kishon,
> 
> On Fri, Feb 28, 2020 at 3:41 PM Lad Prabhakar
> <prabhakar.csengg@gmail.com> wrote:
> >
> > This patch series adds support for PCIe controller on rcar to work in
> > endpoint mode, this also extends the epf framework to handle base region
> > for mapping PCI address locally.
> >
> > Note:
> > The cadence/rockchip/designware endpoint drivers are build tested only.
> >
> > Changes for v5:
> > 1] Rebased the patches on next branch of https://git.kernel.org/pub/scm/
> >    linux/kernel/git/helgaas/pci.git
> > 2] Fixed review comments reported by Kishon while fetching the matching
> >    window in function pci_epc_get_matching_window()
> > 3] Fixed review comments reported by Bjorn
> >    a] Split patch up first patch so that its easier to review and incremental
> >    b] Fixed typos
> > 4] Included Reviewed tag from Rob for the dt-binding patch
> > 5] Fixed issue reported by Nathan for assigning variable to itself
> >
> > Changes for v4:
> > 1] Fixed dtb_check error reported by Rob
> > 2] Fixed review comments reported by Kishon
> >    a] Dropped pci_epc_find_best_fit_window()
> >    b] Fixed initializing mem ptr in __pci_epc_mem_init()
> >    c] Dropped map_size from pci_epc_mem_window structure
> >
> > Changes for v3:
> > 1] Fixed review comments from Bjorn and Kishon.
> > 3] Converted to DT schema
> >
> > Changes for v2:
> > 1] Fixed review comments from Biju for dt-bindings to include an example
> >    for a tested platform.
> > 2] Fixed review comments from Kishon to extend the features of outbound
> >    regions in epf framework.
> > 3] Added support to parse outbound-ranges in OF.
> >
> > Lad Prabhakar (7):
> >   PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c
> >   PCI: rcar: Move shareable code to a common file
> >   PCI: rcar: Fix calculating mask for PCIEPAMR register
> >   PCI: endpoint: Add support to handle multiple base for mapping
> >     outbound memory
> >   dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint
> >     controller
> >   PCI: rcar: Add support for rcar PCIe controller in endpoint mode
> >   misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller
> >
> Gentle ping.

You should ask the R-CAR maintainers first to have a look at your
code and ACK accordingly.

Lorenzo

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

* Re: [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs
  2020-03-16 12:18   ` Lorenzo Pieralisi
@ 2020-03-16 12:33     ` Lad, Prabhakar
  0 siblings, 0 replies; 26+ messages in thread
From: Lad, Prabhakar @ 2020-03-16 12:33 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Bjorn Helgaas, Kishon Vijay Abraham I, Yoshihiro Shimoda,
	Andrew Murray, linux-pci, LAK, Rob Herring, Linux-Renesas,
	open list:ARM/Rockchip SoC...,
	LKML, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Marek Vasut, Gustavo Pimentel, Heiko Stuebner, Will Deacon,
	Catalin Marinas, Mark Rutland, Lad Prabhakar, Shawn Lin,
	Jingoo Han, Greg Kroah-Hartman, Arnd Bergmann

Hi Lorenzo,

On Mon, Mar 16, 2020 at 12:19 PM Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
>
> On Fri, Mar 13, 2020 at 03:46:42PM +0000, Lad, Prabhakar wrote:
> > Hi Bjorn/Kishon,
> >
> > On Fri, Feb 28, 2020 at 3:41 PM Lad Prabhakar
> > <prabhakar.csengg@gmail.com> wrote:
> > >
> > > This patch series adds support for PCIe controller on rcar to work in
> > > endpoint mode, this also extends the epf framework to handle base region
> > > for mapping PCI address locally.
> > >
> > > Note:
> > > The cadence/rockchip/designware endpoint drivers are build tested only.
> > >
> > > Changes for v5:
> > > 1] Rebased the patches on next branch of https://git.kernel.org/pub/scm/
> > >    linux/kernel/git/helgaas/pci.git
> > > 2] Fixed review comments reported by Kishon while fetching the matching
> > >    window in function pci_epc_get_matching_window()
> > > 3] Fixed review comments reported by Bjorn
> > >    a] Split patch up first patch so that its easier to review and incremental
> > >    b] Fixed typos
> > > 4] Included Reviewed tag from Rob for the dt-binding patch
> > > 5] Fixed issue reported by Nathan for assigning variable to itself
> > >
> > > Changes for v4:
> > > 1] Fixed dtb_check error reported by Rob
> > > 2] Fixed review comments reported by Kishon
> > >    a] Dropped pci_epc_find_best_fit_window()
> > >    b] Fixed initializing mem ptr in __pci_epc_mem_init()
> > >    c] Dropped map_size from pci_epc_mem_window structure
> > >
> > > Changes for v3:
> > > 1] Fixed review comments from Bjorn and Kishon.
> > > 3] Converted to DT schema
> > >
> > > Changes for v2:
> > > 1] Fixed review comments from Biju for dt-bindings to include an example
> > >    for a tested platform.
> > > 2] Fixed review comments from Kishon to extend the features of outbound
> > >    regions in epf framework.
> > > 3] Added support to parse outbound-ranges in OF.
> > >
> > > Lad Prabhakar (7):
> > >   PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c
> > >   PCI: rcar: Move shareable code to a common file
> > >   PCI: rcar: Fix calculating mask for PCIEPAMR register
> > >   PCI: endpoint: Add support to handle multiple base for mapping
> > >     outbound memory
> > >   dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint
> > >     controller
> > >   PCI: rcar: Add support for rcar PCIe controller in endpoint mode
> > >   misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller
> > >
> > Gentle ping.
>
> You should ask the R-CAR maintainers first to have a look at your
> code and ACK accordingly.
>
Thanks I have pinged the R-CAR maintainers to do the needy.

Cheers,
--Prabhakar

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

* RE: [PATCH v5 1/7] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c
  2020-02-28 15:41 ` [PATCH v5 1/7] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c Lad Prabhakar
@ 2020-03-17  6:59   ` Yoshihiro Shimoda
  2020-03-17  8:26     ` Prabhakar Mahadev Lad
  0 siblings, 1 reply; 26+ messages in thread
From: Yoshihiro Shimoda @ 2020-03-17  6:59 UTC (permalink / raw)
  To: Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Bjorn Helgaas,
	Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
	Kishon Vijay Abraham I, Lorenzo Pieralisi, Arnd Bergmann,
	Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel, Marek Vasut,
	Shawn Lin, Heiko Stuebner, Prabhakar Mahadev Lad

Hi Prabhakar-san,

Thank you for the patch!

> From: Lad Prabhakar, Sent: Saturday, February 29, 2020 12:41 AM

Since your email account is different with the Singed-off-by,
I think you should add your From: tag here like your v2 patch series.

> This commit renames pcie-rcar.c to pcie-rcar-host.c in preparation for
> adding support for endpoint mode. CONFIG_PCIE_RCAR is also renamed to
> CONFIG_PCIE_RCAR_HOST to match the driver name accordingly.
> 
> In addition to this defconfig file has also been updated to match the new
> config option.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> ---
>  arch/arm64/configs/defconfig                             | 2 +-
>  drivers/pci/controller/Kconfig                           | 7 ++++---
>  drivers/pci/controller/Makefile                          | 2 +-
>  drivers/pci/controller/{pcie-rcar.c => pcie-rcar-host.c} | 0
>  4 files changed, 6 insertions(+), 5 deletions(-)
>  rename drivers/pci/controller/{pcie-rcar.c => pcie-rcar-host.c} (100%)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 0f21288..7a34fce 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -185,7 +185,7 @@ CONFIG_HOTPLUG_PCI=y
>  CONFIG_HOTPLUG_PCI_ACPI=y
>  CONFIG_PCI_AARDVARK=y
>  CONFIG_PCI_TEGRA=y
> -CONFIG_PCIE_RCAR=y
> +CONFIG_PCIE_RCAR_HOST=y

I think you should separate this change.
To avoid this, I have an idea in the Kconfig like below:
 - adding PCIE_RCAR_HOST.
 - keeping PCIE_RCAR and select PCIE_RCAR_HOST here.
 - adding a description in the help of PCIE_RCAR like "This will be removed after defconfig is updated" is better.

The following is a sample. What do you think?
---
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -58,8 +58,18 @@ config PCIE_RCAR
 	bool "Renesas R-Car PCIe controller"
 	depends on ARCH_RENESAS || COMPILE_TEST
 	depends on PCI_MSI_IRQ_DOMAIN
+	select PCIE_RCAR_HOST
 	help
 	  Say Y here if you want PCIe controller support on R-Car SoCs.
+	  This will be removed after defconfig is updated.
+
+config PCIE_RCAR_HOST
+	bool "Renesas R-Car PCIe host controller"
+	depends on ARCH_RENESAS || COMPILE_TEST
+	depends on PCI_MSI_IRQ_DOMAIN
+	help
+	  Say Y here if you want PCIe controller support on R-Car SoCs in host
+	  mode.
 
 config PCI_HOST_COMMON
 	bool
---

Best regards,
Yoshihiro Shimoda

>  CONFIG_PCI_HOST_GENERIC=y
>  CONFIG_PCI_XGENE=y
>  CONFIG_PCIE_ALTERA=y
> diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
> index f84e5ff..37e0ea7 100644
> --- a/drivers/pci/controller/Kconfig
> +++ b/drivers/pci/controller/Kconfig
> @@ -54,12 +54,13 @@ config PCI_RCAR_GEN2
>  	  There are 3 internal PCI controllers available with a single
>  	  built-in EHCI/OHCI host controller present on each one.
> 
> -config PCIE_RCAR
> -	bool "Renesas R-Car PCIe controller"
> +config PCIE_RCAR_HOST
> +	bool "Renesas R-Car PCIe host controller"
>  	depends on ARCH_RENESAS || COMPILE_TEST
>  	depends on PCI_MSI_IRQ_DOMAIN
>  	help
> -	  Say Y here if you want PCIe controller support on R-Car SoCs.
> +	  Say Y here if you want PCIe controller support on R-Car SoCs in host
> +	  mode.
> 
>  config PCI_HOST_COMMON
>  	bool
> diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
> index 01b2502..4ca2da6 100644
> --- a/drivers/pci/controller/Makefile
> +++ b/drivers/pci/controller/Makefile
> @@ -7,7 +7,7 @@ obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
>  obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
>  obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
>  obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
> -obj-$(CONFIG_PCIE_RCAR) += pcie-rcar.o
> +obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar-host.o
>  obj-$(CONFIG_PCI_HOST_COMMON) += pci-host-common.o
>  obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
>  obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
> diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar-host.c
> similarity index 100%
> rename from drivers/pci/controller/pcie-rcar.c
> rename to drivers/pci/controller/pcie-rcar-host.c
> --
> 2.7.4


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

* RE: [PATCH v5 2/7] PCI: rcar: Move shareable code to a common file
  2020-02-28 15:41 ` [PATCH v5 2/7] PCI: rcar: Move shareable code to a common file Lad Prabhakar
@ 2020-03-17  7:23   ` Yoshihiro Shimoda
  2020-03-17  8:29     ` Prabhakar Mahadev Lad
  0 siblings, 1 reply; 26+ messages in thread
From: Yoshihiro Shimoda @ 2020-03-17  7:23 UTC (permalink / raw)
  To: Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Prabhakar Mahadev Lad,
	Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Shawn Lin, Heiko Stuebner

Hi Prabhakar-san,

Thank you for the patch!

> From: Lad Prabhakar, Sent: Saturday, February 29, 2020 12:41 AM
> 
> This patch moves sharable code to common file pcie-rcar.c and the #defines
> to pcie-rcar.h so that the common code can be reused with endpoint driver.
> There are no functional changes with this patch for the host controller
> driver.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> ---
>  drivers/pci/controller/Makefile         |   2 +-
>  drivers/pci/controller/pcie-rcar-host.c | 358 ++++++++------------------------
>  drivers/pci/controller/pcie-rcar.c      | 117 +++++++++++
>  drivers/pci/controller/pcie-rcar.h      | 125 +++++++++++
>  4 files changed, 324 insertions(+), 278 deletions(-)
>  create mode 100644 drivers/pci/controller/pcie-rcar.c
>  create mode 100644 drivers/pci/controller/pcie-rcar.h
> 
> diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
> index 4ca2da6..b4ada32 100644
> --- a/drivers/pci/controller/Makefile
> +++ b/drivers/pci/controller/Makefile
> @@ -7,7 +7,7 @@ obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
>  obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
>  obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
>  obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
> -obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar-host.o
> +obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar.o pcie-rcar-host.o
>  obj-$(CONFIG_PCI_HOST_COMMON) += pci-host-common.o
>  obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
>  obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
> diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c
> index 759c654..93f22d8 100644
> --- a/drivers/pci/controller/pcie-rcar-host.c
> +++ b/drivers/pci/controller/pcie-rcar-host.c
> @@ -1,7 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0
>  /*
>   * PCIe driver for Renesas R-Car SoCs
> - *  Copyright (C) 2014 Renesas Electronics Europe Ltd
> + *  Copyright (C) 2014-2020 Renesas Electronics Europe Ltd
>   *
>   * Based on:
>   *  arch/sh/drivers/pci/pcie-sh7786.c
> @@ -30,104 +30,7 @@
>  #include <linux/pm_runtime.h>
>  #include <linux/slab.h>
> 
> -#define PCIECAR			0x000010
> -#define PCIECCTLR		0x000018
> -#define  CONFIG_SEND_ENABLE	BIT(31)
> -#define  TYPE0			(0 << 8)
> -#define  TYPE1			BIT(8)
> -#define PCIECDR			0x000020
> -#define PCIEMSR			0x000028
> -#define PCIEINTXR		0x000400
> -#define PCIEPHYSR		0x0007f0
> -#define  PHYRDY			BIT(0)
> -#define PCIEMSITXR		0x000840
> -
> -/* Transfer control */
> -#define PCIETCTLR		0x02000
> -#define  DL_DOWN		BIT(3)
> -#define  CFINIT			BIT(0)
> -#define PCIETSTR		0x02004
> -#define  DATA_LINK_ACTIVE	BIT(0)
> -#define PCIEERRFR		0x02020
> -#define  UNSUPPORTED_REQUEST	BIT(4)
> -#define PCIEMSIFR		0x02044
> -#define PCIEMSIALR		0x02048
> -#define  MSIFE			BIT(0)
> -#define PCIEMSIAUR		0x0204c
> -#define PCIEMSIIER		0x02050
> -
> -/* root port address */
> -#define PCIEPRAR(x)		(0x02080 + ((x) * 0x4))
> -
> -/* local address reg & mask */
> -#define PCIELAR(x)		(0x02200 + ((x) * 0x20))
> -#define PCIELAMR(x)		(0x02208 + ((x) * 0x20))
> -#define  LAM_PREFETCH		BIT(3)
> -#define  LAM_64BIT		BIT(2)
> -#define  LAR_ENABLE		BIT(1)
> -
> -/* PCIe address reg & mask */
> -#define PCIEPALR(x)		(0x03400 + ((x) * 0x20))
> -#define PCIEPAUR(x)		(0x03404 + ((x) * 0x20))
> -#define PCIEPAMR(x)		(0x03408 + ((x) * 0x20))
> -#define PCIEPTCTLR(x)		(0x0340c + ((x) * 0x20))
> -#define  PAR_ENABLE		BIT(31)
> -#define  IO_SPACE		BIT(8)
> -
> -/* Configuration */
> -#define PCICONF(x)		(0x010000 + ((x) * 0x4))
> -#define PMCAP(x)		(0x010040 + ((x) * 0x4))
> -#define EXPCAP(x)		(0x010070 + ((x) * 0x4))
> -#define VCCAP(x)		(0x010100 + ((x) * 0x4))
> -
> -/* link layer */
> -#define IDSETR1			0x011004
> -#define TLCTLR			0x011048
> -#define MACSR			0x011054
> -#define  SPCHGFIN		BIT(4)
> -#define  SPCHGFAIL		BIT(6)
> -#define  SPCHGSUC		BIT(7)
> -#define  LINK_SPEED		(0xf << 16)
> -#define  LINK_SPEED_2_5GTS	(1 << 16)
> -#define  LINK_SPEED_5_0GTS	(2 << 16)
> -#define MACCTLR			0x011058
> -#define  MACCTLR_NFTS_MASK	GENMASK(23, 16)	/* The name is from SH7786 */
> -#define  SPEED_CHANGE		BIT(24)
> -#define  SCRAMBLE_DISABLE	BIT(27)
> -#define  LTSMDIS		BIT(31)
> -#define  MACCTLR_INIT_VAL	(LTSMDIS | MACCTLR_NFTS_MASK)
> -#define PMSR			0x01105c
> -#define MACS2R			0x011078
> -#define MACCGSPSETR		0x011084
> -#define  SPCNGRSN		BIT(31)
> -
> -/* R-Car H1 PHY */
> -#define H1_PCIEPHYADRR		0x04000c
> -#define  WRITE_CMD		BIT(16)
> -#define  PHY_ACK		BIT(24)
> -#define  RATE_POS		12
> -#define  LANE_POS		8
> -#define  ADR_POS		0
> -#define H1_PCIEPHYDOUTR		0x040014
> -
> -/* R-Car Gen2 PHY */
> -#define GEN2_PCIEPHYADDR	0x780
> -#define GEN2_PCIEPHYDATA	0x784
> -#define GEN2_PCIEPHYCTRL	0x78c
> -
> -#define INT_PCI_MSI_NR		32
> -
> -#define RCONF(x)		(PCICONF(0) + (x))
> -#define RPMCAP(x)		(PMCAP(0) + (x))
> -#define REXPCAP(x)		(EXPCAP(0) + (x))
> -#define RVCCAP(x)		(VCCAP(0) + (x))
> -
> -#define PCIE_CONF_BUS(b)	(((b) & 0xff) << 24)
> -#define PCIE_CONF_DEV(d)	(((d) & 0x1f) << 19)
> -#define PCIE_CONF_FUNC(f)	(((f) & 0x7) << 16)
> -
> -#define RCAR_PCI_MAX_RESOURCES	4
> -#define MAX_NR_INBOUND_MAPS	6
> +#include "pcie-rcar.h"
> 
>  struct rcar_msi {
>  	DECLARE_BITMAP(used, INT_PCI_MSI_NR);
> @@ -155,36 +58,10 @@ struct rcar_pcie {
>  	struct			rcar_msi msi;
>  };
> 
> -static void rcar_pci_write_reg(struct rcar_pcie *pcie, u32 val,
> -			       unsigned int reg)
> -{
> -	writel(val, pcie->base + reg);
> -}
> -
> -static u32 rcar_pci_read_reg(struct rcar_pcie *pcie, unsigned int reg)
> -{
> -	return readl(pcie->base + reg);
> -}
> -
> -enum {
> -	RCAR_PCI_ACCESS_READ,
> -	RCAR_PCI_ACCESS_WRITE,
> -};
> -
> -static void rcar_rmw32(struct rcar_pcie *pcie, int where, u32 mask, u32 data)
> -{
> -	unsigned int shift = BITS_PER_BYTE * (where & 3);
> -	u32 val = rcar_pci_read_reg(pcie, where & ~3);
> -
> -	val &= ~(mask << shift);
> -	val |= data << shift;
> -	rcar_pci_write_reg(pcie, val, where & ~3);
> -}
> -
>  static u32 rcar_read_conf(struct rcar_pcie *pcie, int where)
>  {
>  	unsigned int shift = BITS_PER_BYTE * (where & 3);
> -	u32 val = rcar_pci_read_reg(pcie, where & ~3);
> +	u32 val = rcar_pci_read_reg(pcie->base, where & ~3);

I'd like to avoid these many changes about "pcie" to "pcie->base" somehow.
My idea is moving declaration of struct rcar_pcie to rcar-pcie.h and use it
from both host and ep codes. According to the patch 6/7, the rcar-pcie-ep.c
also has the same name of struct rcar_pcie and this has the same "base" and "dev.
So, common rcar_pcie should have these members. Remaining members are
contained on renamed structures like "rcar_pcie_host" and "rcar_pcie_ep".
And then, the rcar_pcie_{host,ep} have struct rcar_pcie pcie member.

Best regards,
Yoshihiro Shimoda

>  	return val >> shift;
>  }
> @@ -221,13 +98,13 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie,
>  			return PCIBIOS_DEVICE_NOT_FOUND;
> 
>  		if (access_type == RCAR_PCI_ACCESS_READ) {
> -			*data = rcar_pci_read_reg(pcie, PCICONF(index));
> +			*data = rcar_pci_read_reg(pcie->base, PCICONF(index));
>  		} else {
>  			/* Keep an eye out for changes to the root bus number */
>  			if (pci_is_root_bus(bus) && (reg == PCI_PRIMARY_BUS))
>  				pcie->root_bus_nr = *data & 0xff;
> 
> -			rcar_pci_write_reg(pcie, *data, PCICONF(index));
> +			rcar_pci_write_reg(pcie->base, *data, PCICONF(index));
>  		}
> 
>  		return PCIBIOS_SUCCESSFUL;
> @@ -237,20 +114,23 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie,
>  		return PCIBIOS_DEVICE_NOT_FOUND;
> 
>  	/* Clear errors */
> -	rcar_pci_write_reg(pcie, rcar_pci_read_reg(pcie, PCIEERRFR), PCIEERRFR);
> +	rcar_pci_write_reg(pcie->base, rcar_pci_read_reg(pcie->base, PCIEERRFR),
> +			   PCIEERRFR);
> 
>  	/* Set the PIO address */
> -	rcar_pci_write_reg(pcie, PCIE_CONF_BUS(bus->number) |
> +	rcar_pci_write_reg(pcie->base, PCIE_CONF_BUS(bus->number) |
>  		PCIE_CONF_DEV(dev) | PCIE_CONF_FUNC(func) | reg, PCIECAR);
> 
>  	/* Enable the configuration access */
>  	if (bus->parent->number == pcie->root_bus_nr)
> -		rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE0, PCIECCTLR);
> +		rcar_pci_write_reg(pcie->base, CONFIG_SEND_ENABLE | TYPE0,
> +				   PCIECCTLR);
>  	else
> -		rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE1, PCIECCTLR);
> +		rcar_pci_write_reg(pcie->base, CONFIG_SEND_ENABLE | TYPE1,
> +				   PCIECCTLR);
> 
>  	/* Check for errors */
> -	if (rcar_pci_read_reg(pcie, PCIEERRFR) & UNSUPPORTED_REQUEST)
> +	if (rcar_pci_read_reg(pcie->base, PCIEERRFR) & UNSUPPORTED_REQUEST)
>  		return PCIBIOS_DEVICE_NOT_FOUND;
> 
>  	/* Check for master and target aborts */
> @@ -259,12 +139,12 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie,
>  		return PCIBIOS_DEVICE_NOT_FOUND;
> 
>  	if (access_type == RCAR_PCI_ACCESS_READ)
> -		*data = rcar_pci_read_reg(pcie, PCIECDR);
> +		*data = rcar_pci_read_reg(pcie->base, PCIECDR);
>  	else
> -		rcar_pci_write_reg(pcie, *data, PCIECDR);
> +		rcar_pci_write_reg(pcie->base, *data, PCIECDR);
> 
>  	/* Disable the configuration access */
> -	rcar_pci_write_reg(pcie, 0, PCIECCTLR);
> +	rcar_pci_write_reg(pcie->base, 0, PCIECCTLR);
> 
>  	return PCIBIOS_SUCCESSFUL;
>  }
> @@ -332,41 +212,6 @@ static struct pci_ops rcar_pcie_ops = {
>  	.write	= rcar_pcie_write_conf,
>  };
> 
> -static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie,
> -				   struct resource *res)
> -{
> -	/* Setup PCIe address space mappings for each resource */
> -	resource_size_t size;
> -	resource_size_t res_start;
> -	u32 mask;
> -
> -	rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
> -
> -	/*
> -	 * The PAMR mask is calculated in units of 128Bytes, which
> -	 * keeps things pretty simple.
> -	 */
> -	size = resource_size(res);
> -	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
> -	rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
> -
> -	if (res->flags & IORESOURCE_IO)
> -		res_start = pci_pio_to_address(res->start);
> -	else
> -		res_start = res->start;
> -
> -	rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPAUR(win));
> -	rcar_pci_write_reg(pcie, lower_32_bits(res_start) & ~0x7F,
> -			   PCIEPALR(win));
> -
> -	/* First resource is for IO */
> -	mask = PAR_ENABLE;
> -	if (res->flags & IORESOURCE_IO)
> -		mask |= IO_SPACE;
> -
> -	rcar_pci_write_reg(pcie, mask, PCIEPTCTLR(win));
> -}
> -
>  static int rcar_pcie_setup(struct list_head *resource, struct rcar_pcie *pci)
>  {
>  	struct resource_entry *win;
> @@ -382,7 +227,7 @@ static int rcar_pcie_setup(struct list_head *resource, struct rcar_pcie *pci)
>  		switch (resource_type(res)) {
>  		case IORESOURCE_IO:
>  		case IORESOURCE_MEM:
> -			rcar_pcie_setup_window(i, pci, res);
> +			rcar_pcie_set_outbound(i, pci->base, res);
>  			i++;
>  			break;
>  		case IORESOURCE_BUS:
> @@ -404,37 +249,38 @@ static void rcar_pcie_force_speedup(struct rcar_pcie *pcie)
>  	unsigned int timeout = 1000;
>  	u32 macsr;
> 
> -	if ((rcar_pci_read_reg(pcie, MACS2R) & LINK_SPEED) != LINK_SPEED_5_0GTS)
> +	if ((rcar_pci_read_reg(pcie->base, MACS2R) & LINK_SPEED) !=
> +		LINK_SPEED_5_0GTS)
>  		return;
> 
> -	if (rcar_pci_read_reg(pcie, MACCTLR) & SPEED_CHANGE) {
> +	if (rcar_pci_read_reg(pcie->base, MACCTLR) & SPEED_CHANGE) {
>  		dev_err(dev, "Speed change already in progress\n");
>  		return;
>  	}
> 
> -	macsr = rcar_pci_read_reg(pcie, MACSR);
> +	macsr = rcar_pci_read_reg(pcie->base, MACSR);
>  	if ((macsr & LINK_SPEED) == LINK_SPEED_5_0GTS)
>  		goto done;
> 
>  	/* Set target link speed to 5.0 GT/s */
> -	rcar_rmw32(pcie, EXPCAP(12), PCI_EXP_LNKSTA_CLS,
> +	rcar_rmw32(pcie->base, EXPCAP(12), PCI_EXP_LNKSTA_CLS,
>  		   PCI_EXP_LNKSTA_CLS_5_0GB);
> 
>  	/* Set speed change reason as intentional factor */
> -	rcar_rmw32(pcie, MACCGSPSETR, SPCNGRSN, 0);
> +	rcar_rmw32(pcie->base, MACCGSPSETR, SPCNGRSN, 0);
> 
>  	/* Clear SPCHGFIN, SPCHGSUC, and SPCHGFAIL */
>  	if (macsr & (SPCHGFIN | SPCHGSUC | SPCHGFAIL))
> -		rcar_pci_write_reg(pcie, macsr, MACSR);
> +		rcar_pci_write_reg(pcie->base, macsr, MACSR);
> 
>  	/* Start link speed change */
> -	rcar_rmw32(pcie, MACCTLR, SPEED_CHANGE, SPEED_CHANGE);
> +	rcar_rmw32(pcie->base, MACCTLR, SPEED_CHANGE, SPEED_CHANGE);
> 
>  	while (timeout--) {
> -		macsr = rcar_pci_read_reg(pcie, MACSR);
> +		macsr = rcar_pci_read_reg(pcie->base, MACSR);
>  		if (macsr & SPCHGFIN) {
>  			/* Clear the interrupt bits */
> -			rcar_pci_write_reg(pcie, macsr, MACSR);
> +			rcar_pci_write_reg(pcie->base, macsr, MACSR);
> 
>  			if (macsr & SPCHGFAIL)
>  				dev_err(dev, "Speed change failed\n");
> @@ -498,7 +344,7 @@ static int phy_wait_for_ack(struct rcar_pcie *pcie)
>  	unsigned int timeout = 100;
> 
>  	while (timeout--) {
> -		if (rcar_pci_read_reg(pcie, H1_PCIEPHYADRR) & PHY_ACK)
> +		if (rcar_pci_read_reg(pcie->base, H1_PCIEPHYADRR) & PHY_ACK)
>  			return 0;
> 
>  		udelay(100);
> @@ -521,60 +367,31 @@ static void phy_write_reg(struct rcar_pcie *pcie,
>  		((addr & 0xff) << ADR_POS);
> 
>  	/* Set write data */
> -	rcar_pci_write_reg(pcie, data, H1_PCIEPHYDOUTR);
> -	rcar_pci_write_reg(pcie, phyaddr, H1_PCIEPHYADRR);
> +	rcar_pci_write_reg(pcie->base, data, H1_PCIEPHYDOUTR);
> +	rcar_pci_write_reg(pcie->base, phyaddr, H1_PCIEPHYADRR);
> 
>  	/* Ignore errors as they will be dealt with if the data link is down */
>  	phy_wait_for_ack(pcie);
> 
>  	/* Clear command */
> -	rcar_pci_write_reg(pcie, 0, H1_PCIEPHYDOUTR);
> -	rcar_pci_write_reg(pcie, 0, H1_PCIEPHYADRR);
> +	rcar_pci_write_reg(pcie->base, 0, H1_PCIEPHYDOUTR);
> +	rcar_pci_write_reg(pcie->base, 0, H1_PCIEPHYADRR);
> 
>  	/* Ignore errors as they will be dealt with if the data link is down */
>  	phy_wait_for_ack(pcie);
>  }
> 
> -static int rcar_pcie_wait_for_phyrdy(struct rcar_pcie *pcie)
> -{
> -	unsigned int timeout = 10;
> -
> -	while (timeout--) {
> -		if (rcar_pci_read_reg(pcie, PCIEPHYSR) & PHYRDY)
> -			return 0;
> -
> -		msleep(5);
> -	}
> -
> -	return -ETIMEDOUT;
> -}
> -
> -static int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie)
> -{
> -	unsigned int timeout = 10000;
> -
> -	while (timeout--) {
> -		if ((rcar_pci_read_reg(pcie, PCIETSTR) & DATA_LINK_ACTIVE))
> -			return 0;
> -
> -		udelay(5);
> -		cpu_relax();
> -	}
> -
> -	return -ETIMEDOUT;
> -}
> -
>  static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
>  {
>  	int err;
> 
>  	/* Begin initialization */
> -	rcar_pci_write_reg(pcie, 0, PCIETCTLR);
> +	rcar_pci_write_reg(pcie->base, 0, PCIETCTLR);
> 
>  	/* Set mode */
> -	rcar_pci_write_reg(pcie, 1, PCIEMSR);
> +	rcar_pci_write_reg(pcie->base, 1, PCIEMSR);
> 
> -	err = rcar_pcie_wait_for_phyrdy(pcie);
> +	err = rcar_pcie_wait_for_phyrdy(pcie->base);
>  	if (err)
>  		return err;
> 
> @@ -583,51 +400,51 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
>  	 * class to match. Hardware takes care of propagating the IDSETR
>  	 * settings, so there is no need to bother with a quirk.
>  	 */
> -	rcar_pci_write_reg(pcie, PCI_CLASS_BRIDGE_PCI << 16, IDSETR1);
> +	rcar_pci_write_reg(pcie->base, PCI_CLASS_BRIDGE_PCI << 16, IDSETR1);
> 
>  	/*
>  	 * Setup Secondary Bus Number & Subordinate Bus Number, even though
>  	 * they aren't used, to avoid bridge being detected as broken.
>  	 */
> -	rcar_rmw32(pcie, RCONF(PCI_SECONDARY_BUS), 0xff, 1);
> -	rcar_rmw32(pcie, RCONF(PCI_SUBORDINATE_BUS), 0xff, 1);
> +	rcar_rmw32(pcie->base, RCONF(PCI_SECONDARY_BUS), 0xff, 1);
> +	rcar_rmw32(pcie->base, RCONF(PCI_SUBORDINATE_BUS), 0xff, 1);
> 
>  	/* Initialize default capabilities. */
> -	rcar_rmw32(pcie, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
> -	rcar_rmw32(pcie, REXPCAP(PCI_EXP_FLAGS),
> -		PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ROOT_PORT << 4);
> -	rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
> -		PCI_HEADER_TYPE_BRIDGE);
> +	rcar_rmw32(pcie->base, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
> +	rcar_rmw32(pcie->base, REXPCAP(PCI_EXP_FLAGS),
> +		   PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ROOT_PORT << 4);
> +	rcar_rmw32(pcie->base, RCONF(PCI_HEADER_TYPE), 0x7f,
> +		   PCI_HEADER_TYPE_BRIDGE);
> 
>  	/* Enable data link layer active state reporting */
> -	rcar_rmw32(pcie, REXPCAP(PCI_EXP_LNKCAP), PCI_EXP_LNKCAP_DLLLARC,
> -		PCI_EXP_LNKCAP_DLLLARC);
> +	rcar_rmw32(pcie->base, REXPCAP(PCI_EXP_LNKCAP), PCI_EXP_LNKCAP_DLLLARC,
> +		   PCI_EXP_LNKCAP_DLLLARC);
> 
>  	/* Write out the physical slot number = 0 */
> -	rcar_rmw32(pcie, REXPCAP(PCI_EXP_SLTCAP), PCI_EXP_SLTCAP_PSN, 0);
> +	rcar_rmw32(pcie->base, REXPCAP(PCI_EXP_SLTCAP), PCI_EXP_SLTCAP_PSN, 0);
> 
>  	/* Set the completion timer timeout to the maximum 50ms. */
> -	rcar_rmw32(pcie, TLCTLR + 1, 0x3f, 50);
> +	rcar_rmw32(pcie->base, TLCTLR + 1, 0x3f, 50);
> 
>  	/* Terminate list of capabilities (Next Capability Offset=0) */
> -	rcar_rmw32(pcie, RVCCAP(0), 0xfff00000, 0);
> +	rcar_rmw32(pcie->base, RVCCAP(0), 0xfff00000, 0);
> 
>  	/* Enable MSI */
>  	if (IS_ENABLED(CONFIG_PCI_MSI))
> -		rcar_pci_write_reg(pcie, 0x801f0000, PCIEMSITXR);
> +		rcar_pci_write_reg(pcie->base, 0x801f0000, PCIEMSITXR);
> 
> -	rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR);
> +	rcar_pci_write_reg(pcie->base, MACCTLR_INIT_VAL, MACCTLR);
> 
>  	/* Finish initialization - establish a PCI Express link */
> -	rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR);
> +	rcar_pci_write_reg(pcie->base, CFINIT, PCIETCTLR);
> 
>  	/* This will timeout if we don't have a link. */
> -	err = rcar_pcie_wait_for_dl(pcie);
> +	err = rcar_pcie_wait_for_dl(pcie->base);
>  	if (err)
>  		return err;
> 
>  	/* Enable INTx interrupts */
> -	rcar_rmw32(pcie, PCIEINTXR, 0, 0xF << 8);
> +	rcar_rmw32(pcie->base, PCIEINTXR, 0, 0xF << 8);
> 
>  	wmb();
> 
> @@ -663,16 +480,16 @@ static int rcar_pcie_phy_init_gen2(struct rcar_pcie *pcie)
>  	 * These settings come from the R-Car Series, 2nd Generation User's
>  	 * Manual, section 50.3.1 (2) Initialization of the physical layer.
>  	 */
> -	rcar_pci_write_reg(pcie, 0x000f0030, GEN2_PCIEPHYADDR);
> -	rcar_pci_write_reg(pcie, 0x00381203, GEN2_PCIEPHYDATA);
> -	rcar_pci_write_reg(pcie, 0x00000001, GEN2_PCIEPHYCTRL);
> -	rcar_pci_write_reg(pcie, 0x00000006, GEN2_PCIEPHYCTRL);
> +	rcar_pci_write_reg(pcie->base, 0x000f0030, GEN2_PCIEPHYADDR);
> +	rcar_pci_write_reg(pcie->base, 0x00381203, GEN2_PCIEPHYDATA);
> +	rcar_pci_write_reg(pcie->base, 0x00000001, GEN2_PCIEPHYCTRL);
> +	rcar_pci_write_reg(pcie->base, 0x00000006, GEN2_PCIEPHYCTRL);
> 
> -	rcar_pci_write_reg(pcie, 0x000f0054, GEN2_PCIEPHYADDR);
> +	rcar_pci_write_reg(pcie->base, 0x000f0054, GEN2_PCIEPHYADDR);
>  	/* The following value is for DC connection, no termination resistor */
> -	rcar_pci_write_reg(pcie, 0x13802007, GEN2_PCIEPHYDATA);
> -	rcar_pci_write_reg(pcie, 0x00000001, GEN2_PCIEPHYCTRL);
> -	rcar_pci_write_reg(pcie, 0x00000006, GEN2_PCIEPHYCTRL);
> +	rcar_pci_write_reg(pcie->base, 0x13802007, GEN2_PCIEPHYDATA);
> +	rcar_pci_write_reg(pcie->base, 0x00000001, GEN2_PCIEPHYCTRL);
> +	rcar_pci_write_reg(pcie->base, 0x00000006, GEN2_PCIEPHYCTRL);
> 
>  	return 0;
>  }
> @@ -735,7 +552,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
>  	struct device *dev = pcie->dev;
>  	unsigned long reg;
> 
> -	reg = rcar_pci_read_reg(pcie, PCIEMSIFR);
> +	reg = rcar_pci_read_reg(pcie->base, PCIEMSIFR);
> 
>  	/* MSI & INTx share an interrupt - we only handle MSI here */
>  	if (!reg)
> @@ -746,7 +563,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
>  		unsigned int msi_irq;
> 
>  		/* clear the interrupt */
> -		rcar_pci_write_reg(pcie, 1 << index, PCIEMSIFR);
> +		rcar_pci_write_reg(pcie->base, 1 << index, PCIEMSIFR);
> 
>  		msi_irq = irq_find_mapping(msi->domain, index);
>  		if (msi_irq) {
> @@ -760,7 +577,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
>  		}
> 
>  		/* see if there's any more pending in this vector */
> -		reg = rcar_pci_read_reg(pcie, PCIEMSIFR);
> +		reg = rcar_pci_read_reg(pcie->base, PCIEMSIFR);
>  	}
> 
>  	return IRQ_HANDLED;
> @@ -787,8 +604,8 @@ static int rcar_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
> 
>  	irq_set_msi_desc(irq, desc);
> 
> -	msg.address_lo = rcar_pci_read_reg(pcie, PCIEMSIALR) & ~MSIFE;
> -	msg.address_hi = rcar_pci_read_reg(pcie, PCIEMSIAUR);
> +	msg.address_lo = rcar_pci_read_reg(pcie->base, PCIEMSIALR) & ~MSIFE;
> +	msg.address_hi = rcar_pci_read_reg(pcie->base, PCIEMSIAUR);
>  	msg.data = hwirq;
> 
>  	pci_write_msi_msg(irq, &msg);
> @@ -839,8 +656,8 @@ static int rcar_msi_setup_irqs(struct msi_controller *chip,
>  	desc->nvec_used = nvec;
>  	desc->msi_attrib.multiple = order_base_2(nvec);
> 
> -	msg.address_lo = rcar_pci_read_reg(pcie, PCIEMSIALR) & ~MSIFE;
> -	msg.address_hi = rcar_pci_read_reg(pcie, PCIEMSIAUR);
> +	msg.address_lo = rcar_pci_read_reg(pcie->base, PCIEMSIALR) & ~MSIFE;
> +	msg.address_hi = rcar_pci_read_reg(pcie->base, PCIEMSIAUR);
>  	msg.data = hwirq;
> 
>  	pci_write_msi_msg(irq, &msg);
> @@ -940,11 +757,11 @@ static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)
>  	}
>  	base = virt_to_phys((void *)msi->pages);
> 
> -	rcar_pci_write_reg(pcie, lower_32_bits(base) | MSIFE, PCIEMSIALR);
> -	rcar_pci_write_reg(pcie, upper_32_bits(base), PCIEMSIAUR);
> +	rcar_pci_write_reg(pcie->base, lower_32_bits(base) | MSIFE, PCIEMSIALR);
> +	rcar_pci_write_reg(pcie->base, upper_32_bits(base), PCIEMSIAUR);
> 
>  	/* enable all MSI interrupts */
> -	rcar_pci_write_reg(pcie, 0xffffffff, PCIEMSIIER);
> +	rcar_pci_write_reg(pcie->base, 0xffffffff, PCIEMSIIER);
> 
>  	return 0;
> 
> @@ -958,10 +775,10 @@ static void rcar_pcie_teardown_msi(struct rcar_pcie *pcie)
>  	struct rcar_msi *msi = &pcie->msi;
> 
>  	/* Disable all MSI interrupts */
> -	rcar_pci_write_reg(pcie, 0, PCIEMSIIER);
> +	rcar_pci_write_reg(pcie->base, 0, PCIEMSIIER);
> 
>  	/* Disable address decoding of the MSI interrupt, MSIFE */
> -	rcar_pci_write_reg(pcie, 0, PCIEMSIALR);
> +	rcar_pci_write_reg(pcie->base, 0, PCIEMSIALR);
> 
>  	free_pages(msi->pages, 0);
> 
> @@ -1054,21 +871,8 @@ static int rcar_pcie_inbound_ranges(struct rcar_pcie *pcie,
>  		mask = roundup_pow_of_two(size) - 1;
>  		mask &= ~0xf;
> 
> -		/*
> -		 * Set up 64-bit inbound regions as the range parser doesn't
> -		 * distinguish between 32 and 64-bit types.
> -		 */
> -		rcar_pci_write_reg(pcie, lower_32_bits(pci_addr),
> -				   PCIEPRAR(idx));
> -		rcar_pci_write_reg(pcie, lower_32_bits(cpu_addr), PCIELAR(idx));
> -		rcar_pci_write_reg(pcie, lower_32_bits(mask) | flags,
> -				   PCIELAMR(idx));
> -
> -		rcar_pci_write_reg(pcie, upper_32_bits(pci_addr),
> -				   PCIEPRAR(idx + 1));
> -		rcar_pci_write_reg(pcie, upper_32_bits(cpu_addr),
> -				   PCIELAR(idx + 1));
> -		rcar_pci_write_reg(pcie, 0, PCIELAMR(idx + 1));
> +		rcar_pcie_set_inbound(pcie->base, cpu_addr, pci_addr,
> +				      lower_32_bits(mask) | flags, idx, true);
> 
>  		pci_addr += size;
>  		cpu_addr += size;
> @@ -1170,7 +974,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
>  		goto err_phy_shutdown;
>  	}
> 
> -	data = rcar_pci_read_reg(pcie, MACSR);
> +	data = rcar_pci_read_reg(pcie->base, MACSR);
>  	dev_info(dev, "PCIe x%d: link up\n", (data >> 20) & 0x3f);
> 
>  	if (IS_ENABLED(CONFIG_PCI_MSI)) {
> @@ -1223,14 +1027,14 @@ static int rcar_pcie_resume_noirq(struct device *dev)
>  {
>  	struct rcar_pcie *pcie = dev_get_drvdata(dev);
> 
> -	if (rcar_pci_read_reg(pcie, PMSR) &&
> -	    !(rcar_pci_read_reg(pcie, PCIETCTLR) & DL_DOWN))
> +	if (rcar_pci_read_reg(pcie->base, PMSR) &&
> +	    !(rcar_pci_read_reg(pcie->base, PCIETCTLR) & DL_DOWN))
>  		return 0;
> 
>  	/* Re-establish the PCIe link */
> -	rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR);
> -	rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR);
> -	return rcar_pcie_wait_for_dl(pcie);
> +	rcar_pci_write_reg(pcie->base, MACCTLR_INIT_VAL, MACCTLR);
> +	rcar_pci_write_reg(pcie->base, CFINIT, PCIETCTLR);
> +	return rcar_pcie_wait_for_dl(pcie->base);
>  }
> 
>  static const struct dev_pm_ops rcar_pcie_pm_ops = {
> diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c
> new file mode 100644
> index 0000000..41275f9
> --- /dev/null
> +++ b/drivers/pci/controller/pcie-rcar.c
> @@ -0,0 +1,117 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PCIe driver for Renesas R-Car SoCs
> + *  Copyright (C) 2014-2020 Renesas Electronics Europe Ltd
> + *
> + * Author: Phil Edworthy <phil.edworthy@renesas.com>
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/pci.h>
> +
> +#include "pcie-rcar.h"
> +
> +void rcar_pci_write_reg(void __iomem *base, u32 val, unsigned int reg)
> +{
> +	writel(val, base + reg);
> +}
> +
> +u32 rcar_pci_read_reg(void __iomem *base, unsigned int reg)
> +{
> +	return readl(base + reg);
> +}
> +
> +void rcar_rmw32(void __iomem *base, int where, u32 mask, u32 data)
> +{
> +	unsigned int shift = BITS_PER_BYTE * (where & 3);
> +	u32 val = rcar_pci_read_reg(base, where & ~3);
> +
> +	val &= ~(mask << shift);
> +	val |= data << shift;
> +	rcar_pci_write_reg(base, val, where & ~3);
> +}
> +
> +int rcar_pcie_wait_for_phyrdy(void __iomem *base)
> +{
> +	unsigned int timeout = 10;
> +
> +	while (timeout--) {
> +		if (rcar_pci_read_reg(base, PCIEPHYSR) & PHYRDY)
> +			return 0;
> +
> +		msleep(5);
> +	}
> +
> +	return -ETIMEDOUT;
> +}
> +
> +int rcar_pcie_wait_for_dl(void __iomem *base)
> +{
> +	unsigned int timeout = 10000;
> +
> +	while (timeout--) {
> +		if ((rcar_pci_read_reg(base, PCIETSTR) & DATA_LINK_ACTIVE))
> +			return 0;
> +
> +		udelay(5);
> +		cpu_relax();
> +	}
> +
> +	return -ETIMEDOUT;
> +}
> +
> +void rcar_pcie_set_outbound(int win, void __iomem *base,
> +			    struct resource *res)
> +{
> +	/* Setup PCIe address space mappings for each resource */
> +	resource_size_t res_start;
> +	resource_size_t size;
> +	u32 mask;
> +
> +	rcar_pci_write_reg(base, 0x00000000, PCIEPTCTLR(win));
> +
> +	/*
> +	 * The PAMR mask is calculated in units of 128Bytes, which
> +	 * keeps things pretty simple.
> +	 */
> +	size = resource_size(res);
> +	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
> +	rcar_pci_write_reg(base, mask << 7, PCIEPAMR(win));
> +
> +	if (res->flags & IORESOURCE_IO)
> +		res_start = pci_pio_to_address(res->start);
> +	else
> +		res_start = res->start;
> +
> +	rcar_pci_write_reg(base, upper_32_bits(res_start), PCIEPAUR(win));
> +	rcar_pci_write_reg(base, lower_32_bits(res_start) & ~0x7F,
> +			   PCIEPALR(win));
> +
> +	/* First resource is for IO */
> +	mask = PAR_ENABLE;
> +	if (res->flags & IORESOURCE_IO)
> +		mask |= IO_SPACE;
> +
> +	rcar_pci_write_reg(base, mask, PCIEPTCTLR(win));
> +}
> +
> +void rcar_pcie_set_inbound(void __iomem *base,
> +			   u64 cpu_addr, u64 pci_addr,
> +			   u64 flags, int idx, bool host)
> +{
> +	/*
> +	 * Set up 64-bit inbound regions as the range parser doesn't
> +	 * distinguish between 32 and 64-bit types.
> +	 */
> +	if (host)
> +		rcar_pci_write_reg(base, lower_32_bits(pci_addr),
> +				   PCIEPRAR(idx));
> +	rcar_pci_write_reg(base, lower_32_bits(cpu_addr), PCIELAR(idx));
> +	rcar_pci_write_reg(base, flags, PCIELAMR(idx));
> +
> +	if (host)
> +		rcar_pci_write_reg(base, upper_32_bits(pci_addr),
> +				   PCIEPRAR(idx + 1));
> +	rcar_pci_write_reg(base, upper_32_bits(cpu_addr), PCIELAR(idx + 1));
> +	rcar_pci_write_reg(base, 0, PCIELAMR(idx + 1));
> +}
> diff --git a/drivers/pci/controller/pcie-rcar.h b/drivers/pci/controller/pcie-rcar.h
> new file mode 100644
> index 0000000..b529d806
> --- /dev/null
> +++ b/drivers/pci/controller/pcie-rcar.h
> @@ -0,0 +1,125 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * PCIe driver for Renesas R-Car SoCs
> + *  Copyright (C) 2014-2020 Renesas Electronics Europe Ltd
> + *
> + * Author: Phil Edworthy <phil.edworthy@renesas.com>
> + */
> +
> +#ifndef _PCIE_RCAR_H
> +#define _PCIE_RCAR_H
> +
> +#define PCIECAR			0x000010
> +#define PCIECCTLR		0x000018
> +#define  CONFIG_SEND_ENABLE	BIT(31)
> +#define  TYPE0			(0 << 8)
> +#define  TYPE1			BIT(8)
> +#define PCIECDR			0x000020
> +#define PCIEMSR			0x000028
> +#define PCIEINTXR		0x000400
> +#define PCIEPHYSR		0x0007f0
> +#define  PHYRDY			BIT(0)
> +#define PCIEMSITXR		0x000840
> +
> +/* Transfer control */
> +#define PCIETCTLR		0x02000
> +#define  DL_DOWN		BIT(3)
> +#define  CFINIT			BIT(0)
> +#define PCIETSTR		0x02004
> +#define  DATA_LINK_ACTIVE	BIT(0)
> +#define PCIEERRFR		0x02020
> +#define  UNSUPPORTED_REQUEST	BIT(4)
> +#define PCIEMSIFR		0x02044
> +#define PCIEMSIALR		0x02048
> +#define  MSIFE			BIT(0)
> +#define PCIEMSIAUR		0x0204c
> +#define PCIEMSIIER		0x02050
> +
> +/* root port address */
> +#define PCIEPRAR(x)		(0x02080 + ((x) * 0x4))
> +
> +/* local address reg & mask */
> +#define PCIELAR(x)		(0x02200 + ((x) * 0x20))
> +#define PCIELAMR(x)		(0x02208 + ((x) * 0x20))
> +#define  LAM_PREFETCH		BIT(3)
> +#define  LAM_64BIT		BIT(2)
> +#define  LAR_ENABLE		BIT(1)
> +
> +/* PCIe address reg & mask */
> +#define PCIEPALR(x)		(0x03400 + ((x) * 0x20))
> +#define PCIEPAUR(x)		(0x03404 + ((x) * 0x20))
> +#define PCIEPAMR(x)		(0x03408 + ((x) * 0x20))
> +#define PCIEPTCTLR(x)		(0x0340c + ((x) * 0x20))
> +#define  PAR_ENABLE		BIT(31)
> +#define  IO_SPACE		BIT(8)
> +
> +/* Configuration */
> +#define PCICONF(x)		(0x010000 + ((x) * 0x4))
> +#define PMCAP(x)		(0x010040 + ((x) * 0x4))
> +#define EXPCAP(x)		(0x010070 + ((x) * 0x4))
> +#define VCCAP(x)		(0x010100 + ((x) * 0x4))
> +
> +/* link layer */
> +#define IDSETR1			0x011004
> +#define TLCTLR			0x011048
> +#define MACSR			0x011054
> +#define  SPCHGFIN		BIT(4)
> +#define  SPCHGFAIL		BIT(6)
> +#define  SPCHGSUC		BIT(7)
> +#define  LINK_SPEED		(0xf << 16)
> +#define  LINK_SPEED_2_5GTS	(1 << 16)
> +#define  LINK_SPEED_5_0GTS	(2 << 16)
> +#define MACCTLR			0x011058
> +#define  MACCTLR_NFTS_MASK	GENMASK(23, 16)	/* The name is from SH7786 */
> +#define  SPEED_CHANGE		BIT(24)
> +#define  SCRAMBLE_DISABLE	BIT(27)
> +#define  LTSMDIS		BIT(31)
> +#define  MACCTLR_INIT_VAL	(LTSMDIS | MACCTLR_NFTS_MASK)
> +#define PMSR			0x01105c
> +#define MACS2R			0x011078
> +#define MACCGSPSETR		0x011084
> +#define  SPCNGRSN		BIT(31)
> +
> +/* R-Car H1 PHY */
> +#define H1_PCIEPHYADRR		0x04000c
> +#define  WRITE_CMD		BIT(16)
> +#define  PHY_ACK		BIT(24)
> +#define  RATE_POS		12
> +#define  LANE_POS		8
> +#define  ADR_POS		0
> +#define H1_PCIEPHYDOUTR		0x040014
> +
> +/* R-Car Gen2 PHY */
> +#define GEN2_PCIEPHYADDR	0x780
> +#define GEN2_PCIEPHYDATA	0x784
> +#define GEN2_PCIEPHYCTRL	0x78c
> +
> +#define INT_PCI_MSI_NR		32
> +
> +#define RCONF(x)		(PCICONF(0) + (x))
> +#define RPMCAP(x)		(PMCAP(0) + (x))
> +#define REXPCAP(x)		(EXPCAP(0) + (x))
> +#define RVCCAP(x)		(VCCAP(0) + (x))
> +
> +#define PCIE_CONF_BUS(b)	(((b) & 0xff) << 24)
> +#define PCIE_CONF_DEV(d)	(((d) & 0x1f) << 19)
> +#define PCIE_CONF_FUNC(f)	(((f) & 0x7) << 16)
> +
> +#define RCAR_PCI_MAX_RESOURCES	4
> +#define MAX_NR_INBOUND_MAPS	6
> +
> +enum {
> +	RCAR_PCI_ACCESS_READ,
> +	RCAR_PCI_ACCESS_WRITE,
> +};
> +
> +void rcar_pci_write_reg(void __iomem *base, u32 val, unsigned int reg);
> +u32 rcar_pci_read_reg(void __iomem *base, unsigned int reg);
> +void rcar_rmw32(void __iomem *base, int where, u32 mask, u32 data);
> +int rcar_pcie_wait_for_phyrdy(void __iomem *base);
> +int rcar_pcie_wait_for_dl(void __iomem *base);
> +void rcar_pcie_set_outbound(int win, void __iomem *base, struct resource *res);
> +void rcar_pcie_set_inbound(void __iomem *base, u64 cpu_addr, u64 pci_addr,
> +			   u64 mask, int idx, bool host);
> +
> +#endif
> --
> 2.7.4


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

* RE: [PATCH v5 3/7] PCI: rcar: Fix calculating mask for PCIEPAMR register
  2020-02-28 15:41 ` [PATCH v5 3/7] PCI: rcar: Fix calculating mask for PCIEPAMR register Lad Prabhakar
@ 2020-03-17  7:31   ` Yoshihiro Shimoda
  0 siblings, 0 replies; 26+ messages in thread
From: Yoshihiro Shimoda @ 2020-03-17  7:31 UTC (permalink / raw)
  To: Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Prabhakar Mahadev Lad,
	Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Shawn Lin, Heiko Stuebner

Hi Prabhakar-san,

Thank you for the patch!

> From: Lad Prabhakar, Sent: Saturday, February 29, 2020 12:41 AM
> 
> The mask value was calculated incorrectly for PCIEPAMR register if the
> size was less than 128 bytes. Fix this issue by adding a check on size.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> ---
>  drivers/pci/controller/pcie-rcar.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c
> index 41275f9..90d47b21 100644
> --- a/drivers/pci/controller/pcie-rcar.c
> +++ b/drivers/pci/controller/pcie-rcar.c
> @@ -75,7 +75,10 @@ void rcar_pcie_set_outbound(int win, void __iomem *base,
>  	 * keeps things pretty simple.
>  	 */
>  	size = resource_size(res);
> -	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
> +	if (size > 128)
> +		mask = (roundup_pow_of_two(size) / SZ_128) - 1;
> +	else
> +		mask = 0x0;
>  	rcar_pci_write_reg(base, mask << 7, PCIEPAMR(win));

This patch seems OK. I think rebasing is needed though. Anyway,

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

Best regards,
Yoshihiro Shimoda

>  	if (res->flags & IORESOURCE_IO)
> --
> 2.7.4


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

* RE: [PATCH v5 4/7] PCI: endpoint: Add support to handle multiple base for mapping outbound memory
  2020-02-28 15:41 ` [PATCH v5 4/7] PCI: endpoint: Add support to handle multiple base for mapping outbound memory Lad Prabhakar
@ 2020-03-17  8:11   ` Yoshihiro Shimoda
  2020-03-17 10:03     ` Prabhakar Mahadev Lad
  0 siblings, 1 reply; 26+ messages in thread
From: Yoshihiro Shimoda @ 2020-03-17  8:11 UTC (permalink / raw)
  To: Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Prabhakar Mahadev Lad,
	Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Shawn Lin, Heiko Stuebner

Hi Prabhakar-san,

Thank you for the patch!

> From: Lad Prabhakar, Sent: Saturday, February 29, 2020 12:41 AM
> 
> R-Car PCIe controller has support to map multiple memory regions for
> mapping the outbound memory in local system also the controller limits
> single allocation for each region (that is, once a chunk is used from the
> region it cannot be used to allocate a new one). This features inspires to
> add support for handling multiple memory bases in endpoint framework.
> 
> With this patch pci_epc_mem_init() now accepts multiple regions, also
> page_size for each memory region is passed during initialization so as
> to handle single allocation for each region by setting the page_size to
> window_size.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> ---
>  drivers/pci/controller/cadence/pcie-cadence-ep.c |   7 +-
>  drivers/pci/controller/dwc/pcie-designware-ep.c  |  29 ++--
>  drivers/pci/controller/pcie-rockchip-ep.c        |   7 +-
>  drivers/pci/endpoint/pci-epc-mem.c               | 167 ++++++++++++++++-------

I could not apply this patch on the latest pci.git / next branch.
So, you need to rebase.

>  include/linux/pci-epc.h                          |  39 ++++--
>  5 files changed, 169 insertions(+), 80 deletions(-)
> 
> diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> index 1c173da..90e32438 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
> +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> @@ -401,6 +401,7 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
>  	struct device *dev = ep->pcie.dev;
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct device_node *np = dev->of_node;
> +	struct pci_epc_mem_window mem_window;
>  	struct cdns_pcie *pcie = &ep->pcie;
>  	struct resource *res;
>  	struct pci_epc *epc;
> @@ -449,8 +450,10 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
>  	if (of_property_read_u8(np, "max-functions", &epc->max_functions) < 0)
>  		epc->max_functions = 1;
> 
> -	ret = pci_epc_mem_init(epc, pcie->mem_res->start,
> -			       resource_size(pcie->mem_res));
> +	mem_window.phys_base = pcie->mem_res->start;
> +	mem_window.size = resource_size(pcie->mem_res);
> +	mem_window.page_size = PAGE_SIZE;
> +	ret = pci_epc_mem_init(epc, &mem_window, 1);

I'm not sure my idea is acceptable or not but,
I think we can have compatible API for single window like below.
- In this patch, pci_epc_mem_init() and __pci_epc_mem_init() become the same behavior.
  So, for example, pci_epc_mem_init() is for simple, and __pci_epc_mem_init() is multiple windows.
-- In this case, pci_epc_mem_init() should have page_size argument.
- The original "mem" in the pci_epc can be the default window instead of
  PCI_EPC_DEFAULT_WINDOW.

>  	if (ret < 0) {
>  		dev_err(dev, "failed to initialize the memory space\n");
>  		goto err_init;
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index cfeccd7..b150ef3 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -195,8 +195,7 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
>  }
> 
>  static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
> -			       phys_addr_t addr,
> -			       u64 pci_addr, size_t size)
> +			       phys_addr_t addr, u64 pci_addr, size_t size)
>  {
>  	int ret;
>  	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
> @@ -367,6 +366,7 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
>  	unsigned int aligned_offset;
>  	u16 msg_ctrl, msg_data;
>  	u32 msg_addr_lower, msg_addr_upper, reg;
> +	int window = PCI_EPC_DEFAULT_WINDOW;
>  	u64 msg_addr;
>  	bool has_upper;
>  	int ret;
> @@ -390,11 +390,11 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
>  		reg = ep->msi_cap + PCI_MSI_DATA_32;
>  		msg_data = dw_pcie_readw_dbi(pci, reg);
>  	}
> -	aligned_offset = msg_addr_lower & (epc->mem->page_size - 1);
> +	aligned_offset = msg_addr_lower & (epc->mem[window]->page_size - 1);
>  	msg_addr = ((u64)msg_addr_upper) << 32 |
>  			(msg_addr_lower & ~aligned_offset);
> -	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
> -				  epc->mem->page_size);
> +	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys,
> +				  msg_addr, epc->mem[window]->page_size);
>  	if (ret)
>  		return ret;
> 
> @@ -416,6 +416,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
>  	u32 reg, msg_data, vec_ctrl;
>  	u64 tbl_addr, msg_addr, reg_u64;
>  	void __iomem *msix_tbl;
> +	int window = PCI_EPC_DEFAULT_WINDOW;
>  	int ret;
> 
>  	reg = ep->msix_cap + PCI_MSIX_TABLE;
> @@ -452,8 +453,8 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
>  		return -EPERM;
>  	}
> 
> -	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
> -				  epc->mem->page_size);
> +	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys,
> +				  msg_addr, epc->mem[window]->page_size);
>  	if (ret)
>  		return ret;
> 
> @@ -466,10 +467,11 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
> 
>  void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
>  {
> +	int window = PCI_EPC_DEFAULT_WINDOW;
>  	struct pci_epc *epc = ep->epc;
> 
>  	pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
> -			      epc->mem->page_size);
> +			      epc->mem[window]->page_size);
> 
>  	pci_epc_mem_exit(epc);
>  }
> @@ -502,6 +504,8 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
>  	unsigned int nbars;
>  	unsigned int offset;
>  	struct pci_epc *epc;
> +	size_t msi_page_size;
> +	struct pci_epc_mem_window mem_window;
>  	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>  	struct device *dev = pci->dev;
>  	struct device_node *np = dev->of_node;
> @@ -574,15 +578,18 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
>  	if (ret < 0)
>  		epc->max_functions = 1;
> 
> -	ret = __pci_epc_mem_init(epc, ep->phys_base, ep->addr_size,
> -				 ep->page_size);
> +	mem_window.phys_base = ep->phys_base;
> +	mem_window.size = ep->addr_size;
> +	mem_window.page_size = ep->page_size;
> +	ret = __pci_epc_mem_init(epc, &mem_window, 1);
>  	if (ret < 0) {
>  		dev_err(dev, "Failed to initialize address space\n");
>  		return ret;
>  	}
> 
> +	msi_page_size = epc->mem[PCI_EPC_DEFAULT_WINDOW]->page_size;
>  	ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
> -					     epc->mem->page_size);
> +					     msi_page_size);
>  	if (!ep->msi_mem) {
>  		dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n");
>  		return -ENOMEM;
> diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
> index d743b0a..5a97390 100644
> --- a/drivers/pci/controller/pcie-rockchip-ep.c
> +++ b/drivers/pci/controller/pcie-rockchip-ep.c
> @@ -562,6 +562,7 @@ static const struct of_device_id rockchip_pcie_ep_of_match[] = {
> 
>  static int rockchip_pcie_ep_probe(struct platform_device *pdev)
>  {
> +	struct pci_epc_mem_window mem_window;
>  	struct device *dev = &pdev->dev;
>  	struct rockchip_pcie_ep *ep;
>  	struct rockchip_pcie *rockchip;
> @@ -614,8 +615,10 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)
>  	/* Only enable function 0 by default */
>  	rockchip_pcie_write(rockchip, BIT(0), PCIE_CORE_PHY_FUNC_CFG);
> 
> -	err = pci_epc_mem_init(epc, rockchip->mem_res->start,
> -			       resource_size(rockchip->mem_res));
> +	mem_window.phys_base = rockchip->mem_res->start;
> +	mem_window.size = resource_size(rockchip->mem_res);
> +	mem_window.page_size = PAGE_SIZE;
> +	err = pci_epc_mem_init(epc, &mem_window, 1);
>  	if (err < 0) {
>  		dev_err(dev, "failed to initialize the memory space\n");
>  		goto err_uninit_port;
> diff --git a/drivers/pci/endpoint/pci-epc-mem.c b/drivers/pci/endpoint/pci-epc-mem.c
> index d2b174c..6c21957 100644
> --- a/drivers/pci/endpoint/pci-epc-mem.c
> +++ b/drivers/pci/endpoint/pci-epc-mem.c
> @@ -38,57 +38,76 @@ static int pci_epc_mem_get_order(struct pci_epc_mem *mem, size_t size)
>  /**
>   * __pci_epc_mem_init() - initialize the pci_epc_mem structure
>   * @epc: the EPC device that invoked pci_epc_mem_init
> - * @phys_base: the physical address of the base
> - * @size: the size of the address space
> - * @page_size: size of each page
> + * @windows: pointer to windows supported by the device
> + * @num_windows: number of windows device supports
>   *
>   * Invoke to initialize the pci_epc_mem structure used by the
>   * endpoint functions to allocate mapped PCI address.
>   */
> -int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size,
> -		       size_t page_size)
> +int __pci_epc_mem_init(struct pci_epc *epc, struct pci_epc_mem_window *windows,
> +		       int num_windows)
>  {
> -	int ret;
> -	struct pci_epc_mem *mem;
> -	unsigned long *bitmap;
> +	struct pci_epc_mem *mem = NULL;
> +	unsigned long *bitmap = NULL;
>  	unsigned int page_shift;
> -	int pages;
> +	size_t page_size;
>  	int bitmap_size;
> -
> -	if (page_size < PAGE_SIZE)
> -		page_size = PAGE_SIZE;
> -
> -	page_shift = ilog2(page_size);
> -	pages = size >> page_shift;
> -	bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
> -
> -	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
> -	if (!mem) {
> -		ret = -ENOMEM;
> -		goto err;
> -	}
> -
> -	bitmap = kzalloc(bitmap_size, GFP_KERNEL);
> -	if (!bitmap) {
> -		ret = -ENOMEM;
> -		goto err_mem;
> +	int pages;
> +	int ret;
> +	int i;
> +
> +	epc->mem_windows = 0;
> +
> +	if (!windows)
> +		return -EINVAL;
> +
> +	if (num_windows <= 0)
> +		return -EINVAL;
> +
> +	epc->mem = kcalloc(num_windows, sizeof(*mem), GFP_KERNEL);
> +	if (!epc->mem)
> +		return -EINVAL;
> +
> +	for (i = 0; i < num_windows; i++) {
> +		page_size = windows[i].page_size;
> +		if (page_size < PAGE_SIZE)
> +			page_size = PAGE_SIZE;
> +		page_shift = ilog2(page_size);
> +		pages = windows[i].size >> page_shift;
> +		bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
> +
> +		mem = kzalloc(sizeof(*mem), GFP_KERNEL);
> +		if (!mem) {
> +			ret = -ENOMEM;
> +			goto err_mem;
> +		}
> +
> +		bitmap = kzalloc(bitmap_size, GFP_KERNEL);
> +		if (!bitmap) {
> +			ret = -ENOMEM;
> +			goto err_mem;
> +		}
> +
> +		mem->bitmap = bitmap;
> +		mem->window.phys_base = windows[i].phys_base;

I could not understand why the window member is needed.
I think original members (just phys_base and size) are enough.
Also, this function doesn't store the page_size to mem->window.page_size.

> +		mem->page_size = page_size;
> +		mem->pages = pages;
> +		mem->window.size = windows[i].size;
> +		epc->mem[i] = mem;
>  	}
> -
> -	mem->bitmap = bitmap;
> -	mem->phys_base = phys_base;
> -	mem->page_size = page_size;
> -	mem->pages = pages;
> -	mem->size = size;
> -
> -	epc->mem = mem;
> +	epc->mem_windows = num_windows;
> 
>  	return 0;
> 
>  err_mem:
> -	kfree(mem);
> +	for (; i >= 0; i--) {
> +		mem = epc->mem[i];
> +		kfree(mem->bitmap);

If bitmap cannot be allocated, the epc->mem[i] is NULL.
So, freeing mem->bitmap anyway is not good.

> +		kfree(mem);
> +	}
> +	kfree(epc->mem);
> 
> -err:
> -return ret;
> +	return ret;
>  }
>  EXPORT_SYMBOL_GPL(__pci_epc_mem_init);
> 
> @@ -101,11 +120,21 @@ EXPORT_SYMBOL_GPL(__pci_epc_mem_init);
>   */
>  void pci_epc_mem_exit(struct pci_epc *epc)
>  {
> -	struct pci_epc_mem *mem = epc->mem;
> +	struct pci_epc_mem *mem;
> +	int i;
> +
> +	if (!epc->mem_windows)
> +		return;
> +
> +	for (i = 0; i <= epc->mem_windows; i++) {
> +		mem = epc->mem[i];
> +		kfree(mem->bitmap);
> +		kfree(mem);
> +	}
> +	kfree(epc->mem);
> 
>  	epc->mem = NULL;
> -	kfree(mem->bitmap);
> -	kfree(mem);
> +	epc->mem_windows = 0;
>  }
>  EXPORT_SYMBOL_GPL(pci_epc_mem_exit);
> 
> @@ -121,20 +150,30 @@ EXPORT_SYMBOL_GPL(pci_epc_mem_exit);
>  void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
>  				     phys_addr_t *phys_addr, size_t size)
>  {
> -	int pageno;
> -	void __iomem *virt_addr;
> -	struct pci_epc_mem *mem = epc->mem;
> -	unsigned int page_shift = ilog2(mem->page_size);
> +	void __iomem *virt_addr = NULL;
> +	struct pci_epc_mem *mem;
> +	unsigned int page_shift;
> +	int pageno = -EINVAL;
>  	int order;
> +	int i;
> 
> -	size = ALIGN(size, mem->page_size);
> -	order = pci_epc_mem_get_order(mem, size);
> +	for (i = 0; i < epc->mem_windows; i++) {
> +		mem = epc->mem[i];
> +		size = ALIGN(size, mem->page_size);
> +		order = pci_epc_mem_get_order(mem, size);
> +
> +		pageno = bitmap_find_free_region(mem->bitmap, mem->pages,
> +						 order);
> +		if (pageno >= 0)
> +			break;
> +	}
> 
> -	pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);
>  	if (pageno < 0)
>  		return NULL;
> 
> -	*phys_addr = mem->phys_base + ((phys_addr_t)pageno << page_shift);
> +	page_shift = ilog2(mem->page_size);
> +	*phys_addr = mem->window.phys_base +
> +		     ((phys_addr_t)pageno << page_shift);
>  	virt_addr = ioremap(*phys_addr, size);
>  	if (!virt_addr)
>  		bitmap_release_region(mem->bitmap, pageno, order);
> @@ -143,6 +182,23 @@ void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
>  }
>  EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);
> 
> +struct pci_epc_mem *pci_epc_get_matching_window(struct pci_epc *epc,
> +						phys_addr_t phys_addr)
> +{
> +	struct pci_epc_mem *mem;
> +	int i;
> +
> +	for (i = 0; i < epc->mem_windows; i++) {
> +		mem = epc->mem[i];
> +
> +		if (phys_addr >= mem->window.phys_base &&
> +		    phys_addr < (mem->window.phys_base + mem->window.size))
> +			return mem;
> +	}
> +
> +	return NULL;
> +}
> +
>  /**
>   * pci_epc_mem_free_addr() - free the allocated memory address
>   * @epc: the EPC device on which memory was allocated
> @@ -155,13 +211,20 @@ EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);
>  void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr,
>  			   void __iomem *virt_addr, size_t size)
>  {
> +	struct pci_epc_mem *mem;
> +	unsigned int page_shift;
>  	int pageno;
> -	struct pci_epc_mem *mem = epc->mem;
> -	unsigned int page_shift = ilog2(mem->page_size);
>  	int order;
> 
> +	mem = pci_epc_get_matching_window(epc, phys_addr);
> +	if (!mem) {
> +		pr_err("failed to get matching window\n");
> +		return;
> +	}
> +
> +	page_shift = ilog2(mem->page_size);
>  	iounmap(virt_addr);
> -	pageno = (phys_addr - mem->phys_base) >> page_shift;
> +	pageno = (phys_addr - mem->window.phys_base) >> page_shift;
>  	size = ALIGN(size, mem->page_size);
>  	order = pci_epc_mem_get_order(mem, size);
>  	bitmap_release_region(mem->bitmap, pageno, order);
> diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
> index 56f1846..dde42e5 100644
> --- a/include/linux/pci-epc.h
> +++ b/include/linux/pci-epc.h
> @@ -64,17 +64,29 @@ struct pci_epc_ops {
>  	struct module *owner;
>  };
> 
> +#define PCI_EPC_DEFAULT_WINDOW         0
> +
> +/**
> + * struct pci_epc_mem_window - address window of the endpoint controller
> + * @phys_base: physical base address of the PCI address window
> + * @size: the size of the PCI address window
> + * @page_size: size of each page
> + */
> +struct pci_epc_mem_window {
> +	phys_addr_t	phys_base;
> +	size_t		size;
> +	size_t		page_size;
> +};
> +
>  /**
>   * struct pci_epc_mem - address space of the endpoint controller
> - * @phys_base: physical base address of the PCI address space
> - * @size: the size of the PCI address space
> + * @window: address window of the endpoint controller
>   * @bitmap: bitmap to manage the PCI address space
> - * @pages: number of bits representing the address region
>   * @page_size: size of each page
> + * @pages: number of bits representing the address region
>   */
>  struct pci_epc_mem {
> -	phys_addr_t	phys_base;
> -	size_t		size;
> +	struct pci_epc_mem_window window;
>  	unsigned long	*bitmap;
>  	size_t		page_size;
>  	int		pages;
> @@ -85,7 +97,8 @@ struct pci_epc_mem {
>   * @dev: PCI EPC device
>   * @pci_epf: list of endpoint functions present in this EPC device
>   * @ops: function pointers for performing endpoint operations
> - * @mem: address space of the endpoint controller

If my idea is acceptable, this should be "default address space ...".

> + * @mem: array of address space of the endpoint controller

And, this should be difference name.

> + * @mem_windows: number of windows supported by device

Perhaps, num_windows?

>   * @max_functions: max number of functions that can be configured in this EPC
>   * @group: configfs group representing the PCI EPC device
>   * @lock: spinlock to protect pci_epc ops
> @@ -94,7 +107,8 @@ struct pci_epc {
>  	struct device			dev;
>  	struct list_head		pci_epf;
>  	const struct pci_epc_ops	*ops;
> -	struct pci_epc_mem		*mem;
> +	struct pci_epc_mem		**mem;
> +	unsigned int			mem_windows;
>  	u8				max_functions;
>  	struct config_group		*group;
>  	/* spinlock to protect against concurrent access of EP controller */
> @@ -128,8 +142,8 @@ struct pci_epc_features {
>  #define devm_pci_epc_create(dev, ops)    \
>  		__devm_pci_epc_create((dev), (ops), THIS_MODULE)
> 
> -#define pci_epc_mem_init(epc, phys_addr, size)	\
> -		__pci_epc_mem_init((epc), (phys_addr), (size), PAGE_SIZE)
> +#define pci_epc_mem_init(epc, windows, num_windows)	\
> +		__pci_epc_mem_init((epc), windows, num_windows)

As I mentioned above, pci_epc_mem_init() and __ pci_epc_mem_init() are the same behavior.

>  static inline void epc_set_drvdata(struct pci_epc *epc, void *data)
>  {
> @@ -159,8 +173,7 @@ int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
>  void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,
>  		       struct pci_epf_bar *epf_bar);
>  int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
> -		     phys_addr_t phys_addr,
> -		     u64 pci_addr, size_t size);
> +		     phys_addr_t phys_addr, u64 pci_addr, size_t size);

Perhaps, this is not needed to change?

Best regards,
Yoshihiro Shimoda

>  void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
>  			phys_addr_t phys_addr);
>  int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts);
> @@ -178,8 +191,8 @@ unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
>  struct pci_epc *pci_epc_get(const char *epc_name);
>  void pci_epc_put(struct pci_epc *epc);
> 
> -int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr, size_t size,
> -		       size_t page_size);
> +int __pci_epc_mem_init(struct pci_epc *epc, struct pci_epc_mem_window *window,
> +		       int num_windows);
>  void pci_epc_mem_exit(struct pci_epc *epc);
>  void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
>  				     phys_addr_t *phys_addr, size_t size);
> --
> 2.7.4


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

* RE: [PATCH v5 5/7] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller
  2020-02-28 15:41 ` [PATCH v5 5/7] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller Lad Prabhakar
@ 2020-03-17  8:26   ` Yoshihiro Shimoda
  2020-03-17 10:18     ` Prabhakar Mahadev Lad
  0 siblings, 1 reply; 26+ messages in thread
From: Yoshihiro Shimoda @ 2020-03-17  8:26 UTC (permalink / raw)
  To: Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Prabhakar Mahadev Lad,
	Rob Herring, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Catalin Marinas, Will Deacon, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han,
	Gustavo Pimentel, Marek Vasut, Shawn Lin, Heiko Stuebner

Hi Prabhakar-san,

Thank you for the patch!

> From: Lad Prabhakar, Sent: Saturday, February 29, 2020 12:41 AM
> 
> This patch adds the bindings for the R-Car PCIe endpoint driver.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> Reviewed-by: Rob Herring <robh@kernel.org>

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

Best regards,
Yoshihiro Shimoda


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

* RE: [PATCH v5 1/7] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c
  2020-03-17  6:59   ` Yoshihiro Shimoda
@ 2020-03-17  8:26     ` Prabhakar Mahadev Lad
  0 siblings, 0 replies; 26+ messages in thread
From: Prabhakar Mahadev Lad @ 2020-03-17  8:26 UTC (permalink / raw)
  To: Yoshihiro Shimoda, Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Bjorn Helgaas,
	Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
	Kishon Vijay Abraham I, Lorenzo Pieralisi, Arnd Bergmann,
	Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel, Marek Vasut,
	Shawn Lin, Heiko Stuebner

Hi Yoshihiro-San,

Thank you for the review.

> -----Original Message-----
> From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Sent: 17 March 2020 06:59
> To: Lad Prabhakar <prabhakar.csengg@gmail.com>
> Cc: Andrew Murray <andrew.murray@arm.com>; linux-pci@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-renesas-soc@vger.kernel.org;
> linux-rockchip@lists.infradead.org; linux-kernel@vger.kernel.org;
> devicetree@vger.kernel.org; Bjorn Helgaas <bhelgaas@google.com>; Rob
> Herring <robh+dt@kernel.org>; Mark Rutland <mark.rutland@arm.com>;
> Catalin Marinas <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>;
> Kishon Vijay Abraham I <kishon@ti.com>; Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com>; Arnd Bergmann <arnd@arndb.de>; Greg
> Kroah-Hartman <gregkh@linuxfoundation.org>; Jingoo Han
> <jingoohan1@gmail.com>; Gustavo Pimentel
> <gustavo.pimentel@synopsys.com>; Marek Vasut
> <marek.vasut+renesas@gmail.com>; Shawn Lin <shawn.lin@rock-
> chips.com>; Heiko Stuebner <heiko@sntech.de>; Prabhakar Mahadev Lad
> <prabhakar.mahadev-lad.rj@bp.renesas.com>
> Subject: RE: [PATCH v5 1/7] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c
>
> Hi Prabhakar-san,
>
> Thank you for the patch!
>
> > From: Lad Prabhakar, Sent: Saturday, February 29, 2020 12:41 AM
>
> Since your email account is different with the Singed-off-by, I think you
> should add your From: tag here like your v2 patch series.
>
> > This commit renames pcie-rcar.c to pcie-rcar-host.c in preparation for
> > adding support for endpoint mode. CONFIG_PCIE_RCAR is also renamed to
> > CONFIG_PCIE_RCAR_HOST to match the driver name accordingly.
> >
> > In addition to this defconfig file has also been updated to match the
> > new config option.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-
> lad.rj@bp.renesas.com>
> > ---
> >  arch/arm64/configs/defconfig                             | 2 +-
> >  drivers/pci/controller/Kconfig                           | 7 ++++---
> >  drivers/pci/controller/Makefile                          | 2 +-
> >  drivers/pci/controller/{pcie-rcar.c => pcie-rcar-host.c} | 0
> >  4 files changed, 6 insertions(+), 5 deletions(-)  rename
> > drivers/pci/controller/{pcie-rcar.c => pcie-rcar-host.c} (100%)
> >
> > diff --git a/arch/arm64/configs/defconfig
> > b/arch/arm64/configs/defconfig index 0f21288..7a34fce 100644
> > --- a/arch/arm64/configs/defconfig
> > +++ b/arch/arm64/configs/defconfig
> > @@ -185,7 +185,7 @@ CONFIG_HOTPLUG_PCI=y
> CONFIG_HOTPLUG_PCI_ACPI=y
> > CONFIG_PCI_AARDVARK=y  CONFIG_PCI_TEGRA=y -
> CONFIG_PCIE_RCAR=y
> > +CONFIG_PCIE_RCAR_HOST=y
>
> I think you should separate this change.
> To avoid this, I have an idea in the Kconfig like below:
>  - adding PCIE_RCAR_HOST.
>  - keeping PCIE_RCAR and select PCIE_RCAR_HOST here.
>  - adding a description in the help of PCIE_RCAR like "This will be removed
> after defconfig is updated" is better.
>
> The following is a sample. What do you think?
Sound like a plan will do that, I will just append the description "This will be removed
after defconfig is updated" to PCIE_RCAR config option.

Cheers,
--Prabhakar

> ---
> --- a/drivers/pci/controller/Kconfig
> +++ b/drivers/pci/controller/Kconfig
> @@ -58,8 +58,18 @@ config PCIE_RCAR
>  bool "Renesas R-Car PCIe controller"
>  depends on ARCH_RENESAS || COMPILE_TEST
>  depends on PCI_MSI_IRQ_DOMAIN
> +select PCIE_RCAR_HOST
>  help
>    Say Y here if you want PCIe controller support on R-Car SoCs.
> +  This will be removed after defconfig is updated.
> +
> +config PCIE_RCAR_HOST
> +bool "Renesas R-Car PCIe host controller"
> +depends on ARCH_RENESAS || COMPILE_TEST
> +depends on PCI_MSI_IRQ_DOMAIN
> +help
> +  Say Y here if you want PCIe controller support on R-Car SoCs in host
> +  mode.
>
>  config PCI_HOST_COMMON
>  bool
> ---
>
> Best regards,
> Yoshihiro Shimoda
>
> >  CONFIG_PCI_HOST_GENERIC=y
> >  CONFIG_PCI_XGENE=y
> >  CONFIG_PCIE_ALTERA=y
> > diff --git a/drivers/pci/controller/Kconfig
> > b/drivers/pci/controller/Kconfig index f84e5ff..37e0ea7 100644
> > --- a/drivers/pci/controller/Kconfig
> > +++ b/drivers/pci/controller/Kconfig
> > @@ -54,12 +54,13 @@ config PCI_RCAR_GEN2
> >    There are 3 internal PCI controllers available with a single
> >    built-in EHCI/OHCI host controller present on each one.
> >
> > -config PCIE_RCAR
> > -bool "Renesas R-Car PCIe controller"
> > +config PCIE_RCAR_HOST
> > +bool "Renesas R-Car PCIe host controller"
> >  depends on ARCH_RENESAS || COMPILE_TEST
> >  depends on PCI_MSI_IRQ_DOMAIN
> >  help
> > -  Say Y here if you want PCIe controller support on R-Car SoCs.
> > +  Say Y here if you want PCIe controller support on R-Car SoCs in host
> > +  mode.
> >
> >  config PCI_HOST_COMMON
> >  bool
> > diff --git a/drivers/pci/controller/Makefile
> > b/drivers/pci/controller/Makefile index 01b2502..4ca2da6 100644
> > --- a/drivers/pci/controller/Makefile
> > +++ b/drivers/pci/controller/Makefile
> > @@ -7,7 +7,7 @@ obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
> >  obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
> >  obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
> >  obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
> > -obj-$(CONFIG_PCIE_RCAR) += pcie-rcar.o
> > +obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar-host.o
> >  obj-$(CONFIG_PCI_HOST_COMMON) += pci-host-common.o
> >  obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
> >  obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o diff --git
> > a/drivers/pci/controller/pcie-rcar.c
> > b/drivers/pci/controller/pcie-rcar-host.c
> > similarity index 100%
> > rename from drivers/pci/controller/pcie-rcar.c
> > rename to drivers/pci/controller/pcie-rcar-host.c
> > --
> > 2.7.4



Renesas Electronics Europe GmbH, Geschaeftsfuehrer/President: Carsten Jauch, Sitz der Gesellschaft/Registered office: Duesseldorf, Arcadiastrasse 10, 40472 Duesseldorf, Germany, Handelsregister/Commercial Register: Duesseldorf, HRB 3708 USt-IDNr./Tax identification no.: DE 119353406 WEEE-Reg.-Nr./WEEE reg. no.: DE 14978647

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

* RE: [PATCH v5 2/7] PCI: rcar: Move shareable code to a common file
  2020-03-17  7:23   ` Yoshihiro Shimoda
@ 2020-03-17  8:29     ` Prabhakar Mahadev Lad
  0 siblings, 0 replies; 26+ messages in thread
From: Prabhakar Mahadev Lad @ 2020-03-17  8:29 UTC (permalink / raw)
  To: Yoshihiro Shimoda, Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Bjorn Helgaas,
	Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
	Kishon Vijay Abraham I, Lorenzo Pieralisi, Arnd Bergmann,
	Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel, Marek Vasut,
	Shawn Lin, Heiko Stuebner

Hi Yoshihiro-san,

Thank you for the review.

> -----Original Message-----
> From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Sent: 17 March 2020 07:23
> To: Lad Prabhakar <prabhakar.csengg@gmail.com>
> Cc: Andrew Murray <andrew.murray@arm.com>; linux-pci@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-renesas-soc@vger.kernel.org;
> linux-rockchip@lists.infradead.org; linux-kernel@vger.kernel.org;
> devicetree@vger.kernel.org; Prabhakar Mahadev Lad <prabhakar.mahadev-
> lad.rj@bp.renesas.com>; Bjorn Helgaas <bhelgaas@google.com>; Rob
> Herring <robh+dt@kernel.org>; Mark Rutland <mark.rutland@arm.com>;
> Catalin Marinas <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>;
> Kishon Vijay Abraham I <kishon@ti.com>; Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com>; Arnd Bergmann <arnd@arndb.de>; Greg
> Kroah-Hartman <gregkh@linuxfoundation.org>; Jingoo Han
> <jingoohan1@gmail.com>; Gustavo Pimentel
> <gustavo.pimentel@synopsys.com>; Marek Vasut
> <marek.vasut+renesas@gmail.com>; Shawn Lin <shawn.lin@rock-
> chips.com>; Heiko Stuebner <heiko@sntech.de>
> Subject: RE: [PATCH v5 2/7] PCI: rcar: Move shareable code to a common file
>
> Hi Prabhakar-san,
>
> Thank you for the patch!
>
> > From: Lad Prabhakar, Sent: Saturday, February 29, 2020 12:41 AM
> >
> > This patch moves sharable code to common file pcie-rcar.c and the
> > #defines to pcie-rcar.h so that the common code can be reused with
> endpoint driver.
> > There are no functional changes with this patch for the host
> > controller driver.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-
> lad.rj@bp.renesas.com>
> > ---
> >  drivers/pci/controller/Makefile         |   2 +-
> >  drivers/pci/controller/pcie-rcar-host.c | 358 ++++++++------------------------
> >  drivers/pci/controller/pcie-rcar.c      | 117 +++++++++++
> >  drivers/pci/controller/pcie-rcar.h      | 125 +++++++++++
> >  4 files changed, 324 insertions(+), 278 deletions(-)  create mode
> > 100644 drivers/pci/controller/pcie-rcar.c
> >  create mode 100644 drivers/pci/controller/pcie-rcar.h
> >
> > diff --git a/drivers/pci/controller/Makefile
> > b/drivers/pci/controller/Makefile index 4ca2da6..b4ada32 100644
> > --- a/drivers/pci/controller/Makefile
> > +++ b/drivers/pci/controller/Makefile
> > @@ -7,7 +7,7 @@ obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
> >  obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
> >  obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
> >  obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
> > -obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar-host.o
> > +obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar.o pcie-rcar-host.o
> >  obj-$(CONFIG_PCI_HOST_COMMON) += pci-host-common.o
> >  obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
> >  obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o diff --git
> > a/drivers/pci/controller/pcie-rcar-host.c
> > b/drivers/pci/controller/pcie-rcar-host.c
> > index 759c654..93f22d8 100644
> > --- a/drivers/pci/controller/pcie-rcar-host.c
> > +++ b/drivers/pci/controller/pcie-rcar-host.c
> > @@ -1,7 +1,7 @@
> >  // SPDX-License-Identifier: GPL-2.0
> >  /*
> >   * PCIe driver for Renesas R-Car SoCs
> > - *  Copyright (C) 2014 Renesas Electronics Europe Ltd
> > + *  Copyright (C) 2014-2020 Renesas Electronics Europe Ltd
> >   *
> >   * Based on:
> >   *  arch/sh/drivers/pci/pcie-sh7786.c @@ -30,104 +30,7 @@  #include
> > <linux/pm_runtime.h>  #include <linux/slab.h>
> >
> > -#define PCIECAR0x000010
> > -#define PCIECCTLR0x000018
> > -#define  CONFIG_SEND_ENABLEBIT(31)
> > -#define  TYPE0(0 << 8)
> > -#define  TYPE1BIT(8)
> > -#define PCIECDR0x000020
> > -#define PCIEMSR0x000028
> > -#define PCIEINTXR0x000400
> > -#define PCIEPHYSR0x0007f0
> > -#define  PHYRDYBIT(0)
> > -#define PCIEMSITXR0x000840
> > -
> > -/* Transfer control */
> > -#define PCIETCTLR0x02000
> > -#define  DL_DOWNBIT(3)
> > -#define  CFINITBIT(0)
> > -#define PCIETSTR0x02004
> > -#define  DATA_LINK_ACTIVEBIT(0)
> > -#define PCIEERRFR0x02020
> > -#define  UNSUPPORTED_REQUESTBIT(4)
> > -#define PCIEMSIFR0x02044
> > -#define PCIEMSIALR0x02048
> > -#define  MSIFEBIT(0)
> > -#define PCIEMSIAUR0x0204c
> > -#define PCIEMSIIER0x02050
> > -
> > -/* root port address */
> > -#define PCIEPRAR(x)(0x02080 + ((x) * 0x4))
> > -
> > -/* local address reg & mask */
> > -#define PCIELAR(x)(0x02200 + ((x) * 0x20))
> > -#define PCIELAMR(x)(0x02208 + ((x) * 0x20))
> > -#define  LAM_PREFETCHBIT(3)
> > -#define  LAM_64BITBIT(2)
> > -#define  LAR_ENABLEBIT(1)
> > -
> > -/* PCIe address reg & mask */
> > -#define PCIEPALR(x)(0x03400 + ((x) * 0x20))
> > -#define PCIEPAUR(x)(0x03404 + ((x) * 0x20))
> > -#define PCIEPAMR(x)(0x03408 + ((x) * 0x20))
> > -#define PCIEPTCTLR(x)(0x0340c + ((x) * 0x20))
> > -#define  PAR_ENABLEBIT(31)
> > -#define  IO_SPACEBIT(8)
> > -
> > -/* Configuration */
> > -#define PCICONF(x)(0x010000 + ((x) * 0x4))
> > -#define PMCAP(x)(0x010040 + ((x) * 0x4))
> > -#define EXPCAP(x)(0x010070 + ((x) * 0x4))
> > -#define VCCAP(x)(0x010100 + ((x) * 0x4))
> > -
> > -/* link layer */
> > -#define IDSETR10x011004
> > -#define TLCTLR0x011048
> > -#define MACSR0x011054
> > -#define  SPCHGFINBIT(4)
> > -#define  SPCHGFAILBIT(6)
> > -#define  SPCHGSUCBIT(7)
> > -#define  LINK_SPEED(0xf << 16)
> > -#define  LINK_SPEED_2_5GTS(1 << 16)
> > -#define  LINK_SPEED_5_0GTS(2 << 16)
> > -#define MACCTLR0x011058
> > -#define  MACCTLR_NFTS_MASKGENMASK(23, 16)/* The name
> is from SH7786 */
> > -#define  SPEED_CHANGEBIT(24)
> > -#define  SCRAMBLE_DISABLEBIT(27)
> > -#define  LTSMDISBIT(31)
> > -#define  MACCTLR_INIT_VAL(LTSMDIS | MACCTLR_NFTS_MASK)
> > -#define PMSR0x01105c
> > -#define MACS2R0x011078
> > -#define MACCGSPSETR0x011084
> > -#define  SPCNGRSNBIT(31)
> > -
> > -/* R-Car H1 PHY */
> > -#define H1_PCIEPHYADRR0x04000c
> > -#define  WRITE_CMDBIT(16)
> > -#define  PHY_ACKBIT(24)
> > -#define  RATE_POS12
> > -#define  LANE_POS8
> > -#define  ADR_POS0
> > -#define H1_PCIEPHYDOUTR0x040014
> > -
> > -/* R-Car Gen2 PHY */
> > -#define GEN2_PCIEPHYADDR0x780
> > -#define GEN2_PCIEPHYDATA0x784
> > -#define GEN2_PCIEPHYCTRL0x78c
> > -
> > -#define INT_PCI_MSI_NR32
> > -
> > -#define RCONF(x)(PCICONF(0) + (x))
> > -#define RPMCAP(x)(PMCAP(0) + (x))
> > -#define REXPCAP(x)(EXPCAP(0) + (x))
> > -#define RVCCAP(x)(VCCAP(0) + (x))
> > -
> > -#define PCIE_CONF_BUS(b)(((b) & 0xff) << 24)
> > -#define PCIE_CONF_DEV(d)(((d) & 0x1f) << 19)
> > -#define PCIE_CONF_FUNC(f)(((f) & 0x7) << 16)
> > -
> > -#define RCAR_PCI_MAX_RESOURCES4
> > -#define MAX_NR_INBOUND_MAPS6
> > +#include "pcie-rcar.h"
> >
> >  struct rcar_msi {
> >  DECLARE_BITMAP(used, INT_PCI_MSI_NR); @@ -155,36 +58,10 @@
> struct
> > rcar_pcie {
> >  structrcar_msi msi;
> >  };
> >
> > -static void rcar_pci_write_reg(struct rcar_pcie *pcie, u32 val,
> > -       unsigned int reg)
> > -{
> > -writel(val, pcie->base + reg);
> > -}
> > -
> > -static u32 rcar_pci_read_reg(struct rcar_pcie *pcie, unsigned int
> > reg) -{
> > -return readl(pcie->base + reg);
> > -}
> > -
> > -enum {
> > -RCAR_PCI_ACCESS_READ,
> > -RCAR_PCI_ACCESS_WRITE,
> > -};
> > -
> > -static void rcar_rmw32(struct rcar_pcie *pcie, int where, u32 mask,
> > u32 data) -{
> > -unsigned int shift = BITS_PER_BYTE * (where & 3);
> > -u32 val = rcar_pci_read_reg(pcie, where & ~3);
> > -
> > -val &= ~(mask << shift);
> > -val |= data << shift;
> > -rcar_pci_write_reg(pcie, val, where & ~3);
> > -}
> > -
> >  static u32 rcar_read_conf(struct rcar_pcie *pcie, int where)  {
> >  unsigned int shift = BITS_PER_BYTE * (where & 3);
> > -u32 val = rcar_pci_read_reg(pcie, where & ~3);
> > +u32 val = rcar_pci_read_reg(pcie->base, where & ~3);
>
> I'd like to avoid these many changes about "pcie" to "pcie->base" somehow.
> My idea is moving declaration of struct rcar_pcie to rcar-pcie.h and use it
> from both host and ep codes. According to the patch 6/7, the rcar-pcie-ep.c
> also has the same name of struct rcar_pcie and this has the same "base" and
> "dev.
> So, common rcar_pcie should have these members. Remaining members are
> contained on renamed structures like "rcar_pcie_host" and "rcar_pcie_ep".
> And then, the rcar_pcie_{host,ep} have struct rcar_pcie pcie member.
>
Agreed will do that.

Cheers,
--Prabhakar

> Best regards,
> Yoshihiro Shimoda
>
> >  return val >> shift;
> >  }
> > @@ -221,13 +98,13 @@ static int rcar_pcie_config_access(struct rcar_pcie
> *pcie,
> >  return PCIBIOS_DEVICE_NOT_FOUND;
> >
> >  if (access_type == RCAR_PCI_ACCESS_READ) {
> > -*data = rcar_pci_read_reg(pcie, PCICONF(index));
> > +*data = rcar_pci_read_reg(pcie->base,
> PCICONF(index));
> >  } else {
> >  /* Keep an eye out for changes to the root bus
> number */
> >  if (pci_is_root_bus(bus) && (reg ==
> PCI_PRIMARY_BUS))
> >  pcie->root_bus_nr = *data & 0xff;
> >
> > -rcar_pci_write_reg(pcie, *data, PCICONF(index));
> > +rcar_pci_write_reg(pcie->base, *data,
> PCICONF(index));
> >  }
> >
> >  return PCIBIOS_SUCCESSFUL;
> > @@ -237,20 +114,23 @@ static int rcar_pcie_config_access(struct rcar_pcie
> *pcie,
> >  return PCIBIOS_DEVICE_NOT_FOUND;
> >
> >  /* Clear errors */
> > -rcar_pci_write_reg(pcie, rcar_pci_read_reg(pcie, PCIEERRFR),
> PCIEERRFR);
> > +rcar_pci_write_reg(pcie->base, rcar_pci_read_reg(pcie->base,
> PCIEERRFR),
> > +   PCIEERRFR);
> >
> >  /* Set the PIO address */
> > -rcar_pci_write_reg(pcie, PCIE_CONF_BUS(bus->number) |
> > +rcar_pci_write_reg(pcie->base, PCIE_CONF_BUS(bus->number) |
> >  PCIE_CONF_DEV(dev) | PCIE_CONF_FUNC(func) | reg,
> PCIECAR);
> >
> >  /* Enable the configuration access */
> >  if (bus->parent->number == pcie->root_bus_nr)
> > -rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE0,
> PCIECCTLR);
> > +rcar_pci_write_reg(pcie->base, CONFIG_SEND_ENABLE |
> TYPE0,
> > +   PCIECCTLR);
> >  else
> > -rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE1,
> PCIECCTLR);
> > +rcar_pci_write_reg(pcie->base, CONFIG_SEND_ENABLE |
> TYPE1,
> > +   PCIECCTLR);
> >
> >  /* Check for errors */
> > -if (rcar_pci_read_reg(pcie, PCIEERRFR) & UNSUPPORTED_REQUEST)
> > +if (rcar_pci_read_reg(pcie->base, PCIEERRFR) &
> UNSUPPORTED_REQUEST)
> >  return PCIBIOS_DEVICE_NOT_FOUND;
> >
> >  /* Check for master and target aborts */ @@ -259,12 +139,12 @@
> > static int rcar_pcie_config_access(struct rcar_pcie *pcie,
> >  return PCIBIOS_DEVICE_NOT_FOUND;
> >
> >  if (access_type == RCAR_PCI_ACCESS_READ)
> > -*data = rcar_pci_read_reg(pcie, PCIECDR);
> > +*data = rcar_pci_read_reg(pcie->base, PCIECDR);
> >  else
> > -rcar_pci_write_reg(pcie, *data, PCIECDR);
> > +rcar_pci_write_reg(pcie->base, *data, PCIECDR);
> >
> >  /* Disable the configuration access */
> > -rcar_pci_write_reg(pcie, 0, PCIECCTLR);
> > +rcar_pci_write_reg(pcie->base, 0, PCIECCTLR);
> >
> >  return PCIBIOS_SUCCESSFUL;
> >  }
> > @@ -332,41 +212,6 @@ static struct pci_ops rcar_pcie_ops = {
> >  .write= rcar_pcie_write_conf,
> >  };
> >
> > -static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie,
> > -   struct resource *res)
> > -{
> > -/* Setup PCIe address space mappings for each resource */
> > -resource_size_t size;
> > -resource_size_t res_start;
> > -u32 mask;
> > -
> > -rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
> > -
> > -/*
> > - * The PAMR mask is calculated in units of 128Bytes, which
> > - * keeps things pretty simple.
> > - */
> > -size = resource_size(res);
> > -mask = (roundup_pow_of_two(size) / SZ_128) - 1;
> > -rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
> > -
> > -if (res->flags & IORESOURCE_IO)
> > -res_start = pci_pio_to_address(res->start);
> > -else
> > -res_start = res->start;
> > -
> > -rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPAUR(win));
> > -rcar_pci_write_reg(pcie, lower_32_bits(res_start) & ~0x7F,
> > -   PCIEPALR(win));
> > -
> > -/* First resource is for IO */
> > -mask = PAR_ENABLE;
> > -if (res->flags & IORESOURCE_IO)
> > -mask |= IO_SPACE;
> > -
> > -rcar_pci_write_reg(pcie, mask, PCIEPTCTLR(win));
> > -}
> > -
> >  static int rcar_pcie_setup(struct list_head *resource, struct
> > rcar_pcie *pci)  {
> >  struct resource_entry *win;
> > @@ -382,7 +227,7 @@ static int rcar_pcie_setup(struct list_head
> *resource, struct rcar_pcie *pci)
> >  switch (resource_type(res)) {
> >  case IORESOURCE_IO:
> >  case IORESOURCE_MEM:
> > -rcar_pcie_setup_window(i, pci, res);
> > +rcar_pcie_set_outbound(i, pci->base, res);
> >  i++;
> >  break;
> >  case IORESOURCE_BUS:
> > @@ -404,37 +249,38 @@ static void rcar_pcie_force_speedup(struct
> rcar_pcie *pcie)
> >  unsigned int timeout = 1000;
> >  u32 macsr;
> >
> > -if ((rcar_pci_read_reg(pcie, MACS2R) & LINK_SPEED) !=
> LINK_SPEED_5_0GTS)
> > +if ((rcar_pci_read_reg(pcie->base, MACS2R) & LINK_SPEED) !=
> > +LINK_SPEED_5_0GTS)
> >  return;
> >
> > -if (rcar_pci_read_reg(pcie, MACCTLR) & SPEED_CHANGE) {
> > +if (rcar_pci_read_reg(pcie->base, MACCTLR) & SPEED_CHANGE) {
> >  dev_err(dev, "Speed change already in progress\n");
> >  return;
> >  }
> >
> > -macsr = rcar_pci_read_reg(pcie, MACSR);
> > +macsr = rcar_pci_read_reg(pcie->base, MACSR);
> >  if ((macsr & LINK_SPEED) == LINK_SPEED_5_0GTS)
> >  goto done;
> >
> >  /* Set target link speed to 5.0 GT/s */
> > -rcar_rmw32(pcie, EXPCAP(12), PCI_EXP_LNKSTA_CLS,
> > +rcar_rmw32(pcie->base, EXPCAP(12), PCI_EXP_LNKSTA_CLS,
> >     PCI_EXP_LNKSTA_CLS_5_0GB);
> >
> >  /* Set speed change reason as intentional factor */
> > -rcar_rmw32(pcie, MACCGSPSETR, SPCNGRSN, 0);
> > +rcar_rmw32(pcie->base, MACCGSPSETR, SPCNGRSN, 0);
> >
> >  /* Clear SPCHGFIN, SPCHGSUC, and SPCHGFAIL */
> >  if (macsr & (SPCHGFIN | SPCHGSUC | SPCHGFAIL))
> > -rcar_pci_write_reg(pcie, macsr, MACSR);
> > +rcar_pci_write_reg(pcie->base, macsr, MACSR);
> >
> >  /* Start link speed change */
> > -rcar_rmw32(pcie, MACCTLR, SPEED_CHANGE, SPEED_CHANGE);
> > +rcar_rmw32(pcie->base, MACCTLR, SPEED_CHANGE,
> SPEED_CHANGE);
> >
> >  while (timeout--) {
> > -macsr = rcar_pci_read_reg(pcie, MACSR);
> > +macsr = rcar_pci_read_reg(pcie->base, MACSR);
> >  if (macsr & SPCHGFIN) {
> >  /* Clear the interrupt bits */
> > -rcar_pci_write_reg(pcie, macsr, MACSR);
> > +rcar_pci_write_reg(pcie->base, macsr, MACSR);
> >
> >  if (macsr & SPCHGFAIL)
> >  dev_err(dev, "Speed change failed\n"); @@
> -498,7 +344,7 @@ static
> > int phy_wait_for_ack(struct rcar_pcie *pcie)
> >  unsigned int timeout = 100;
> >
> >  while (timeout--) {
> > -if (rcar_pci_read_reg(pcie, H1_PCIEPHYADRR) & PHY_ACK)
> > +if (rcar_pci_read_reg(pcie->base, H1_PCIEPHYADRR) &
> PHY_ACK)
> >  return 0;
> >
> >  udelay(100);
> > @@ -521,60 +367,31 @@ static void phy_write_reg(struct rcar_pcie *pcie,
> >  ((addr & 0xff) << ADR_POS);
> >
> >  /* Set write data */
> > -rcar_pci_write_reg(pcie, data, H1_PCIEPHYDOUTR);
> > -rcar_pci_write_reg(pcie, phyaddr, H1_PCIEPHYADRR);
> > +rcar_pci_write_reg(pcie->base, data, H1_PCIEPHYDOUTR);
> > +rcar_pci_write_reg(pcie->base, phyaddr, H1_PCIEPHYADRR);
> >
> >  /* Ignore errors as they will be dealt with if the data link is down */
> >  phy_wait_for_ack(pcie);
> >
> >  /* Clear command */
> > -rcar_pci_write_reg(pcie, 0, H1_PCIEPHYDOUTR);
> > -rcar_pci_write_reg(pcie, 0, H1_PCIEPHYADRR);
> > +rcar_pci_write_reg(pcie->base, 0, H1_PCIEPHYDOUTR);
> > +rcar_pci_write_reg(pcie->base, 0, H1_PCIEPHYADRR);
> >
> >  /* Ignore errors as they will be dealt with if the data link is down */
> >  phy_wait_for_ack(pcie);
> >  }
> >
> > -static int rcar_pcie_wait_for_phyrdy(struct rcar_pcie *pcie) -{
> > -unsigned int timeout = 10;
> > -
> > -while (timeout--) {
> > -if (rcar_pci_read_reg(pcie, PCIEPHYSR) & PHYRDY)
> > -return 0;
> > -
> > -msleep(5);
> > -}
> > -
> > -return -ETIMEDOUT;
> > -}
> > -
> > -static int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie) -{
> > -unsigned int timeout = 10000;
> > -
> > -while (timeout--) {
> > -if ((rcar_pci_read_reg(pcie, PCIETSTR) &
> DATA_LINK_ACTIVE))
> > -return 0;
> > -
> > -udelay(5);
> > -cpu_relax();
> > -}
> > -
> > -return -ETIMEDOUT;
> > -}
> > -
> >  static int rcar_pcie_hw_init(struct rcar_pcie *pcie)  {
> >  int err;
> >
> >  /* Begin initialization */
> > -rcar_pci_write_reg(pcie, 0, PCIETCTLR);
> > +rcar_pci_write_reg(pcie->base, 0, PCIETCTLR);
> >
> >  /* Set mode */
> > -rcar_pci_write_reg(pcie, 1, PCIEMSR);
> > +rcar_pci_write_reg(pcie->base, 1, PCIEMSR);
> >
> > -err = rcar_pcie_wait_for_phyrdy(pcie);
> > +err = rcar_pcie_wait_for_phyrdy(pcie->base);
> >  if (err)
> >  return err;
> >
> > @@ -583,51 +400,51 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
> >   * class to match. Hardware takes care of propagating the IDSETR
> >   * settings, so there is no need to bother with a quirk.
> >   */
> > -rcar_pci_write_reg(pcie, PCI_CLASS_BRIDGE_PCI << 16, IDSETR1);
> > +rcar_pci_write_reg(pcie->base, PCI_CLASS_BRIDGE_PCI << 16,
> IDSETR1);
> >
> >  /*
> >   * Setup Secondary Bus Number & Subordinate Bus Number, even
> though
> >   * they aren't used, to avoid bridge being detected as broken.
> >   */
> > -rcar_rmw32(pcie, RCONF(PCI_SECONDARY_BUS), 0xff, 1);
> > -rcar_rmw32(pcie, RCONF(PCI_SUBORDINATE_BUS), 0xff, 1);
> > +rcar_rmw32(pcie->base, RCONF(PCI_SECONDARY_BUS), 0xff, 1);
> > +rcar_rmw32(pcie->base, RCONF(PCI_SUBORDINATE_BUS), 0xff, 1);
> >
> >  /* Initialize default capabilities. */
> > -rcar_rmw32(pcie, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
> > -rcar_rmw32(pcie, REXPCAP(PCI_EXP_FLAGS),
> > -PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ROOT_PORT << 4);
> > -rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
> > -PCI_HEADER_TYPE_BRIDGE);
> > +rcar_rmw32(pcie->base, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
> > +rcar_rmw32(pcie->base, REXPCAP(PCI_EXP_FLAGS),
> > +   PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ROOT_PORT << 4);
> > +rcar_rmw32(pcie->base, RCONF(PCI_HEADER_TYPE), 0x7f,
> > +   PCI_HEADER_TYPE_BRIDGE);
> >
> >  /* Enable data link layer active state reporting */
> > -rcar_rmw32(pcie, REXPCAP(PCI_EXP_LNKCAP),
> PCI_EXP_LNKCAP_DLLLARC,
> > -PCI_EXP_LNKCAP_DLLLARC);
> > +rcar_rmw32(pcie->base, REXPCAP(PCI_EXP_LNKCAP),
> PCI_EXP_LNKCAP_DLLLARC,
> > +   PCI_EXP_LNKCAP_DLLLARC);
> >
> >  /* Write out the physical slot number = 0 */
> > -rcar_rmw32(pcie, REXPCAP(PCI_EXP_SLTCAP),
> PCI_EXP_SLTCAP_PSN, 0);
> > +rcar_rmw32(pcie->base, REXPCAP(PCI_EXP_SLTCAP),
> PCI_EXP_SLTCAP_PSN,
> > +0);
> >
> >  /* Set the completion timer timeout to the maximum 50ms. */
> > -rcar_rmw32(pcie, TLCTLR + 1, 0x3f, 50);
> > +rcar_rmw32(pcie->base, TLCTLR + 1, 0x3f, 50);
> >
> >  /* Terminate list of capabilities (Next Capability Offset=0) */
> > -rcar_rmw32(pcie, RVCCAP(0), 0xfff00000, 0);
> > +rcar_rmw32(pcie->base, RVCCAP(0), 0xfff00000, 0);
> >
> >  /* Enable MSI */
> >  if (IS_ENABLED(CONFIG_PCI_MSI))
> > -rcar_pci_write_reg(pcie, 0x801f0000, PCIEMSITXR);
> > +rcar_pci_write_reg(pcie->base, 0x801f0000, PCIEMSITXR);
> >
> > -rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR);
> > +rcar_pci_write_reg(pcie->base, MACCTLR_INIT_VAL, MACCTLR);
> >
> >  /* Finish initialization - establish a PCI Express link */
> > -rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR);
> > +rcar_pci_write_reg(pcie->base, CFINIT, PCIETCTLR);
> >
> >  /* This will timeout if we don't have a link. */
> > -err = rcar_pcie_wait_for_dl(pcie);
> > +err = rcar_pcie_wait_for_dl(pcie->base);
> >  if (err)
> >  return err;
> >
> >  /* Enable INTx interrupts */
> > -rcar_rmw32(pcie, PCIEINTXR, 0, 0xF << 8);
> > +rcar_rmw32(pcie->base, PCIEINTXR, 0, 0xF << 8);
> >
> >  wmb();
> >
> > @@ -663,16 +480,16 @@ static int rcar_pcie_phy_init_gen2(struct
> rcar_pcie *pcie)
> >   * These settings come from the R-Car Series, 2nd Generation User's
> >   * Manual, section 50.3.1 (2) Initialization of the physical layer.
> >   */
> > -rcar_pci_write_reg(pcie, 0x000f0030, GEN2_PCIEPHYADDR);
> > -rcar_pci_write_reg(pcie, 0x00381203, GEN2_PCIEPHYDATA);
> > -rcar_pci_write_reg(pcie, 0x00000001, GEN2_PCIEPHYCTRL);
> > -rcar_pci_write_reg(pcie, 0x00000006, GEN2_PCIEPHYCTRL);
> > +rcar_pci_write_reg(pcie->base, 0x000f0030, GEN2_PCIEPHYADDR);
> > +rcar_pci_write_reg(pcie->base, 0x00381203, GEN2_PCIEPHYDATA);
> > +rcar_pci_write_reg(pcie->base, 0x00000001, GEN2_PCIEPHYCTRL);
> > +rcar_pci_write_reg(pcie->base, 0x00000006, GEN2_PCIEPHYCTRL);
> >
> > -rcar_pci_write_reg(pcie, 0x000f0054, GEN2_PCIEPHYADDR);
> > +rcar_pci_write_reg(pcie->base, 0x000f0054, GEN2_PCIEPHYADDR);
> >  /* The following value is for DC connection, no termination resistor
> */
> > -rcar_pci_write_reg(pcie, 0x13802007, GEN2_PCIEPHYDATA);
> > -rcar_pci_write_reg(pcie, 0x00000001, GEN2_PCIEPHYCTRL);
> > -rcar_pci_write_reg(pcie, 0x00000006, GEN2_PCIEPHYCTRL);
> > +rcar_pci_write_reg(pcie->base, 0x13802007, GEN2_PCIEPHYDATA);
> > +rcar_pci_write_reg(pcie->base, 0x00000001, GEN2_PCIEPHYCTRL);
> > +rcar_pci_write_reg(pcie->base, 0x00000006, GEN2_PCIEPHYCTRL);
> >
> >  return 0;
> >  }
> > @@ -735,7 +552,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void
> *data)
> >  struct device *dev = pcie->dev;
> >  unsigned long reg;
> >
> > -reg = rcar_pci_read_reg(pcie, PCIEMSIFR);
> > +reg = rcar_pci_read_reg(pcie->base, PCIEMSIFR);
> >
> >  /* MSI & INTx share an interrupt - we only handle MSI here */
> >  if (!reg)
> > @@ -746,7 +563,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void
> *data)
> >  unsigned int msi_irq;
> >
> >  /* clear the interrupt */
> > -rcar_pci_write_reg(pcie, 1 << index, PCIEMSIFR);
> > +rcar_pci_write_reg(pcie->base, 1 << index, PCIEMSIFR);
> >
> >  msi_irq = irq_find_mapping(msi->domain, index);
> >  if (msi_irq) {
> > @@ -760,7 +577,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void
> *data)
> >  }
> >
> >  /* see if there's any more pending in this vector */
> > -reg = rcar_pci_read_reg(pcie, PCIEMSIFR);
> > +reg = rcar_pci_read_reg(pcie->base, PCIEMSIFR);
> >  }
> >
> >  return IRQ_HANDLED;
> > @@ -787,8 +604,8 @@ static int rcar_msi_setup_irq(struct
> > msi_controller *chip, struct pci_dev *pdev,
> >
> >  irq_set_msi_desc(irq, desc);
> >
> > -msg.address_lo = rcar_pci_read_reg(pcie, PCIEMSIALR) & ~MSIFE;
> > -msg.address_hi = rcar_pci_read_reg(pcie, PCIEMSIAUR);
> > +msg.address_lo = rcar_pci_read_reg(pcie->base, PCIEMSIALR) &
> ~MSIFE;
> > +msg.address_hi = rcar_pci_read_reg(pcie->base, PCIEMSIAUR);
> >  msg.data = hwirq;
> >
> >  pci_write_msi_msg(irq, &msg);
> > @@ -839,8 +656,8 @@ static int rcar_msi_setup_irqs(struct msi_controller
> *chip,
> >  desc->nvec_used = nvec;
> >  desc->msi_attrib.multiple = order_base_2(nvec);
> >
> > -msg.address_lo = rcar_pci_read_reg(pcie, PCIEMSIALR) & ~MSIFE;
> > -msg.address_hi = rcar_pci_read_reg(pcie, PCIEMSIAUR);
> > +msg.address_lo = rcar_pci_read_reg(pcie->base, PCIEMSIALR) &
> ~MSIFE;
> > +msg.address_hi = rcar_pci_read_reg(pcie->base, PCIEMSIAUR);
> >  msg.data = hwirq;
> >
> >  pci_write_msi_msg(irq, &msg);
> > @@ -940,11 +757,11 @@ static int rcar_pcie_enable_msi(struct rcar_pcie
> *pcie)
> >  }
> >  base = virt_to_phys((void *)msi->pages);
> >
> > -rcar_pci_write_reg(pcie, lower_32_bits(base) | MSIFE, PCIEMSIALR);
> > -rcar_pci_write_reg(pcie, upper_32_bits(base), PCIEMSIAUR);
> > +rcar_pci_write_reg(pcie->base, lower_32_bits(base) | MSIFE,
> PCIEMSIALR);
> > +rcar_pci_write_reg(pcie->base, upper_32_bits(base), PCIEMSIAUR);
> >
> >  /* enable all MSI interrupts */
> > -rcar_pci_write_reg(pcie, 0xffffffff, PCIEMSIIER);
> > +rcar_pci_write_reg(pcie->base, 0xffffffff, PCIEMSIIER);
> >
> >  return 0;
> >
> > @@ -958,10 +775,10 @@ static void rcar_pcie_teardown_msi(struct
> rcar_pcie *pcie)
> >  struct rcar_msi *msi = &pcie->msi;
> >
> >  /* Disable all MSI interrupts */
> > -rcar_pci_write_reg(pcie, 0, PCIEMSIIER);
> > +rcar_pci_write_reg(pcie->base, 0, PCIEMSIIER);
> >
> >  /* Disable address decoding of the MSI interrupt, MSIFE */
> > -rcar_pci_write_reg(pcie, 0, PCIEMSIALR);
> > +rcar_pci_write_reg(pcie->base, 0, PCIEMSIALR);
> >
> >  free_pages(msi->pages, 0);
> >
> > @@ -1054,21 +871,8 @@ static int rcar_pcie_inbound_ranges(struct
> rcar_pcie *pcie,
> >  mask = roundup_pow_of_two(size) - 1;
> >  mask &= ~0xf;
> >
> > -/*
> > - * Set up 64-bit inbound regions as the range parser doesn't
> > - * distinguish between 32 and 64-bit types.
> > - */
> > -rcar_pci_write_reg(pcie, lower_32_bits(pci_addr),
> > -   PCIEPRAR(idx));
> > -rcar_pci_write_reg(pcie, lower_32_bits(cpu_addr),
> PCIELAR(idx));
> > -rcar_pci_write_reg(pcie, lower_32_bits(mask) | flags,
> > -   PCIELAMR(idx));
> > -
> > -rcar_pci_write_reg(pcie, upper_32_bits(pci_addr),
> > -   PCIEPRAR(idx + 1));
> > -rcar_pci_write_reg(pcie, upper_32_bits(cpu_addr),
> > -   PCIELAR(idx + 1));
> > -rcar_pci_write_reg(pcie, 0, PCIELAMR(idx + 1));
> > +rcar_pcie_set_inbound(pcie->base, cpu_addr, pci_addr,
> > +      lower_32_bits(mask) | flags, idx, true);
> >
> >  pci_addr += size;
> >  cpu_addr += size;
> > @@ -1170,7 +974,7 @@ static int rcar_pcie_probe(struct platform_device
> *pdev)
> >  goto err_phy_shutdown;
> >  }
> >
> > -data = rcar_pci_read_reg(pcie, MACSR);
> > +data = rcar_pci_read_reg(pcie->base, MACSR);
> >  dev_info(dev, "PCIe x%d: link up\n", (data >> 20) & 0x3f);
> >
> >  if (IS_ENABLED(CONFIG_PCI_MSI)) {
> > @@ -1223,14 +1027,14 @@ static int rcar_pcie_resume_noirq(struct
> > device *dev)  {
> >  struct rcar_pcie *pcie = dev_get_drvdata(dev);
> >
> > -if (rcar_pci_read_reg(pcie, PMSR) &&
> > -    !(rcar_pci_read_reg(pcie, PCIETCTLR) & DL_DOWN))
> > +if (rcar_pci_read_reg(pcie->base, PMSR) &&
> > +    !(rcar_pci_read_reg(pcie->base, PCIETCTLR) & DL_DOWN))
> >  return 0;
> >
> >  /* Re-establish the PCIe link */
> > -rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR);
> > -rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR);
> > -return rcar_pcie_wait_for_dl(pcie);
> > +rcar_pci_write_reg(pcie->base, MACCTLR_INIT_VAL, MACCTLR);
> > +rcar_pci_write_reg(pcie->base, CFINIT, PCIETCTLR);
> > +return rcar_pcie_wait_for_dl(pcie->base);
> >  }
> >
> >  static const struct dev_pm_ops rcar_pcie_pm_ops = { diff --git
> > a/drivers/pci/controller/pcie-rcar.c
> > b/drivers/pci/controller/pcie-rcar.c
> > new file mode 100644
> > index 0000000..41275f9
> > --- /dev/null
> > +++ b/drivers/pci/controller/pcie-rcar.c
> > @@ -0,0 +1,117 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * PCIe driver for Renesas R-Car SoCs
> > + *  Copyright (C) 2014-2020 Renesas Electronics Europe Ltd
> > + *
> > + * Author: Phil Edworthy <phil.edworthy@renesas.com>  */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/pci.h>
> > +
> > +#include "pcie-rcar.h"
> > +
> > +void rcar_pci_write_reg(void __iomem *base, u32 val, unsigned int
> > +reg) {
> > +writel(val, base + reg);
> > +}
> > +
> > +u32 rcar_pci_read_reg(void __iomem *base, unsigned int reg) {
> > +return readl(base + reg);
> > +}
> > +
> > +void rcar_rmw32(void __iomem *base, int where, u32 mask, u32 data) {
> > +unsigned int shift = BITS_PER_BYTE * (where & 3);
> > +u32 val = rcar_pci_read_reg(base, where & ~3);
> > +
> > +val &= ~(mask << shift);
> > +val |= data << shift;
> > +rcar_pci_write_reg(base, val, where & ~3); }
> > +
> > +int rcar_pcie_wait_for_phyrdy(void __iomem *base) {
> > +unsigned int timeout = 10;
> > +
> > +while (timeout--) {
> > +if (rcar_pci_read_reg(base, PCIEPHYSR) & PHYRDY)
> > +return 0;
> > +
> > +msleep(5);
> > +}
> > +
> > +return -ETIMEDOUT;
> > +}
> > +
> > +int rcar_pcie_wait_for_dl(void __iomem *base) {
> > +unsigned int timeout = 10000;
> > +
> > +while (timeout--) {
> > +if ((rcar_pci_read_reg(base, PCIETSTR) &
> DATA_LINK_ACTIVE))
> > +return 0;
> > +
> > +udelay(5);
> > +cpu_relax();
> > +}
> > +
> > +return -ETIMEDOUT;
> > +}
> > +
> > +void rcar_pcie_set_outbound(int win, void __iomem *base,
> > +    struct resource *res)
> > +{
> > +/* Setup PCIe address space mappings for each resource */
> > +resource_size_t res_start;
> > +resource_size_t size;
> > +u32 mask;
> > +
> > +rcar_pci_write_reg(base, 0x00000000, PCIEPTCTLR(win));
> > +
> > +/*
> > + * The PAMR mask is calculated in units of 128Bytes, which
> > + * keeps things pretty simple.
> > + */
> > +size = resource_size(res);
> > +mask = (roundup_pow_of_two(size) / SZ_128) - 1;
> > +rcar_pci_write_reg(base, mask << 7, PCIEPAMR(win));
> > +
> > +if (res->flags & IORESOURCE_IO)
> > +res_start = pci_pio_to_address(res->start);
> > +else
> > +res_start = res->start;
> > +
> > +rcar_pci_write_reg(base, upper_32_bits(res_start), PCIEPAUR(win));
> > +rcar_pci_write_reg(base, lower_32_bits(res_start) & ~0x7F,
> > +   PCIEPALR(win));
> > +
> > +/* First resource is for IO */
> > +mask = PAR_ENABLE;
> > +if (res->flags & IORESOURCE_IO)
> > +mask |= IO_SPACE;
> > +
> > +rcar_pci_write_reg(base, mask, PCIEPTCTLR(win)); }
> > +
> > +void rcar_pcie_set_inbound(void __iomem *base,
> > +   u64 cpu_addr, u64 pci_addr,
> > +   u64 flags, int idx, bool host)
> > +{
> > +/*
> > + * Set up 64-bit inbound regions as the range parser doesn't
> > + * distinguish between 32 and 64-bit types.
> > + */
> > +if (host)
> > +rcar_pci_write_reg(base, lower_32_bits(pci_addr),
> > +   PCIEPRAR(idx));
> > +rcar_pci_write_reg(base, lower_32_bits(cpu_addr), PCIELAR(idx));
> > +rcar_pci_write_reg(base, flags, PCIELAMR(idx));
> > +
> > +if (host)
> > +rcar_pci_write_reg(base, upper_32_bits(pci_addr),
> > +   PCIEPRAR(idx + 1));
> > +rcar_pci_write_reg(base, upper_32_bits(cpu_addr), PCIELAR(idx +
> 1));
> > +rcar_pci_write_reg(base, 0, PCIELAMR(idx + 1)); }
> > diff --git a/drivers/pci/controller/pcie-rcar.h
> > b/drivers/pci/controller/pcie-rcar.h
> > new file mode 100644
> > index 0000000..b529d806
> > --- /dev/null
> > +++ b/drivers/pci/controller/pcie-rcar.h
> > @@ -0,0 +1,125 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * PCIe driver for Renesas R-Car SoCs
> > + *  Copyright (C) 2014-2020 Renesas Electronics Europe Ltd
> > + *
> > + * Author: Phil Edworthy <phil.edworthy@renesas.com>  */
> > +
> > +#ifndef _PCIE_RCAR_H
> > +#define _PCIE_RCAR_H
> > +
> > +#define PCIECAR0x000010
> > +#define PCIECCTLR0x000018
> > +#define  CONFIG_SEND_ENABLEBIT(31)
> > +#define  TYPE0(0 << 8)
> > +#define  TYPE1BIT(8)
> > +#define PCIECDR0x000020
> > +#define PCIEMSR0x000028
> > +#define PCIEINTXR0x000400
> > +#define PCIEPHYSR0x0007f0
> > +#define  PHYRDYBIT(0)
> > +#define PCIEMSITXR0x000840
> > +
> > +/* Transfer control */
> > +#define PCIETCTLR0x02000
> > +#define  DL_DOWNBIT(3)
> > +#define  CFINITBIT(0)
> > +#define PCIETSTR0x02004
> > +#define  DATA_LINK_ACTIVEBIT(0)
> > +#define PCIEERRFR0x02020
> > +#define  UNSUPPORTED_REQUESTBIT(4)
> > +#define PCIEMSIFR0x02044
> > +#define PCIEMSIALR0x02048
> > +#define  MSIFEBIT(0)
> > +#define PCIEMSIAUR0x0204c
> > +#define PCIEMSIIER0x02050
> > +
> > +/* root port address */
> > +#define PCIEPRAR(x)(0x02080 + ((x) * 0x4))
> > +
> > +/* local address reg & mask */
> > +#define PCIELAR(x)(0x02200 + ((x) * 0x20))
> > +#define PCIELAMR(x)(0x02208 + ((x) * 0x20))
> > +#define  LAM_PREFETCHBIT(3)
> > +#define  LAM_64BITBIT(2)
> > +#define  LAR_ENABLEBIT(1)
> > +
> > +/* PCIe address reg & mask */
> > +#define PCIEPALR(x)(0x03400 + ((x) * 0x20))
> > +#define PCIEPAUR(x)(0x03404 + ((x) * 0x20))
> > +#define PCIEPAMR(x)(0x03408 + ((x) * 0x20))
> > +#define PCIEPTCTLR(x)(0x0340c + ((x) * 0x20))
> > +#define  PAR_ENABLEBIT(31)
> > +#define  IO_SPACEBIT(8)
> > +
> > +/* Configuration */
> > +#define PCICONF(x)(0x010000 + ((x) * 0x4))
> > +#define PMCAP(x)(0x010040 + ((x) * 0x4))
> > +#define EXPCAP(x)(0x010070 + ((x) * 0x4))
> > +#define VCCAP(x)(0x010100 + ((x) * 0x4))
> > +
> > +/* link layer */
> > +#define IDSETR10x011004
> > +#define TLCTLR0x011048
> > +#define MACSR0x011054
> > +#define  SPCHGFINBIT(4)
> > +#define  SPCHGFAILBIT(6)
> > +#define  SPCHGSUCBIT(7)
> > +#define  LINK_SPEED(0xf << 16)
> > +#define  LINK_SPEED_2_5GTS(1 << 16)
> > +#define  LINK_SPEED_5_0GTS(2 << 16)
> > +#define MACCTLR0x011058
> > +#define  MACCTLR_NFTS_MASKGENMASK(23, 16)/* The name
> is from SH7786 */
> > +#define  SPEED_CHANGEBIT(24)
> > +#define  SCRAMBLE_DISABLEBIT(27)
> > +#define  LTSMDISBIT(31)
> > +#define  MACCTLR_INIT_VAL(LTSMDIS | MACCTLR_NFTS_MASK)
> > +#define PMSR0x01105c
> > +#define MACS2R0x011078
> > +#define MACCGSPSETR0x011084
> > +#define  SPCNGRSNBIT(31)
> > +
> > +/* R-Car H1 PHY */
> > +#define H1_PCIEPHYADRR0x04000c
> > +#define  WRITE_CMDBIT(16)
> > +#define  PHY_ACKBIT(24)
> > +#define  RATE_POS12
> > +#define  LANE_POS8
> > +#define  ADR_POS0
> > +#define H1_PCIEPHYDOUTR0x040014
> > +
> > +/* R-Car Gen2 PHY */
> > +#define GEN2_PCIEPHYADDR0x780
> > +#define GEN2_PCIEPHYDATA0x784
> > +#define GEN2_PCIEPHYCTRL0x78c
> > +
> > +#define INT_PCI_MSI_NR32
> > +
> > +#define RCONF(x)(PCICONF(0) + (x))
> > +#define RPMCAP(x)(PMCAP(0) + (x))
> > +#define REXPCAP(x)(EXPCAP(0) + (x))
> > +#define RVCCAP(x)(VCCAP(0) + (x))
> > +
> > +#define PCIE_CONF_BUS(b)(((b) & 0xff) << 24)
> > +#define PCIE_CONF_DEV(d)(((d) & 0x1f) << 19)
> > +#define PCIE_CONF_FUNC(f)(((f) & 0x7) << 16)
> > +
> > +#define RCAR_PCI_MAX_RESOURCES4
> > +#define MAX_NR_INBOUND_MAPS6
> > +
> > +enum {
> > +RCAR_PCI_ACCESS_READ,
> > +RCAR_PCI_ACCESS_WRITE,
> > +};
> > +
> > +void rcar_pci_write_reg(void __iomem *base, u32 val, unsigned int
> > +reg);
> > +u32 rcar_pci_read_reg(void __iomem *base, unsigned int reg); void
> > +rcar_rmw32(void __iomem *base, int where, u32 mask, u32 data); int
> > +rcar_pcie_wait_for_phyrdy(void __iomem *base); int
> > +rcar_pcie_wait_for_dl(void __iomem *base); void
> > +rcar_pcie_set_outbound(int win, void __iomem *base, struct resource
> > +*res); void rcar_pcie_set_inbound(void __iomem *base, u64 cpu_addr,
> u64 pci_addr,
> > +   u64 mask, int idx, bool host);
> > +
> > +#endif
> > --
> > 2.7.4



Renesas Electronics Europe GmbH, Geschaeftsfuehrer/President: Carsten Jauch, Sitz der Gesellschaft/Registered office: Duesseldorf, Arcadiastrasse 10, 40472 Duesseldorf, Germany, Handelsregister/Commercial Register: Duesseldorf, HRB 3708 USt-IDNr./Tax identification no.: DE 119353406 WEEE-Reg.-Nr./WEEE reg. no.: DE 14978647

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

* RE: [PATCH v5 6/7] PCI: rcar: Add support for rcar PCIe controller in endpoint mode
  2020-02-28 15:41 ` [PATCH v5 6/7] PCI: rcar: Add support for rcar PCIe controller in endpoint mode Lad Prabhakar
@ 2020-03-17  9:59   ` Yoshihiro Shimoda
  2020-03-17 10:14     ` Prabhakar Mahadev Lad
  0 siblings, 1 reply; 26+ messages in thread
From: Yoshihiro Shimoda @ 2020-03-17  9:59 UTC (permalink / raw)
  To: Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Prabhakar Mahadev Lad,
	Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Shawn Lin, Heiko Stuebner

Hi Prabhakar-san,

Thank you for the patch!

> From: Lad Prabhakar, Sent: Saturday, February 29, 2020 12:41 AM
> 
> This patch adds support for rcar PCIe controller to work in endpoint mode.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> ---
>  drivers/pci/controller/Kconfig        |   8 +
>  drivers/pci/controller/Makefile       |   1 +
>  drivers/pci/controller/pcie-rcar-ep.c | 490 ++++++++++++++++++++++++++++++++++
>  drivers/pci/controller/pcie-rcar.h    |   4 +
>  4 files changed, 503 insertions(+)
>  create mode 100644 drivers/pci/controller/pcie-rcar-ep.c
> 
> diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
> index 37e0ea7..9bf4b02 100644
> --- a/drivers/pci/controller/Kconfig
> +++ b/drivers/pci/controller/Kconfig
> @@ -62,6 +62,14 @@ config PCIE_RCAR_HOST
>  	  Say Y here if you want PCIe controller support on R-Car SoCs in host
>  	  mode.
> 
> +config PCIE_RCAR_EP
> +	bool "Renesas R-Car PCIe endpoint controller"
> +	depends on ARCH_RENESAS || COMPILE_TEST
> +	depends on PCI_ENDPOINT
> +	help
> +	  Say Y here if you want PCIe controller support on R-Car SoCs in
> +	  endpoint mode.
> +
>  config PCI_HOST_COMMON
>  	bool
>  	select PCI_ECAM
> diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
> index b4ada32..067bd33 100644
> --- a/drivers/pci/controller/Makefile
> +++ b/drivers/pci/controller/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
>  obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
>  obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
>  obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar.o pcie-rcar-host.o
> +obj-$(CONFIG_PCIE_RCAR_EP) += pcie-rcar.o pcie-rcar-ep.o
>  obj-$(CONFIG_PCI_HOST_COMMON) += pci-host-common.o
>  obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
>  obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
> diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c
> new file mode 100644
> index 0000000..db89bbe
> --- /dev/null
> +++ b/drivers/pci/controller/pcie-rcar-ep.c
> @@ -0,0 +1,490 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PCIe endpoint driver for Renesas R-Car SoCs
> + *  Copyright (c) 2020 Renesas Electronics Europe GmbH
> + *
> + * Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_pci.h>
> +#include <linux/of_platform.h>
> +#include <linux/pci.h>
> +#include <linux/pci-epc.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +
> +#include "pcie-rcar.h"
> +
> +/* Structure representing the PCIe interface */
> +struct rcar_pcie {
> +	phys_addr_t		*ob_addr;

I think "ob_mapped_addr" is better.

> +	struct pci_epc_mem_window *ob_window;

I think we can get these windows from "array of address space of
the endpoint controller" in struct pci_epc. If so, we can remove
this member.

> +	struct pci_epc		*epc;

This member can be removed like pcie-cadence-ep.c because
this is not used except saving the epc value from devm_pci_epc_create().

<snip>
> +static int rcar_pcie_ep_start(struct pci_epc *epc)
> +{
> +	struct rcar_pcie *ep = epc_get_drvdata(epc);
> +
> +	rcar_pci_write_reg(ep->base, CFINIT, PCIETCTLR);

The following setting is needed before CFINIT like host.

	rcar_pci_write_reg(pcie->base, MACCTLR_INIT_VAL, MACCTLR);

> +
> +	return 0;
> +}
> +
> +static void rcar_pcie_ep_stop(struct pci_epc *epc)
> +{
> +	struct rcar_pcie *ep = epc_get_drvdata(epc);
> +
> +	rcar_pci_write_reg(ep->base, 0, PCIETCTLR);
> +}
> +
> +static const struct pci_epc_features rcar_pcie_epc_features = {
> +	.linkup_notifier = false,
> +	.msi_capable = false,
> +	.msix_capable = false,
> +	/* use 64-bit bars so mark bar1/3/5 as reserved */
> +	.reserved_bar = 1 << BAR_1 | 1 << BAR_3 | 1 << BAR_5,
> +	.bar_fixed_64bit =  (1 << BAR_0) | (1 << BAR_2) | (1 << BAR_4),

These parentheses are not needed like .reserved_bar.

<snip>
> +	err = pci_epc_mem_init(epc, pcie->ob_window, pcie->num_ob_windows);
> +	if (err < 0) {
> +		dev_err(dev, "failed to initialize the epc memory space\n");
> +		goto err_pm_put;
> +	}
> +
> +	rcar_pcie_ep_hw_init(pcie);

I'm not sure, but I wonder if we should call this hw init before pci_epc_mem_init().

<snip>
> +builtin_platform_driver(rcar_pcie_ep_driver);
> diff --git a/drivers/pci/controller/pcie-rcar.h b/drivers/pci/controller/pcie-rcar.h
> index b529d806..5564ca8 100644
> --- a/drivers/pci/controller/pcie-rcar.h
> +++ b/drivers/pci/controller/pcie-rcar.h
> @@ -17,6 +17,7 @@
>  #define PCIECDR			0x000020
>  #define PCIEMSR			0x000028
>  #define PCIEINTXR		0x000400
> +#define  ASTINTX_SHIFT		BIT(16)

Just "ASTINTX" is better.

>  #define PCIEPHYSR		0x0007f0
>  #define  PHYRDY			BIT(0)
>  #define PCIEMSITXR		0x000840
> @@ -55,12 +56,15 @@
> 
>  /* Configuration */
>  #define PCICONF(x)		(0x010000 + ((x) * 0x4))
> +#define  INTDIS_SHIFT		BIT(10)

Same here (we can remove "_SHIFT").

Best regards,
Yoshihiro Shimoda

>  #define PMCAP(x)		(0x010040 + ((x) * 0x4))
>  #define EXPCAP(x)		(0x010070 + ((x) * 0x4))
>  #define VCCAP(x)		(0x010100 + ((x) * 0x4))
> 
>  /* link layer */
> +#define IDSETR0			0x011000
>  #define IDSETR1			0x011004
> +#define SUBIDSETR		0x011024
>  #define TLCTLR			0x011048
>  #define MACSR			0x011054
>  #define  SPCHGFIN		BIT(4)
> --
> 2.7.4


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

* RE: [PATCH v5 4/7] PCI: endpoint: Add support to handle multiple base for mapping outbound memory
  2020-03-17  8:11   ` Yoshihiro Shimoda
@ 2020-03-17 10:03     ` Prabhakar Mahadev Lad
  2020-03-17 11:04       ` Yoshihiro Shimoda
  0 siblings, 1 reply; 26+ messages in thread
From: Prabhakar Mahadev Lad @ 2020-03-17 10:03 UTC (permalink / raw)
  To: Yoshihiro Shimoda, Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Bjorn Helgaas,
	Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
	Kishon Vijay Abraham I, Lorenzo Pieralisi, Arnd Bergmann,
	Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel, Marek Vasut,
	Shawn Lin, Heiko Stuebner

Hi Yoshihiro-san,

Thank you for the review,

> -----Original Message-----
> From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Sent: 17 March 2020 08:12
> To: Lad Prabhakar <prabhakar.csengg@gmail.com>
> Cc: Andrew Murray <andrew.murray@arm.com>; linux-pci@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-renesas-soc@vger.kernel.org;
> linux-rockchip@lists.infradead.org; linux-kernel@vger.kernel.org;
> devicetree@vger.kernel.org; Prabhakar Mahadev Lad <prabhakar.mahadev-
> lad.rj@bp.renesas.com>; Bjorn Helgaas <bhelgaas@google.com>; Rob
> Herring <robh+dt@kernel.org>; Mark Rutland <mark.rutland@arm.com>;
> Catalin Marinas <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>;
> Kishon Vijay Abraham I <kishon@ti.com>; Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com>; Arnd Bergmann <arnd@arndb.de>; Greg
> Kroah-Hartman <gregkh@linuxfoundation.org>; Jingoo Han
> <jingoohan1@gmail.com>; Gustavo Pimentel
> <gustavo.pimentel@synopsys.com>; Marek Vasut
> <marek.vasut+renesas@gmail.com>; Shawn Lin <shawn.lin@rock-
> chips.com>; Heiko Stuebner <heiko@sntech.de>
> Subject: RE: [PATCH v5 4/7] PCI: endpoint: Add support to handle multiple
> base for mapping outbound memory
>
> Hi Prabhakar-san,
>
> Thank you for the patch!
>
> > From: Lad Prabhakar, Sent: Saturday, February 29, 2020 12:41 AM
> >
> > R-Car PCIe controller has support to map multiple memory regions for
> > mapping the outbound memory in local system also the controller limits
> > single allocation for each region (that is, once a chunk is used from
> > the region it cannot be used to allocate a new one). This features
> > inspires to add support for handling multiple memory bases in endpoint
> framework.
> >
> > With this patch pci_epc_mem_init() now accepts multiple regions, also
> > page_size for each memory region is passed during initialization so as
> > to handle single allocation for each region by setting the page_size
> > to window_size.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-
> lad.rj@bp.renesas.com>
> > ---
> >  drivers/pci/controller/cadence/pcie-cadence-ep.c |   7 +-
> >  drivers/pci/controller/dwc/pcie-designware-ep.c  |  29 ++--
> >  drivers/pci/controller/pcie-rockchip-ep.c        |   7 +-
> >  drivers/pci/endpoint/pci-epc-mem.c               | 167 ++++++++++++++++-----
> --
>
> I could not apply this patch on the latest pci.git / next branch.
> So, you need to rebase.
>
Yes it needs rebasing on https://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git/log/?h=pci/endpoint

> >  include/linux/pci-epc.h                          |  39 ++++--
> >  5 files changed, 169 insertions(+), 80 deletions(-)
> >
> > diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c
> > b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> > index 1c173da..90e32438 100644
> > --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
> > +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> > @@ -401,6 +401,7 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
> >  struct device *dev = ep->pcie.dev;
> >  struct platform_device *pdev = to_platform_device(dev);
> >  struct device_node *np = dev->of_node;
> > +struct pci_epc_mem_window mem_window;
> >  struct cdns_pcie *pcie = &ep->pcie;
> >  struct resource *res;
> >  struct pci_epc *epc;
> > @@ -449,8 +450,10 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
> >  if (of_property_read_u8(np, "max-functions", &epc-
> >max_functions) < 0)
> >  epc->max_functions = 1;
> >
> > -ret = pci_epc_mem_init(epc, pcie->mem_res->start,
> > -       resource_size(pcie->mem_res));
> > +mem_window.phys_base = pcie->mem_res->start;
> > +mem_window.size = resource_size(pcie->mem_res);
> > +mem_window.page_size = PAGE_SIZE;
> > +ret = pci_epc_mem_init(epc, &mem_window, 1);
>
> I'm not sure my idea is acceptable or not but, I think we can have compatible
> API for single window like below.
> - In this patch, pci_epc_mem_init() and __pci_epc_mem_init() become the
> same behavior.
>   So, for example, pci_epc_mem_init() is for simple, and
> __pci_epc_mem_init() is multiple windows.
> -- In this case, pci_epc_mem_init() should have page_size argument.
> - The original "mem" in the pci_epc can be the default window instead of
>   PCI_EPC_DEFAULT_WINDOW.
>
OK

> >  if (ret < 0) {
> >  dev_err(dev, "failed to initialize the memory space\n");
> >  goto err_init;
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > index cfeccd7..b150ef3 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > @@ -195,8 +195,7 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc
> > *epc, u8 func_no,  }
> >
> >  static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
> > -       phys_addr_t addr,
> > -       u64 pci_addr, size_t size)
> > +       phys_addr_t addr, u64 pci_addr, size_t size)
> >  {
> >  int ret;
> >  struct dw_pcie_ep *ep = epc_get_drvdata(epc); @@ -367,6 +366,7
> @@
> > int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
> >  unsigned int aligned_offset;
> >  u16 msg_ctrl, msg_data;
> >  u32 msg_addr_lower, msg_addr_upper, reg;
> > +int window = PCI_EPC_DEFAULT_WINDOW;
> >  u64 msg_addr;
> >  bool has_upper;
> >  int ret;
> > @@ -390,11 +390,11 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep
> *ep, u8 func_no,
> >  reg = ep->msi_cap + PCI_MSI_DATA_32;
> >  msg_data = dw_pcie_readw_dbi(pci, reg);
> >  }
> > -aligned_offset = msg_addr_lower & (epc->mem->page_size - 1);
> > +aligned_offset = msg_addr_lower & (epc->mem[window]-
> >page_size - 1);
> >  msg_addr = ((u64)msg_addr_upper) << 32 |
> >  (msg_addr_lower & ~aligned_offset);
> > -ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys,
> msg_addr,
> > -  epc->mem->page_size);
> > +ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys,
> > +  msg_addr, epc->mem[window]-
> >page_size);
> >  if (ret)
> >  return ret;
> >
> > @@ -416,6 +416,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep
> *ep, u8 func_no,
> >  u32 reg, msg_data, vec_ctrl;
> >  u64 tbl_addr, msg_addr, reg_u64;
> >  void __iomem *msix_tbl;
> > +int window = PCI_EPC_DEFAULT_WINDOW;
> >  int ret;
> >
> >  reg = ep->msix_cap + PCI_MSIX_TABLE; @@ -452,8 +453,8 @@ int
> > dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
> >  return -EPERM;
> >  }
> >
> > -ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys,
> msg_addr,
> > -  epc->mem->page_size);
> > +ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys,
> > +  msg_addr, epc->mem[window]-
> >page_size);
> >  if (ret)
> >  return ret;
> >
> > @@ -466,10 +467,11 @@ int dw_pcie_ep_raise_msix_irq(struct
> dw_pcie_ep
> > *ep, u8 func_no,
> >
> >  void dw_pcie_ep_exit(struct dw_pcie_ep *ep)  {
> > +int window = PCI_EPC_DEFAULT_WINDOW;
> >  struct pci_epc *epc = ep->epc;
> >
> >  pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
> > -      epc->mem->page_size);
> > +      epc->mem[window]->page_size);
> >
> >  pci_epc_mem_exit(epc);
> >  }
> > @@ -502,6 +504,8 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
> >  unsigned int nbars;
> >  unsigned int offset;
> >  struct pci_epc *epc;
> > +size_t msi_page_size;
> > +struct pci_epc_mem_window mem_window;
> >  struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> >  struct device *dev = pci->dev;
> >  struct device_node *np = dev->of_node; @@ -574,15 +578,18 @@
> int
> > dw_pcie_ep_init(struct dw_pcie_ep *ep)
> >  if (ret < 0)
> >  epc->max_functions = 1;
> >
> > -ret = __pci_epc_mem_init(epc, ep->phys_base, ep->addr_size,
> > - ep->page_size);
> > +mem_window.phys_base = ep->phys_base;
> > +mem_window.size = ep->addr_size;
> > +mem_window.page_size = ep->page_size;
> > +ret = __pci_epc_mem_init(epc, &mem_window, 1);
> >  if (ret < 0) {
> >  dev_err(dev, "Failed to initialize address space\n");
> >  return ret;
> >  }
> >
> > +msi_page_size = epc->mem[PCI_EPC_DEFAULT_WINDOW]-
> >page_size;
> >  ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep-
> >msi_mem_phys,
> > -     epc->mem->page_size);
> > +     msi_page_size);
> >  if (!ep->msi_mem) {
> >  dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n");
> >  return -ENOMEM;
> > diff --git a/drivers/pci/controller/pcie-rockchip-ep.c
> > b/drivers/pci/controller/pcie-rockchip-ep.c
> > index d743b0a..5a97390 100644
> > --- a/drivers/pci/controller/pcie-rockchip-ep.c
> > +++ b/drivers/pci/controller/pcie-rockchip-ep.c
> > @@ -562,6 +562,7 @@ static const struct of_device_id
> > rockchip_pcie_ep_of_match[] = {
> >
> >  static int rockchip_pcie_ep_probe(struct platform_device *pdev)  {
> > +struct pci_epc_mem_window mem_window;
> >  struct device *dev = &pdev->dev;
> >  struct rockchip_pcie_ep *ep;
> >  struct rockchip_pcie *rockchip;
> > @@ -614,8 +615,10 @@ static int rockchip_pcie_ep_probe(struct
> platform_device *pdev)
> >  /* Only enable function 0 by default */
> >  rockchip_pcie_write(rockchip, BIT(0), PCIE_CORE_PHY_FUNC_CFG);
> >
> > -err = pci_epc_mem_init(epc, rockchip->mem_res->start,
> > -       resource_size(rockchip->mem_res));
> > +mem_window.phys_base = rockchip->mem_res->start;
> > +mem_window.size = resource_size(rockchip->mem_res);
> > +mem_window.page_size = PAGE_SIZE;
> > +err = pci_epc_mem_init(epc, &mem_window, 1);
> >  if (err < 0) {
> >  dev_err(dev, "failed to initialize the memory space\n");
> >  goto err_uninit_port;
> > diff --git a/drivers/pci/endpoint/pci-epc-mem.c
> > b/drivers/pci/endpoint/pci-epc-mem.c
> > index d2b174c..6c21957 100644
> > --- a/drivers/pci/endpoint/pci-epc-mem.c
> > +++ b/drivers/pci/endpoint/pci-epc-mem.c
> > @@ -38,57 +38,76 @@ static int pci_epc_mem_get_order(struct
> > pci_epc_mem *mem, size_t size)
> >  /**
> >   * __pci_epc_mem_init() - initialize the pci_epc_mem structure
> >   * @epc: the EPC device that invoked pci_epc_mem_init
> > - * @phys_base: the physical address of the base
> > - * @size: the size of the address space
> > - * @page_size: size of each page
> > + * @windows: pointer to windows supported by the device
> > + * @num_windows: number of windows device supports
> >   *
> >   * Invoke to initialize the pci_epc_mem structure used by the
> >   * endpoint functions to allocate mapped PCI address.
> >   */
> > -int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base,
> size_t size,
> > -       size_t page_size)
> > +int __pci_epc_mem_init(struct pci_epc *epc, struct
> pci_epc_mem_window *windows,
> > +       int num_windows)
> >  {
> > -int ret;
> > -struct pci_epc_mem *mem;
> > -unsigned long *bitmap;
> > +struct pci_epc_mem *mem = NULL;
> > +unsigned long *bitmap = NULL;
> >  unsigned int page_shift;
> > -int pages;
> > +size_t page_size;
> >  int bitmap_size;
> > -
> > -if (page_size < PAGE_SIZE)
> > -page_size = PAGE_SIZE;
> > -
> > -page_shift = ilog2(page_size);
> > -pages = size >> page_shift;
> > -bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
> > -
> > -mem = kzalloc(sizeof(*mem), GFP_KERNEL);
> > -if (!mem) {
> > -ret = -ENOMEM;
> > -goto err;
> > -}
> > -
> > -bitmap = kzalloc(bitmap_size, GFP_KERNEL);
> > -if (!bitmap) {
> > -ret = -ENOMEM;
> > -goto err_mem;
> > +int pages;
> > +int ret;
> > +int i;
> > +
> > +epc->mem_windows = 0;
> > +
> > +if (!windows)
> > +return -EINVAL;
> > +
> > +if (num_windows <= 0)
> > +return -EINVAL;
> > +
> > +epc->mem = kcalloc(num_windows, sizeof(*mem), GFP_KERNEL);
> > +if (!epc->mem)
> > +return -EINVAL;
> > +
> > +for (i = 0; i < num_windows; i++) {
> > +page_size = windows[i].page_size;
> > +if (page_size < PAGE_SIZE)
> > +page_size = PAGE_SIZE;
> > +page_shift = ilog2(page_size);
> > +pages = windows[i].size >> page_shift;
> > +bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
> > +
> > +mem = kzalloc(sizeof(*mem), GFP_KERNEL);
> > +if (!mem) {
> > +ret = -ENOMEM;
> > +goto err_mem;
> > +}
> > +
> > +bitmap = kzalloc(bitmap_size, GFP_KERNEL);
> > +if (!bitmap) {
> > +ret = -ENOMEM;
> > +goto err_mem;
> > +}
> > +
> > +mem->bitmap = bitmap;
> > +mem->window.phys_base = windows[i].phys_base;
>
> I could not understand why the window member is needed.
> I think original members (just phys_base and size) are enough.
> Also, this function doesn't store the page_size to mem->window.page_size.
>
Because,  for example on RZ/Gx platforms, following are the windows on endpoint device
where the root's address can be mapped, but where as on other platforms atm there
exists just single window to map. Also on RZ/Gx platforms if a window is allocated say of
size 1K, rest of the window cannot be used for other allocations.

1: 0xfe000000 0 0x80000
2: 0xfe100000 0 0x100000
3: 0xfe200000 0 0x200000
4: 0x30000000 0 0x8000000
5: 0x38000000 0 0x8000000

Struct pci_epc_mem_window, represents the above windows.

window.page_size is set by endpoint controller drivers as done in this patch.

> > +mem->page_size = page_size;
> > +mem->pages = pages;
> > +mem->window.size = windows[i].size;
> > +epc->mem[i] = mem;
> >  }
> > -
> > -mem->bitmap = bitmap;
> > -mem->phys_base = phys_base;
> > -mem->page_size = page_size;
> > -mem->pages = pages;
> > -mem->size = size;
> > -
> > -epc->mem = mem;
> > +epc->mem_windows = num_windows;
> >
> >  return 0;
> >
> >  err_mem:
> > -kfree(mem);
> > +for (; i >= 0; i--) {
> > +mem = epc->mem[i];
> > +kfree(mem->bitmap);
>
> If bitmap cannot be allocated, the epc->mem[i] is NULL.
> So, freeing mem->bitmap anyway is not good.
>
Agreed shall fix it.

> > +kfree(mem);
> > +}
> > +kfree(epc->mem);
> >
> > -err:
> > -return ret;
> > +return ret;
> >  }
> >  EXPORT_SYMBOL_GPL(__pci_epc_mem_init);
> >
> > @@ -101,11 +120,21 @@ EXPORT_SYMBOL_GPL(__pci_epc_mem_init);
> >   */
> >  void pci_epc_mem_exit(struct pci_epc *epc)  {
> > -struct pci_epc_mem *mem = epc->mem;
> > +struct pci_epc_mem *mem;
> > +int i;
> > +
> > +if (!epc->mem_windows)
> > +return;
> > +
> > +for (i = 0; i <= epc->mem_windows; i++) {
> > +mem = epc->mem[i];
> > +kfree(mem->bitmap);
> > +kfree(mem);
> > +}
> > +kfree(epc->mem);
> >
> >  epc->mem = NULL;
> > -kfree(mem->bitmap);
> > -kfree(mem);
> > +epc->mem_windows = 0;
> >  }
> >  EXPORT_SYMBOL_GPL(pci_epc_mem_exit);
> >
> > @@ -121,20 +150,30 @@ EXPORT_SYMBOL_GPL(pci_epc_mem_exit);
> >  void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
> >       phys_addr_t *phys_addr, size_t size)  {
> > -int pageno;
> > -void __iomem *virt_addr;
> > -struct pci_epc_mem *mem = epc->mem;
> > -unsigned int page_shift = ilog2(mem->page_size);
> > +void __iomem *virt_addr = NULL;
> > +struct pci_epc_mem *mem;
> > +unsigned int page_shift;
> > +int pageno = -EINVAL;
> >  int order;
> > +int i;
> >
> > -size = ALIGN(size, mem->page_size);
> > -order = pci_epc_mem_get_order(mem, size);
> > +for (i = 0; i < epc->mem_windows; i++) {
> > +mem = epc->mem[i];
> > +size = ALIGN(size, mem->page_size);
> > +order = pci_epc_mem_get_order(mem, size);
> > +
> > +pageno = bitmap_find_free_region(mem->bitmap, mem-
> >pages,
> > + order);
> > +if (pageno >= 0)
> > +break;
> > +}
> >
> > -pageno = bitmap_find_free_region(mem->bitmap, mem->pages,
> order);
> >  if (pageno < 0)
> >  return NULL;
> >
> > -*phys_addr = mem->phys_base + ((phys_addr_t)pageno <<
> page_shift);
> > +page_shift = ilog2(mem->page_size);
> > +*phys_addr = mem->window.phys_base +
> > +     ((phys_addr_t)pageno << page_shift);
> >  virt_addr = ioremap(*phys_addr, size);
> >  if (!virt_addr)
> >  bitmap_release_region(mem->bitmap, pageno, order); @@
> -143,6
> > +182,23 @@ void __iomem *pci_epc_mem_alloc_addr(struct pci_epc
> *epc,
> > }  EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);
> >
> > +struct pci_epc_mem *pci_epc_get_matching_window(struct pci_epc
> *epc,
> > +phys_addr_t phys_addr)
> > +{
> > +struct pci_epc_mem *mem;
> > +int i;
> > +
> > +for (i = 0; i < epc->mem_windows; i++) {
> > +mem = epc->mem[i];
> > +
> > +if (phys_addr >= mem->window.phys_base &&
> > +    phys_addr < (mem->window.phys_base + mem-
> >window.size))
> > +return mem;
> > +}
> > +
> > +return NULL;
> > +}
> > +
> >  /**
> >   * pci_epc_mem_free_addr() - free the allocated memory address
> >   * @epc: the EPC device on which memory was allocated @@ -155,13
> > +211,20 @@ EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);
> >  void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t
> phys_addr,
> >     void __iomem *virt_addr, size_t size)  {
> > +struct pci_epc_mem *mem;
> > +unsigned int page_shift;
> >  int pageno;
> > -struct pci_epc_mem *mem = epc->mem;
> > -unsigned int page_shift = ilog2(mem->page_size);
> >  int order;
> >
> > +mem = pci_epc_get_matching_window(epc, phys_addr);
> > +if (!mem) {
> > +pr_err("failed to get matching window\n");
> > +return;
> > +}
> > +
> > +page_shift = ilog2(mem->page_size);
> >  iounmap(virt_addr);
> > -pageno = (phys_addr - mem->phys_base) >> page_shift;
> > +pageno = (phys_addr - mem->window.phys_base) >> page_shift;
> >  size = ALIGN(size, mem->page_size);
> >  order = pci_epc_mem_get_order(mem, size);
> >  bitmap_release_region(mem->bitmap, pageno, order); diff --git
> > a/include/linux/pci-epc.h b/include/linux/pci-epc.h index
> > 56f1846..dde42e5 100644
> > --- a/include/linux/pci-epc.h
> > +++ b/include/linux/pci-epc.h
> > @@ -64,17 +64,29 @@ struct pci_epc_ops {
> >  struct module *owner;
> >  };
> >
> > +#define PCI_EPC_DEFAULT_WINDOW         0
> > +
> > +/**
> > + * struct pci_epc_mem_window - address window of the endpoint
> > +controller
> > + * @phys_base: physical base address of the PCI address window
> > + * @size: the size of the PCI address window
> > + * @page_size: size of each page
> > + */
> > +struct pci_epc_mem_window {
> > +phys_addr_tphys_base;
> > +size_tsize;
> > +size_tpage_size;
> > +};
> > +
> >  /**
> >   * struct pci_epc_mem - address space of the endpoint controller
> > - * @phys_base: physical base address of the PCI address space
> > - * @size: the size of the PCI address space
> > + * @window: address window of the endpoint controller
> >   * @bitmap: bitmap to manage the PCI address space
> > - * @pages: number of bits representing the address region
> >   * @page_size: size of each page
> > + * @pages: number of bits representing the address region
> >   */
> >  struct pci_epc_mem {
> > -phys_addr_tphys_base;
> > -size_tsize;
> > +struct pci_epc_mem_window window;
> >  unsigned long*bitmap;
> >  size_tpage_size;
> >  intpages;
> > @@ -85,7 +97,8 @@ struct pci_epc_mem {
> >   * @dev: PCI EPC device
> >   * @pci_epf: list of endpoint functions present in this EPC device
> >   * @ops: function pointers for performing endpoint operations
> > - * @mem: address space of the endpoint controller
>
> If my idea is acceptable, this should be "default address space ...".
>
Could you please elaborate more on how you would like the structures to be organized.

> > + * @mem: array of address space of the endpoint controller
>
> And, this should be difference name.
>
OK

> > + * @mem_windows: number of windows supported by device
>
> Perhaps, num_windows?
>
OK

> >   * @max_functions: max number of functions that can be configured in
> this EPC
> >   * @group: configfs group representing the PCI EPC device
> >   * @lock: spinlock to protect pci_epc ops @@ -94,7 +107,8 @@ struct
> > pci_epc {
> >  struct devicedev;
> >  struct list_headpci_epf;
> >  const struct pci_epc_ops*ops;
> > -struct pci_epc_mem*mem;
> > +struct pci_epc_mem**mem;
> > +unsigned intmem_windows;
> >  u8max_functions;
> >  struct config_group*group;
> >  /* spinlock to protect against concurrent access of EP controller */
> > @@ -128,8 +142,8 @@ struct pci_epc_features {
> >  #define devm_pci_epc_create(dev, ops)    \
> >  __devm_pci_epc_create((dev), (ops), THIS_MODULE)
> >
> > -#define pci_epc_mem_init(epc, phys_addr, size)\
> > -__pci_epc_mem_init((epc), (phys_addr), (size), PAGE_SIZE)
> > +#define pci_epc_mem_init(epc, windows, num_windows)\
> > +__pci_epc_mem_init((epc), windows, num_windows)
>
> As I mentioned above, pci_epc_mem_init() and __ pci_epc_mem_init() are
> the same behavior.
>
> >  static inline void epc_set_drvdata(struct pci_epc *epc, void *data)
> > { @@ -159,8 +173,7 @@ int pci_epc_set_bar(struct pci_epc *epc, u8
> > func_no,  void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,
> >         struct pci_epf_bar *epf_bar);  int
> pci_epc_map_addr(struct
> > pci_epc *epc, u8 func_no,
> > -     phys_addr_t phys_addr,
> > -     u64 pci_addr, size_t size);
> > +     phys_addr_t phys_addr, u64 pci_addr, size_t size);
>
> Perhaps, this is not needed to change?
>
Yes my bad.

Cheers,
--Prabhakar

> Best regards,
> Yoshihiro Shimoda
>
> >  void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
> >  phys_addr_t phys_addr);
> >  int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts);
> > @@ -178,8 +191,8 @@ unsigned int pci_epc_get_first_free_bar(const
> > struct pci_epc_features  struct pci_epc *pci_epc_get(const char
> > *epc_name);  void pci_epc_put(struct pci_epc *epc);
> >
> > -int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr,
> size_t size,
> > -       size_t page_size);
> > +int __pci_epc_mem_init(struct pci_epc *epc, struct
> pci_epc_mem_window *window,
> > +       int num_windows);
> >  void pci_epc_mem_exit(struct pci_epc *epc);  void __iomem
> > *pci_epc_mem_alloc_addr(struct pci_epc *epc,
> >       phys_addr_t *phys_addr, size_t size);
> > --
> > 2.7.4



Renesas Electronics Europe GmbH, Geschaeftsfuehrer/President: Carsten Jauch, Sitz der Gesellschaft/Registered office: Duesseldorf, Arcadiastrasse 10, 40472 Duesseldorf, Germany, Handelsregister/Commercial Register: Duesseldorf, HRB 3708 USt-IDNr./Tax identification no.: DE 119353406 WEEE-Reg.-Nr./WEEE reg. no.: DE 14978647

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

* RE: [PATCH v5 6/7] PCI: rcar: Add support for rcar PCIe controller in endpoint mode
  2020-03-17  9:59   ` Yoshihiro Shimoda
@ 2020-03-17 10:14     ` Prabhakar Mahadev Lad
  0 siblings, 0 replies; 26+ messages in thread
From: Prabhakar Mahadev Lad @ 2020-03-17 10:14 UTC (permalink / raw)
  To: Yoshihiro Shimoda, Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Bjorn Helgaas,
	Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
	Kishon Vijay Abraham I, Lorenzo Pieralisi, Arnd Bergmann,
	Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel, Marek Vasut,
	Shawn Lin, Heiko Stuebner

Hi Yoshihiro-san,

Thank you for the review,

> -----Original Message-----
> From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Sent: 17 March 2020 09:59
> To: Lad Prabhakar <prabhakar.csengg@gmail.com>
> Cc: Andrew Murray <andrew.murray@arm.com>; linux-pci@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-renesas-soc@vger.kernel.org;
> linux-rockchip@lists.infradead.org; linux-kernel@vger.kernel.org;
> devicetree@vger.kernel.org; Prabhakar Mahadev Lad <prabhakar.mahadev-
> lad.rj@bp.renesas.com>; Bjorn Helgaas <bhelgaas@google.com>; Rob
> Herring <robh+dt@kernel.org>; Mark Rutland <mark.rutland@arm.com>;
> Catalin Marinas <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>;
> Kishon Vijay Abraham I <kishon@ti.com>; Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com>; Arnd Bergmann <arnd@arndb.de>; Greg
> Kroah-Hartman <gregkh@linuxfoundation.org>; Jingoo Han
> <jingoohan1@gmail.com>; Gustavo Pimentel
> <gustavo.pimentel@synopsys.com>; Marek Vasut
> <marek.vasut+renesas@gmail.com>; Shawn Lin <shawn.lin@rock-
> chips.com>; Heiko Stuebner <heiko@sntech.de>
> Subject: RE: [PATCH v5 6/7] PCI: rcar: Add support for rcar PCIe controller in
> endpoint mode
>
> Hi Prabhakar-san,
>
> Thank you for the patch!
>
> > From: Lad Prabhakar, Sent: Saturday, February 29, 2020 12:41 AM
> >
> > This patch adds support for rcar PCIe controller to work in endpoint mode.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-
> lad.rj@bp.renesas.com>
> > ---
> >  drivers/pci/controller/Kconfig        |   8 +
> >  drivers/pci/controller/Makefile       |   1 +
> >  drivers/pci/controller/pcie-rcar-ep.c | 490
> ++++++++++++++++++++++++++++++++++
> >  drivers/pci/controller/pcie-rcar.h    |   4 +
> >  4 files changed, 503 insertions(+)
> >  create mode 100644 drivers/pci/controller/pcie-rcar-ep.c
> >
> > diff --git a/drivers/pci/controller/Kconfig
> > b/drivers/pci/controller/Kconfig index 37e0ea7..9bf4b02 100644
> > --- a/drivers/pci/controller/Kconfig
> > +++ b/drivers/pci/controller/Kconfig
> > @@ -62,6 +62,14 @@ config PCIE_RCAR_HOST
> >    Say Y here if you want PCIe controller support on R-Car SoCs in host
> >    mode.
> >
> > +config PCIE_RCAR_EP
> > +bool "Renesas R-Car PCIe endpoint controller"
> > +depends on ARCH_RENESAS || COMPILE_TEST
> > +depends on PCI_ENDPOINT
> > +help
> > +  Say Y here if you want PCIe controller support on R-Car SoCs in
> > +  endpoint mode.
> > +
> >  config PCI_HOST_COMMON
> >  bool
> >  select PCI_ECAM
> > diff --git a/drivers/pci/controller/Makefile
> > b/drivers/pci/controller/Makefile index b4ada32..067bd33 100644
> > --- a/drivers/pci/controller/Makefile
> > +++ b/drivers/pci/controller/Makefile
> > @@ -8,6 +8,7 @@ obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
> >  obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
> >  obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
> >  obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar.o pcie-rcar-host.o
> > +obj-$(CONFIG_PCIE_RCAR_EP) += pcie-rcar.o pcie-rcar-ep.o
> >  obj-$(CONFIG_PCI_HOST_COMMON) += pci-host-common.o
> >  obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
> >  obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o diff --git
> > a/drivers/pci/controller/pcie-rcar-ep.c
> > b/drivers/pci/controller/pcie-rcar-ep.c
> > new file mode 100644
> > index 0000000..db89bbe
> > --- /dev/null
> > +++ b/drivers/pci/controller/pcie-rcar-ep.c
> > @@ -0,0 +1,490 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * PCIe endpoint driver for Renesas R-Car SoCs
> > + *  Copyright (c) 2020 Renesas Electronics Europe GmbH
> > + *
> > + * Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_pci.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/pci.h>
> > +#include <linux/pci-epc.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "pcie-rcar.h"
> > +
> > +/* Structure representing the PCIe interface */ struct rcar_pcie {
> > +phys_addr_t*ob_addr;
>
> I think "ob_mapped_addr" is better.
>
OK will rename that.

> > +struct pci_epc_mem_window *ob_window;
>
> I think we can get these windows from "array of address space of the
> endpoint controller" in struct pci_epc. If so, we can remove this member.
>
I shall see if this can be dropped.

> > +struct pci_epc*epc;
>
> This member can be removed like pcie-cadence-ep.c because this is not used
> except saving the epc value from devm_pci_epc_create().
>
OK will drop it.

> <snip>
> > +static int rcar_pcie_ep_start(struct pci_epc *epc) {
> > +struct rcar_pcie *ep = epc_get_drvdata(epc);
> > +
> > +rcar_pci_write_reg(ep->base, CFINIT, PCIETCTLR);
>
> The following setting is needed before CFINIT like host.
>
> rcar_pci_write_reg(pcie->base, MACCTLR_INIT_VAL, MACCTLR);
>
I shall add this as part of rcar_pcie_ep_hw_init()

> > +
> > +return 0;
> > +}
> > +
> > +static void rcar_pcie_ep_stop(struct pci_epc *epc) {
> > +struct rcar_pcie *ep = epc_get_drvdata(epc);
> > +
> > +rcar_pci_write_reg(ep->base, 0, PCIETCTLR); }
> > +
> > +static const struct pci_epc_features rcar_pcie_epc_features = {
> > +.linkup_notifier = false,
> > +.msi_capable = false,
> > +.msix_capable = false,
> > +/* use 64-bit bars so mark bar1/3/5 as reserved */
> > +.reserved_bar = 1 << BAR_1 | 1 << BAR_3 | 1 << BAR_5,
> > +.bar_fixed_64bit =  (1 << BAR_0) | (1 << BAR_2) | (1 << BAR_4),
>
> These parentheses are not needed like .reserved_bar.
>
Agreed.

> <snip>
> > +err = pci_epc_mem_init(epc, pcie->ob_window, pcie-
> >num_ob_windows);
> > +if (err < 0) {
> > +dev_err(dev, "failed to initialize the epc memory space\n");
> > +goto err_pm_put;
> > +}
> > +
> > +rcar_pcie_ep_hw_init(pcie);
>
> I'm not sure, but I wonder if we should call this hw init before
> pci_epc_mem_init().
>
Ideally shouldn't matter because in pci_epc_mem_init(), we just tell the framework
our windows properties.  But shall move hw_init() before mem_init().

> <snip>
> > +builtin_platform_driver(rcar_pcie_ep_driver);
> > diff --git a/drivers/pci/controller/pcie-rcar.h
> > b/drivers/pci/controller/pcie-rcar.h
> > index b529d806..5564ca8 100644
> > --- a/drivers/pci/controller/pcie-rcar.h
> > +++ b/drivers/pci/controller/pcie-rcar.h
> > @@ -17,6 +17,7 @@
> >  #define PCIECDR0x000020
> >  #define PCIEMSR0x000028
> >  #define PCIEINTXR0x000400
> > +#define  ASTINTX_SHIFTBIT(16)
>
> Just "ASTINTX" is better.
>
Shall replace it.

> >  #define PCIEPHYSR0x0007f0
> >  #define  PHYRDYBIT(0)
> >  #define PCIEMSITXR0x000840
> > @@ -55,12 +56,15 @@
> >
> >  /* Configuration */
> >  #define PCICONF(x)(0x010000 + ((x) * 0x4))
> > +#define  INTDIS_SHIFTBIT(10)
>
> Same here (we can remove "_SHIFT").
>
OK.

Cheers,
--Prabhakar

> Best regards,
> Yoshihiro Shimoda
>
> >  #define PMCAP(x)(0x010040 + ((x) * 0x4))
> >  #define EXPCAP(x)(0x010070 + ((x) * 0x4))
> >  #define VCCAP(x)(0x010100 + ((x) * 0x4))
> >
> >  /* link layer */
> > +#define IDSETR00x011000
> >  #define IDSETR10x011004
> > +#define SUBIDSETR0x011024
> >  #define TLCTLR0x011048
> >  #define MACSR0x011054
> >  #define  SPCHGFINBIT(4)
> > --
> > 2.7.4



Renesas Electronics Europe GmbH, Geschaeftsfuehrer/President: Carsten Jauch, Sitz der Gesellschaft/Registered office: Duesseldorf, Arcadiastrasse 10, 40472 Duesseldorf, Germany, Handelsregister/Commercial Register: Duesseldorf, HRB 3708 USt-IDNr./Tax identification no.: DE 119353406 WEEE-Reg.-Nr./WEEE reg. no.: DE 14978647

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

* RE: [PATCH v5 5/7] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller
  2020-03-17  8:26   ` Yoshihiro Shimoda
@ 2020-03-17 10:18     ` Prabhakar Mahadev Lad
  2020-03-17 11:11       ` Yoshihiro Shimoda
  0 siblings, 1 reply; 26+ messages in thread
From: Prabhakar Mahadev Lad @ 2020-03-17 10:18 UTC (permalink / raw)
  To: Yoshihiro Shimoda, Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Rob Herring,
	Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Shawn Lin, Heiko Stuebner

Hi Yoshihiro-san,

> -----Original Message-----
> From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Sent: 17 March 2020 08:26
> To: Lad Prabhakar <prabhakar.csengg@gmail.com>
> Cc: Andrew Murray <andrew.murray@arm.com>; linux-pci@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-renesas-soc@vger.kernel.org;
> linux-rockchip@lists.infradead.org; linux-kernel@vger.kernel.org;
> devicetree@vger.kernel.org; Prabhakar Mahadev Lad <prabhakar.mahadev-
> lad.rj@bp.renesas.com>; Rob Herring <robh@kernel.org>; Bjorn Helgaas
> <bhelgaas@google.com>; Rob Herring <robh+dt@kernel.org>; Mark Rutland
> <mark.rutland@arm.com>; Catalin Marinas <catalin.marinas@arm.com>; Will
> Deacon <will@kernel.org>; Kishon Vijay Abraham I <kishon@ti.com>;
> Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>; Arnd Bergmann
> <arnd@arndb.de>; Greg Kroah-Hartman <gregkh@linuxfoundation.org>;
> Jingoo Han <jingoohan1@gmail.com>; Gustavo Pimentel
> <gustavo.pimentel@synopsys.com>; Marek Vasut
> <marek.vasut+renesas@gmail.com>; Shawn Lin <shawn.lin@rock-
> chips.com>; Heiko Stuebner <heiko@sntech.de>
> Subject: RE: [PATCH v5 5/7] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe
> endpoint controller
>
> Hi Prabhakar-san,
>
> Thank you for the patch!
>
> > From: Lad Prabhakar, Sent: Saturday, February 29, 2020 12:41 AM
> >
> > This patch adds the bindings for the R-Car PCIe endpoint driver.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-
> lad.rj@bp.renesas.com>
> > Reviewed-by: Rob Herring <robh@kernel.org>
>
> Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
>
Thank you for the review. Shall I add this file under "PCI DRIVER FOR RENESAS R-CAR"
In MAINTAINERS file as a separate patch ?

Cheers,
--Prabhakar

> Best regards,
> Yoshihiro Shimoda



Renesas Electronics Europe GmbH, Geschaeftsfuehrer/President: Carsten Jauch, Sitz der Gesellschaft/Registered office: Duesseldorf, Arcadiastrasse 10, 40472 Duesseldorf, Germany, Handelsregister/Commercial Register: Duesseldorf, HRB 3708 USt-IDNr./Tax identification no.: DE 119353406 WEEE-Reg.-Nr./WEEE reg. no.: DE 14978647

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

* RE: [PATCH v5 7/7] misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller
  2020-02-28 15:41 ` [PATCH v5 7/7] misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller Lad Prabhakar
@ 2020-03-17 10:31   ` Yoshihiro Shimoda
  2020-03-17 10:36     ` Prabhakar Mahadev Lad
  0 siblings, 1 reply; 26+ messages in thread
From: Yoshihiro Shimoda @ 2020-03-17 10:31 UTC (permalink / raw)
  To: Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Prabhakar Mahadev Lad,
	Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Shawn Lin, Heiko Stuebner

Hi Prabhakar-san,

Thank you for the patch!

> From: Lad Prabhakar, Sent: Saturday, February 29, 2020 12:41 AM
> 
> Add RZ/G2E in pci_device_id table so that pci-epf-test can be used for
> testing PCIe EP in RZ/G2E.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> ---
>  drivers/misc/pci_endpoint_test.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
> index a5e3170..3c84e9a 100644
> --- a/drivers/misc/pci_endpoint_test.c
> +++ b/drivers/misc/pci_endpoint_test.c
> @@ -66,6 +66,8 @@
> 
>  #define PCI_DEVICE_ID_TI_AM654			0xb00c
> 
> +#define PCI_DEVICE_ID_RENESAS_RZG2E		0x002d

This define should be in include/linux/pci_ids.h, and adding
the define should be separated.
Also, I think "R8A774C0" is better than "RZG2E".

Best regards,
Yoshihiro Shimoda

>  #define is_am654_pci_dev(pdev)		\
>  		((pdev)->device == PCI_DEVICE_ID_TI_AM654)
> 
> @@ -797,6 +799,7 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = {
>  	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),
>  	  .driver_data = (kernel_ulong_t)&am654_data
>  	},
> +	{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_RZG2E) },
>  	{ }
>  };
>  MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
> --
> 2.7.4


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

* RE: [PATCH v5 7/7] misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller
  2020-03-17 10:31   ` Yoshihiro Shimoda
@ 2020-03-17 10:36     ` Prabhakar Mahadev Lad
  0 siblings, 0 replies; 26+ messages in thread
From: Prabhakar Mahadev Lad @ 2020-03-17 10:36 UTC (permalink / raw)
  To: Yoshihiro Shimoda, Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Bjorn Helgaas,
	Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
	Kishon Vijay Abraham I, Lorenzo Pieralisi, Arnd Bergmann,
	Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel, Marek Vasut,
	Shawn Lin, Heiko Stuebner

Hi Yoshihiro,

Thank you for the review.

> -----Original Message-----
> From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Sent: 17 March 2020 10:32
> To: Lad Prabhakar <prabhakar.csengg@gmail.com>
> Cc: Andrew Murray <andrew.murray@arm.com>; linux-pci@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-renesas-soc@vger.kernel.org;
> linux-rockchip@lists.infradead.org; linux-kernel@vger.kernel.org;
> devicetree@vger.kernel.org; Prabhakar Mahadev Lad <prabhakar.mahadev-
> lad.rj@bp.renesas.com>; Bjorn Helgaas <bhelgaas@google.com>; Rob
> Herring <robh+dt@kernel.org>; Mark Rutland <mark.rutland@arm.com>;
> Catalin Marinas <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>;
> Kishon Vijay Abraham I <kishon@ti.com>; Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com>; Arnd Bergmann <arnd@arndb.de>; Greg
> Kroah-Hartman <gregkh@linuxfoundation.org>; Jingoo Han
> <jingoohan1@gmail.com>; Gustavo Pimentel
> <gustavo.pimentel@synopsys.com>; Marek Vasut
> <marek.vasut+renesas@gmail.com>; Shawn Lin <shawn.lin@rock-
> chips.com>; Heiko Stuebner <heiko@sntech.de>
> Subject: RE: [PATCH v5 7/7] misc: pci_endpoint_test: Add Device ID for
> RZ/G2E PCIe controller
>
> Hi Prabhakar-san,
>
> Thank you for the patch!
>
> > From: Lad Prabhakar, Sent: Saturday, February 29, 2020 12:41 AM
> >
> > Add RZ/G2E in pci_device_id table so that pci-epf-test can be used for
> > testing PCIe EP in RZ/G2E.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-
> lad.rj@bp.renesas.com>
> > ---
> >  drivers/misc/pci_endpoint_test.c | 3 +++
> >  1 file changed, 3 insertions(+)
> >
> > diff --git a/drivers/misc/pci_endpoint_test.c
> > b/drivers/misc/pci_endpoint_test.c
> > index a5e3170..3c84e9a 100644
> > --- a/drivers/misc/pci_endpoint_test.c
> > +++ b/drivers/misc/pci_endpoint_test.c
> > @@ -66,6 +66,8 @@
> >
> >  #define PCI_DEVICE_ID_TI_AM6540xb00c
> >
> > +#define PCI_DEVICE_ID_RENESAS_RZG2E0x002d
>
> This define should be in include/linux/pci_ids.h, and adding the define
> should be separated.
> Also, I think "R8A774C0" is better than "RZG2E".
>
Agreed will add it under PCI_VENDOR_ID_RENESAS.

Cheers,
--Prabhakar

> Best regards,
> Yoshihiro Shimoda
>
> >  #define is_am654_pci_dev(pdev)\
> >  ((pdev)->device == PCI_DEVICE_ID_TI_AM654)
> >
> > @@ -797,6 +799,7 @@ static const struct pci_device_id
> pci_endpoint_test_tbl[] = {
> >  { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),
> >    .driver_data = (kernel_ulong_t)&am654_data
> >  },
> > +{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS,
> PCI_DEVICE_ID_RENESAS_RZG2E) },
> >  { }
> >  };
> >  MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
> > --
> > 2.7.4



Renesas Electronics Europe GmbH, Geschaeftsfuehrer/President: Carsten Jauch, Sitz der Gesellschaft/Registered office: Duesseldorf, Arcadiastrasse 10, 40472 Duesseldorf, Germany, Handelsregister/Commercial Register: Duesseldorf, HRB 3708 USt-IDNr./Tax identification no.: DE 119353406 WEEE-Reg.-Nr./WEEE reg. no.: DE 14978647

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

* RE: [PATCH v5 4/7] PCI: endpoint: Add support to handle multiple base for mapping outbound memory
  2020-03-17 10:03     ` Prabhakar Mahadev Lad
@ 2020-03-17 11:04       ` Yoshihiro Shimoda
  0 siblings, 0 replies; 26+ messages in thread
From: Yoshihiro Shimoda @ 2020-03-17 11:04 UTC (permalink / raw)
  To: Prabhakar Mahadev Lad, Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Bjorn Helgaas,
	Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
	Kishon Vijay Abraham I, Lorenzo Pieralisi, Arnd Bergmann,
	Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel, Marek Vasut,
	Shawn Lin, Heiko Stuebner

Hi Prabhakar-san,

Just in my opinion though, automatically adding new line of email client
should be disabled or setting larger characters.
# In my side, I change the setting as 132 characters on Outlook :)

> From: Prabhakar Mahadev Lad, Sent: Tuesday, March 17, 2020 7:04 PM
<snip>
> > > -int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base,
> > size_t size,
> > > -		       size_t page_size)
> > > +int __pci_epc_mem_init(struct pci_epc *epc, struct
> > pci_epc_mem_window *windows,
> > > +		       int num_windows)
> > >  {
> > > -	int ret;
> > > -	struct pci_epc_mem *mem;
> > > -	unsigned long *bitmap;
> > > +	struct pci_epc_mem *mem = NULL;
> > > +	unsigned long *bitmap = NULL;
> > >  	unsigned int page_shift;
> > > -	int pages;
> > > +	size_t page_size;
> > >  	int bitmap_size;
> > > -
> > > -	if (page_size < PAGE_SIZE)
> > > -		page_size = PAGE_SIZE;
> > > -
> > > -	page_shift = ilog2(page_size);
> > > -	pages = size >> page_shift;
> > > -	bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
> > > -
> > > -	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
> > > -	if (!mem) {
> > > -		ret = -ENOMEM;
> > > -		goto err;
> > > -	}
> > > -
> > > -	bitmap = kzalloc(bitmap_size, GFP_KERNEL);
> > > -	if (!bitmap) {
> > > -		ret = -ENOMEM;
> > > -		goto err_mem;
> > > +	int pages;
> > > +	int ret;
> > > +	int i;
> > > +
> > > +	epc->mem_windows = 0;
> > > +
> > > +	if (!windows)
> > > +		return -EINVAL;
> > > +
> > > +	if (num_windows <= 0)
> > > +		return -EINVAL;
> > > +
> > > +	epc->mem = kcalloc(num_windows, sizeof(*mem), GFP_KERNEL);
> > > +	if (!epc->mem)
> > > +		return -EINVAL;
> > > +
> > > +	for (i = 0; i < num_windows; i++) {
> > > +		page_size = windows[i].page_size;
> > > +		if (page_size < PAGE_SIZE)
> > > +			page_size = PAGE_SIZE;
> > > +		page_shift = ilog2(page_size);
> > > +		pages = windows[i].size >> page_shift;
> > > +		bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
> > > +
> > > +		mem = kzalloc(sizeof(*mem), GFP_KERNEL);
> > > +		if (!mem) {
> > > +			ret = -ENOMEM;
> > > +			goto err_mem;
> > > +		}
> > > +
> > > +		bitmap = kzalloc(bitmap_size, GFP_KERNEL);
> > > +		if (!bitmap) {
> > > +			ret = -ENOMEM;
> > > +			goto err_mem;
> > > +		}
> > > +
> > > +		mem->bitmap = bitmap;
> > > +		mem->window.phys_base = windows[i].phys_base;
> >
> > I could not understand why the window member is needed.
> > I think original members (just phys_base and size) are enough.
> > Also, this function doesn't store the page_size to mem->window.page_size.

I'm sorry, but I meant the window member is in the left side (mem->window.phys_base).
In other words, this patch changes the struct pci_epc_mem like below, but
I'm thinking this change is not needed because struct pci_epc will have
multiple windows as "array of address space of the endpoint controller".
---
struct pci_epc_mem {
-	phys_addr_t	phys_base;
-	size_t		size;
+	struct pci_epc_mem_window window;
---

> Because,  for example on RZ/Gx platforms, following are the windows on endpoint device
> where the root's address can be mapped, but where as on other platforms atm there
> exists just single window to map. Also on RZ/Gx platforms if a window is allocated say of
> size 1K, rest of the window cannot be used for other allocations.
> 
> 1: 0xfe000000 0 0x80000
> 2: 0xfe100000 0 0x100000
> 3: 0xfe200000 0 0x200000
> 4: 0x30000000 0 0x8000000
> 5: 0x38000000 0 0x8000000
> 
> Struct pci_epc_mem_window, represents the above windows.

Yes, I understood it.

> window.page_size is set by endpoint controller drivers as done in this patch.

I meant the left side. No one change the mem->window.page_size so that
the value seems to be 0. Of course, for now, this is no problem because
no one uses this value though.

<snip>
> > >  /**
> > >   * struct pci_epc_mem - address space of the endpoint controller
> > > - * @phys_base: physical base address of the PCI address space
> > > - * @size: the size of the PCI address space
> > > + * @window: address window of the endpoint controller
> > >   * @bitmap: bitmap to manage the PCI address space
> > > - * @pages: number of bits representing the address region
> > >   * @page_size: size of each page
> > > + * @pages: number of bits representing the address region
> > >   */
> > >  struct pci_epc_mem {
> > > -	phys_addr_t	phys_base;
> > > -	size_t		size;
> > > +	struct pci_epc_mem_window window;
> > >  	unsigned long	*bitmap;
> > >  	size_t		page_size;
> > >  	int		pages;
> > > @@ -85,7 +97,8 @@ struct pci_epc_mem {
> > >   * @dev: PCI EPC device
> > >   * @pci_epf: list of endpoint functions present in this EPC device
> > >   * @ops: function pointers for performing endpoint operations
> > > - * @mem: address space of the endpoint controller
> >
> > If my idea is acceptable, this should be "default address space ...".
> >
> Could you please elaborate more on how you would like the structures to be organized.

 * @mem: default address space of the endpoint controller.

And, if I assumed the "array of address space of the endpoint controller"
is renamed as struct pci_epc_mem **windows and when __pci_epc_mem_init() is succeeded,
the function should set the mem value right before return as the first window like below.

+	epc->mem = epc->windows[0];
+	epc->num_windows = num_windows;

	return 0;

Best regards,
Yoshihiro Shimoda


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

* RE: [PATCH v5 5/7] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller
  2020-03-17 10:18     ` Prabhakar Mahadev Lad
@ 2020-03-17 11:11       ` Yoshihiro Shimoda
  0 siblings, 0 replies; 26+ messages in thread
From: Yoshihiro Shimoda @ 2020-03-17 11:11 UTC (permalink / raw)
  To: Prabhakar Mahadev Lad, Lad Prabhakar
  Cc: Andrew Murray, linux-pci, linux-arm-kernel, linux-renesas-soc,
	linux-rockchip, linux-kernel, devicetree, Rob Herring,
	Bjorn Helgaas, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Arnd Bergmann, Greg Kroah-Hartman, Jingoo Han, Gustavo Pimentel,
	Marek Vasut, Shawn Lin, Heiko Stuebner

Hi Prabhakar-san,

> From: Prabhakar Mahadev Lad, Sent: Tuesday, March 17, 2020 7:18 PM
<snip>
> > > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-
> > lad.rj@bp.renesas.com>
> > > Reviewed-by: Rob Herring <robh@kernel.org>
> >
> > Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> >
> Thank you for the review. Shall I add this file under "PCI DRIVER FOR RENESAS R-CAR"
> In MAINTAINERS file as a separate patch ?

That's a nice idea! I think we should add the following like for dt-binding:

F:	Documentation/devicetree/bindings/pci/*rcar*

Best regards,
Yoshihiro Shimoda

> Cheers,
> --Prabhakar
> 
> > Best regards,
> > Yoshihiro Shimoda


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

end of thread, other threads:[~2020-03-17 11:19 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-28 15:41 [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
2020-02-28 15:41 ` [PATCH v5 1/7] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c Lad Prabhakar
2020-03-17  6:59   ` Yoshihiro Shimoda
2020-03-17  8:26     ` Prabhakar Mahadev Lad
2020-02-28 15:41 ` [PATCH v5 2/7] PCI: rcar: Move shareable code to a common file Lad Prabhakar
2020-03-17  7:23   ` Yoshihiro Shimoda
2020-03-17  8:29     ` Prabhakar Mahadev Lad
2020-02-28 15:41 ` [PATCH v5 3/7] PCI: rcar: Fix calculating mask for PCIEPAMR register Lad Prabhakar
2020-03-17  7:31   ` Yoshihiro Shimoda
2020-02-28 15:41 ` [PATCH v5 4/7] PCI: endpoint: Add support to handle multiple base for mapping outbound memory Lad Prabhakar
2020-03-17  8:11   ` Yoshihiro Shimoda
2020-03-17 10:03     ` Prabhakar Mahadev Lad
2020-03-17 11:04       ` Yoshihiro Shimoda
2020-02-28 15:41 ` [PATCH v5 5/7] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller Lad Prabhakar
2020-03-17  8:26   ` Yoshihiro Shimoda
2020-03-17 10:18     ` Prabhakar Mahadev Lad
2020-03-17 11:11       ` Yoshihiro Shimoda
2020-02-28 15:41 ` [PATCH v5 6/7] PCI: rcar: Add support for rcar PCIe controller in endpoint mode Lad Prabhakar
2020-03-17  9:59   ` Yoshihiro Shimoda
2020-03-17 10:14     ` Prabhakar Mahadev Lad
2020-02-28 15:41 ` [PATCH v5 7/7] misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller Lad Prabhakar
2020-03-17 10:31   ` Yoshihiro Shimoda
2020-03-17 10:36     ` Prabhakar Mahadev Lad
2020-03-13 15:46 ` [PATCH v5 0/7] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad, Prabhakar
2020-03-16 12:18   ` Lorenzo Pieralisi
2020-03-16 12:33     ` Lad, Prabhakar

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).