linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 00/11] Add support for PCIe controller to work in endpoint mode on R-Car SoCs
@ 2020-04-02 19:38 Lad Prabhakar
  2020-04-02 19:38 ` [PATCH v6 01/11] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c Lad Prabhakar
                   ` (10 more replies)
  0 siblings, 11 replies; 30+ messages in thread
From: Lad Prabhakar @ 2020-04-02 19:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Magnus Damm, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Marek Vasut, Yoshihiro Shimoda, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	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.

root@salvator-x:~# ./pcitest.sh 
BAR tests

BAR0:           OKAY
BAR1:           NOT OKAY
BAR2:           OKAY
BAR3:           NOT OKAY
BAR4:           OKAY
BAR5:           NOT OKAY

Interrupt tests

SET IRQ TYPE TO LEGACY:         OKAY
LEGACY IRQ:     OKAY
SET IRQ TYPE TO MSI:            OKAY
MSI1:           OKAY
MSI2:           OKAY
MSI3:           OKAY
MSI4:           OKAY
MSI5:           OKAY
MSI6:           OKAY
MSI7:           OKAY
MSI8:           OKAY
MSI9:           OKAY
MSI10:          OKAY
MSI11:          OKAY
MSI12:          OKAY
MSI13:          OKAY
MSI14:          OKAY
MSI15:          OKAY
MSI16:          OKAY
MSI17:          NOT OKAY
MSI18:          NOT OKAY
MSI19:          NOT OKAY
MSI20:          NOT OKAY
MSI21:          NOT OKAY
MSI22:          NOT OKAY
MSI23:          NOT OKAY
MSI24:          NOT OKAY
MSI25:          NOT OKAY
MSI26:          NOT OKAY
MSI27:          NOT OKAY
MSI28:          NOT OKAY
MSI29:          NOT OKAY
MSI30:          NOT OKAY
MSI31:          NOT OKAY
MSI32:          NOT OKAY


Read Tests

SET IRQ TYPE TO MSI:            OKAY
READ (      1 bytes):           OKAY
READ (   1024 bytes):           OKAY
READ (   1025 bytes):           OKAY
READ (1024000 bytes):           OKAY
READ (1024001 bytes):           OKAY

Write Tests

WRITE (      1 bytes):          OKAY
WRITE (   1024 bytes):          OKAY
WRITE (   1025 bytes):          OKAY
WRITE (1024000 bytes):          OKAY
WRITE (1024001 bytes):          OKAY

Copy Tests

COPY (      1 bytes):           OKAY
COPY (   1024 bytes):           OKAY
COPY (   1025 bytes):           OKAY
COPY (1024000 bytes):           OKAY
COPY (1024001 bytes):           OKAY


Changes for v6:
1] Rebased patches on endpoint branch of https://git.kernel.org/pub/
   scm/linux/kernel/git/lpieralisi/pci.git/
2] Fixed review comments from Shimoda-san
   a] Made sure defconfig changes were in seprate patch
   b] Created rcar_pcie_host/rcar_pcie_ep structures
   c] Added pci-id for R8A774C0
   d] Added entry in MAINTAINERS for dt-binding
   e] Dropped unnecessary braces
3] Added support for msi.

Changes for v5:
1] Rebased 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 (11):
  PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c
  arm64: defconfig: enable CONFIG_PCIE_RCAR_HOST
  PCI: drop PCIE_RCAR config option
  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
  PCI: Add Renesas R8A774C0 device ID
  misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller
  MAINTAINERS: Add file patterns for rcar PCI device tree bindings

 .../devicetree/bindings/pci/rcar-pci-ep.yaml  |   76 ++
 MAINTAINERS                                   |    1 +
 arch/arm64/configs/defconfig                  |    2 +-
 drivers/misc/pci_endpoint_test.c              |    2 +
 drivers/pci/controller/Kconfig                |   15 +-
 drivers/pci/controller/Makefile               |    3 +-
 .../pci/controller/cadence/pcie-cadence-ep.c  |    3 +-
 .../pci/controller/dwc/pcie-designware-ep.c   |   16 +-
 drivers/pci/controller/pcie-rcar-ep.c         |  556 ++++++++
 drivers/pci/controller/pcie-rcar-host.c       | 1065 +++++++++++++++
 drivers/pci/controller/pcie-rcar.c            | 1206 +----------------
 drivers/pci/controller/pcie-rcar.h            |  140 ++
 drivers/pci/controller/pcie-rockchip-ep.c     |    2 +-
 drivers/pci/endpoint/pci-epc-mem.c            |  195 ++-
 include/linux/pci-epc.h                       |   39 +-
 include/linux/pci_ids.h                       |    1 +
 16 files changed, 2068 insertions(+), 1254 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.20.1


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

* [PATCH v6 01/11] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c
  2020-04-02 19:38 [PATCH v6 00/11] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
@ 2020-04-02 19:38 ` Lad Prabhakar
  2020-04-03  7:52   ` Yoshihiro Shimoda
  2020-04-02 19:38 ` [PATCH v6 02/11] arm64: defconfig: enable CONFIG_PCIE_RCAR_HOST Lad Prabhakar
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Lad Prabhakar @ 2020-04-02 19:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Magnus Damm, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Marek Vasut, Yoshihiro Shimoda, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	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 kept so that arm64
defconfig change can be a separate patch.

With this patch both config options PCIE_RCAR and PCIE_RCAR_HOST will be
available but PCIE_RCAR internally selects PCIE_RCAR_HOST so that bisect
builds wont be affected.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
 drivers/pci/controller/Kconfig                         | 10 ++++++++++
 drivers/pci/controller/Makefile                        |  2 +-
 .../pci/controller/{pcie-rcar.c => pcie-rcar-host.c}   |  0
 3 files changed, 11 insertions(+), 1 deletion(-)
 rename drivers/pci/controller/{pcie-rcar.c => pcie-rcar-host.c} (100%)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index af0f0bc11917..cfdc898450d0 100644
--- 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 option will be removed after arm64 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
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index 158c59771824..9dbccb5b24e1 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.20.1


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

* [PATCH v6 02/11] arm64: defconfig: enable CONFIG_PCIE_RCAR_HOST
  2020-04-02 19:38 [PATCH v6 00/11] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
  2020-04-02 19:38 ` [PATCH v6 01/11] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c Lad Prabhakar
@ 2020-04-02 19:38 ` Lad Prabhakar
  2020-04-03  8:03   ` Yoshihiro Shimoda
  2020-04-02 19:38 ` [PATCH v6 03/11] PCI: drop PCIE_RCAR config option Lad Prabhakar
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Lad Prabhakar @ 2020-04-02 19:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Magnus Damm, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Marek Vasut, Yoshihiro Shimoda, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Lad Prabhakar

config option PCIE_RCAR internally selects PCIE_RCAR_HOST which builds the
same driver. So this patch renames CONFIG_PCIE_RCAR to
CONFIG_PCIE_RCAR_HOST so that PCIE_RCAR can be safely dropped from Kconfig
file.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
 arch/arm64/configs/defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 24e534d85045..97575f9a91e2 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -192,7 +192,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
-- 
2.20.1


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

* [PATCH v6 03/11] PCI: drop PCIE_RCAR config option
  2020-04-02 19:38 [PATCH v6 00/11] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
  2020-04-02 19:38 ` [PATCH v6 01/11] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c Lad Prabhakar
  2020-04-02 19:38 ` [PATCH v6 02/11] arm64: defconfig: enable CONFIG_PCIE_RCAR_HOST Lad Prabhakar
@ 2020-04-02 19:38 ` Lad Prabhakar
  2020-04-02 19:38 ` [PATCH v6 04/11] PCI: rcar: Move shareable code to a common file Lad Prabhakar
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 30+ messages in thread
From: Lad Prabhakar @ 2020-04-02 19:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Magnus Damm, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Marek Vasut, Yoshihiro Shimoda, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Lad Prabhakar

Drop PCIE_RCAR config option as PCIE_RCAR_HOST builds the same driver.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
 drivers/pci/controller/Kconfig | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index cfdc898450d0..37e234ad583b 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -54,15 +54,6 @@ 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"
-	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 option will be removed after arm64 defconfig is updated.
-
 config PCIE_RCAR_HOST
 	bool "Renesas R-Car PCIe host controller"
 	depends on ARCH_RENESAS || COMPILE_TEST
-- 
2.20.1


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

* [PATCH v6 04/11] PCI: rcar: Move shareable code to a common file
  2020-04-02 19:38 [PATCH v6 00/11] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
                   ` (2 preceding siblings ...)
  2020-04-02 19:38 ` [PATCH v6 03/11] PCI: drop PCIE_RCAR config option Lad Prabhakar
@ 2020-04-02 19:38 ` Lad Prabhakar
  2020-04-03  8:06   ` Yoshihiro Shimoda
  2020-04-02 19:38 ` [PATCH v6 05/11] PCI: rcar: Fix calculating mask for PCIEPAMR register Lad Prabhakar
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Lad Prabhakar @ 2020-04-02 19:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Magnus Damm, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Marek Vasut, Yoshihiro Shimoda, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	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 | 378 ++++++------------------
 drivers/pci/controller/pcie-rcar.c      | 116 ++++++++
 drivers/pci/controller/pcie-rcar.h      | 131 ++++++++
 4 files changed, 345 insertions(+), 282 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 9dbccb5b24e1..39802ee32946 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 759c6542c5c8..f5740995dd96 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);
@@ -145,42 +48,15 @@ static inline struct rcar_msi *to_rcar_msi(struct msi_controller *chip)
 }
 
 /* Structure representing the PCIe interface */
-struct rcar_pcie {
-	struct device		*dev;
+struct rcar_pcie_host {
+	struct rcar_pcie	pcie;
 	struct phy		*phy;
-	void __iomem		*base;
 	struct list_head	resources;
 	int			root_bus_nr;
 	struct clk		*bus_clk;
 	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);
@@ -190,10 +66,11 @@ static u32 rcar_read_conf(struct rcar_pcie *pcie, int where)
 }
 
 /* Serialization is provided by 'pci_lock' in drivers/pci/access.c */
-static int rcar_pcie_config_access(struct rcar_pcie *pcie,
+static int rcar_pcie_config_access(struct rcar_pcie_host *host,
 		unsigned char access_type, struct pci_bus *bus,
 		unsigned int devfn, int where, u32 *data)
 {
+	struct rcar_pcie *pcie = &host->pcie;
 	unsigned int dev, func, reg, index;
 
 	dev = PCI_SLOT(devfn);
@@ -225,7 +102,7 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie,
 		} 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;
+				host->root_bus_nr = *data & 0xff;
 
 			rcar_pci_write_reg(pcie, *data, PCICONF(index));
 		}
@@ -233,7 +110,7 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie,
 		return PCIBIOS_SUCCESSFUL;
 	}
 
-	if (pcie->root_bus_nr < 0)
+	if (host->root_bus_nr < 0)
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	/* Clear errors */
@@ -244,7 +121,7 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie,
 		PCIE_CONF_DEV(dev) | PCIE_CONF_FUNC(func) | reg, PCIECAR);
 
 	/* Enable the configuration access */
-	if (bus->parent->number == pcie->root_bus_nr)
+	if (bus->parent->number == host->root_bus_nr)
 		rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE0, PCIECCTLR);
 	else
 		rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE1, PCIECCTLR);
