OSDN Git Service

drm/msm: enable vblank during atomic commits
authorRob Clark <robdclark@chromium.org>
Tue, 18 Aug 2020 16:31:19 +0000 (09:31 -0700)
committerRob Clark <robdclark@chromium.org>
Sat, 22 Aug 2020 05:30:17 +0000 (22:30 -0700)
This has roughly the same effect as drm_atomic_helper_wait_for_vblanks(),
basically just ensuring that vblank accounting is enabled so that we get
valid timestamp/seqn on pageflip events.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Tested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Rob Clark <robdclark@chromium.org>
drivers/gpu/drm/msm/msm_atomic.c

index 5ccfad7..561bfa4 100644 (file)
@@ -27,6 +27,34 @@ int msm_atomic_prepare_fb(struct drm_plane *plane,
        return msm_framebuffer_prepare(new_state->fb, kms->aspace);
 }
 
+/*
+ * Helpers to control vblanks while we flush.. basically just to ensure
+ * that vblank accounting is switched on, so we get valid seqn/timestamp
+ * on pageflip events (if requested)
+ */
+
+static void vblank_get(struct msm_kms *kms, unsigned crtc_mask)
+{
+       struct drm_crtc *crtc;
+
+       for_each_crtc_mask(kms->dev, crtc, crtc_mask) {
+               if (!crtc->state->active)
+                       continue;
+               drm_crtc_vblank_get(crtc);
+       }
+}
+
+static void vblank_put(struct msm_kms *kms, unsigned crtc_mask)
+{
+       struct drm_crtc *crtc;
+
+       for_each_crtc_mask(kms->dev, crtc, crtc_mask) {
+               if (!crtc->state->active)
+                       continue;
+               drm_crtc_vblank_put(crtc);
+       }
+}
+
 static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx)
 {
        unsigned crtc_mask = BIT(crtc_idx);
@@ -44,6 +72,8 @@ static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx)
 
        kms->funcs->enable_commit(kms);
 
+       vblank_get(kms, crtc_mask);
+
        /*
         * Flush hardware updates:
         */
@@ -58,6 +88,8 @@ static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx)
        kms->funcs->wait_flush(kms, crtc_mask);
        trace_msm_atomic_wait_flush_finish(crtc_mask);
 
+       vblank_put(kms, crtc_mask);
+
        mutex_lock(&kms->commit_lock);
        kms->funcs->complete_commit(kms, crtc_mask);
        mutex_unlock(&kms->commit_lock);
@@ -221,6 +253,8 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
         */
        kms->pending_crtc_mask &= ~crtc_mask;
 
+       vblank_get(kms, crtc_mask);
+
        /*
         * Flush hardware updates:
         */
@@ -235,6 +269,8 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
        kms->funcs->wait_flush(kms, crtc_mask);
        trace_msm_atomic_wait_flush_finish(crtc_mask);
 
+       vblank_put(kms, crtc_mask);
+
        mutex_lock(&kms->commit_lock);
        kms->funcs->complete_commit(kms, crtc_mask);
        mutex_unlock(&kms->commit_lock);