[PATCH v7 4/9] drm: renesas: rcar-du: embed the writeback encoder in rcar_du_crtc

From: Dmitry Baryshkov

Date: Mon Oct 19 2026 - 09:35:34 EST


drm_writeback_connector_init() hides the encoder inside struct
drm_writeback_connector, which is the only reason that structure carries
an encoder at all. Every other writeback user already owns its encoder.

Embed the encoder in the driver's own structure and register the
connector with drm_writeback_connector_init_with_encoder(), so that the
encoder can be dropped from drm_writeback_connector.

Assisted-by: LLM
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.h | 2 ++
.../gpu/drm/renesas/rcar-du/rcar_du_writeback.c | 29 +++++++++++++++++-----
2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.h
index 8857926e109a..d8b1dcab8dea 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.h
@@ -44,6 +44,7 @@ struct rcar_du_vsp;
* @vsp: VSP feeding video to this CRTC
* @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
* @writeback: the writeback connector
+ * @encoder: the writeback encoder
*/
struct rcar_du_crtc {
struct drm_crtc crtc;
@@ -74,6 +75,7 @@ struct rcar_du_crtc {
unsigned int sources_count;

struct drm_writeback_connector writeback;
+ struct drm_encoder encoder;
};

#define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc)
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_writeback.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_writeback.c
index e5e6e6a156aa..b0c1ca0d0dfa 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_writeback.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_writeback.c
@@ -174,6 +174,10 @@ static int rcar_du_wb_enc_atomic_check(struct drm_encoder *encoder,
return 0;
}

+static const struct drm_encoder_funcs rcar_du_wb_enc_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
static const struct drm_encoder_helper_funcs rcar_du_wb_enc_helper_funcs = {
.atomic_check = rcar_du_wb_enc_atomic_check,
};
@@ -201,16 +205,29 @@ int rcar_du_writeback_init(struct rcar_du_device *rcdu,
struct rcar_du_crtc *rcrtc)
{
struct drm_writeback_connector *wb_conn = &rcrtc->writeback;
+ struct drm_encoder *encoder = &rcrtc->encoder;
+ int ret;
+
+ drm_encoder_helper_add(encoder, &rcar_du_wb_enc_helper_funcs);
+ encoder->possible_crtcs = drm_crtc_mask(&rcrtc->crtc);
+
+ ret = drm_encoder_init(&rcdu->ddev, encoder, &rcar_du_wb_enc_funcs,
+ DRM_MODE_ENCODER_VIRTUAL, NULL);
+ if (ret)
+ return ret;

drm_connector_helper_add(&wb_conn->base,
&rcar_du_wb_conn_helper_funcs);

- return drm_writeback_connector_init(&rcdu->ddev, wb_conn,
- &rcar_du_wb_conn_funcs,
- &rcar_du_wb_enc_helper_funcs,
- writeback_formats,
- ARRAY_SIZE(writeback_formats),
- 1 << drm_crtc_index(&rcrtc->crtc));
+ ret = drm_writeback_connector_init_with_encoder(&rcdu->ddev, wb_conn,
+ encoder,
+ &rcar_du_wb_conn_funcs,
+ writeback_formats,
+ ARRAY_SIZE(writeback_formats));
+ if (ret)
+ drm_encoder_cleanup(encoder);
+
+ return ret;
}

void rcar_du_writeback_setup(struct rcar_du_crtc *rcrtc,

--
2.47.3