From: Andy Yan andy.yan@rock-chips.com
[ Upstream commit c5996e4ab109c8bb5541453b20647eaaf9350f41 ]
Because the layer/window enable/disable is take effect by vsync, if the overlay configuration of these layers does not follow vsync and takes effect immediately instead, when multiple layers are dynamically enable/disable, inconsistent display contents may be seen on the screen.
Signed-off-by: Andy Yan andy.yan@rock-chips.com Signed-off-by: Heiko Stuebner heiko@sntech.de Link: https://lore.kernel.org/r/20250318062024.4555-1-andyshrk@163.com Signed-off-by: Sasha Levin sashal@kernel.org ---
Based on my analysis of the commit and the kernel repository context, here is my assessment: **YES** This commit should be backported to stable kernel trees for the following extensive reasons: ## Code Analysis The commit addresses a critical timing synchronization issue in the Rockchip VOP2 display controller. The changes are: 1. **Register Bit Field Changes**: The commit modifies `RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD` and introduces `RK3568_OVL_CTRL__LAYERSEL_REGDONE_SEL` in the header file, indicating a switch from immediate register updates to vsync-synchronized updates. 2. **Timing Control Logic**: In `rk3568_vop2_setup_layer_mixer()`, the code changes from: ```c ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD; // Immediate mode ``` to: ```c ovl_ctrl &= ~RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD; // Remove immediate mode ovl_ctrl |= FIELD_PREP(RK3568_OVL_CTRL__LAYERSEL_REGDONE_SEL, vp->id); // Per-VP vsync sync ``` ## Why This Should Be Backported ### 1. **Fixes User-Visible Display Corruption** The commit message explicitly states it fixes "inconsistent display contents" when multiple layers are dynamically enabled/disabled. This is a user-visible bug that affects display quality and stability. ### 2. **Critical Display Functionality** The overlay layer selection controls fundamental display pipeline routing in VOP2. From examining similar commits, I found this subsystem has had multiple recent layer-related fixes, indicating active issues in this area that affect real users. ### 3. **Low Risk, High Impact Change** - **Low Risk**: The change only modifies timing synchronization, not display logic - **High Impact**: Affects any Rockchip RK3568/RK3588 system using multiple display layers - **Contained Scope**: Limited to VOP2 overlay timing control ### 4. **Follows Stable Tree Criteria** - **Important bugfix**: Fixes visible display artifacts - **Small and contained**: Only changes register timing configuration - **No architectural changes**: Maintains existing display logic - **Clear side effects**: Improves display consistency during layer transitions ### 5. **Hardware Synchronization Issue** The commit addresses a fundamental hardware synchronization problem where layer enable/disable operations take effect at vsync, but overlay configuration was taking effect immediately. This mismatch creates race conditions causing display corruption during dynamic layer changes. ### 6. **Broad User Impact** Systems commonly affected include: - Video players with overlay graphics - Compositing window managers - Embedded displays with multiple UI layers - Any application dynamically managing display layers The fix ensures that overlay layer selection changes are properly synchronized with display refresh cycles, eliminating intermediate corrupted states that users can see during layer transitions. This is exactly the type of important, low-risk display fix that stable trees should include.
drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 1 + drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h index 680bedbb770e6..fc3ecb9fcd957 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h @@ -710,6 +710,7 @@ enum dst_factor_mode {
#define VOP2_COLOR_KEY_MASK BIT(31)
+#define RK3568_OVL_CTRL__LAYERSEL_REGDONE_SEL GENMASK(31, 30) #define RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD BIT(28) #define RK3568_OVL_CTRL__YUV_MODE(vp) BIT(vp)
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c index 0a2840cbe8e22..32c4ed6857395 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -2070,7 +2070,10 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp) struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL); - ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD; + ovl_ctrl &= ~RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD; + ovl_ctrl &= ~RK3568_OVL_CTRL__LAYERSEL_REGDONE_SEL; + ovl_ctrl |= FIELD_PREP(RK3568_OVL_CTRL__LAYERSEL_REGDONE_SEL, vp->id); + if (vcstate->yuv_overlay) ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id); else