dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Marcin Slusarz <marcin.slusarz@gmail.com>
To: Rob Clark <rob.clark@linaro.org>
Cc: patches@linaro.org, daniel.vetter@ffwll.ch,
	dri-devel@lists.freedesktop.org,
	laurent.pinchart@ideasonboard.com, gregkh@linuxfoundation.org,
	Rob Clark <rob@ti.com>,
	bskeggs@redhat.com
Subject: Re: [PATCH 01/11] drm: add drm_send_vblank_event() helper (v3)
Date: Fri, 12 Oct 2012 19:05:21 +0200	[thread overview]
Message-ID: <20121012170521.GA3121@joi.lan> (raw)
In-Reply-To: <1350001756-5460-1-git-send-email-rob.clark@linaro.org>

On Thu, Oct 11, 2012 at 07:29:15PM -0500, Rob Clark wrote:
> From: Rob Clark <rob@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.
> 
> v1: original
> v2: add back 'vblwait->reply.sequence = seq' which should not have
>     been deleted
> v3: add WARN_ON() in case lock is not held and comments
> 
> Signed-off-by: Rob Clark <rob@ti.com>
> ---
>  drivers/gpu/drm/drm_irq.c |   74 +++++++++++++++++++++++++++++++--------------
>  include/drm/drmP.h        |    2 ++
>  2 files changed, 54 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index 076c4a8..d623a06 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -802,6 +802,46 @@ 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_device *dev,
> +		struct drm_pending_vblank_event *e,
> +		unsigned long seq, struct timeval *now)
> +{
> +	WARN_ON(!spin_is_locked(&dev->event_lock));

This should be WARN_ON_SMP - on !SMP && !DEBUG_SPINLOCK spin_is_locked always returns 0.

> +	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.
> + * Caller must hold event lock.
> + */
> +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(dev, e, seq, &now);
> +}
> +EXPORT_SYMBOL(drm_send_vblank_event);
> +
>  /**
>   * drm_update_vblank_count - update the master vblank counter
>   * @dev: DRM device
> @@ -936,6 +976,13 @@ void drm_vblank_put(struct drm_device *dev, int crtc)
>  }
>  EXPORT_SYMBOL(drm_vblank_put);
>  
> +/**
> + * drm_vblank_off - disable vblank events on a CRTC
> + * @dev: DRM device
> + * @crtc: CRTC in question
> + *
> + * Caller must hold event lock.
> + */
>  void drm_vblank_off(struct drm_device *dev, int crtc)
>  {
>  	struct drm_pending_vblank_event *e, *t;
> @@ -955,15 +1002,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(dev, e, seq, &now);
>  	}
>  
>  	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
> @@ -1107,15 +1148,9 @@ 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);
> +		send_vblank_event(dev, e, seq, &now);
>  		vblwait->reply.sequence = seq;
> -		trace_drm_vblank_event_delivered(current->pid, pipe,
> -						 vblwait->request.sequence);
>  	} else {
>  		/* drm_handle_vblank_events will call drm_vblank_put */
>  		list_add_tail(&e->base.link, &dev->vblank_event_list);
> @@ -1256,14 +1291,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(dev, 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	other threads:[~2012-10-12 17:05 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-12  0:29 [PATCH 01/11] drm: add drm_send_vblank_event() helper (v3) Rob Clark
2012-10-12 17:05 ` Marcin Slusarz [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20121012170521.GA3121@joi.lan \
    --to=marcin.slusarz@gmail.com \
    --cc=bskeggs@redhat.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=patches@linaro.org \
    --cc=rob.clark@linaro.org \
    --cc=rob@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox