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
