Hello, On 5/5/26 02:24, Cristian Ciocaltea wrote:
LAYERSEL_REGDONE_SEL mask of RK3568_OVL_CTRL register controls which Video Port (VP) vsync latches the shared RK3568_OVL_{LAYER|PORT}_SEL shadow registers into the active configuration.rk3568_vop2_setup_layer_mixer() overwrites LAYERSEL_REGDONE_SEL to the current VP ID before waiting for the previous VP layer configuration to take effect. As a consequence, the previous VP vsync can no longer trigger the latch, so the wait polls a value that might never appear. Move the layer cfg done wait before the RK3568_OVL_CTRL write so the previous VP vsync can still commit the pending configuration. Fixes: 3e89a8c68354 ("drm/rockchip: vop2: Fix the update of LAYER/PORT select registers when there are multi display output on rk3588/rk3568") Signed-off-by: Cristian Ciocaltea <[email protected]>
Reviewed-by: Andy Yan <[email protected]>
--- drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c index edca0fb16e08..5206f01ec787 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -2289,15 +2289,6 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp) * lead to the configuration of the previous VP being take effect along with the VSYNC * of the new VP. */ - if (layer_sel != old_layer_sel || port_sel != old_port_sel) - ovl_ctrl |= FIELD_PREP(RK3568_OVL_CTRL__LAYERSEL_REGDONE_SEL, vp->id); - vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl); - - if (port_sel != old_port_sel) { - vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel); - vop2_cfg_done(vp); - rk3568_vop2_wait_for_port_mux_done(vop2); - }if (layer_sel != old_layer_sel && atv_layer_sel != old_layer_sel) {cfg_done = vop2_readl(vop2, RK3568_REG_CFG_DONE); @@ -2310,6 +2301,16 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp) rk3568_vop2_wait_for_layer_cfg_done(vop2, old_layer_sel); }+ if (layer_sel != old_layer_sel || port_sel != old_port_sel)+ ovl_ctrl |= FIELD_PREP(RK3568_OVL_CTRL__LAYERSEL_REGDONE_SEL, vp->id); + vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl); + + if (port_sel != old_port_sel) { + vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel); + vop2_cfg_done(vp); + rk3568_vop2_wait_for_port_mux_done(vop2); + } + vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel); mutex_unlock(&vop2->ovl_lock); }
