drm:vc4: Add wait for vblank twice and then page flip 'workaround' 50/231050/1 accepted/tizen/unified/20200422.032155 submit/tizen/20200421.025351
authorHoegeun Kwon <hoegeun.kwon@samsung.com>
Fri, 17 Apr 2020 03:39:23 +0000 (12:39 +0900)
committerHoegeun Kwon <hoegeun.kwon@samsung.com>
Fri, 17 Apr 2020 03:52:44 +0000 (12:52 +0900)
There is problem for tearing, wait for vblank twice and then run
page_flip.

Change-Id: I723a51bee9d956231253f5caa5fe989a7eaf0182
Signed-off-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
drivers/gpu/drm/vc4/vc4_firmware_kms.c

index 92f6d58..07946af 100644 (file)
@@ -250,6 +250,8 @@ struct vc4_crtc {
        bool vblank_enabled;
        u32 display_number;
        u32 display_type;
+
+       u32 cnt_vblanks;
 };
 
 static inline struct vc4_crtc *to_vc4_crtc(struct drm_crtc *crtc)
@@ -1059,8 +1061,13 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
 static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
                                  struct drm_crtc_state *old_state)
 {
+       struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+
        DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_flush.\n",
                      crtc->base.id);
+
+       vc4_crtc->cnt_vblanks = 2;
+
        if (crtc->state->active && old_state->active && crtc->state->event)
                vc4_crtc_consume_event(crtc);
 }
@@ -1071,8 +1078,14 @@ static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
        struct drm_device *dev = crtc->dev;
        unsigned long flags;
 
+       /*
+        * WORKAROUND: A tearing problem occurs due to a firmware,
+        * so we wait for vblank twice and then run page_flip.
+        */
        spin_lock_irqsave(&dev->event_lock, flags);
-       if (vc4_crtc->event) {
+       if (vc4_crtc->cnt_vblanks)
+               vc4_crtc->cnt_vblanks--;
+       if (vc4_crtc->event && !vc4_crtc->cnt_vblanks) {
                drm_crtc_send_vblank_event(crtc, vc4_crtc->event);
                vc4_crtc->event = NULL;
                drm_crtc_vblank_put(crtc);