Linux PCI subsystem development
 help / color / mirror / Atom feed
* [PATCH v4 0/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4
@ 2026-09-05 21:26 Marek Vasut
  2026-09-05 21:26 ` [PATCH v4 1/6] dt-bindings: PCI: rcar-gen4-pci-host: Add R-Car X5H PCIe4 compatible Marek Vasut
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Marek Vasut @ 2026-09-05 21:26 UTC (permalink / raw)
  To: linux-pci
  Cc: Marek Vasut, Krzysztof Wilczyński, Bjorn Helgaas,
	Conor Dooley, Geert Uytterhoeven, Krzysztof Kozlowski,
	Lorenzo Pieralisi, Manivannan Sadhasivam, Rob Herring,
	Yoshihiro Shimoda, devicetree, linux-kernel, linux-renesas-soc

Add support for R8A78000 (R-Car X5H) PCIe4.

This driver previously supported R-Car Gen4 S4/V4H/V4M. PCIe features
of R-Car X5H PCIe4 are almost all the same, except for different PHY
which has its own driver, slightly different initialization code and
the DMA is no longer eDMA but HDMA.

Endpoint mode is currently not implemented for R-Car Gen5 PCIe4.

Marek Vasut (6):
  dt-bindings: PCI: rcar-gen4-pci-host: Add R-Car X5H PCIe4 compatible
  PCI: dwc: rcar-gen4: Rework rcar_gen4_pcie_drvdata
    .additional_common_init into .init
  PCI: dwc: rcar-gen4: Add .deinit callback
  PCI: dwc: rcar-gen4: Split .start_link into ltssm_control and
    speed_control
  PCI: dwc: rcar-gen4: Handle PERST via reset subsystem
  PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4

 .../bindings/pci/rcar-gen4-pci-host.yaml      |  74 +++--
 drivers/pci/controller/dwc/pcie-rcar-gen4.c   | 264 +++++++++++++++---
 2 files changed, 277 insertions(+), 61 deletions(-)

---
Cc: "Krzysztof Wilczyński" <kwilczynski@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org

-- 
2.53.0


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

* [PATCH v4 1/6] dt-bindings: PCI: rcar-gen4-pci-host: Add R-Car X5H PCIe4 compatible
  2026-09-05 21:26 [PATCH v4 0/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4 Marek Vasut
@ 2026-09-05 21:26 ` Marek Vasut
  2026-09-05 21:36   ` sashiko-bot
  2026-09-05 21:26 ` [PATCH v4 2/6] PCI: dwc: rcar-gen4: Rework rcar_gen4_pcie_drvdata .additional_common_init into .init Marek Vasut
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2026-09-05 21:26 UTC (permalink / raw)
  To: linux-pci
  Cc: Marek Vasut, Krzysztof Kozlowski, Krzysztof Wilczyński,
	Bjorn Helgaas, Conor Dooley, Geert Uytterhoeven,
	Krzysztof Kozlowski, Lorenzo Pieralisi, Manivannan Sadhasivam,
	Rob Herring, Yoshihiro Shimoda, devicetree, linux-kernel,
	linux-renesas-soc

Document bindings for R-Car X5H (R8A78000) PCIe4 host module.

The binding document is deliberately using "renesas,rcar-gen5-pcie4"
DT compatible string to discern R-Car X5H PCIe4 controller supported
by this binding, from R-Car X5H PCIe6 controller which will use a
separate binding.

The R-Car X5H PCIe4 controller does no longer include PHY register
range, the PHY is now a separate IP and referenced via the 'phy' DT
property. The 'reg' and 'reg-names' DT properties therefore differ
between R-Car Gen4 PCIe and R-Car X5H PCIe4, and the difference is
handled in the allOf section.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: "Krzysztof Wilczyński" <kwilczynski@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
---
V2: Add RB from Krzysztof
V3: No change
V4: Rebase on next-20260904
---
 .../bindings/pci/rcar-gen4-pci-host.yaml      | 74 +++++++++++++------
 1 file changed, 52 insertions(+), 22 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/rcar-gen4-pci-host.yaml b/Documentation/devicetree/bindings/pci/rcar-gen4-pci-host.yaml
index 64f456c6a75a1..9767a52f3904e 100644
--- a/Documentation/devicetree/bindings/pci/rcar-gen4-pci-host.yaml
+++ b/Documentation/devicetree/bindings/pci/rcar-gen4-pci-host.yaml
@@ -10,30 +10,20 @@ title: Renesas R-Car Gen4 PCIe Host
 maintainers:
   - Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
 
-allOf:
-  - $ref: snps,dw-pcie.yaml#
-
 properties:
   compatible:
-    items:
-      - enum:
-          - renesas,r8a779f0-pcie      # R-Car S4-8
-          - renesas,r8a779g0-pcie      # R-Car V4H
-          - renesas,r8a779h0-pcie      # R-Car V4M
-      - const: renesas,rcar-gen4-pcie  # R-Car Gen4
-
-  reg:
-    maxItems: 7
-
-  reg-names:
-    items:
-      - const: dbi
-      - const: dbi2
-      - const: atu
-      - const: dma
-      - const: app
-      - const: phy
-      - const: config
+    oneOf:
+      - items:
+          - enum:
+              - renesas,r8a779f0-pcie      # R-Car S4-8
+              - renesas,r8a779g0-pcie      # R-Car V4H
+              - renesas,r8a779h0-pcie      # R-Car V4M
+          - const: renesas,rcar-gen4-pcie  # R-Car Gen4
+
+      - items:
+          - enum:
+              - renesas,r8a78000-pcie4     # R-Car X5H PCIe4
+          - const: renesas,rcar-gen5-pcie4 # R-Car Gen5 PCIe4
 
   interrupts:
     maxItems: 4
@@ -84,6 +74,46 @@ required:
   - resets
   - reset-names
 
+allOf:
+  - $ref: snps,dw-pcie.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: renesas,rcar-gen4-pcie
+    then:
+      properties:
+        reg:
+          maxItems: 7
+
+        reg-names:
+          items:
+            - const: dbi
+            - const: dbi2
+            - const: atu
+            - const: dma
+            - const: app
+            - const: phy
+            - const: config
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: renesas,rcar-gen5-pcie4
+    then:
+      properties:
+        reg:
+          maxItems: 6
+
+        reg-names:
+          items:
+            - const: dbi
+            - const: dbi2
+            - const: atu
+            - const: dma
+            - const: app
+            - const: config
+
 unevaluatedProperties: false
 
 examples:
-- 
2.53.0


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

* [PATCH v4 2/6] PCI: dwc: rcar-gen4: Rework rcar_gen4_pcie_drvdata .additional_common_init into .init
  2026-09-05 21:26 [PATCH v4 0/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4 Marek Vasut
  2026-09-05 21:26 ` [PATCH v4 1/6] dt-bindings: PCI: rcar-gen4-pci-host: Add R-Car X5H PCIe4 compatible Marek Vasut
@ 2026-09-05 21:26 ` Marek Vasut
  2026-09-05 21:33   ` sashiko-bot
  2026-09-05 21:26 ` [PATCH v4 3/6] PCI: dwc: rcar-gen4: Add .deinit callback Marek Vasut
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2026-09-05 21:26 UTC (permalink / raw)
  To: linux-pci
  Cc: Marek Vasut, Krzysztof Wilczyński, Bjorn Helgaas,
	Conor Dooley, Geert Uytterhoeven, Krzysztof Kozlowski,
	Lorenzo Pieralisi, Manivannan Sadhasivam, Rob Herring,
	Yoshihiro Shimoda, devicetree, linux-kernel, linux-renesas-soc

Rework the current complicated initialization callchain that invokes
host_init->common_init->additional_common_init() for host and
ep_init->common_init->additional_common_init() for endpoint into
simpler host_init->init() and ep_init->init() .

The init callback is now always implmented for all R-Car Gen4 SoCs,
therefore there is no need to check whether the callback is not NULL.
For R-Car S4 the .init callback is rcar_gen4_pcie_common_init(),
for R-Car V4H and V4M the .init callback is implemented using a
new function rcar_gen4_v4h_v4m_pcie_init() which calls the common
rcar_gen4_pcie_common_init() followed by R-Car V4H and V4M specific
hardware initialization. The hardware initialization sequence remains
unchanged.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: "Krzysztof Wilczyński" <kwilczynski@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
---
V2: Rename additional_common_init to init, reworked from previous patch
    PCI: dwc: rcar-gen4: Return error code from .additional_common_init
V3: No change
V4: Rebase on next-20260904
---
 drivers/pci/controller/dwc/pcie-rcar-gen4.c | 56 ++++++++++++---------
 1 file changed, 32 insertions(+), 24 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index 5a076aa3f4904..a19ebbab2f8c3 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -87,7 +87,7 @@ MODULE_FIRMWARE(RCAR_GEN4_PCIE_FIRMWARE_NAME);
 
 struct rcar_gen4_pcie;
 struct rcar_gen4_pcie_drvdata {
-	void (*additional_common_init)(struct rcar_gen4_pcie *rcar);
+	int (*init)(struct rcar_gen4_pcie *rcar);
 	int (*ltssm_control)(struct rcar_gen4_pcie *rcar, bool enable);
 	enum dw_pcie_device_mode mode;
 };
@@ -241,9 +241,6 @@ static int rcar_gen4_pcie_common_init(struct rcar_gen4_pcie *rcar)
 	reset_control_status(dw->core_rsts[DW_PCIE_PWR_RST].rstc);
 	fsleep(1000);
 
-	if (rcar->drvdata->additional_common_init)
-		rcar->drvdata->additional_common_init(rcar);
-
 	return 0;
 
 err_unprepare:
@@ -252,6 +249,31 @@ static int rcar_gen4_pcie_common_init(struct rcar_gen4_pcie *rcar)
 	return ret;
 }
 
+static int rcar_gen4_v4h_v4m_pcie_init(struct rcar_gen4_pcie *rcar)
+{
+	struct dw_pcie *dw = &rcar->dw;
+	u32 val;
+	int ret;
+
+	/* R-Car Gen4 common initialization. */
+	ret = rcar_gen4_pcie_common_init(rcar);
+	if (ret)
+		return ret;
+
+	/* R-Car V4H and V4M specific additional initialization. */
+	val = dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW);
+	val &= ~PORT_LANE_SKEW_INSERT_MASK;
+	if (dw->num_lanes < 4)
+		val |= BIT(6);
+	dw_pcie_writel_dbi(dw, PCIE_PORT_LANE_SKEW, val);
+
+	val = readl(rcar->base + PCIEPWRMNGCTRL);
+	val |= APP_CLK_REQ_N | APP_CLK_PM_EN;
+	writel(val, rcar->base + PCIEPWRMNGCTRL);
+
+	return 0;
+}
+
 static void rcar_gen4_pcie_common_deinit(struct rcar_gen4_pcie *rcar)
 {
 	struct dw_pcie *dw = &rcar->dw;
@@ -474,7 +496,7 @@ static int rcar_gen4_pcie_host_init(struct dw_pcie_rp *pp)
 
 	gpiod_set_value_cansleep(dw->pe_rst, 1);
 
-	ret = rcar_gen4_pcie_common_init(rcar);
+	ret = rcar->drvdata->init(rcar);
 	if (ret)
 		return ret;
 
@@ -543,7 +565,7 @@ static int rcar_gen4_pcie_ep_pre_init(struct dw_pcie_ep *ep)
 
 	writel(0, rcar->base + PCIEDMAINTSTSEN);
 
-	ret = rcar_gen4_pcie_common_init(rcar);
+	ret = rcar->drvdata->init(rcar);
 	if (ret)
 		return ret;
 
@@ -739,22 +761,6 @@ static int r8a779f0_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
 	return 0;
 }
 
