* [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support
@ 2026-05-07 9:21 Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 01/13] dt-bindings: display: renesas,rzg2l-du: Refuse port@1 for RZ/G2UL Tommaso Merciai
` (12 more replies)
0 siblings, 13 replies; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
Dear All,
This patch series adds DU/DRM support for the 2 Display Units (DUs) interface
found on the Renesas RZ/G3E SoC.
RZ/G3E SoC has 2 LCD controller (LCDC0 and LCDC1), both are composed
of Frame Compression Processor (FCPVD), Video Signal Processor (VSPD),
and Display Unit (DU).
LCDC0 is connected to LVDS (single or dual channel) and DSI.
LCDC1 is connected to LVDS (single ch), DSI, and GPIO (Parallel I/F).
This apply on top of [1]
[1] https://lore.kernel.org/all/20260429170012.366537-1-prabhakar.mahadev-lad.rj@bp.renesas.com/
Thanks & Regards,
Tommaso
v6->v7:
- Rebased on top of next-20260605
- Splitted the original series into smaller chunks for easy review and easy
merging. The original series is available here:
http://lore.kernel.org/all/cover.1775636898.git.tommaso.merciai.xr@bp.renesas.com/
- PATCH 01/13: Collected LPinchart tag. Removed wrong fixes tag.
- PATCH 02/13: Rebased on top of [1]. Use single DRM device aggregating
both DU instances (1 DU dt node), modelling single port for each DU0,
DU1 and multiple endpoints for outputs.
- PATCH 12/13: Removed feature flag usage, rebased on top of T2H/N2H LCDC series [1]
Reworked commit body as now outputs routing is based on endpoint id
instead of port number. Fixed rzg2l_du_r9a09g047_info instead of
rzg2l_du_r9a09g047_du_info.
Added bump of RZG2L_DU_MAX_CRTCS and RZG2L_DU_MAX_VSPS to 2.
Tommaso Merciai (13):
dt-bindings: display: renesas,rzg2l-du: Refuse port@1 for RZ/G2UL
dt-bindings: display: renesas,rzg2l-du: Add support for RZ/G3E SoC
drm: renesas: rz-du: Move mmio from rzg2l_du_device to rzg2l_du_crtc
drm: renesas: rz-du: crtc: Introduce rzg2l_du_crtc_clk_get()
reset: Add devm_reset_control_get_optional_shared_by_index()
drm: renesas: rz-du: crtc: Parameterize rzg2l_du_crtc_create() with
hw/sw index
drm: renesas: rz-du: kms: Enable multi CRTC creation
drm: renesas: rz-du: Add endpoint-based output routing
drm: renesas: rz-du: Narrow active channels to DT-connected outputs
drm: renesas: rz-du: Skip disabled endpoint nodes in encoder init
drm: renesas: rz-du: Add multi-VSP instance support in plane selection
drm: renesas: rz-du: Add RZ/G3E support
drm: renesas: rz-du: Update output routing comment to reflect all
supported outputs
.../bindings/display/renesas,rzg2l-du.yaml | 135 +++++++++++++++-
drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c | 109 ++++++++++---
drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.h | 7 +-
drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c | 33 +++-
drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h | 21 ++-
drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c | 144 +++++++++++++++---
drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c | 3 +-
include/linux/reset.h | 18 +++
8 files changed, 410 insertions(+), 60 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v7 01/13] dt-bindings: display: renesas,rzg2l-du: Refuse port@1 for RZ/G2UL
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
@ 2026-05-07 9:21 ` Tommaso Merciai
2026-05-13 22:23 ` Rob Herring (Arm)
2026-05-07 9:21 ` [PATCH v7 02/13] dt-bindings: display: renesas,rzg2l-du: Add support for RZ/G3E SoC Tommaso Merciai
` (11 subsequent siblings)
12 siblings, 1 reply; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
The RZ/G2UL DU supports only a single port@0 DPI. Explicitly refuse
port@1 in the ports node.
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v6->v7:
- Collected LPinchart tag.
- Removed wrong fixes tag.
v5->v6:
- New patch.
Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
index 45678d536a75..0d7df210407b 100644
--- a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
+++ b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
@@ -108,6 +108,7 @@ allOf:
properties:
port@0:
description: DPI
+ port@1: false
required:
- port@0
--
2.54.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 02/13] dt-bindings: display: renesas,rzg2l-du: Add support for RZ/G3E SoC
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 01/13] dt-bindings: display: renesas,rzg2l-du: Refuse port@1 for RZ/G2UL Tommaso Merciai
@ 2026-05-07 9:21 ` Tommaso Merciai
2026-05-13 22:27 ` Rob Herring
2026-05-07 9:21 ` [PATCH v7 03/13] drm: renesas: rz-du: Move mmio from rzg2l_du_device to rzg2l_du_crtc Tommaso Merciai
` (10 subsequent siblings)
12 siblings, 1 reply; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
The RZ/G3E SoC integrates two LCD controllers (LCDC0 and LCDC1), each
containing a FCPVD, VSPD, and Display Unit (DU).
- LCDC0 supports DSI and LVDS (single or dual-channel) outputs.
- LCDC1 supports DSI, LVDS (single-channel), and RGB outputs.
Add compatible string 'renesas,r9a09g047-du' and extend the binding to
support two DU instances: add reg-names ('du0'/'du1'), extend reg,
interrupts, and resets to maxItems: 2, and extend clocks/clock-names to
six entries (aclk/pclk/vclk per instance, minItems: 3).
Drop the "Each port shall have a single endpoint." constraint since
RZ/G3E ports expose multiple endpoints.
Add a RZ/G3E-specific allOf rule mapping two DU instances to two ports:
- port@0 (DU0): endpoint@0 DSI, endpoint@2 LVDS ch0, endpoint@3 LVDS ch1
- port@1 (DU1): endpoint@0 DSI, endpoint@1 RGB (DPAD), endpoint@3 LVDS ch1
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v6->v7:
- Rebased on top of [1]
[1] https://lore.kernel.org/all/20260429170012.366537-1-prabhakar.mahadev-lad.rj@bp.renesas.com/
- Use single DRM device aggregating both DU instances (1 DU dt node),
modelling single port for each DU0, DU1 and multiple endpoints for
outputs.
v5->v6:
- Extend patternProperties from "^port@[0-1]$" to "^port@[0-3]$" and
explicitly disable port@2 and port@3 for existing SoCs that do not expose
them.
- Reworked ports numbering + improved/fixed ports descriptions in the
bindings documentation.
- Improved commit body.
v4->v5:
- Dropped renesas,id property and updated bindings
accordingly.
v2->v3:
- No changes.
v2->v3:
- No changes.
v1->v2:
- Use single compatible string instead of multiple compatible strings
for the two DU instances, leveraging a 'renesas,id' property to
differentiate between DU0 and DU1.
- Updated commit message accordingly.
.../bindings/display/renesas,rzg2l-du.yaml | 134 +++++++++++++++++-
1 file changed, 130 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
index 0d7df210407b..8ad1361a0f3a 100644
--- a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
+++ b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
@@ -20,6 +20,7 @@ properties:
- enum:
- renesas,r9a07g043u-du # RZ/G2UL
- renesas,r9a07g044-du # RZ/G2{L,LC}
+ - renesas,r9a09g047-du # RZ/G3E
- renesas,r9a09g057-du # RZ/V2H(P)
- renesas,r9a09g077-du # RZ/T2H
- items:
@@ -34,25 +35,47 @@ properties:
- const: renesas,r9a09g077-du # RZ/T2H fallback
reg:
- maxItems: 1
+ minItems: 1
+ maxItems: 2
+
+ reg-names:
+ items:
+ - const: du0
+ - const: du1
interrupts:
- maxItems: 1
+ minItems: 1
+ maxItems: 2
clocks:
+ minItems: 3
items:
- description: Main clock
- description: Register access clock
- description: Video clock
+ - description: Main clock for DU1
+ - description: Register access clock for DU1
+ - description: Video clock for DU1
clock-names:
+ minItems: 3
items:
- const: aclk
- const: pclk
- const: vclk
+ - const: aclk1
+ - const: pclk1
+ - const: vclk1
resets:
- maxItems: 1
+ minItems: 1
+ maxItems: 2
+
+ reset-names:
+ minItems: 1
+ items:
+ - const: resetn
+ - const: resetn1
power-domains:
maxItems: 1
@@ -66,7 +89,7 @@ properties:
description: |
The connections to the DU output video ports are modeled using the OF
graph bindings. The number of ports and their assignment are
- model-dependent. Each port shall have a single endpoint.
+ model-dependent.
patternProperties:
"^port@[0-1]$":
@@ -104,6 +127,18 @@ allOf:
const: renesas,r9a07g043u-du
then:
properties:
+ reg:
+ maxItems: 1
+ reg-names: false
+ interrupts:
+ maxItems: 1
+ clocks:
+ maxItems: 3
+ clock-names:
+ maxItems: 3
+ resets:
+ maxItems: 1
+ reset-names: false
ports:
properties:
port@0:
@@ -119,6 +154,18 @@ allOf:
const: renesas,r9a07g044-du
then:
properties:
+ reg:
+ maxItems: 1
+ reg-names: false
+ interrupts:
+ maxItems: 1
+ clocks:
+ maxItems: 3
+ clock-names:
+ maxItems: 3
+ resets:
+ maxItems: 1
+ reset-names: false
ports:
properties:
port@0:
@@ -136,6 +183,18 @@ allOf:
const: renesas,r9a09g057-du
then:
properties:
+ reg:
+ maxItems: 1
+ reg-names: false
+ interrupts:
+ maxItems: 1
+ clocks:
+ maxItems: 3
+ clock-names:
+ maxItems: 3
+ resets:
+ maxItems: 1
+ reset-names: false
ports:
properties:
port@0:
@@ -151,7 +210,17 @@ allOf:
const: renesas,r9a09g077-du
then:
properties:
+ reg:
+ maxItems: 1
+ reg-names: false
+ interrupts:
+ maxItems: 1
+ clocks:
+ maxItems: 3
+ clock-names:
+ maxItems: 3
resets: false
+ reset-names: false
required:
- port
else:
@@ -159,6 +228,63 @@ allOf:
- resets
- ports
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,r9a09g047-du
+ then:
+ properties:
+ reg:
+ minItems: 2
+ interrupts:
+ minItems: 2
+ clocks:
+ minItems: 6
+ clock-names:
+ minItems: 6
+ reg-names:
+ minItems: 2
+ resets:
+ minItems: 2
+ reset-names:
+ minItems: 2
+ ports:
+ properties:
+ port@0:
+ description: DU0 outputs
+ properties:
+ endpoint@0:
+ description: DSI
+ endpoint@2:
+ description: LVDS, Channel 0
+ endpoint@3:
+ description: LVDS, Channel 1
+ required:
+ - endpoint@0
+ - endpoint@2
+ - endpoint@3
+ port@1:
+ description: DU1 outputs
+ properties:
+ endpoint@0:
+ description: DSI
+ endpoint@1:
+ description: RGB (DPAD)
+ endpoint@3:
+ description: LVDS, Channel 1
+ required:
+ - endpoint@0
+ - endpoint@1
+ - endpoint@3
+
+ required:
+ - port@0
+ - port@1
+ required:
+ - reg-names
+ - reset-names
+
examples:
# RZ/G2L DU
- |
--
2.54.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 03/13] drm: renesas: rz-du: Move mmio from rzg2l_du_device to rzg2l_du_crtc
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 01/13] dt-bindings: display: renesas,rzg2l-du: Refuse port@1 for RZ/G2UL Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 02/13] dt-bindings: display: renesas,rzg2l-du: Add support for RZ/G3E SoC Tommaso Merciai
@ 2026-05-07 9:21 ` Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 04/13] drm: renesas: rz-du: crtc: Introduce rzg2l_du_crtc_clk_get() Tommaso Merciai
` (9 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
The mmio base address is currently stored in rzg2l_du_device and the
devm_platform_ioremap_resource() call lives in rzg2l_du_probe(). In
preparation for supporting multiple CRTCs, each with its own register
bank, move the mmio pointer and the ioremap call into rzg2l_du_crtc,
and update all register accessors in rzg2l_du_crtc.c to use
rcrtc->mmio instead of rcdu->mmio.
No functional change intended.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v6->v7:
- New patch.
drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c | 23 +++++++++++--------
drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.h | 2 ++
drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c | 5 ----
drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h | 2 --
4 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
index d0f01aa642a7..88915babca12 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
@@ -67,7 +67,6 @@ static void rzg2l_du_crtc_set_display_timing(struct rzg2l_du_crtc *rcrtc)
const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
unsigned long mode_clock = mode->clock * 1000;
u32 ditr0, ditr1, ditr2, ditr3, ditr4, pbcr0;
- struct rzg2l_du_device *rcdu = rcrtc->dev;
clk_prepare_enable(rcrtc->rzg2l_clocks.dclk);
clk_set_rate(rcrtc->rzg2l_clocks.dclk, mode_clock);
@@ -90,15 +89,15 @@ static void rzg2l_du_crtc_set_display_timing(struct rzg2l_du_crtc *rcrtc)
pbcr0 = DU_PBCR0_PB_DEP(0x1f);
- writel(ditr0, rcdu->mmio + DU_DITR0);
- writel(ditr1, rcdu->mmio + DU_DITR1);
- writel(ditr2, rcdu->mmio + DU_DITR2);
- writel(ditr3, rcdu->mmio + DU_DITR3);
- writel(ditr4, rcdu->mmio + DU_DITR4);
- writel(pbcr0, rcdu->mmio + DU_PBCR0);
+ writel(ditr0, rcrtc->mmio + DU_DITR0);
+ writel(ditr1, rcrtc->mmio + DU_DITR1);
+ writel(ditr2, rcrtc->mmio + DU_DITR2);
+ writel(ditr3, rcrtc->mmio + DU_DITR3);
+ writel(ditr4, rcrtc->mmio + DU_DITR4);
+ writel(pbcr0, rcrtc->mmio + DU_PBCR0);
/* Enable auto clear */
- writel(DU_MCR1_PB_AUTOCLR, rcdu->mmio + DU_MCR1);
+ writel(DU_MCR1_PB_AUTOCLR, rcrtc->mmio + DU_MCR1);
}
/* -----------------------------------------------------------------------------
@@ -223,7 +222,7 @@ static void rzg2l_du_start_stop(struct rzg2l_du_crtc *rcrtc, bool start)
if (start && rzg2l_du_has(rcdu, RZG2L_DU_FEATURE_DPIO_OE))
val |= DU_MCR0_DPI_EN;
- writel(start ? val : 0, rcdu->mmio + DU_MCR0);
+ writel(start ? val : 0, rcrtc->mmio + DU_MCR0);
}
static void rzg2l_du_crtc_start(struct rzg2l_du_crtc *rcrtc)
@@ -380,11 +379,17 @@ static const struct drm_crtc_funcs crtc_funcs_rz = {
int rzg2l_du_crtc_create(struct rzg2l_du_device *rcdu)
{
+ struct platform_device *pdev = to_platform_device(rcdu->dev);
struct rzg2l_du_crtc *rcrtc = &rcdu->crtcs[0];
struct drm_crtc *crtc = &rcrtc->crtc;
struct drm_plane *primary;
int ret;
+ /* I/O resources */
+ rcrtc->mmio = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(rcrtc->mmio))
+ return PTR_ERR(rcrtc->mmio);
+
rcrtc->rstc = devm_reset_control_get_optional_shared(rcdu->dev, NULL);
if (IS_ERR(rcrtc->rstc)) {
dev_err(rcdu->dev, "can't get cpg reset\n");
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.h b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.h
index cbba38acc377..9b2deb3c589a 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.h
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.h
@@ -29,6 +29,7 @@ struct rzg2l_du_format_info;
* struct rzg2l_du_crtc - the CRTC, representing a DU superposition processor
* @crtc: base DRM CRTC
* @dev: the DU device
+ * @mmio: base address of the DU hardware registers for this CRTC
* @initialized: whether the CRTC has been initialized and clocks enabled
* @vblank_enable: whether vblank events are enabled on this CRTC
* @event: event to post when the pending page flip completes
@@ -42,6 +43,7 @@ struct rzg2l_du_crtc {
struct drm_crtc crtc;
struct rzg2l_du_device *dev;
+ void __iomem *mmio;
bool initialized;
bool vblank_enable;
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
index fc55dfffebaf..887b840e63d2 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
@@ -157,11 +157,6 @@ static int rzg2l_du_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rcdu);
- /* I/O resources */
- rcdu->mmio = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(rcdu->mmio))
- return PTR_ERR(rcdu->mmio);
-
ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (ret)
return ret;
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
index baf076d69cda..d0e59b787cd7 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
@@ -66,8 +66,6 @@ struct rzg2l_du_device {
struct device *dev;
const struct rzg2l_du_device_info *info;
- void __iomem *mmio;
-
struct drm_device ddev;
struct rzg2l_du_crtc crtcs[RZG2L_DU_MAX_CRTCS];
--
2.54.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 04/13] drm: renesas: rz-du: crtc: Introduce rzg2l_du_crtc_clk_get()
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
` (2 preceding siblings ...)
2026-05-07 9:21 ` [PATCH v7 03/13] drm: renesas: rz-du: Move mmio from rzg2l_du_device to rzg2l_du_crtc Tommaso Merciai
@ 2026-05-07 9:21 ` Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 05/13] reset: Add devm_reset_control_get_optional_shared_by_index() Tommaso Merciai
` (8 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
Introduce rzg2l_du_crtc_clk_get(), a helper wrapping devm_clk_get()
that appends a numeric index suffix to the clock name when hw_index is
non-zero (e.g. "vclk" -> "vclk1"), preserving backward compatibility
with existing devicetree bindings for index 0.
This is preparatory work for RZ/G3E that has two DU instances
where each requires independently named clock entries.
No functional change intended.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v6->v7:
- New patch.
drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
index 88915babca12..622044f994e8 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
@@ -377,6 +377,17 @@ static const struct drm_crtc_funcs crtc_funcs_rz = {
* Initialization
*/
+static struct clk *rzg2l_du_crtc_clk_get(struct device *dev, const char *name,
+ unsigned int hw_index)
+{
+ char buf[16];
+
+ if (hw_index != 0)
+ snprintf(buf, sizeof(buf), "%s%u", name, hw_index);
+
+ return devm_clk_get(dev, hw_index == 0 ? name : buf);
+}
+
int rzg2l_du_crtc_create(struct rzg2l_du_device *rcdu)
{
struct platform_device *pdev = to_platform_device(rcdu->dev);
@@ -396,19 +407,19 @@ int rzg2l_du_crtc_create(struct rzg2l_du_device *rcdu)
return PTR_ERR(rcrtc->rstc);
}
- rcrtc->rzg2l_clocks.aclk = devm_clk_get(rcdu->dev, "aclk");
+ rcrtc->rzg2l_clocks.aclk = rzg2l_du_crtc_clk_get(rcdu->dev, "aclk", 0);
if (IS_ERR(rcrtc->rzg2l_clocks.aclk)) {
dev_err(rcdu->dev, "no axi clock for DU\n");
return PTR_ERR(rcrtc->rzg2l_clocks.aclk);
}
- rcrtc->rzg2l_clocks.pclk = devm_clk_get(rcdu->dev, "pclk");
+ rcrtc->rzg2l_clocks.pclk = rzg2l_du_crtc_clk_get(rcdu->dev, "pclk", 0);
if (IS_ERR(rcrtc->rzg2l_clocks.pclk)) {
dev_err(rcdu->dev, "no peripheral clock for DU\n");
return PTR_ERR(rcrtc->rzg2l_clocks.pclk);
}
- rcrtc->rzg2l_clocks.dclk = devm_clk_get(rcdu->dev, "vclk");
+ rcrtc->rzg2l_clocks.dclk = rzg2l_du_crtc_clk_get(rcdu->dev, "vclk", 0);
if (IS_ERR(rcrtc->rzg2l_clocks.dclk)) {
dev_err(rcdu->dev, "no video clock for DU\n");
return PTR_ERR(rcrtc->rzg2l_clocks.dclk);
--
2.54.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 05/13] reset: Add devm_reset_control_get_optional_shared_by_index()
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
` (3 preceding siblings ...)
2026-05-07 9:21 ` [PATCH v7 04/13] drm: renesas: rz-du: crtc: Introduce rzg2l_du_crtc_clk_get() Tommaso Merciai
@ 2026-05-07 9:21 ` Tommaso Merciai
2026-05-07 9:58 ` Philipp Zabel
2026-05-07 9:21 ` [PATCH v7 06/13] drm: renesas: rz-du: crtc: Parameterize rzg2l_du_crtc_create() with hw/sw index Tommaso Merciai
` (7 subsequent siblings)
12 siblings, 1 reply; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
Add devm_reset_control_get_optional_shared_by_index() to allow the
drivers to get optional shared reset by passing the index.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v6->v7:
- New patch.
include/linux/reset.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/include/linux/reset.h b/include/linux/reset.h
index 9c391cf0c822..d49545019631 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -965,6 +965,24 @@ devm_reset_control_get_shared_by_index(struct device *dev, int index)
return __devm_reset_control_get(dev, NULL, index, RESET_CONTROL_SHARED);
}
+/**
+ * devm_reset_control_get_optional_shared_by_index - resource managed
+ * reset_control_get_optional_shared()
+ * @dev: device to be reset by the controller
+ * @index: index of the reset controller
+ *
+ * Managed reset_control_get_optional_shared(). For reset controllers returned
+ * from this function, reset_control_put() is called automatically on driver
+ * detach.
+ *
+ * See reset_control_get_optional_shared() for more information.
+ */
+static inline struct reset_control *
+devm_reset_control_get_optional_shared_by_index(struct device *dev, int index)
+{
+ return __devm_reset_control_get(dev, NULL, index, RESET_CONTROL_OPTIONAL_SHARED);
+}
+
/*
* TEMPORARY calls to use during transition:
*
--
2.54.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 06/13] drm: renesas: rz-du: crtc: Parameterize rzg2l_du_crtc_create() with hw/sw index
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
` (4 preceding siblings ...)
2026-05-07 9:21 ` [PATCH v7 05/13] reset: Add devm_reset_control_get_optional_shared_by_index() Tommaso Merciai
@ 2026-05-07 9:21 ` Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 07/13] drm: renesas: rz-du: kms: Enable multi CRTC creation Tommaso Merciai
` (6 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
Extend rzg2l_du_crtc_create() with software index (swindex) and
hardware index (hwindex) parameters to support creating CRTCs for
multiple DU instances. Use swindex to select the CRTC entry in the
device array, hwindex to fetch per-channel MMIO, reset, and clocks.
Store hwindex in the CRTC structure for later use.
No functional change for existing platforms the sole caller passes
swindex=0, hwindex=0.
This is a preparatory step towards supporting the two DU instances
available on RZ/G3E.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v6->v7:
- New patch.
drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c | 31 +++++++++++--------
drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.h | 5 ++-
drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c | 2 +-
3 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
index 622044f994e8..3e8b6cca6d57 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
@@ -388,45 +388,50 @@ static struct clk *rzg2l_du_crtc_clk_get(struct device *dev, const char *name,
return devm_clk_get(dev, hw_index == 0 ? name : buf);
}
-int rzg2l_du_crtc_create(struct rzg2l_du_device *rcdu)
+int rzg2l_du_crtc_create(struct rzg2l_du_device *rcdu, unsigned int swindex,
+ unsigned int hwindex)
{
struct platform_device *pdev = to_platform_device(rcdu->dev);
- struct rzg2l_du_crtc *rcrtc = &rcdu->crtcs[0];
+ struct rzg2l_du_crtc *rcrtc = &rcdu->crtcs[swindex];
struct drm_crtc *crtc = &rcrtc->crtc;
struct drm_plane *primary;
int ret;
+ rcrtc->hw_index = hwindex;
+ rcrtc->dev = rcdu;
+
/* I/O resources */
- rcrtc->mmio = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(rcrtc->mmio))
+ rcrtc->mmio = devm_platform_ioremap_resource(pdev, hwindex);
+ if (IS_ERR(rcrtc->mmio)) {
+ dev_err(rcdu->dev, "failed to map MMIO for DU%u\n", hwindex);
return PTR_ERR(rcrtc->mmio);
+ }
- rcrtc->rstc = devm_reset_control_get_optional_shared(rcdu->dev, NULL);
+ rcrtc->rstc = devm_reset_control_get_optional_shared_by_index(rcdu->dev, hwindex);
if (IS_ERR(rcrtc->rstc)) {
- dev_err(rcdu->dev, "can't get cpg reset\n");
+ dev_err(rcdu->dev, "can't get cpg reset for DU%u\n", hwindex);
return PTR_ERR(rcrtc->rstc);
}
- rcrtc->rzg2l_clocks.aclk = rzg2l_du_crtc_clk_get(rcdu->dev, "aclk", 0);
+ rcrtc->rzg2l_clocks.aclk = rzg2l_du_crtc_clk_get(rcdu->dev, "aclk", hwindex);
if (IS_ERR(rcrtc->rzg2l_clocks.aclk)) {
- dev_err(rcdu->dev, "no axi clock for DU\n");
+ dev_err(rcdu->dev, "no axi clock for DU%u\n", hwindex);
return PTR_ERR(rcrtc->rzg2l_clocks.aclk);
}
- rcrtc->rzg2l_clocks.pclk = rzg2l_du_crtc_clk_get(rcdu->dev, "pclk", 0);
+ rcrtc->rzg2l_clocks.pclk = rzg2l_du_crtc_clk_get(rcdu->dev, "pclk", hwindex);
if (IS_ERR(rcrtc->rzg2l_clocks.pclk)) {
- dev_err(rcdu->dev, "no peripheral clock for DU\n");
+ dev_err(rcdu->dev, "no peripheral clock for DU%u\n", hwindex);
return PTR_ERR(rcrtc->rzg2l_clocks.pclk);
}
- rcrtc->rzg2l_clocks.dclk = rzg2l_du_crtc_clk_get(rcdu->dev, "vclk", 0);
+ rcrtc->rzg2l_clocks.dclk = rzg2l_du_crtc_clk_get(rcdu->dev, "vclk", hwindex);
if (IS_ERR(rcrtc->rzg2l_clocks.dclk)) {
- dev_err(rcdu->dev, "no video clock for DU\n");
+ dev_err(rcdu->dev, "no video clock for DU%u\n", hwindex);
return PTR_ERR(rcrtc->rzg2l_clocks.dclk);
}
init_waitqueue_head(&rcrtc->flip_wait);
- rcrtc->dev = rcdu;
primary = rzg2l_du_vsp_get_drm_plane(rcrtc, rcrtc->vsp_pipe);
if (IS_ERR(primary))
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.h b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.h
index 9b2deb3c589a..1c4f82a1a701 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.h
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.h
@@ -30,6 +30,7 @@ struct rzg2l_du_format_info;
* @crtc: base DRM CRTC
* @dev: the DU device
* @mmio: base address of the DU hardware registers for this CRTC
+ * @hw_index: hardware DU index
* @initialized: whether the CRTC has been initialized and clocks enabled
* @vblank_enable: whether vblank events are enabled on this CRTC
* @event: event to post when the pending page flip completes
@@ -44,6 +45,7 @@ struct rzg2l_du_crtc {
struct rzg2l_du_device *dev;
void __iomem *mmio;
+ unsigned int hw_index;
bool initialized;
bool vblank_enable;
@@ -84,7 +86,8 @@ static inline struct rzg2l_du_crtc_state *to_rzg2l_crtc_state(struct drm_crtc_st
return container_of(s, struct rzg2l_du_crtc_state, state);
}
-int rzg2l_du_crtc_create(struct rzg2l_du_device *rcdu);
+int rzg2l_du_crtc_create(struct rzg2l_du_device *rcdu, unsigned int swindex,
+ unsigned int hwindex);
void rzg2l_du_crtc_finish_page_flip(struct rzg2l_du_crtc *rcrtc);
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
index 87f171145a23..7cbdf146788e 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
@@ -440,7 +440,7 @@ int rzg2l_du_modeset_init(struct rzg2l_du_device *rcdu)
return ret;
/* Create the CRTCs. */
- ret = rzg2l_du_crtc_create(rcdu);
+ ret = rzg2l_du_crtc_create(rcdu, 0, 0);
if (ret < 0)
return ret;
--
2.54.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 07/13] drm: renesas: rz-du: kms: Enable multi CRTC creation
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
` (5 preceding siblings ...)
2026-05-07 9:21 ` [PATCH v7 06/13] drm: renesas: rz-du: crtc: Parameterize rzg2l_du_crtc_create() with hw/sw index Tommaso Merciai
@ 2026-05-07 9:21 ` Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 08/13] drm: renesas: rz-du: Add endpoint-based output routing Tommaso Merciai
` (5 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
Replace the hardcoded rzg2l_du_crtc_create(rcdu, 0, 0) call with a
loop over channels_mask using for_each_set_bit(), passing the correct
software and hardware indices to each invocation.
Iterate the registered CRTCs by their hardware index when building
encoder possible_crtcs masks, so that the DRM software CRTC index
correctly maps to the hardware channel.
No functional changes intended.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v6->v7:
- New patch.
drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c | 28 ++++++++++++++++----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
index 7cbdf146788e..fc5ce8c7eea0 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
@@ -404,7 +404,10 @@ int rzg2l_du_modeset_init(struct rzg2l_du_device *rcdu)
{
struct drm_device *dev = &rcdu->ddev;
struct drm_encoder *encoder;
+ unsigned long channels_mask;
unsigned int num_encoders;
+ unsigned int swindex = 0;
+ unsigned int hwindex;
int ret;
ret = drmm_mode_config_init(dev);
@@ -424,7 +427,8 @@ int rzg2l_du_modeset_init(struct rzg2l_du_device *rcdu)
dev->mode_config.max_width = 1920;
dev->mode_config.max_height = 1920;
- rcdu->num_crtcs = hweight8(rcdu->info->channels_mask);
+ channels_mask = rcdu->info->channels_mask;
+ rcdu->num_crtcs = hweight8(channels_mask);
/*
* Initialize vertical blanking interrupts handling. Start with vblank
@@ -440,9 +444,11 @@ int rzg2l_du_modeset_init(struct rzg2l_du_device *rcdu)
return ret;
/* Create the CRTCs. */
- ret = rzg2l_du_crtc_create(rcdu, 0, 0);
- if (ret < 0)
- return ret;
+ for_each_set_bit(hwindex, &channels_mask, RZG2L_DU_MAX_CRTCS) {
+ ret = rzg2l_du_crtc_create(rcdu, swindex++, hwindex);
+ if (ret < 0)
+ return ret;
+ }
/* Initialize the encoders. */
ret = rzg2l_du_encoders_init(rcdu);
@@ -461,13 +467,25 @@ int rzg2l_du_modeset_init(struct rzg2l_du_device *rcdu)
* Set the possible CRTCs and possible clones. There's always at least
* one way for all encoders to clone each other, set all bits in the
* possible clones field.
+ *
+ * route->possible_outputs uses hardware channel indices, but DRM
+ * possible_crtcs uses the CRTC registration order. Convert by
+ * mapping each set bit in possible_outputs through the hw_index
+ * stored in each CRTC.
*/
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
struct rzg2l_du_encoder *renc = to_rzg2l_encoder(encoder);
const struct rzg2l_du_output_routing *route =
&rcdu->info->routes[renc->output];
+ unsigned int possible_crtcs = 0;
+ unsigned int i;
+
+ for (i = 0; i < rcdu->num_crtcs; i++) {
+ if (route->possible_outputs & BIT(rcdu->crtcs[i].hw_index))
+ possible_crtcs |= BIT(i);
+ }
- encoder->possible_crtcs = route->possible_outputs;
+ encoder->possible_crtcs = possible_crtcs;
encoder->possible_clones = (1 << num_encoders) - 1;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 08/13] drm: renesas: rz-du: Add endpoint-based output routing
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
` (6 preceding siblings ...)
2026-05-07 9:21 ` [PATCH v7 07/13] drm: renesas: rz-du: kms: Enable multi CRTC creation Tommaso Merciai
@ 2026-05-07 9:21 ` Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 09/13] drm: renesas: rz-du: Narrow active channels to DT-connected outputs Tommaso Merciai
` (4 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
On RZ/G3E all outputs of a DU instance share a single port and are
distinguished by endpoint id, unlike the port-per-output layout on
RZ/G2L.
Auto-detect the routing mode by checking whether any port exposes more
than one endpoint (rzg2l_du_ep_routing()). Add an 'ep' field in a union
with 'port' in rzg2l_du_output_routing to cover both conventions, and
update rzg2l_du_encoders_init() to match routes by ep.id when endpoint
routing is detected. Track a linked_outputs bitmask to skip duplicate
encoder creation when the same output type appears under multiple
DU-channel ports.
No functional change for existing platforms.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v6->v7:
- New patch.
drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h | 6 ++-
drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c | 57 +++++++++++++++++---
2 files changed, 55 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
index d0e59b787cd7..eed8e1215f08 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
@@ -32,6 +32,7 @@ enum rzg2l_du_output {
* struct rzg2l_du_output_routing - Output routing specification
* @possible_outputs: bitmask of possible outputs
* @port: device tree port number corresponding to this output route
+ * @ep: device tree endpoint id corresponding to this output route
*
* The DU has 2 possible outputs (DPAD0, DSI0). Output routing data
* specify the valid SoC outputs, which CRTC can drive the output, and the type
@@ -39,7 +40,10 @@ enum rzg2l_du_output {
*/
struct rzg2l_du_output_routing {
unsigned int possible_outputs;
- unsigned int port;
+ union {
+ unsigned int port;
+ unsigned int ep;
+ };
};
/*
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
index fc5ce8c7eea0..01b037594926 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
@@ -266,15 +266,37 @@ static int rzg2l_du_encoders_init_one(struct rzg2l_du_device *rcdu,
return ret;
}
+static bool rzg2l_du_ep_routing(const struct device_node *np)
+{
+ for_each_of_graph_port(np, port) {
+ unsigned int count = 0;
+
+ for_each_of_graph_port_endpoint(port, ep)
+ count++;
+
+ if (count > 1)
+ return true;
+ }
+ return false;
+}
+
static int rzg2l_du_encoders_init(struct rzg2l_du_device *rcdu)
{
struct device_node *np = rcdu->dev->of_node;
+ bool ep_routing = rzg2l_du_ep_routing(np);
+ unsigned int linked_outputs = 0;
struct device_node *ep_node;
unsigned int num_encoders = 0;
/*
* Iterate over the endpoints and create one encoder for each output
* pipeline.
+ *
+ * Two routing modes are supported:
+ * - Port-based (default): each output lives on its own port, routes
+ * are matched by ep.port.
+ * - Endpoint-based: all outputs share a single port, each output lives
+ * on its own endpoint, routes are matched by ep.id.
*/
for_each_endpoint_of_node(np, ep_node) {
enum rzg2l_du_output output;
@@ -288,19 +310,39 @@ static int rzg2l_du_encoders_init(struct rzg2l_du_device *rcdu)
return ret;
}
- /* Find the output route corresponding to the port number. */
+ /* Find the output route corresponding to the port/endpoint. */
for (i = 0; i < RZG2L_DU_OUTPUT_MAX; ++i) {
- if (rcdu->info->routes[i].possible_outputs &&
- rcdu->info->routes[i].port == ep.port) {
- output = i;
+ const struct rzg2l_du_output_routing *route =
+ &rcdu->info->routes[i];
+
+ if (!route->possible_outputs)
+ continue;
+
+ if (ep_routing ? route->ep == ep.id :
+ route->port == ep.port)
break;
- }
}
if (i == RZG2L_DU_OUTPUT_MAX) {
dev_warn(rcdu->dev,
- "port %u references unexisting output, skipping\n",
- ep.port);
+ "port %u endpoint %u references unexisting output, skipping\n",
+ ep.port, ep.id);
+ continue;
+ }
+
+ output = i;
+
+ /*
+ * With endpoint-based routing the same output type can appear
+ * under multiple DU-channel ports (e.g. DSI on both port@0 and
+ * port@1). Only create one encoder per output the encoder's
+ * possible_crtcs mask already covers all channels that can
+ * drive it.
+ */
+ if (ep_routing && (linked_outputs & BIT(output))) {
+ dev_dbg(rcdu->dev,
+ "output %s already linked, skipping port %u endpoint %u\n",
+ rzg2l_du_output_name(output), ep.port, ep.id);
continue;
}
@@ -315,6 +357,7 @@ static int rzg2l_du_encoders_init(struct rzg2l_du_device *rcdu)
continue;
}
+ linked_outputs |= BIT(output);
num_encoders++;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 09/13] drm: renesas: rz-du: Narrow active channels to DT-connected outputs
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
` (7 preceding siblings ...)
2026-05-07 9:21 ` [PATCH v7 08/13] drm: renesas: rz-du: Add endpoint-based output routing Tommaso Merciai
@ 2026-05-07 9:21 ` Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 10/13] drm: renesas: rz-du: Skip disabled endpoint nodes in encoder init Tommaso Merciai
` (3 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
Skip CRTC creation for DU channels that have no connected output in DT.
Scan the device endpoint graph to determine which channels have at least
one endpoint with a remote-endpoint phandle, and restrict the active
channels mask to that subset.
On EP-routing platforms (RZG2L_DU_FEATURE_EP_ROUTING), port@N maps
directly to DU channel N. On port-based platforms, any connected
endpoint activates the single hardware channel.
Update rzg2l_du_vsps_init() to compute the renesas,vsps property stride
from the full hardware channel count (hweight8(channels_mask)) rather
than the narrowed connected count, so the correct DT entry is selected
for each active channel.
No functional change intended for existing platforms.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v6->v7:
- New patch.
drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c | 58 +++++++++++++++++---
1 file changed, 49 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
index 01b037594926..c2cd542a8cf5 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
@@ -364,7 +364,8 @@ static int rzg2l_du_encoders_init(struct rzg2l_du_device *rcdu)
return num_encoders;
}
-static int rzg2l_du_vsps_init(struct rzg2l_du_device *rcdu)
+static int rzg2l_du_vsps_init(struct rzg2l_du_device *rcdu,
+ unsigned long channels_mask)
{
const struct device_node *np = rcdu->dev->of_node;
const char *vsps_prop_name = "renesas,vsps";
@@ -374,6 +375,8 @@ static int rzg2l_du_vsps_init(struct rzg2l_du_device *rcdu)
unsigned int crtcs_mask;
} vsps[RZG2L_DU_MAX_VSPS] = { { NULL, }, };
unsigned int vsps_count = 0;
+ unsigned int swindex = 0;
+ unsigned int hwindex;
unsigned int cells;
unsigned int i;
int ret;
@@ -384,15 +387,15 @@ static int rzg2l_du_vsps_init(struct rzg2l_du_device *rcdu)
* connected DU CRTCs.
*/
ret = of_property_count_u32_elems(np, vsps_prop_name);
- cells = ret / rcdu->num_crtcs - 1;
+ cells = ret / hweight8(rcdu->info->channels_mask) - 1;
if (cells != 1)
return -EINVAL;
- for (i = 0; i < rcdu->num_crtcs; ++i) {
+ for_each_set_bit(hwindex, &channels_mask, RZG2L_DU_MAX_CRTCS) {
unsigned int j;
ret = of_parse_phandle_with_fixed_args(np, vsps_prop_name,
- cells, i, &args);
+ cells, hwindex, &args);
if (ret < 0)
goto done;
@@ -410,15 +413,16 @@ static int rzg2l_du_vsps_init(struct rzg2l_du_device *rcdu)
else
vsps[vsps_count++].np = args.np;
- vsps[j].crtcs_mask |= BIT(i);
+ vsps[j].crtcs_mask |= BIT(swindex);
/*
* Store the VSP pointer and pipe index in the CRTC. If the
* second cell of the 'renesas,vsps' specifier isn't present,
* default to 0.
*/
- rcdu->crtcs[i].vsp = &rcdu->vsps[j];
- rcdu->crtcs[i].vsp_pipe = cells >= 1 ? args.args[0] : 0;
+ rcdu->crtcs[swindex].vsp = &rcdu->vsps[j];
+ rcdu->crtcs[swindex].vsp_pipe = cells >= 1 ? args.args[0] : 0;
+ swindex++;
}
/*
@@ -443,8 +447,36 @@ static int rzg2l_du_vsps_init(struct rzg2l_du_device *rcdu)
return ret;
}
+static unsigned int rzg2l_du_connected_channels(struct rzg2l_du_device *rcdu)
+{
+ struct device_node *np = rcdu->dev->of_node;
+ unsigned int connected = 0;
+ struct device_node *ep_node;
+
+ for_each_endpoint_of_node(np, ep_node) {
+ struct of_endpoint ep;
+ struct device_node *remote;
+
+ if (!of_device_is_available(ep_node))
+ continue;
+
+ if (of_graph_parse_endpoint(ep_node, &ep))
+ continue;
+
+ remote = of_graph_get_remote_endpoint(ep_node);
+ if (!remote)
+ continue;
+ of_node_put(remote);
+
+ connected |= BIT(ep.port);
+ }
+
+ return rcdu->info->channels_mask & connected;
+}
+
int rzg2l_du_modeset_init(struct rzg2l_du_device *rcdu)
{
+ struct device_node *np = rcdu->dev->of_node;
struct drm_device *dev = &rcdu->ddev;
struct drm_encoder *encoder;
unsigned long channels_mask;
@@ -470,7 +502,15 @@ int rzg2l_du_modeset_init(struct rzg2l_du_device *rcdu)
dev->mode_config.max_width = 1920;
dev->mode_config.max_height = 1920;
- channels_mask = rcdu->info->channels_mask;
+ if (rzg2l_du_ep_routing(np)) {
+ channels_mask = rzg2l_du_connected_channels(rcdu);
+ if (!channels_mask) {
+ dev_err(rcdu->dev, "no connected DU channels found in DT\n");
+ return -ENODEV;
+ }
+ } else {
+ channels_mask = rcdu->info->channels_mask;
+ }
rcdu->num_crtcs = hweight8(channels_mask);
/*
@@ -482,7 +522,7 @@ int rzg2l_du_modeset_init(struct rzg2l_du_device *rcdu)
return ret;
/* Initialize the compositors. */
- ret = rzg2l_du_vsps_init(rcdu);
+ ret = rzg2l_du_vsps_init(rcdu, channels_mask);
if (ret < 0)
return ret;
--
2.54.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 10/13] drm: renesas: rz-du: Skip disabled endpoint nodes in encoder init
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
` (8 preceding siblings ...)
2026-05-07 9:21 ` [PATCH v7 09/13] drm: renesas: rz-du: Narrow active channels to DT-connected outputs Tommaso Merciai
@ 2026-05-07 9:21 ` Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 11/13] drm: renesas: rz-du: Add multi-VSP instance support in plane selection Tommaso Merciai
` (2 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
of_graph iterates all endpoint nodes regardless of their status
property. Skip endpoints marked as disabled in rzg2l_du_encoders_init()
so that unused outputs in the DT don't cause spurious encoder
initialisation.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v6->v7:
- New patch.
drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
index c2cd542a8cf5..9c158f9294c4 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
@@ -304,6 +304,9 @@ static int rzg2l_du_encoders_init(struct rzg2l_du_device *rcdu)
unsigned int i;
int ret;
+ if (!of_device_is_available(ep_node))
+ continue;
+
ret = of_graph_parse_endpoint(ep_node, &ep);
if (ret < 0) {
of_node_put(ep_node);
--
2.54.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 11/13] drm: renesas: rz-du: Add multi-VSP instance support in plane selection
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
` (9 preceding siblings ...)
2026-05-07 9:21 ` [PATCH v7 10/13] drm: renesas: rz-du: Skip disabled endpoint nodes in encoder init Tommaso Merciai
@ 2026-05-07 9:21 ` Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 12/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 13/13] drm: renesas: rz-du: Update output routing comment to reflect all supported outputs Tommaso Merciai
12 siblings, 0 replies; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
rzg2l_du_vsp_get_drm_plane() scans all DRM planes for a matching
pipe_index, but with multiple VSP instances two planes belonging to
different VSPs can share the same index. Add a vsp pointer check so
the search is scoped to the CRTC's own VSP instance.
No functional change for single-VSP platforms.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v6->v7:
- New patch.
drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c
index bc205c25cd21..1edbcb9f134f 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c
@@ -80,7 +80,8 @@ struct drm_plane *rzg2l_du_vsp_get_drm_plane(struct rzg2l_du_crtc *crtc,
drm_for_each_plane(plane, &rcdu->ddev) {
struct rzg2l_du_vsp_plane *vsp_plane = to_rzg2l_vsp_plane(plane);
- if (vsp_plane->index == pipe_index)
+ if (vsp_plane->vsp == crtc->vsp &&
+ vsp_plane->index == pipe_index)
break;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 12/13] drm: renesas: rz-du: Add RZ/G3E support
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
` (10 preceding siblings ...)
2026-05-07 9:21 ` [PATCH v7 11/13] drm: renesas: rz-du: Add multi-VSP instance support in plane selection Tommaso Merciai
@ 2026-05-07 9:21 ` Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 13/13] drm: renesas: rz-du: Update output routing comment to reflect all supported outputs Tommaso Merciai
12 siblings, 0 replies; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
The RZ/G3E SoC has 2 LCD controllers (LCDC), each containing a Frame
Compression Processor (FCPVD), a Video Signal Processor (VSPD), and a
Display Unit (DU).
LCDC0 supports DSI and LVDS (single or dual-channel) outputs.
LCDC1 supports DSI, LVDS (single-channel), and RGB outputs.
Depending on the selected output, the correct SMUX2 clock parent must be
chosen based on the requested duty cycle:
- Index 0 for LVDS -> CDIV7_DSIx_CLK (DUTY H/L=4/3, 4/7 duty cycle)
- Index 1 for DSI/DPAD -> CSDIV_2to16_PLLDSIx (symmetric 50% duty cycle)
To support this behavior, introduce the `RZG2L_DU_FEATURE_SMUX2_DSI_CLK`
feature flag.
Add support for the RZ/G3E SoC by introducing:
- `rzg2l_du_r9a09g047_info` structure
- The `renesas,r9a09g047-du` compatible string
Additionally, introduce the missing output definitions
`RZG2L_DU_OUTPUT_LVDS{0,1}`.
Introduce `rzg2l_du_crtc_atomic_check()` helper to store the routes from
the CRTC output to the DU outputs.
Bump RZG2L_DU_MAX_CRTCS and RZG2L_DU_MAX_VSPS to 2.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v6->v7:
- Removed feature flag usage, rebased on top of T2H/N2H LCDC series [1]
[1] https://patchwork.global.renesas.com/project/spl2-reviews/list/?series=694&state=%2A&archive=both
- Reworked commit body as now outputs routing is based on endpoint id
instead of port number.
- Fixed rzg2l_du_r9a09g047_info instead of rzg2l_du_r9a09g047_du_info.
- Added bump of RZG2L_DU_MAX_CRTCS and RZG2L_DU_MAX_VSPS to 2.
v5->v6:
- Aligned ports numbering with the bindings changes.
v4->v5:
- Fixed RG2L_DU_FEATURE_SMUX2_DSI_CLK to RZG2L_DU_FEATURE_SMUX2_DSI_CLK,
update commit body accordingly.
- Added features field documentation.
v3->v4:
- No changes.
v2->v3:
- No changes.
v1->v2:
- Instead of using clk-provider API to select the right parent clock,
based on the outputs. Just set the correct duty cycle based on the
output, this reflects at CPG lvl to select the right parent.
- Updated commit message accordingly.
drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c | 48 +++++++++++++++++++
drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c | 28 ++++++++++-
drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h | 7 ++-
3 files changed, 80 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
index 3e8b6cca6d57..5c455391015f 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
@@ -65,10 +65,31 @@
static void rzg2l_du_crtc_set_display_timing(struct rzg2l_du_crtc *rcrtc)
{
const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
+ struct rzg2l_du_crtc_state *rstate = to_rzg2l_crtc_state(rcrtc->crtc.state);
+ struct rzg2l_du_device *rcdu = rcrtc->dev;
unsigned long mode_clock = mode->clock * 1000;
u32 ditr0, ditr1, ditr2, ditr3, ditr4, pbcr0;
clk_prepare_enable(rcrtc->rzg2l_clocks.dclk);
+
+ if (rzg2l_du_has(rcdu, RZG2L_DU_FEATURE_SMUX2_DSI_CLK)) {
+ struct clk *clk_parent;
+
+ clk_parent = clk_get_parent(rcrtc->rzg2l_clocks.dclk);
+
+ /*
+ * Request appropriate duty cycle to let the clock driver select
+ * the correct parent:
+ * - CDIV7_DSIx_CLK (LVDS path): DUTY H/L=4/3, 4/7 duty cycle
+ * - CSDIV_2to16_PLLDSIx (DSI/RGB path): symmetric 50% duty cycle
+ */
+ if (rstate->outputs == BIT(RZG2L_DU_OUTPUT_LVDS0) ||
+ rstate->outputs == BIT(RZG2L_DU_OUTPUT_LVDS1))
+ clk_set_duty_cycle(clk_parent, 4, 7);
+ else
+ clk_set_duty_cycle(clk_parent, 1, 2);
+ }
+
clk_set_rate(rcrtc->rzg2l_clocks.dclk, mode_clock);
ditr0 = (DU_DITR0_DEMD_HIGH
@@ -252,6 +273,32 @@ static void rzg2l_du_crtc_stop(struct rzg2l_du_crtc *rcrtc)
* CRTC Functions
*/
+static int rzg2l_du_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_atomic_commit *state)
+{
+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
+ crtc);
+ struct rzg2l_du_crtc_state *rstate = to_rzg2l_crtc_state(crtc_state);
+ struct drm_encoder *encoder;
+
+ /* Store the routes from the CRTC output to the DU outputs. */
+ rstate->outputs = 0;
+
+ drm_for_each_encoder_mask(encoder, crtc->dev,
+ crtc_state->encoder_mask) {
+ struct rzg2l_du_encoder *renc;
+
+ /* Skip the writeback encoder. */
+ if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
+ continue;
+
+ renc = to_rzg2l_encoder(encoder);
+ rstate->outputs |= BIT(renc->output);
+ }
+
+ return 0;
+}
+
static void rzg2l_du_crtc_atomic_enable(struct drm_crtc *crtc,
struct drm_atomic_commit *state)
{
@@ -300,6 +347,7 @@ static void rzg2l_du_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
+ .atomic_check = rzg2l_du_crtc_atomic_check,
.atomic_flush = rzg2l_du_crtc_atomic_flush,
.atomic_enable = rzg2l_du_crtc_atomic_enable,
.atomic_disable = rzg2l_du_crtc_atomic_disable,
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
index 887b840e63d2..59dd7572c730 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
@@ -53,6 +53,29 @@ static const struct rzg2l_du_device_info rzg2l_du_r9a07g044_info = {
}
};
+static const struct rzg2l_du_device_info rzg2l_du_r9a09g047_info = {
+ .features = RZG2L_DU_FEATURE_SMUX2_DSI_CLK,
+ .channels_mask = BIT(0) | BIT(1),
+ .routes = {
+ [RZG2L_DU_OUTPUT_DSI0] = {
+ .possible_outputs = BIT(0) | BIT(1),
+ .ep = 0,
+ },
+ [RZG2L_DU_OUTPUT_DPAD0] = {
+ .possible_outputs = BIT(0) | BIT(1),
+ .ep = 1,
+ },
+ [RZG2L_DU_OUTPUT_LVDS0] = {
+ .possible_outputs = BIT(0) | BIT(1),
+ .ep = 2,
+ },
+ [RZG2L_DU_OUTPUT_LVDS1] = {
+ .possible_outputs = BIT(0) | BIT(1),
+ .ep = 3,
+ },
+ },
+};
+
static const struct rzg2l_du_device_info rzg2l_du_r9a09g057_info = {
.channels_mask = BIT(0),
.routes = {
@@ -79,6 +102,7 @@ static const struct rzg2l_du_device_info rzg2l_du_r9a09g077_info = {
static const struct of_device_id rzg2l_du_of_table[] = {
{ .compatible = "renesas,r9a07g043u-du", .data = &rzg2l_du_r9a07g043u_info },
{ .compatible = "renesas,r9a07g044-du", .data = &rzg2l_du_r9a07g044_info },
+ { .compatible = "renesas,r9a09g047-du", .data = &rzg2l_du_r9a09g047_info },
{ .compatible = "renesas,r9a09g057-du", .data = &rzg2l_du_r9a09g057_info },
{ .compatible = "renesas,r9a09g077-du", .data = &rzg2l_du_r9a09g077_info },
{ /* sentinel */ }
@@ -90,7 +114,9 @@ const char *rzg2l_du_output_name(enum rzg2l_du_output output)
{
static const char * const names[] = {
[RZG2L_DU_OUTPUT_DSI0] = "DSI0",
- [RZG2L_DU_OUTPUT_DPAD0] = "DPAD0"
+ [RZG2L_DU_OUTPUT_DPAD0] = "DPAD0",
+ [RZG2L_DU_OUTPUT_LVDS0] = "LVDS0",
+ [RZG2L_DU_OUTPUT_LVDS1] = "LVDS1"
};
if (output >= ARRAY_SIZE(names))
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
index eed8e1215f08..649cd9b70223 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
@@ -21,10 +21,13 @@ struct device;
struct drm_property;
#define RZG2L_DU_FEATURE_DPIO_OE BIT(0) /* Has DPIO output enable control */
+#define RZG2L_DU_FEATURE_SMUX2_DSI_CLK BIT(1) /* Select SMUX2 clock parent via duty cycle */
enum rzg2l_du_output {
RZG2L_DU_OUTPUT_DSI0,
RZG2L_DU_OUTPUT_DPAD0,
+ RZG2L_DU_OUTPUT_LVDS0,
+ RZG2L_DU_OUTPUT_LVDS1,
RZG2L_DU_OUTPUT_MAX,
};
@@ -62,8 +65,8 @@ struct rzg2l_du_device_info {
unsigned int features;
};
-#define RZG2L_DU_MAX_CRTCS 1
-#define RZG2L_DU_MAX_VSPS 1
+#define RZG2L_DU_MAX_CRTCS 2
+#define RZG2L_DU_MAX_VSPS 2
#define RZG2L_DU_MAX_DSI 1
struct rzg2l_du_device {
--
2.54.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 13/13] drm: renesas: rz-du: Update output routing comment to reflect all supported outputs
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
` (11 preceding siblings ...)
2026-05-07 9:21 ` [PATCH v7 12/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
@ 2026-05-07 9:21 ` Tommaso Merciai
12 siblings, 0 replies; 17+ messages in thread
From: Tommaso Merciai @ 2026-05-07 9:21 UTC (permalink / raw)
To: tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Geert Uytterhoeven, Magnus Damm, Laurent Pinchart,
dri-devel, devicetree, linux-kernel
The comment describing the DU output routing was outdated, listing only
DPAD0 and DSI0 as possible outputs. Since LVDS0 and LVDS1 are also valid
outputs supported by the driver, update the comment to reflect the full
set of possible outputs.
No functional change.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
index 649cd9b70223..dc1e5c4cbeb9 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.h
@@ -37,9 +37,9 @@ enum rzg2l_du_output {
* @port: device tree port number corresponding to this output route
* @ep: device tree endpoint id corresponding to this output route
*
- * The DU has 2 possible outputs (DPAD0, DSI0). Output routing data
- * specify the valid SoC outputs, which CRTC can drive the output, and the type
- * of in-SoC encoder for the output.
+ * The DU has multiple possible outputs (DSI0, DPAD0, LVDS0, LVDS1).
+ * Output routing data specify the valid SoC outputs, which CRTC can drive
+ * the output, and the type of in-SoC encoder for the output.
*/
struct rzg2l_du_output_routing {
unsigned int possible_outputs;
--
2.54.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v7 05/13] reset: Add devm_reset_control_get_optional_shared_by_index()
2026-05-07 9:21 ` [PATCH v7 05/13] reset: Add devm_reset_control_get_optional_shared_by_index() Tommaso Merciai
@ 2026-05-07 9:58 ` Philipp Zabel
0 siblings, 0 replies; 17+ messages in thread
From: Philipp Zabel @ 2026-05-07 9:58 UTC (permalink / raw)
To: Tommaso Merciai, tomm.merciai, geert, laurent.pinchart
Cc: linux-renesas-soc, biju.das.jz, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Laurent Pinchart, dri-devel, devicetree,
linux-kernel
On Do, 2026-05-07 at 11:21 +0200, Tommaso Merciai wrote:
> Add devm_reset_control_get_optional_shared_by_index() to allow the
> drivers to get optional shared reset by passing the index.
>
> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
> ---
> v6->v7:
> - New patch.
>
> include/linux/reset.h | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/include/linux/reset.h b/include/linux/reset.h
> index 9c391cf0c822..d49545019631 100644
> --- a/include/linux/reset.h
> +++ b/include/linux/reset.h
> @@ -965,6 +965,24 @@ devm_reset_control_get_shared_by_index(struct device *dev, int index)
> return __devm_reset_control_get(dev, NULL, index, RESET_CONTROL_SHARED);
> }
>
> +/**
> + * devm_reset_control_get_optional_shared_by_index - resource managed
> + * reset_control_get_optional_shared()
> + * @dev: device to be reset by the controller
> + * @index: index of the reset controller
> + *
> + * Managed reset_control_get_optional_shared(). For reset controllers returned
> + * from this function, reset_control_put() is called automatically on driver
> + * detach.
> + *
> + * See reset_control_get_optional_shared() for more information.
> + */
> +static inline struct reset_control *
> +devm_reset_control_get_optional_shared_by_index(struct device *dev, int index)
> +{
> + return __devm_reset_control_get(dev, NULL, index, RESET_CONTROL_OPTIONAL_SHARED);
> +}
> +
> /*
> * TEMPORARY calls to use during transition:
> *
Please don't look up by index.
I'd prefer to get rid of the remaining users of the _by_index() APIs
and remove them entirely.
You have specified reset-names in the bindings. Use them.
regards
Philipp
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v7 01/13] dt-bindings: display: renesas,rzg2l-du: Refuse port@1 for RZ/G2UL
2026-05-07 9:21 ` [PATCH v7 01/13] dt-bindings: display: renesas,rzg2l-du: Refuse port@1 for RZ/G2UL Tommaso Merciai
@ 2026-05-13 22:23 ` Rob Herring (Arm)
0 siblings, 0 replies; 17+ messages in thread
From: Rob Herring (Arm) @ 2026-05-13 22:23 UTC (permalink / raw)
To: Tommaso Merciai
Cc: Laurent Pinchart, devicetree, Simona Vetter, linux-renesas-soc,
Magnus Damm, David Airlie, Krzysztof Kozlowski, geert,
Conor Dooley, laurent.pinchart, Philipp Zabel, tomm.merciai,
biju.das.jz, dri-devel, Geert Uytterhoeven, Thomas Zimmermann,
linux-kernel, Maarten Lankhorst, Maxime Ripard
On Thu, 07 May 2026 11:21:29 +0200, Tommaso Merciai wrote:
> The RZ/G2UL DU supports only a single port@0 DPI. Explicitly refuse
> port@1 in the ports node.
>
> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
> ---
> v6->v7:
> - Collected LPinchart tag.
> - Removed wrong fixes tag.
>
> v5->v6:
> - New patch.
>
> Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml | 1 +
> 1 file changed, 1 insertion(+)
>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v7 02/13] dt-bindings: display: renesas,rzg2l-du: Add support for RZ/G3E SoC
2026-05-07 9:21 ` [PATCH v7 02/13] dt-bindings: display: renesas,rzg2l-du: Add support for RZ/G3E SoC Tommaso Merciai
@ 2026-05-13 22:27 ` Rob Herring
0 siblings, 0 replies; 17+ messages in thread
From: Rob Herring @ 2026-05-13 22:27 UTC (permalink / raw)
To: Tommaso Merciai
Cc: tomm.merciai, geert, laurent.pinchart, linux-renesas-soc,
biju.das.jz, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, Geert Uytterhoeven, Magnus Damm,
Laurent Pinchart, dri-devel, devicetree, linux-kernel
On Thu, May 07, 2026 at 11:21:30AM +0200, Tommaso Merciai wrote:
> The RZ/G3E SoC integrates two LCD controllers (LCDC0 and LCDC1), each
> containing a FCPVD, VSPD, and Display Unit (DU).
>
> - LCDC0 supports DSI and LVDS (single or dual-channel) outputs.
> - LCDC1 supports DSI, LVDS (single-channel), and RGB outputs.
>
> Add compatible string 'renesas,r9a09g047-du' and extend the binding to
> support two DU instances: add reg-names ('du0'/'du1'), extend reg,
> interrupts, and resets to maxItems: 2, and extend clocks/clock-names to
> six entries (aclk/pclk/vclk per instance, minItems: 3).
Don't write what the diff has. I can read the diff for that.
>
> Drop the "Each port shall have a single endpoint." constraint since
> RZ/G3E ports expose multiple endpoints.
>
> Add a RZ/G3E-specific allOf rule mapping two DU instances to two ports:
>
> - port@0 (DU0): endpoint@0 DSI, endpoint@2 LVDS ch0, endpoint@3 LVDS ch1
> - port@1 (DU1): endpoint@0 DSI, endpoint@1 RGB (DPAD), endpoint@3 LVDS ch1
>
> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
> ---
> v6->v7:
> - Rebased on top of [1]
> [1] https://lore.kernel.org/all/20260429170012.366537-1-prabhakar.mahadev-lad.rj@bp.renesas.com/
> - Use single DRM device aggregating both DU instances (1 DU dt node),
> modelling single port for each DU0, DU1 and multiple endpoints for
> outputs.
That seems like the completely wrong thing to do and you've given no
reason why you think it is the right choice.
Rob
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2026-05-13 22:27 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-07 9:21 [PATCH v7 00/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 01/13] dt-bindings: display: renesas,rzg2l-du: Refuse port@1 for RZ/G2UL Tommaso Merciai
2026-05-13 22:23 ` Rob Herring (Arm)
2026-05-07 9:21 ` [PATCH v7 02/13] dt-bindings: display: renesas,rzg2l-du: Add support for RZ/G3E SoC Tommaso Merciai
2026-05-13 22:27 ` Rob Herring
2026-05-07 9:21 ` [PATCH v7 03/13] drm: renesas: rz-du: Move mmio from rzg2l_du_device to rzg2l_du_crtc Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 04/13] drm: renesas: rz-du: crtc: Introduce rzg2l_du_crtc_clk_get() Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 05/13] reset: Add devm_reset_control_get_optional_shared_by_index() Tommaso Merciai
2026-05-07 9:58 ` Philipp Zabel
2026-05-07 9:21 ` [PATCH v7 06/13] drm: renesas: rz-du: crtc: Parameterize rzg2l_du_crtc_create() with hw/sw index Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 07/13] drm: renesas: rz-du: kms: Enable multi CRTC creation Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 08/13] drm: renesas: rz-du: Add endpoint-based output routing Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 09/13] drm: renesas: rz-du: Narrow active channels to DT-connected outputs Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 10/13] drm: renesas: rz-du: Skip disabled endpoint nodes in encoder init Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 11/13] drm: renesas: rz-du: Add multi-VSP instance support in plane selection Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 12/13] drm: renesas: rz-du: Add RZ/G3E support Tommaso Merciai
2026-05-07 9:21 ` [PATCH v7 13/13] drm: renesas: rz-du: Update output routing comment to reflect all supported outputs Tommaso Merciai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox