[PATCH 2/5] drm/rockchip: vop2: Wait for layer cfg done before switching LAYERSEL_REGDONE_SEL
Andy Yan
andy.yan at rock-chips.com
Mon Jun 1 03:45:28 PDT 2026
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 <cristian.ciocaltea at collabora.com>
Reviewed-by: Andy Yan <andy.yan at rock-chips.com>
> ---
> 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);
> }
>
More information about the linux-arm-kernel
mailing list