-static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
-{
-	struct dw_pcie *dw = &rcar->dw;
-	u32 val;
-
-	val = dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW);
-	val &= ~PORT_LANE_SKEW_INSERT_MASK;
-	if (dw->num_lanes < 4)
-		val |= BIT(6);
-	dw_pcie_writel_dbi(dw, PCIE_PORT_LANE_SKEW, val);
-
-	val = readl(rcar->base + PCIEPWRMNGCTRL);
-	val |= APP_CLK_REQ_N | APP_CLK_PM_EN;
-	writel(val, rcar->base + PCIEPWRMNGCTRL);
-}
-
 static void rcar_gen4_pcie_phy_reg_update_bits(struct rcar_gen4_pcie *rcar,
 					       u32 offset, u32 mask, u32 val)
 {
@@ -906,23 +912,25 @@ static int rcar_gen4_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable
 }
 
 static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie = {
+	.init = rcar_gen4_pcie_common_init,
 	.ltssm_control = r8a779f0_pcie_ltssm_control,
 	.mode = DW_PCIE_RC_TYPE,
 };
 
 static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie_ep = {
+	.init = rcar_gen4_pcie_common_init,
 	.ltssm_control = r8a779f0_pcie_ltssm_control,
 	.mode = DW_PCIE_EP_TYPE,
 };
 
 static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie = {
-	.additional_common_init = rcar_gen4_pcie_additional_common_init,
+	.init = rcar_gen4_v4h_v4m_pcie_init,
 	.ltssm_control = rcar_gen4_pcie_ltssm_control,
 	.mode = DW_PCIE_RC_TYPE,
 };
 
 static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie_ep = {
-	.additional_common_init = rcar_gen4_pcie_additional_common_init,
+	.init = rcar_gen4_v4h_v4m_pcie_init,
 	.ltssm_control = rcar_gen4_pcie_ltssm_control,
 	.mode = DW_PCIE_EP_TYPE,
 };
-- 
2.53.0


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

