On Mon, Oct 08, 2012 at 02:50:39PM -0500, Rob Clark wrote:
> From: Rob Clark <rob at ti.com>
> 
> A helper that drivers can use to send vblank event after a pageflip.
> If the driver doesn't support proper vblank irq based time/seqn then
> just pass -1 for the pipe # to get do_gettimestamp() behavior (since
> there are a lot of drivers that don't use drm_vblank_count_and_time())
> 
> Also an internal send_vblank_event() helper for the various other code
> paths within drm_irq that also need to send vblank events.
> 
> Signed-off-by: Rob Clark <rob at ti.com>
> ---
>  drivers/gpu/drm/drm_irq.c |   65 
> +++++++++++++++++++++++++++++----------------
>  include/drm/drmP.h        |    2 ++
>  2 files changed, 44 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index 076c4a8..7a00d94 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -802,6 +802,43 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, 
> int crtc,
>  }
>  EXPORT_SYMBOL(drm_vblank_count_and_time);
>  
> +static void send_vblank_event(struct drm_pending_vblank_event *e,
> +             unsigned long seq, struct timeval *now)
> +{
> +     e->event.sequence = seq;
> +     e->event.tv_sec = now->tv_sec;
> +     e->event.tv_usec = now->tv_usec;
> +
> +     list_add_tail(&e->base.link,
> +                   &e->base.file_priv->event_list);
> +     wake_up_interruptible(&e->base.file_priv->event_wait);
> +     trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
> +                                      e->event.sequence);
> +}
> +
> +/**
> + * drm_send_vblank_event - helper to send vblank event after pageflip
> + * @dev: DRM device
> + * @crtc: CRTC in question
> + * @e: the event to send
> + *
> + * Updates sequence # and timestamp on event, and sends it to userspace.
> + */
> +void drm_send_vblank_event(struct drm_device *dev, int crtc,
> +             struct drm_pending_vblank_event *e)
> +{
> +     struct timeval now;
> +     unsigned int seq;
> +     if (crtc >= 0) {
> +             seq = drm_vblank_count_and_time(dev, crtc, &now);
> +     } else {
> +             seq = 0;
> +             do_gettimeofday(&now);
> +     }
> +     send_vblank_event(e, seq, &now);
> +}
> +EXPORT_SYMBOL(drm_send_vblank_event);
> +
>  /**
>   * drm_update_vblank_count - update the master vblank counter
>   * @dev: DRM device
> @@ -955,15 +992,9 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
>               DRM_DEBUG("Sending premature vblank event on disable: \
>                         wanted %d, current %d\n",
>                         e->event.sequence, seq);
> -
> -             e->event.sequence = seq;
> -             e->event.tv_sec = now.tv_sec;
> -             e->event.tv_usec = now.tv_usec;
> +             list_del(&e->base.link);
>               drm_vblank_put(dev, e->pipe);
> -             list_move_tail(&e->base.link, &e->base.file_priv->event_list);
> -             wake_up_interruptible(&e->base.file_priv->event_wait);
> -             trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
> -                                              e->event.sequence);
> +             send_vblank_event(e, seq, &now);
>       }
>  
>       spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
> @@ -1107,15 +1138,8 @@ static int drm_queue_vblank_event(struct drm_device 
> *dev, int pipe,
>  
>       e->event.sequence = vblwait->request.sequence;
>       if ((seq - vblwait->request.sequence) <= (1 << 23)) {
> -             e->event.sequence = seq;
> -             e->event.tv_sec = now.tv_sec;
> -             e->event.tv_usec = now.tv_usec;
>               drm_vblank_put(dev, pipe);
> -             list_add_tail(&e->base.link, &e->base.file_priv->event_list);
> -             wake_up_interruptible(&e->base.file_priv->event_wait);
> -             vblwait->reply.sequence = seq;

D?j? vu

http://lists.freedesktop.org/archives/dri-devel/2011-April/010693.html

:)

> -             trace_drm_vblank_event_delivered(current->pid, pipe,
> -                                              vblwait->request.sequence);
> +             send_vblank_event(e, seq, &now);
>       } else {
>               /* drm_handle_vblank_events will call drm_vblank_put */
>               list_add_tail(&e->base.link, &dev->vblank_event_list);
> @@ -1256,14 +1280,9 @@ static void drm_handle_vblank_events(struct drm_device 
> *dev, int crtc)
>               DRM_DEBUG("vblank event on %d, current %d\n",
>                         e->event.sequence, seq);
>  
> -             e->event.sequence = seq;
> -             e->event.tv_sec = now.tv_sec;
> -             e->event.tv_usec = now.tv_usec;
> +             list_del(&e->base.link);
>               drm_vblank_put(dev, e->pipe);
> -             list_move_tail(&e->base.link, &e->base.file_priv->event_list);
> -             wake_up_interruptible(&e->base.file_priv->event_wait);
> -             trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
> -                                              e->event.sequence);
> +             send_vblank_event(e, seq, &now);
>       }
>  
>       spin_unlock_irqrestore(&dev->event_lock, flags);
> diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> index 05af0e7..ee8f927 100644
> --- a/include/drm/drmP.h
> +++ b/include/drm/drmP.h
> @@ -1437,6 +1437,8 @@ extern int drm_vblank_wait(struct drm_device *dev, 
> unsigned int *vbl_seq);
>  extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
>  extern u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc,
>                                    struct timeval *vblanktime);
> +extern void drm_send_vblank_event(struct drm_device *dev, int crtc,
> +                                  struct drm_pending_vblank_event *e);
>  extern bool drm_handle_vblank(struct drm_device *dev, int crtc);
>  extern int drm_vblank_get(struct drm_device *dev, int crtc);
>  extern void drm_vblank_put(struct drm_device *dev, int crtc);
> -- 

Reply via email to