From 5c295c7639743d1dcff31322281ebe283e0e20f0 Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Tue, 8 Apr 2025 16:46:47 +0800 Subject: [PATCH] drm/rockchip: vop2: avoid config done time close to vsync Avoid commit new plane time close to vsync at async mode, the following case maybe lead to error: vsync[1]->update plane[2]->config done[3]->update plane[4]->vsync[5] If new vsync[5] insert step 4, only part of plane register complete, this will lead to part of plane register take effect and lead to error. So we introduce this safeguard, when commit time exceeds 15/16 of a frame, this frame will be postponed to the next frame. Signed-off-by: Sandy Huang Change-Id: I4e405baf6ac080f6990e94f639c168ff9f0daf1c --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 46bbd657c764..b9de39ca740a 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -1084,6 +1084,12 @@ static inline void rk3588_vop2_dsc_cfg_done(struct drm_crtc *crtc); static inline void vop2_cfg_done(struct drm_crtc *crtc); static void vop2_wait_for_fs_by_done_bit_status(struct vop2_video_port *vp); static int vop2_clk_reset(struct reset_control *rstc); +static void vop2_wait_for_scan_timing_max_to_assigned_line(struct vop2_video_port *vp, + u32 current_line, + u32 wait_line); +static void vop2_wait_for_scan_timing_from_the_assigned_line(struct vop2_video_port *vp, + u32 current_line, + u32 wait_line); static inline struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc) { @@ -12555,6 +12561,25 @@ static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_stat goto out; } + /* + * Avoid commit new plane time close to vsync at async mode, the + * following case maybe lead to error: + * vsync[1] -> update plane[2] -> config done[3] -> update plane[4] -> vsync[5] + * If new vsync[5] insert step 4, only part of plane register complete, + * this will lead to part of plane register take effect and lead to error. + * + * So we introduce this safeguard, when commit time exceeds 15/16 of a frame, + * this commit will be postponed to the next frame. + */ + if (state->legacy_cursor_update) { + u16 vtotal = VOP_MODULE_GET(vop2, vp, dsp_vtotal); + u32 assigned_line = vtotal * 15 >> 4; + u32 current_line = vop2_read_vcnt(vp); + + if (current_line > assigned_line) + vop2_wait_for_scan_timing_max_to_assigned_line(vp, current_line, assigned_line); + } + if (vop2->version == VOP_VERSION_RK3588) vop2_crtc_update_vrr(crtc);