* [PATCH v4 3/6] PCI: dwc: rcar-gen4: Add .deinit callback
  2026-09-05 21:26 [PATCH v4 0/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4 Marek Vasut
  2026-09-05 21:26 ` [PATCH v4 1/6] dt-bindings: PCI: rcar-gen4-pci-host: Add R-Car X5H PCIe4 compatible Marek Vasut
  2026-09-05 21:26 ` [PATCH v4 2/6] PCI: dwc: rcar-gen4: Rework rcar_gen4_pcie_drvdata .additional_common_init into .init Marek Vasut
@ 2026-09-05 21:26 ` Marek Vasut
  2026-09-05 21:38   ` sashiko-bot
  2026-09-05 21:26 ` [PATCH v4 4/6] PCI: dwc: rcar-gen4: Split .start_link into ltssm_control and speed_control Marek Vasut
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2026-09-05 21:26 UTC (permalink / raw)
  To: linux-pci
  Cc: Marek Vasut, Krzysztof Wilczyński, Bjorn Helgaas,
	Conor Dooley, Geert Uytterhoeven, Krzysztof Kozlowski,
	Lorenzo Pieralisi, Manivannan Sadhasivam, Rob Herring,
	Yoshihiro Shimoda, devicetree, linux-kernel, linux-renesas-soc

Add .deinit callback in preparation for R-Car Gen5 support. The
.deinit callback will be used to tear down the PHY on R-Car Gen5.
Thus far, it does what rcar_gen4_pcie_common_deinit() used to do
directly.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: "Krzysztof Wilczyński" <kwilczynski@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
---
V3: New patch
V4: Rebase on next-20260904
---
 drivers/pci/controller/dwc/pcie-rcar-gen4.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index a19ebbab2f8c3..04871ac11c348 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -88,6 +88,7 @@ MODULE_FIRMWARE(RCAR_GEN4_PCIE_FIRMWARE_NAME);
 struct rcar_gen4_pcie;
 struct rcar_gen4_pcie_drvdata {
 	int (*init)(struct rcar_gen4_pcie *rcar);
+	void (*deinit)(struct rcar_gen4_pcie *rcar);
 	int (*ltssm_control)(struct rcar_gen4_pcie *rcar, bool enable);
 	enum dw_pcie_device_mode mode;
 };
@@ -520,7 +521,7 @@ static int rcar_gen4_pcie_host_init(struct dw_pcie_rp *pp)
 	return 0;
 
 err:
-	rcar_gen4_pcie_common_deinit(rcar);
+	rcar->drvdata->deinit(rcar);
 	return ret;
 }
 
@@ -530,7 +531,7 @@ static void rcar_gen4_pcie_host_deinit(struct dw_pcie_rp *pp)
 	struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
 
 	gpiod_set_value_cansleep(dw->pe_rst, 1);
-	rcar_gen4_pcie_common_deinit(rcar);
+	rcar->drvdata->deinit(rcar);
 }
 
 static const struct dw_pcie_host_ops rcar_gen4_pcie_host_ops = {
@@ -580,7 +581,7 @@ static void rcar_gen4_pcie_ep_post_deinit(struct dw_pcie_ep *ep)
 	struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
 
 	writel(0, rcar->base + PCIEDMAINTSTSEN);
-	rcar_gen4_pcie_common_deinit(rcar);
+	rcar->drvdata->deinit(rcar);
 }
 
 static int rcar_gen4_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
@@ -913,24 +914,28 @@ static int rcar_gen4_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable
 
 static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie = {
 	.init = rcar_gen4_pcie_common_init,
+	.deinit = rcar_gen4_pcie_common_deinit,
 	.ltssm_control = r8a779f0_pcie_ltssm_control,
 	.mode = DW_PCIE_RC_TYPE,
 };
 
 static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie_ep = {
 	.init = rcar_gen4_pcie_common_init,
+	.deinit = rcar_gen4_pcie_common_deinit,
 	.ltssm_control = r8a779f0_pcie_ltssm_control,
 	.mode = DW_PCIE_EP_TYPE,
 };
 
 static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie = {
 	.init = rcar_gen4_v4h_v4m_pcie_init,
+	.deinit = rcar_gen4_pcie_common_deinit,
 	.ltssm_control = rcar_gen4_pcie_ltssm_control,
 	.mode = DW_PCIE_RC_TYPE,
 };
 
 static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie_ep = {
 	.init = rcar_gen4_v4h_v4m_pcie_init,
+	.deinit = rcar_gen4_pcie_common_deinit,
 	.ltssm_control = rcar_gen4_pcie_ltssm_control,
 	.mode = DW_PCIE_EP_TYPE,
 };
-- 
2.53.0


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

* [PATCH v4 4/6] PCI: dwc: rcar-gen4: Split .start_link into ltssm_control and speed_control
  2026-09-05 21:26 [PATCH v4 0/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4 Marek Vasut
                   ` (2 preceding siblings ...)
  2026-09-05 21:26 ` [PATCH v4 3/6] PCI: dwc: rcar-gen4: Add .deinit callback Marek Vasut
@ 2026-09-05 21:26 ` Marek Vasut
  2026-09-05 21:32   ` sashiko-bot
  2026-09-05 21:26 ` [PATCH v4 5/6] PCI: dwc: rcar-gen4: Handle PERST via reset subsystem Marek Vasut
  2026-09-05 21:26 ` [PATCH v4 6/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4 Marek Vasut
  5 siblings, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2026-09-05 21:26 UTC (permalink / raw)
  To: linux-pci
  Cc: Marek Vasut, Krzysztof Wilczyński, Bjorn Helgaas,
	Conor Dooley, Geert Uytterhoeven, Krzysztof Kozlowski,
	Lorenzo Pieralisi, Manivannan Sadhasivam, Rob Herring,
	Yoshihiro Shimoda, devicetree, linux-kernel, linux-renesas-soc

Introduce new .speed_control callback and implement it on R-Car Gen4.
The callback implements the second half of what is currently present
in rcar_gen4_pcie_start_link(), and rcar_gen4_pcie_start_link() does
call the .speed_control callback. This is a preparatory patch for
R-Car Gen5 support, where the .speed_control implementation is
different.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: "Krzysztof Wilczyński" <kwilczynski@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
---
V2: No change
V3: No change
V4: Rebase on next-20260904
---
 drivers/pci/controller/dwc/pcie-rcar-gen4.c | 39 ++++++++++++++-------
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index 04871ac11c348..c768a9c7b3b76 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -90,6 +90,7 @@ struct rcar_gen4_pcie_drvdata {
 	int (*init)(struct rcar_gen4_pcie *rcar);
 	void (*deinit)(struct rcar_gen4_pcie *rcar);
 	int (*ltssm_control)(struct rcar_gen4_pcie *rcar, bool enable);
+	int (*speed_control)(struct rcar_gen4_pcie *rcar);
 	enum dw_pcie_device_mode mode;
 };
 
@@ -141,20 +142,10 @@ static int rcar_gen4_pcie_speed_change(struct dw_pcie *dw)
 	return -ETIMEDOUT;
 }
 
-/*
- * Enable LTSSM of this controller and manually initiate the speed change.
- * Always return 0.
- */
-static int rcar_gen4_pcie_start_link(struct dw_pcie *dw)
+static int rcar_gen4_pcie_speed_control(struct rcar_gen4_pcie *rcar)
 {
-	struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
-	int i, changes, ret;
-
-	if (rcar->drvdata->ltssm_control) {
-		ret = rcar->drvdata->ltssm_control(rcar, true);
-		if (ret)
-			return ret;
-	}
+	struct dw_pcie *dw = &rcar->dw;
+	int i, changes;
 
 	/*
 	 * Require direct speed change with retrying here if the max_link_speed
@@ -178,6 +169,24 @@ static int rcar_gen4_pcie_start_link(struct dw_pcie *dw)
 	return 0;
 }
 
+/*
+ * Enable LTSSM of this controller and manually initiate the speed change.
+ * Always return 0.
+ */
+static int rcar_gen4_pcie_start_link(struct dw_pcie *dw)
+{
+	struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
+	int ret;
+
+	if (rcar->drvdata->ltssm_control) {
+		ret = rcar->drvdata->ltssm_control(rcar, true);
+		if (ret)
+			return ret;
+	}
+
+	return rcar->drvdata->speed_control(rcar);
+}
+
 static void rcar_gen4_pcie_stop_link(struct dw_pcie *dw)
 {
 	struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
@@ -916,6 +925,7 @@ static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie = {
 	.init = rcar_gen4_pcie_common_init,
 	.deinit = rcar_gen4_pcie_common_deinit,
 	.ltssm_control = r8a779f0_pcie_ltssm_control,
+	.speed_control = rcar_gen4_pcie_speed_control,
 	.mode = DW_PCIE_RC_TYPE,
 };
 
@@ -923,6 +933,7 @@ static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie_ep = {
 	.init = rcar_gen4_pcie_common_init,
 	.deinit = rcar_gen4_pcie_common_deinit,
 	.ltssm_control = r8a779f0_pcie_ltssm_control,
+	.speed_control = rcar_gen4_pcie_speed_control,
 	.mode = DW_PCIE_EP_TYPE,
 };
 
@@ -930,6 +941,7 @@ static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie = {
 	.init = rcar_gen4_v4h_v4m_pcie_init,
 	.deinit = rcar_gen4_pcie_common_deinit,
 	.ltssm_control = rcar_gen4_pcie_ltssm_control,
+	.speed_control = rcar_gen4_pcie_speed_control,
 	.mode = DW_PCIE_RC_TYPE,
 };
 
@@ -937,6 +949,7 @@ static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie_ep = {
 	.init = rcar_gen4_v4h_v4m_pcie_init,
 	.deinit = rcar_gen4_pcie_common_deinit,
 	.ltssm_control = rcar_gen4_pcie_ltssm_control,
+	.speed_control = rcar_gen4_pcie_speed_control,
 	.mode = DW_PCIE_EP_TYPE,
 };
 
-- 
2.53.0


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

* [PATCH v4 5/6] PCI: dwc: rcar-gen4: Handle PERST via reset subsystem
  2026-09-05 21:26 [PATCH v4 0/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4 Marek Vasut
                   ` (3 preceding siblings ...)
  2026-09-05 21:26 ` [PATCH v4 4/6] PCI: dwc: rcar-gen4: Split .start_link into ltssm_control and speed_control Marek Vasut
@ 2026-09-05 21:26 ` Marek Vasut
  2026-09-05 21:38   ` sashiko-bot
  2026-09-05 21:26 ` [PATCH v4 6/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4 Marek Vasut
  5 siblings, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2026-09-05 21:26 UTC (permalink / raw)
  To: linux-pci
  Cc: Marek Vasut, Krzysztof Wilczyński, Bjorn Helgaas,
	Conor Dooley, Geert Uytterhoeven, Krzysztof Kozlowski,
	Lorenzo Pieralisi, Manivannan Sadhasivam, Rob Herring,
	Yoshihiro Shimoda, devicetree, linux-kernel, linux-renesas-soc

Handle PERST via both GPIO and reset subsystem. On R-Car Gen4, the
PERST signal is operated as a GPIO, on R-Car Gen5 it might only be
accessible via SCMI reset via reset subsystem. Support both options.
This is a preparatory patch for R-Car Gen5 support.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: "Krzysztof Wilczyński" <kwilczynski@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
---
V2: - Use dev_err_probe() for perst in rcar_gen4_pcie_get_resources()
    - Use of_get_next_available_child() to obtain root port OF node
    - Switch to of_reset_control_get_optional_exclusive() to deal with
      R-Car Gen4, where the PERST is handled as GPIO instead of reset
    - Rename rcar_gen4_pcie_host_perst() to rcar_gen4_pcie_host_perst_assert()
      and use bool type for assert and deassert selection
    - Add missing reset_control_put() into rcar_gen4_pcie_probe() fail path
V3: - Handle controllers without root port DT node
    - Swap fail path order
V4: Rebase on next-20260904
---
 drivers/pci/controller/dwc/pcie-rcar-gen4.c | 44 +++++++++++++++++++--
 1 file changed, 40 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index c768a9c7b3b76..89472a4becc46 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -99,6 +99,7 @@ struct rcar_gen4_pcie {
 	void __iomem *base;
 	void __iomem *phy_base;
 	struct platform_device *pdev;
+	struct reset_control *perst;
 	const struct rcar_gen4_pcie_drvdata *drvdata;
 };
 #define to_rcar_gen4_pcie(_dw)	container_of(_dw, struct rcar_gen4_pcie, dw)
@@ -317,12 +318,27 @@ static void rcar_gen4_pcie_unprepare(struct rcar_gen4_pcie *rcar)
 
 static int rcar_gen4_pcie_get_resources(struct rcar_gen4_pcie *rcar)
 {
+	struct device *dev = rcar->dw.dev;
+	struct device_node *root_port;
+
 	rcar->phy_base = devm_platform_ioremap_resource_byname(rcar->pdev, "phy");
 	if (IS_ERR(rcar->phy_base))
 		return PTR_ERR(rcar->phy_base);
 
+	root_port = of_get_next_available_child(dev->of_node, NULL);
+	if (root_port) {
+		rcar->perst = of_reset_control_get_optional_exclusive(root_port, "perst");
+		of_node_put(root_port);
+		if (IS_ERR(rcar->perst))
+			return dev_err_probe(dev, PTR_ERR(rcar->perst), "Failed to get PERST#\n");
+	} else {
+		rcar->perst = NULL;
+	}
+
 	/* Renesas-specific registers */
 	rcar->base = devm_platform_ioremap_resource_byname(rcar->pdev, "app");
+	if (IS_ERR(rcar->base))
+		reset_control_put(rcar->perst);
 
 	return PTR_ERR_OR_ZERO(rcar->base);
 }
@@ -494,6 +510,22 @@ static int rcar_gen4_pcie_enable_device(struct pci_host_bridge *bridge,
 	return 0;
 }
 
+static void rcar_gen4_pcie_host_perst_assert(struct dw_pcie_rp *pp, bool assert)
+{
+	struct dw_pcie *dw = to_dw_pcie_from_pp(pp);
+	struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
+
+	gpiod_set_value_cansleep(dw->pe_rst, assert);
+
+	if (!rcar->perst)
+		return;
+
+	if (assert)
+		reset_control_assert(rcar->perst);
+	else
+		reset_control_deassert(rcar->perst);
+}
+
 /* Host mode */
 static int rcar_gen4_pcie_host_init(struct dw_pcie_rp *pp)
 {
@@ -504,7 +536,7 @@ static int rcar_gen4_pcie_host_init(struct dw_pcie_rp *pp)
 	if (pp->bridge)
 		pp->bridge->enable_device = rcar_gen4_pcie_enable_device;
 
-	gpiod_set_value_cansleep(dw->pe_rst, 1);
+	rcar_gen4_pcie_host_perst_assert(pp, true);
 
 	ret = rcar->drvdata->init(rcar);
 	if (ret)
@@ -525,7 +557,7 @@ static int rcar_gen4_pcie_host_init(struct dw_pcie_rp *pp)
 
 	msleep(PCIE_T_PVPERL_MS);	/* pe_rst requires 100msec delay */
 
-	gpiod_set_value_cansleep(dw->pe_rst, 0);
+	rcar_gen4_pcie_host_perst_assert(pp, false);
 
 	return 0;
 
@@ -539,7 +571,7 @@ static void rcar_gen4_pcie_host_deinit(struct dw_pcie_rp *pp)
 	struct dw_pcie *dw = to_dw_pcie_from_pp(pp);
 	struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
 
-	gpiod_set_value_cansleep(dw->pe_rst, 1);
+	rcar_gen4_pcie_host_perst_assert(pp, true);
 	rcar->drvdata->deinit(rcar);
 }
 
@@ -713,7 +745,7 @@ static int rcar_gen4_pcie_probe(struct platform_device *pdev)
 
 	err = rcar_gen4_pcie_prepare(rcar);
 	if (err)
-		return err;
+		goto err_prepare;
 
 	err = rcar_gen4_add_dw_pcie(rcar);
 	if (err)
@@ -724,6 +756,9 @@ static int rcar_gen4_pcie_probe(struct platform_device *pdev)
 err_unprepare:
 	rcar_gen4_pcie_unprepare(rcar);
 
+err_prepare:
+	reset_control_put(rcar->perst);
+
 	return err;
 }
 
@@ -747,6 +782,7 @@ static void rcar_gen4_pcie_remove(struct platform_device *pdev)
 
 	rcar_gen4_remove_dw_pcie(rcar);
 	rcar_gen4_pcie_unprepare(rcar);
+	reset_control_put(rcar->perst);
 }
 
 static int r8a779f0_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
