summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-10-03 10:56:11 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-10-03 10:56:11 +0100
commit58e10eb92d36a62568349d985c9140d9be16a99c (patch)
tree6ffaf65e64db390f6a28c1dca8c43d4eb1493f94 /drivers/gpu/drm/i915/intel_display.c
parent1cdf7fef793c715d8c4998575aba3741fa4a0b01 (diff)
parentab7ad7f6451580aa7eccc0ba62807c872088a8f9 (diff)
Merge branch 'drm-intel-fixes' into drm-intel-next
Conflicts: drivers/gpu/drm/i915/i915_gem_evict.c drivers/gpu/drm/i915/intel_display.c drivers/gpu/drm/i915/intel_dp.c
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c57
1 files changed, 35 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 00214c123ec..a2e8e15b8f5 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1017,8 +1017,8 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
DRM_DEBUG_KMS("vblank wait timed out\n");
}
-/**
- * intel_wait_for_vblank_off - wait for vblank after disabling a pipe
+/*
+ * intel_wait_for_pipe_off - wait for pipe to turn off
* @dev: drm device
* @pipe: pipe to wait for
*
@@ -1026,26 +1026,39 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
* spinning on the vblank interrupt status bit, since we won't actually
* see an interrupt when the pipe is disabled.
*
- * So this function waits for the display line value to settle (it
- * usually ends up stopping at the start of the next frame).
+ * On Gen4 and above:
+ * wait for the pipe register state bit to turn off
+ *
+ * Otherwise:
+ * wait for the display line value to settle (it usually
+ * ends up stopping at the start of the next frame).
+ *
*/
-void intel_wait_for_vblank_off(struct drm_device *dev, int pipe)
+void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL);
- unsigned long timeout = jiffies + msecs_to_jiffies(100);
- u32 last_line, line;
-
- /* Wait for the display line to settle */
- line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
- do {
- last_line = line;
- MSLEEP(5);
- line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
- } while (line != last_line && time_after(timeout, jiffies));
-
- if (line != last_line)
- DRM_DEBUG_KMS("vblank wait timed out\n");
+
+ if (INTEL_INFO(dev)->gen >= 4) {
+ int reg = PIPECONF(pipe);
+
+ /* Wait for the Pipe State to go off */
+ if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0,
+ 100))
+ DRM_DEBUG_KMS("pipe_off wait timed out\n");
+ } else {
+ u32 last_line;
+ int reg = PIPEDSL(pipe);
+ unsigned long timeout = jiffies + msecs_to_jiffies(100);
+
+ /* Wait for the display line to settle */
+ do {
+ last_line = I915_READ(reg) & DSL_LINEMASK;
+ mdelay(5);
+ } while (((I915_READ(reg) & DSL_LINEMASK) != last_line) &&
+ time_after(timeout, jiffies));
+ if (time_after(jiffies, timeout))
+ DRM_DEBUG_KMS("pipe_off wait timed out\n");
+ }
}
static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
@@ -2406,7 +2419,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
/* Wait for vblank for the disable to take effect */
if (IS_GEN2(dev))
- intel_wait_for_vblank_off(dev, pipe);
+ intel_wait_for_vblank(dev, pipe);
}
/* Don't disable pipe A or pipe A PLLs if needed */
@@ -2419,9 +2432,9 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
if (temp & PIPECONF_ENABLE) {
I915_WRITE(reg, temp & ~PIPECONF_ENABLE);
- /* Wait for vblank for the disable to take effect. */
+ /* Wait for the pipe to turn off */
POSTING_READ(reg);
- intel_wait_for_vblank_off(dev, pipe);
+ intel_wait_for_pipe_off(dev, pipe);
}
reg = DPLL(pipe);