drm/i915: Fix pipe off timeout handling for pre-gen4
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 11 Oct 2013 11:21:31 +0000 (14:21 +0300)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 11 Oct 2013 21:22:25 +0000 (23:22 +0200)
The current pre-gen4 pipe off code might break out of the loop
due to the timeout, but then the fail to print the warning.

Refactor the code a bit to use wait_for() to avoid the problem,
and that we also re-check the condition after the timeout has
expired.

v2: Use wait_for()

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_display.c

index ebe5d0840a860c5ba0da0b633445f29f367ad6ca..502f000e252c061fa54419a7e40c7cbf847ec9c6 100644 (file)
@@ -800,6 +800,25 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
                DRM_DEBUG_KMS("vblank wait timed out\n");
 }
 
+static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 reg = PIPEDSL(pipe);
+       u32 line1, line2;
+       u32 line_mask;
+
+       if (IS_GEN2(dev))
+               line_mask = DSL_LINEMASK_GEN2;
+       else
+               line_mask = DSL_LINEMASK_GEN3;
+
+       line1 = I915_READ(reg) & line_mask;
+       mdelay(5);
+       line2 = I915_READ(reg) & line_mask;
+
+       return line1 == line2;
+}
+
 /*
  * intel_wait_for_pipe_off - wait for pipe to turn off
  * @dev: drm device
@@ -831,22 +850,8 @@ void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
                             100))
                        WARN(1, "pipe_off wait timed out\n");
        } else {
-               u32 last_line, line_mask;
-               int reg = PIPEDSL(pipe);
-               unsigned long timeout = jiffies + msecs_to_jiffies(100);
-
-               if (IS_GEN2(dev))
-                       line_mask = DSL_LINEMASK_GEN2;
-               else
-                       line_mask = DSL_LINEMASK_GEN3;
-
                /* Wait for the display line to settle */
-               do {
-                       last_line = I915_READ(reg) & line_mask;
-                       mdelay(5);
-               } while (((I915_READ(reg) & line_mask) != last_line) &&
-                        time_after(timeout, jiffies));
-               if (time_after(jiffies, timeout))
+               if (wait_for(pipe_dsl_stopped(dev, pipe), 100))
                        WARN(1, "pipe_off wait timed out\n");
        }
 }