From 83963f689f6d6ed622508de73964bd9cb7c1fc12 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 12 Jan 2011 20:22:10 +0000 Subject: [PATCH] drm/i915: Disable SSC for outputs other than LVDS or DP For CRT and SDVO/HDMI, we need to use a normal, non-SSC, clock and so we must clear any enabling bits left-over from earlier outputs. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_display.c | 57 +++++++++++++++++++--------------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 40a407f..7683916 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2898,6 +2898,7 @@ #define DREF_NONSPREAD_SOURCE_MASK (3<<9) #define DREF_SUPERSPREAD_SOURCE_DISABLE (0<<7) #define DREF_SUPERSPREAD_SOURCE_ENABLE (2<<7) +#define DREF_SUPERSPREAD_SOURCE_MASK (3<<7) #define DREF_SSC4_DOWNSPREAD (0<<6) #define DREF_SSC4_CENTERSPREAD (1<<6) #define DREF_SSC1_DISABLE (0<<1) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 98967f3..c33d620 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4052,44 +4052,51 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, * ignoring this setting. */ if (HAS_PCH_SPLIT(dev)) { + /*XXX BIOS treats 16:31 as a mask for 0:15 */ + temp = I915_READ(PCH_DREF_CONTROL); - /* Always enable nonspread source */ + + /* First clear the current state for output switching */ + temp &= ~DREF_SSC1_ENABLE; + temp &= ~DREF_SSC4_ENABLE; + temp &= ~DREF_SUPERSPREAD_SOURCE_MASK; temp &= ~DREF_NONSPREAD_SOURCE_MASK; - temp |= DREF_NONSPREAD_SOURCE_ENABLE; temp &= ~DREF_SSC_SOURCE_MASK; - temp |= DREF_SSC_SOURCE_ENABLE; + temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; I915_WRITE(PCH_DREF_CONTROL, temp); POSTING_READ(PCH_DREF_CONTROL); udelay(200); - if (has_edp_encoder) { - if (intel_panel_use_ssc(dev_priv)) { - temp |= DREF_SSC1_ENABLE; - I915_WRITE(PCH_DREF_CONTROL, temp); - - POSTING_READ(PCH_DREF_CONTROL); - udelay(200); - } - temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; - - /* Enable CPU source on CPU attached eDP */ - if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - if (intel_panel_use_ssc(dev_priv)) + if ((is_lvds || has_edp_encoder) && + intel_panel_use_ssc(dev_priv)) { + temp |= DREF_SSC1_ENABLE; + temp |= DREF_SSC_SOURCE_ENABLE; + if (has_edp_encoder) { + if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { + /* Enable CPU source on CPU attached eDP */ temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; - else - temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; - } else { - /* Enable SSC on PCH eDP if needed */ - if (intel_panel_use_ssc(dev_priv)) { - DRM_ERROR("enabling SSC on PCH\n"); + } else { + /* Enable SSC on PCH eDP if needed */ temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; } + I915_WRITE(PCH_DREF_CONTROL, temp); } - I915_WRITE(PCH_DREF_CONTROL, temp); - POSTING_READ(PCH_DREF_CONTROL); - udelay(200); + } else { + bool BTM_mode = true; + + if (BTM_mode) + temp |= DREF_NONSPREAD_CK505_ENABLE; + else + temp |= DREF_NONSPREAD_SOURCE_ENABLE; + if (has_edp_encoder && + !intel_encoder_is_pch_edp(&has_edp_encoder->base)) + temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; } + + I915_WRITE(PCH_DREF_CONTROL, temp); + POSTING_READ(PCH_DREF_CONTROL); + udelay(200); } if (IS_PINEVIEW(dev)) { -- 1.7.2.3