From 8d3d26903e8aeab7bd385ac136c6d03224576bd5 Mon Sep 17 00:00:00 2001 From: Damon Ding Date: Tue, 8 Apr 2025 17:12:06 +0800 Subject: [PATCH] drm/rockchip: vop2: add support mcu panel psr mode Psr mode can help reduce power consumption when using the mcu panel, which supports to refresh the image on its own while it remains unchanged. Change-Id: Ib9bd1bb472c996277eb374cc9ba1433ce3930d55 Signed-off-by: Damon Ding --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 50 ++++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index c877c0f17875..f823c2c25623 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -5583,16 +5583,28 @@ static void vop2_crtc_atomic_enter_psr(struct drm_crtc *crtc, struct drm_crtc_st unsigned long win_mask = vp->enabled_win_mask; int phys_id; - for_each_set_bit(phys_id, &win_mask, ROCKCHIP_MAX_LAYER) { - win = vop2_find_win_by_phys_id(vop2, phys_id); - VOP_WIN_SET(vop2, win, enable, 0); + /* + * For mcu interface, if mcu_hold_mode is enabled, the wins will stop + * accessing DDR and the interface will also stop output. + * + * In addition, the regs operations related to disabling wins will not + * take effect when the mcu_hold_mode is enabled. + */ + if (vp->mcu_timing.mcu_pix_total) { + VOP_MODULE_SET(vop2, vp, mcu_hold_mode, 1); + } else { + for_each_set_bit(phys_id, &win_mask, ROCKCHIP_MAX_LAYER) { + win = vop2_find_win_by_phys_id(vop2, phys_id); + VOP_WIN_SET(vop2, win, enable, 0); - if (win->feature & WIN_FEATURE_CLUSTER_MAIN) - VOP_CLUSTER_SET(vop2, win, enable, 0); + if (win->feature & WIN_FEATURE_CLUSTER_MAIN) + VOP_CLUSTER_SET(vop2, win, enable, 0); + } + + vop2_cfg_done(crtc); + vop2_wait_for_fs_by_done_bit_status(vp); } - vop2_cfg_done(crtc); - vop2_wait_for_fs_by_done_bit_status(vp); if (hweight8(vop2->active_vp_mask) == 1) { u32 adjust_aclk_rate = 0; u32 htotal = (VOP_MODULE_GET(vop2, vp, htotal_pw) >> 16) & 0xffff; @@ -5626,15 +5638,23 @@ static void vop2_crtc_atomic_exit_psr(struct drm_crtc *crtc, struct drm_crtc_sta clk_set_rate(vop2->aclk, vop2->aclk_current_freq); vop2->aclk_rate_reset = false; - for_each_set_bit(phys_id, &enabled_win_mask, ROCKCHIP_MAX_LAYER) { - win = vop2_find_win_by_phys_id(vop2, phys_id); - VOP_WIN_SET(vop2, win, enable, 1); - if (win->feature & WIN_FEATURE_CLUSTER_MAIN) - VOP_CLUSTER_SET(vop2, win, enable, 1); - } + /* + * For mcu interface, if mcu_hold_mode is disabled, the wins will + * resume accessing DDR and the interface will also return to work. + */ + if (vp->mcu_timing.mcu_pix_total) { + VOP_MODULE_SET(vop2, vp, mcu_hold_mode, 0); + } else { + for_each_set_bit(phys_id, &enabled_win_mask, ROCKCHIP_MAX_LAYER) { + win = vop2_find_win_by_phys_id(vop2, phys_id); + VOP_WIN_SET(vop2, win, enable, 1); + if (win->feature & WIN_FEATURE_CLUSTER_MAIN) + VOP_CLUSTER_SET(vop2, win, enable, 1); + } - vop2_cfg_done(crtc); - vop2_wait_for_fs_by_done_bit_status(vp); + vop2_cfg_done(crtc); + vop2_wait_for_fs_by_done_bit_status(vp); + } } static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,