From d0f2bf61579c1a0a1fc285f13cd113163bf876d0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 24 Jan 2011 10:20:16 +0100 Subject: [PATCH 1/2] drm/i915: Fix DPMS setups at resume The patch From 032d2a0d068b0368296a56469761394ef03207c3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 6 Sep 2010 16:17:22 +0100 Subject: drm/i915: Prevent double dpms on in 2.6.32.22 stable queue causes a regression in S4 resume on PineView machines. It's because DPMS isn't reset properly in the power transition. This band-aid patch fixes the DPMS setup by introducing is_resume flag so that dpms-callbacks can forcibly set the state at resume. Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/i915_drv.c | 2 ++ drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_display.c | 17 ++++++++++++----- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f737960..317bb8f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -304,6 +304,8 @@ static int i915_drm_thaw(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; int error = 0; + dev_priv->resume_count++; + i915_restore_state(dev); intel_opregion_setup(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 409826d..8582af3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -707,6 +707,8 @@ typedef struct drm_i915_private { /* list of fbdev register on this device */ struct intel_fbdev *fbdev; + + int resume_count; } drm_i915_private_t; /** driver private structure attached to each drm_gem_object */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fca5232..63bc904 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2032,7 +2032,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) int plane = intel_crtc->plane; u32 reg, temp; - if (intel_crtc->active) + if (intel_crtc->active && + intel_crtc->resume_count == dev_priv->resume_count) return; intel_crtc->active = true; @@ -2177,7 +2178,8 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) int plane = intel_crtc->plane; u32 reg, temp; - if (!intel_crtc->active) + if (!intel_crtc->active && + intel_crtc->resume_count == dev_priv->resume_count) return; intel_crtc_wait_for_pending_flips(crtc); @@ -2370,7 +2372,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) int plane = intel_crtc->plane; u32 reg, temp; - if (intel_crtc->active) + if (intel_crtc->active && + intel_crtc->resume_count == dev_priv->resume_count) return; intel_crtc->active = true; @@ -2430,7 +2433,8 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) int plane = intel_crtc->plane; u32 reg, temp; - if (!intel_crtc->active) + if (!intel_crtc->active && + intel_crtc->resume_count == dev_priv->resume_count) return; /* Give the overlay scaler a chance to disable if it's on this pipe */ @@ -2517,13 +2521,15 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) int pipe = intel_crtc->pipe; bool enabled; - if (intel_crtc->dpms_mode == mode) + if (intel_crtc->dpms_mode == mode && + intel_crtc->resume_count == dev_priv->resume_count) return; intel_crtc->dpms_mode = mode; dev_priv->display.dpms(crtc, mode); + intel_crtc->resume_count = dev_priv->resume_count; if (!dev->primary->master) return; @@ -5318,6 +5324,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) intel_crtc->cursor_addr = 0; intel_crtc->dpms_mode = -1; intel_crtc->active = true; /* force the pipe off on setup_init_config */ + intel_crtc->resume_count = dev_priv->resume_count; if (HAS_PCH_SPLIT(dev)) { intel_helper_funcs.prepare = ironlake_crtc_prepare; -- 1.7.3.4