From 2f8f5b49a3244de8fd33278799f905d3b09e38b9 Mon Sep 17 00:00:00 2001 From: Egbert Eich Date: Mon, 25 Feb 2013 12:45:10 -0500 Subject: [PATCH] DRM/i915: On G45 enable cursor plane before enabling display plane. On G45 some low res modes (800x600 and 1024x768) produce a blank screen when the display plane is enabled with with cursor plane off. To work around this issue this patch enables the cursor plane if it is not already enabled before enabing the display plane. Once the plane is enabled the cursor plane is disabled again. This workaround is very ugly - mostly because it contains an experimentally determined, not understood delay delay before restoring the cursor plane register. Without this delay the problem will occasionally reoccur. Signed-off-by: Egbert Eich --- drivers/gpu/drm/i915/intel_display.c | 48 ++++++++++++++++++++++++++++++++- 1 files changed, 46 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6eb3882..ece535e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1914,6 +1914,50 @@ static void intel_enable_plane(struct drm_i915_private *dev_priv, } /** + * i9xx_enable_plane - like intel_enable_plane(). It however has some + * ugly workaround for G45 to fire up the hardware cursor plane if + * it is not already running before enabling the display plane and + * restore it afterwards. + */ +void +i9xx_enable_plane(struct drm_device *dev, enum plane plane, enum pipe pipe) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int reg; + u32 val; + u32 cntl = 0, base = 0; + bool set_cursor_enable = false; + + /* If the pipe isn't enabled, we can't pump pixels and may hang */ + assert_pipe_enabled(dev_priv, pipe); + + reg = DSPCNTR(plane); + val = I915_READ(reg); + if (val & DISPLAY_PLANE_ENABLE) + return; + + if (IS_G4X(dev)) { + cntl = I915_READ(CURCNTR(pipe)); + if ((cntl & CURSOR_MODE) == 0) { + base = I915_READ(CURBASE(pipe)); + I915_WRITE(CURCNTR(pipe), CURSOR_MODE_64_ARGB_AX); + set_cursor_enable = true; + } + } + + I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE); + intel_flush_display_plane(dev_priv, plane); + intel_wait_for_vblank(dev_priv->dev, pipe); + + if (set_cursor_enable) { + intel_wait_for_vblank(dev, pipe); + mdelay(9); + I915_WRITE(CURCNTR(pipe), cntl); + I915_WRITE(CURBASE(pipe), base); + } +} + +/** * intel_disable_plane - disable a display plane * @dev_priv: i915 private structure * @plane: plane to disable @@ -3617,7 +3661,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) encoder->pre_enable(encoder); intel_enable_pipe(dev_priv, pipe, false); - intel_enable_plane(dev_priv, plane, pipe); + i9xx_enable_plane(dev, plane, pipe); intel_crtc_load_lut(crtc); intel_update_fbc(dev); @@ -6337,7 +6381,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); } else i915_gem_object_unpin(intel_crtc->cursor_bo); - drm_gem_object_unreference(&intel_crtc->cursor_bo->base); + drm_gem_object_unreference(&intel_crtc->cursor_bo->base); } mutex_unlock(&dev->struct_mutex); -- 1.7.7