drm: Pass CRTC ID in userspace vblank events
authorAo Xu <ao.xu@amlogic.com>
Mon, 29 Jul 2019 08:35:36 +0000 (16:35 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Mon, 29 Jul 2019 10:46:57 +0000 (03:46 -0700)
PD#SWPL-4863

With the atomic API, it is possible that a single commit affects
multiple crtcs. If the user requests an event with that commit, one
event will be sent for each CRTC, but it is not possible to distinguish
which crtc an event is for in user space. To solve this, the reserved
field in struct drm_vblank_event is repurposed to include the crtc_id
which the event is for.

The DRM_CAP_CRTC_IN_VBLANK_EVENT is added to allow userspace to query if
the crtc field will be set properly.

[daniels: Rebased, using Maarten's forward-port.]

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Signed-off-by: Daniel Stone <daniels@collabora.com>
Cc: Maarten Lankhorst <maarten.lankhorst@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170404165221.28240-2-daniels@collabora.com
Change-Id: Ide7657bdc38563d2de91edc2d649b53262002c39
Signed-off-by: Ao Xu <ao.xu@amlogic.com>
drivers/gpu/drm/drm_ioctl.c
drivers/gpu/drm/drm_irq.c
include/uapi/drm/drm.h

index 71c3473476c7498721a8524c2b8fbde18bf22d7b..649ff759cbfd73bcb99b6bcafd16c877a75be148 100644 (file)
@@ -277,6 +277,9 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_
        case DRM_CAP_ADDFB2_MODIFIERS:
                req->value = dev->mode_config.allow_fb_modifiers;
                break;
+       case DRM_CAP_CRTC_IN_VBLANK_EVENT:
+               req->value = 1;
+               break;
        default:
                return -EINVAL;
        }
index 00c815a7c414f320c457e57ca4ac0041612490fe..28536aa0a87554a07c63db35bcff5729ece696b4 100644 (file)
@@ -1048,6 +1048,7 @@ void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
 
        e->pipe = pipe;
        e->event.sequence = drm_vblank_count(dev, pipe);
+       e->event.crtc_id = crtc->base.id;
        list_add_tail(&e->base.link, &dev->vblank_event_list);
 }
 EXPORT_SYMBOL(drm_crtc_arm_vblank_event);
@@ -1078,6 +1079,7 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
                now = get_drm_timestamp();
        }
        e->pipe = pipe;
+       e->event.crtc_id = crtc->base.id;
        send_vblank_event(dev, e, seq, &now);
 }
 EXPORT_SYMBOL(drm_crtc_send_vblank_event);
index b2c52843bc7025b97d6e35961379a29ea29e5d33..42d9f64ce416c18cac72bfff15c9e7384e416567 100644 (file)
@@ -647,6 +647,7 @@ struct drm_gem_open {
 #define DRM_CAP_CURSOR_HEIGHT          0x9
 #define DRM_CAP_ADDFB2_MODIFIERS       0x10
 #define DRM_CAP_PAGE_FLIP_TARGET       0x11
+#define DRM_CAP_CRTC_IN_VBLANK_EVENT   0x12
 
 /** DRM_IOCTL_GET_CAP ioctl argument type */
 struct drm_get_cap {
@@ -851,7 +852,7 @@ struct drm_event_vblank {
        __u32 tv_sec;
        __u32 tv_usec;
        __u32 sequence;
-       __u32 reserved;
+       __u32 crtc_id; /* 0 on older kernels that do not support this */
 };
 
 /* typedef area */