On Wed, Apr 18, 2012 at 01:31:59PM +0900, Joonyoung Shim wrote: > 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> If I understand the current kms api correctly, set_plane is akin to set_base and should not generate an asynchronous flip completion event. To do that we need a new pageflip ioctl which changes a complete set of fb + planes + any crtc attributes that might be in an atomic fashion. At which point we can just reuse the existing page flip event mechanism. Yours, Daniel > --- > 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 -- Daniel Vetter Mail: daniel@xxxxxxxx Mobile: +41 (0)79 365 57 48 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel