Decouple vblank handling from the underlying hrtimer. This will be
helpful for replacing vmwgfx's vblank timer with DRM's common
implementation.

The new helper vmw_vkms_handle_vblank_timeout() can later be used as
callback for DRM's handle_vblank call as-is. The remaining code in
vmw_vkms_vblank_simulate() will be replaced by the DRM implementation.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c | 37 +++++++++++++++++++---------
 drivers/gpu/drm/vmwgfx/vmwgfx_vkms.h |  1 +
 2 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c
index 7862f6972512..15439ddd4f22 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c
@@ -157,27 +157,19 @@ crc_generate_worker(struct work_struct *work)
                drm_crtc_add_crc_entry(crtc, true, frame_start++, &crc32);
 }
 
-static enum hrtimer_restart
-vmw_vkms_vblank_simulate(struct hrtimer *timer)
+bool
+vmw_vkms_handle_vblank_timeout(struct drm_crtc *crtc)
 {
-       struct vmw_display_unit *du = container_of(timer, struct 
vmw_display_unit, vkms.timer);
-       struct drm_crtc *crtc = &du->crtc;
+       struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
        struct vmw_private *vmw = vmw_priv(crtc->dev);
        bool has_surface = false;
-       u64 ret_overrun;
        bool locked, ret;
 
-       ret_overrun = hrtimer_forward_now(&du->vkms.timer,
-                                         du->vkms.period_ns);
-       if (ret_overrun != 1)
-               drm_dbg_driver(crtc->dev, "vblank timer missed %lld frames.\n",
-                              ret_overrun - 1);
-
        locked = vmw_vkms_vblank_trylock(crtc);
        ret = drm_crtc_handle_vblank(crtc);
        WARN_ON(!ret);
        if (!locked)
-               return HRTIMER_RESTART;
+               return true;
        has_surface = du->vkms.surface != NULL;
        vmw_vkms_unlock(crtc);
 
@@ -200,6 +192,27 @@ vmw_vkms_vblank_simulate(struct hrtimer *timer)
                        drm_dbg_driver(crtc->dev, "Composer worker already 
queued\n");
        }
 
+       return true;
+}
+
+static enum hrtimer_restart
+vmw_vkms_vblank_simulate(struct hrtimer *timer)
+{
+       struct vmw_display_unit *du = container_of(timer, struct 
vmw_display_unit, vkms.timer);
+       struct drm_crtc *crtc = &du->crtc;
+       u64 ret_overrun;
+       bool success;
+
+       ret_overrun = hrtimer_forward_now(&du->vkms.timer,
+                                         du->vkms.period_ns);
+       if (ret_overrun != 1)
+               drm_dbg_driver(crtc->dev, "vblank timer missed %lld frames.\n",
+                              ret_overrun - 1);
+
+       success = vmw_vkms_handle_vblank_timeout(crtc);
+       if (!success)
+               return HRTIMER_NORESTART;
+
        return HRTIMER_RESTART;
 }
 
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.h
index 69ddd33a8444..0b6bbf7c4487 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.h
@@ -45,6 +45,7 @@ bool vmw_vkms_modeset_lock_relaxed(struct drm_crtc *crtc);
 bool vmw_vkms_vblank_trylock(struct drm_crtc *crtc);
 void vmw_vkms_unlock(struct drm_crtc *crtc);
 
+bool vmw_vkms_handle_vblank_timeout(struct drm_crtc *crtc);
 bool vmw_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
                                   int *max_error,
                                   ktime_t *vblank_time,
-- 
2.53.0

Reply via email to