-- 
2.53.0


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

* [PATCH v4 6/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4
  2026-09-05 21:26 [PATCH v4 0/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4 Marek Vasut
                   ` (4 preceding siblings ...)
  2026-09-05 21:26 ` [PATCH v4 5/6] PCI: dwc: rcar-gen4: Handle PERST via reset subsystem Marek Vasut
@ 2026-09-05 21:26 ` Marek Vasut
  2026-09-05 21:40   ` sashiko-bot
  5 siblings, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2026-09-05 21:26 UTC (permalink / raw)
  To: linux-pci
  Cc: Marek Vasut, Krzysztof Wilczyński, Bjorn Helgaas,
	Conor Dooley, Geert Uytterhoeven, Krzysztof Kozlowski,
	Lorenzo Pieralisi, Manivannan Sadhasivam, Rob Herring,
	Yoshihiro Shimoda, devicetree, linux-kernel, linux-renesas-soc

Add support for R8A78000 (R-Car X5H) PCIe4.

This driver previously supported R-Car Gen4 S4/V4H/V4M. PCIe features
of R-Car X5H PCIe4 are almost all the same.

The controller initialization sequence is slightly different and is
factored out into controller specific callbacks, in a manner similar
to previous R-Car Gen4 handling.

The controller does have a PHY attached to it, but the PHY is operated
by a separate PHY driver, the PHY driver instance binding is handled
in rcar_gen4_pcie_get_resources() and controlled in the aforementioned
controller specific callbacks.

The controller driver is deliberately using "renesas,rcar-gen5-pcie4"
DT compatible string to discern R-Car X5H PCIe4 controller supported
by this driver, from R-Car X5H PCIe6 controller which will most likely
use a separate driver.

The R-Car X5H PCIe4 controller embeds HDMA instead of EDMA embedded
in the R-Car Gen4 PCIe controller, "dw-edma" driver supports both
DMA variants.

Endpoint mode is currently not implemented for R-Car Gen5 PCIe4.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: "Krzysztof Wilczyński" <kwilczynski@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
---
V2: No change
V3: - Disable clock in case of PHY init failure in rcar_gen5_pcie_init()
    - Add .deinit callback and tear down Gen5 PHY in it
    - Use 16bit accessors on LNKCTL register
V4: Rebase on next-20260904
---
 drivers/pci/controller/dwc/pcie-rcar-gen4.c | 128 +++++++++++++++++++-
 1 file changed, 126 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index 89472a4becc46..5c0d5fd686cb5 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -19,6 +19,7 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/pci.h>
+#include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/reset.h>
@@ -36,6 +37,7 @@
 
 /* MSI Capability */
 #define MSICAP0			0x0050
+#define MSICAP0_MMESCAP_MASK	GENMASK(19, 17)
 #define MSICAP0_MSIE		BIT(16)
 
 /* PCIe Interrupt Status 0 */
@@ -74,6 +76,11 @@
 #define PCIEPWRMNGCTRL		0x0070
 #define APP_CLK_REQ_N		BIT(11)
 #define APP_CLK_PM_EN		BIT(10)
+#define APP_READY_ENTR_L23	BIT(6)
+#define APP_REQ_ENTR_L1		BIT(5)
+
+/* PCI Express capability */
+#define EXPCAP(x)		(0x0070 + (x))
 
 #define RCAR_NUM_SPEED_CHANGE_RETRIES	10
 #define RCAR_MAX_LINK_SPEED		4
@@ -98,6 +105,7 @@ struct rcar_gen4_pcie {
 	struct dw_pcie dw;
 	void __iomem *base;
 	void __iomem *phy_base;
+	struct phy *phy;
 	struct platform_device *pdev;
 	struct reset_control *perst;
 	const struct rcar_gen4_pcie_drvdata *drvdata;
@@ -170,6 +178,35 @@ static int rcar_gen4_pcie_speed_control(struct rcar_gen4_pcie *rcar)
 	return 0;
 }
 
+static int rcar_gen5_pcie_speed_control(struct rcar_gen4_pcie *rcar)
+{
+	struct dw_pcie *dw = &rcar->dw;
+	u32 lnkcap = dw_pcie_readl_dbi(dw, EXPCAP(PCI_EXP_LNKCAP));
+	u32 lnksta = dw_pcie_readw_dbi(dw, EXPCAP(PCI_EXP_LNKSTA));
+	u32 val, retries;
+
+	if ((lnksta & PCI_EXP_LNKSTA_CLS) == (lnkcap & PCI_EXP_LNKCAP_SLS))
+		return 0;
+
+	/* Retrain link */
+	val = dw_pcie_readw_dbi(dw, EXPCAP(PCI_EXP_LNKCTL));
+	val |= PCI_EXP_LNKCTL_RL;
+	dw_pcie_writew_dbi(dw, EXPCAP(PCI_EXP_LNKCTL), val);
+
+	/* Wait for link retrain */
+	for (retries = 0; retries <= 10; retries++) {
+		lnksta = dw_pcie_readw_dbi(dw, EXPCAP(PCI_EXP_LNKSTA));
+
+		/* Check retrain flag */
+		if (!(lnksta & PCI_EXP_LNKSTA_LT))
+			break;
+
+		usleep_range(1000, 1100);
+	}
+
+	return 0;
+}
+
 /*
  * Enable LTSSM of this controller and manually initiate the speed change.
  * Always return 0.
@@ -285,6 +322,49 @@ static int rcar_gen4_v4h_v4m_pcie_init(struct rcar_gen4_pcie *rcar)
 	return 0;
 }
 
+static int rcar_gen5_pcie_init(struct rcar_gen4_pcie *rcar)
+{
+	struct dw_pcie *dw = &rcar->dw;
+	int ret;
+	u32 val;
+
+	/* R-Car Gen4 and Gen5 common initialization. */
+	ret = rcar_gen4_pcie_common_init(rcar);
+	if (ret)
+		return ret;
+
+	/* R-Car Gen5 specific additional initialization. */
+	ret = phy_init(rcar->phy);
+	if (ret)
+		goto err_unprepare;
+
+	dw_pcie_dbi_ro_wr_en(dw);
+
+	val = dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW);
+	val &= ~PORT_LANE_SKEW_INSERT_MASK;
+	if (dw->num_lanes < 8)
+		val |= BIT(6);
+	dw_pcie_writel_dbi(dw, PCIE_PORT_LANE_SKEW, val);
+
+	val = dw_pcie_readl_dbi(dw, MSICAP0);
+	FIELD_MODIFY(MSICAP0_MMESCAP_MASK, &val, 4);
+	dw_pcie_writel_dbi(dw, MSICAP0, val);
+
+	dw_pcie_dbi_ro_wr_dis(dw);
+
+	val = readl(rcar->base + PCIEPWRMNGCTRL);
+	val |= APP_CLK_REQ_N | APP_CLK_PM_EN |
+	       APP_READY_ENTR_L23 | APP_REQ_ENTR_L1;
+	writel(val, rcar->base + PCIEPWRMNGCTRL);
+
+	return 0;
+
+err_unprepare:
+	clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, dw->core_clks);
+
+	return ret;
+}
+
 static void rcar_gen4_pcie_common_deinit(struct rcar_gen4_pcie *rcar)
 {
 	struct dw_pcie *dw = &rcar->dw;
@@ -293,6 +373,12 @@ static void rcar_gen4_pcie_common_deinit(struct rcar_gen4_pcie *rcar)
 	clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, dw->core_clks);
 }
 
