diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 33ee515c9777..d80d95289e10 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -219,7 +219,7 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) for (i = 0; i < num_crtcs; i++) init_waitqueue_head(&dev->vblank[i].queue); - DRM_INFO("Supports vblank timestamp caching Rev 1 (10.10.2010).\n"); + DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n"); /* Driver specific high-precision vblank timestamping supported? */ if (dev->driver->get_vblank_timestamp) @@ -586,14 +586,17 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, * code gets preempted or delayed for some reason. */ for (i = 0; i < DRM_TIMESTAMP_MAXRETRIES; i++) { - /* Get system timestamp before query. */ - stime = ktime_get(); + /* + * Get vertical and horizontal scanout position vpos, hpos, + * and bounding timestamps stime, etime, pre/post query. + */ + vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, + &hpos, &stime, &etime); - /* Get vertical and horizontal scanout pos. vpos, hpos. */ - vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, &hpos); - - /* Get system timestamp after query. */ - etime = ktime_get(); + /* + * Get correction for CLOCK_MONOTONIC -> CLOCK_REALTIME if + * CLOCK_REALTIME is requested. + */ if (!drm_timestamp_monotonic) mono_time_offset = ktime_get_monotonic_offset(); @@ -604,6 +607,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, return -EIO; } + /* Compute uncertainty in timestamp of scanout position query. */ duration_ns = ktime_to_ns(etime) - ktime_to_ns(stime); /* Accept result with < max_error nsecs timing uncertainty. */ diff --git a/include/drm/drmP.h b/include/drm/drmP.h index e6d0cd9f518e..748c72907829 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -836,12 +836,17 @@ struct drm_driver { /** * Called by vblank timestamping code. * - * Return the current display scanout position from a crtc. + * Return the current display scanout position from a crtc, and an + * optional accurate ktime_get timestamp of when position was measured. * * \param dev DRM device. * \param crtc Id of the crtc to query. * \param *vpos Target location for current vertical scanout position. * \param *hpos Target location for current horizontal scanout position. + * \param *stime Target location for timestamp taken immediately before + * scanout position query. Can be NULL to skip timestamp. + * \param *etime Target location for timestamp taken immediately after + * scanout position query. Can be NULL to skip timestamp. * * Returns vpos as a positive number while in active scanout area. * Returns vpos as a negative number inside vblank, counting the number @@ -858,7 +863,8 @@ struct drm_driver { * */ int (*get_scanout_position) (struct drm_device *dev, int crtc, - int *vpos, int *hpos); + int *vpos, int *hpos, ktime_t *stime, + ktime_t *etime); /** * Called by \c drm_get_last_vbltimestamp. Should return a precise