From bb0ed863d88d8a3cec260c4d05275d8843af3495 Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Mon, 6 Feb 2023 11:29:33 +0800 Subject: [PATCH] drm/rockchip: vop2: filter VP vcnt status VP vcnt update and read are driven by two asynchronous dclk and hclk, so add this filtering process, otherwise may read the wrong vcnt value. Signed-off-by: Sandy Huang Change-Id: Ibe933c3b507933720222544ac695e06ad6b957dd --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index e2b66130055e..14cb1c3f5201 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -1286,8 +1286,23 @@ static bool vop2_fs_irq_is_pending(struct vop2_video_port *vp) static uint32_t vop2_read_vcnt(struct vop2_video_port *vp) { uint32_t offset = RK3568_SYS_STATUS0 + (vp->id << 2); + uint32_t vcnt0, vcnt1; + int i = 0; - return vop2_readl(vp->vop2, offset) >> 16; + for (i = 0; i < 10; i++) { + vcnt0 = vop2_readl(vp->vop2, offset) >> 16; + vcnt1 = vop2_readl(vp->vop2, offset) >> 16; + + if ((vcnt1 - vcnt0) <= 1) + break; + } + + if (i == 10) { + DRM_DEV_ERROR(vp->vop2->dev, "read VP%d vcnt error: %d %d\n", vp->id, vcnt0, vcnt1); + vcnt1 = vop2_readl(vp->vop2, offset) >> 16; + } + + return vcnt1; } static void vop2_wait_for_irq_handler(struct drm_crtc *crtc)