* [PATCH v4 01/15] PCI: rzg3s-host: Fix reset handling in probe error path
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-01-29 21:41 ` [PATCH v4 02/15] PCI: renesas: rzg3s: Rework inbound window algorithm for multi-SoC support John Madieu
` (13 subsequent siblings)
14 siblings, 0 replies; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
Fix incorrect reset_control_bulk_deassert() call in the probe error
path. When unwinding from a failed pci_host_probe(), the configuration
resets should be asserted to restore the hardware to its initial state,
not deasserted again.
Fixes: 7ef502fb35b2 ("PCI: Add Renesas RZ/G3S host controller driver")
Reviewed-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: No changes
v3: No changes
v2: Collected Rb tag
drivers/pci/controller/pcie-rzg3s-host.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
index 5aa58638903f..58e78fc52913 100644
--- a/drivers/pci/controller/pcie-rzg3s-host.c
+++ b/drivers/pci/controller/pcie-rzg3s-host.c
@@ -1588,8 +1588,7 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
host_probe_teardown:
rzg3s_pcie_teardown_irqdomain(host);
- reset_control_bulk_deassert(host->data->num_cfg_resets,
- host->cfg_resets);
+ reset_control_bulk_assert(host->data->num_cfg_resets, host->cfg_resets);
rpm_put:
pm_runtime_put_sync(dev);
rpm_disable:
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v4 02/15] PCI: renesas: rzg3s: Rework inbound window algorithm for multi-SoC support
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
2026-01-29 21:41 ` [PATCH v4 01/15] PCI: rzg3s-host: Fix reset handling in probe error path John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-01-30 13:52 ` Claudiu Beznea
2026-01-29 21:41 ` [PATCH v4 03/15] clk: renesas: rzv2h-cpg: Add support for init_{off|asserted} clocks/resets John Madieu
` (12 subsequent siblings)
14 siblings, 1 reply; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
The existing inbound window configuration algorithm has two issues that
prevent proper operation on RZ/G3E:
1. Over-mapping: Using roundup_pow_of_two() on the remaining region size
can result in windows that extend beyond the intended memory region.
2. Alignment violation: Addresses are only aligned to 4K regardless of
the actual window size. According to the RZ/G3S HW manual (Rev.1.10,
section 34.3.7.6) and RZ/G3E HW manual (Rev.1.15, section 6.6.7.6),
bit carry must not occur when adding AXI Window Base and AXI Window
Mask registers. This effectively requires the base address to be
aligned to the window size.
While RZ/G3S tolerates these issues, RZ/G3E strictly enforces these
constraints and requires precise window boundaries with properly aligned
addresses.
Rework the algorithm to properly handle arbitrary region sizes and
alignment constraints by splitting non-power-of-2 regions into multiple
windows. The new approach iteratively selects the largest power-of-2
size that:
- Fits within the remaining region (__fls of remaining size)
- Does not exceed the natural alignment of the CPU address (__ffs)
- Does not exceed the natural alignment of the PCI address (__ffs)
This ensures windows never over-map beyond the intended region and
satisfies the hardware requirement that base address + mask must not
cause bit carry, while maintaining the 4K * 2^N byte window size
constraint.
The reworked algorithm is required for RZ/G3E support and remains
fully compatible with RZ/G3S.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: No changes
v3: No changes
v2: New patch
drivers/pci/controller/pcie-rzg3s-host.c | 53 ++++++++++++++----------
1 file changed, 31 insertions(+), 22 deletions(-)
diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
index 58e78fc52913..7b42f9415d3a 100644
--- a/drivers/pci/controller/pcie-rzg3s-host.c
+++ b/drivers/pci/controller/pcie-rzg3s-host.c
@@ -1270,50 +1270,59 @@ static int rzg3s_pcie_set_inbound_windows(struct rzg3s_pcie_host *host,
u64 pci_addr = entry->res->start - entry->offset;
u64 cpu_addr = entry->res->start;
u64 cpu_end = entry->res->end;
- u64 size_id = 0;
int id = *index;
u64 size;
- while (cpu_addr < cpu_end) {
+ /*
+ * According to the RZ/G3S HW manual (Rev.1.10, section 34.3.7.6) and
+ * RZ/G3E HW manual (Rev.1.15, section 6.6.7.6):
+ * - Each window must be a single memory size of power of two
+ * - Mask registers must be set to (2^N - 1)
+ * - Bit carry must not occur when adding base and mask registers,
+ * meaning the base address must be aligned to the window size
+ *
+ * Split non-power-of-2 regions into multiple windows to satisfy
+ * these constraints without over-mapping.
+ */
+ while (cpu_addr <= cpu_end) {
+ u64 remaining_size = cpu_end - cpu_addr + 1;
+ u64 align_limit;
+
if (id >= RZG3S_MAX_WINDOWS)
return dev_err_probe(host->dev, -ENOSPC,
"Failed to map inbound window for resource (%s)\n",
entry->res->name);
- size = resource_size(entry->res) - size_id;
+ /* Start with largest power-of-two that fits in remaining size */
+ size = 1ULL << __fls(remaining_size);
/*
- * According to the RZ/G3S HW manual (Rev.1.10,
- * section 34.3.1.71 AXI Window Mask (Lower) Registers) the min
- * size is 4K.
+ * The "no bit carry" rule requires base addresses to be
+ * aligned to the window size. Find the maximum window size
+ * that both addresses can support based on their natural
+ * alignment (lowest set bit).
*/
- size = max(size, SZ_4K);
+ align_limit = min(cpu_addr ? (1ULL << __ffs(cpu_addr)) : ~0ULL,
+ pci_addr ? (1ULL << __ffs(pci_addr)) : ~0ULL);
+
+ size = min(size, align_limit);
/*
- * According the RZ/G3S HW manual (Rev.1.10, sections:
- * - 34.3.1.69 AXI Window Base (Lower) Registers
- * - 34.3.1.71 AXI Window Mask (Lower) Registers
- * - 34.3.1.73 AXI Destination (Lower) Registers)
- * the CPU addr, PCIe addr, size should be 4K aligned and be a
- * power of 2.
+ * Minimum window size is 4KB.
+ * See RZ/G3S HW manual (Rev.1.10, section 34.3.1.71) and
+ * RZ/G3E HW manual (Rev.1.15, section 6.6.4.1.3.(74)).
*/
- size = ALIGN(size, SZ_4K);
- size = roundup_pow_of_two(size);
-
- cpu_addr = ALIGN(cpu_addr, SZ_4K);
- pci_addr = ALIGN(pci_addr, SZ_4K);
+ size = max(size, SZ_4K);
/*
- * According to the RZ/G3S HW manual (Rev.1.10, section
- * 34.3.1.71 AXI Window Mask (Lower) Registers) HW expects first
- * 12 LSB bits to be 0xfff. Subtract 1 from size for this.
+ * HW expects (size - 1) for mask register, e.g., a 4KB window
+ * (0x1000) requires mask value 0xFFF.
*/
rzg3s_pcie_set_inbound_window(host, cpu_addr, pci_addr,
size - 1, id);
pci_addr += size;
cpu_addr += size;
- size_id = size;
id++;
}
*index = id;
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v4 02/15] PCI: renesas: rzg3s: Rework inbound window algorithm for multi-SoC support
2026-01-29 21:41 ` [PATCH v4 02/15] PCI: renesas: rzg3s: Rework inbound window algorithm for multi-SoC support John Madieu
@ 2026-01-30 13:52 ` Claudiu Beznea
2026-01-30 20:14 ` John Madieu
0 siblings, 1 reply; 27+ messages in thread
From: Claudiu Beznea @ 2026-01-30 13:52 UTC (permalink / raw)
To: John Madieu, claudiu.beznea.uj, lpieralisi, kwilczynski, mani,
geert+renesas, krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu
Hi, John,
On 1/29/26 23:41, John Madieu wrote:
> The existing inbound window configuration algorithm has two issues that
> prevent proper operation on RZ/G3E:
>
> 1. Over-mapping: Using roundup_pow_of_two() on the remaining region size
> can result in windows that extend beyond the intended memory region.
>
> 2. Alignment violation: Addresses are only aligned to 4K regardless of
> the actual window size. According to the RZ/G3S HW manual (Rev.1.10,
> section 34.3.7.6) and RZ/G3E HW manual (Rev.1.15, section 6.6.7.6),
Section 34.3.7.6 does not exist on RZ/G3S Rev.1.10 neither on later revisions. I
suppose this had to be 34.6.6, point 7.
> bit carry must not occur when adding AXI Window Base and AXI Window
> Mask registers. This effectively requires the base address to be
> aligned to the window size.
>
> While RZ/G3S tolerates these issues,
I don't think it tolerates this but I haven't tested more than one window.
> RZ/G3E strictly enforces these
> constraints and requires precise window boundaries with properly aligned
> addresses.
>
> Rework the algorithm to properly handle arbitrary region sizes and
> alignment constraints by splitting non-power-of-2 regions into multiple
> windows. The new approach iteratively selects the largest power-of-2
> size that:
> - Fits within the remaining region (__fls of remaining size)
> - Does not exceed the natural alignment of the CPU address (__ffs)
> - Does not exceed the natural alignment of the PCI address (__ffs)
>
> This ensures windows never over-map beyond the intended region and
> satisfies the hardware requirement that base address + mask must not
> cause bit carry, while maintaining the 4K * 2^N byte window size
> constraint.
>
> The reworked algorithm is required for RZ/G3E support and remains
> fully compatible with RZ/G3S.
>
> Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> ---
>
> Changes:
>
> v4: No changes
> v3: No changes
> v2: New patch
>
> drivers/pci/controller/pcie-rzg3s-host.c | 53 ++++++++++++++----------
> 1 file changed, 31 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
> index 58e78fc52913..7b42f9415d3a 100644
> --- a/drivers/pci/controller/pcie-rzg3s-host.c
> +++ b/drivers/pci/controller/pcie-rzg3s-host.c
> @@ -1270,50 +1270,59 @@ static int rzg3s_pcie_set_inbound_windows(struct rzg3s_pcie_host *host,
> u64 pci_addr = entry->res->start - entry->offset;
> u64 cpu_addr = entry->res->start;
> u64 cpu_end = entry->res->end;
> - u64 size_id = 0;
> int id = *index;
> u64 size;
>
> - while (cpu_addr < cpu_end) {
> + /*
> + * According to the RZ/G3S HW manual (Rev.1.10, section 34.3.7.6)
s/34.3.7.6/34.6.6.7 or 34.6.6 point 7
> and
> + * RZ/G3E HW manual (Rev.1.15, section 6.6.7.6):
> + * - Each window must be a single memory size of power of two
> + * - Mask registers must be set to (2^N - 1)
> + * - Bit carry must not occur when adding base and mask registers,
> + * meaning the base address must be aligned to the window size
> + *
> + * Split non-power-of-2 regions into multiple windows to satisfy
> + * these constraints without over-mapping.
> + */
> + while (cpu_addr <= cpu_end) {
> + u64 remaining_size = cpu_end - cpu_addr + 1;
> + u64 align_limit;
> +
> if (id >= RZG3S_MAX_WINDOWS)
> return dev_err_probe(host->dev, -ENOSPC,
> "Failed to map inbound window for resource (%s)\n",
> entry->res->name);
>
> - size = resource_size(entry->res) - size_id;
> + /* Start with largest power-of-two that fits in remaining size */
> + size = 1ULL << __fls(remaining_size);
>
> /*
> - * According to the RZ/G3S HW manual (Rev.1.10,
> - * section 34.3.1.71 AXI Window Mask (Lower) Registers) the min
> - * size is 4K.
> + * The "no bit carry" rule requires base addresses to be
> + * aligned to the window size. Find the maximum window size
> + * that both addresses can support based on their natural
> + * alignment (lowest set bit).
> */
> - size = max(size, SZ_4K);
> + align_limit = min(cpu_addr ? (1ULL << __ffs(cpu_addr)) : ~0ULL,
> + pci_addr ? (1ULL << __ffs(pci_addr)) : ~0ULL);
> +
> + size = min(size, align_limit);
>
> /*
> - * According the RZ/G3S HW manual (Rev.1.10, sections:
> - * - 34.3.1.69 AXI Window Base (Lower) Registers
> - * - 34.3.1.71 AXI Window Mask (Lower) Registers
> - * - 34.3.1.73 AXI Destination (Lower) Registers)
> - * the CPU addr, PCIe addr, size should be 4K aligned and be a
> - * power of 2.
> + * Minimum window size is 4KB.
> + * See RZ/G3S HW manual (Rev.1.10, section 34.3.1.71) and
> + * RZ/G3E HW manual (Rev.1.15, section 6.6.4.1.3.(74)).
> */
> - size = ALIGN(size, SZ_4K);
> - size = roundup_pow_of_two(size);
> -
> - cpu_addr = ALIGN(cpu_addr, SZ_4K);
> - pci_addr = ALIGN(pci_addr, SZ_4K);
> + size = max(size, SZ_4K);
>
> /*
> - * According to the RZ/G3S HW manual (Rev.1.10, section
> - * 34.3.1.71 AXI Window Mask (Lower) Registers) HW expects first
> - * 12 LSB bits to be 0xfff. Subtract 1 from size for this.
> + * HW expects (size - 1) for mask register, e.g., a 4KB window
> + * (0x1000) requires mask value 0xFFF.
This change is unrelated for this patch. It can be dropped.
With those addressed:
Reviewed-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
> */
> rzg3s_pcie_set_inbound_window(host, cpu_addr, pci_addr,
> size - 1, id);
>
> pci_addr += size;
> cpu_addr += size;
> - size_id = size;
> id++;
> }
> *index = id;
^ permalink raw reply [flat|nested] 27+ messages in thread* RE: [PATCH v4 02/15] PCI: renesas: rzg3s: Rework inbound window algorithm for multi-SoC support
2026-01-30 13:52 ` Claudiu Beznea
@ 2026-01-30 20:14 ` John Madieu
0 siblings, 0 replies; 27+ messages in thread
From: John Madieu @ 2026-01-30 20:14 UTC (permalink / raw)
To: Claudiu.Beznea, Claudiu Beznea, lpieralisi@kernel.org,
kwilczynski@kernel.org, mani@kernel.org, geert+renesas@glider.be,
krzk+dt@kernel.org
Cc: robh@kernel.org, bhelgaas@google.com, conor+dt@kernel.org,
magnus.damm, Biju Das, linux-pci@vger.kernel.org,
linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org,
linux-clk@vger.kernel.org, john.madieu@gmail.com
Hi Claudiu,
Thanks for your review.
> -----Original Message-----
> From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
> Sent: Friday, January 30, 2026 2:53 PM
> To: John Madieu <john.madieu.xa@bp.renesas.com>; Claudiu Beznea
> <claudiu.beznea.uj@bp.renesas.com>; lpieralisi@kernel.org;
> kwilczynski@kernel.org; mani@kernel.org; geert+renesas@glider.be;
> krzk+dt@kernel.org
> Cc: robh@kernel.org; bhelgaas@google.com; conor+dt@kernel.org; magnus.damm
> <magnus.damm@gmail.com>; Biju Das <biju.das.jz@bp.renesas.com>; linux-
> pci@vger.kernel.org; linux-renesas-soc@vger.kernel.org;
> devicetree@vger.kernel.org; linux-clk@vger.kernel.org;
> john.madieu@gmail.com
> Subject: Re: [PATCH v4 02/15] PCI: renesas: rzg3s: Rework inbound window
> algorithm for multi-SoC support
>
> Hi, John,
>
> On 1/29/26 23:41, John Madieu wrote:
> > The existing inbound window configuration algorithm has two issues
> > that prevent proper operation on RZ/G3E:
> >
> > 1. Over-mapping: Using roundup_pow_of_two() on the remaining region size
> > can result in windows that extend beyond the intended memory region.
> >
> > 2. Alignment violation: Addresses are only aligned to 4K regardless of
> > the actual window size. According to the RZ/G3S HW manual (Rev.1.10,
> > section 34.3.7.6) and RZ/G3E HW manual (Rev.1.15, section
> > 6.6.7.6),
>
> Section 34.3.7.6 does not exist on RZ/G3S Rev.1.10 neither on later
> revisions. I suppose this had to be 34.6.6, point 7.
>
> > bit carry must not occur when adding AXI Window Base and AXI Window
> > Mask registers. This effectively requires the base address to be
> > aligned to the window size.
> >
> > While RZ/G3S tolerates these issues,
>
> I don't think it tolerates this but I haven't tested more than one window.
>
> > RZ/G3E strictly enforces these
> > constraints and requires precise window boundaries with properly
> > aligned addresses.
> >
> > Rework the algorithm to properly handle arbitrary region sizes and
> > alignment constraints by splitting non-power-of-2 regions into
> > multiple windows. The new approach iteratively selects the largest
> > power-of-2 size that:
> > - Fits within the remaining region (__fls of remaining size)
> > - Does not exceed the natural alignment of the CPU address (__ffs)
> > - Does not exceed the natural alignment of the PCI address (__ffs)
> >
> > This ensures windows never over-map beyond the intended region and
> > satisfies the hardware requirement that base address + mask must not
> > cause bit carry, while maintaining the 4K * 2^N byte window size
> > constraint.
> >
> > The reworked algorithm is required for RZ/G3E support and remains
> > fully compatible with RZ/G3S.
> >
> > Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> > ---
> >
> > Changes:
> >
> > v4: No changes
> > v3: No changes
> > v2: New patch
> >
> > drivers/pci/controller/pcie-rzg3s-host.c | 53 ++++++++++++++----------
> > 1 file changed, 31 insertions(+), 22 deletions(-)
> >
> > diff --git a/drivers/pci/controller/pcie-rzg3s-host.c
> > b/drivers/pci/controller/pcie-rzg3s-host.c
> > index 58e78fc52913..7b42f9415d3a 100644
> > --- a/drivers/pci/controller/pcie-rzg3s-host.c
> > +++ b/drivers/pci/controller/pcie-rzg3s-host.c
> > @@ -1270,50 +1270,59 @@ static int rzg3s_pcie_set_inbound_windows(struct
> rzg3s_pcie_host *host,
> > u64 pci_addr = entry->res->start - entry->offset;
> > u64 cpu_addr = entry->res->start;
> > u64 cpu_end = entry->res->end;
> > - u64 size_id = 0;
> > int id = *index;
> > u64 size;
> >
> > - while (cpu_addr < cpu_end) {
> > + /*
> > + * According to the RZ/G3S HW manual (Rev.1.10, section 34.3.7.6)
>
> s/34.3.7.6/34.6.6.7 or 34.6.6 point 7
>
Noted for v4.
>
> > and
> > + * RZ/G3E HW manual (Rev.1.15, section 6.6.7.6):
> > + * - Each window must be a single memory size of power of two
> > + * - Mask registers must be set to (2^N - 1)
> > + * - Bit carry must not occur when adding base and mask registers,
> > + * meaning the base address must be aligned to the window size
> > + *
> > + * Split non-power-of-2 regions into multiple windows to satisfy
> > + * these constraints without over-mapping.
> > + */
> > + while (cpu_addr <= cpu_end) {
> > + u64 remaining_size = cpu_end - cpu_addr + 1;
> > + u64 align_limit;
> > +
> > if (id >= RZG3S_MAX_WINDOWS)
> > return dev_err_probe(host->dev, -ENOSPC,
> > "Failed to map inbound window for
> resource (%s)\n",
> > entry->res->name);
> >
> > - size = resource_size(entry->res) - size_id;
> > + /* Start with largest power-of-two that fits in remaining size
> */
> > + size = 1ULL << __fls(remaining_size);
> >
> > /*
> > - * According to the RZ/G3S HW manual (Rev.1.10,
> > - * section 34.3.1.71 AXI Window Mask (Lower) Registers) the
> min
> > - * size is 4K.
> > + * The "no bit carry" rule requires base addresses to be
> > + * aligned to the window size. Find the maximum window size
> > + * that both addresses can support based on their natural
> > + * alignment (lowest set bit).
> > */
> > - size = max(size, SZ_4K);
> > + align_limit = min(cpu_addr ? (1ULL << __ffs(cpu_addr)) :
> ~0ULL,
> > + pci_addr ? (1ULL << __ffs(pci_addr)) : ~0ULL);
> > +
> > + size = min(size, align_limit);
> >
> > /*
> > - * According the RZ/G3S HW manual (Rev.1.10, sections:
> > - * - 34.3.1.69 AXI Window Base (Lower) Registers
> > - * - 34.3.1.71 AXI Window Mask (Lower) Registers
> > - * - 34.3.1.73 AXI Destination (Lower) Registers)
> > - * the CPU addr, PCIe addr, size should be 4K aligned and be a
> > - * power of 2.
> > + * Minimum window size is 4KB.
> > + * See RZ/G3S HW manual (Rev.1.10, section 34.3.1.71) and
> > + * RZ/G3E HW manual (Rev.1.15, section 6.6.4.1.3.(74)).
> > */
> > - size = ALIGN(size, SZ_4K);
> > - size = roundup_pow_of_two(size);
> > -
> > - cpu_addr = ALIGN(cpu_addr, SZ_4K);
> > - pci_addr = ALIGN(pci_addr, SZ_4K);
> > + size = max(size, SZ_4K);
> >
> > /*
> > - * According to the RZ/G3S HW manual (Rev.1.10, section
> > - * 34.3.1.71 AXI Window Mask (Lower) Registers) HW expects
> first
> > - * 12 LSB bits to be 0xfff. Subtract 1 from size for this.
> > + * HW expects (size - 1) for mask register, e.g., a 4KB window
> > + * (0x1000) requires mask value 0xFFF.
>
> This change is unrelated for this patch. It can be dropped.
>
Will drop it in v5.
Regards,
John
> With those addressed:
>
> Reviewed-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
>
> > */
> > rzg3s_pcie_set_inbound_window(host, cpu_addr, pci_addr,
> > size - 1, id);
> >
> > pci_addr += size;
> > cpu_addr += size;
> > - size_id = size;
> > id++;
> > }
> > *index = id;
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v4 03/15] clk: renesas: rzv2h-cpg: Add support for init_{off|asserted} clocks/resets
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
2026-01-29 21:41 ` [PATCH v4 01/15] PCI: rzg3s-host: Fix reset handling in probe error path John Madieu
2026-01-29 21:41 ` [PATCH v4 02/15] PCI: renesas: rzg3s: Rework inbound window algorithm for multi-SoC support John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-01-29 21:41 ` [PATCH v4 04/15] clk: renesas: r9a09g047: Add PCIe clocks and reset John Madieu
` (11 subsequent siblings)
14 siblings, 0 replies; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
Some peripherals may be left enabled by the bootloader but should be
explicitly disabled by the kernel to ensure a known initial state.
This is particularly important for PCIe which requires proper
initialization sequencing.
Add new macros DEF_MOD_INIT_OFF() and DEF_RST_INIT_ASSERTED() to declare
module clocks that should be turned off and resets that should be
asserted during CPG probe if found in the opposite state.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: No changes
v3:
- Fixed potential unitialized rcdev crash
- Removed duplicated message
v2:
- Added reset-specific assert on probe
- Removed Rb tag from Geert due to previous point
drivers/clk/renesas/rzv2h-cpg.c | 24 ++++++++++++++++++++++-
drivers/clk/renesas/rzv2h-cpg.h | 34 +++++++++++++++++++++++++--------
2 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c
index 3f6299b9fec0..8e45f6f48e29 100644
--- a/drivers/clk/renesas/rzv2h-cpg.c
+++ b/drivers/clk/renesas/rzv2h-cpg.c
@@ -1337,6 +1337,13 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod,
spin_unlock_irqrestore(&priv->rmw_lock, flags);
}
+ /*
+ * Turn off clocks marked with init_off flag if they were left
+ * enabled by the bootloader. This ensures a known initial state.
+ */
+ if (mod->init_off && rzv2h_mod_clock_is_enabled(&clock->hw))
+ rzv2h_mod_clock_endisable(&clock->hw, false);
+
return;
fail:
@@ -1585,7 +1592,7 @@ static int __init rzv2h_cpg_probe(struct platform_device *pdev)
struct rzv2h_cpg_priv *priv;
unsigned int nclks, i;
struct clk **clks;
- int error;
+ int error, ret;
info = of_device_get_match_data(dev);
@@ -1635,6 +1642,21 @@ static int __init rzv2h_cpg_probe(struct platform_device *pdev)
for (i = 0; i < info->num_mod_clks; i++)
rzv2h_cpg_register_mod_clk(&info->mod_clks[i], priv);
+ /*
+ * Assert resets marked with init_asserted flag if they were left
+ * deasserted by the bootloader. This ensures a known initial state.
+ */
+ priv->rcdev.dev = dev;
+ for (i = 0; i < info->num_resets; i++) {
+ if (!info->resets[i].init_asserted)
+ continue;
+
+ /* Check if reset is currently deasserted (status == 0) */
+ ret = rzv2h_cpg_status(&priv->rcdev, i);
+ if (ret == 0)
+ rzv2h_cpg_assert(&priv->rcdev, i);
+ }
+
error = of_clk_add_provider(np, rzv2h_cpg_clk_src_twocell_get, priv);
if (error)
return error;
diff --git a/drivers/clk/renesas/rzv2h-cpg.h b/drivers/clk/renesas/rzv2h-cpg.h
index dc957bdaf5e9..927009431a73 100644
--- a/drivers/clk/renesas/rzv2h-cpg.h
+++ b/drivers/clk/renesas/rzv2h-cpg.h
@@ -250,6 +250,7 @@ enum clk_types {
* @parent: id of parent clock
* @critical: flag to indicate the clock is critical
* @no_pm: flag to indicate PM is not supported
+ * @init_off: flag to indicate the clock should be turned off during probe
* @on_index: control register index
* @on_bit: ON bit
* @mon_index: monitor register index
@@ -262,6 +263,7 @@ struct rzv2h_mod_clk {
u16 parent;
bool critical;
bool no_pm;
+ bool init_off;
u8 on_index;
u8 on_bit;
s8 mon_index;
@@ -269,14 +271,15 @@ struct rzv2h_mod_clk {
s8 ext_clk_mux_index;
};
-#define DEF_MOD_BASE(_name, _mstop, _parent, _critical, _no_pm, _onindex, \
- _onbit, _monindex, _monbit, _ext_clk_mux_index) \
+#define DEF_MOD_BASE(_name, _mstop, _parent, _critical, _no_pm, _init_off, \
+ _onindex, _onbit, _monindex, _monbit, _ext_clk_mux_index) \
{ \
.name = (_name), \
.mstop_data = (_mstop), \
.parent = (_parent), \
.critical = (_critical), \
.no_pm = (_no_pm), \
+ .init_off = (_init_off), \
.on_index = (_onindex), \
.on_bit = (_onbit), \
.mon_index = (_monindex), \
@@ -285,17 +288,20 @@ struct rzv2h_mod_clk {
}
#define DEF_MOD(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop) \
- DEF_MOD_BASE(_name, _mstop, _parent, false, false, _onindex, _onbit, _monindex, _monbit, -1)
+ DEF_MOD_BASE(_name, _mstop, _parent, false, false, false, _onindex, _onbit, _monindex, _monbit, -1)
#define DEF_MOD_CRITICAL(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop) \
- DEF_MOD_BASE(_name, _mstop, _parent, true, false, _onindex, _onbit, _monindex, _monbit, -1)
+ DEF_MOD_BASE(_name, _mstop, _parent, true, false, false, _onindex, _onbit, _monindex, _monbit, -1)
+
+#define DEF_MOD_INIT_OFF(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop) \
+ DEF_MOD_BASE(_name, _mstop, _parent, false, false, true, _onindex, _onbit, _monindex, _monbit, -1)
#define DEF_MOD_NO_PM(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop) \
- DEF_MOD_BASE(_name, _mstop, _parent, false, true, _onindex, _onbit, _monindex, _monbit, -1)
+ DEF_MOD_BASE(_name, _mstop, _parent, false, true, false, _onindex, _onbit, _monindex, _monbit, -1)
#define DEF_MOD_MUX_EXTERNAL(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop, \
_ext_clk_mux_index) \
- DEF_MOD_BASE(_name, _mstop, _parent, false, false, _onindex, _onbit, _monindex, _monbit, \
+ DEF_MOD_BASE(_name, _mstop, _parent, false, false, false, _onindex, _onbit, _monindex, _monbit, \
_ext_clk_mux_index)
/**
@@ -305,24 +311,36 @@ struct rzv2h_mod_clk {
* @reset_bit: reset bit
* @mon_index: monitor register index
* @mon_bit: monitor bit
+ * @init_asserted: flag to indicate the reset should be asserted during probe
*/
struct rzv2h_reset {
u8 reset_index;
u8 reset_bit;
u8 mon_index;
u8 mon_bit;
+ bool init_asserted;
};
-#define DEF_RST_BASE(_resindex, _resbit, _monindex, _monbit) \
+#define DEF_RST_BASE(_resindex, _resbit, _monindex, _monbit, _init_asserted) \
{ \
.reset_index = (_resindex), \
.reset_bit = (_resbit), \
.mon_index = (_monindex), \
.mon_bit = (_monbit), \
+ .init_asserted = (_init_asserted), \
}
#define DEF_RST(_resindex, _resbit, _monindex, _monbit) \
- DEF_RST_BASE(_resindex, _resbit, _monindex, _monbit)
+ DEF_RST_BASE(_resindex, _resbit, _monindex, _monbit, false)
+
+/**
+ * DEF_RST_INIT_ASSERTED - Define a reset that should be asserted during probe
+ *
+ * Use this for peripherals that require their reset to be asserted at boot
+ * to ensure a known initial state before the peripheral driver takes over.
+ */
+#define DEF_RST_INIT_ASSERTED(_reset_index, _reset_bit, _mon_index, _mon_bit) \
+ DEF_RST_BASE(_reset_index, _reset_bit, _mon_index, _mon_bit, true)
/**
* struct rzv2h_cpg_info - SoC-specific CPG Description
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v4 04/15] clk: renesas: r9a09g047: Add PCIe clocks and reset
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
` (2 preceding siblings ...)
2026-01-29 21:41 ` [PATCH v4 03/15] clk: renesas: rzv2h-cpg: Add support for init_{off|asserted} clocks/resets John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-01-29 21:41 ` [PATCH v4 05/15] dt-bindings: PCI: renesas,r9a08g045s33-pcie: Fix naming properties John Madieu
` (10 subsequent siblings)
14 siblings, 0 replies; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
Add necessary clocks and reset entries for the PCIe controller
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: No changes
v3:
- Collected Rb tag
- Preserved sort order (by _onindex, _onbit);
v2:
- Fixed clock names
- Used assert-variant for reset
drivers/clk/renesas/r9a09g047-cpg.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/clk/renesas/r9a09g047-cpg.c b/drivers/clk/renesas/r9a09g047-cpg.c
index 1e9896742a06..567169194ee8 100644
--- a/drivers/clk/renesas/r9a09g047-cpg.c
+++ b/drivers/clk/renesas/r9a09g047-cpg.c
@@ -424,6 +424,10 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = {
BUS_MSTOP(8, BIT(6))),
DEF_MOD("gbeth_1_aclk_i", CLK_PLLDTY_DIV8, 12, 3, 6, 3,
BUS_MSTOP(8, BIT(6))),
+ DEF_MOD_INIT_OFF("pcie_0_aclk", CLK_PLLDTY_ACPU_DIV2, 12, 4, 6, 4,
+ BUS_MSTOP(1, BIT(15))),
+ DEF_MOD_INIT_OFF("pcie_0_clk_pmu", CLK_PLLDTY_ACPU_DIV2, 12, 5, 6, 5,
+ BUS_MSTOP(1, BIT(15))),
DEF_MOD("cru_0_aclk", CLK_PLLDTY_ACPU_DIV2, 13, 2, 6, 18,
BUS_MSTOP(9, BIT(4))),
DEF_MOD_NO_PM("cru_0_vclk", CLK_PLLVDO_CRU0, 13, 3, 6, 19,
@@ -503,6 +507,7 @@ static const struct rzv2h_reset r9a09g047_resets[] __initconst = {
DEF_RST(10, 15, 5, 0), /* USB2_0_PRESETN */
DEF_RST(11, 0, 5, 1), /* GBETH_0_ARESETN_I */
DEF_RST(11, 1, 5, 2), /* GBETH_1_ARESETN_I */
+ DEF_RST_INIT_ASSERTED(11, 2, 5, 3), /* PCIE_0_ARESETN */
DEF_RST(12, 5, 5, 22), /* CRU_0_PRESETN */
DEF_RST(12, 6, 5, 23), /* CRU_0_ARESETN */
DEF_RST(12, 7, 5, 24), /* CRU_0_S_RESETN */
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v4 05/15] dt-bindings: PCI: renesas,r9a08g045s33-pcie: Fix naming properties
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
` (3 preceding siblings ...)
2026-01-29 21:41 ` [PATCH v4 04/15] clk: renesas: r9a09g047: Add PCIe clocks and reset John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-01-30 13:53 ` Claudiu Beznea
2026-01-29 21:41 ` [PATCH v4 06/15] dt-bindings: PCI: renesas,r9a08g045s33-pcie: Document RZ/G3E SoC John Madieu
` (9 subsequent siblings)
14 siblings, 1 reply; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu, Conor Dooley
Fix a typo in interrupt-names: "ser_cor" should be "serr_cor" (System
Error Correctable).
Also convert interrupt-names, clock-names, and reset-names properties
from "description" to "const" to enable proper validation with
dtbs_check.
Fixes: e7534e790557 ("dt-bindings: PCI: renesas,r9a08g045s33-pcie: Document RZ/G3E SoC")
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: Collected Acked-by tag from Conor
v3: New patch
.../bindings/pci/renesas,r9a08g045-pcie.yaml | 50 +++++++++----------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/Documentation/devicetree/bindings/pci/renesas,r9a08g045-pcie.yaml b/Documentation/devicetree/bindings/pci/renesas,r9a08g045-pcie.yaml
index d668782546a2..d1eb92995e2c 100644
--- a/Documentation/devicetree/bindings/pci/renesas,r9a08g045-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/renesas,r9a08g045-pcie.yaml
@@ -41,22 +41,22 @@ properties:
interrupt-names:
items:
- - description: serr
- - description: ser_cor
- - description: serr_nonfatal
- - description: serr_fatal
- - description: axi_err
- - description: inta
- - description: intb
- - description: intc
- - description: intd
- - description: msi
- - description: link_bandwidth
- - description: pm_pme
- - description: dma
- - description: pcie_evt
- - description: msg
- - description: all
+ - const: serr
+ - const: serr_cor
+ - const: serr_nonfatal
+ - const: serr_fatal
+ - const: axi_err
+ - const: inta
+ - const: intb
+ - const: intc
+ - const: intd
+ - const: msi
+ - const: link_bandwidth
+ - const: pm_pme
+ - const: dma
+ - const: pcie_evt
+ - const: msg
+ - const: all
interrupt-controller: true
@@ -67,8 +67,8 @@ properties:
clock-names:
items:
- - description: aclk
- - description: pm
+ - const: aclk
+ - const: pm
resets:
items:
@@ -82,13 +82,13 @@ properties:
reset-names:
items:
- - description: aresetn
- - description: rst_b
- - description: rst_gp_b
- - description: rst_ps_b
- - description: rst_rsm_b
- - description: rst_cfg_b
- - description: rst_load_b
+ - const: aresetn
+ - const: rst_b
+ - const: rst_gp_b
+ - const: rst_ps_b
+ - const: rst_rsm_b
+ - const: rst_cfg_b
+ - const: rst_load_b
power-domains:
maxItems: 1
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v4 05/15] dt-bindings: PCI: renesas,r9a08g045s33-pcie: Fix naming properties
2026-01-29 21:41 ` [PATCH v4 05/15] dt-bindings: PCI: renesas,r9a08g045s33-pcie: Fix naming properties John Madieu
@ 2026-01-30 13:53 ` Claudiu Beznea
0 siblings, 0 replies; 27+ messages in thread
From: Claudiu Beznea @ 2026-01-30 13:53 UTC (permalink / raw)
To: John Madieu, claudiu.beznea.uj, lpieralisi, kwilczynski, mani,
geert+renesas, krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
Conor Dooley
On 1/29/26 23:41, John Madieu wrote:
> Fix a typo in interrupt-names: "ser_cor" should be "serr_cor" (System
> Error Correctable).
>
> Also convert interrupt-names, clock-names, and reset-names properties
> from "description" to "const" to enable proper validation with
> dtbs_check.
>
> Fixes: e7534e790557 ("dt-bindings: PCI: renesas,r9a08g045s33-pcie: Document RZ/G3E SoC")
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
Thanks for fixing this!
Reviewed-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v4 06/15] dt-bindings: PCI: renesas,r9a08g045s33-pcie: Document RZ/G3E SoC
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
` (4 preceding siblings ...)
2026-01-29 21:41 ` [PATCH v4 05/15] dt-bindings: PCI: renesas,r9a08g045s33-pcie: Fix naming properties John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-02-09 17:51 ` Rob Herring (Arm)
2026-01-29 21:41 ` [PATCH v4 07/15] PCI: rzg3s-host: Make SYSC register offsets SoC-specific John Madieu
` (8 subsequent siblings)
14 siblings, 1 reply; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
Extend the existing device tree bindings for Renesas RZ/G3S PCIe
controller to include support for the RZ/G3E (renesas,r9a09g047e57-pcie) PCIe
controller. The RZ/G3E PCIe controller is similar to RZ/G3S but has some key
differences:
- Uses a different device ID
- Supports PCIe Gen3 (8.0 GT/s) link speeds
- Uses a different clock naming (clkpmu vs clkl1pm)
- Has a different set of interrupts, interrupt ordering, and reset signals
Add device tree bindings for renesas,r9a09g047e57-pcie compatible IPs.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: Fixed clock name constraint using enum
v3:
- Moved interrupt/clock description in distinct PATCH
- Fixed clock name constraints
- Updated clock descriptions
v2: Reuse G3S names
.../bindings/pci/renesas,r9a08g045-pcie.yaml | 73 +++++++++++++++++--
1 file changed, 67 insertions(+), 6 deletions(-)
diff --git a/Documentation/devicetree/bindings/pci/renesas,r9a08g045-pcie.yaml b/Documentation/devicetree/bindings/pci/renesas,r9a08g045-pcie.yaml
index d1eb92995e2c..a67108c48feb 100644
--- a/Documentation/devicetree/bindings/pci/renesas,r9a08g045-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/renesas,r9a08g045-pcie.yaml
@@ -10,17 +10,21 @@ maintainers:
- Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
description:
- Renesas RZ/G3S PCIe host controller complies with PCIe Base Specification
- 4.0 and supports up to 5 GT/s (Gen2).
+ Renesas RZ/G3{E,S} PCIe host controllers comply with PCIe
+ Base Specification 4.0 and support up to 5 GT/s (Gen2) for RZ/G3S and
+ up to 8 GT/s (Gen3) for RZ/G3E.
properties:
compatible:
- const: renesas,r9a08g045-pcie # RZ/G3S
+ enum:
+ - renesas,r9a08g045-pcie # RZ/G3S
+ - renesas,r9a09g047-pcie # RZ/G3E
reg:
maxItems: 1
interrupts:
+ minItems: 16
items:
- description: System error interrupt
- description: System error on correctable error interrupt
@@ -38,8 +42,16 @@ properties:
- description: PCIe event interrupt
- description: Message interrupt
- description: All interrupts
+ - description: Link equalization request interrupt
+ - description: Turn off event interrupt
+ - description: PMU power off interrupt
+ - description: D3 event function 0 interrupt
+ - description: D3 event function 1 interrupt
+ - description: Configuration PMCSR write clear function 0 interrupt
+ - description: Configuration PMCSR write clear function 1 interrupt
interrupt-names:
+ minItems: 16
items:
- const: serr
- const: serr_cor
@@ -57,20 +69,28 @@ properties:
- const: pcie_evt
- const: msg
- const: all
+ - const: link_equalization_request
+ - const: turn_off_event
+ - const: pmu_poweroff
+ - const: d3_event_f0
+ - const: d3_event_f1
+ - const: cfg_pmcsr_writeclear_f0
+ - const: cfg_pmcsr_writeclear_f1
interrupt-controller: true
clocks:
items:
- description: System clock
- - description: PM control clock
+ - description: PM control clock or clock for L1 substate handling
clock-names:
items:
- const: aclk
- - const: pm
+ - enum: [pm, pmu]
resets:
+ minItems: 1
items:
- description: AXI2PCIe Bridge reset
- description: Data link layer/transaction layer reset
@@ -81,6 +101,7 @@ properties:
- description: Configuration register reset
reset-names:
+ minItems: 1
items:
- const: aresetn
- const: rst_b
@@ -128,7 +149,9 @@ patternProperties:
const: 0x1912
device-id:
- const: 0x0033
+ enum:
+ - 0x0033
+ - 0x0039
clocks:
items:
@@ -167,6 +190,44 @@ required:
allOf:
- $ref: /schemas/pci/pci-host-bridge.yaml#
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,r9a08g045-pcie
+ then:
+ properties:
+ interrupts:
+ maxItems: 16
+ interrupt-names:
+ maxItems: 16
+ clock-names:
+ items:
+ - const: aclk
+ - const: pm
+ resets:
+ minItems: 7
+ reset-names:
+ minItems: 7
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,r9a09g047-pcie
+ then:
+ properties:
+ interrupts:
+ minItems: 23
+ interrupt-names:
+ minItems: 23
+ clock-names:
+ items:
+ - const: aclk
+ - const: pmu
+ resets:
+ maxItems: 1
+ reset-names:
+ maxItems: 1
unevaluatedProperties: false
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v4 06/15] dt-bindings: PCI: renesas,r9a08g045s33-pcie: Document RZ/G3E SoC
2026-01-29 21:41 ` [PATCH v4 06/15] dt-bindings: PCI: renesas,r9a08g045s33-pcie: Document RZ/G3E SoC John Madieu
@ 2026-02-09 17:51 ` Rob Herring (Arm)
0 siblings, 0 replies; 27+ messages in thread
From: Rob Herring (Arm) @ 2026-02-09 17:51 UTC (permalink / raw)
To: John Madieu
Cc: john.madieu, linux-pci, claudiu.beznea.uj, mani, bhelgaas,
conor+dt, magnus.damm, linux-renesas-soc, devicetree, krzk+dt,
linux-clk, lpieralisi, biju.das.jz, kwilczynski, geert+renesas
On Thu, 29 Jan 2026 22:41:20 +0100, John Madieu wrote:
> Extend the existing device tree bindings for Renesas RZ/G3S PCIe
> controller to include support for the RZ/G3E (renesas,r9a09g047e57-pcie) PCIe
> controller. The RZ/G3E PCIe controller is similar to RZ/G3S but has some key
> differences:
>
> - Uses a different device ID
> - Supports PCIe Gen3 (8.0 GT/s) link speeds
> - Uses a different clock naming (clkpmu vs clkl1pm)
> - Has a different set of interrupts, interrupt ordering, and reset signals
>
> Add device tree bindings for renesas,r9a09g047e57-pcie compatible IPs.
>
> Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> ---
>
> Changes:
>
> v4: Fixed clock name constraint using enum
>
> v3:
> - Moved interrupt/clock description in distinct PATCH
> - Fixed clock name constraints
> - Updated clock descriptions
>
> v2: Reuse G3S names
>
> .../bindings/pci/renesas,r9a08g045-pcie.yaml | 73 +++++++++++++++++--
> 1 file changed, 67 insertions(+), 6 deletions(-)
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v4 07/15] PCI: rzg3s-host: Make SYSC register offsets SoC-specific
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
` (5 preceding siblings ...)
2026-01-29 21:41 ` [PATCH v4 06/15] dt-bindings: PCI: renesas,r9a08g045s33-pcie: Document RZ/G3E SoC John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-01-30 13:53 ` Claudiu Beznea
2026-01-29 21:41 ` [PATCH v4 08/15] PCI: rzg3s-host: Make configuration reset lines optional John Madieu
` (7 subsequent siblings)
14 siblings, 1 reply; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
In preparation for adding RZ/G3E support, move the RST_RSM_B register
offset and mask into a SoC-specific data structure. Compared with RZ/G3S,
the RZ/G3E SYSC controls different functionalities for the PCIe controller.
Make SYSC operations conditional on the presence of register offset
information, allowing the driver to handle SoCs that don't use the
RST_RSM_B signal.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: No changes
v3: No changes
v2: Address Claudiu's styling comment
drivers/pci/controller/pcie-rzg3s-host.c | 92 +++++++++++++++++-------
1 file changed, 66 insertions(+), 26 deletions(-)
diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
index 7b42f9415d3a..d883d3cd4541 100644
--- a/drivers/pci/controller/pcie-rzg3s-host.c
+++ b/drivers/pci/controller/pcie-rzg3s-host.c
@@ -159,10 +159,6 @@
#define RZG3S_PCI_CFG_PCIEC 0x60
-/* System controller registers */
-#define RZG3S_SYS_PCIE_RST_RSM_B 0xd74
-#define RZG3S_SYS_PCIE_RST_RSM_B_MASK BIT(0)
-
/* Maximum number of windows */
#define RZG3S_MAX_WINDOWS 8
@@ -174,6 +170,34 @@
/* Timeouts experimentally determined */
#define RZG3S_REQ_ISSUE_TIMEOUT_US 2500
+/**
+ * struct rzg3s_sysc_function - System Controller register function descriptor
+ * @offset: Register offset from the System Controller base address
+ * @mask: Bit mask for the function within the register
+ */
+struct rzg3s_sysc_function {
+ u32 offset;
+ u32 mask;
+};
+
+/**
+ * struct rzg3s_sysc_info - RZ/G3S System Controller function info
+ * @rst_rsm_b: Reset RSM_B function descriptor
+ */
+struct rzg3s_sysc_info {
+ struct rzg3s_sysc_function rst_rsm_b;
+};
+
+/**
+ * struct rzg3s_sysc - RZ/G3S System Controller descriptor
+ * @regmap: System controller regmap
+ * @info: System controller info
+ */
+struct rzg3s_sysc {
+ struct regmap *regmap;
+ const struct rzg3s_sysc_info *info;
+};
+
/**
* struct rzg3s_pcie_msi - RZ/G3S PCIe MSI data structure
* @domain: IRQ domain
@@ -203,6 +227,7 @@ struct rzg3s_pcie_host;
* power-on
* @cfg_resets: array with the resets that need to be de-asserted after
* configuration
+ * @sysc_info: SYSC functionalities
* @num_power_resets: number of power resets
* @num_cfg_resets: number of configuration resets
*/
@@ -210,6 +235,7 @@ struct rzg3s_pcie_soc_data {
int (*init_phy)(struct rzg3s_pcie_host *host);
const char * const *power_resets;
const char * const *cfg_resets;
+ struct rzg3s_sysc_info sysc_info;
u8 num_power_resets;
u8 num_cfg_resets;
};
@@ -233,7 +259,7 @@ struct rzg3s_pcie_port {
* @dev: struct device
* @power_resets: reset control signals that should be set after power up
* @cfg_resets: reset control signals that should be set after configuration
- * @sysc: SYSC regmap
+ * @sysc: SYSC descriptor
* @intx_domain: INTx IRQ domain
* @data: SoC specific data
* @msi: MSI data structure
@@ -248,7 +274,7 @@ struct rzg3s_pcie_host {
struct device *dev;
struct reset_control_bulk_data *power_resets;
struct reset_control_bulk_data *cfg_resets;
- struct regmap *sysc;
+ struct rzg3s_sysc *sysc;
struct irq_domain *intx_domain;
const struct rzg3s_pcie_soc_data *data;
struct rzg3s_pcie_msi msi;
@@ -1525,6 +1551,7 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
struct device_node *sysc_np __free(device_node) =
of_parse_phandle(np, "renesas,sysc", 0);
struct rzg3s_pcie_host *host;
+ struct rzg3s_sysc *sysc;
int ret;
bridge = devm_pci_alloc_host_bridge(dev, sizeof(*host));
@@ -1536,6 +1563,13 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
host->data = device_get_match_data(dev);
platform_set_drvdata(pdev, host);
+ host->sysc = devm_kzalloc(dev, sizeof(*host->sysc), GFP_KERNEL);
+ if (!host->sysc)
+ return -ENOMEM;
+
+ sysc = host->sysc;
+ sysc->info = &host->data->sysc_info;
+
host->axi = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(host->axi))
return PTR_ERR(host->axi);
@@ -1549,15 +1583,15 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
if (ret)
return ret;
- host->sysc = syscon_node_to_regmap(sysc_np);
- if (IS_ERR(host->sysc)) {
- ret = PTR_ERR(host->sysc);
+ sysc->regmap = syscon_node_to_regmap(sysc_np);
+ if (IS_ERR(sysc->regmap)) {
+ ret = PTR_ERR(sysc->regmap);
goto port_refclk_put;
}
- ret = regmap_update_bits(host->sysc, RZG3S_SYS_PCIE_RST_RSM_B,
- RZG3S_SYS_PCIE_RST_RSM_B_MASK,
- FIELD_PREP(RZG3S_SYS_PCIE_RST_RSM_B_MASK, 1));
+ ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
+ sysc->info->rst_rsm_b.mask,
+ field_prep(sysc->info->rst_rsm_b.mask, 1));
if (ret)
goto port_refclk_put;
@@ -1609,9 +1643,9 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
* SYSC RST_RSM_B signal need to be asserted before turning off the
* power to the PHY.
*/
- regmap_update_bits(host->sysc, RZG3S_SYS_PCIE_RST_RSM_B,
- RZG3S_SYS_PCIE_RST_RSM_B_MASK,
- FIELD_PREP(RZG3S_SYS_PCIE_RST_RSM_B_MASK, 0));
+ regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
+ sysc->info->rst_rsm_b.mask,
+ field_prep(sysc->info->rst_rsm_b.mask, 0));
port_refclk_put:
clk_put(host->port.refclk);
@@ -1623,7 +1657,7 @@ static int rzg3s_pcie_suspend_noirq(struct device *dev)
struct rzg3s_pcie_host *host = dev_get_drvdata(dev);
const struct rzg3s_pcie_soc_data *data = host->data;
struct rzg3s_pcie_port *port = &host->port;
- struct regmap *sysc = host->sysc;
+ struct rzg3s_sysc *sysc = host->sysc;
int ret;
ret = pm_runtime_put_sync(dev);
@@ -1642,9 +1676,9 @@ static int rzg3s_pcie_suspend_noirq(struct device *dev)
if (ret)
goto power_resets_restore;
- ret = regmap_update_bits(sysc, RZG3S_SYS_PCIE_RST_RSM_B,
- RZG3S_SYS_PCIE_RST_RSM_B_MASK,
- FIELD_PREP(RZG3S_SYS_PCIE_RST_RSM_B_MASK, 0));
+ ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
+ sysc->info->rst_rsm_b.mask,
+ field_prep(sysc->info->rst_rsm_b.mask, 0));
if (ret)
goto cfg_resets_restore;
@@ -1667,12 +1701,12 @@ static int rzg3s_pcie_resume_noirq(struct device *dev)
{
struct rzg3s_pcie_host *host = dev_get_drvdata(dev);
const struct rzg3s_pcie_soc_data *data = host->data;
- struct regmap *sysc = host->sysc;
+ struct rzg3s_sysc *sysc = host->sysc;
int ret;
- ret = regmap_update_bits(sysc, RZG3S_SYS_PCIE_RST_RSM_B,
- RZG3S_SYS_PCIE_RST_RSM_B_MASK,
- FIELD_PREP(RZG3S_SYS_PCIE_RST_RSM_B_MASK, 1));
+ ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
+ sysc->info->rst_rsm_b.mask,
+ field_prep(sysc->info->rst_rsm_b.mask, 1));
if (ret)
return ret;
@@ -1701,9 +1735,9 @@ static int rzg3s_pcie_resume_noirq(struct device *dev)
reset_control_bulk_assert(data->num_power_resets,
host->power_resets);
assert_rst_rsm_b:
- regmap_update_bits(sysc, RZG3S_SYS_PCIE_RST_RSM_B,
- RZG3S_SYS_PCIE_RST_RSM_B_MASK,
- FIELD_PREP(RZG3S_SYS_PCIE_RST_RSM_B_MASK, 0));
+ regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
+ sysc->info->rst_rsm_b.mask,
+ field_prep(sysc->info->rst_rsm_b.mask, 0));
return ret;
}
@@ -1726,6 +1760,12 @@ static const struct rzg3s_pcie_soc_data rzg3s_soc_data = {
.cfg_resets = rzg3s_soc_cfg_resets,
.num_cfg_resets = ARRAY_SIZE(rzg3s_soc_cfg_resets),
.init_phy = rzg3s_soc_pcie_init_phy,
+ .sysc_info = {
+ .rst_rsm_b = {
+ .offset = 0xd74,
+ .mask = BIT(0),
+ },
+ },
};
static const struct of_device_id rzg3s_pcie_of_match[] = {
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v4 07/15] PCI: rzg3s-host: Make SYSC register offsets SoC-specific
2026-01-29 21:41 ` [PATCH v4 07/15] PCI: rzg3s-host: Make SYSC register offsets SoC-specific John Madieu
@ 2026-01-30 13:53 ` Claudiu Beznea
0 siblings, 0 replies; 27+ messages in thread
From: Claudiu Beznea @ 2026-01-30 13:53 UTC (permalink / raw)
To: John Madieu, claudiu.beznea.uj, lpieralisi, kwilczynski, mani,
geert+renesas, krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu
On 1/29/26 23:41, John Madieu wrote:
> In preparation for adding RZ/G3E support, move the RST_RSM_B register
> offset and mask into a SoC-specific data structure. Compared with RZ/G3S,
> the RZ/G3E SYSC controls different functionalities for the PCIe controller.
>
> Make SYSC operations conditional on the presence of register offset
> information, allowing the driver to handle SoCs that don't use the
> RST_RSM_B signal.
>
> Signed-off-by: John Madieu<john.madieu.xa@bp.renesas.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v4 08/15] PCI: rzg3s-host: Make configuration reset lines optional
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
` (6 preceding siblings ...)
2026-01-29 21:41 ` [PATCH v4 07/15] PCI: rzg3s-host: Make SYSC register offsets SoC-specific John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-01-29 21:41 ` [PATCH v4 09/15] PCI: rzg3s-host: Add SoC-specific configuration and initialization callbacks John Madieu
` (6 subsequent siblings)
14 siblings, 0 replies; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
Some SoC variants such as RZ/G3E handle configuration reset control
through PCIe AXI registers instead of dedicated reset lines. Make cfg_resets
optional by using devm_reset_control_bulk_get_optional_exclusive() to allow
SoCs to use alternative or complementary reset control mechanisms.
Reviewed-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
changes:
v4: No changes
v3: No changes
v2: Collected Rb tag.
drivers/pci/controller/pcie-rzg3s-host.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
index d883d3cd4541..a6fb2ec4a341 100644
--- a/drivers/pci/controller/pcie-rzg3s-host.c
+++ b/drivers/pci/controller/pcie-rzg3s-host.c
@@ -1161,9 +1161,9 @@ static int rzg3s_pcie_resets_prepare_and_get(struct rzg3s_pcie_host *host)
if (ret)
return ret;
- return devm_reset_control_bulk_get_exclusive(host->dev,
- data->num_cfg_resets,
- host->cfg_resets);
+ return devm_reset_control_bulk_get_optional_exclusive(host->dev,
+ data->num_cfg_resets,
+ host->cfg_resets);
}
static int rzg3s_pcie_host_parse_port(struct rzg3s_pcie_host *host)
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v4 09/15] PCI: rzg3s-host: Add SoC-specific configuration and initialization callbacks
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
` (7 preceding siblings ...)
2026-01-29 21:41 ` [PATCH v4 08/15] PCI: rzg3s-host: Make configuration reset lines optional John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-01-30 13:54 ` Claudiu Beznea
2026-01-29 21:41 ` [PATCH v4 10/15] PCI: rzg3s-host: Explicitly set class code for RZ/G3E compatibility John Madieu
` (5 subsequent siblings)
14 siblings, 1 reply; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
Add optional cfg_pre_init, cfg_post_init, and cfg_deinit callbacks
to handle SoC-specific configuration methods. While RZ/G3S uses the Linux
reset framework with dedicated reset lines, other SoC variants like RZ/G3E
control configuration resets through PCIe AXI registers.
As Linux reset bulk API gracefully handles optional NULL reset lines
(num_cfg_resets = 0 for RZ/G3E), the driver continues to use the standard
reset framework when reset lines are available, while custom callbacks
are only invoked when provided.
This provides a balanced pattern where:
- RZ/G3S: Uses reset framework only, no callbacks needed
- RZ/G3E: Sets num_cfg_resets=0, provides cfg_pre_init/cfg_post_init/cfg_deinit
- In addition to that, RZ/G3E requires explicit cfg reset and clock turned off
to put the PCIe IP in a known state.
Add cfg_pre_init, cfg_post_init, and cfg_deinit callbacks to support
custom configuration mechanism in preparation to RZ/G3E PCIe support.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: No changes
v3: No changes
v2:
- Renamed callbacks as per Claudiu's comments
- Reworded goto labels to be consistents with callbacks
drivers/pci/controller/pcie-rzg3s-host.c | 66 +++++++++++++++++-------
1 file changed, 46 insertions(+), 20 deletions(-)
diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
index a6fb2ec4a341..15ccd9095a3e 100644
--- a/drivers/pci/controller/pcie-rzg3s-host.c
+++ b/drivers/pci/controller/pcie-rzg3s-host.c
@@ -223,6 +223,9 @@ struct rzg3s_pcie_host;
/**
* struct rzg3s_pcie_soc_data - SoC specific data
* @init_phy: PHY initialization function
+ * @config_pre_init: Optional callback for SoC-specific pre-configuration
+ * @config_post_init: Callback for SoC-specific post-configuration
+ * @config_deinit: Callback for SoC-specific de-initialization
* @power_resets: array with the resets that need to be de-asserted after
* power-on
* @cfg_resets: array with the resets that need to be de-asserted after
@@ -233,6 +236,9 @@ struct rzg3s_pcie_host;
*/
struct rzg3s_pcie_soc_data {
int (*init_phy)(struct rzg3s_pcie_host *host);
+ void (*config_pre_init)(struct rzg3s_pcie_host *host);
+ int (*config_post_init)(struct rzg3s_pcie_host *host);
+ int (*config_deinit)(struct rzg3s_pcie_host *host);
const char * const *power_resets;
const char * const *cfg_resets;
struct rzg3s_sysc_info sysc_info;
@@ -1082,6 +1088,18 @@ static int rzg3s_pcie_config_init(struct rzg3s_pcie_host *host)
return 0;
}
+static int rzg3s_config_post_init(struct rzg3s_pcie_host *host)
+{
+ return reset_control_bulk_deassert(host->data->num_cfg_resets,
+ host->cfg_resets);
+}
+
+static int rzg3s_config_deinit(struct rzg3s_pcie_host *host)
+{
+ return reset_control_bulk_assert(host->data->num_cfg_resets,
+ host->cfg_resets);
+}
+
static void rzg3s_pcie_irq_init(struct rzg3s_pcie_host *host)
{
/*
@@ -1229,20 +1247,24 @@ static int rzg3s_pcie_host_init(struct rzg3s_pcie_host *host)
u32 val;
int ret;
+ /* SoC-specific pre-configuration */
+ if (host->data->config_pre_init)
+ host->data->config_pre_init(host);
+
/* Initialize the PCIe related registers */
ret = rzg3s_pcie_config_init(host);
if (ret)
- return ret;
+ goto config_deinit;
ret = rzg3s_pcie_host_init_port(host);
if (ret)
- return ret;
+ goto config_deinit;
/* Initialize the interrupts */
rzg3s_pcie_irq_init(host);
- ret = reset_control_bulk_deassert(host->data->num_cfg_resets,
- host->cfg_resets);
+ /* SoC-specific post-configuration */
+ ret = host->data->config_post_init(host);
if (ret)
goto disable_port_refclk;
@@ -1253,19 +1275,22 @@ static int rzg3s_pcie_host_init(struct rzg3s_pcie_host *host)
PCIE_LINK_WAIT_SLEEP_MS * MILLI *
PCIE_LINK_WAIT_MAX_RETRIES);
if (ret)
- goto cfg_resets_deassert;
+ goto config_deinit_post;
val = readl_relaxed(host->axi + RZG3S_PCI_PCSTAT2);
dev_info(host->dev, "PCIe link status [0x%x]\n", val);
return 0;
-cfg_resets_deassert:
- reset_control_bulk_assert(host->data->num_cfg_resets,
- host->cfg_resets);
+config_deinit_post:
+ host->data->config_deinit(host);
disable_port_refclk:
clk_disable_unprepare(host->port.refclk);
return ret;
+
+config_deinit:
+ host->data->config_deinit(host);
+ return ret;
}
static void rzg3s_pcie_set_inbound_window(struct rzg3s_pcie_host *host,
@@ -1631,7 +1656,7 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
host_probe_teardown:
rzg3s_pcie_teardown_irqdomain(host);
- reset_control_bulk_assert(host->data->num_cfg_resets, host->cfg_resets);
+ host->data->config_deinit(host);
rpm_put:
pm_runtime_put_sync(dev);
rpm_disable:
@@ -1666,32 +1691,31 @@ static int rzg3s_pcie_suspend_noirq(struct device *dev)
clk_disable_unprepare(port->refclk);
- ret = reset_control_bulk_assert(data->num_power_resets,
- host->power_resets);
+ /* SoC-specific de-initialization */
+ ret = data->config_deinit(host);
if (ret)
- goto refclk_restore;
+ goto config_reinit;
- ret = reset_control_bulk_assert(data->num_cfg_resets,
- host->cfg_resets);
+ ret = reset_control_bulk_assert(data->num_power_resets,
+ host->power_resets);
if (ret)
- goto power_resets_restore;
+ goto config_reinit;
ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
sysc->info->rst_rsm_b.mask,
field_prep(sysc->info->rst_rsm_b.mask, 0));
if (ret)
- goto cfg_resets_restore;
+ goto power_resets_restore;
return 0;
/* Restore the previous state if any error happens */
-cfg_resets_restore:
- reset_control_bulk_deassert(data->num_cfg_resets,
- host->cfg_resets);
power_resets_restore:
reset_control_bulk_deassert(data->num_power_resets,
host->power_resets);
-refclk_restore:
+config_reinit:
+ data->config_post_init(host);
+
clk_prepare_enable(port->refclk);
pm_runtime_resume_and_get(dev);
return ret;
@@ -1759,6 +1783,8 @@ static const struct rzg3s_pcie_soc_data rzg3s_soc_data = {
.num_power_resets = ARRAY_SIZE(rzg3s_soc_power_resets),
.cfg_resets = rzg3s_soc_cfg_resets,
.num_cfg_resets = ARRAY_SIZE(rzg3s_soc_cfg_resets),
+ .config_post_init = rzg3s_config_post_init,
+ .config_deinit = rzg3s_config_deinit,
.init_phy = rzg3s_soc_pcie_init_phy,
.sysc_info = {
.rst_rsm_b = {
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v4 09/15] PCI: rzg3s-host: Add SoC-specific configuration and initialization callbacks
2026-01-29 21:41 ` [PATCH v4 09/15] PCI: rzg3s-host: Add SoC-specific configuration and initialization callbacks John Madieu
@ 2026-01-30 13:54 ` Claudiu Beznea
0 siblings, 0 replies; 27+ messages in thread
From: Claudiu Beznea @ 2026-01-30 13:54 UTC (permalink / raw)
To: John Madieu, claudiu.beznea.uj, lpieralisi, kwilczynski, mani,
geert+renesas, krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu
Hi, John,
On 1/29/26 23:41, John Madieu wrote:
> Add optional cfg_pre_init, cfg_post_init, and cfg_deinit callbacks
> to handle SoC-specific configuration methods. While RZ/G3S uses the Linux
> reset framework with dedicated reset lines, other SoC variants like RZ/G3E
> control configuration resets through PCIe AXI registers.
>
> As Linux reset bulk API gracefully handles optional NULL reset lines
> (num_cfg_resets = 0 for RZ/G3E), the driver continues to use the standard
> reset framework when reset lines are available, while custom callbacks
> are only invoked when provided.
>
> This provides a balanced pattern where:
> - RZ/G3S: Uses reset framework only, no callbacks needed
> - RZ/G3E: Sets num_cfg_resets=0, provides cfg_pre_init/cfg_post_init/cfg_deinit
> - In addition to that, RZ/G3E requires explicit cfg reset and clock turned off
> to put the PCIe IP in a known state.
>
> Add cfg_pre_init, cfg_post_init, and cfg_deinit callbacks to support
> custom configuration mechanism in preparation to RZ/G3E PCIe support.
>
> Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> ---
>
> Changes:
>
> v4: No changes
>
> v3: No changes
>
> v2:
> - Renamed callbacks as per Claudiu's comments
> - Reworded goto labels to be consistents with callbacks
>
> drivers/pci/controller/pcie-rzg3s-host.c | 66 +++++++++++++++++-------
> 1 file changed, 46 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
> index a6fb2ec4a341..15ccd9095a3e 100644
> --- a/drivers/pci/controller/pcie-rzg3s-host.c
> +++ b/drivers/pci/controller/pcie-rzg3s-host.c
> @@ -223,6 +223,9 @@ struct rzg3s_pcie_host;
> /**
> * struct rzg3s_pcie_soc_data - SoC specific data
> * @init_phy: PHY initialization function
> + * @config_pre_init: Optional callback for SoC-specific pre-configuration
> + * @config_post_init: Callback for SoC-specific post-configuration
> + * @config_deinit: Callback for SoC-specific de-initialization
> * @power_resets: array with the resets that need to be de-asserted after
> * power-on
> * @cfg_resets: array with the resets that need to be de-asserted after
> @@ -233,6 +236,9 @@ struct rzg3s_pcie_host;
> */
> struct rzg3s_pcie_soc_data {
> int (*init_phy)(struct rzg3s_pcie_host *host);
> + void (*config_pre_init)(struct rzg3s_pcie_host *host);
> + int (*config_post_init)(struct rzg3s_pcie_host *host);
> + int (*config_deinit)(struct rzg3s_pcie_host *host);
> const char * const *power_resets;
> const char * const *cfg_resets;
> struct rzg3s_sysc_info sysc_info;
> @@ -1082,6 +1088,18 @@ static int rzg3s_pcie_config_init(struct rzg3s_pcie_host *host)
> return 0;
> }
>
> +static int rzg3s_config_post_init(struct rzg3s_pcie_host *host)
> +{
> + return reset_control_bulk_deassert(host->data->num_cfg_resets,
> + host->cfg_resets);
> +}
> +
> +static int rzg3s_config_deinit(struct rzg3s_pcie_host *host)
> +{
> + return reset_control_bulk_assert(host->data->num_cfg_resets,
> + host->cfg_resets);
> +}
> +
> static void rzg3s_pcie_irq_init(struct rzg3s_pcie_host *host)
> {
> /*
> @@ -1229,20 +1247,24 @@ static int rzg3s_pcie_host_init(struct rzg3s_pcie_host *host)
> u32 val;
> int ret;
>
> + /* SoC-specific pre-configuration */
> + if (host->data->config_pre_init)
> + host->data->config_pre_init(host);
> +
> /* Initialize the PCIe related registers */
> ret = rzg3s_pcie_config_init(host);
> if (ret)
> - return ret;
> + goto config_deinit;
>
> ret = rzg3s_pcie_host_init_port(host);
> if (ret)
> - return ret;
> + goto config_deinit;
>
> /* Initialize the interrupts */
> rzg3s_pcie_irq_init(host);
>
> - ret = reset_control_bulk_deassert(host->data->num_cfg_resets,
> - host->cfg_resets);
> + /* SoC-specific post-configuration */
> + ret = host->data->config_post_init(host);
> if (ret)
> goto disable_port_refclk;
This will have to jump to the config_deinit_and_reclk label (see below).
>
> @@ -1253,19 +1275,22 @@ static int rzg3s_pcie_host_init(struct rzg3s_pcie_host *host)
> PCIE_LINK_WAIT_SLEEP_MS * MILLI *
> PCIE_LINK_WAIT_MAX_RETRIES);
> if (ret)
> - goto cfg_resets_deassert;
> + goto config_deinit_post;
>
> val = readl_relaxed(host->axi + RZG3S_PCI_PCSTAT2);
> dev_info(host->dev, "PCIe link status [0x%x]\n", val);
>
> return 0;
>
> -cfg_resets_deassert:
> - reset_control_bulk_assert(host->data->num_cfg_resets,
> - host->cfg_resets);
> +config_deinit_post:
> + host->data->config_deinit(host);
> disable_port_refclk:
> clk_disable_unprepare(host->port.refclk);
> return ret;
> +
> +config_deinit:
> + host->data->config_deinit(host);
This should be like:
config_deinit_and_reclk:
clk_disable_unprepare(host->port.refclk);
config_deinit:
if (host->data->config_pre_init)
host->data->config_deinit(host);
To avoid asserting CFG resets on RZ/G3S when they weren't configured.
> + return ret;
> }
>
> static void rzg3s_pcie_set_inbound_window(struct rzg3s_pcie_host *host,
> @@ -1631,7 +1656,7 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
>
> host_probe_teardown:
> rzg3s_pcie_teardown_irqdomain(host);
> - reset_control_bulk_assert(host->data->num_cfg_resets, host->cfg_resets);
> + host->data->config_deinit(host);
> rpm_put:
> pm_runtime_put_sync(dev);
> rpm_disable:
> @@ -1666,32 +1691,31 @@ static int rzg3s_pcie_suspend_noirq(struct device *dev)
>
> clk_disable_unprepare(port->refclk);
>
> - ret = reset_control_bulk_assert(data->num_power_resets,
> - host->power_resets);
> + /* SoC-specific de-initialization */
> + ret = data->config_deinit(host);
> if (ret)
> - goto refclk_restore;
> + goto config_reinit;
Shouldn't this jump to clk_prepare_enable(port->refclk) ?
Also, you've changed the reset order here. Please mention it in the patch
description or add a separate patch for that.
Thank you,
Claudiu
>
> - ret = reset_control_bulk_assert(data->num_cfg_resets,
> - host->cfg_resets);
> + ret = reset_control_bulk_assert(data->num_power_resets,
> + host->power_resets);
> if (ret)
> - goto power_resets_restore;
> + goto config_reinit;
>
> ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
> sysc->info->rst_rsm_b.mask,
> field_prep(sysc->info->rst_rsm_b.mask, 0));
> if (ret)
> - goto cfg_resets_restore;
> + goto power_resets_restore;
>
> return 0;
>
> /* Restore the previous state if any error happens */
> -cfg_resets_restore:
> - reset_control_bulk_deassert(data->num_cfg_resets,
> - host->cfg_resets);
> power_resets_restore:
> reset_control_bulk_deassert(data->num_power_resets,
> host->power_resets);
> -refclk_restore:
> +config_reinit:
> + data->config_post_init(host);
> +
Here
> clk_prepare_enable(port->refclk);
> pm_runtime_resume_and_get(dev);
> return ret;
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v4 10/15] PCI: rzg3s-host: Explicitly set class code for RZ/G3E compatibility
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
` (8 preceding siblings ...)
2026-01-29 21:41 ` [PATCH v4 09/15] PCI: rzg3s-host: Add SoC-specific configuration and initialization callbacks John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-01-30 13:55 ` Claudiu Beznea
2026-01-29 21:41 ` [PATCH v4 11/15] PCI: rzg3s-host: Add PCIe Gen3 (8.0 GT/s) link speed support John Madieu
` (4 subsequent siblings)
14 siblings, 1 reply; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
Program the class code register explicitly during PCIe configuration
initialization. RZ/G3E requires this register to be set, while RZ/G3S
has these values as hardware defaults.
This configuration is harmless for RZ/G3S where these match the hardware
defaults, and necessary for RZ/G3E to properly identify the device as a
PCI bridge.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: No changes
v3: No changes
v2: No changes
drivers/pci/controller/pcie-rzg3s-host.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
index 15ccd9095a3e..76f6d940ba45 100644
--- a/drivers/pci/controller/pcie-rzg3s-host.c
+++ b/drivers/pci/controller/pcie-rzg3s-host.c
@@ -1054,6 +1054,7 @@ static int rzg3s_pcie_set_max_link_speed(struct rzg3s_pcie_host *host)
static int rzg3s_pcie_config_init(struct rzg3s_pcie_host *host)
{
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(host);
+ u32 mask = GENMASK(31, 8);
struct resource_entry *ft;
struct resource *bus;
u8 subordinate_bus;
@@ -1077,6 +1078,13 @@ static int rzg3s_pcie_config_init(struct rzg3s_pcie_host *host)
writel_relaxed(0xffffffff, host->pcie + RZG3S_PCI_CFG_BARMSK00L);
writel_relaxed(0xffffffff, host->pcie + RZG3S_PCI_CFG_BARMSK00U);
+ /*
+ * Explicitly program class code. RZ/G3E requires this configuration.
+ * Harmless for RZ/G3S where this matches the hardware default.
+ */
+ rzg3s_pcie_update_bits(host->pcie, PCI_CLASS_REVISION, mask,
+ FIELD_PREP(mask, PCI_CLASS_BRIDGE_PCI_NORMAL));
+
/* Disable access control to the CFGU */
writel_relaxed(0, host->axi + RZG3S_PCI_PERM);
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v4 10/15] PCI: rzg3s-host: Explicitly set class code for RZ/G3E compatibility
2026-01-29 21:41 ` [PATCH v4 10/15] PCI: rzg3s-host: Explicitly set class code for RZ/G3E compatibility John Madieu
@ 2026-01-30 13:55 ` Claudiu Beznea
2026-01-30 15:08 ` Geert Uytterhoeven
0 siblings, 1 reply; 27+ messages in thread
From: Claudiu Beznea @ 2026-01-30 13:55 UTC (permalink / raw)
To: John Madieu, claudiu.beznea.uj, lpieralisi, kwilczynski, mani,
geert+renesas, krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu
Hi, John,
On 1/29/26 23:41, John Madieu wrote:
> Program the class code register explicitly during PCIe configuration
> initialization. RZ/G3E requires this register to be set, while RZ/G3S
> has these values as hardware defaults.
>
> This configuration is harmless for RZ/G3S where these match the hardware
> defaults, and necessary for RZ/G3E to properly identify the device as a
> PCI bridge.
>
> Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> ---
>
> Changes:
>
> v4: No changes
> v3: No changes
> v2: No changes
>
> drivers/pci/controller/pcie-rzg3s-host.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
> index 15ccd9095a3e..76f6d940ba45 100644
> --- a/drivers/pci/controller/pcie-rzg3s-host.c
> +++ b/drivers/pci/controller/pcie-rzg3s-host.c
> @@ -1054,6 +1054,7 @@ static int rzg3s_pcie_set_max_link_speed(struct rzg3s_pcie_host *host)
> static int rzg3s_pcie_config_init(struct rzg3s_pcie_host *host)
> {
> struct pci_host_bridge *bridge = pci_host_bridge_from_priv(host);
> + u32 mask = GENMASK(31, 8);
> struct resource_entry *ft;
> struct resource *bus;
> u8 subordinate_bus;
> @@ -1077,6 +1078,13 @@ static int rzg3s_pcie_config_init(struct rzg3s_pcie_host *host)
> writel_relaxed(0xffffffff, host->pcie + RZG3S_PCI_CFG_BARMSK00L);
> writel_relaxed(0xffffffff, host->pcie + RZG3S_PCI_CFG_BARMSK00U);
>
> + /*
> + * Explicitly program class code. RZ/G3E requires this configuration.
> + * Harmless for RZ/G3S where this matches the hardware default.
> + */
> + rzg3s_pcie_update_bits(host->pcie, PCI_CLASS_REVISION, mask,
> + FIELD_PREP(mask, PCI_CLASS_BRIDGE_PCI_NORMAL));
According to kernel test robot report on v1 this throws a compilation warning:
https://lore.kernel.org/all/202601152104.pV9uMS76-lkp@intel.com/
> +
> /* Disable access control to the CFGU */
> writel_relaxed(0, host->axi + RZG3S_PCI_PERM);
>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v4 10/15] PCI: rzg3s-host: Explicitly set class code for RZ/G3E compatibility
2026-01-30 13:55 ` Claudiu Beznea
@ 2026-01-30 15:08 ` Geert Uytterhoeven
2026-01-30 20:26 ` John Madieu
0 siblings, 1 reply; 27+ messages in thread
From: Geert Uytterhoeven @ 2026-01-30 15:08 UTC (permalink / raw)
To: Claudiu Beznea
Cc: John Madieu, claudiu.beznea.uj, lpieralisi, kwilczynski, mani,
geert+renesas, krzk+dt, robh, bhelgaas, conor+dt, magnus.damm,
biju.das.jz, linux-pci, linux-renesas-soc, devicetree, linux-clk,
john.madieu
On Fri, 30 Jan 2026 at 14:55, Claudiu Beznea <claudiu.beznea@tuxon.dev> wrote:
> On 1/29/26 23:41, John Madieu wrote:
> > Program the class code register explicitly during PCIe configuration
> > initialization. RZ/G3E requires this register to be set, while RZ/G3S
> > has these values as hardware defaults.
> >
> > This configuration is harmless for RZ/G3S where these match the hardware
> > defaults, and necessary for RZ/G3E to properly identify the device as a
> > PCI bridge.
> >
> > Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> > --- a/drivers/pci/controller/pcie-rzg3s-host.c
> > +++ b/drivers/pci/controller/pcie-rzg3s-host.c
> > @@ -1054,6 +1054,7 @@ static int rzg3s_pcie_set_max_link_speed(struct rzg3s_pcie_host *host)
> > static int rzg3s_pcie_config_init(struct rzg3s_pcie_host *host)
> > {
> > struct pci_host_bridge *bridge = pci_host_bridge_from_priv(host);
> > + u32 mask = GENMASK(31, 8);
> > struct resource_entry *ft;
> > struct resource *bus;
> > u8 subordinate_bus;
> > @@ -1077,6 +1078,13 @@ static int rzg3s_pcie_config_init(struct rzg3s_pcie_host *host)
> > writel_relaxed(0xffffffff, host->pcie + RZG3S_PCI_CFG_BARMSK00L);
> > writel_relaxed(0xffffffff, host->pcie + RZG3S_PCI_CFG_BARMSK00U);
> >
> > + /*
> > + * Explicitly program class code. RZ/G3E requires this configuration.
> > + * Harmless for RZ/G3S where this matches the hardware default.
> > + */
> > + rzg3s_pcie_update_bits(host->pcie, PCI_CLASS_REVISION, mask,
> > + FIELD_PREP(mask, PCI_CLASS_BRIDGE_PCI_NORMAL));
>
> According to kernel test robot report on v1 this throws a compilation warning:
Yeah, in case of a non-const mask, you must use field_prep() instead.
> https://lore.kernel.org/all/202601152104.pV9uMS76-lkp@intel.com/
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] 27+ messages in thread* RE: [PATCH v4 10/15] PCI: rzg3s-host: Explicitly set class code for RZ/G3E compatibility
2026-01-30 15:08 ` Geert Uytterhoeven
@ 2026-01-30 20:26 ` John Madieu
0 siblings, 0 replies; 27+ messages in thread
From: John Madieu @ 2026-01-30 20:26 UTC (permalink / raw)
To: geert, Claudiu.Beznea
Cc: Claudiu Beznea, lpieralisi@kernel.org, kwilczynski@kernel.org,
mani@kernel.org, geert+renesas@glider.be, krzk+dt@kernel.org,
robh@kernel.org, bhelgaas@google.com, conor+dt@kernel.org,
magnus.damm, Biju Das, linux-pci@vger.kernel.org,
linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org,
linux-clk@vger.kernel.org, john.madieu@gmail.com
Hi Geert, Claudiu,
Thanks for the review.
> -----Original Message-----
> From: Geert Uytterhoeven <geert@linux-m68k.org>
> Sent: Friday, January 30, 2026 4:08 PM
> To: Claudiu.Beznea <claudiu.beznea@tuxon.dev>
> Cc: John Madieu <john.madieu.xa@bp.renesas.com>; Claudiu Beznea
> <claudiu.beznea.uj@bp.renesas.com>; lpieralisi@kernel.org;
> kwilczynski@kernel.org; mani@kernel.org; geert+renesas@glider.be;
> krzk+dt@kernel.org; robh@kernel.org; bhelgaas@google.com;
> conor+dt@kernel.org; magnus.damm <magnus.damm@gmail.com>; Biju Das
> <biju.das.jz@bp.renesas.com>; linux-pci@vger.kernel.org; linux-renesas-
> soc@vger.kernel.org; devicetree@vger.kernel.org; linux-
> clk@vger.kernel.org; john.madieu@gmail.com
> Subject: Re: [PATCH v4 10/15] PCI: rzg3s-host: Explicitly set class code
> for RZ/G3E compatibility
>
> On Fri, 30 Jan 2026 at 14:55, Claudiu Beznea <claudiu.beznea@tuxon.dev>
> wrote:
> > On 1/29/26 23:41, John Madieu wrote:
> > > Program the class code register explicitly during PCIe configuration
> > > initialization. RZ/G3E requires this register to be set, while
> > > RZ/G3S has these values as hardware defaults.
> > >
> > > This configuration is harmless for RZ/G3S where these match the
> > > hardware defaults, and necessary for RZ/G3E to properly identify the
> > > device as a PCI bridge.
> > >
> > > Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
>
> > > --- a/drivers/pci/controller/pcie-rzg3s-host.c
> > > +++ b/drivers/pci/controller/pcie-rzg3s-host.c
> > > @@ -1054,6 +1054,7 @@ static int rzg3s_pcie_set_max_link_speed(struct
> rzg3s_pcie_host *host)
> > > static int rzg3s_pcie_config_init(struct rzg3s_pcie_host *host)
> > > {
> > > struct pci_host_bridge *bridge =
> > > pci_host_bridge_from_priv(host);
> > > + u32 mask = GENMASK(31, 8);
> > > struct resource_entry *ft;
> > > struct resource *bus;
> > > u8 subordinate_bus;
> > > @@ -1077,6 +1078,13 @@ static int rzg3s_pcie_config_init(struct
> rzg3s_pcie_host *host)
> > > writel_relaxed(0xffffffff, host->pcie +
> RZG3S_PCI_CFG_BARMSK00L);
> > > writel_relaxed(0xffffffff, host->pcie +
> > > RZG3S_PCI_CFG_BARMSK00U);
> > >
> > > + /*
> > > + * Explicitly program class code. RZ/G3E requires this
> configuration.
> > > + * Harmless for RZ/G3S where this matches the hardware default.
> > > + */
> > > + rzg3s_pcie_update_bits(host->pcie, PCI_CLASS_REVISION, mask,
> > > + FIELD_PREP(mask,
> > > + PCI_CLASS_BRIDGE_PCI_NORMAL));
> >
> > According to kernel test robot report on v1 this throws a compilation
> warning:
>
> Yeah, in case of a non-const mask, you must use field_prep() instead.
>
Thanks for pointing that out. Will use field_prep()
in v5.
Regards,
John
> > https://lore.kernel.org/all/202601152104.pV9uMS76-lkp@intel.com/
>
> 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] 27+ messages in thread
* [PATCH v4 11/15] PCI: rzg3s-host: Add PCIe Gen3 (8.0 GT/s) link speed support
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
` (9 preceding siblings ...)
2026-01-29 21:41 ` [PATCH v4 10/15] PCI: rzg3s-host: Explicitly set class code for RZ/G3E compatibility John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-01-29 21:41 ` [PATCH v4 12/15] PCI: rzg3s-host: Add support for RZ/G3E PCIe controller John Madieu
` (3 subsequent siblings)
14 siblings, 0 replies; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
Extend the link speed configuration to support Gen3 (8.0 GT/s) in addition
to Gen2 (5.0 GT/s). This is required for RZ/G3E PCIe host support, which is
Gen3 capable.
Instead of relying on DT max-link-speed for configuration, read the hardware
capabilities from the PCI_EXP_LNKCAP register to determine the maximum
supported speed. The DT max-link-speed property is now only used as an
optional limit when explicitly specified, which aligns with PCIe subsystem
expectations.
Reviewed-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: No changes
v3: No changes
v2: Collected tag.
drivers/pci/controller/pcie-rzg3s-host.c | 26 ++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
index 76f6d940ba45..985414076a85 100644
--- a/drivers/pci/controller/pcie-rzg3s-host.c
+++ b/drivers/pci/controller/pcie-rzg3s-host.c
@@ -977,8 +977,9 @@ static int rzg3s_pcie_set_max_link_speed(struct rzg3s_pcie_host *host)
{
u32 remote_supported_link_speeds, max_supported_link_speeds;
u32 cs2, tmp, pcie_cap = RZG3S_PCI_CFG_PCIEC;
- u32 cur_link_speed, link_speed;
+ u32 cur_link_speed, link_speed, hw_max_speed;
u8 ltssm_state_l0 = 0xc;
+ u32 lnkcap;
int ret;
u16 ls;
@@ -998,7 +999,22 @@ static int rzg3s_pcie_set_max_link_speed(struct rzg3s_pcie_host *host)
ls = readw_relaxed(host->pcie + pcie_cap + PCI_EXP_LNKSTA);
cs2 = readl_relaxed(host->axi + RZG3S_PCI_PCSTAT2);
- switch (pcie_link_speed[host->max_link_speed]) {
+ /* Read hardware supported link speed from Link Capabilities Register */
+ lnkcap = readl_relaxed(host->pcie + pcie_cap + PCI_EXP_LNKCAP);
+ hw_max_speed = FIELD_GET(PCI_EXP_LNKCAP_SLS, lnkcap);
+
+ /*
+ * Use DT max-link-speed only as a limit. If specified and lower
+ * than hardware capability, cap to that value.
+ */
+ if (host->max_link_speed > 0 && host->max_link_speed < hw_max_speed)
+ hw_max_speed = host->max_link_speed;
+
+ switch (pcie_link_speed[hw_max_speed]) {
+ case PCIE_SPEED_8_0GT:
+ max_supported_link_speeds = GENMASK(PCI_EXP_LNKSTA_CLS_8_0GB - 1, 0);
+ link_speed = PCI_EXP_LNKCTL2_TLS_8_0GT;
+ break;
case PCIE_SPEED_5_0GT:
max_supported_link_speeds = GENMASK(PCI_EXP_LNKSTA_CLS_5_0GB - 1, 0);
link_speed = PCI_EXP_LNKCTL2_TLS_5_0GT;
@@ -1014,10 +1030,10 @@ static int rzg3s_pcie_set_max_link_speed(struct rzg3s_pcie_host *host)
remote_supported_link_speeds &= max_supported_link_speeds;
/*
- * Return if max link speed is already set or the connected device
+ * Return if target link speed is already set or the connected device
* doesn't support it.
*/
- if (cur_link_speed == host->max_link_speed ||
+ if (cur_link_speed == hw_max_speed ||
remote_supported_link_speeds != max_supported_link_speeds)
return 0;
@@ -1609,8 +1625,6 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
host->pcie = host->axi + RZG3S_PCI_CFG_BASE;
host->max_link_speed = of_pci_get_max_link_speed(np);
- if (host->max_link_speed < 0)
- host->max_link_speed = 2;
ret = rzg3s_pcie_host_parse_port(host);
if (ret)
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v4 12/15] PCI: rzg3s-host: Add support for RZ/G3E PCIe controller
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
` (10 preceding siblings ...)
2026-01-29 21:41 ` [PATCH v4 11/15] PCI: rzg3s-host: Add PCIe Gen3 (8.0 GT/s) link speed support John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-01-30 13:57 ` Claudiu Beznea
2026-01-29 21:41 ` [PATCH v4 13/15] arm64: dts: renesas: r9a09g047: Add PCIe node John Madieu
` (2 subsequent siblings)
14 siblings, 1 reply; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
Add support for the PCIe controller found in RZ/G3E SoCs to the existing
RZ/G3S PCIe host driver. The RZ/G3E PCIe controller is similar to the
RZ/G3S's, with the following key differences:
- Supports PCIe Gen3 (8.0 GT/s) link speeds alongside Gen2 (5.0 GT/s)
- Uses a different reset control mechanism via AXI registers instead
of the Linux reset framework
- Requires specific SYSC configuration for link state control and
Root Complex mode selection
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: No changes
v3: No changes
v2:
- Restructure as per Claudiu's comments
- Properly wrap multi-line statements
- Removed driver-specif code for init-off reset. This is now Document
from CPG driver.
drivers/pci/controller/pcie-rzg3s-host.c | 167 ++++++++++++++++++++---
1 file changed, 146 insertions(+), 21 deletions(-)
diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
index 985414076a85..240635dafe69 100644
--- a/drivers/pci/controller/pcie-rzg3s-host.c
+++ b/drivers/pci/controller/pcie-rzg3s-host.c
@@ -111,6 +111,16 @@
#define RZG3S_PCI_PERM_CFG_HWINIT_EN BIT(2)
#define RZG3S_PCI_PERM_PIPE_PHY_REG_EN BIT(1)
+/* RZ/G3E specific registers */
+#define RZG3E_PCI_RESET 0x310
+#define RZG3E_PCI_RESET_RST_OUT_B BIT(6)
+#define RZG3E_PCI_RESET_RST_PS_B BIT(5)
+#define RZG3E_PCI_RESET_RST_LOAD_B BIT(4)
+#define RZG3E_PCI_RESET_RST_CFG_B BIT(3)
+#define RZG3E_PCI_RESET_RST_RSM_B BIT(2)
+#define RZG3E_PCI_RESET_RST_GP_B BIT(1)
+#define RZG3E_PCI_RESET_RST_B BIT(0)
+
#define RZG3S_PCI_MSIRE(id) (0x600 + (id) * 0x10)
#define RZG3S_PCI_MSIRE_ENA BIT(0)
@@ -183,9 +193,13 @@ struct rzg3s_sysc_function {
/**
* struct rzg3s_sysc_info - RZ/G3S System Controller function info
* @rst_rsm_b: Reset RSM_B function descriptor
+ * @l1_allow: L1 power state management function descriptor
+ * @mode: Mode configuration function descriptor
*/
struct rzg3s_sysc_info {
struct rzg3s_sysc_function rst_rsm_b;
+ struct rzg3s_sysc_function l1_allow;
+ struct rzg3s_sysc_function mode;
};
/**
@@ -1124,6 +1138,49 @@ static int rzg3s_config_deinit(struct rzg3s_pcie_host *host)
host->cfg_resets);
}
+/* RZ/G3E SoC-specific config implementations */
+static void rzg3e_pcie_config_pre_init(struct rzg3s_pcie_host *host)
+{
+ /*
+ * De-assert LOAD_B and CFG_B during configuration phase.
+ * These are part of the RZ/G3E reset register, not reset framework.
+ * Other reset bits remain asserted until config_post_init.
+ */
+ rzg3s_pcie_update_bits(host->axi, RZG3E_PCI_RESET,
+ RZG3E_PCI_RESET_RST_LOAD_B | RZG3E_PCI_RESET_RST_CFG_B,
+ RZG3E_PCI_RESET_RST_LOAD_B | RZG3E_PCI_RESET_RST_CFG_B);
+}
+
+static int rzg3e_config_deinit(struct rzg3s_pcie_host *host)
+{
+ writel_relaxed(0, host->axi + RZG3E_PCI_RESET);
+ return 0;
+}
+
+static int rzg3e_config_post_init(struct rzg3s_pcie_host *host)
+{
+ /* De-assert PS_B, GP_B, RST_B */
+ rzg3s_pcie_update_bits(host->axi, RZG3E_PCI_RESET,
+ RZG3E_PCI_RESET_RST_PS_B | RZG3E_PCI_RESET_RST_GP_B |
+ RZG3E_PCI_RESET_RST_B,
+ RZG3E_PCI_RESET_RST_PS_B | RZG3E_PCI_RESET_RST_GP_B |
+ RZG3E_PCI_RESET_RST_B);
+
+ /*
+ * According to the RZ/G3E HW manual (Rev.1.15, Table 6.6-130
+ * Initialization Procedure (RC)), hardware requires >= 500us delay
+ * before final reset deassert.
+ */
+ fsleep(500);
+
+ /* De-assert OUT_B and RSM_B to complete reset sequence */
+ rzg3s_pcie_update_bits(host->axi, RZG3E_PCI_RESET,
+ RZG3E_PCI_RESET_RST_OUT_B | RZG3E_PCI_RESET_RST_RSM_B,
+ RZG3E_PCI_RESET_RST_OUT_B | RZG3E_PCI_RESET_RST_RSM_B);
+
+ return 0;
+}
+
static void rzg3s_pcie_irq_init(struct rzg3s_pcie_host *host)
{
/*
@@ -1268,6 +1325,7 @@ static int rzg3s_pcie_host_init_port(struct rzg3s_pcie_host *host)
static int rzg3s_pcie_host_init(struct rzg3s_pcie_host *host)
{
+ const struct rzg3s_sysc_info *sysc_info = host->sysc->info;
u32 val;
int ret;
@@ -1284,6 +1342,16 @@ static int rzg3s_pcie_host_init(struct rzg3s_pcie_host *host)
if (ret)
goto config_deinit;
+ /* Enable ASPM L1 transition for SoCs that use it */
+ if (sysc_info->l1_allow.mask) {
+ ret = regmap_update_bits(host->sysc->regmap,
+ sysc_info->l1_allow.offset,
+ sysc_info->l1_allow.mask,
+ field_prep(sysc_info->l1_allow.mask, 1));
+ if (ret)
+ goto config_deinit;
+ }
+
/* Initialize the interrupts */
rzg3s_pcie_irq_init(host);
@@ -1636,11 +1704,25 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
goto port_refclk_put;
}
- ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
- sysc->info->rst_rsm_b.mask,
- field_prep(sysc->info->rst_rsm_b.mask, 1));
- if (ret)
- goto port_refclk_put;
+ /*
+ * Put controller in RC (Root Complex) mode for SoCs that
+ * support it. These can operate in either EP or RC mode.
+ */
+ if (sysc->info->mode.mask) {
+ ret = regmap_write(sysc->regmap, sysc->info->mode.offset,
+ sysc->info->mode.mask);
+ if (ret)
+ goto port_refclk_put;
+ }
+
+ if (sysc->info->rst_rsm_b.mask) {
+ ret = regmap_update_bits(sysc->regmap,
+ sysc->info->rst_rsm_b.offset,
+ sysc->info->rst_rsm_b.mask,
+ field_prep(sysc->info->rst_rsm_b.mask, 1));
+ if (ret)
+ goto port_refclk_put;
+ }
ret = rzg3s_pcie_resets_prepare_and_get(host);
if (ret)
@@ -1690,9 +1772,12 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
* SYSC RST_RSM_B signal need to be asserted before turning off the
* power to the PHY.
*/
- regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
- sysc->info->rst_rsm_b.mask,
- field_prep(sysc->info->rst_rsm_b.mask, 0));
+ if (sysc->info->rst_rsm_b.mask) {
+ regmap_update_bits(sysc->regmap,
+ sysc->info->rst_rsm_b.offset,
+ sysc->info->rst_rsm_b.mask,
+ field_prep(sysc->info->rst_rsm_b.mask, 0));
+ }
port_refclk_put:
clk_put(host->port.refclk);
@@ -1723,11 +1808,14 @@ static int rzg3s_pcie_suspend_noirq(struct device *dev)
if (ret)
goto config_reinit;
- ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
- sysc->info->rst_rsm_b.mask,
- field_prep(sysc->info->rst_rsm_b.mask, 0));
- if (ret)
- goto power_resets_restore;
+ if (sysc->info->rst_rsm_b.mask) {
+ ret = regmap_update_bits(sysc->regmap,
+ sysc->info->rst_rsm_b.offset,
+ sysc->info->rst_rsm_b.mask,
+ field_prep(sysc->info->rst_rsm_b.mask, 0));
+ if (ret)
+ goto power_resets_restore;
+ }
return 0;
@@ -1750,11 +1838,21 @@ static int rzg3s_pcie_resume_noirq(struct device *dev)
struct rzg3s_sysc *sysc = host->sysc;
int ret;
- ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
- sysc->info->rst_rsm_b.mask,
- field_prep(sysc->info->rst_rsm_b.mask, 1));
- if (ret)
- return ret;
+ if (sysc->info->mode.mask) {
+ ret = regmap_write(sysc->regmap, sysc->info->mode.offset,
+ sysc->info->mode.mask);
+ if (ret)
+ return ret;
+ }
+
+ if (sysc->info->rst_rsm_b.mask) {
+ ret = regmap_update_bits(sysc->regmap,
+ sysc->info->rst_rsm_b.offset,
+ sysc->info->rst_rsm_b.mask,
+ field_prep(sysc->info->rst_rsm_b.mask, 1));
+ if (ret)
+ return ret;
+ }
ret = rzg3s_pcie_power_resets_deassert(host);
if (ret)
@@ -1781,9 +1879,12 @@ static int rzg3s_pcie_resume_noirq(struct device *dev)
reset_control_bulk_assert(data->num_power_resets,
host->power_resets);
assert_rst_rsm_b:
- regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
- sysc->info->rst_rsm_b.mask,
- field_prep(sysc->info->rst_rsm_b.mask, 0));
+ if (sysc->info->rst_rsm_b.mask) {
+ regmap_update_bits(sysc->regmap,
+ sysc->info->rst_rsm_b.offset,
+ sysc->info->rst_rsm_b.mask,
+ field_prep(sysc->info->rst_rsm_b.mask, 0));
+ }
return ret;
}
@@ -1816,11 +1917,35 @@ static const struct rzg3s_pcie_soc_data rzg3s_soc_data = {
},
};
+static const char * const rzg3e_soc_power_resets[] = { "aresetn" };
+
+static const struct rzg3s_pcie_soc_data rzg3e_soc_data = {
+ .power_resets = rzg3e_soc_power_resets,
+ .num_power_resets = ARRAY_SIZE(rzg3e_soc_power_resets),
+ .config_pre_init = rzg3e_pcie_config_pre_init,
+ .config_post_init = rzg3e_config_post_init,
+ .config_deinit = rzg3e_config_deinit,
+ .sysc_info = {
+ .l1_allow = {
+ .offset = 0x1020,
+ .mask = BIT(0),
+ },
+ .mode = {
+ .offset = 0x1024,
+ .mask = BIT(0),
+ },
+ },
+};
+
static const struct of_device_id rzg3s_pcie_of_match[] = {
{
.compatible = "renesas,r9a08g045-pcie",
.data = &rzg3s_soc_data,
},
+ {
+ .compatible = "renesas,r9a09g047-pcie",
+ .data = &rzg3e_soc_data,
+ },
{}
};
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v4 12/15] PCI: rzg3s-host: Add support for RZ/G3E PCIe controller
2026-01-29 21:41 ` [PATCH v4 12/15] PCI: rzg3s-host: Add support for RZ/G3E PCIe controller John Madieu
@ 2026-01-30 13:57 ` Claudiu Beznea
2026-01-30 20:23 ` John Madieu
0 siblings, 1 reply; 27+ messages in thread
From: Claudiu Beznea @ 2026-01-30 13:57 UTC (permalink / raw)
To: John Madieu, claudiu.beznea.uj, lpieralisi, kwilczynski, mani,
geert+renesas, krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu
Hi, John,
On 1/29/26 23:41, John Madieu wrote:
> Add support for the PCIe controller found in RZ/G3E SoCs to the existing
> RZ/G3S PCIe host driver. The RZ/G3E PCIe controller is similar to the
> RZ/G3S's, with the following key differences:
>
> - Supports PCIe Gen3 (8.0 GT/s) link speeds alongside Gen2 (5.0 GT/s)
> - Uses a different reset control mechanism via AXI registers instead
> of the Linux reset framework
> - Requires specific SYSC configuration for link state control and
> Root Complex mode selection
>
> Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> ---
>
> Changes:
>
> v4: No changes
> v3: No changes
>
> v2:
> - Restructure as per Claudiu's comments
> - Properly wrap multi-line statements
> - Removed driver-specif code for init-off reset. This is now Document
> from CPG driver.
>
> drivers/pci/controller/pcie-rzg3s-host.c | 167 ++++++++++++++++++++---
> 1 file changed, 146 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
> index 985414076a85..240635dafe69 100644
> --- a/drivers/pci/controller/pcie-rzg3s-host.c
> +++ b/drivers/pci/controller/pcie-rzg3s-host.c
> @@ -111,6 +111,16 @@
> #define RZG3S_PCI_PERM_CFG_HWINIT_EN BIT(2)
> #define RZG3S_PCI_PERM_PIPE_PHY_REG_EN BIT(1)
>
> +/* RZ/G3E specific registers */
> +#define RZG3E_PCI_RESET 0x310
> +#define RZG3E_PCI_RESET_RST_OUT_B BIT(6)
> +#define RZG3E_PCI_RESET_RST_PS_B BIT(5)
> +#define RZG3E_PCI_RESET_RST_LOAD_B BIT(4)
> +#define RZG3E_PCI_RESET_RST_CFG_B BIT(3)
> +#define RZG3E_PCI_RESET_RST_RSM_B BIT(2)
> +#define RZG3E_PCI_RESET_RST_GP_B BIT(1)
> +#define RZG3E_PCI_RESET_RST_B BIT(0)
> +
> #define RZG3S_PCI_MSIRE(id) (0x600 + (id) * 0x10)
> #define RZG3S_PCI_MSIRE_ENA BIT(0)
>
> @@ -183,9 +193,13 @@ struct rzg3s_sysc_function {
> /**
> * struct rzg3s_sysc_info - RZ/G3S System Controller function info
> * @rst_rsm_b: Reset RSM_B function descriptor
> + * @l1_allow: L1 power state management function descriptor
> + * @mode: Mode configuration function descriptor
> */
> struct rzg3s_sysc_info {
> struct rzg3s_sysc_function rst_rsm_b;
> + struct rzg3s_sysc_function l1_allow;
> + struct rzg3s_sysc_function mode;
> };
>
> /**
> @@ -1124,6 +1138,49 @@ static int rzg3s_config_deinit(struct rzg3s_pcie_host *host)
> host->cfg_resets);
> }
>
> +/* RZ/G3E SoC-specific config implementations */
> +static void rzg3e_pcie_config_pre_init(struct rzg3s_pcie_host *host)
> +{
> + /*
> + * De-assert LOAD_B and CFG_B during configuration phase.
> + * These are part of the RZ/G3E reset register, not reset framework.
> + * Other reset bits remain asserted until config_post_init.
> + */
> + rzg3s_pcie_update_bits(host->axi, RZG3E_PCI_RESET,
> + RZG3E_PCI_RESET_RST_LOAD_B | RZG3E_PCI_RESET_RST_CFG_B,
> + RZG3E_PCI_RESET_RST_LOAD_B | RZG3E_PCI_RESET_RST_CFG_B);
> +}
> +
> +static int rzg3e_config_deinit(struct rzg3s_pcie_host *host)
> +{
> + writel_relaxed(0, host->axi + RZG3E_PCI_RESET);
> + return 0;
> +}
> +
> +static int rzg3e_config_post_init(struct rzg3s_pcie_host *host)
> +{
> + /* De-assert PS_B, GP_B, RST_B */
> + rzg3s_pcie_update_bits(host->axi, RZG3E_PCI_RESET,
> + RZG3E_PCI_RESET_RST_PS_B | RZG3E_PCI_RESET_RST_GP_B |
> + RZG3E_PCI_RESET_RST_B,
> + RZG3E_PCI_RESET_RST_PS_B | RZG3E_PCI_RESET_RST_GP_B |
> + RZG3E_PCI_RESET_RST_B);
> +
> + /*
> + * According to the RZ/G3E HW manual (Rev.1.15, Table 6.6-130
> + * Initialization Procedure (RC)), hardware requires >= 500us delay
> + * before final reset deassert.
> + */
> + fsleep(500);
> +
> + /* De-assert OUT_B and RSM_B to complete reset sequence */
> + rzg3s_pcie_update_bits(host->axi, RZG3E_PCI_RESET,
> + RZG3E_PCI_RESET_RST_OUT_B | RZG3E_PCI_RESET_RST_RSM_B,
> + RZG3E_PCI_RESET_RST_OUT_B | RZG3E_PCI_RESET_RST_RSM_B);
> +
> + return 0;
> +}
> +
> static void rzg3s_pcie_irq_init(struct rzg3s_pcie_host *host)
> {
> /*
> @@ -1268,6 +1325,7 @@ static int rzg3s_pcie_host_init_port(struct rzg3s_pcie_host *host)
>
> static int rzg3s_pcie_host_init(struct rzg3s_pcie_host *host)
> {
> + const struct rzg3s_sysc_info *sysc_info = host->sysc->info;
> u32 val;
> int ret;
>
> @@ -1284,6 +1342,16 @@ static int rzg3s_pcie_host_init(struct rzg3s_pcie_host *host)
> if (ret)
> goto config_deinit;
>
> + /* Enable ASPM L1 transition for SoCs that use it */
> + if (sysc_info->l1_allow.mask) {
> + ret = regmap_update_bits(host->sysc->regmap,
> + sysc_info->l1_allow.offset,
> + sysc_info->l1_allow.mask,
> + field_prep(sysc_info->l1_allow.mask, 1));
> + if (ret)
> + goto config_deinit;
> + }
> +
> /* Initialize the interrupts */
> rzg3s_pcie_irq_init(host);
>
> @@ -1636,11 +1704,25 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
> goto port_refclk_put;
> }
>
> - ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
> - sysc->info->rst_rsm_b.mask,
> - field_prep(sysc->info->rst_rsm_b.mask, 1));
> - if (ret)
> - goto port_refclk_put;
> + /*
> + * Put controller in RC (Root Complex) mode for SoCs that
> + * support it. These can operate in either EP or RC mode.
> + */
> + if (sysc->info->mode.mask) {
> + ret = regmap_write(sysc->regmap, sysc->info->mode.offset,
> + sysc->info->mode.mask);
> + if (ret)
> + goto port_refclk_put;
> + }
> +
> + if (sysc->info->rst_rsm_b.mask) {
> + ret = regmap_update_bits(sysc->regmap,
> + sysc->info->rst_rsm_b.offset,
> + sysc->info->rst_rsm_b.mask,
> + field_prep(sysc->info->rst_rsm_b.mask, 1));
> + if (ret)
> + goto port_refclk_put;
> + }
sysc configuration pattern is repeated in different places. I think it could be
replaced by something like:
static int rzg3s_sysc_config(struct sysc_info *sysc, int mode, int rsm_b)
{
struct rzg3s_sysc_info *info = sysc->info;
int ret;
if (mode > 0 && info->mode.mask) {
ret = regmap_write(sysc->regmap, info->mode.offset,
field_prep(info->mode.mask, mode));
if (ret)
return ret;
}
if (rsm_b > 0 && info->rst_rsm_b.mask) {
ret = regmap_update_bits(sysc->regmap, info->rst_rsm_b.offset,
info->rst_rsm_b.mask,
field_prep(info->rst_rsm_b.mask, 1));
if (ret)
return ret;
}
// l1 allow configuration could be added as well.
return 0;
}
And call it here like:
ret = rzg3s_sysc_config(sysc, 1, 1);
if (ret)
goto port_refclk_put;
>
> ret = rzg3s_pcie_resets_prepare_and_get(host);
> if (ret)
> @@ -1690,9 +1772,12 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
> * SYSC RST_RSM_B signal need to be asserted before turning off the
> * power to the PHY.
> */
> - regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
> - sysc->info->rst_rsm_b.mask,
> - field_prep(sysc->info->rst_rsm_b.mask, 0));
> + if (sysc->info->rst_rsm_b.mask) {
> + regmap_update_bits(sysc->regmap,
> + sysc->info->rst_rsm_b.offset,
This can fit on the previous line to save one exta line of code.
> + sysc->info->rst_rsm_b.mask,
> + field_prep(sysc->info->rst_rsm_b.mask, 0));
> + }
And it could be replaced by, if any:
rzg3s_sysc_config(sysc, -1, 0);
> port_refclk_put:
> clk_put(host->port.refclk);
>
> @@ -1723,11 +1808,14 @@ static int rzg3s_pcie_suspend_noirq(struct device *dev)
> if (ret)
> goto config_reinit;
>
> - ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
> - sysc->info->rst_rsm_b.mask,
> - field_prep(sysc->info->rst_rsm_b.mask, 0));
> - if (ret)
> - goto power_resets_restore;
> + if (sysc->info->rst_rsm_b.mask) {
> + ret = regmap_update_bits(sysc->regmap,
> + sysc->info->rst_rsm_b.offset,
> + sysc->info->rst_rsm_b.mask,
> + field_prep(sysc->info->rst_rsm_b.mask, 0));
> + if (ret)
> + goto power_resets_restore;
> + }
Same here, if sysc config is done through the above proposed code:
rzg3s_sysc_config(sysc, -1, 0);
>
> return 0;
>
> @@ -1750,11 +1838,21 @@ static int rzg3s_pcie_resume_noirq(struct device *dev)
> struct rzg3s_sysc *sysc = host->sysc;
> int ret;
>
> - ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
> - sysc->info->rst_rsm_b.mask,
> - field_prep(sysc->info->rst_rsm_b.mask, 1));
> - if (ret)
> - return ret;
> + if (sysc->info->mode.mask) {
> + ret = regmap_write(sysc->regmap, sysc->info->mode.offset,
> + sysc->info->mode.mask);
> + if (ret)
> + return ret;
> + }
> +
> + if (sysc->info->rst_rsm_b.mask) {
> + ret = regmap_update_bits(sysc->regmap,
> + sysc->info->rst_rsm_b.offset,
Same here, this can fit on the previous line.
> + sysc->info->rst_rsm_b.mask,
> + field_prep(sysc->info->rst_rsm_b.mask, 1));
> + if (ret)
> + return ret;
> + }
And this block could be replaced by:
ret = rzg3s_sysc_config(sysc, 1, 1);
>
> ret = rzg3s_pcie_power_resets_deassert(host);
> if (ret)
> @@ -1781,9 +1879,12 @@ static int rzg3s_pcie_resume_noirq(struct device *dev)
> reset_control_bulk_assert(data->num_power_resets,
> host->power_resets);
> assert_rst_rsm_b:
> - regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
> - sysc->info->rst_rsm_b.mask,
> - field_prep(sysc->info->rst_rsm_b.mask, 0));
> + if (sysc->info->rst_rsm_b.mask) {
> + regmap_update_bits(sysc->regmap,
> + sysc->info->rst_rsm_b.offset,
> + sysc->info->rst_rsm_b.mask,
> + field_prep(sysc->info->rst_rsm_b.mask, 0));
> + }
And this:
rzg3s_sysc_config(sysc, -1, 0);
Thank you,
Claudiu
^ permalink raw reply [flat|nested] 27+ messages in thread* RE: [PATCH v4 12/15] PCI: rzg3s-host: Add support for RZ/G3E PCIe controller
2026-01-30 13:57 ` Claudiu Beznea
@ 2026-01-30 20:23 ` John Madieu
0 siblings, 0 replies; 27+ messages in thread
From: John Madieu @ 2026-01-30 20:23 UTC (permalink / raw)
To: Claudiu.Beznea, Claudiu Beznea, lpieralisi@kernel.org,
kwilczynski@kernel.org, mani@kernel.org, geert+renesas@glider.be,
krzk+dt@kernel.org
Cc: robh@kernel.org, bhelgaas@google.com, conor+dt@kernel.org,
magnus.damm, Biju Das, linux-pci@vger.kernel.org,
linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org,
linux-clk@vger.kernel.org, john.madieu@gmail.com
Hi Claudiu,
Thanks for your review.
> -----Original Message-----
> From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
> Sent: Friday, January 30, 2026 2:57 PM
> To: John Madieu <john.madieu.xa@bp.renesas.com>; Claudiu Beznea
> <claudiu.beznea.uj@bp.renesas.com>; lpieralisi@kernel.org;
> kwilczynski@kernel.org; mani@kernel.org; geert+renesas@glider.be;
> krzk+dt@kernel.org
> Cc: robh@kernel.org; bhelgaas@google.com; conor+dt@kernel.org; magnus.damm
> <magnus.damm@gmail.com>; Biju Das <biju.das.jz@bp.renesas.com>; linux-
> pci@vger.kernel.org; linux-renesas-soc@vger.kernel.org;
> devicetree@vger.kernel.org; linux-clk@vger.kernel.org;
> john.madieu@gmail.com
> Subject: Re: [PATCH v4 12/15] PCI: rzg3s-host: Add support for RZ/G3E PCIe
> controller
>
> Hi, John,
>
> On 1/29/26 23:41, John Madieu wrote:
> > Add support for the PCIe controller found in RZ/G3E SoCs to the
> > existing RZ/G3S PCIe host driver. The RZ/G3E PCIe controller is
> > similar to the RZ/G3S's, with the following key differences:
> >
> > - Supports PCIe Gen3 (8.0 GT/s) link speeds alongside Gen2 (5.0 GT/s)
> > - Uses a different reset control mechanism via AXI registers instead
> > of the Linux reset framework
> > - Requires specific SYSC configuration for link state control and
> > Root Complex mode selection
> >
> > Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> > ---
> >
> > Changes:
> >
> > v4: No changes
> > v3: No changes
> >
> > v2:
> > - Restructure as per Claudiu's comments
> > - Properly wrap multi-line statements
> > - Removed driver-specif code for init-off reset. This is now Document
> > from CPG driver.
> >
> > drivers/pci/controller/pcie-rzg3s-host.c | 167 ++++++++++++++++++++---
> > 1 file changed, 146 insertions(+), 21 deletions(-)
> >
> > diff --git a/drivers/pci/controller/pcie-rzg3s-host.c
> > b/drivers/pci/controller/pcie-rzg3s-host.c
> > index 985414076a85..240635dafe69 100644
> > --- a/drivers/pci/controller/pcie-rzg3s-host.c
> > +++ b/drivers/pci/controller/pcie-rzg3s-host.c
> > @@ -111,6 +111,16 @@
> > #define RZG3S_PCI_PERM_CFG_HWINIT_EN BIT(2)
> > #define RZG3S_PCI_PERM_PIPE_PHY_REG_EN BIT(1)
> >
> > +/* RZ/G3E specific registers */
> > +#define RZG3E_PCI_RESET 0x310
> > +#define RZG3E_PCI_RESET_RST_OUT_B BIT(6)
> > +#define RZG3E_PCI_RESET_RST_PS_B BIT(5)
> > +#define RZG3E_PCI_RESET_RST_LOAD_B BIT(4)
> > +#define RZG3E_PCI_RESET_RST_CFG_B BIT(3)
> > +#define RZG3E_PCI_RESET_RST_RSM_B BIT(2)
> > +#define RZG3E_PCI_RESET_RST_GP_B BIT(1)
> > +#define RZG3E_PCI_RESET_RST_B BIT(0)
> > +
> > #define RZG3S_PCI_MSIRE(id) (0x600 + (id) * 0x10)
> > #define RZG3S_PCI_MSIRE_ENA BIT(0)
> >
> > @@ -183,9 +193,13 @@ struct rzg3s_sysc_function {
> > /**
> > * struct rzg3s_sysc_info - RZ/G3S System Controller function info
> > * @rst_rsm_b: Reset RSM_B function descriptor
> > + * @l1_allow: L1 power state management function descriptor
> > + * @mode: Mode configuration function descriptor
> > */
> > struct rzg3s_sysc_info {
> > struct rzg3s_sysc_function rst_rsm_b;
> > + struct rzg3s_sysc_function l1_allow;
> > + struct rzg3s_sysc_function mode;
> > };
> >
> > /**
> > @@ -1124,6 +1138,49 @@ static int rzg3s_config_deinit(struct
> rzg3s_pcie_host *host)
> > host->cfg_resets);
> > }
> >
> > +/* RZ/G3E SoC-specific config implementations */ static void
> > +rzg3e_pcie_config_pre_init(struct rzg3s_pcie_host *host) {
> > + /*
> > + * De-assert LOAD_B and CFG_B during configuration phase.
> > + * These are part of the RZ/G3E reset register, not reset framework.
> > + * Other reset bits remain asserted until config_post_init.
> > + */
> > + rzg3s_pcie_update_bits(host->axi, RZG3E_PCI_RESET,
> > + RZG3E_PCI_RESET_RST_LOAD_B |
> RZG3E_PCI_RESET_RST_CFG_B,
> > + RZG3E_PCI_RESET_RST_LOAD_B |
> RZG3E_PCI_RESET_RST_CFG_B); }
> > +
> > +static int rzg3e_config_deinit(struct rzg3s_pcie_host *host) {
> > + writel_relaxed(0, host->axi + RZG3E_PCI_RESET);
> > + return 0;
> > +}
> > +
> > +static int rzg3e_config_post_init(struct rzg3s_pcie_host *host) {
> > + /* De-assert PS_B, GP_B, RST_B */
> > + rzg3s_pcie_update_bits(host->axi, RZG3E_PCI_RESET,
> > + RZG3E_PCI_RESET_RST_PS_B |
> RZG3E_PCI_RESET_RST_GP_B |
> > + RZG3E_PCI_RESET_RST_B,
> > + RZG3E_PCI_RESET_RST_PS_B |
> RZG3E_PCI_RESET_RST_GP_B |
> > + RZG3E_PCI_RESET_RST_B);
> > +
> > + /*
> > + * According to the RZ/G3E HW manual (Rev.1.15, Table 6.6-130
> > + * Initialization Procedure (RC)), hardware requires >= 500us delay
> > + * before final reset deassert.
> > + */
> > + fsleep(500);
> > +
> > + /* De-assert OUT_B and RSM_B to complete reset sequence */
> > + rzg3s_pcie_update_bits(host->axi, RZG3E_PCI_RESET,
> > + RZG3E_PCI_RESET_RST_OUT_B |
> RZG3E_PCI_RESET_RST_RSM_B,
> > + RZG3E_PCI_RESET_RST_OUT_B |
> RZG3E_PCI_RESET_RST_RSM_B);
> > +
> > + return 0;
> > +}
> > +
> > static void rzg3s_pcie_irq_init(struct rzg3s_pcie_host *host)
> > {
> > /*
> > @@ -1268,6 +1325,7 @@ static int rzg3s_pcie_host_init_port(struct
> > rzg3s_pcie_host *host)
> >
> > static int rzg3s_pcie_host_init(struct rzg3s_pcie_host *host)
> > {
> > + const struct rzg3s_sysc_info *sysc_info = host->sysc->info;
> > u32 val;
> > int ret;
> >
> > @@ -1284,6 +1342,16 @@ static int rzg3s_pcie_host_init(struct
> rzg3s_pcie_host *host)
> > if (ret)
> > goto config_deinit;
> >
> > + /* Enable ASPM L1 transition for SoCs that use it */
> > + if (sysc_info->l1_allow.mask) {
> > + ret = regmap_update_bits(host->sysc->regmap,
> > + sysc_info->l1_allow.offset,
> > + sysc_info->l1_allow.mask,
> > + field_prep(sysc_info->l1_allow.mask, 1));
> > + if (ret)
> > + goto config_deinit;
> > + }
> > +
> > /* Initialize the interrupts */
> > rzg3s_pcie_irq_init(host);
> >
> > @@ -1636,11 +1704,25 @@ static int rzg3s_pcie_probe(struct
> platform_device *pdev)
> > goto port_refclk_put;
> > }
> >
> > - ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
> > - sysc->info->rst_rsm_b.mask,
> > - field_prep(sysc->info->rst_rsm_b.mask, 1));
> > - if (ret)
> > - goto port_refclk_put;
> > + /*
> > + * Put controller in RC (Root Complex) mode for SoCs that
> > + * support it. These can operate in either EP or RC mode.
> > + */
> > + if (sysc->info->mode.mask) {
> > + ret = regmap_write(sysc->regmap, sysc->info->mode.offset,
> > + sysc->info->mode.mask);
> > + if (ret)
> > + goto port_refclk_put;
> > + }
> > +
> > + if (sysc->info->rst_rsm_b.mask) {
> > + ret = regmap_update_bits(sysc->regmap,
> > + sysc->info->rst_rsm_b.offset,
> > + sysc->info->rst_rsm_b.mask,
> > + field_prep(sysc->info->rst_rsm_b.mask, 1));
> > + if (ret)
> > + goto port_refclk_put;
> > + }
>
> sysc configuration pattern is repeated in different places. I think it
> could be replaced by something like:
>
> static int rzg3s_sysc_config(struct sysc_info *sysc, int mode, int rsm_b)
> {
> struct rzg3s_sysc_info *info = sysc->info;
> int ret;
>
> if (mode > 0 && info->mode.mask) {
> ret = regmap_write(sysc->regmap, info->mode.offset,
> field_prep(info->mode.mask, mode));
> if (ret)
> return ret;
> }
>
> if (rsm_b > 0 && info->rst_rsm_b.mask) {
> ret = regmap_update_bits(sysc->regmap, info->rst_rsm_b.offset,
> info->rst_rsm_b.mask,
> field_prep(info->rst_rsm_b.mask, 1));
> if (ret)
> return ret;
> }
>
> // l1 allow configuration could be added as well.
>
> return 0;
> }
>
> And call it here like:
> ret = rzg3s_sysc_config(sysc, 1, 1);
> if (ret)
> goto port_refclk_put;
>
Indeed, I'll adopt this in next version.
>
> >
> > ret = rzg3s_pcie_resets_prepare_and_get(host);
> > if (ret)
> > @@ -1690,9 +1772,12 @@ static int rzg3s_pcie_probe(struct
> platform_device *pdev)
> > * SYSC RST_RSM_B signal need to be asserted before turning off the
> > * power to the PHY.
> > */
> > - regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
> > - sysc->info->rst_rsm_b.mask,
> > - field_prep(sysc->info->rst_rsm_b.mask, 0));
> > + if (sysc->info->rst_rsm_b.mask) {
> > + regmap_update_bits(sysc->regmap,
> > + sysc->info->rst_rsm_b.offset,
>
> This can fit on the previous line to save one exta line of code.
Noted.
>
> > + sysc->info->rst_rsm_b.mask,
> > + field_prep(sysc->info->rst_rsm_b.mask, 0));
> > + }
>
> And it could be replaced by, if any:
> rzg3s_sysc_config(sysc, -1, 0);
>
Noted.
> > port_refclk_put:
> > clk_put(host->port.refclk);
> >
> > @@ -1723,11 +1808,14 @@ static int rzg3s_pcie_suspend_noirq(struct
> device *dev)
> > if (ret)
> > goto config_reinit;
> >
> > - ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
> > - sysc->info->rst_rsm_b.mask,
> > - field_prep(sysc->info->rst_rsm_b.mask, 0));
> > - if (ret)
> > - goto power_resets_restore;
> > + if (sysc->info->rst_rsm_b.mask) {
> > + ret = regmap_update_bits(sysc->regmap,
> > + sysc->info->rst_rsm_b.offset,
> > + sysc->info->rst_rsm_b.mask,
> > + field_prep(sysc->info->rst_rsm_b.mask, 0));
> > + if (ret)
> > + goto power_resets_restore;
> > + }
>
> Same here, if sysc config is done through the above proposed code:
>
> rzg3s_sysc_config(sysc, -1, 0);
>
Noted for v5, as well as other comments.
Regards,
John.
> >
> > return 0;
> >
> > @@ -1750,11 +1838,21 @@ static int rzg3s_pcie_resume_noirq(struct device
> *dev)
> > struct rzg3s_sysc *sysc = host->sysc;
> > int ret;
> >
> > - ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
> > - sysc->info->rst_rsm_b.mask,
> > - field_prep(sysc->info->rst_rsm_b.mask, 1));
> > - if (ret)
> > - return ret;
> > + if (sysc->info->mode.mask) {
> > + ret = regmap_write(sysc->regmap, sysc->info->mode.offset,
> > + sysc->info->mode.mask);
> > + if (ret)
> > + return ret;
> > + }
> > +
> > + if (sysc->info->rst_rsm_b.mask) {
> > + ret = regmap_update_bits(sysc->regmap,
> > + sysc->info->rst_rsm_b.offset,
>
> Same here, this can fit on the previous line.
>
> > + sysc->info->rst_rsm_b.mask,
> > + field_prep(sysc->info->rst_rsm_b.mask, 1));
> > + if (ret)
> > + return ret;
> > + }
>
> And this block could be replaced by:
>
> ret = rzg3s_sysc_config(sysc, 1, 1);
>
> >
> > ret = rzg3s_pcie_power_resets_deassert(host);
> > if (ret)
> > @@ -1781,9 +1879,12 @@ static int rzg3s_pcie_resume_noirq(struct device
> *dev)
> > reset_control_bulk_assert(data->num_power_resets,
> > host->power_resets);
> > assert_rst_rsm_b:
> > - regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset,
> > - sysc->info->rst_rsm_b.mask,
> > - field_prep(sysc->info->rst_rsm_b.mask, 0));
> > + if (sysc->info->rst_rsm_b.mask) {
> > + regmap_update_bits(sysc->regmap,
> > + sysc->info->rst_rsm_b.offset,
> > + sysc->info->rst_rsm_b.mask,
> > + field_prep(sysc->info->rst_rsm_b.mask, 0));
> > + }
>
> And this:
>
> rzg3s_sysc_config(sysc, -1, 0);
>
> Thank you,
> Claudiu
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v4 13/15] arm64: dts: renesas: r9a09g047: Add PCIe node
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
` (11 preceding siblings ...)
2026-01-29 21:41 ` [PATCH v4 12/15] PCI: rzg3s-host: Add support for RZ/G3E PCIe controller John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-01-29 21:41 ` [PATCH v4 14/15] arm64: dts: renesas: r9a09g047e57-smarc-som: Add PCIe reference clock John Madieu
2026-01-29 21:41 ` [PATCH v4 15/15] arm64: dts: renesas: r9a09g047e57-smarc: Enable PCIe John Madieu
14 siblings, 0 replies; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
The RZ/G3E SoC family features an x2 PCIe IP. Add the PCIe node.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: No changes
v3: No changes
v2:
- Roerder interrupts and interrupt names to match binding
arch/arm64/boot/dts/renesas/r9a09g047.dtsi | 69 ++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r9a09g047.dtsi b/arch/arm64/boot/dts/renesas/r9a09g047.dtsi
index cbb48ff5028f..2eccaa7ed1c5 100644
--- a/arch/arm64/boot/dts/renesas/r9a09g047.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a09g047.dtsi
@@ -841,6 +841,75 @@ wdt3: watchdog@13000400 {
status = "disabled";
};
+ pcie: pcie@13400000 {
+ compatible = "renesas,r9a09g047-pcie";
+ reg = <0 0x13400000 0 0x10000>;
+ ranges = <0x02000000 0 0x30000000 0 0x30000000 0 0x8000000>,
+ <0x43000000 4 0x40000000 4 0x40000000 6 0x00000000>;
+ dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 2 0x00000000>;
+ bus-range = <0x0 0xff>;
+ interrupts = <GIC_SPI 800 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 801 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 802 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 803 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 806 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 792 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 793 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 794 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 795 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 796 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 797 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 799 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 804 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 805 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 807 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 791 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 798 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 808 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 809 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 810 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 811 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 812 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 813 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "serr", "serr_cor", "serr_nonfatal",
+ "serr_fatal", "axi_err", "inta",
+ "intb", "intc", "intd", "msi",
+ "link_bandwidth", "pm_pme", "dma",
+ "pcie_evt", "msg", "all",
+ "link_equalization_request",
+ "turn_off_event", "pmu_poweroff",
+ "d3_event_f0", "d3_event_f1",
+ "cfg_pmcsr_writeclear_f0",
+ "cfg_pmcsr_writeclear_f1";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie 0 0 0 0>, /* INTA */
+ <0 0 0 2 &pcie 0 0 0 1>, /* INTB */
+ <0 0 0 3 &pcie 0 0 0 2>, /* INTC */
+ <0 0 0 4 &pcie 0 0 0 3>; /* INTD */
+ clocks = <&cpg CPG_MOD 0xc4>, <&cpg CPG_MOD 0xc5>;
+ clock-names = "aclk", "pmu";
+ resets = <&cpg 0xb2>;
+ reset-names = "aresetn";
+ power-domains = <&cpg>;
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ renesas,sysc = <&sys>;
+ status = "disabled";
+
+ pcie_port0: pcie@0,0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ ranges;
+ device_type = "pci";
+ vendor-id = <0x1912>;
+ device-id = <0x0039>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ };
+ };
+
tsu: thermal@14002000 {
compatible = "renesas,r9a09g047-tsu";
reg = <0 0x14002000 0 0x1000>;
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v4 14/15] arm64: dts: renesas: r9a09g047e57-smarc-som: Add PCIe reference clock
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
` (12 preceding siblings ...)
2026-01-29 21:41 ` [PATCH v4 13/15] arm64: dts: renesas: r9a09g047: Add PCIe node John Madieu
@ 2026-01-29 21:41 ` John Madieu
2026-01-29 21:41 ` [PATCH v4 15/15] arm64: dts: renesas: r9a09g047e57-smarc: Enable PCIe John Madieu
14 siblings, 0 replies; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
The RZ/G3E SMARC SoM has a fixed 100 MHz reference clock generator
for PCIe. Model it as a fixed-clock and assign it to the PCIe port.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: No changes
v3: No changes
v2: No changes
arch/arm64/boot/dts/renesas/rzg3e-smarc-som.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/rzg3e-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg3e-smarc-som.dtsi
index eb0de21d6716..7e2345bb9918 100644
--- a/arch/arm64/boot/dts/renesas/rzg3e-smarc-som.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg3e-smarc-som.dtsi
@@ -43,6 +43,12 @@ memory@48000000 {
reg = <0x0 0x48000000 0x0 0xf8000000>;
};
+ pcie_refclk: clock-pcie-ref {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
reg_1p8v: regulator-1p8v {
compatible = "regulator-fixed";
regulator-name = "fixed-1.8V";
@@ -168,6 +174,11 @@ phy1: ethernet-phy@7 {
};
};
+&pcie_port0 {
+ clocks = <&pcie_refclk>;
+ clock-names = "ref";
+};
+
&pinctrl {
eth0_pins: eth0 {
clk {
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v4 15/15] arm64: dts: renesas: r9a09g047e57-smarc: Enable PCIe
2026-01-29 21:41 [PATCH v4 00/15] PCI: renesas: Add RZ/G3E PCIe controller support John Madieu
` (13 preceding siblings ...)
2026-01-29 21:41 ` [PATCH v4 14/15] arm64: dts: renesas: r9a09g047e57-smarc-som: Add PCIe reference clock John Madieu
@ 2026-01-29 21:41 ` John Madieu
14 siblings, 0 replies; 27+ messages in thread
From: John Madieu @ 2026-01-29 21:41 UTC (permalink / raw)
To: claudiu.beznea.uj, lpieralisi, kwilczynski, mani, geert+renesas,
krzk+dt
Cc: robh, bhelgaas, conor+dt, magnus.damm, biju.das.jz, linux-pci,
linux-renesas-soc, devicetree, linux-clk, john.madieu,
John Madieu
The RZ Smarc Crarrier-II board has PCIe slots mounted on it.
Enable PCIe support.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v4: No changes
v3:
- Splitted enablement into common carrier dtsi and board dts
v2:
- Removed board-specific dma-ranges.
- Merged enablement and pinmux assignment in same file
.../boot/dts/renesas/r9a09g047e57-smarc.dts | 16 ++++++++++++++++
arch/arm64/boot/dts/renesas/renesas-smarc2.dtsi | 4 ++++
2 files changed, 20 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r9a09g047e57-smarc.dts b/arch/arm64/boot/dts/renesas/r9a09g047e57-smarc.dts
index 696903dc7a63..1ba50512f4ef 100644
--- a/arch/arm64/boot/dts/renesas/r9a09g047e57-smarc.dts
+++ b/arch/arm64/boot/dts/renesas/r9a09g047e57-smarc.dts
@@ -122,6 +122,11 @@ key-sleep {
#endif
};
+&pcie {
+ pinctrl-0 = <&pcie_pins>;
+ pinctrl-names = "default";
+};
+
&pinctrl {
canfd_pins: canfd {
can1_pins: can1 {
@@ -167,6 +172,17 @@ rsci9_pins: rsci9 {
bias-pull-up;
};
+ pcie-clkreq-n {
+ gpio-hog;
+ gpios = <RZG3E_GPIO(4, 5) GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "pcie_clkreq_n";
+ };
+
+ pcie_pins: pcie {
+ pinmux = <RZG3E_PORT_PINMUX(G, 7, 1)>; /* PCIE_RST_OUT# */
+ };
+
scif_pins: scif {
pins = "SCIF_TXD", "SCIF_RXD";
renesas,output-impedance = <1>;
diff --git a/arch/arm64/boot/dts/renesas/renesas-smarc2.dtsi b/arch/arm64/boot/dts/renesas/renesas-smarc2.dtsi
index b607b5d6c259..e2a34577a1a1 100644
--- a/arch/arm64/boot/dts/renesas/renesas-smarc2.dtsi
+++ b/arch/arm64/boot/dts/renesas/renesas-smarc2.dtsi
@@ -96,6 +96,10 @@ &i2c0 {
clock-frequency = <400000>;
};
+&pcie {
+ status = "okay";
+};
+
&scif0 {
status = "okay";
};
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread