diff options
author | Dave Airlie <airlied@redhat.com> | 2013-03-07 05:12:14 +0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-03-07 05:12:14 +0400 |
commit | 2cc79544bd0aabb4b3cf467ead5df526d9134c64 (patch) | |
tree | 1cecfe645494883b5bb86ca500873626f1697e04 /drivers/gpu/drm/i915/intel_display.c | |
parent | 64e38a8c8d6882e321eb7a9959321a85d16a05aa (diff) | |
parent | f40ebd6bcbbd0d30591f42dc16be52b5086a366b (diff) | |
download | linux-2cc79544bd0aabb4b3cf467ead5df526d9134c64.tar.xz |
Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel into drm-next
A bunch of fixes, nothing truely horrible:
- Fix PCH irq handling race which resulted in missed gmbus/dp aux irqs
and subsequent fallout (Paulo)
- Fixup off-by-one in our hsw id table (Kenneth)
- Fixup ilk rc6 support (disabled by default), regression introduced in
3.8
- g4x plane w/a from Egbert Eich
- gen2/3/4 dpms suspend/standy fixes for VGA outputs from Patrik Jakobsson
- Workaround dying ivb machines with less aggressive rc6 values (Stéphane
Marchesin)
* 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel:
drm/i915: Turn off hsync and vsync on ADPA when disabling crt
drm/i915: Fix incorrect definition of ADPA HSYNC and VSYNC bits
drm/i915: also disable south interrupts when handling them
drm/i915: enable irqs earlier when resuming
drm/i915: Increase the RC6p threshold.
DRM/i915: On G45 enable cursor plane briefly after enabling the display plane.
drm/i915: Fix Haswell/CRW PCI IDs.
drm/i915: Don't clobber crtc->fb when queue_flip fails
drm/i915: wait_event_timeout's timeout is in jiffies
drm/i915: Fix missing variable initilization
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a05ac2c91ba2..287b42c9d1a8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3604,6 +3604,30 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) */ } +/** + * i9xx_fixup_plane - ugly workaround for G45 to fire up the hardware + * cursor plane briefly if not already running after enabling the display + * plane. + * This workaround avoids occasional blank screens when self refresh is + * enabled. + */ +static void +g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe) +{ + u32 cntl = I915_READ(CURCNTR(pipe)); + + if ((cntl & CURSOR_MODE) == 0) { + u32 fw_bcl_self = I915_READ(FW_BLC_SELF); + + I915_WRITE(FW_BLC_SELF, fw_bcl_self & ~FW_BLC_SELF_EN); + I915_WRITE(CURCNTR(pipe), CURSOR_MODE_64_ARGB_AX); + intel_wait_for_vblank(dev_priv->dev, pipe); + I915_WRITE(CURCNTR(pipe), cntl); + I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe))); + I915_WRITE(FW_BLC_SELF, fw_bcl_self); + } +} + static void i9xx_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -3629,6 +3653,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) intel_enable_pipe(dev_priv, pipe, false); intel_enable_plane(dev_priv, plane, pipe); + if (IS_G4X(dev)) + g4x_fixup_plane(dev_priv, pipe); intel_crtc_load_lut(crtc); intel_update_fbc(dev); @@ -7256,8 +7282,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_framebuffer *intel_fb; - struct drm_i915_gem_object *obj; + struct drm_framebuffer *old_fb = crtc->fb; + struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_unpin_work *work; unsigned long flags; @@ -7282,8 +7308,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work->event = event; work->crtc = crtc; - intel_fb = to_intel_framebuffer(crtc->fb); - work->old_fb_obj = intel_fb->obj; + work->old_fb_obj = to_intel_framebuffer(old_fb)->obj; INIT_WORK(&work->work, intel_unpin_work_fn); ret = drm_vblank_get(dev, intel_crtc->pipe); @@ -7303,9 +7328,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, intel_crtc->unpin_work = work; spin_unlock_irqrestore(&dev->event_lock, flags); - intel_fb = to_intel_framebuffer(fb); - obj = intel_fb->obj; - if (atomic_read(&intel_crtc->unpin_work_count) >= 2) flush_workqueue(dev_priv->wq); @@ -7340,6 +7362,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, cleanup_pending: atomic_dec(&intel_crtc->unpin_work_count); + crtc->fb = old_fb; drm_gem_object_unreference(&work->old_fb_obj->base); drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); |