From b33b02707ba3eeccbf8e3687ab5c4124db6d3479 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 17 Mar 2017 20:20:30 +0000 Subject: [PATCH] drm: Peek at the current counter/timestamp for vblank queries MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Bypass all the spinlocks and return the last timestamp and counter from the last vblank if the driver delcares that it is accurate (and stable across on/off), and the vblank is currently enabled. This is dependent upon the both the hardware and driver to provide the proper barriers to facilitate reading our bookkeeping outside of the vblank interrupt and outside of the explicit vblank locks. Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: Daniel Vetter Cc: Michel Dänzer Cc: Laurent Pinchart Cc: Dave Airlie , Cc: Mario Kleiner Link: http://patchwork.freedesktop.org/patch/msgid/20170317202030.24410-4-chris@chris-wilson.co.uk Reviewed-by: Ville Syrjälä Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_irq.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 124402270568..aa23b9833588 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1561,6 +1561,17 @@ err_put: return ret; } +static bool drm_wait_vblank_is_query(union drm_wait_vblank *vblwait) +{ + if (vblwait->request.sequence) + return false; + + return _DRM_VBLANK_RELATIVE == + (vblwait->request.type & (_DRM_VBLANK_TYPES_MASK | + _DRM_VBLANK_EVENT | + _DRM_VBLANK_NEXTONMISS)); +} + /* * Wait for VBLANK. * @@ -1610,6 +1621,21 @@ int drm_wait_vblank(struct drm_device *dev, void *data, vblank = &dev->vblank[pipe]; + /* If the counter is currently enabled and accurate, short-circuit + * queries to return the cached timestamp of the last vblank. + */ + if (dev->vblank_disable_immediate && + drm_wait_vblank_is_query(vblwait) && + READ_ONCE(vblank->enabled)) { + struct timeval now; + + vblwait->reply.sequence = + drm_vblank_count_and_time(dev, pipe, &now); + vblwait->reply.tval_sec = now.tv_sec; + vblwait->reply.tval_usec = now.tv_usec; + return 0; + } + ret = drm_vblank_get(dev, pipe); if (ret) { DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", pipe, ret); -- 2.20.1