diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6eb3882..cdeebd5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1914,6 +1914,57 @@ 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; + u32 fw_bcl_self = 0; + + /* 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)); + fw_bcl_self = I915_READ(FW_BLC_SELF); + if (((cntl & CURSOR_MODE) == 0) && + ((fw_bcl_self & FW_BLC_SELF_EN) != 0)) { + I915_WRITE(FW_BLC_SELF, fw_bcl_self & ~FW_BLC_SELF_EN); + POSTING_READ(FW_BLC_SELF); + base = I915_READ(CURBASE(pipe)); + I915_WRITE(CURCNTR(pipe), CURSOR_MODE_64_ARGB_AX); + POSTING_READ(CURCNTR(pipe)); + 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); + I915_WRITE(FW_BLC_SELF, fw_bcl_self); + } +} + +/** * intel_disable_plane - disable a display plane * @dev_priv: i915 private structure * @plane: plane to disable @@ -3617,7 +3668,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 +6388,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);