+static void rcar_gen5_pcie_deinit(struct rcar_gen4_pcie *rcar)
+{
+	phy_exit(rcar->phy);
+	rcar_gen4_pcie_common_deinit(rcar);
+}
+
 static int rcar_gen4_pcie_prepare(struct rcar_gen4_pcie *rcar)
 {
 	struct device *dev = rcar->dw.dev;
@@ -322,8 +408,12 @@ static int rcar_gen4_pcie_get_resources(struct rcar_gen4_pcie *rcar)
 	struct device_node *root_port;
 
 	rcar->phy_base = devm_platform_ioremap_resource_byname(rcar->pdev, "phy");
-	if (IS_ERR(rcar->phy_base))
-		return PTR_ERR(rcar->phy_base);
+	if (IS_ERR(rcar->phy_base)) {
+		rcar->phy_base = NULL;
+		rcar->phy = devm_phy_get(dev, NULL);
+		if (IS_ERR(rcar->phy))
+			return PTR_ERR(rcar->phy);
+	}
 
 	root_port = of_get_next_available_child(dev->of_node, NULL);
 	if (root_port) {
@@ -807,6 +897,28 @@ static int r8a779f0_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
 	return 0;
 }
 
+static int rcar_gen5_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
+{
+	u32 val;
+
+	val = readl(rcar->base + PCIERSTCTRL1);
+	if (enable) {
+		val |= APP_LTSSM_ENABLE;
+		val &= ~APP_HOLD_PHY_RST;
+	} else {
+		val &= ~APP_LTSSM_ENABLE;
+		val |= APP_HOLD_PHY_RST;
+	}
+	writel(val, rcar->base + PCIERSTCTRL1);
+
+	if (enable)
+		phy_power_on(rcar->phy);
+	else
+		phy_power_off(rcar->phy);
+
+	return 0;
+}
+
 static void rcar_gen4_pcie_phy_reg_update_bits(struct rcar_gen4_pcie *rcar,
 					       u32 offset, u32 mask, u32 val)
 {
@@ -989,6 +1101,14 @@ static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie_ep = {
 	.mode = DW_PCIE_EP_TYPE,
 };
 
+static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen5_pcie = {
+	.init = rcar_gen5_pcie_init,
+	.deinit = rcar_gen5_pcie_deinit,
+	.ltssm_control = rcar_gen5_pcie_ltssm_control,
+	.speed_control = rcar_gen5_pcie_speed_control,
+	.mode = DW_PCIE_RC_TYPE,
+};
+
 static const struct of_device_id rcar_gen4_pcie_of_match[] = {
 	{
 		.compatible = "renesas,r8a779f0-pcie",
@@ -1006,6 +1126,10 @@ static const struct of_device_id rcar_gen4_pcie_of_match[] = {
 		.compatible = "renesas,rcar-gen4-pcie-ep",
 		.data = &drvdata_rcar_gen4_pcie_ep,
 	},
+	{
+		.compatible = "renesas,rcar-gen5-pcie4",
+		.data = &drvdata_rcar_gen5_pcie,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, rcar_gen4_pcie_of_match);
-- 
2.53.0


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

* Re: [PATCH v4 4/6] PCI: dwc: rcar-gen4: Split .start_link into ltssm_control and speed_control
  2026-09-05 21:26 ` [PATCH v4 4/6] PCI: dwc: rcar-gen4: Split .start_link into ltssm_control and speed_control Marek Vasut
@ 2026-09-05 21:32   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-09-05 21:32 UTC (permalink / raw)
  To: Marek Vasut; +Cc: devicetree, wsa+renesas, linux-pci, robh, conor+dt

> Introduce new .speed_control callback and implement it on R-Car Gen4.
> The callback implements the second half of what is currently present
> in rcar_gen4_pcie_start_link(), and rcar_gen4_pcie_start_link() does
> call the .speed_control callback. This is a preparatory patch for
> R-Car Gen5 support, where the .speed_control implementation is
> different.
> 
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260905212649.360498-1-marek.vasut+renesas@mailbox.org?part=4


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

* Re: [PATCH v4 2/6] PCI: dwc: rcar-gen4: Rework rcar_gen4_pcie_drvdata .additional_common_init into .init
  2026-09-05 21:26 ` [PATCH v4 2/6] PCI: dwc: rcar-gen4: Rework rcar_gen4_pcie_drvdata .additional_common_init into .init Marek Vasut
@ 2026-09-05 21:33   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-09-05 21:33 UTC (permalink / raw)
  To: Marek Vasut; +Cc: wsa+renesas, devicetree, robh, conor+dt, linux-pci

> Rework the current complicated initialization callchain that invokes
> host_init->common_init->additional_common_init() for host and
> ep_init->common_init->additional_common_init() for endpoint into
> simpler host_init->init() and ep_init->init() .
> 
> The init callback is now always implmented for all R-Car Gen4 SoCs,
> therefore there is no need to check whether the callback is not NULL.
> For R-Car S4 the .init callback is rcar_gen4_pcie_common_init(),
> for R-Car V4H and V4M the .init callback is implemented using a
> new function rcar_gen4_v4h_v4m_pcie_init() which calls the common
> rcar_gen4_pcie_common_init() followed by R-Car V4H and V4M specific
> hardware initialization. The hardware initialization sequence remains
> unchanged.
> 
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260905212649.360498-1-marek.vasut+renesas@mailbox.org?part=2


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

* Re: [PATCH v4 1/6] dt-bindings: PCI: rcar-gen4-pci-host: Add R-Car X5H PCIe4 compatible
  2026-09-05 21:26 ` [PATCH v4 1/6] dt-bindings: PCI: rcar-gen4-pci-host: Add R-Car X5H PCIe4 compatible Marek Vasut
@ 2026-09-05 21:36   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-09-05 21:36 UTC (permalink / raw)
  To: Marek Vasut; +Cc: devicetree, conor+dt, linux-pci, wsa+renesas, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Missing required `phys` property in device tree schema for R-Car Gen5 PCIe4, and incorrect property name referenced in commit message.
--

commit c9ec2af02aea699681c72cca90dd0320653d84c0
Author: Marek Vasut <marek.vasut+renesas@mailbox.org>

dt-bindings: PCI: rcar-gen4-pci-host: Add R-Car X5H PCIe4 compatible

Document bindings for R-Car X5H (R8A78000) PCIe4 host module.
The R-Car X5H PCIe4 controller no longer includes the PHY register range,
and the PHY is now a separate IP referenced via the 'phy' DT property.

> The R-Car X5H PCIe4 controller does no longer include PHY register
> range, the PHY is now a separate IP and referenced via the 'phy' DT
> property.

[Severity: Medium]
Is the property name in the commit message correct?

The standard property name for PHY references is phys, not phy. A property
named phy would be rejected by unevaluatedProperties: false during schema
validation if actually used.

> diff --git a/Documentation/devicetree/bindings/pci/rcar-gen4-pci-host.yaml b/Documentation/devicetree/bindings/pci/rcar-gen4-pci-host.yaml
> index 64f456c6a75a1..9767a52f3904e 100644
> --- a/Documentation/devicetree/bindings/pci/rcar-gen4-pci-host.yaml
> +++ b/Documentation/devicetree/bindings/pci/rcar-gen4-pci-host.yaml
[ ... ]
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: renesas,rcar-gen5-pcie4
> +    then:
> +      properties:
> +        reg:
> +          maxItems: 6
> +
> +        reg-names:
> +          items:
> +            - const: dbi
> +            - const: dbi2
> +            - const: atu
> +            - const: dma
> +            - const: app
> +            - const: config

[Severity: Medium]
Since the Gen5 PCIe4 controller removes the internal phy register region and
mandates an external PHY, should this conditional block also add the standard
phys property to a required list?

Without enforcing this requirement in the schema, incomplete device trees
missing the phys property will pass validation but cause runtime failures
when the driver attempts to retrieve the PHY using devm_phy_get(dev, NULL).

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260905212649.360498-1-marek.vasut+renesas@mailbox.org?part=1

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

* Re: [PATCH v4 3/6] PCI: dwc: rcar-gen4: Add .deinit callback
  2026-09-05 21:26 ` [PATCH v4 3/6] PCI: dwc: rcar-gen4: Add .deinit callback Marek Vasut
@ 2026-09-05 21:38   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-09-05 21:38 UTC (permalink / raw)
  To: Marek Vasut; +Cc: linux-pci, devicetree, conor+dt, wsa+renesas, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Missing early return or goto in error path of rcar_gen4_add_dw_pcie_ep().
--

commit 2da5cda33af2a170742ef5426b300f42371937c6
Author: Marek Vasut <marek.vasut+renesas@mailbox.org>

    PCI: dwc: rcar-gen4: Add .deinit callback
    
    Add .deinit callback in preparation for R-Car Gen5 support. The
    .deinit callback will be used to tear down the PHY on R-Car Gen5.

> diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> index a19ebbab2f8c3..04871ac11c348 100644
> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
[ ... ]
> @@ -580,7 +581,7 @@ static void rcar_gen4_pcie_ep_post_deinit(struct dw_pcie_ep *ep)
>  	struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
>  
>  	writel(0, rcar->base + PCIEDMAINTSTSEN);
> -	rcar_gen4_pcie_common_deinit(rcar);
> +	rcar->drvdata->deinit(rcar);
>  }

[Severity: High]
This isn't a bug introduced by this patch, but looking at
rcar_gen4_add_dw_pcie_ep() in this same file:

	ret = dw_pcie_ep_init_registers(ep);
	if (ret) {
		dev_err(dev, "Failed to initialize DWC endpoint registers\n");
		dw_pcie_ep_deinit(ep);
	}

	pci_epc_init_notify(ep->epc);

	return ret;

Should the error path for dw_pcie_ep_init_registers() return early or jump to
an error handler?

If dw_pcie_ep_init_registers() fails, the code falls through to
pci_epc_init_notify() despite having called dw_pcie_ep_deinit(). This causes
the Endpoint Controller (EPC) framework to spuriously notify registered
listeners (like EPF drivers) that the controller is successfully initialized
when it has actually failed and been de-initialized.

Could this lead to use-after-free or NULL-pointer dereferences in the EPF
drivers attempting to interact with the torn-down EPC?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260905212649.360498-1-marek.vasut+renesas@mailbox.org?part=3

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

* Re: [PATCH v4 5/6] PCI: dwc: rcar-gen4: Handle PERST via reset subsystem
  2026-09-05 21:26 ` [PATCH v4 5/6] PCI: dwc: rcar-gen4: Handle PERST via reset subsystem Marek Vasut
@ 2026-09-05 21:38   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-09-05 21:38 UTC (permalink / raw)
  To: Marek Vasut; +Cc: linux-pci, robh, conor+dt, devicetree, wsa+renesas

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] Calling pci_epc_init_notify() and returning an error after deinitializing endpoint resources in rcar_gen4_add_dw_pcie_ep().
- [Medium] Missing of_node_put() for msi_node obtained from of_msi_xlate() in rcar_gen4_pcie_host_msi_addr().
--

commit d2f3f23cb3b48c3f0a77ad5561fa549d03ac01cf
Author: Marek Vasut <marek.vasut+renesas@mailbox.org>

PCI: dwc: rcar-gen4: Handle PERST via reset subsystem

This patch supports handling the PERST signal via both GPIO and the reset
subsystem. This change prepares the driver for R-Car Gen5 support, where
PERST might only be accessible via an SCMI reset.

> diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> index c768a9c7b3b76..89472a4becc46 100644
> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c

[ ... ]

> @@ -494,6 +510,22 @@ static int rcar_gen4_pcie_enable_device(struct pci_host_bridge *bridge,
>  	return 0;
>  }
>  

[Severity: Medium]
This is a pre-existing issue, but does rcar_gen4_pcie_host_msi_addr()
leak the msi_node obtained from of_msi_xlate() on successful return?

drivers/pci/controller/dwc/pcie-rcar-gen4.c:rcar_gen4_pcie_host_msi_addr() {
    ...
	of_msi_xlate(dev, &msi_node, 0);
	if (!msi_node)
		return -ENODEV;
    ...
	*msi_addr = addr;
	return 0;
}

It appears the reference count of msi_node is never decremented on this return
path. Should we call of_node_put(msi_node) before returning?

[ ... ]

> @@ -747,6 +782,7 @@ static void rcar_gen4_pcie_remove(struct platform_device *pdev)
>  
>  	rcar_gen4_remove_dw_pcie(rcar);
>  	rcar_gen4_pcie_unprepare(rcar);
> +	reset_control_put(rcar->perst);
>  }

[Severity: High]
This isn't a bug introduced by this patch, but can rcar_gen4_add_dw_pcie_ep()
trigger an initialization notification on a deinitialized endpoint if
dw_pcie_ep_init_registers() fails?

drivers/pci/controller/dwc/pcie-rcar-gen4.c:rcar_gen4_add_dw_pcie_ep() {
    ...
	ret = dw_pcie_ep_init_registers(ep);
	if (ret) {
		dev_err(dev, "Failed to initialize DWC endpoint registers\n");
		dw_pcie_ep_deinit(ep);
	}

	pci_epc_init_notify(ep->epc);

	return ret;
}

Should there be a return statement inside the error handling block for
dw_pcie_ep_init_registers() to avoid calling pci_epc_init_notify()
on a deinitialized EPC?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260905212649.360498-1-marek.vasut+renesas@mailbox.org?part=5

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

* Re: [PATCH v4 6/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4
  2026-09-05 21:26 ` [PATCH v4 6/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4 Marek Vasut
@ 2026-09-05 21:40   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-09-05 21:40 UTC (permalink / raw)
  To: Marek Vasut; +Cc: robh, conor+dt, devicetree, wsa+renesas, linux-pci

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Incorrect PHY power-on sequencing and unchecked return value in rcar_gen5_pcie_ltssm_control().
- [High] The driver fails to configure the dw-edma core for HDMA on Gen5, breaking the commit's claim of HDMA support.
- [Medium] Missing assertion of DW_PCIE_PWR_RST on the error path of rcar_gen5_pcie_init() leaks hardware reset state.
--

commit 33f1bd3dbda597464a41cce7e19a3d761ff8b7c8
Author: Marek Vasut <marek.vasut+renesas@mailbox.org>

PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4

This patch adds support for the R8A78000 (R-Car X5H) PCIe4 controller,
differentiating it with the "renesas,rcar-gen5-pcie4" compatible string.
It implements Gen5-specific initialization, deinitialization, link speed,
and LTSSM control callbacks, and handles a separate PHY driver instance.

> The R-Car X5H PCIe4 controller embeds HDMA instead of EDMA embedded
> in the R-Car Gen4 PCIe controller, "dw-edma" driver supports both
> DMA variants.

[Severity: High]
Does the driver actually configure the dw-edma core for HDMA on Gen5 hardware?

Looking at rcar_gen4_pcie_alloc() elsewhere in the same file, the DMA mode
appears to be unconditionally hardcoded:

rcar_gen4_pcie_alloc() {
    ...
    rcar->dw.edma.mf = EDMA_MF_EDMA_UNROLL;
    ...
}

Since this mapping format is never updated for Gen5 controllers (e.g., to
EDMA_MF_HDMA_NATIVE or EDMA_MF_HDMA_COMPAT), will the dw-edma driver attempt
to program EDMA registers and descriptors instead of HDMA, causing DMA
operations to fail on Gen5?

> diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
[ ... ]
> @@ -285,6 +322,49 @@ static int rcar_gen4_v4h_v4m_pcie_init(struct rcar_gen4_pcie *rcar)
[ ... ]
> +static int rcar_gen5_pcie_init(struct rcar_gen4_pcie *rcar)
> +{
[ ... ]
> +	/* R-Car Gen4 and Gen5 common initialization. */
> +	ret = rcar_gen4_pcie_common_init(rcar);
> +	if (ret)
> +		return ret;
> +
> +	/* R-Car Gen5 specific additional initialization. */
> +	ret = phy_init(rcar->phy);
> +	if (ret)
> +		goto err_unprepare;
[ ... ]
> +err_unprepare:
> +	clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, dw->core_clks);
> +
> +	return ret;
> +}

[Severity: Medium]
Does this error path leak the hardware reset state?

rcar_gen4_pcie_common_init() successfully deasserts the DW_PCIE_PWR_RST
reset control before returning. If phy_init() subsequently fails, the
code jumps to err_unprepare, which disables the core clocks but leaves
the reset deasserted.

Should this error path also include a call to reset_control_assert() to
balance the state?

[ ... ]
> @@ -807,6 +897,28 @@ static int r8a779f0_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
[ ... ]
> +static int rcar_gen5_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
> +{
> +	u32 val;
> +
> +	val = readl(rcar->base + PCIERSTCTRL1);
> +	if (enable) {
> +		val |= APP_LTSSM_ENABLE;
> +		val &= ~APP_HOLD_PHY_RST;
> +	} else {
> +		val &= ~APP_LTSSM_ENABLE;
> +		val |= APP_HOLD_PHY_RST;
> +	}
> +	writel(val, rcar->base + PCIERSTCTRL1);
> +
> +	if (enable)
> +		phy_power_on(rcar->phy);
> +	else
> +		phy_power_off(rcar->phy);
> +
> +	return 0;
> +}

[Severity: High]
Does this sequence start link training before the PHY is properly powered
on and stabilized?

By writing APP_LTSSM_ENABLE to PCIERSTCTRL1 before calling phy_power_on(),
the controller might attempt training with an unpowered PHY.

Also, is it safe to ignore the return value of phy_power_on() here? If the
PHY fails to power on, the function still returns 0, leaving the controller
in a broken state with an unpowered PHY.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260905212649.360498-1-marek.vasut+renesas@mailbox.org?part=6

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

end of thread, other threads:[~2026-09-05 21:40 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-05 21:26 [PATCH v4 0/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4 Marek Vasut
2026-09-05 21:26 ` [PATCH v4 1/6] dt-bindings: PCI: rcar-gen4-pci-host: Add R-Car X5H PCIe4 compatible Marek Vasut
2026-09-05 21:36   ` sashiko-bot
2026-09-05 21:26 ` [PATCH v4 2/6] PCI: dwc: rcar-gen4: Rework rcar_gen4_pcie_drvdata .additional_common_init into .init Marek Vasut
2026-09-05 21:33   ` sashiko-bot
2026-09-05 21:26 ` [PATCH v4 3/6] PCI: dwc: rcar-gen4: Add .deinit callback Marek Vasut
2026-09-05 21:38   ` sashiko-bot
2026-09-05 21:26 ` [PATCH v4 4/6] PCI: dwc: rcar-gen4: Split .start_link into ltssm_control and speed_control Marek Vasut
2026-09-05 21:32   ` sashiko-bot
2026-09-05 21:26 ` [PATCH v4 5/6] PCI: dwc: rcar-gen4: Handle PERST via reset subsystem Marek Vasut
2026-09-05 21:38   ` sashiko-bot
2026-09-05 21:26 ` [PATCH v4 6/6] PCI: dwc: rcar-gen4: Add support for R-Car X5H PCIe4 Marek Vasut
2026-09-05 21:40   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox