Add DRM_VBLANK_FLAG_SIMULATED for CRTCs that do not have a hardware
vblank interrupt. Setting the flag tells DRM to not report vblank
capabilities from the WAIT_VBLANK ioctl.

DRM_IOCTL_WAIT_VBLANK queries timestamps from a vblank event or waits
for the next vblank event to occur. DRM clients use this functionality
to synchronize their output with the display's vblank phase. Hence this
is only supported for hardware implementations.

Software implementations are not synchronized to the display and merely
act as a rate limiter for page-flip events. The WAIT_VBLANK ioctl thus
should fail with an error.

v2:
- add filter in CRTC_GET_SEQUENCE and CRTC_QUEUE_SEQUENCE ioctls (Michel)

Suggested-by: Simona Vetter <[email protected]>
Signed-off-by: Thomas Zimmermann <[email protected]>
---
 drivers/gpu/drm/drm_vblank.c | 10 ++++++++++
 include/drm/drm_vblank.h     |  5 +++++
 2 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 21ca91b4c014..3ef4ed08e7f6 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1794,6 +1794,9 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void 
*data,
 
        vblank = drm_vblank_crtc(dev, pipe);
 
+       if (vblank->flags & DRM_VBLANK_FLAG_SIMULATED)
+               return -EOPNOTSUPP;
+
        /* If the counter is currently enabled and accurate, short-circuit
         * queries to return the cached timestamp of the last vblank.
         */
@@ -2035,6 +2038,10 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, 
void *data,
        pipe = drm_crtc_index(crtc);
 
        vblank = drm_crtc_vblank_crtc(crtc);
+
+       if (vblank->flags & DRM_VBLANK_FLAG_SIMULATED)
+               return -EOPNOTSUPP;
+
        vblank_enabled = READ_ONCE(vblank->config.disable_immediate) &&
                READ_ONCE(vblank->enabled);
 
@@ -2102,6 +2109,9 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, 
void *data,
 
        vblank = drm_crtc_vblank_crtc(crtc);
 
+       if (vblank->flags & DRM_VBLANK_FLAG_SIMULATED)
+               return -EOPNOTSUPP;
+
        e = kzalloc_obj(*e);
        if (e == NULL)
                return -ENOMEM;
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index 39a201b83781..03fa7259b6ac 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -37,6 +37,11 @@ struct drm_device;
 struct drm_crtc;
 struct drm_vblank_work;
 
+/**
+ * DRM_VBLANK_FLAG_SIMULATED - vblank uses a software timer
+ */
+#define DRM_VBLANK_FLAG_SIMULATED      BIT(1)
+
 /**
  * struct drm_pending_vblank_event - pending vblank event tracking
  */
-- 
2.54.0

Reply via email to