drm/hisilicon: Implement some semblance of vblank event handling
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 8 Jun 2016 12:18:57 +0000 (14:18 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 9 Jun 2016 08:28:14 +0000 (10:28 +0200)
atomic_flush seems to be the right place, but I'm not entirely sure
whether this will catch them all. It could be that when disabling the
crtc we'll miss the vblank.

While at it nuke the dummy functions.

v2: Be more robust and either arm, when the CRTC is on, or just send
the event out right away.

Cc: Xinliang Liu <xinliang.liu@linaro.org>
Cc: Xinwei Kong <kong.kongxinwei@hisilicon.com>
Cc: Archit Taneja <architt@codeaurora.org>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1465388359-8070-5-git-send-email-daniel.vetter@ffwll.ch
drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c

index fba6372d060e2124dfa9cdf9208858ccf044ff90..ed76baad525fa5de193c97698341fa01e748c6ec 100644 (file)
@@ -502,13 +502,6 @@ static void ade_crtc_disable(struct drm_crtc *crtc)
        acrtc->enable = false;
 }
 
-static int ade_crtc_atomic_check(struct drm_crtc *crtc,
-                                struct drm_crtc_state *state)
-{
-       /* do nothing */
-       return 0;
-}
-
 static void ade_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
        struct ade_crtc *acrtc = to_ade_crtc(crtc);
@@ -537,6 +530,7 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
 {
        struct ade_crtc *acrtc = to_ade_crtc(crtc);
        struct ade_hw_ctx *ctx = acrtc->ctx;
+       struct drm_pending_vblank_event *event = crtc->state->event;
        void __iomem *base = ctx->base;
 
        /* only crtc is enabled regs take effect */
@@ -545,12 +539,22 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
                /* flush ade registers */
                writel(ADE_ENABLE, base + ADE_EN);
        }
+
+       if (event) {
+               crtc->state->event = NULL;
+
+               spin_lock_irq(&crtc->dev->event_lock);
+               if (drm_crtc_vblank_get(crtc) == 0)
+                       drm_crtc_arm_vblank_event(crtc, event);
+               else
+                       drm_crtc_send_vblank_event(crtc, event);
+               spin_unlock_irq(&crtc->dev->event_lock);
+       }
 }
 
 static const struct drm_crtc_helper_funcs ade_crtc_helper_funcs = {
        .enable         = ade_crtc_enable,
        .disable        = ade_crtc_disable,
-       .atomic_check   = ade_crtc_atomic_check,
        .mode_set_nofb  = ade_crtc_mode_set_nofb,
        .atomic_begin   = ade_crtc_atomic_begin,
        .atomic_flush   = ade_crtc_atomic_flush,