drm/rockchip: vop2: Wait for layer cfg done before switching LAYERSEL_REGDONE_SEL

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: 3e89a8c683 ("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 <cristian.ciocaltea@collabora.com>
Reviewed-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patch.msgid.link/20260504-vop2-layer-cfg-tmout-v1-2-730226a7331e@collabora.com
This commit is contained in:
Cristian Ciocaltea 2026-05-04 21:24:00 +03:00 committed by Heiko Stuebner
parent 9f5670802d
commit d1ad644e57

View File

@ -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);
}