* [PATCH 01/11] drm: add drm_send_vblank_event() helper (v3)
@ 2012-10-12 0:29 Rob Clark
2012-10-12 17:05 ` Marcin Slusarz
0 siblings, 1 reply; 2+ messages in thread
From: Rob Clark @ 2012-10-12 0:29 UTC (permalink / raw)
To: dri-devel
Cc: patches, daniel.vetter, laurent.pinchart, gregkh, Rob Clark,
bskeggs
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));
+ 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);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH 01/11] drm: add drm_send_vblank_event() helper (v3)
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
0 siblings, 0 replies; 2+ messages in thread
From: Marcin Slusarz @ 2012-10-12 17:05 UTC (permalink / raw)
To: Rob Clark
Cc: patches, daniel.vetter, dri-devel, laurent.pinchart, gregkh,
Rob Clark, bskeggs
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);
> --
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2012-10-12 17:05 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox