drm/i915: Wait for pipe to start before sampling vblank timestamps on gen2
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 14 Dec 2015 16:23:43 +0000 (18:23 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 12 Jan 2016 14:10:57 +0000 (16:10 +0200)
We use the vblank timestamps to generate the vblank frame counter value
on gen2. That means we need the pipe scanout position to be accurate
when we call drm_crtc_vblank_on(), otherwise the frame counter
guesstimate may jump when the pipe actually start.

What I observed on my 85x is that the DSL initially reads 0, and when
the pipe actually starts DSL jumps to vblank_start. On gen2 DSL==0 means
actually vtotal-1 (see update_scanline_offset()), so if we initially
get vtotal-1, and then very quickly vblank_start (or thereabouts), the
scanout position will appear to jump backwards by approximately one
vblank length. Which means the frame counter guesstimate will also
jump backwards. That's no good, so let's make sure the pipe has
started before we call drm_crtc_vblank_on().

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1450110229-30450-5-git-send-email-ville.syrjala@linux.intel.com
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_display.c

index 20e99a0c553662f4497edfa536cb8e690ddf06bf..9c87d5784f1a8b4bb66a7568fdf79a03db0f0625 100644 (file)
@@ -2151,6 +2151,17 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
 
        I915_WRITE(reg, val | PIPECONF_ENABLE);
        POSTING_READ(reg);
+
+       /*
+        * Until the pipe starts DSL will read as 0, which would cause
+        * an apparent vblank timestamp jump, which messes up also the
+        * frame count when it's derived from the timestamps. So let's
+        * wait for the pipe to start properly before we call
+        * drm_crtc_vblank_on()
+        */
+       if (dev->max_vblank_count == 0 &&
+           wait_for(intel_get_crtc_scanline(crtc) != crtc->scanline_offset, 50))
+               DRM_ERROR("pipe %c didn't start\n", pipe_name(pipe));
 }
 
 /**