[PATCH v8 4/9] drm: renesas: rz-du: vsp: Keep the planes in the VSP

From: Tommaso Merciai

Date: Fri Aug 28 2026 - 08:25:16 EST


Each VSP numbers its planes from zero, so the device-wide search in
rzg2l_du_vsp_get_drm_plane() picks the wrong plane as soon as a SoC has
more than one VSP: the primary plane of the second CRTC is looked up on
the first VSP, whose possible_crtcs mask does not cover that CRTC.

In preparation of supporting RZ/G3E, store the planes in the VSP that
owns them and index the per-VSP array directly from
rzg2l_du_crtc_create(). Validate the pipe index read from the device
tree, and drop the now unused search helper.

No functional change intended.

Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@xxxxxxxxxxxxxx>
---
v7->v8
- New patch.

drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c | 10 ++++++---
drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c | 21 ++++---------------
drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.h | 11 ++++------
3 files changed, 15 insertions(+), 27 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 5aecf325e89b..81934fcb551b 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c
@@ -420,9 +420,13 @@ int rzg2l_du_crtc_create(struct rzg2l_du_device *rcdu, unsigned int swindex,
init_waitqueue_head(&rcrtc->flip_wait);
rcrtc->dev = rcdu;

- primary = rzg2l_du_vsp_get_drm_plane(rcrtc, rcrtc->vsp_pipe);
- if (IS_ERR(primary))
- return PTR_ERR(primary);
+ if (rcrtc->vsp_pipe >= rcrtc->vsp->num_planes) {
+ dev_err(rcdu->dev, "invalid VSP pipe %u for DU%u\n",
+ rcrtc->vsp_pipe, hwindex);
+ return -EINVAL;
+ }
+
+ primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe]->plane;

ret = drmm_crtc_init_with_planes(&rcdu->ddev, crtc, primary, NULL,
&crtc_funcs_rz, NULL);
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 1efa0f0451fe..b0565b88d841 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c
@@ -71,22 +71,6 @@ void rzg2l_du_vsp_atomic_flush(struct rzg2l_du_crtc *crtc)
vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
}

-struct drm_plane *rzg2l_du_vsp_get_drm_plane(struct rzg2l_du_crtc *crtc,
- unsigned int pipe_index)
-{
- struct rzg2l_du_device *rcdu = crtc->vsp->dev;
- struct drm_plane *plane = NULL;
-
- 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)
- break;
- }
-
- return plane ? plane : ERR_PTR(-EINVAL);
-}
-
static const u32 rzg2l_du_vsp_formats[] = {
DRM_FORMAT_RGB332,
DRM_FORMAT_ARGB4444,
@@ -306,7 +290,7 @@ int rzg2l_du_vsp_init(struct rzg2l_du_vsp *vsp, struct device_node *np,
struct rzg2l_du_device *rcdu = vsp->dev;
struct platform_device *pdev;
unsigned int num_crtcs = hweight32(crtcs);
- unsigned int num_planes = 2;
+ unsigned int num_planes = RZG2L_DU_VSP_MAX_PLANES;
unsigned int i;
int ret;

@@ -353,6 +337,7 @@ int rzg2l_du_vsp_init(struct rzg2l_du_vsp *vsp, struct device_node *np,

plane->vsp = vsp;
plane->index = i;
+ vsp->planes[i] = plane;

drm_plane_helper_add(&plane->plane,
&rzg2l_du_vsp_plane_helper_funcs);
@@ -365,6 +350,8 @@ int rzg2l_du_vsp_init(struct rzg2l_du_vsp *vsp, struct device_node *np,
BIT(DRM_MODE_BLEND_PIXEL_NONE) |
BIT(DRM_MODE_BLEND_PREMULTI) |
BIT(DRM_MODE_BLEND_COVERAGE));
+
+ vsp->num_planes++;
}

return 0;
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.h b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.h
index a22aaf0843ed..63f6e508264d 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.h
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.h
@@ -27,11 +27,15 @@ struct rzg2l_du_vsp_plane {
unsigned int index;
};

+#define RZG2L_DU_VSP_MAX_PLANES 2
+
struct rzg2l_du_vsp {
unsigned int index;
struct device *vsp;
struct device_link *link;
struct rzg2l_du_device *dev;
+ struct rzg2l_du_vsp_plane *planes[RZG2L_DU_VSP_MAX_PLANES];
+ unsigned int num_planes;
};

static inline struct rzg2l_du_vsp_plane *to_rzg2l_vsp_plane(struct drm_plane *p)
@@ -62,8 +66,6 @@ int rzg2l_du_vsp_init(struct rzg2l_du_vsp *vsp, struct device_node *np,
void rzg2l_du_vsp_enable(struct rzg2l_du_crtc *crtc);
void rzg2l_du_vsp_disable(struct rzg2l_du_crtc *crtc);
void rzg2l_du_vsp_atomic_flush(struct rzg2l_du_crtc *crtc);
-struct drm_plane *rzg2l_du_vsp_get_drm_plane(struct rzg2l_du_crtc *crtc,
- unsigned int pipe_index);
#else
static inline int rzg2l_du_vsp_init(struct rzg2l_du_vsp *vsp, struct device_node *np,
unsigned int crtcs)
@@ -74,11 +76,6 @@ static inline int rzg2l_du_vsp_init(struct rzg2l_du_vsp *vsp, struct device_node
static inline void rzg2l_du_vsp_enable(struct rzg2l_du_crtc *crtc) { };
static inline void rzg2l_du_vsp_disable(struct rzg2l_du_crtc *crtc) { };
static inline void rzg2l_du_vsp_atomic_flush(struct rzg2l_du_crtc *crtc) { };
-static inline struct drm_plane *rzg2l_du_vsp_get_drm_plane(struct rzg2l_du_crtc *crtc,
- unsigned int pipe_index)
-{
- return ERR_PTR(-ENXIO);
-}
#endif

#endif /* __RZG2L_DU_VSP_H__ */
--
2.54.0