[RFC PATCH] drm: Add plane event
Joonyoung Shim
jy0922.shim at samsung.com
Tue Apr 17 21:31:59 PDT 2012
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 at samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
---
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
More information about the dri-devel
mailing list