@@ -272,10 +149,10 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie,
 static int rcar_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
 			       int where, int size, u32 *val)
 {
-	struct rcar_pcie *pcie = bus->sysdata;
+	struct rcar_pcie_host *host = bus->sysdata;
 	int ret;
 
-	ret = rcar_pcie_config_access(pcie, RCAR_PCI_ACCESS_READ,
+	ret = rcar_pcie_config_access(host, RCAR_PCI_ACCESS_READ,
 				      bus, devfn, where, val);
 	if (ret != PCIBIOS_SUCCESSFUL) {
 		*val = 0xffffffff;
@@ -297,12 +174,12 @@ static int rcar_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
 static int rcar_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
 				int where, int size, u32 val)
 {
-	struct rcar_pcie *pcie = bus->sysdata;
+	struct rcar_pcie_host *host = bus->sysdata;
 	unsigned int shift;
 	u32 data;
 	int ret;
 
-	ret = rcar_pcie_config_access(pcie, RCAR_PCI_ACCESS_READ,
+	ret = rcar_pcie_config_access(host, RCAR_PCI_ACCESS_READ,
 				      bus, devfn, where, &data);
 	if (ret != PCIBIOS_SUCCESSFUL)
 		return ret;
@@ -321,7 +198,7 @@ static int rcar_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
 	} else
 		data = val;
 
-	ret = rcar_pcie_config_access(pcie, RCAR_PCI_ACCESS_WRITE,
+	ret = rcar_pcie_config_access(host, RCAR_PCI_ACCESS_WRITE,
 				      bus, devfn, where, &data);
 
 	return ret;
@@ -332,48 +209,14 @@ 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)
+static int rcar_pcie_setup(struct list_head *resource,
+			   struct rcar_pcie_host *host)
 {
 	struct resource_entry *win;
 	int i = 0;
 
 	/* Setup PCI resources */
-	resource_list_for_each_entry(win, &pci->resources) {
+	resource_list_for_each_entry(win, &host->resources) {
 		struct resource *res = win->res;
 
 		if (!res->flags)
@@ -382,11 +225,11 @@ 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(&host->pcie, i, res);
 			i++;
 			break;
 		case IORESOURCE_BUS:
-			pci->root_bus_nr = res->start;
+			host->root_bus_nr = res->start;
 			break;
 		default:
 			continue;
@@ -452,28 +295,29 @@ static void rcar_pcie_force_speedup(struct rcar_pcie *pcie)
 		 (macsr & LINK_SPEED) == LINK_SPEED_5_0GTS ? "5" : "2.5");
 }
 
-static int rcar_pcie_enable(struct rcar_pcie *pcie)
+static int rcar_pcie_enable(struct rcar_pcie_host *host)
 {
+	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(host);
+	struct rcar_pcie *pcie = &host->pcie;
 	struct device *dev = pcie->dev;
-	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
 	struct pci_bus *bus, *child;
 	int ret;
 
 	/* Try setting 5 GT/s link speed */
 	rcar_pcie_force_speedup(pcie);
 
-	rcar_pcie_setup(&bridge->windows, pcie);
+	rcar_pcie_setup(&bridge->windows, host);
 
 	pci_add_flags(PCI_REASSIGN_ALL_BUS);
 
 	bridge->dev.parent = dev;
-	bridge->sysdata = pcie;
-	bridge->busnr = pcie->root_bus_nr;
+	bridge->sysdata = host;
+	bridge->busnr = host->root_bus_nr;
 	bridge->ops = &rcar_pcie_ops;
 	bridge->map_irq = of_irq_parse_and_map_pci;
 	bridge->swizzle_irq = pci_common_swizzle;
 	if (IS_ENABLED(CONFIG_PCI_MSI))
-		bridge->msi = &pcie->msi.chip;
+		bridge->msi = &host->msi.chip;
 
 	ret = pci_scan_root_bus_bridge(bridge);
 	if (ret < 0)
@@ -535,35 +379,6 @@ static void phy_write_reg(struct rcar_pcie *pcie,
 	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;
@@ -601,7 +416,7 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
 
 	/* Enable data link layer active state reporting */
 	rcar_rmw32(pcie, REXPCAP(PCI_EXP_LNKCAP), PCI_EXP_LNKCAP_DLLLARC,
-		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);
@@ -634,8 +449,10 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
 	return 0;
 }
 
-static int rcar_pcie_phy_init_h1(struct rcar_pcie *pcie)
+static int rcar_pcie_phy_init_h1(struct rcar_pcie_host *host)
 {
+	struct rcar_pcie *pcie = &host->pcie;
+
 	/* Initialize the phy */
 	phy_write_reg(pcie, 0, 0x42, 0x1, 0x0EC34191);
 	phy_write_reg(pcie, 1, 0x42, 0x1, 0x0EC34180);
@@ -657,8 +474,10 @@ static int rcar_pcie_phy_init_h1(struct rcar_pcie *pcie)
 	return 0;
 }
 
-static int rcar_pcie_phy_init_gen2(struct rcar_pcie *pcie)
+static int rcar_pcie_phy_init_gen2(struct rcar_pcie_host *host)
 {
+	struct rcar_pcie *pcie = &host->pcie;
+
 	/*
 	 * These settings come from the R-Car Series, 2nd Generation User's
 	 * Manual, section 50.3.1 (2) Initialization of the physical layer.
@@ -677,17 +496,17 @@ static int rcar_pcie_phy_init_gen2(struct rcar_pcie *pcie)
 	return 0;
 }
 
-static int rcar_pcie_phy_init_gen3(struct rcar_pcie *pcie)
+static int rcar_pcie_phy_init_gen3(struct rcar_pcie_host *host)
 {
 	int err;
 
-	err = phy_init(pcie->phy);
+	err = phy_init(host->phy);
 	if (err)
 		return err;
 
-	err = phy_power_on(pcie->phy);
+	err = phy_power_on(host->phy);
 	if (err)
-		phy_exit(pcie->phy);
+		phy_exit(host->phy);
 
 	return err;
 }
@@ -730,8 +549,9 @@ static void rcar_msi_free(struct rcar_msi *chip, unsigned long irq)
 
 static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
 {
-	struct rcar_pcie *pcie = data;
-	struct rcar_msi *msi = &pcie->msi;
+	struct rcar_pcie_host *host = data;
+	struct rcar_pcie *pcie = &host->pcie;
+	struct rcar_msi *msi = &host->msi;
 	struct device *dev = pcie->dev;
 	unsigned long reg;
 
@@ -770,7 +590,9 @@ static int rcar_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
 			      struct msi_desc *desc)
 {
 	struct rcar_msi *msi = to_rcar_msi(chip);
-	struct rcar_pcie *pcie = container_of(chip, struct rcar_pcie, msi.chip);
+	struct rcar_pcie_host *host = container_of(chip, struct rcar_pcie_host,
+						   msi.chip);
+	struct rcar_pcie *pcie = &host->pcie;
 	struct msi_msg msg;
 	unsigned int irq;
 	int hwirq;
@@ -799,8 +621,10 @@ static int rcar_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
 static int rcar_msi_setup_irqs(struct msi_controller *chip,
 			       struct pci_dev *pdev, int nvec, int type)
 {
-	struct rcar_pcie *pcie = container_of(chip, struct rcar_pcie, msi.chip);
 	struct rcar_msi *msi = to_rcar_msi(chip);
+	struct rcar_pcie_host *host = container_of(chip, struct rcar_pcie_host,
+						   msi.chip);
+	struct rcar_pcie *pcie = &host->pcie;
 	struct msi_desc *desc;
 	struct msi_msg msg;
 	unsigned int irq;
@@ -877,9 +701,9 @@ static const struct irq_domain_ops msi_domain_ops = {
 	.map = rcar_msi_map,
 };
 
-static void rcar_pcie_unmap_msi(struct rcar_pcie *pcie)
+static void rcar_pcie_unmap_msi(struct rcar_pcie_host *host)
 {
-	struct rcar_msi *msi = &pcie->msi;
+	struct rcar_msi *msi = &host->msi;
 	int i, irq;
 
 	for (i = 0; i < INT_PCI_MSI_NR; i++) {
@@ -891,10 +715,11 @@ static void rcar_pcie_unmap_msi(struct rcar_pcie *pcie)
 	irq_domain_remove(msi->domain);
 }
 
-static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)
+static int rcar_pcie_enable_msi(struct rcar_pcie_host *host)
 {
+	struct rcar_pcie *pcie = &host->pcie;
 	struct device *dev = pcie->dev;
-	struct rcar_msi *msi = &pcie->msi;
+	struct rcar_msi *msi = &host->msi;
 	phys_addr_t base;
 	int err, i;
 
@@ -918,7 +743,7 @@ static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)
 	/* Two irqs are for MSI, but they are also used for non-MSI irqs */
 	err = devm_request_irq(dev, msi->irq1, rcar_pcie_msi_irq,
 			       IRQF_SHARED | IRQF_NO_THREAD,
-			       rcar_msi_irq_chip.name, pcie);
+			       rcar_msi_irq_chip.name, host);
 	if (err < 0) {
 		dev_err(dev, "failed to request IRQ: %d\n", err);
 		goto err;
@@ -926,7 +751,7 @@ static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)
 
 	err = devm_request_irq(dev, msi->irq2, rcar_pcie_msi_irq,
 			       IRQF_SHARED | IRQF_NO_THREAD,
-			       rcar_msi_irq_chip.name, pcie);
+			       rcar_msi_irq_chip.name, host);
 	if (err < 0) {
 		dev_err(dev, "failed to request IRQ: %d\n", err);
 		goto err;
@@ -949,13 +774,14 @@ static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)
 	return 0;
 
 err:
-	rcar_pcie_unmap_msi(pcie);
+	rcar_pcie_unmap_msi(host);
 	return err;
 }
 
-static void rcar_pcie_teardown_msi(struct rcar_pcie *pcie)
+static void rcar_pcie_teardown_msi(struct rcar_pcie_host *host)
 {
-	struct rcar_msi *msi = &pcie->msi;
+	struct rcar_pcie *pcie = &host->pcie;
+	struct rcar_msi *msi = &host->msi;
 
 	/* Disable all MSI interrupts */
 	rcar_pci_write_reg(pcie, 0, PCIEMSIIER);
@@ -965,18 +791,19 @@ static void rcar_pcie_teardown_msi(struct rcar_pcie *pcie)
 
 	free_pages(msi->pages, 0);
 
-	rcar_pcie_unmap_msi(pcie);
+	rcar_pcie_unmap_msi(host);
 }
 
-static int rcar_pcie_get_resources(struct rcar_pcie *pcie)
+static int rcar_pcie_get_resources(struct rcar_pcie_host *host)
 {
+	struct rcar_pcie *pcie = &host->pcie;
 	struct device *dev = pcie->dev;
 	struct resource res;
 	int err, i;
 
-	pcie->phy = devm_phy_optional_get(dev, "pcie");
-	if (IS_ERR(pcie->phy))
-		return PTR_ERR(pcie->phy);
+	host->phy = devm_phy_optional_get(dev, "pcie");
+	if (IS_ERR(host->phy))
+		return PTR_ERR(host->phy);
 
 	err = of_address_to_resource(dev->of_node, 0, &res);
 	if (err)
@@ -986,10 +813,10 @@ static int rcar_pcie_get_resources(struct rcar_pcie *pcie)
 	if (IS_ERR(pcie->base))
 		return PTR_ERR(pcie->base);
 
-	pcie->bus_clk = devm_clk_get(dev, "pcie_bus");
-	if (IS_ERR(pcie->bus_clk)) {
+	host->bus_clk = devm_clk_get(dev, "pcie_bus");
+	if (IS_ERR(host->bus_clk)) {
 		dev_err(dev, "cannot get pcie bus clock\n");
-		return PTR_ERR(pcie->bus_clk);
+		return PTR_ERR(host->bus_clk);
 	}
 
 	i = irq_of_parse_and_map(dev->of_node, 0);
@@ -998,7 +825,7 @@ static int rcar_pcie_get_resources(struct rcar_pcie *pcie)
 		err = -ENOENT;
 		goto err_irq1;
 	}
-	pcie->msi.irq1 = i;
+	host->msi.irq1 = i;
 
 	i = irq_of_parse_and_map(dev->of_node, 1);
 	if (!i) {
@@ -1006,12 +833,12 @@ static int rcar_pcie_get_resources(struct rcar_pcie *pcie)
 		err = -ENOENT;
 		goto err_irq2;
 	}
-	pcie->msi.irq2 = i;
+	host->msi.irq2 = i;
 
 	return 0;
 
 err_irq2:
-	irq_dispose_mapping(pcie->msi.irq1);
+	irq_dispose_mapping(host->msi.irq1);
 err_irq1:
 	return err;
 }
@@ -1054,21 +881,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, cpu_addr, pci_addr,
+				      lower_32_bits(mask) | flags, idx, true);
 
 		pci_addr += size;
 		cpu_addr += size;
@@ -1079,14 +893,14 @@ static int rcar_pcie_inbound_ranges(struct rcar_pcie *pcie,
 	return 0;
 }
 
-static int rcar_pcie_parse_map_dma_ranges(struct rcar_pcie *pcie)
+static int rcar_pcie_parse_map_dma_ranges(struct rcar_pcie_host *host)
 {
-	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
+	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(host);
 	struct resource_entry *entry;
 	int index = 0, err = 0;
 
 	resource_list_for_each_entry(entry, &bridge->dma_ranges) {
-		err = rcar_pcie_inbound_ranges(pcie, entry, &index);
+		err = rcar_pcie_inbound_ranges(&host->pcie, entry, &index);
 		if (err)
 			break;
 	}
@@ -1113,22 +927,23 @@ static const struct of_device_id rcar_pcie_of_match[] = {
 static int rcar_pcie_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct rcar_pcie_host *host;
 	struct rcar_pcie *pcie;
 	u32 data;
 	int err;
-	int (*phy_init_fn)(struct rcar_pcie *);
+	int (*phy_init_fn)(struct rcar_pcie_host *);
 	struct pci_host_bridge *bridge;
 
-	bridge = pci_alloc_host_bridge(sizeof(*pcie));
+	bridge = pci_alloc_host_bridge(sizeof(*host));
 	if (!bridge)
 		return -ENOMEM;
 
-	pcie = pci_host_bridge_priv(bridge);
-
+	host = pci_host_bridge_priv(bridge);
+	pcie = &host->pcie;
 	pcie->dev = dev;
-	platform_set_drvdata(pdev, pcie);
+	platform_set_drvdata(pdev, host);
 
-	err = pci_parse_request_of_pci_ranges(dev, &pcie->resources,
+	err = pci_parse_request_of_pci_ranges(dev, &host->resources,
 					      &bridge->dma_ranges, NULL);
 	if (err)
 		goto err_free_bridge;
@@ -1140,24 +955,24 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 		goto err_pm_disable;
 	}
 
-	err = rcar_pcie_get_resources(pcie);
+	err = rcar_pcie_get_resources(host);
 	if (err < 0) {
 		dev_err(dev, "failed to request resources: %d\n", err);
 		goto err_pm_put;
 	}
 
-	err = clk_prepare_enable(pcie->bus_clk);
+	err = clk_prepare_enable(host->bus_clk);
 	if (err) {
 		dev_err(dev, "failed to enable bus clock: %d\n", err);
 		goto err_unmap_msi_irqs;
 	}
 
-	err = rcar_pcie_parse_map_dma_ranges(pcie);
+	err = rcar_pcie_parse_map_dma_ranges(host);
 	if (err)
 		goto err_clk_disable;
 
 	phy_init_fn = of_device_get_match_data(dev);
-	err = phy_init_fn(pcie);
+	err = phy_init_fn(host);
 	if (err) {
 		dev_err(dev, "failed to init PCIe PHY\n");
 		goto err_clk_disable;
@@ -1174,7 +989,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 	dev_info(dev, "PCIe x%d: link up\n", (data >> 20) & 0x3f);
 
 	if (IS_ENABLED(CONFIG_PCI_MSI)) {
-		err = rcar_pcie_enable_msi(pcie);
+		err = rcar_pcie_enable_msi(host);
 		if (err < 0) {
 			dev_err(dev,
 				"failed to enable MSI support: %d\n",
@@ -1183,7 +998,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 		}
 	}
 
-	err = rcar_pcie_enable(pcie);
+	err = rcar_pcie_enable(host);
 	if (err)
 		goto err_msi_teardown;
 
@@ -1191,27 +1006,27 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 
 err_msi_teardown:
 	if (IS_ENABLED(CONFIG_PCI_MSI))
-		rcar_pcie_teardown_msi(pcie);
+		rcar_pcie_teardown_msi(host);
 
 err_phy_shutdown:
-	if (pcie->phy) {
-		phy_power_off(pcie->phy);
-		phy_exit(pcie->phy);
+	if (host->phy) {
+		phy_power_off(host->phy);
+		phy_exit(host->phy);
 	}
 
 err_clk_disable:
-	clk_disable_unprepare(pcie->bus_clk);
+	clk_disable_unprepare(host->bus_clk);
 
 err_unmap_msi_irqs:
-	irq_dispose_mapping(pcie->msi.irq2);
-	irq_dispose_mapping(pcie->msi.irq1);
+	irq_dispose_mapping(host->msi.irq2);
+	irq_dispose_mapping(host->msi.irq1);
 
 err_pm_put:
 	pm_runtime_put(dev);
 
 err_pm_disable:
 	pm_runtime_disable(dev);
-	pci_free_resource_list(&pcie->resources);
+	pci_free_resource_list(&host->resources);
 
 err_free_bridge:
 	pci_free_host_bridge(bridge);
@@ -1221,7 +1036,8 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 
 static int rcar_pcie_resume_noirq(struct device *dev)
 {
-	struct rcar_pcie *pcie = dev_get_drvdata(dev);
+	struct rcar_pcie_host *host = dev_get_drvdata(dev);
+	struct rcar_pcie *pcie = &host->pcie;
 
 	if (rcar_pci_read_reg(pcie, PMSR) &&
 	    !(rcar_pci_read_reg(pcie, PCIETCTLR) & DL_DOWN))
diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c
new file mode 100644
index 000000000000..b82f200985ec
--- /dev/null
+++ b/drivers/pci/controller/pcie-rcar.c
@@ -0,0 +1,116 @@
+// 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(struct rcar_pcie *pcie, u32 val, unsigned int reg)
+{
+	writel(val, pcie->base + reg);
+}
+
+u32 rcar_pci_read_reg(struct rcar_pcie *pcie, unsigned int reg)
+{
+	return readl(pcie->base + reg);
+}
+
+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);
+}
+
+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;
+}
+
+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;
+}
+
+void rcar_pcie_set_outbound(struct rcar_pcie *pcie, int win,
+			    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(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));
+}
+
+void rcar_pcie_set_inbound(struct rcar_pcie *pcie, 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(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, flags, PCIELAMR(idx));
+
+	if (host)
+		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));
+}
diff --git a/drivers/pci/controller/pcie-rcar.h b/drivers/pci/controller/pcie-rcar.h
new file mode 100644
index 000000000000..cec7768b4725
--- /dev/null
+++ b/drivers/pci/controller/pcie-rcar.h
@@ -0,0 +1,131 @@
+/* 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
+
+struct rcar_pcie {
+	struct device		*dev;
+	void __iomem		*base;
+};
+
+enum {
+	RCAR_PCI_ACCESS_READ,
+	RCAR_PCI_ACCESS_WRITE,
+};
+
+void rcar_pci_write_reg(struct rcar_pcie *pcie, u32 val, unsigned int reg);
+u32 rcar_pci_read_reg(struct rcar_pcie *pcie, unsigned int reg);
+void rcar_rmw32(struct rcar_pcie *pcie, int where, u32 mask, u32 data);
+int rcar_pcie_wait_for_phyrdy(struct rcar_pcie *pcie);
+int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie);
+void rcar_pcie_set_outbound(struct rcar_pcie *pcie, int win,
+			    struct resource *res);
+void rcar_pcie_set_inbound(struct rcar_pcie *pcie, u64 cpu_addr,
+			   u64 pci_addr, u64 flags, int idx, bool host);
+
+#endif
-- 
2.20.1


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

* [PATCH v6 05/11] PCI: rcar: Fix calculating mask for PCIEPAMR register
  2020-04-02 19:38 [PATCH v6 00/11] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
                   ` (3 preceding siblings ...)
  2020-04-02 19:38 ` [PATCH v6 04/11] PCI: rcar: Move shareable code to a common file Lad Prabhakar
@ 2020-04-02 19:38 ` Lad Prabhakar
  2020-04-02 19:38 ` [PATCH v6 06/11] PCI: endpoint: Add support to handle multiple base for mapping outbound memory Lad Prabhakar
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 30+ messages in thread
From: Lad Prabhakar @ 2020-04-02 19:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Magnus Damm, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Marek Vasut, Yoshihiro Shimoda, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	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>
Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@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 b82f200985ec..b46c69ac62f2 100644
--- a/drivers/pci/controller/pcie-rcar.c
+++ b/drivers/pci/controller/pcie-rcar.c
@@ -75,7 +75,10 @@ void rcar_pcie_set_outbound(struct rcar_pcie *pcie, int win,
 	 * 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(pcie, mask << 7, PCIEPAMR(win));
 
 	if (res->flags & IORESOURCE_IO)
-- 
2.20.1


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

* [PATCH v6 06/11] PCI: endpoint: Add support to handle multiple base for mapping outbound memory
  2020-04-02 19:38 [PATCH v6 00/11] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
                   ` (4 preceding siblings ...)
  2020-04-02 19:38 ` [PATCH v6 05/11] PCI: rcar: Fix calculating mask for PCIEPAMR register Lad Prabhakar
@ 2020-04-02 19:38 ` Lad Prabhakar
  2020-04-03  8:23   ` Yoshihiro Shimoda
  2020-04-02 19:38 ` [PATCH v6 07/11] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller Lad Prabhakar
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Lad Prabhakar @ 2020-04-02 19:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Magnus Damm, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Marek Vasut, Yoshihiro Shimoda, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	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() initializes address space for endpoint
controller which support single window and whereas __pci_epc_mem_init()
now accepts pointer to multiple windows supported by endpoint controller.

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

diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 1c173dad67d1..d62eec6bbbbb 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -450,7 +450,8 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 		epc->max_functions = 1;
 
 	ret = pci_epc_mem_init(epc, pcie->mem_res->start,
-			       resource_size(pcie->mem_res));
+			       resource_size(pcie->mem_res),
+			       PAGE_SIZE);
 	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 1cdcbd102ce8..a78902cbf2f0 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -412,11 +412,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);
+				  epc->mem->window.page_size);
 	if (ret)
 		return ret;
 
@@ -459,9 +459,9 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 		return -EPERM;
 	}
 
-	aligned_offset = msg_addr & (epc->mem->page_size - 1);
+	aligned_offset = msg_addr & (epc->mem->window.page_size - 1);
 	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys,  msg_addr,
-				  epc->mem->page_size);
+				  epc->mem->window.page_size);
 	if (ret)
 		return ret;
 
@@ -477,7 +477,7 @@ void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
 	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);
 }
@@ -610,15 +610,15 @@ 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);
+	ret = pci_epc_mem_init(epc, ep->phys_base, ep->addr_size,
+			       ep->page_size);
 	if (ret < 0) {
 		dev_err(dev, "Failed to initialize address space\n");
 		return ret;
 	}
 
 	ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
-					     epc->mem->page_size);
+					     epc->mem->window.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 d743b0a48988..5eaf36629a75 100644
--- a/drivers/pci/controller/pcie-rockchip-ep.c
+++ b/drivers/pci/controller/pcie-rockchip-ep.c
@@ -615,7 +615,7 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)
 	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));
+			       resource_size(rockchip->mem_res), PAGE_SIZE);
 	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 abfac1109a13..87effe825f81 100644
--- a/drivers/pci/endpoint/pci-epc-mem.c
+++ b/drivers/pci/endpoint/pci-epc-mem.c
@@ -23,7 +23,7 @@
 static int pci_epc_mem_get_order(struct pci_epc_mem *mem, size_t size)
 {
 	int order;
-	unsigned int page_shift = ilog2(mem->page_size);
+	unsigned int page_shift = ilog2(mem->window.page_size);
 
 	size--;
 	size >>= page_shift;
@@ -38,61 +38,95 @@ 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,
+		       unsigned 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;
+	int pages;
+	int ret;
+	int i;
 
-	if (page_size < PAGE_SIZE)
-		page_size = PAGE_SIZE;
+	epc->num_windows = 0;
 
-	page_shift = ilog2(page_size);
-	pages = size >> page_shift;
-	bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
+	if (!windows || !num_windows)
+		return -EINVAL;
 
-	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
-	if (!mem) {
-		ret = -ENOMEM;
-		goto err;
-	}
+	epc->windows = kcalloc(num_windows, sizeof(*mem), GFP_KERNEL);
+	if (!epc->windows)
+		return -ENOMEM;
 
-	bitmap = kzalloc(bitmap_size, GFP_KERNEL);
-	if (!bitmap) {
-		ret = -ENOMEM;
-		goto err_mem;
-	}
+	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;
+			i -= 1;
+			goto err_mem;
+		}
+
+		bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+		if (!bitmap) {
+			ret = -ENOMEM;
+			kfree(mem);
+			i -= 1;
+			goto err_mem;
+		}
 
-	mem->bitmap = bitmap;
-	mem->phys_base = phys_base;
-	mem->page_size = page_size;
-	mem->pages = pages;
-	mem->size = size;
-	mutex_init(&mem->lock);
+		mem->window.phys_base = windows[i].phys_base;
+		mem->window.size = windows[i].size;
+		mem->window.page_size = page_size;
+		mem->bitmap = bitmap;
+		mem->pages = pages;
+		mutex_init(&mem->lock);
+		epc->windows[i] = mem;
+	}
 
-	epc->mem = mem;
+	epc->mem = epc->windows[0];
+	epc->num_windows = num_windows;
 
 	return 0;
 
 err_mem:
-	kfree(mem);
+	for (; i >= 0; i--) {
+		mem = epc->windows[i];
+		kfree(mem->bitmap);
+		kfree(mem);
+	}
+	kfree(epc->windows);
 
-err:
-return ret;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(__pci_epc_mem_init);
 
+int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t base,
+		     size_t size, size_t page_size)
+{
+	struct pci_epc_mem_window mem_window;
+
+	mem_window.phys_base = base;
+	mem_window.size = size;
+	mem_window.page_size = page_size;
+
+	return __pci_epc_mem_init(epc, &mem_window, 1);
+}
+EXPORT_SYMBOL_GPL(pci_epc_mem_init);
+
 /**
  * pci_epc_mem_exit() - cleanup the pci_epc_mem structure
  * @epc: the EPC device that invoked pci_epc_mem_exit
@@ -102,11 +136,22 @@ 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->num_windows)
+		return;
+
+	for (i = 0; i <= epc->num_windows; i++) {
+		mem = epc->windows[i];
+		kfree(mem->bitmap);
+		kfree(mem);
+	}
+	kfree(epc->windows);
 
+	epc->windows = NULL;
 	epc->mem = NULL;
-	kfree(mem->bitmap);
-	kfree(mem);
+	epc->num_windows = 0;
 }
 EXPORT_SYMBOL_GPL(pci_epc_mem_exit);
 
@@ -122,31 +167,56 @@ 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 = NULL;
-	struct pci_epc_mem *mem = epc->mem;
-	unsigned int page_shift = ilog2(mem->page_size);
+	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);
-
-	mutex_lock(&mem->lock);
-	pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);
-	if (pageno < 0)
-		goto ret;
+	for (i = 0; i < epc->num_windows; i++) {
+		mem = epc->windows[i];
+		mutex_lock(&mem->lock);
+		size = ALIGN(size, mem->window.page_size);
+		order = pci_epc_mem_get_order(mem, size);
 
-	*phys_addr = mem->phys_base + ((phys_addr_t)pageno << page_shift);
-	virt_addr = ioremap(*phys_addr, size);
-	if (!virt_addr)
-		bitmap_release_region(mem->bitmap, pageno, order);
+		pageno = bitmap_find_free_region(mem->bitmap, mem->pages,
+						 order);
+		if (pageno >= 0) {
+			page_shift = ilog2(mem->window.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);
+			mutex_unlock(&mem->lock);
+			return virt_addr;
+		}
+		mutex_unlock(&mem->lock);
+	}
 
-ret:
-	mutex_unlock(&mem->lock);
 	return virt_addr;
 }
 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->num_windows; i++) {
+		mem = epc->windows[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
@@ -159,14 +229,23 @@ 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;
+	size_t page_size;
 	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_size = mem->window.page_size;
+	page_shift = ilog2(page_size);
 	iounmap(virt_addr);
-	pageno = (phys_addr - mem->phys_base) >> page_shift;
-	size = ALIGN(size, mem->page_size);
+	pageno = (phys_addr - mem->window.phys_base) >> page_shift;
+	size = ALIGN(size, page_size);
 	order = pci_epc_mem_get_order(mem, size);
 	mutex_lock(&mem->lock);
 	bitmap_release_region(mem->bitmap, pageno, order);
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index e0ed9d01f6e5..d5da11cf0f2a 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -65,20 +65,28 @@ struct pci_epc_ops {
 	struct module *owner;
 };
 
+/**
+ * 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
  * @lock: mutex to protect bitmap
+ * @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;
 	/* mutex to protect against concurrent access for memory allocation*/
 	struct mutex	lock;
@@ -89,7 +97,11 @@ 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
+ * @windows: array of address space of the endpoint controller
+ * @mem: first window of the endpoint controller, which corresponds to
+ *       default address space of the endpoint controller supporting
+ *       single window.
+ * @num_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: mutex to protect pci_epc ops
@@ -100,7 +112,9 @@ struct pci_epc {
 	struct device			dev;
 	struct list_head		pci_epf;
 	const struct pci_epc_ops	*ops;
+	struct pci_epc_mem		**windows;
 	struct pci_epc_mem		*mem;
+	unsigned int			num_windows;
 	u8				max_functions;
 	struct config_group		*group;
 	/* mutex to protect against concurrent access of EP controller */
@@ -137,9 +151,6 @@ 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)
-
 static inline void epc_set_drvdata(struct pci_epc *epc, void *data)
 {
 	dev_set_drvdata(&epc->dev, data);
@@ -195,8 +206,10 @@ 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,
+		       unsigned int num_windows);
+int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t base,
+		     size_t size, size_t page_size);
 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.20.1


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

* [PATCH v6 07/11] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller
  2020-04-02 19:38 [PATCH v6 00/11] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
                   ` (5 preceding siblings ...)
  2020-04-02 19:38 ` [PATCH v6 06/11] PCI: endpoint: Add support to handle multiple base for mapping outbound memory Lad Prabhakar
@ 2020-04-02 19:38 ` Lad Prabhakar
  2020-04-03  8:28   ` Yoshihiro Shimoda
  2020-04-02 19:38 ` [PATCH v6 08/11] PCI: rcar: Add support for rcar PCIe controller in endpoint mode Lad Prabhakar
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Lad Prabhakar @ 2020-04-02 19:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Magnus Damm, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Marek Vasut, Yoshihiro Shimoda, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Lad Prabhakar

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>
---
 .../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 000000000000..07cd5a7325d0
--- /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.20.1


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

* [PATCH v6 08/11] PCI: rcar: Add support for rcar PCIe controller in endpoint mode
  2020-04-02 19:38 [PATCH v6 00/11] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
                   ` (6 preceding siblings ...)
  2020-04-02 19:38 ` [PATCH v6 07/11] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller Lad Prabhakar
@ 2020-04-02 19:38 ` Lad Prabhakar
  2020-04-03  8:44   ` Yoshihiro Shimoda
  2020-04-02 19:38 ` [PATCH v6 09/11] PCI: Add Renesas R8A774C0 device ID Lad Prabhakar
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Lad Prabhakar @ 2020-04-02 19:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Magnus Damm, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Marek Vasut, Yoshihiro Shimoda, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	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 | 556 ++++++++++++++++++++++++++
 drivers/pci/controller/pcie-rcar.h    |   9 +
 4 files changed, 574 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-rcar-ep.c

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 37e234ad583b..283ff8175cb7 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 39802ee32946..741a5204aa5e 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 000000000000..047be2ac062c
--- /dev/null
+++ b/drivers/pci/controller/pcie-rcar-ep.c
@@ -0,0 +1,556 @@
+// 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_endpoint {
+	struct rcar_pcie	pcie;
+	phys_addr_t		*ob_mapped_addr;
+	struct pci_epc_mem_window *ob_window;
+	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, 0, PCIETCTLR);
+
+	/* Set endpoint mode */
+	rcar_pci_write_reg(pcie, 0, PCIEMSR);
+
+	/* 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_ENDPOINT << 4);
+	rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
+		   PCI_HEADER_TYPE_NORMAL);
+
+	/* Write out the physical slot number = 0 */
+	rcar_rmw32(pcie, REXPCAP(PCI_EXP_SLTCAP), PCI_EXP_SLTCAP_PSN, 0);
+
+	val = rcar_pci_read_reg(pcie, EXPCAP(1));
+	/* device supports fixed 128 bytes MPSS */
+	val &= ~GENMASK(2, 0);
+	rcar_pci_write_reg(pcie, val, EXPCAP(1));
+
+	val = rcar_pci_read_reg(pcie, EXPCAP(2));
+	/* read requests size 128 bytes */
+	val &= ~GENMASK(14, 12);
+	/* payload size 128 bytes */
+	val &= ~GENMASK(7, 5);
+	rcar_pci_write_reg(pcie, val, EXPCAP(2));
+
+	/* Set target link speed to 5.0 GT/s */
+	rcar_rmw32(pcie, EXPCAP(12), PCI_EXP_LNKSTA_CLS,
+		   PCI_EXP_LNKSTA_CLS_5_0GB);
+
+	/* Set the completion timer timeout to the maximum 50ms. */
+	rcar_rmw32(pcie, TLCTLR + 1, 0x3f, 50);
+
+	/* Terminate list of capabilities (Next Capability Offset=0) */
+	rcar_rmw32(pcie, RVCCAP(0), 0xfff00000, 0);
+
+	rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR);
+
+	/* flush modifications */
+	wmb();
+}
+
+static int rcar_pcie_ep_get_window(struct rcar_pcie_endpoint *ep,
+				   phys_addr_t addr)
+{
+	int i;
+
+	for (i = 0; i < ep->num_ob_windows; i++)
+		if (ep->ob_window[i].phys_base == addr)
+			return i;
+
+	return -EINVAL;
+}
+
+static int rcar_pcie_parse_outbound_ranges(struct rcar_pcie_endpoint *ep,
+					   struct platform_device *pdev)
+{
+	struct rcar_pcie *pcie = &ep->pcie;
+	char outbound_name[10];
+	struct resource *res;
+	unsigned int i = 0;
+
+	ep->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;
+		}
+
+		ep->ob_window[i].phys_base = res->start;
+		ep->ob_window[i].size = resource_size(res);
+		/* controller doesn't support multiple allocation
+		 * from same window, so set page_size to window size
+		 */
+		ep->ob_window[i].page_size = resource_size(res);
+	}
+	ep->num_ob_windows = i;
+
+	return 0;
+}
+
+static int rcar_pcie_ep_get_pdata(struct rcar_pcie_endpoint *ep,
+				  struct platform_device *pdev)
+{
+	struct rcar_pcie *pcie = &ep->pcie;
+	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);
+
+	ep->ob_window = devm_kcalloc(dev, RCAR_PCI_MAX_RESOURCES,
+				     sizeof(*window), GFP_KERNEL);
+	if (!ep->ob_window)
+		return -ENOMEM;
+
+	rcar_pcie_parse_outbound_ranges(ep, pdev);
+
+	err = of_property_read_u8(dev->of_node, "max-functions",
+				  &ep->max_functions);
+	if (err < 0)
+		ep->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_endpoint *ep = epc_get_drvdata(epc);
+	struct rcar_pcie *pcie = &ep->pcie;
+	u32 val;
+
+	if (!fn)
+		val = hdr->vendorid;
+	else
+		val = rcar_pci_read_reg(pcie, IDSETR0);
+	val |= hdr->deviceid << 16;
+	rcar_pci_write_reg(pcie, val, IDSETR0);
+
+	val = hdr->revid;
+	val |= hdr->progif_code << 8;
+	val |= hdr->subclass_code << 16;
+	val |= hdr->baseclass_code << 24;
+	rcar_pci_write_reg(pcie, val, IDSETR1);
+
+	if (!fn)
+		val = hdr->subsys_vendor_id;
+	else
+		val = rcar_pci_read_reg(pcie, SUBIDSETR);
+	val |= hdr->subsys_id << 16;
+	rcar_pci_write_reg(pcie, val, SUBIDSETR);
+
+	if (hdr->interrupt_pin > PCI_INTERRUPT_INTA)
+		return -EINVAL;
+	val = rcar_pci_read_reg(pcie, PCICONF(15));
+	val |= (hdr->interrupt_pin << 8);
+	rcar_pci_write_reg(pcie, 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)
+{
+	int flags = epf_bar->flags | LAR_ENABLE | LAM_64BIT;
+	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
+	u64 size = 1ULL << fls64(epf_bar->size - 1);
+	dma_addr_t cpu_addr = epf_bar->phys_addr;
+	enum pci_barno bar = epf_bar->barno;
+	struct rcar_pcie *pcie = &ep->pcie;
+	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(pcie->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(pcie, cpu_addr,
+			      0x0, mask | flags, idx, false);
+
+	err = rcar_pcie_wait_for_phyrdy(pcie);
+	if (err) {
+		dev_err(pcie->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_endpoint *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->pcie, 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_set_msi(struct pci_epc *epc, u8 fn, u8 interrupts)
+{
+	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
+	struct rcar_pcie *pcie = &ep->pcie;
+	u32 flags;
+
+	flags = rcar_pci_read_reg(pcie, MSICAP(fn));
+	flags |= interrupts << MSICAP0_MMESCAP_OFFSET;
+	rcar_pci_write_reg(pcie, flags, MSICAP(fn));
+
+	return 0;
+}
+
+static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
+{
+	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
+	struct rcar_pcie *pcie = &ep->pcie;
+	u32 flags;
+
+	flags = rcar_pci_read_reg(pcie, MSICAP(fn));
+	if (!(flags & MSICAP0_MSIE))
+		return -EINVAL;
+
+	return ((flags & MSICAP0_MMENUM_MASK) >> MSICAP0_MMENUM_OFFSET);
+}
+
+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_endpoint *ep = epc_get_drvdata(epc);
+	struct rcar_pcie *pcie = &ep->pcie;
+	struct resource res;
+	int window;
+	int err;
+
+	/* check if we have a link. */
+	err = rcar_pcie_wait_for_dl(pcie);
+	if (err) {
+		dev_err(pcie->dev, "link not up\n");
+		return err;
+	}
+
+	window = rcar_pcie_ep_get_window(ep, addr);
+	if (window < 0) {
+		dev_err(pcie->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(pcie, window, &res);
+
+	ep->ob_mapped_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_endpoint *ep = epc_get_drvdata(epc);
+	struct resource res;
+	int idx;
+
+	for (idx = 0; idx < ep->num_ob_windows; idx++)
+		if (ep->ob_mapped_addr[idx] == addr)
+			break;
+
+	if (idx >= ep->num_ob_windows)
+		return;
+
+	memset(&res, 0x0, sizeof(res));
+	rcar_pcie_set_outbound(&ep->pcie, idx, &res);
+
+	ep->ob_mapped_addr[idx] = 0;
+}
+
+static int rcar_pcie_ep_assert_intx(struct rcar_pcie_endpoint *ep,
+				    u8 fn, u8 intx)
+{
+	struct rcar_pcie *pcie = &ep->pcie;
+	u32 val;
+
+	val = rcar_pci_read_reg(pcie, PCIEMSITXR);
+	if ((val & PCI_MSI_FLAGS_ENABLE)) {
+		dev_err(pcie->dev, "MSI is enabled, cannot assert INTx\n");
+		return -EINVAL;
+	}
+
+	val = rcar_pci_read_reg(pcie, PCICONF(1));
+	if ((val & INTDIS)) {
+		dev_err(pcie->dev, "INTx message transmission is disabled\n");
+		return -EINVAL;
+	}
+
+	val = rcar_pci_read_reg(pcie, PCIEINTXR);
+	if ((val & ASTINTX)) {
+		dev_err(pcie->dev, "INTx is already asserted\n");
+		return -EINVAL;
+	}
+
+	val |= ASTINTX;
+	rcar_pci_write_reg(pcie, val, PCIEINTXR);
+	mdelay(1);
+	val = rcar_pci_read_reg(pcie, PCIEINTXR);
+	val &= ~ASTINTX;
+	rcar_pci_write_reg(pcie, val, PCIEINTXR);
+
+	return 0;
+}
+
+static int rcar_pcie_ep_assert_msi(struct rcar_pcie *pcie,
+				   u8 fn, u8 interrupt_num)
+{
+	u16 msi_count;
+	u32 val;
+
+	/* Check MSI enable bit */
+	val = rcar_pci_read_reg(pcie, MSICAP(fn));
+	if (!(val & MSICAP0_MSIE))
+		return -EINVAL;
+
+	/* Get MSI numbers from MME */
+	msi_count = ((val & MSICAP0_MMENUM_MASK) >> MSICAP0_MMENUM_OFFSET);
+	msi_count = 1 << msi_count;
+
+	if (!interrupt_num || interrupt_num > msi_count)
+		return -EINVAL;
+
+	val = rcar_pci_read_reg(pcie, PCIEMSITXR);
+	rcar_pci_write_reg(pcie, val | (interrupt_num - 1), PCIEMSITXR);
+
+	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_endpoint *ep = epc_get_drvdata(epc);
+
+	switch (type) {
+	case PCI_EPC_IRQ_LEGACY:
+		return rcar_pcie_ep_assert_intx(ep, fn, 0);
+
+	case PCI_EPC_IRQ_MSI:
+		return rcar_pcie_ep_assert_msi(&ep->pcie, fn, interrupt_num);
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int rcar_pcie_ep_start(struct pci_epc *epc)
+{
+	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
+
+	rcar_pci_write_reg(&ep->pcie, CFINIT, PCIETCTLR);
+
+	return 0;
+}
+
+static void rcar_pcie_ep_stop(struct pci_epc *epc)
+{
+	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
+
+	rcar_pci_write_reg(&ep->pcie, 0, PCIETCTLR);
+}
+
+static const struct pci_epc_features rcar_pcie_epc_features = {
+	.linkup_notifier = false,
+	.msi_capable = true,
+	.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,
+	.set_msi	= rcar_pcie_ep_set_msi,
+	.get_msi	= rcar_pcie_ep_get_msi,
+	.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_endpoint *ep;
+	struct rcar_pcie *pcie;
+	struct pci_epc *epc;
+	int err;
+
+	ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
+	if (!ep)
+		return -ENOMEM;
+
+	pcie = &ep->pcie;
+	pcie->dev = dev;
+
+	pm_runtime_enable(dev);
+	err = pm_runtime_get_sync(dev);
+	if (err < 0) {
+		dev_err(dev, "pm_runtime_get_sync failed\n");
+		goto err_pm_disable;
+	}
+
+	err = rcar_pcie_ep_get_pdata(ep, pdev);
+	if (err < 0) {
+		dev_err(dev, "failed to request resources: %d\n", err);
+		goto err_pm_put;
+	}
+
+	ep->num_ib_windows = MAX_NR_INBOUND_MAPS;
+	ep->ib_window_map =
+			devm_kcalloc(dev, BITS_TO_LONGS(ep->num_ib_windows),
+				     sizeof(long), GFP_KERNEL);
+	if (!ep->ib_window_map) {
+		err = -ENOMEM;
+		dev_err(dev, "failed to allocate memory for inbound map\n");
+		goto err_pm_put;
+	}
+
+	ep->ob_mapped_addr = devm_kcalloc(dev, ep->num_ob_windows,
+					  sizeof(*ep->ob_mapped_addr),
+					  GFP_KERNEL);
+	if (!ep->ob_mapped_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 = ep->max_functions;
+	epc_set_drvdata(epc, ep);
+
+	rcar_pcie_ep_hw_init(pcie);
+
+	err = __pci_epc_mem_init(epc, ep->ob_window, ep->num_ob_windows);
+	if (err < 0) {
+		dev_err(dev, "failed to initialize the epc memory space\n");
+		goto err_pm_put;
+	}
+
+	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 cec7768b4725..0fbeff3d7b78 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		BIT(16)
 #define PCIEPHYSR		0x0007f0
 #define  PHYRDY			BIT(0)
 #define PCIEMSITXR		0x000840
@@ -55,12 +56,20 @@
 
 /* Configuration */
 #define PCICONF(x)		(0x010000 + ((x) * 0x4))
+#define  INTDIS			BIT(10)
 #define PMCAP(x)		(0x010040 + ((x) * 0x4))
+#define MSICAP(x)		(0x010050 + ((x) * 0x4))
+#define  MSICAP0_MSIE		BIT(16)
+#define  MSICAP0_MMESCAP_OFFSET	17
+#define  MSICAP0_MMENUM_OFFSET	20
+#define  MSICAP0_MMENUM_MASK	GENMASK(22, 20)
 #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.20.1


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

* [PATCH v6 09/11] PCI: Add Renesas R8A774C0 device ID
  2020-04-02 19:38 [PATCH v6 00/11] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
                   ` (7 preceding siblings ...)
  2020-04-02 19:38 ` [PATCH v6 08/11] PCI: rcar: Add support for rcar PCIe controller in endpoint mode Lad Prabhakar
@ 2020-04-02 19:38 ` Lad Prabhakar
  2020-04-03  8:46   ` Yoshihiro Shimoda
  2020-04-02 19:38 ` [PATCH v6 10/11] misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller Lad Prabhakar
  2020-04-02 19:38 ` [PATCH v6 11/11] MAINTAINERS: Add file patterns for rcar PCI device tree bindings Lad Prabhakar
  10 siblings, 1 reply; 30+ messages in thread
From: Lad Prabhakar @ 2020-04-02 19:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Magnus Damm, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Marek Vasut, Yoshihiro Shimoda, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Lad Prabhakar

Add R8A774C0 device ID so that this can be used by
pci_endpoint_test driver.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
 include/linux/pci_ids.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 1dfc4e1dcb94..9e957c18abeb 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2460,6 +2460,7 @@
 #define PCI_DEVICE_ID_RENESAS_SH7763	0x0004
 #define PCI_DEVICE_ID_RENESAS_SH7785	0x0007
 #define PCI_DEVICE_ID_RENESAS_SH7786	0x0010
+#define PCI_DEVICE_ID_RENESAS_R8A774C0	0x002d
 
 #define PCI_VENDOR_ID_SOLARFLARE	0x1924
 #define PCI_DEVICE_ID_SOLARFLARE_SFC4000A_0	0x0703
-- 
2.20.1


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

* [PATCH v6 10/11] misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller
  2020-04-02 19:38 [PATCH v6 00/11] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
                   ` (8 preceding siblings ...)
  2020-04-02 19:38 ` [PATCH v6 09/11] PCI: Add Renesas R8A774C0 device ID Lad Prabhakar
@ 2020-04-02 19:38 ` Lad Prabhakar
  2020-04-03  8:47   ` Yoshihiro Shimoda
  2020-04-02 19:38 ` [PATCH v6 11/11] MAINTAINERS: Add file patterns for rcar PCI device tree bindings Lad Prabhakar
  10 siblings, 1 reply; 30+ messages in thread
From: Lad Prabhakar @ 2020-04-02 19:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Magnus Damm, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Marek Vasut, Yoshihiro Shimoda, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Lad Prabhakar

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

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

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index ef5a1af6bab7..d8e1121c0464 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -942,6 +942,8 @@ 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_R8A774C0),
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
-- 
2.20.1


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

* [PATCH v6 11/11] MAINTAINERS: Add file patterns for rcar PCI device tree bindings
  2020-04-02 19:38 [PATCH v6 00/11] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
                   ` (9 preceding siblings ...)
  2020-04-02 19:38 ` [PATCH v6 10/11] misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller Lad Prabhakar
@ 2020-04-02 19:38 ` Lad Prabhakar
  2020-04-03  8:48   ` Yoshihiro Shimoda
  10 siblings, 1 reply; 30+ messages in thread
From: Lad Prabhakar @ 2020-04-02 19:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	Magnus Damm, Kishon Vijay Abraham I, Lorenzo Pieralisi,
	Marek Vasut, Yoshihiro Shimoda, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Lad Prabhakar

Add file pattern entry for rcar PCI devicetree binding, so that when
people run ./scripts/get_maintainer.pl the rcar PCI maintainers could also
be listed.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3f0f2ee2af32..87df2d31a54b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12933,6 +12933,7 @@ L:	linux-pci@vger.kernel.org
 L:	linux-renesas-soc@vger.kernel.org
 S:	Maintained
 F:	drivers/pci/controller/*rcar*
+F:	Documentation/devicetree/bindings/pci/*rcar*
 
 PCI DRIVER FOR SAMSUNG EXYNOS
 M:	Jingoo Han <jingoohan1@gmail.com>
-- 
2.20.1


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

* RE: [PATCH v6 01/11] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c
  2020-04-02 19:38 ` [PATCH v6 01/11] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c Lad Prabhakar
@ 2020-04-03  7:52   ` Yoshihiro Shimoda
  0 siblings, 0 replies; 30+ messages in thread
From: Yoshihiro Shimoda @ 2020-04-03  7:52 UTC (permalink / raw)
  To: Prabhakar Mahadev Lad, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Prabhakar Mahadev Lad

Hi Prabhakar-san,

> From: Lad Prabhakar, Sent: Friday, April 3, 2020 4:38 AM
> 
> This commit renames pcie-rcar.c to pcie-rcar-host.c in preparation for
> adding support for endpoint mode. CONFIG_PCIE_RCAR is kept so that arm64
> defconfig change can be a separate patch.
> 
> With this patch both config options PCIE_RCAR and PCIE_RCAR_HOST will be
> available but PCIE_RCAR internally selects PCIE_RCAR_HOST so that bisect
> builds wont be affected.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>

Thank you for the patch!

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

Best regards,
Yoshihiro Shimoda

> ---
>  drivers/pci/controller/Kconfig                         | 10 ++++++++++
>  drivers/pci/controller/Makefile                        |  2 +-
>  .../pci/controller/{pcie-rcar.c => pcie-rcar-host.c}   |  0
>  3 files changed, 11 insertions(+), 1 deletion(-)
>  rename drivers/pci/controller/{pcie-rcar.c => pcie-rcar-host.c} (100%)
> 
> diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
> index af0f0bc11917..cfdc898450d0 100644
> --- 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 option will be removed after arm64 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
> diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
> index 158c59771824..9dbccb5b24e1 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.20.1


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

* RE: [PATCH v6 02/11] arm64: defconfig: enable CONFIG_PCIE_RCAR_HOST
  2020-04-02 19:38 ` [PATCH v6 02/11] arm64: defconfig: enable CONFIG_PCIE_RCAR_HOST Lad Prabhakar
@ 2020-04-03  8:03   ` Yoshihiro Shimoda
  2020-04-03  8:28     ` Geert Uytterhoeven
  0 siblings, 1 reply; 30+ messages in thread
From: Yoshihiro Shimoda @ 2020-04-03  8:03 UTC (permalink / raw)
  To: Prabhakar Mahadev Lad, Geert Uytterhoeven
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Prabhakar Mahadev Lad, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci, Bjorn Helgaas,
	Rob Herring, Mark Rutland

Hi Prabhakar-san,

> From: Lad Prabhakar, Sent: Friday, April 3, 2020 4:39 AM
> 
> config option PCIE_RCAR internally selects PCIE_RCAR_HOST which builds the
> same driver. So this patch renames CONFIG_PCIE_RCAR to
> CONFIG_PCIE_RCAR_HOST so that PCIE_RCAR can be safely dropped from Kconfig
> file.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>

Thank you for the patch!

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

But, I'm thinking this patch (and patch 03/11) should be separated
from this patch series for arm64 subsystem to ease maintenance.
My scenario is:
 1) patch series 1: R-Car PCIe endpoint support.
 -- This means: patch 1, 4 - 9, 11

 2) After the patch series 1 is merged, submit this patch 2/11 to arm subsystem
   and submit the patch 10/11 to misc subsystem.

 3) At last, submit patch 3/11 after the patch 2/11 is merged.

Geert-san, what do you think?

Best regards,
Yoshihiro Shimoda


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

* RE: [PATCH v6 04/11] PCI: rcar: Move shareable code to a common file
  2020-04-02 19:38 ` [PATCH v6 04/11] PCI: rcar: Move shareable code to a common file Lad Prabhakar
@ 2020-04-03  8:06   ` Yoshihiro Shimoda
  0 siblings, 0 replies; 30+ messages in thread
From: Yoshihiro Shimoda @ 2020-04-03  8:06 UTC (permalink / raw)
  To: Prabhakar Mahadev Lad, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Prabhakar Mahadev Lad

Hi Prabhakar-san,

> From: Lad Prabhakar, Sent: Friday, April 3, 2020 4:39 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>

Thank you for the patch!

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

Best regards,
Yoshihiro Shimoda


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

* RE: [PATCH v6 06/11] PCI: endpoint: Add support to handle multiple base for mapping outbound memory
  2020-04-02 19:38 ` [PATCH v6 06/11] PCI: endpoint: Add support to handle multiple base for mapping outbound memory Lad Prabhakar
@ 2020-04-03  8:23   ` Yoshihiro Shimoda
  2020-04-03  9:11     ` Prabhakar Mahadev Lad
  0 siblings, 1 reply; 30+ messages in thread
From: Yoshihiro Shimoda @ 2020-04-03  8:23 UTC (permalink / raw)
  To: Prabhakar Mahadev Lad, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Prabhakar Mahadev Lad

Hi Prabhakar-san,

Thank you for the patch!

> From: Lad Prabhakar, Sent: Friday, April 3, 2020 4:39 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() initializes address space for endpoint
> controller which support single window and whereas __pci_epc_mem_init()
> now accepts pointer to multiple windows supported by endpoint controller.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> ---
> @@ -38,61 +38,95 @@ 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,
> +		       unsigned 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;
> +	int pages;
> +	int ret;
> +	int i;
> 
> -	if (page_size < PAGE_SIZE)
> -		page_size = PAGE_SIZE;
> +	epc->num_windows = 0;
> 
> -	page_shift = ilog2(page_size);
> -	pages = size >> page_shift;
> -	bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
> +	if (!windows || !num_windows)
> +		return -EINVAL;
> 
> -	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
> -	if (!mem) {
> -		ret = -ENOMEM;
> -		goto err;
> -	}
> +	epc->windows = kcalloc(num_windows, sizeof(*mem), GFP_KERNEL);
> +	if (!epc->windows)
> +		return -ENOMEM;
> 
> -	bitmap = kzalloc(bitmap_size, GFP_KERNEL);
> -	if (!bitmap) {
> -		ret = -ENOMEM;
> -		goto err_mem;
> -	}
> +	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;
> +			i -= 1;

nit: We can use i--;

> +			goto err_mem;
> +		}
> +
> +		bitmap = kzalloc(bitmap_size, GFP_KERNEL);
> +		if (!bitmap) {
> +			ret = -ENOMEM;
> +			kfree(mem);
> +			i -= 1;

nit: We can use i--;

<snip>
> @@ -122,31 +167,56 @@ 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 = NULL;
> -	struct pci_epc_mem *mem = epc->mem;
> -	unsigned int page_shift = ilog2(mem->page_size);
> +	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);
> -
> -	mutex_lock(&mem->lock);
> -	pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);
> -	if (pageno < 0)
> -		goto ret;
> +	for (i = 0; i < epc->num_windows; i++) {
> +		mem = epc->windows[i];
> +		mutex_lock(&mem->lock);

This is my feeling though, calling mutex_lock() in the loop seems
to cause overhead. And, if we call mutex_lock() at out-of the loop,
I think we can write single mutex_unlock() calling.

> +		size = ALIGN(size, mem->window.page_size);

I'm sorry I should have realized this in the previous review,
but overwriting this size is possible to cause an issue at second time or more loops.
So, the first argument of ALIGN should be kept for the loop.

> +		order = pci_epc_mem_get_order(mem, size);
> 
> -	*phys_addr = mem->phys_base + ((phys_addr_t)pageno << page_shift);
> -	virt_addr = ioremap(*phys_addr, size);
> -	if (!virt_addr)
> -		bitmap_release_region(mem->bitmap, pageno, order);
> +		pageno = bitmap_find_free_region(mem->bitmap, mem->pages,
> +						 order);
> +		if (pageno >= 0) {
> +			page_shift = ilog2(mem->window.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);
> +			mutex_unlock(&mem->lock);
> +			return virt_addr;

As I mentioned above, if mutex_lock() is called at out-of-loop,
we can use "goto ret;" here like the original code,

> +		}
> +		mutex_unlock(&mem->lock);

and we can remove this.

> +	}
> 
> -ret:
> -	mutex_unlock(&mem->lock);
>  	return virt_addr;
>  }
>  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->num_windows; i++) {
> +		mem = epc->windows[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
> @@ -159,14 +229,23 @@ 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;
> +	size_t page_size;
>  	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_size = mem->window.page_size;
> +	page_shift = ilog2(page_size);
>  	iounmap(virt_addr);
> -	pageno = (phys_addr - mem->phys_base) >> page_shift;
> -	size = ALIGN(size, mem->page_size);
> +	pageno = (phys_addr - mem->window.phys_base) >> page_shift;
> +	size = ALIGN(size, page_size);
>  	order = pci_epc_mem_get_order(mem, size);
>  	mutex_lock(&mem->lock);
>  	bitmap_release_region(mem->bitmap, pageno, order);
> diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
> index e0ed9d01f6e5..d5da11cf0f2a 100644
> --- a/include/linux/pci-epc.h
> +++ b/include/linux/pci-epc.h
> @@ -65,20 +65,28 @@ struct pci_epc_ops {
>  	struct module *owner;
>  };
> 
> +/**
> + * 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
>   * @lock: mutex to protect bitmap
> + * @pages: number of bits representing the address region

Perhaps, we should not change the "@pages" line.

Best regards,
Yoshihiro Shimoda


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

* RE: [PATCH v6 07/11] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller
  2020-04-02 19:38 ` [PATCH v6 07/11] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller Lad Prabhakar
@ 2020-04-03  8:28   ` Yoshihiro Shimoda
  2020-04-03  9:02     ` Prabhakar Mahadev Lad
  0 siblings, 1 reply; 30+ messages in thread
From: Yoshihiro Shimoda @ 2020-04-03  8:28 UTC (permalink / raw)
  To: Prabhakar Mahadev Lad, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Prabhakar Mahadev Lad

Hi Prabhakar-san,

Thank you for your patch!

> From: Lad Prabhakar, Sent: Friday, April 3, 2020 4:39 AM
<snip>
> 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 000000000000..07cd5a7325d0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/rcar-pci-ep.yaml
> @@ -0,0 +1,76 @@
> +# SPDX-License-Identifier: GPL-2.0

I'm sorry I should have mentioned in the previous review.
This is better like the following.

# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)

https://patchwork.kernel.org/patch/11459267/#23246825

<snip>
> +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>;

Examples are built with #{address,size}-cells = <1>, so

            reg = <0xfe000000 0x80000>,
                  <0xfe100000 0x100000>,
                  <0xfe200000 0x200000>,
                  <0x30000000 0x8000000>,
                  <0x38000000 0x8000000>;

https://patchwork.kernel.org/patch/11459267/#23246825

Best regards,
Yoshihiro Shimoda


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

* Re: [PATCH v6 02/11] arm64: defconfig: enable CONFIG_PCIE_RCAR_HOST
  2020-04-03  8:03   ` Yoshihiro Shimoda
@ 2020-04-03  8:28     ` Geert Uytterhoeven
  2020-04-03  9:04       ` Yoshihiro Shimoda
  0 siblings, 1 reply; 30+ messages in thread
From: Geert Uytterhoeven @ 2020-04-03  8:28 UTC (permalink / raw)
  To: Yoshihiro Shimoda
  Cc: Prabhakar Mahadev Lad, Geert Uytterhoeven, Catalin Marinas,
	Will Deacon, Arnd Bergmann, Greg Kroah-Hartman, Andrew Murray,
	devicetree, linux-kernel, linux-arm-kernel, linux-renesas-soc,
	Chris Paterson, Frank Rowand, Gustavo Pimentel, Jingoo Han,
	Simon Horman, Shawn Lin, Tom Joseph, Heiko Stuebner,
	linux-rockchip, Lad Prabhakar, Magnus Damm,
	Kishon Vijay Abraham I, Lorenzo Pieralisi, Marek Vasut,
	linux-pci, Bjorn Helgaas, Rob Herring, Mark Rutland

Hi Shimoda-san,

On Fri, Apr 3, 2020 at 10:03 AM Yoshihiro Shimoda
<yoshihiro.shimoda.uh@renesas.com> wrote:
> > From: Lad Prabhakar, Sent: Friday, April 3, 2020 4:39 AM
> >
> > config option PCIE_RCAR internally selects PCIE_RCAR_HOST which builds the
> > same driver. So this patch renames CONFIG_PCIE_RCAR to
> > CONFIG_PCIE_RCAR_HOST so that PCIE_RCAR can be safely dropped from Kconfig
> > file.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
>
> Thank you for the patch!
>
> Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
>
> But, I'm thinking this patch (and patch 03/11) should be separated
> from this patch series for arm64 subsystem to ease maintenance.
> My scenario is:
>  1) patch series 1: R-Car PCIe endpoint support.
>  -- This means: patch 1, 4 - 9, 11
>
>  2) After the patch series 1 is merged, submit this patch 2/11 to arm subsystem
>    and submit the patch 10/11 to misc subsystem.
>
>  3) At last, submit patch 3/11 after the patch 2/11 is merged.
>
> Geert-san, what do you think?

Thanks, I agree with your summary.

I can take patch 2/11 through renesas-devel.
Probably it's best if I submit it to arm-soc as a fix for v5.8, after
the driver part
has been merged into v5.8-rc1, so 3/11 can be submitted for v5.9.

BTW, I'm wondering about "[PATCH v6 05/11] PCI: rcar: Fix calculating
mask for PCIEPAMR register". Can the issue fixed by this patch happen with
the current driver in host mode, or is that limited to ep mode?
In case of the former, please submit it to the PCI maintainer as a separate
fix.

Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* RE: [PATCH v6 08/11] PCI: rcar: Add support for rcar PCIe controller in endpoint mode
  2020-04-02 19:38 ` [PATCH v6 08/11] PCI: rcar: Add support for rcar PCIe controller in endpoint mode Lad Prabhakar
@ 2020-04-03  8:44   ` Yoshihiro Shimoda
  2020-04-03  8:58     ` Prabhakar Mahadev Lad
  0 siblings, 1 reply; 30+ messages in thread
From: Yoshihiro Shimoda @ 2020-04-03  8:44 UTC (permalink / raw)
  To: Prabhakar Mahadev Lad, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Prabhakar Mahadev Lad

Hi Prabhakar-san,

Thank you for the patch!

> From: Lad Prabhakar, Sent: Friday, April 3, 2020 4:39 AM
> Subject: [PATCH v6 08/11] PCI: rcar: Add support for rcar PCIe controller in endpoint mode
> 
> This patch adds support for rcar PCIe controller to work in endpoint mode.

I'm sorry but s/rcar/R-Car/ in the subject and description.

> 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 | 556 ++++++++++++++++++++++++++
>  drivers/pci/controller/pcie-rcar.h    |   9 +
>  4 files changed, 574 insertions(+)
>  create mode 100644 drivers/pci/controller/pcie-rcar-ep.c
> 
> diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
> index 37e234ad583b..283ff8175cb7 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 39802ee32946..741a5204aa5e 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 000000000000..047be2ac062c
> --- /dev/null
> +++ b/drivers/pci/controller/pcie-rcar-ep.c
> @@ -0,0 +1,556 @@
> +// 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_endpoint {
> +	struct rcar_pcie	pcie;
> +	phys_addr_t		*ob_mapped_addr;
> +	struct pci_epc_mem_window *ob_window;
> +	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, 0, PCIETCTLR);
> +
> +	/* Set endpoint mode */
> +	rcar_pci_write_reg(pcie, 0, PCIEMSR);
> +
> +	/* 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_ENDPOINT << 4);
> +	rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
> +		   PCI_HEADER_TYPE_NORMAL);
> +
> +	/* Write out the physical slot number = 0 */
> +	rcar_rmw32(pcie, REXPCAP(PCI_EXP_SLTCAP), PCI_EXP_SLTCAP_PSN, 0);
> +
> +	val = rcar_pci_read_reg(pcie, EXPCAP(1));
> +	/* device supports fixed 128 bytes MPSS */
> +	val &= ~GENMASK(2, 0);
> +	rcar_pci_write_reg(pcie, val, EXPCAP(1));
> +
> +	val = rcar_pci_read_reg(pcie, EXPCAP(2));
> +	/* read requests size 128 bytes */
> +	val &= ~GENMASK(14, 12);
> +	/* payload size 128 bytes */
> +	val &= ~GENMASK(7, 5);
> +	rcar_pci_write_reg(pcie, val, EXPCAP(2));
> +
> +	/* Set target link speed to 5.0 GT/s */
> +	rcar_rmw32(pcie, EXPCAP(12), PCI_EXP_LNKSTA_CLS,
> +		   PCI_EXP_LNKSTA_CLS_5_0GB);
> +
> +	/* Set the completion timer timeout to the maximum 50ms. */
> +	rcar_rmw32(pcie, TLCTLR + 1, 0x3f, 50);
> +
> +	/* Terminate list of capabilities (Next Capability Offset=0) */
> +	rcar_rmw32(pcie, RVCCAP(0), 0xfff00000, 0);
> +
> +	rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR);

Why is this MACCTLR setting here? In other words, cannot we set this in
rcar_pcie_ep_start()? My concern is this rcar_pcie_ep_hw_init() is called
once so that if rcar_pcie_ep_start() is called multiple times,
that is wrong process from the hardware requirement.

Best regards,
Yoshihiro Shimoda

> +	/* flush modifications */
> +	wmb();
> +}
> +
> +static int rcar_pcie_ep_get_window(struct rcar_pcie_endpoint *ep,
> +				   phys_addr_t addr)
> +{
> +	int i;
> +
> +	for (i = 0; i < ep->num_ob_windows; i++)
> +		if (ep->ob_window[i].phys_base == addr)
> +			return i;
> +
> +	return -EINVAL;
> +}
> +
> +static int rcar_pcie_parse_outbound_ranges(struct rcar_pcie_endpoint *ep,
> +					   struct platform_device *pdev)
> +{
> +	struct rcar_pcie *pcie = &ep->pcie;
> +	char outbound_name[10];
> +	struct resource *res;
> +	unsigned int i = 0;
> +
> +	ep->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;
> +		}
> +
> +		ep->ob_window[i].phys_base = res->start;
> +		ep->ob_window[i].size = resource_size(res);
> +		/* controller doesn't support multiple allocation
> +		 * from same window, so set page_size to window size
> +		 */
> +		ep->ob_window[i].page_size = resource_size(res);
> +	}
> +	ep->num_ob_windows = i;
> +
> +	return 0;
> +}
> +
> +static int rcar_pcie_ep_get_pdata(struct rcar_pcie_endpoint *ep,
> +				  struct platform_device *pdev)
> +{
> +	struct rcar_pcie *pcie = &ep->pcie;
> +	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);
> +
> +	ep->ob_window = devm_kcalloc(dev, RCAR_PCI_MAX_RESOURCES,
> +				     sizeof(*window), GFP_KERNEL);
> +	if (!ep->ob_window)
> +		return -ENOMEM;
> +
> +	rcar_pcie_parse_outbound_ranges(ep, pdev);
> +
> +	err = of_property_read_u8(dev->of_node, "max-functions",
> +				  &ep->max_functions);
> +	if (err < 0)
> +		ep->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_endpoint *ep = epc_get_drvdata(epc);
> +	struct rcar_pcie *pcie = &ep->pcie;
> +	u32 val;
> +
> +	if (!fn)
> +		val = hdr->vendorid;
> +	else
> +		val = rcar_pci_read_reg(pcie, IDSETR0);
> +	val |= hdr->deviceid << 16;
> +	rcar_pci_write_reg(pcie, val, IDSETR0);
> +
> +	val = hdr->revid;
> +	val |= hdr->progif_code << 8;
> +	val |= hdr->subclass_code << 16;
> +	val |= hdr->baseclass_code << 24;
> +	rcar_pci_write_reg(pcie, val, IDSETR1);
> +
> +	if (!fn)
> +		val = hdr->subsys_vendor_id;
> +	else
> +		val = rcar_pci_read_reg(pcie, SUBIDSETR);
> +	val |= hdr->subsys_id << 16;
> +	rcar_pci_write_reg(pcie, val, SUBIDSETR);
> +
> +	if (hdr->interrupt_pin > PCI_INTERRUPT_INTA)
> +		return -EINVAL;
> +	val = rcar_pci_read_reg(pcie, PCICONF(15));
> +	val |= (hdr->interrupt_pin << 8);
> +	rcar_pci_write_reg(pcie, 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)
> +{
> +	int flags = epf_bar->flags | LAR_ENABLE | LAM_64BIT;
> +	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
> +	u64 size = 1ULL << fls64(epf_bar->size - 1);
> +	dma_addr_t cpu_addr = epf_bar->phys_addr;
> +	enum pci_barno bar = epf_bar->barno;
> +	struct rcar_pcie *pcie = &ep->pcie;
> +	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(pcie->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(pcie, cpu_addr,
> +			      0x0, mask | flags, idx, false);
> +
> +	err = rcar_pcie_wait_for_phyrdy(pcie);
> +	if (err) {
> +		dev_err(pcie->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_endpoint *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->pcie, 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_set_msi(struct pci_epc *epc, u8 fn, u8 interrupts)
> +{
> +	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
> +	struct rcar_pcie *pcie = &ep->pcie;
> +	u32 flags;
> +
> +	flags = rcar_pci_read_reg(pcie, MSICAP(fn));
> +	flags |= interrupts << MSICAP0_MMESCAP_OFFSET;
> +	rcar_pci_write_reg(pcie, flags, MSICAP(fn));
> +
> +	return 0;
> +}
> +
> +static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
> +{
> +	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
> +	struct rcar_pcie *pcie = &ep->pcie;
> +	u32 flags;
> +
> +	flags = rcar_pci_read_reg(pcie, MSICAP(fn));
> +	if (!(flags & MSICAP0_MSIE))
> +		return -EINVAL;
> +
> +	return ((flags & MSICAP0_MMENUM_MASK) >> MSICAP0_MMENUM_OFFSET);
> +}
> +
> +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_endpoint *ep = epc_get_drvdata(epc);
> +	struct rcar_pcie *pcie = &ep->pcie;
> +	struct resource res;
> +	int window;
> +	int err;
> +
> +	/* check if we have a link. */
> +	err = rcar_pcie_wait_for_dl(pcie);
> +	if (err) {
> +		dev_err(pcie->dev, "link not up\n");
> +		return err;
> +	}
> +
> +	window = rcar_pcie_ep_get_window(ep, addr);
> +	if (window < 0) {
> +		dev_err(pcie->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(pcie, window, &res);
> +
> +	ep->ob_mapped_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_endpoint *ep = epc_get_drvdata(epc);
> +	struct resource res;
> +	int idx;
> +
> +	for (idx = 0; idx < ep->num_ob_windows; idx++)
> +		if (ep->ob_mapped_addr[idx] == addr)
> +			break;
> +
> +	if (idx >= ep->num_ob_windows)
> +		return;
> +
> +	memset(&res, 0x0, sizeof(res));
> +	rcar_pcie_set_outbound(&ep->pcie, idx, &res);
> +
> +	ep->ob_mapped_addr[idx] = 0;
> +}
> +
> +static int rcar_pcie_ep_assert_intx(struct rcar_pcie_endpoint *ep,
> +				    u8 fn, u8 intx)
> +{
> +	struct rcar_pcie *pcie = &ep->pcie;
> +	u32 val;
> +
> +	val = rcar_pci_read_reg(pcie, PCIEMSITXR);
> +	if ((val & PCI_MSI_FLAGS_ENABLE)) {
> +		dev_err(pcie->dev, "MSI is enabled, cannot assert INTx\n");
> +		return -EINVAL;
> +	}
> +
> +	val = rcar_pci_read_reg(pcie, PCICONF(1));
> +	if ((val & INTDIS)) {
> +		dev_err(pcie->dev, "INTx message transmission is disabled\n");
> +		return -EINVAL;
> +	}
> +
> +	val = rcar_pci_read_reg(pcie, PCIEINTXR);
> +	if ((val & ASTINTX)) {
> +		dev_err(pcie->dev, "INTx is already asserted\n");
> +		return -EINVAL;
> +	}
> +
> +	val |= ASTINTX;
> +	rcar_pci_write_reg(pcie, val, PCIEINTXR);
> +	mdelay(1);
> +	val = rcar_pci_read_reg(pcie, PCIEINTXR);
> +	val &= ~ASTINTX;
> +	rcar_pci_write_reg(pcie, val, PCIEINTXR);
> +
> +	return 0;
> +}
> +
> +static int rcar_pcie_ep_assert_msi(struct rcar_pcie *pcie,
> +				   u8 fn, u8 interrupt_num)
> +{
> +	u16 msi_count;
> +	u32 val;
> +
> +	/* Check MSI enable bit */
> +	val = rcar_pci_read_reg(pcie, MSICAP(fn));
> +	if (!(val & MSICAP0_MSIE))
> +		return -EINVAL;
> +
> +	/* Get MSI numbers from MME */
> +	msi_count = ((val & MSICAP0_MMENUM_MASK) >> MSICAP0_MMENUM_OFFSET);
> +	msi_count = 1 << msi_count;
> +
> +	if (!interrupt_num || interrupt_num > msi_count)
> +		return -EINVAL;
> +
> +	val = rcar_pci_read_reg(pcie, PCIEMSITXR);
> +	rcar_pci_write_reg(pcie, val | (interrupt_num - 1), PCIEMSITXR);
> +
> +	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_endpoint *ep = epc_get_drvdata(epc);
> +
> +	switch (type) {
> +	case PCI_EPC_IRQ_LEGACY:
> +		return rcar_pcie_ep_assert_intx(ep, fn, 0);
> +
> +	case PCI_EPC_IRQ_MSI:
> +		return rcar_pcie_ep_assert_msi(&ep->pcie, fn, interrupt_num);
> +
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int rcar_pcie_ep_start(struct pci_epc *epc)
> +{
> +	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
> +
> +	rcar_pci_write_reg(&ep->pcie, CFINIT, PCIETCTLR);
> +
> +	return 0;
> +}
> +
> +static void rcar_pcie_ep_stop(struct pci_epc *epc)
> +{
> +	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
> +
> +	rcar_pci_write_reg(&ep->pcie, 0, PCIETCTLR);
> +}
> +
> +static const struct pci_epc_features rcar_pcie_epc_features = {
> +	.linkup_notifier = false,
> +	.msi_capable = true,
> +	.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,
> +	.set_msi	= rcar_pcie_ep_set_msi,
> +	.get_msi	= rcar_pcie_ep_get_msi,
> +	.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_endpoint *ep;
> +	struct rcar_pcie *pcie;
> +	struct pci_epc *epc;
> +	int err;
> +
> +	ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
> +	if (!ep)
> +		return -ENOMEM;
> +
> +	pcie = &ep->pcie;
> +	pcie->dev = dev;
> +
> +	pm_runtime_enable(dev);
> +	err = pm_runtime_get_sync(dev);
> +	if (err < 0) {
> +		dev_err(dev, "pm_runtime_get_sync failed\n");
> +		goto err_pm_disable;
> +	}
> +
> +	err = rcar_pcie_ep_get_pdata(ep, pdev);
> +	if (err < 0) {
> +		dev_err(dev, "failed to request resources: %d\n", err);
> +		goto err_pm_put;
> +	}
> +
> +	ep->num_ib_windows = MAX_NR_INBOUND_MAPS;
> +	ep->ib_window_map =
> +			devm_kcalloc(dev, BITS_TO_LONGS(ep->num_ib_windows),
> +				     sizeof(long), GFP_KERNEL);
> +	if (!ep->ib_window_map) {
> +		err = -ENOMEM;
> +		dev_err(dev, "failed to allocate memory for inbound map\n");
> +		goto err_pm_put;
> +	}
> +
> +	ep->ob_mapped_addr = devm_kcalloc(dev, ep->num_ob_windows,
> +					  sizeof(*ep->ob_mapped_addr),
> +					  GFP_KERNEL);
> +	if (!ep->ob_mapped_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 = ep->max_functions;
> +	epc_set_drvdata(epc, ep);
> +
> +	rcar_pcie_ep_hw_init(pcie);
> +
> +	err = __pci_epc_mem_init(epc, ep->ob_window, ep->num_ob_windows);
> +	if (err < 0) {
> +		dev_err(dev, "failed to initialize the epc memory space\n");
> +		goto err_pm_put;
> +	}
> +
> +	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 cec7768b4725..0fbeff3d7b78 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		BIT(16)
>  #define PCIEPHYSR		0x0007f0
>  #define  PHYRDY			BIT(0)
>  #define PCIEMSITXR		0x000840
> @@ -55,12 +56,20 @@
> 
>  /* Configuration */
>  #define PCICONF(x)		(0x010000 + ((x) * 0x4))
> +#define  INTDIS			BIT(10)
>  #define PMCAP(x)		(0x010040 + ((x) * 0x4))
> +#define MSICAP(x)		(0x010050 + ((x) * 0x4))
> +#define  MSICAP0_MSIE		BIT(16)
> +#define  MSICAP0_MMESCAP_OFFSET	17
> +#define  MSICAP0_MMENUM_OFFSET	20
> +#define  MSICAP0_MMENUM_MASK	GENMASK(22, 20)
>  #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.20.1


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

* RE: [PATCH v6 09/11] PCI: Add Renesas R8A774C0 device ID
  2020-04-02 19:38 ` [PATCH v6 09/11] PCI: Add Renesas R8A774C0 device ID Lad Prabhakar
@ 2020-04-03  8:46   ` Yoshihiro Shimoda
  0 siblings, 0 replies; 30+ messages in thread
From: Yoshihiro Shimoda @ 2020-04-03  8:46 UTC (permalink / raw)
  To: Prabhakar Mahadev Lad, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Prabhakar Mahadev Lad

Hi Prabhakar-san,

> From: Lad Prabhakar, Sent: Friday, April 3, 2020 4:39 AM
> 
> Add R8A774C0 device ID so that this can be used by
> pci_endpoint_test driver.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>

Thank you for the patch!

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

Best regards,
Yoshihiro Shimoda


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

* RE: [PATCH v6 10/11] misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller
  2020-04-02 19:38 ` [PATCH v6 10/11] misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller Lad Prabhakar
@ 2020-04-03  8:47   ` Yoshihiro Shimoda
  0 siblings, 0 replies; 30+ messages in thread
From: Yoshihiro Shimoda @ 2020-04-03  8:47 UTC (permalink / raw)
  To: Prabhakar Mahadev Lad, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Prabhakar Mahadev Lad

Hi Prabhakar-san,

> From: Lad Prabhakar, Sent: Friday, April 3, 2020 4:39 AM
> 
> Add Renesas R8A774C0 in pci_device_id table so that pci-epf-test can be
> used for testing PCIe EP on RZ/G2E.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>

Thank you for the patch!

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

Best regards,
Yoshihiro Shimoda


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

* RE: [PATCH v6 11/11] MAINTAINERS: Add file patterns for rcar PCI device tree bindings
  2020-04-02 19:38 ` [PATCH v6 11/11] MAINTAINERS: Add file patterns for rcar PCI device tree bindings Lad Prabhakar
@ 2020-04-03  8:48   ` Yoshihiro Shimoda
  0 siblings, 0 replies; 30+ messages in thread
From: Yoshihiro Shimoda @ 2020-04-03  8:48 UTC (permalink / raw)
  To: Prabhakar Mahadev Lad, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar,
	Prabhakar Mahadev Lad

Hi Prabhakar-san,

> From: Lad Prabhakar, Sent: Friday, April 3, 2020 4:39 AM
> 
> Add file pattern entry for rcar PCI devicetree binding, so that when
> people run ./scripts/get_maintainer.pl the rcar PCI maintainers could also
> be listed.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>

Thank you for the patch!

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

Best regards,
Yoshihiro Shimoda


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

* RE: [PATCH v6 08/11] PCI: rcar: Add support for rcar PCIe controller in endpoint mode
  2020-04-03  8:44   ` Yoshihiro Shimoda
@ 2020-04-03  8:58     ` Prabhakar Mahadev Lad
  0 siblings, 0 replies; 30+ messages in thread
From: Prabhakar Mahadev Lad @ 2020-04-03  8:58 UTC (permalink / raw)
  To: Yoshihiro Shimoda, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar

Hi Shimoda-san,

Thank you for the review.

> -----Original Message-----
> From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Sent: 03 April 2020 09:44
> To: 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>; Geert Uytterhoeven <geert+renesas@glider.be>; Magnus Damm
> <magnus.damm@gmail.com>; Kishon Vijay Abraham I <kishon@ti.com>; Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>; Marek Vasut
> <marek.vasut+renesas@gmail.com>; linux-pci@vger.kernel.org
> Cc: Catalin Marinas <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>; Arnd Bergmann <arnd@arndb.de>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Andrew Murray <andrew.murray@arm.com>; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-renesas-soc@vger.kernel.org; Chris Paterson <Chris.Paterson2@renesas.com>; Frank Rowand
> <frowand.list@gmail.com>; Gustavo Pimentel <gustavo.pimentel@synopsys.com>; Jingoo Han <jingoohan1@gmail.com>; Simon Horman
> <horms@verge.net.au>; Shawn Lin <shawn.lin@rock-chips.com>; Tom Joseph <tjoseph@cadence.com>; Heiko Stuebner
> <heiko@sntech.de>; linux-rockchip@lists.infradead.org; Lad Prabhakar <prabhakar.csengg@gmail.com>; Prabhakar Mahadev Lad
> <prabhakar.mahadev-lad.rj@bp.renesas.com>
> Subject: RE: [PATCH v6 08/11] PCI: rcar: Add support for rcar PCIe controller in endpoint mode
>
> Hi Prabhakar-san,
>
> Thank you for the patch!
>
> > From: Lad Prabhakar, Sent: Friday, April 3, 2020 4:39 AM
> > Subject: [PATCH v6 08/11] PCI: rcar: Add support for rcar PCIe controller in endpoint mode
> >
> > This patch adds support for rcar PCIe controller to work in endpoint mode.
>
> I'm sorry but s/rcar/R-Car/ in the subject and description.
>
Sure ill change this.

> > 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 | 556 ++++++++++++++++++++++++++
> >  drivers/pci/controller/pcie-rcar.h    |   9 +
> >  4 files changed, 574 insertions(+)
> >  create mode 100644 drivers/pci/controller/pcie-rcar-ep.c
> >
> > diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
> > index 37e234ad583b..283ff8175cb7 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 39802ee32946..741a5204aa5e 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 000000000000..047be2ac062c
> > --- /dev/null
> > +++ b/drivers/pci/controller/pcie-rcar-ep.c
> > @@ -0,0 +1,556 @@
> > +// 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_endpoint {
> > +struct rcar_pciepcie;
> > +phys_addr_t*ob_mapped_addr;
> > +struct pci_epc_mem_window *ob_window;
> > +u8max_functions;
> > +unsigned intbar_to_atu[MAX_NR_INBOUND_MAPS];
> > +unsigned long*ib_window_map;
> > +u32num_ib_windows;
> > +u32num_ob_windows;
> > +};
> > +
> > +static void rcar_pcie_ep_hw_init(struct rcar_pcie *pcie)
> > +{
> > +u32 val;
> > +
> > +rcar_pci_write_reg(pcie, 0, PCIETCTLR);
> > +
> > +/* Set endpoint mode */
> > +rcar_pci_write_reg(pcie, 0, PCIEMSR);
> > +
> > +/* 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_ENDPOINT << 4);
> > +rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
> > +   PCI_HEADER_TYPE_NORMAL);
> > +
> > +/* Write out the physical slot number = 0 */
> > +rcar_rmw32(pcie, REXPCAP(PCI_EXP_SLTCAP), PCI_EXP_SLTCAP_PSN, 0);
> > +
> > +val = rcar_pci_read_reg(pcie, EXPCAP(1));
> > +/* device supports fixed 128 bytes MPSS */
> > +val &= ~GENMASK(2, 0);
> > +rcar_pci_write_reg(pcie, val, EXPCAP(1));
> > +
> > +val = rcar_pci_read_reg(pcie, EXPCAP(2));
> > +/* read requests size 128 bytes */
> > +val &= ~GENMASK(14, 12);
> > +/* payload size 128 bytes */
> > +val &= ~GENMASK(7, 5);
> > +rcar_pci_write_reg(pcie, val, EXPCAP(2));
> > +
> > +/* Set target link speed to 5.0 GT/s */
> > +rcar_rmw32(pcie, EXPCAP(12), PCI_EXP_LNKSTA_CLS,
> > +   PCI_EXP_LNKSTA_CLS_5_0GB);
> > +
> > +/* Set the completion timer timeout to the maximum 50ms. */
> > +rcar_rmw32(pcie, TLCTLR + 1, 0x3f, 50);
> > +
> > +/* Terminate list of capabilities (Next Capability Offset=0) */
> > +rcar_rmw32(pcie, RVCCAP(0), 0xfff00000, 0);
> > +
> > +rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR);
>
> Why is this MACCTLR setting here? In other words, cannot we set this in
> rcar_pcie_ep_start()? My concern is this rcar_pcie_ep_hw_init() is called
> once so that if rcar_pcie_ep_start() is called multiple times,
> that is wrong process from the hardware requirement.
>
Agreed will move this into rcar_pcie_ep_start ().

Cheers,
--Prabhakar

> Best regards,
> Yoshihiro Shimoda
>
> > +/* flush modifications */
> > +wmb();
> > +}
> > +
> > +static int rcar_pcie_ep_get_window(struct rcar_pcie_endpoint *ep,
> > +   phys_addr_t addr)
> > +{
> > +int i;
> > +
> > +for (i = 0; i < ep->num_ob_windows; i++)
> > +if (ep->ob_window[i].phys_base == addr)
> > +return i;
> > +
> > +return -EINVAL;
> > +}
> > +
> > +static int rcar_pcie_parse_outbound_ranges(struct rcar_pcie_endpoint *ep,
> > +   struct platform_device *pdev)
> > +{
> > +struct rcar_pcie *pcie = &ep->pcie;
> > +char outbound_name[10];
> > +struct resource *res;
> > +unsigned int i = 0;
> > +
> > +ep->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;
> > +}
> > +
> > +ep->ob_window[i].phys_base = res->start;
> > +ep->ob_window[i].size = resource_size(res);
> > +/* controller doesn't support multiple allocation
> > + * from same window, so set page_size to window size
> > + */
> > +ep->ob_window[i].page_size = resource_size(res);
> > +}
> > +ep->num_ob_windows = i;
> > +
> > +return 0;
> > +}
> > +
> > +static int rcar_pcie_ep_get_pdata(struct rcar_pcie_endpoint *ep,
> > +  struct platform_device *pdev)
> > +{
> > +struct rcar_pcie *pcie = &ep->pcie;
> > +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);
> > +
> > +ep->ob_window = devm_kcalloc(dev, RCAR_PCI_MAX_RESOURCES,
> > +     sizeof(*window), GFP_KERNEL);
> > +if (!ep->ob_window)
> > +return -ENOMEM;
> > +
> > +rcar_pcie_parse_outbound_ranges(ep, pdev);
> > +
> > +err = of_property_read_u8(dev->of_node, "max-functions",
> > +  &ep->max_functions);
> > +if (err < 0)
> > +ep->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_endpoint *ep = epc_get_drvdata(epc);
> > +struct rcar_pcie *pcie = &ep->pcie;
> > +u32 val;
> > +
> > +if (!fn)
> > +val = hdr->vendorid;
> > +else
> > +val = rcar_pci_read_reg(pcie, IDSETR0);
> > +val |= hdr->deviceid << 16;
> > +rcar_pci_write_reg(pcie, val, IDSETR0);
> > +
> > +val = hdr->revid;
> > +val |= hdr->progif_code << 8;
> > +val |= hdr->subclass_code << 16;
> > +val |= hdr->baseclass_code << 24;
> > +rcar_pci_write_reg(pcie, val, IDSETR1);
> > +
> > +if (!fn)
> > +val = hdr->subsys_vendor_id;
> > +else
> > +val = rcar_pci_read_reg(pcie, SUBIDSETR);
> > +val |= hdr->subsys_id << 16;
> > +rcar_pci_write_reg(pcie, val, SUBIDSETR);
> > +
> > +if (hdr->interrupt_pin > PCI_INTERRUPT_INTA)
> > +return -EINVAL;
> > +val = rcar_pci_read_reg(pcie, PCICONF(15));
> > +val |= (hdr->interrupt_pin << 8);
> > +rcar_pci_write_reg(pcie, 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)
> > +{
> > +int flags = epf_bar->flags | LAR_ENABLE | LAM_64BIT;
> > +struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
> > +u64 size = 1ULL << fls64(epf_bar->size - 1);
> > +dma_addr_t cpu_addr = epf_bar->phys_addr;
> > +enum pci_barno bar = epf_bar->barno;
> > +struct rcar_pcie *pcie = &ep->pcie;
> > +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(pcie->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(pcie, cpu_addr,
> > +      0x0, mask | flags, idx, false);
> > +
> > +err = rcar_pcie_wait_for_phyrdy(pcie);
> > +if (err) {
> > +dev_err(pcie->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_endpoint *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->pcie, 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_set_msi(struct pci_epc *epc, u8 fn, u8 interrupts)
> > +{
> > +struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
> > +struct rcar_pcie *pcie = &ep->pcie;
> > +u32 flags;
> > +
> > +flags = rcar_pci_read_reg(pcie, MSICAP(fn));
> > +flags |= interrupts << MSICAP0_MMESCAP_OFFSET;
> > +rcar_pci_write_reg(pcie, flags, MSICAP(fn));
> > +
> > +return 0;
> > +}
> > +
> > +static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
> > +{
> > +struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
> > +struct rcar_pcie *pcie = &ep->pcie;
> > +u32 flags;
> > +
> > +flags = rcar_pci_read_reg(pcie, MSICAP(fn));
> > +if (!(flags & MSICAP0_MSIE))
> > +return -EINVAL;
> > +
> > +return ((flags & MSICAP0_MMENUM_MASK) >> MSICAP0_MMENUM_OFFSET);
> > +}
> > +
> > +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_endpoint *ep = epc_get_drvdata(epc);
> > +struct rcar_pcie *pcie = &ep->pcie;
> > +struct resource res;
> > +int window;
> > +int err;
> > +
> > +/* check if we have a link. */
> > +err = rcar_pcie_wait_for_dl(pcie);
> > +if (err) {
> > +dev_err(pcie->dev, "link not up\n");
> > +return err;
> > +}
> > +
> > +window = rcar_pcie_ep_get_window(ep, addr);
> > +if (window < 0) {
> > +dev_err(pcie->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(pcie, window, &res);
> > +
> > +ep->ob_mapped_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_endpoint *ep = epc_get_drvdata(epc);
> > +struct resource res;
> > +int idx;
> > +
> > +for (idx = 0; idx < ep->num_ob_windows; idx++)
> > +if (ep->ob_mapped_addr[idx] == addr)
> > +break;
> > +
> > +if (idx >= ep->num_ob_windows)
> > +return;
> > +
> > +memset(&res, 0x0, sizeof(res));
> > +rcar_pcie_set_outbound(&ep->pcie, idx, &res);
> > +
> > +ep->ob_mapped_addr[idx] = 0;
> > +}
> > +
> > +static int rcar_pcie_ep_assert_intx(struct rcar_pcie_endpoint *ep,
> > +    u8 fn, u8 intx)
> > +{
> > +struct rcar_pcie *pcie = &ep->pcie;
> > +u32 val;
> > +
> > +val = rcar_pci_read_reg(pcie, PCIEMSITXR);
> > +if ((val & PCI_MSI_FLAGS_ENABLE)) {
> > +dev_err(pcie->dev, "MSI is enabled, cannot assert INTx\n");
> > +return -EINVAL;
> > +}
> > +
> > +val = rcar_pci_read_reg(pcie, PCICONF(1));
> > +if ((val & INTDIS)) {
> > +dev_err(pcie->dev, "INTx message transmission is disabled\n");
> > +return -EINVAL;
> > +}
> > +
> > +val = rcar_pci_read_reg(pcie, PCIEINTXR);
> > +if ((val & ASTINTX)) {
> > +dev_err(pcie->dev, "INTx is already asserted\n");
> > +return -EINVAL;
> > +}
> > +
> > +val |= ASTINTX;
> > +rcar_pci_write_reg(pcie, val, PCIEINTXR);
> > +mdelay(1);
> > +val = rcar_pci_read_reg(pcie, PCIEINTXR);
> > +val &= ~ASTINTX;
> > +rcar_pci_write_reg(pcie, val, PCIEINTXR);
> > +
> > +return 0;
> > +}
> > +
> > +static int rcar_pcie_ep_assert_msi(struct rcar_pcie *pcie,
> > +   u8 fn, u8 interrupt_num)
> > +{
> > +u16 msi_count;
> > +u32 val;
> > +
> > +/* Check MSI enable bit */
> > +val = rcar_pci_read_reg(pcie, MSICAP(fn));
> > +if (!(val & MSICAP0_MSIE))
> > +return -EINVAL;
> > +
> > +/* Get MSI numbers from MME */
> > +msi_count = ((val & MSICAP0_MMENUM_MASK) >> MSICAP0_MMENUM_OFFSET);
> > +msi_count = 1 << msi_count;
> > +
> > +if (!interrupt_num || interrupt_num > msi_count)
> > +return -EINVAL;
> > +
> > +val = rcar_pci_read_reg(pcie, PCIEMSITXR);
> > +rcar_pci_write_reg(pcie, val | (interrupt_num - 1), PCIEMSITXR);
> > +
> > +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_endpoint *ep = epc_get_drvdata(epc);
> > +
> > +switch (type) {
> > +case PCI_EPC_IRQ_LEGACY:
> > +return rcar_pcie_ep_assert_intx(ep, fn, 0);
> > +
> > +case PCI_EPC_IRQ_MSI:
> > +return rcar_pcie_ep_assert_msi(&ep->pcie, fn, interrupt_num);
> > +
> > +default:
> > +return -EINVAL;
> > +}
> > +}
> > +
> > +static int rcar_pcie_ep_start(struct pci_epc *epc)
> > +{
> > +struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
> > +
> > +rcar_pci_write_reg(&ep->pcie, CFINIT, PCIETCTLR);
> > +
> > +return 0;
> > +}
> > +
> > +static void rcar_pcie_ep_stop(struct pci_epc *epc)
> > +{
> > +struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
> > +
> > +rcar_pci_write_reg(&ep->pcie, 0, PCIETCTLR);
> > +}
> > +
> > +static const struct pci_epc_features rcar_pcie_epc_features = {
> > +.linkup_notifier = false,
> > +.msi_capable = true,
> > +.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,
> > +.set_msi= rcar_pcie_ep_set_msi,
> > +.get_msi= rcar_pcie_ep_get_msi,
> > +.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_endpoint *ep;
> > +struct rcar_pcie *pcie;
> > +struct pci_epc *epc;
> > +int err;
> > +
> > +ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
> > +if (!ep)
> > +return -ENOMEM;
> > +
> > +pcie = &ep->pcie;
> > +pcie->dev = dev;
> > +
> > +pm_runtime_enable(dev);
> > +err = pm_runtime_get_sync(dev);
> > +if (err < 0) {
> > +dev_err(dev, "pm_runtime_get_sync failed\n");
> > +goto err_pm_disable;
> > +}
> > +
> > +err = rcar_pcie_ep_get_pdata(ep, pdev);
> > +if (err < 0) {
> > +dev_err(dev, "failed to request resources: %d\n", err);
> > +goto err_pm_put;
> > +}
> > +
> > +ep->num_ib_windows = MAX_NR_INBOUND_MAPS;
> > +ep->ib_window_map =
> > +devm_kcalloc(dev, BITS_TO_LONGS(ep->num_ib_windows),
> > +     sizeof(long), GFP_KERNEL);
> > +if (!ep->ib_window_map) {
> > +err = -ENOMEM;
> > +dev_err(dev, "failed to allocate memory for inbound map\n");
> > +goto err_pm_put;
> > +}
> > +
> > +ep->ob_mapped_addr = devm_kcalloc(dev, ep->num_ob_windows,
> > +  sizeof(*ep->ob_mapped_addr),
> > +  GFP_KERNEL);
> > +if (!ep->ob_mapped_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 = ep->max_functions;
> > +epc_set_drvdata(epc, ep);
> > +
> > +rcar_pcie_ep_hw_init(pcie);
> > +
> > +err = __pci_epc_mem_init(epc, ep->ob_window, ep->num_ob_windows);
> > +if (err < 0) {
> > +dev_err(dev, "failed to initialize the epc memory space\n");
> > +goto err_pm_put;
> > +}
> > +
> > +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 cec7768b4725..0fbeff3d7b78 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  ASTINTXBIT(16)
> >  #define PCIEPHYSR0x0007f0
> >  #define  PHYRDYBIT(0)
> >  #define PCIEMSITXR0x000840
> > @@ -55,12 +56,20 @@
> >
> >  /* Configuration */
> >  #define PCICONF(x)(0x010000 + ((x) * 0x4))
> > +#define  INTDISBIT(10)
> >  #define PMCAP(x)(0x010040 + ((x) * 0x4))
> > +#define MSICAP(x)(0x010050 + ((x) * 0x4))
> > +#define  MSICAP0_MSIEBIT(16)
> > +#define  MSICAP0_MMESCAP_OFFSET17
> > +#define  MSICAP0_MMENUM_OFFSET20
> > +#define  MSICAP0_MMENUM_MASKGENMASK(22, 20)
> >  #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.20.1



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] 30+ messages in thread

* RE: [PATCH v6 07/11] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller
  2020-04-03  8:28   ` Yoshihiro Shimoda
@ 2020-04-03  9:02     ` Prabhakar Mahadev Lad
  0 siblings, 0 replies; 30+ messages in thread
From: Prabhakar Mahadev Lad @ 2020-04-03  9:02 UTC (permalink / raw)
  To: Yoshihiro Shimoda, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar

Hi Shimoda-san,

Thank you for the review.

> -----Original Message-----
> From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Sent: 03 April 2020 09:28
> To: 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>; Geert Uytterhoeven <geert+renesas@glider.be>; Magnus Damm
> <magnus.damm@gmail.com>; Kishon Vijay Abraham I <kishon@ti.com>; Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>; Marek Vasut
> <marek.vasut+renesas@gmail.com>; linux-pci@vger.kernel.org
> Cc: Catalin Marinas <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>; Arnd Bergmann <arnd@arndb.de>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Andrew Murray <andrew.murray@arm.com>; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-renesas-soc@vger.kernel.org; Chris Paterson <Chris.Paterson2@renesas.com>; Frank Rowand
> <frowand.list@gmail.com>; Gustavo Pimentel <gustavo.pimentel@synopsys.com>; Jingoo Han <jingoohan1@gmail.com>; Simon Horman
> <horms@verge.net.au>; Shawn Lin <shawn.lin@rock-chips.com>; Tom Joseph <tjoseph@cadence.com>; Heiko Stuebner
> <heiko@sntech.de>; linux-rockchip@lists.infradead.org; Lad Prabhakar <prabhakar.csengg@gmail.com>; Prabhakar Mahadev Lad
> <prabhakar.mahadev-lad.rj@bp.renesas.com>
> Subject: RE: [PATCH v6 07/11] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller
>
> Hi Prabhakar-san,
>
> Thank you for your patch!
>
> > From: Lad Prabhakar, Sent: Friday, April 3, 2020 4:39 AM
> <snip>
> > 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 000000000000..07cd5a7325d0
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pci/rcar-pci-ep.yaml
> > @@ -0,0 +1,76 @@
> > +# SPDX-License-Identifier: GPL-2.0
>
> I'm sorry I should have mentioned in the previous review.
> This is better like the following.
>
> # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>
> https://patchwork.kernel.org/patch/11459267/#23246825
>
Argh my bad I should have noticed this too, usual tendency is to ignore the patch when its being Acked 😃

> <snip>
> > +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>;
>
> Examples are built with #{address,size}-cells = <1>, so
>
>             reg = <0xfe000000 0x80000>,
>                   <0xfe100000 0x100000>,
>                   <0xfe200000 0x200000>,
>                   <0x30000000 0x8000000>,
>                   <0x38000000 0x8000000>;
>
> https://patchwork.kernel.org/patch/11459267/#23246825
>
Will change this as above.

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] 30+ messages in thread

* RE: [PATCH v6 02/11] arm64: defconfig: enable CONFIG_PCIE_RCAR_HOST
  2020-04-03  8:28     ` Geert Uytterhoeven
@ 2020-04-03  9:04       ` Yoshihiro Shimoda
  2020-04-03  9:31         ` Prabhakar Mahadev Lad
  0 siblings, 1 reply; 30+ messages in thread
From: Yoshihiro Shimoda @ 2020-04-03  9:04 UTC (permalink / raw)
  To: Geert Uytterhoeven, Prabhakar Mahadev Lad
  Cc: Will Deacon, Geert Uytterhoeven, Catalin Marinas, Arnd Bergmann,
	Greg Kroah-Hartman, Andrew Murray, devicetree, linux-kernel,
	linux-arm-kernel, linux-renesas-soc, Chris Paterson,
	Frank Rowand, Gustavo Pimentel, Jingoo Han, Simon Horman,
	Shawn Lin, Tom Joseph, Heiko Stuebner, linux-rockchip,
	Lad Prabhakar, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci, Bjorn Helgaas,
	Rob Herring, Mark Rutland

Hi Geert-san,

Thank you for your comments!

> From: Geert Uytterhoeven, Sent: Friday, April 3, 2020 5:28 PM
<snip>
> > But, I'm thinking this patch (and patch 03/11) should be separated
> > from this patch series for arm64 subsystem to ease maintenance.
> > My scenario is:
> >  1) patch series 1: R-Car PCIe endpoint support.
> >  -- This means: patch 1, 4 - 9, 11
> >
> >  2) After the patch series 1 is merged, submit this patch 2/11 to arm subsystem
> >    and submit the patch 10/11 to misc subsystem.
> >
> >  3) At last, submit patch 3/11 after the patch 2/11 is merged.
> >
> > Geert-san, what do you think?
> 
> Thanks, I agree with your summary.
> 
> I can take patch 2/11 through renesas-devel.
> Probably it's best if I submit it to arm-soc as a fix for v5.8, after
> the driver part
> has been merged into v5.8-rc1, so 3/11 can be submitted for v5.9.

Thank you! I got it.

> BTW, I'm wondering about "[PATCH v6 05/11] PCI: rcar: Fix calculating
> mask for PCIEPAMR register". Can the issue fixed by this patch happen with
> the current driver in host mode, or is that limited to ep mode?
> In case of the former, please submit it to the PCI maintainer as a separate
> fix.

Thank you for pointed it out. I think this is the case of the former.
IIUC, if such a small window PCIe device exists, the issue happens.

Prabhakar-san, is my understanding correct?

Best regards,
Yoshihiro Shimoda


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

* RE: [PATCH v6 06/11] PCI: endpoint: Add support to handle multiple base for mapping outbound memory
  2020-04-03  8:23   ` Yoshihiro Shimoda
@ 2020-04-03  9:11     ` Prabhakar Mahadev Lad
  2020-04-03  9:34       ` Yoshihiro Shimoda
  0 siblings, 1 reply; 30+ messages in thread
From: Prabhakar Mahadev Lad @ 2020-04-03  9:11 UTC (permalink / raw)
  To: Yoshihiro Shimoda, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar

Hi Shimoda-san,

Thank you for the review.

> -----Original Message-----
> From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Sent: 03 April 2020 09:23
> To: 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>; Geert Uytterhoeven <geert+renesas@glider.be>; Magnus Damm
> <magnus.damm@gmail.com>; Kishon Vijay Abraham I <kishon@ti.com>; Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>; Marek Vasut
> <marek.vasut+renesas@gmail.com>; linux-pci@vger.kernel.org
> Cc: Catalin Marinas <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>; Arnd Bergmann <arnd@arndb.de>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Andrew Murray <andrew.murray@arm.com>; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-renesas-soc@vger.kernel.org; Chris Paterson <Chris.Paterson2@renesas.com>; Frank Rowand
> <frowand.list@gmail.com>; Gustavo Pimentel <gustavo.pimentel@synopsys.com>; Jingoo Han <jingoohan1@gmail.com>; Simon Horman
> <horms@verge.net.au>; Shawn Lin <shawn.lin@rock-chips.com>; Tom Joseph <tjoseph@cadence.com>; Heiko Stuebner
> <heiko@sntech.de>; linux-rockchip@lists.infradead.org; Lad Prabhakar <prabhakar.csengg@gmail.com>; Prabhakar Mahadev Lad
> <prabhakar.mahadev-lad.rj@bp.renesas.com>
> Subject: RE: [PATCH v6 06/11] PCI: endpoint: Add support to handle multiple base for mapping outbound memory
>
> Hi Prabhakar-san,
>
> Thank you for the patch!
>
> > From: Lad Prabhakar, Sent: Friday, April 3, 2020 4:39 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() initializes address space for endpoint
> > controller which support single window and whereas __pci_epc_mem_init()
> > now accepts pointer to multiple windows supported by endpoint controller.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> > ---
> > @@ -38,61 +38,95 @@ 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,
> > +       unsigned 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;
> > +int pages;
> > +int ret;
> > +int i;
> >
> > -if (page_size < PAGE_SIZE)
> > -page_size = PAGE_SIZE;
> > +epc->num_windows = 0;
> >
> > -page_shift = ilog2(page_size);
> > -pages = size >> page_shift;
> > -bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
> > +if (!windows || !num_windows)
> > +return -EINVAL;
> >
> > -mem = kzalloc(sizeof(*mem), GFP_KERNEL);
> > -if (!mem) {
> > -ret = -ENOMEM;
> > -goto err;
> > -}
> > +epc->windows = kcalloc(num_windows, sizeof(*mem), GFP_KERNEL);
> > +if (!epc->windows)
> > +return -ENOMEM;
> >
> > -bitmap = kzalloc(bitmap_size, GFP_KERNEL);
> > -if (!bitmap) {
> > -ret = -ENOMEM;
> > -goto err_mem;
> > -}
> > +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;
> > +i -= 1;
>
> nit: We can use i--;
>
Will change it.

> > +goto err_mem;
> > +}
> > +
> > +bitmap = kzalloc(bitmap_size, GFP_KERNEL);
> > +if (!bitmap) {
> > +ret = -ENOMEM;
> > +kfree(mem);
> > +i -= 1;
>
> nit: We can use i--;
>
As above.

> <snip>
> > @@ -122,31 +167,56 @@ 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 = NULL;
> > -struct pci_epc_mem *mem = epc->mem;
> > -unsigned int page_shift = ilog2(mem->page_size);
> > +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);
> > -
> > -mutex_lock(&mem->lock);
> > -pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);
> > -if (pageno < 0)
> > -goto ret;
> > +for (i = 0; i < epc->num_windows; i++) {
> > +mem = epc->windows[i];
> > +mutex_lock(&mem->lock);
>
> This is my feeling though, calling mutex_lock() in the loop seems
> to cause overhead. And, if we call mutex_lock() at out-of the loop,
> I think we can write single mutex_unlock() calling.
>
But the mutex is for each window, are you suggesting to add a global mutex ?

> > +size = ALIGN(size, mem->window.page_size);
>
> I'm sorry I should have realized this in the previous review,
> but overwriting this size is possible to cause an issue at second time or more loops.
> So, the first argument of ALIGN should be kept for the loop.
>
Could you please elaborate on this.

> > +order = pci_epc_mem_get_order(mem, size);
> >
> > -*phys_addr = mem->phys_base + ((phys_addr_t)pageno << page_shift);
> > -virt_addr = ioremap(*phys_addr, size);
> > -if (!virt_addr)
> > -bitmap_release_region(mem->bitmap, pageno, order);
> > +pageno = bitmap_find_free_region(mem->bitmap, mem->pages,
> > + order);
> > +if (pageno >= 0) {
> > +page_shift = ilog2(mem->window.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);
> > +mutex_unlock(&mem->lock);
> > +return virt_addr;
>
> As I mentioned above, if mutex_lock() is called at out-of-loop,
> we can use "goto ret;" here like the original code,
>
> > +}
> > +mutex_unlock(&mem->lock);
>
> and we can remove this.
>
> > +}
> >
> > -ret:
> > -mutex_unlock(&mem->lock);
> >  return virt_addr;
> >  }
> >  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->num_windows; i++) {
> > +mem = epc->windows[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
> > @@ -159,14 +229,23 @@ 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;
> > +size_t page_size;
> >  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_size = mem->window.page_size;
> > +page_shift = ilog2(page_size);
> >  iounmap(virt_addr);
> > -pageno = (phys_addr - mem->phys_base) >> page_shift;
> > -size = ALIGN(size, mem->page_size);
> > +pageno = (phys_addr - mem->window.phys_base) >> page_shift;
> > +size = ALIGN(size, page_size);
> >  order = pci_epc_mem_get_order(mem, size);
> >  mutex_lock(&mem->lock);
> >  bitmap_release_region(mem->bitmap, pageno, order);
> > diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
> > index e0ed9d01f6e5..d5da11cf0f2a 100644
> > --- a/include/linux/pci-epc.h
> > +++ b/include/linux/pci-epc.h
> > @@ -65,20 +65,28 @@ struct pci_epc_ops {
> >  struct module *owner;
> >  };
> >
> > +/**
> > + * 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
> >   * @lock: mutex to protect bitmap
> > + * @pages: number of bits representing the address region
>
> Perhaps, we should not change the "@pages" line.
>
OK will drop this change.

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] 30+ messages in thread

* RE: [PATCH v6 02/11] arm64: defconfig: enable CONFIG_PCIE_RCAR_HOST
  2020-04-03  9:04       ` Yoshihiro Shimoda
@ 2020-04-03  9:31         ` Prabhakar Mahadev Lad
  2020-04-03  9:44           ` Yoshihiro Shimoda
  0 siblings, 1 reply; 30+ messages in thread
From: Prabhakar Mahadev Lad @ 2020-04-03  9:31 UTC (permalink / raw)
  To: Yoshihiro Shimoda, Geert Uytterhoeven
  Cc: Will Deacon, Geert Uytterhoeven, Catalin Marinas, Arnd Bergmann,
	Greg Kroah-Hartman, Andrew Murray, devicetree, linux-kernel,
	linux-arm-kernel, linux-renesas-soc, Chris Paterson,
	Frank Rowand, Gustavo Pimentel, Jingoo Han, Simon Horman,
	Shawn Lin, Tom Joseph, Heiko Stuebner, linux-rockchip,
	Lad Prabhakar, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci, Bjorn Helgaas,
	Rob Herring, Mark Rutland

Hi Shimoda-san/Geert-san,

> -----Original Message-----
> From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Sent: 03 April 2020 10:05
> To: Geert Uytterhoeven <geert@linux-m68k.org>; Prabhakar Mahadev Lad <prabhakar.mahadev-lad.rj@bp.renesas.com>
> Cc: Will Deacon <will@kernel.org>; Geert Uytterhoeven <geert+renesas@glider.be>; Catalin Marinas <catalin.marinas@arm.com>; Arnd
> Bergmann <arnd@arndb.de>; Greg Kroah-Hartman <gregkh@linuxfoundation.org>; Andrew Murray <andrew.murray@arm.com>;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-renesas-soc@vger.kernel.org; Chris
> Paterson <Chris.Paterson2@renesas.com>; Frank Rowand <frowand.list@gmail.com>; Gustavo Pimentel
> <gustavo.pimentel@synopsys.com>; Jingoo Han <jingoohan1@gmail.com>; Simon Horman <horms@verge.net.au>; Shawn Lin
> <shawn.lin@rock-chips.com>; Tom Joseph <tjoseph@cadence.com>; Heiko Stuebner <heiko@sntech.de>; linux-
> rockchip@lists.infradead.org; Lad Prabhakar <prabhakar.csengg@gmail.com>; Magnus Damm <magnus.damm@gmail.com>; Kishon Vijay
> Abraham I <kishon@ti.com>; Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>; Marek Vasut <marek.vasut+renesas@gmail.com>; linux-
> pci@vger.kernel.org; Bjorn Helgaas <bhelgaas@google.com>; Rob Herring <robh+dt@kernel.org>; Mark Rutland
> <mark.rutland@arm.com>
> Subject: RE: [PATCH v6 02/11] arm64: defconfig: enable CONFIG_PCIE_RCAR_HOST
>
> Hi Geert-san,
>
> Thank you for your comments!
>
> > From: Geert Uytterhoeven, Sent: Friday, April 3, 2020 5:28 PM
> <snip>
> > > But, I'm thinking this patch (and patch 03/11) should be separated
> > > from this patch series for arm64 subsystem to ease maintenance.
> > > My scenario is:
> > >  1) patch series 1: R-Car PCIe endpoint support.
> > >  -- This means: patch 1, 4 - 9, 11
> > >
> > >  2) After the patch series 1 is merged, submit this patch 2/11 to arm subsystem
> > >    and submit the patch 10/11 to misc subsystem.
> > >
> > >  3) At last, submit patch 3/11 after the patch 2/11 is merged.
> > >
> > > Geert-san, what do you think?
> >
> > Thanks, I agree with your summary.
> >
> > I can take patch 2/11 through renesas-devel.
> > Probably it's best if I submit it to arm-soc as a fix for v5.8, after
> > the driver part
> > has been merged into v5.8-rc1, so 3/11 can be submitted for v5.9.
>
> Thank you! I got it.
>
Thank you, Ill split the patches accordingly and post a v7.

> > BTW, I'm wondering about "[PATCH v6 05/11] PCI: rcar: Fix calculating
> > mask for PCIEPAMR register". Can the issue fixed by this patch happen with
> > the current driver in host mode, or is that limited to ep mode?
> > In case of the former, please submit it to the PCI maintainer as a separate
> > fix.
>
> Thank you for pointed it out. I think this is the case of the former.
> IIUC, if such a small window PCIe device exists, the issue happens.
>
> Prabhakar-san, is my understanding correct?
>
This issue will only be hit on EP, when in host mode the sizes will be fixed to 1 Mbytes /2 Mbytes /128 Mbytes

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] 30+ messages in thread

* RE: [PATCH v6 06/11] PCI: endpoint: Add support to handle multiple base for mapping outbound memory
  2020-04-03  9:11     ` Prabhakar Mahadev Lad
@ 2020-04-03  9:34       ` Yoshihiro Shimoda
  2020-04-03  9:47         ` Prabhakar Mahadev Lad
  0 siblings, 1 reply; 30+ messages in thread
From: Yoshihiro Shimoda @ 2020-04-03  9:34 UTC (permalink / raw)
  To: Prabhakar Mahadev Lad, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar

Hi Prabhakar-san,

> From: Prabhakar Mahadev Lad, Sent: Friday, April 3, 2020 6:12 PM
<snip>
> > > @@ -122,31 +167,56 @@ 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 = NULL;
> > > -	struct pci_epc_mem *mem = epc->mem;
> > > -	unsigned int page_shift = ilog2(mem->page_size);
> > > +	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);
> > > -
> > > -	mutex_lock(&mem->lock);
> > > -	pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);
> > > -	if (pageno < 0)
> > > -		goto ret;
> > > +	for (i = 0; i < epc->num_windows; i++) {
> > > +		mem = epc->windows[i];
> > > +		mutex_lock(&mem->lock);
> >
> > This is my feeling though, calling mutex_lock() in the loop seems
> > to cause overhead. And, if we call mutex_lock() at out-of the loop,
> > I think we can write single mutex_unlock() calling.
> >
> But the mutex is for each window, are you suggesting to add a global mutex ?

Oops, that's right. So, I'd like to recall.

> > > +		size = ALIGN(size, mem->window.page_size);
> >
> > I'm sorry I should have realized this in the previous review,
> > but overwriting this size is possible to cause an issue at second time or more loops.
> > So, the first argument of ALIGN should be kept for the loop.
> >
> Could you please elaborate on this.

My concern is the following.

For example, the size of argument of pci_epc_mem_alloc_addr() is 4096.
epc->windows[0].window.page_size = 8192
 --> then the size will be changed to 0.

epc->windows[1].window.page_size = 4096
 --> since the size was changed to 0 on the first loop, the result is 0.
     But, this should be 4096.

Does such a case never happen?
(Or, is my understanding incorrect?)

Best regards,
Yoshihiro Shimoda


> > > +		order = pci_epc_mem_get_order(mem, size);
> > >
> > > -	*phys_addr = mem->phys_base + ((phys_addr_t)pageno << page_shift);
> > > -	virt_addr = ioremap(*phys_addr, size);
> > > -	if (!virt_addr)
> > > -		bitmap_release_region(mem->bitmap, pageno, order);
> > > +		pageno = bitmap_find_free_region(mem->bitmap, mem->pages,
> > > +						 order);
> > > +		if (pageno >= 0) {
> > > +			page_shift = ilog2(mem->window.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);
> > > +			mutex_unlock(&mem->lock);
> > > +			return virt_addr;
> >
> > As I mentioned above, if mutex_lock() is called at out-of-loop,
> > we can use "goto ret;" here like the original code,
> >
> > > +		}
> > > +		mutex_unlock(&mem->lock);
> >
> > and we can remove this.
> >
> > > +	}
> > >
> > > -ret:
> > > -	mutex_unlock(&mem->lock);
> > >  	return virt_addr;
> > >  }
> > >  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->num_windows; i++) {
> > > +		mem = epc->windows[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
> > > @@ -159,14 +229,23 @@ 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;
> > > +	size_t page_size;
> > >  	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_size = mem->window.page_size;
> > > +	page_shift = ilog2(page_size);
> > >  	iounmap(virt_addr);
> > > -	pageno = (phys_addr - mem->phys_base) >> page_shift;
> > > -	size = ALIGN(size, mem->page_size);
> > > +	pageno = (phys_addr - mem->window.phys_base) >> page_shift;
> > > +	size = ALIGN(size, page_size);
> > >  	order = pci_epc_mem_get_order(mem, size);
> > >  	mutex_lock(&mem->lock);
> > >  	bitmap_release_region(mem->bitmap, pageno, order);
> > > diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
> > > index e0ed9d01f6e5..d5da11cf0f2a 100644
> > > --- a/include/linux/pci-epc.h
> > > +++ b/include/linux/pci-epc.h
> > > @@ -65,20 +65,28 @@ struct pci_epc_ops {
> > >  	struct module *owner;
> > >  };
> > >
> > > +/**
> > > + * 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
> > >   * @lock: mutex to protect bitmap
> > > + * @pages: number of bits representing the address region
> >
> > Perhaps, we should not change the "@pages" line.
> >
> OK will drop this change.
> 
> Cheers,
> --Prabhakar
> 
> > Best regards,
> > Yoshihiro Shimoda


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

* RE: [PATCH v6 02/11] arm64: defconfig: enable CONFIG_PCIE_RCAR_HOST
  2020-04-03  9:31         ` Prabhakar Mahadev Lad
@ 2020-04-03  9:44           ` Yoshihiro Shimoda
  0 siblings, 0 replies; 30+ messages in thread
From: Yoshihiro Shimoda @ 2020-04-03  9:44 UTC (permalink / raw)
  To: Prabhakar Mahadev Lad, Geert Uytterhoeven
  Cc: Will Deacon, Geert Uytterhoeven, Catalin Marinas, Arnd Bergmann,
	Greg Kroah-Hartman, Andrew Murray, devicetree, linux-kernel,
	linux-arm-kernel, linux-renesas-soc, Chris Paterson,
	Frank Rowand, Gustavo Pimentel, Jingoo Han, Simon Horman,
	Shawn Lin, Tom Joseph, Heiko Stuebner, linux-rockchip,
	Lad Prabhakar, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci, Bjorn Helgaas,
	Rob Herring, Mark Rutland

Hi Prabhakar-san,

> From: Prabhakar Mahadev Lad, Sent: Friday, April 3, 2020 6:32 PM
<snip>
> > > BTW, I'm wondering about "[PATCH v6 05/11] PCI: rcar: Fix calculating
> > > mask for PCIEPAMR register". Can the issue fixed by this patch happen with
> > > the current driver in host mode, or is that limited to ep mode?
> > > In case of the former, please submit it to the PCI maintainer as a separate
> > > fix.
> >
> > Thank you for pointed it out. I think this is the case of the former.
> > IIUC, if such a small window PCIe device exists, the issue happens.
> >
> > Prabhakar-san, is my understanding correct?
> >
> This issue will only be hit on EP, when in host mode the sizes will be fixed to 1 Mbytes /2 Mbytes /128 Mbytes

Thank you for your comment. Now I understood this is related to "PCIEn memory m" in the document
and related to ranges property in the device node. So, I'd like to recall my previous comment and
I agree the patch 06/11 is required on EP mode only.

Best regards,
Yoshihiro Shimoda


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

* RE: [PATCH v6 06/11] PCI: endpoint: Add support to handle multiple base for mapping outbound memory
  2020-04-03  9:34       ` Yoshihiro Shimoda
@ 2020-04-03  9:47         ` Prabhakar Mahadev Lad
  0 siblings, 0 replies; 30+ messages in thread
From: Prabhakar Mahadev Lad @ 2020-04-03  9:47 UTC (permalink / raw)
  To: Yoshihiro Shimoda, Bjorn Helgaas, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, Magnus Damm, Kishon Vijay Abraham I,
	Lorenzo Pieralisi, Marek Vasut, linux-pci
  Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Greg Kroah-Hartman,
	Andrew Murray, devicetree, linux-kernel, linux-arm-kernel,
	linux-renesas-soc, Chris Paterson, Frank Rowand,
	Gustavo Pimentel, Jingoo Han, Simon Horman, Shawn Lin,
	Tom Joseph, Heiko Stuebner, linux-rockchip, Lad Prabhakar

Hi Shimoda-san,

> -----Original Message-----
> From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Sent: 03 April 2020 10:34
> To: 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>; Geert Uytterhoeven <geert+renesas@glider.be>; Magnus Damm
> <magnus.damm@gmail.com>; Kishon Vijay Abraham I <kishon@ti.com>; Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>; Marek Vasut
> <marek.vasut+renesas@gmail.com>; linux-pci@vger.kernel.org
> Cc: Catalin Marinas <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>; Arnd Bergmann <arnd@arndb.de>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Andrew Murray <andrew.murray@arm.com>; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-renesas-soc@vger.kernel.org; Chris Paterson <Chris.Paterson2@renesas.com>; Frank Rowand
> <frowand.list@gmail.com>; Gustavo Pimentel <gustavo.pimentel@synopsys.com>; Jingoo Han <jingoohan1@gmail.com>; Simon Horman
> <horms@verge.net.au>; Shawn Lin <shawn.lin@rock-chips.com>; Tom Joseph <tjoseph@cadence.com>; Heiko Stuebner
> <heiko@sntech.de>; linux-rockchip@lists.infradead.org; Lad Prabhakar <prabhakar.csengg@gmail.com>
> Subject: RE: [PATCH v6 06/11] PCI: endpoint: Add support to handle multiple base for mapping outbound memory
>
> Hi Prabhakar-san,
>
> > From: Prabhakar Mahadev Lad, Sent: Friday, April 3, 2020 6:12 PM
> <snip>
> > > > @@ -122,31 +167,56 @@ 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 = NULL;
> > > > -struct pci_epc_mem *mem = epc->mem;
> > > > -unsigned int page_shift = ilog2(mem->page_size);
> > > > +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);
> > > > -
> > > > -mutex_lock(&mem->lock);
> > > > -pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);
> > > > -if (pageno < 0)
> > > > -goto ret;
> > > > +for (i = 0; i < epc->num_windows; i++) {
> > > > +mem = epc->windows[i];
> > > > +mutex_lock(&mem->lock);
> > >
> > > This is my feeling though, calling mutex_lock() in the loop seems
> > > to cause overhead. And, if we call mutex_lock() at out-of the loop,
> > > I think we can write single mutex_unlock() calling.
> > >
> > But the mutex is for each window, are you suggesting to add a global mutex ?
>
> Oops, that's right. So, I'd like to recall.
>
> > > > +size = ALIGN(size, mem->window.page_size);
> > >
> > > I'm sorry I should have realized this in the previous review,
> > > but overwriting this size is possible to cause an issue at second time or more loops.
> > > So, the first argument of ALIGN should be kept for the loop.
> > >
> > Could you please elaborate on this.
>
> My concern is the following.
>
> For example, the size of argument of pci_epc_mem_alloc_addr() is 4096.
> epc->windows[0].window.page_size = 8192
>  --> then the size will be changed to 0.
>
> epc->windows[1].window.page_size = 4096
>  --> since the size was changed to 0 on the first loop, the result is 0.
>      But, this should be 4096.
>
> Does such a case never happen?
> (Or, is my understanding incorrect?)
>
Good catch, yes that needs fixing probably by having a local variable for size.

Cheers,
--Prabhakar

> Best regards,
> Yoshihiro Shimoda
>
>
> > > > +order = pci_epc_mem_get_order(mem, size);
> > > >
> > > > -*phys_addr = mem->phys_base + ((phys_addr_t)pageno << page_shift);
> > > > -virt_addr = ioremap(*phys_addr, size);
> > > > -if (!virt_addr)
> > > > -bitmap_release_region(mem->bitmap, pageno, order);
> > > > +pageno = bitmap_find_free_region(mem->bitmap, mem->pages,
> > > > + order);
> > > > +if (pageno >= 0) {
> > > > +page_shift = ilog2(mem->window.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);
> > > > +mutex_unlock(&mem->lock);
> > > > +return virt_addr;
> > >
> > > As I mentioned above, if mutex_lock() is called at out-of-loop,
> > > we can use "goto ret;" here like the original code,
> > >
> > > > +}
> > > > +mutex_unlock(&mem->lock);
> > >
> > > and we can remove this.
> > >
> > > > +}
> > > >
> > > > -ret:
> > > > -mutex_unlock(&mem->lock);
> > > >  return virt_addr;
> > > >  }
> > > >  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->num_windows; i++) {
> > > > +mem = epc->windows[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
> > > > @@ -159,14 +229,23 @@ 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;
> > > > +size_t page_size;
> > > >  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_size = mem->window.page_size;
> > > > +page_shift = ilog2(page_size);
> > > >  iounmap(virt_addr);
> > > > -pageno = (phys_addr - mem->phys_base) >> page_shift;
> > > > -size = ALIGN(size, mem->page_size);
> > > > +pageno = (phys_addr - mem->window.phys_base) >> page_shift;
> > > > +size = ALIGN(size, page_size);
> > > >  order = pci_epc_mem_get_order(mem, size);
> > > >  mutex_lock(&mem->lock);
> > > >  bitmap_release_region(mem->bitmap, pageno, order);
> > > > diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
> > > > index e0ed9d01f6e5..d5da11cf0f2a 100644
> > > > --- a/include/linux/pci-epc.h
> > > > +++ b/include/linux/pci-epc.h
> > > > @@ -65,20 +65,28 @@ struct pci_epc_ops {
> > > >  struct module *owner;
> > > >  };
> > > >
> > > > +/**
> > > > + * 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
> > > >   * @lock: mutex to protect bitmap
> > > > + * @pages: number of bits representing the address region
> > >
> > > Perhaps, we should not change the "@pages" line.
> > >
> > OK will drop this change.
> >
> > 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] 30+ messages in thread

end of thread, other threads:[~2020-04-03  9:48 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-02 19:38 [PATCH v6 00/11] Add support for PCIe controller to work in endpoint mode on R-Car SoCs Lad Prabhakar
2020-04-02 19:38 ` [PATCH v6 01/11] PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c Lad Prabhakar
2020-04-03  7:52   ` Yoshihiro Shimoda
2020-04-02 19:38 ` [PATCH v6 02/11] arm64: defconfig: enable CONFIG_PCIE_RCAR_HOST Lad Prabhakar
2020-04-03  8:03   ` Yoshihiro Shimoda
2020-04-03  8:28     ` Geert Uytterhoeven
2020-04-03  9:04       ` Yoshihiro Shimoda
2020-04-03  9:31         ` Prabhakar Mahadev Lad
2020-04-03  9:44           ` Yoshihiro Shimoda
2020-04-02 19:38 ` [PATCH v6 03/11] PCI: drop PCIE_RCAR config option Lad Prabhakar
2020-04-02 19:38 ` [PATCH v6 04/11] PCI: rcar: Move shareable code to a common file Lad Prabhakar
2020-04-03  8:06   ` Yoshihiro Shimoda
2020-04-02 19:38 ` [PATCH v6 05/11] PCI: rcar: Fix calculating mask for PCIEPAMR register Lad Prabhakar
2020-04-02 19:38 ` [PATCH v6 06/11] PCI: endpoint: Add support to handle multiple base for mapping outbound memory Lad Prabhakar
2020-04-03  8:23   ` Yoshihiro Shimoda
2020-04-03  9:11     ` Prabhakar Mahadev Lad
2020-04-03  9:34       ` Yoshihiro Shimoda
2020-04-03  9:47         ` Prabhakar Mahadev Lad
2020-04-02 19:38 ` [PATCH v6 07/11] dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint controller Lad Prabhakar
2020-04-03  8:28   ` Yoshihiro Shimoda
2020-04-03  9:02     ` Prabhakar Mahadev Lad
2020-04-02 19:38 ` [PATCH v6 08/11] PCI: rcar: Add support for rcar PCIe controller in endpoint mode Lad Prabhakar
2020-04-03  8:44   ` Yoshihiro Shimoda
2020-04-03  8:58     ` Prabhakar Mahadev Lad
2020-04-02 19:38 ` [PATCH v6 09/11] PCI: Add Renesas R8A774C0 device ID Lad Prabhakar
2020-04-03  8:46   ` Yoshihiro Shimoda
2020-04-02 19:38 ` [PATCH v6 10/11] misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller Lad Prabhakar
2020-04-03  8:47   ` Yoshihiro Shimoda
2020-04-02 19:38 ` [PATCH v6 11/11] MAINTAINERS: Add file patterns for rcar PCI device tree bindings Lad Prabhakar
2020-04-03  8:48   ` Yoshihiro Shimoda

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