[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