DRM_MODE_PLANE_EVENT is similar to DRM_MODE_PAGE_FLIP_EVENT but it is for a plane. The setplane ioctl (DRM_IOCTL_MODE_SETPLANE) needs to provide the event such as DRM_MODE_PAGE_FLIP_EVENT. The setplane ioctl can change the framebuffer of plane but user can't know completion of changing the framebuffer of plane via event. If DRM_MODE_PLANE_EVENT is added, we can also do pageflip of a plane. Signed-off-by: Joonyoung Shim <jy0922.shim@xxxxxxxxxxx> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> --- drivers/gpu/drm/drm_crtc.c | 45 ++++++++++++++++++++++++++++++++++++++++--- include/drm/drm.h | 1 + include/drm/drm_crtc.h | 3 +- include/drm/drm_mode.h | 3 ++ 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index d3aaeb6..4c4fa03 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1690,8 +1690,10 @@ int drm_mode_setplane(struct drm_device *dev, void *data, struct drm_plane *plane; struct drm_crtc *crtc; struct drm_framebuffer *fb; + struct drm_pending_vblank_event *e = NULL; int ret = 0; unsigned int fb_width, fb_height; + unsigned long flags; int i; if (!drm_core_check_feature(dev, DRIVER_MODESET)) @@ -1785,16 +1787,51 @@ int drm_mode_setplane(struct drm_device *dev, void *data, goto out; } + if (plane_req->flags & DRM_MODE_PLANE_EVENT) { + ret = -ENOMEM; + spin_lock_irqsave(&dev->event_lock, flags); + if (file_priv->event_space < sizeof e->event) { + spin_unlock_irqrestore(&dev->event_lock, flags); + goto out; + } + file_priv->event_space -= sizeof e->event; + spin_unlock_irqrestore(&dev->event_lock, flags); + + e = kzalloc(sizeof *e, GFP_KERNEL); + if (e == NULL) { + spin_lock_irqsave(&dev->event_lock, flags); + file_priv->event_space += sizeof e->event; + spin_unlock_irqrestore(&dev->event_lock, flags); + goto out; + } + + e->event.base.type = DRM_EVENT_SET_PLANE_COMPLETE; + e->event.base.length = sizeof e->event; + e->event.user_data = plane_req->user_data; + e->base.event = &e->event.base; + e->base.file_priv = file_priv; + e->base.destroy = (void (*) (struct drm_pending_event *)) kfree; + } + ret = plane->funcs->update_plane(plane, crtc, fb, plane_req->crtc_x, plane_req->crtc_y, plane_req->crtc_w, plane_req->crtc_h, plane_req->src_x, plane_req->src_y, - plane_req->src_w, plane_req->src_h); - if (!ret) { - plane->crtc = crtc; - plane->fb = fb; + plane_req->src_w, plane_req->src_h, + e); + if (ret) { + if (plane_req->flags & DRM_MODE_PLANE_EVENT) { + spin_lock_irqsave(&dev->event_lock, flags); + file_priv->event_space += sizeof e->event; + spin_unlock_irqrestore(&dev->event_lock, flags); + kfree(e); + } + goto out; } + plane->crtc = crtc; + plane->fb = fb; + out: mutex_unlock(&dev->mode_config.mutex); diff --git a/include/drm/drm.h b/include/drm/drm.h index 64ff02d..8e2d385 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -761,6 +761,7 @@ struct drm_event { #define DRM_EVENT_VBLANK 0x01 #define DRM_EVENT_FLIP_COMPLETE 0x02 +#define DRM_EVENT_SET_PLANE_COMPLETE 0x03 struct drm_event_vblank { struct drm_event base; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index e250eda..19fb9ea 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -602,7 +602,8 @@ struct drm_plane_funcs { int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h); + uint32_t src_w, uint32_t src_h, + struct drm_pending_vblank_event *event); int (*disable_plane)(struct drm_plane *plane); void (*destroy)(struct drm_plane *plane); }; diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index 4a0aae3..5ebdbdd 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -124,6 +124,7 @@ struct drm_mode_crtc { #define DRM_MODE_PRESENT_TOP_FIELD (1<<0) #define DRM_MODE_PRESENT_BOTTOM_FIELD (1<<1) +#define DRM_MODE_PLANE_EVENT (1<<2) /* Planes blend with or override other bits on the CRTC */ struct drm_mode_set_plane { @@ -139,6 +140,8 @@ struct drm_mode_set_plane { /* Source values are 16.16 fixed point */ __u32 src_x, src_y; __u32 src_h, src_w; + + __u64 user_data; }; struct drm_mode_get_plane { -- 1.7.5.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel