aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-03-17 16:20:30 -0400
committerVille Syrjälä <ville.syrjala@linux.intel.com>2017-03-29 07:02:22 -0400
commitb33b02707ba3eeccbf8e3687ab5c4124db6d3479 (patch)
tree37dcc14d876462e12ebc7e5f5d0d8576ef888d2a
parent9a4d9babceeabb86669ff280e94c560193e66a72 (diff)
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: Chris 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.uk Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
-rw-r--r--drivers/gpu/drm/drm_irq.c26
1 files changed, 26 insertions, 0 deletions
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:
1561 return ret; 1561 return ret;
1562} 1562}
1563 1563
1564static bool drm_wait_vblank_is_query(union drm_wait_vblank *vblwait)
1565{
1566 if (vblwait->request.sequence)
1567 return false;
1568
1569 return _DRM_VBLANK_RELATIVE ==
1570 (vblwait->request.type & (_DRM_VBLANK_TYPES_MASK |
1571 _DRM_VBLANK_EVENT |
1572 _DRM_VBLANK_NEXTONMISS));
1573}
1574
1564/* 1575/*
1565 * Wait for VBLANK. 1576 * Wait for VBLANK.
1566 * 1577 *
@@ -1610,6 +1621,21 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
1610 1621
1611 vblank = &dev->vblank[pipe]; 1622 vblank = &dev->vblank[pipe];
1612 1623
1624 /* If the counter is currently enabled and accurate, short-circuit
1625 * queries to return the cached timestamp of the last vblank.
1626 */
1627 if (dev->vblank_disable_immediate &&
1628 drm_wait_vblank_is_query(vblwait) &&
1629 READ_ONCE(vblank->enabled)) {
1630 struct timeval now;
1631
1632 vblwait->reply.sequence =
1633 drm_vblank_count_and_time(dev, pipe, &now);
1634 vblwait->reply.tval_sec = now.tv_sec;
1635 vblwait->reply.tval_usec = now.tv_usec;
1636 return 0;
1637 }
1638
1613 ret = drm_vblank_get(dev, pipe); 1639 ret = drm_vblank_get(dev, pipe);
1614 if (ret) { 1640 if (ret) {
1615 DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", pipe, ret); 1641 DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", pipe, ret);