From cbf6a0d4e256eb560883fc132281f6573425a01c Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Sat, 26 Jul 2025 11:07:59 +0800 Subject: [PATCH] drm/rockchip: drv: fix encoder possible_clones check failed possible_clones is used to indicate which other encoders can share a CRTC with the current encoder. The default logic is that an encoder can exclusively occupy one CRTC. However, in scenarios such as writeback or connector mirroring, we can support multiple encoders sharing one CRTC, hence this logic is introduced. If less this commit, the writeback or connector mirror will commit failed at the drm_atomic_check_valid_clones(), which is introduced by the following commit: commit ffb55ddf2685 ("drm: Add valid clones check") Signed-off-by: Sandy Huang Change-Id: I6b962a3eee80b6fbe80d0dbea1d765b219d70719 --- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index aa4020b6e6ed..68342fd95cb5 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -1802,10 +1802,22 @@ int rockchip_drm_panel_loader_protect(struct drm_panel *panel, bool on) } EXPORT_SYMBOL(rockchip_drm_panel_loader_protect); +static void rockchip_drm_fix_encoder_possible_clones(struct drm_encoder *encoder) +{ + struct drm_device *drm_dev = encoder->dev; + struct drm_encoder *other; + + drm_for_each_encoder(other, drm_dev) { + if (other->possible_crtcs & encoder->possible_crtcs) + encoder->possible_clones |= drm_encoder_mask(other); + } +} + static int rockchip_drm_bind(struct device *dev) { struct drm_device *drm_dev; struct rockchip_drm_private *private; + struct drm_encoder *encoder; int ret; /* Remove existing drivers that may own the framebuffer memory. */ @@ -1895,6 +1907,9 @@ static int rockchip_drm_bind(struct device *dev) if (ret) goto err_kms_helper_poll_fini; + drm_for_each_encoder(encoder, drm_dev) + rockchip_drm_fix_encoder_possible_clones(encoder); + rockchip_drm_show_logo(drm_dev); ret = rockchip_drm_fbdev_init(drm_dev);