summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorMario Kleiner <mario.kleiner@tuebingen.mpg.de>2010-12-08 04:07:19 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-12-16 21:02:24 +0000
commit0af7e4dff50454905092d468e91c1ef92e10e6b4 (patch)
tree6c1c9542720c6cf3b6de7a9ac6e8216ba55aebbc /drivers/gpu/drm/i915/intel_display.c
parentd8c58fabd75021cdd99abcd96513cb088d41092b (diff)
downloadlwn-0af7e4dff50454905092d468e91c1ef92e10e6b4.tar.gz
lwn-0af7e4dff50454905092d468e91c1ef92e10e6b4.zip
drm/i915: Add support for precise vblank timestamping (v2)
v2: Change IS_IRONLAKE to IS_GEN5 to adapt to 2.6.37 This patch adds new functions for use by the drm core: .get_vblank_timestamp() provides a precise timestamp for the end of the most recent (or current) vblank interval of a given crtc, as needed for the DRI2 implementation of the OML_sync_control extension. It is a thin wrapper around the drm function drm_calc_vbltimestamp_from_scanoutpos() which does almost all the work. .get_scanout_position() provides the current horizontal and vertical video scanout position and "in vblank" status of a given crtc, as needed by the drm for use by drm_calc_vbltimestamp_from_scanoutpos(). The patch modifies the pageflip completion routine to use these precise vblank timestamps as the timestamps for pageflip completion events. This code has been only tested on a HP-Mini Netbook with Atom processor and Intel 945GME gpu. The codepath for (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev)) gpu's has not been tested so far due to lack of hardware. Signed-off-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de> Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8645a974a499..0c201d684584 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5252,7 +5252,8 @@ static void intel_unpin_work_fn(struct work_struct *__work)
}
static void do_intel_finish_page_flip(struct drm_device *dev,
- struct drm_crtc *crtc)
+ struct drm_crtc *crtc,
+ int called_before_vblirq)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -5274,19 +5275,33 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
}
intel_crtc->unpin_work = NULL;
- drm_vblank_put(dev, intel_crtc->pipe);
if (work->event) {
e = work->event;
- do_gettimeofday(&now);
- e->event.sequence = drm_vblank_count(dev, intel_crtc->pipe);
+ e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &now);
+
+ /* Called before vblank count and timestamps have
+ * been updated for the vblank interval of flip
+ * completion? Need to increment vblank count and
+ * add one videorefresh duration to returned timestamp
+ * to account for this.
+ */
+ if (called_before_vblirq) {
+ e->event.sequence++;
+ now = ns_to_timeval(timeval_to_ns(&now) +
+ crtc->framedur_ns);
+ }
+
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);
}
+ drm_vblank_put(dev, intel_crtc->pipe);
+
spin_unlock_irqrestore(&dev->event_lock, flags);
obj = work->old_fb_obj;
@@ -5306,7 +5321,8 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
- do_intel_finish_page_flip(dev, crtc);
+ /* Called after drm_handle_vblank has run for finish vblank. */
+ do_intel_finish_page_flip(dev, crtc, 0);
}
void intel_finish_page_flip_plane(struct drm_device *dev, int plane)
@@ -5314,7 +5330,8 @@ void intel_finish_page_flip_plane(struct drm_device *dev, int plane)
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane];
- do_intel_finish_page_flip(dev, crtc);
+ /* Called before drm_handle_vblank has run for finish vblank. */
+ do_intel_finish_page_flip(dev, crtc, 1);
}
void intel_prepare_page_flip(struct drm_device *dev, int plane)