From 0c5249aab14d3d173c6cb96a2787e309bb289095 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Wed, 20 Oct 2021 20:28:15 +0800 Subject: [PATCH] drm/rockchip: vop2: Adjust wait critical time zone policy when there are two pending vp Current policy: If there are two pending config done vp, and one of them is at critical time zone, wait for the one wich has long time to vsync. This may lead a very long wait, for example: VP0 is 3840 x 2160, VP2 is 1920 x 1080, they are all have pending cfg done bits, and the vcnt of VP0 is 1367, the vcnt of VP2 is 995, VP2 is at the critical time zone, we will wait VP0 vsync(almost half frame time) according to this policy. This lead a very long wait. The new policy: If there are two pending config done vp, and one of them is at critical time zone, compare the left vcnt time of the two vp: if (first_vp_left_time > second_vp_left_time) { if ((first_vp_left_time - second_vp_left_time) > first_vp_safe_time) wait_vp = second_done_vp; else wait_vp = first_done_vp; } else { if ((second_vp_left_time - first_vp_left_time) > second_vp_safe_time) wait_vp = first_done_vp; else wait_vp = second_done_vp; } Change-Id: I7154ad716841c6c28947ddfecc845c7271cc507a Signed-off-by: Andy Yan --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 22 +++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index a9ffef9eff26..848e2f665d49 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -1037,20 +1037,22 @@ static int32_t vop2_pending_done_bits(struct vop2_video_port *vp) if (first_vp_left_time > first_vp_safe_time && second_vp_left_time > second_vp_safe_time) return done_bits_bak; - if (first_vp_left_time > second_vp_left_time) - wait_vp = first_done_vp; - else - wait_vp = second_done_vp; + + if (first_vp_left_time > second_vp_left_time) { + if ((first_vp_left_time - second_vp_left_time) > first_vp_safe_time) + wait_vp = second_done_vp; + else + wait_vp = first_done_vp; + } else { + if ((second_vp_left_time - first_vp_left_time) > second_vp_safe_time) + wait_vp = first_done_vp; + else + wait_vp = second_done_vp; + } vop2_wait_for_fs_by_done_bit_status(wait_vp); done_bits = vop2_readl(vop2, RK3568_REG_CFG_DONE) & 0x7; - if (done_bits) { - vp_id = ffs(done_bits) - 1; - done_vp = &vop2->vps[vp_id]; - vop2_wait_for_fs_by_done_bit_status(done_vp); - } - done_bits = 0; } return done_bits; }