From 6ec2ca0aa7ae61be38aa2b5e743290b0ade966f2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 22 Sep 2011 12:01:57 -0700 Subject: [PATCH] --- yaml --- r: 269811 b: refs/heads/master c: 199e5d79f1c988a8039fa75b736a3adcdda56abc h: refs/heads/master i: 269809: 18269f31fe4e2ec79471b7b11e985fa3841c4ea6 269807: 8b2990e7b236fc38287d7b759714c8169328ee3a v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/i915/intel_display.c | 96 +++++++++++++--------- 2 files changed, 60 insertions(+), 38 deletions(-) diff --git a/[refs] b/[refs] index f65852102e25..14122f56bde3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 72bbe58cd9568c7766cc219a779ea68a02132797 +refs/heads/master: 199e5d79f1c988a8039fa75b736a3adcdda56abc diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 603949622104..f99993577168 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -5113,31 +5113,32 @@ static void ironlake_update_pch_refclk(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_crtc *crtc; struct intel_encoder *encoder; - struct intel_encoder *has_edp_encoder = NULL; u32 temp; bool has_lvds = false; + bool has_cpu_edp = false; + bool has_pch_edp = false; + bool has_panel = false; /* We need to take the global config into account */ - list_for_each_entry(crtc, &mode_config->crtc_list, head) { - if (!crtc->enabled) - continue; - - list_for_each_entry(encoder, &mode_config->encoder_list, - base.head) { - if (encoder->base.crtc != crtc) - continue; - - switch (encoder->type) { - case INTEL_OUTPUT_LVDS: - has_lvds = true; - case INTEL_OUTPUT_EDP: - has_edp_encoder = encoder; - break; - } + list_for_each_entry(encoder, &mode_config->encoder_list, + base.head) { + switch (encoder->type) { + case INTEL_OUTPUT_LVDS: + has_panel = true; + has_lvds = true; + break; + case INTEL_OUTPUT_EDP: + has_panel = true; + if (intel_encoder_is_pch_edp(&encoder->base)) + has_pch_edp = true; + else + has_cpu_edp = true; + break; } } + DRM_DEBUG_KMS("has_panel %d has_lvds %d has_pch_edp %d has_cpu_edp %d\n", + has_panel, has_lvds, has_pch_edp, has_cpu_edp); /* Ironlake: try to setup display ref clock before DPLL * enabling. This is only under driver's control after @@ -5148,36 +5149,57 @@ static void ironlake_update_pch_refclk(struct drm_device *dev) /* Always enable nonspread source */ temp &= ~DREF_NONSPREAD_SOURCE_MASK; temp |= DREF_NONSPREAD_SOURCE_ENABLE; - temp &= ~DREF_SSC_SOURCE_MASK; - temp |= DREF_SSC_SOURCE_ENABLE; - I915_WRITE(PCH_DREF_CONTROL, temp); - POSTING_READ(PCH_DREF_CONTROL); - udelay(200); + if (has_panel) { + temp &= ~DREF_SSC_SOURCE_MASK; + temp |= DREF_SSC_SOURCE_ENABLE; - if (has_edp_encoder) { + /* SSC must be turned on before enabling the CPU output */ if (intel_panel_use_ssc(dev_priv)) { + DRM_DEBUG_KMS("Using SSC on panel\n"); temp |= DREF_SSC1_ENABLE; - I915_WRITE(PCH_DREF_CONTROL, temp); - - POSTING_READ(PCH_DREF_CONTROL); - udelay(200); } + + /* Get SSC going before enabling the outputs */ + 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 (has_cpu_edp) { + if (intel_panel_use_ssc(dev_priv)) { + DRM_DEBUG_KMS("Using SSC on eDP\n"); 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"); - temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; - } - } + } else + temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; + + I915_WRITE(PCH_DREF_CONTROL, temp); + POSTING_READ(PCH_DREF_CONTROL); + udelay(200); + } else { + DRM_DEBUG_KMS("Disabling SSC entirely\n"); + + temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; + + /* Turn off CPU output */ + temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; + + I915_WRITE(PCH_DREF_CONTROL, temp); + POSTING_READ(PCH_DREF_CONTROL); + udelay(200); + + /* Turn off the SSC source */ + temp &= ~DREF_SSC_SOURCE_MASK; + temp |= DREF_SSC_SOURCE_DISABLE; + + /* Turn off SSC1 */ + temp &= ~ DREF_SSC1_ENABLE; + I915_WRITE(PCH_DREF_CONTROL, temp); POSTING_READ(PCH_DREF_CONTROL); udelay(200);