Commit b33b0270 authored by Chris Wilson's avatar Chris Wilson Committed by Ville Syrjälä

drm: Peek at the current counter/timestamp for vblank queries

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: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Michel Dänzer <michel@daenzer.net>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Dave Airlie <airlied@redhat.com>,
Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170317202030.24410-4-chris@chris-wilson.co.ukReviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
parent 9a4d9bab
...@@ -1561,6 +1561,17 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, ...@@ -1561,6 +1561,17 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
return ret; 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. * Wait for VBLANK.
* *
...@@ -1610,6 +1621,21 @@ int drm_wait_vblank(struct drm_device *dev, void *data, ...@@ -1610,6 +1621,21 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
vblank = &dev->vblank[pipe]; 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); ret = drm_vblank_get(dev, pipe);
if (ret) { if (ret) {
DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", pipe, ret); DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", pipe, ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment