aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-01-19 08:29:42 -0500
committerChris Wilson <chris@chris-wilson.co.uk>2011-01-19 08:33:27 -0500
commit633f2ea26665d37bb3c8ae30799aa14988622653 (patch)
treee06f4aef5cec14ce6afa144d454872c446a3520a /drivers/gpu/drm
parent9a4114ffa7b6f5f4635e3745a8dc051d15d4596a (diff)
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. And also seems to correct the LVDS panel on the Lenovo U160. However, at one point, it did cause an "ERROR failed to disable trancoder". So prolonged testing on top of Jesse's refactored and error-checking CRTC logic is desired. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c1
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h4
-rw-r--r--drivers/gpu/drm/i915/intel_display.c56
4 files changed, 36 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index eaec56ef12b6..52ceae571397 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -350,6 +350,7 @@ typedef struct drm_i915_private {
350 unsigned int lvds_vbt:1; 350 unsigned int lvds_vbt:1;
351 unsigned int int_crt_support:1; 351 unsigned int int_crt_support:1;
352 unsigned int lvds_use_ssc:1; 352 unsigned int lvds_use_ssc:1;
353 unsigned int display_clock_mode:1;
353 int lvds_ssc_freq; 354 int lvds_ssc_freq;
354 struct { 355 struct {
355 int rate; 356 int rate;
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 4b95295ab04a..35c3b1442ba9 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -279,6 +279,7 @@ parse_general_features(struct drm_i915_private *dev_priv,
279 dev_priv->lvds_use_ssc = general->enable_ssc; 279 dev_priv->lvds_use_ssc = general->enable_ssc;
280 dev_priv->lvds_ssc_freq = 280 dev_priv->lvds_ssc_freq =
281 intel_bios_ssc_frequency(dev, general->ssc_freq); 281 intel_bios_ssc_frequency(dev, general->ssc_freq);
282 dev_priv->display_clock_mode = general->display_clock_mode;
282 } 283 }
283} 284}
284 285
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 5f8e4edcbbb9..02b1b62415df 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -120,7 +120,9 @@ struct bdb_general_features {
120 u8 ssc_freq:1; 120 u8 ssc_freq:1;
121 u8 enable_lfp_on_override:1; 121 u8 enable_lfp_on_override:1;
122 u8 disable_ssc_ddt:1; 122 u8 disable_ssc_ddt:1;
123 u8 rsvd8:3; /* finish byte */ 123 u8 rsvd7:1;
124 u8 display_clock_mode:1;
125 u8 rsvd8:1; /* finish byte */
124 126
125 /* bits 3 */ 127 /* bits 3 */
126 u8 disable_smooth_vision:1; 128 u8 disable_smooth_vision:1;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2c7e90f12657..2f58d97972db 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4506,44 +4506,50 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
4506 * ignoring this setting. 4506 * ignoring this setting.
4507 */ 4507 */
4508 if (HAS_PCH_SPLIT(dev)) { 4508 if (HAS_PCH_SPLIT(dev)) {
4509 /*XXX BIOS treats 16:31 as a mask for 0:15 */
4510
4509 temp = I915_READ(PCH_DREF_CONTROL); 4511 temp = I915_READ(PCH_DREF_CONTROL);
4510 /* Always enable nonspread source */ 4512
4513 /* First clear the current state for output switching */
4514 temp &= ~DREF_SSC1_ENABLE;
4515 temp &= ~DREF_SSC4_ENABLE;
4516 temp &= ~DREF_SUPERSPREAD_SOURCE_MASK;
4511 temp &= ~DREF_NONSPREAD_SOURCE_MASK; 4517 temp &= ~DREF_NONSPREAD_SOURCE_MASK;
4512 temp |= DREF_NONSPREAD_SOURCE_ENABLE;
4513 temp &= ~DREF_SSC_SOURCE_MASK; 4518 temp &= ~DREF_SSC_SOURCE_MASK;
4514 temp |= DREF_SSC_SOURCE_ENABLE; 4519 temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
4515 I915_WRITE(PCH_DREF_CONTROL, temp); 4520 I915_WRITE(PCH_DREF_CONTROL, temp);
4516 4521
4517 POSTING_READ(PCH_DREF_CONTROL); 4522 POSTING_READ(PCH_DREF_CONTROL);
4518 udelay(200); 4523 udelay(200);
4519 4524
4520 if (has_edp_encoder) { 4525 if ((is_lvds || has_edp_encoder) &&
4521 if (intel_panel_use_ssc(dev_priv)) { 4526 intel_panel_use_ssc(dev_priv)) {
4522 temp |= DREF_SSC1_ENABLE; 4527 temp |= DREF_SSC_SOURCE_ENABLE;
4523 I915_WRITE(PCH_DREF_CONTROL, temp); 4528 if (has_edp_encoder) {
4524 4529 if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
4525 POSTING_READ(PCH_DREF_CONTROL); 4530 /* Enable CPU source on CPU attached eDP */
4526 udelay(200);
4527 }
4528 temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
4529
4530 /* Enable CPU source on CPU attached eDP */
4531 if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
4532 if (intel_panel_use_ssc(dev_priv))
4533 temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; 4531 temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
4534 else 4532 } else {
4535 temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; 4533 /* Enable SSC on PCH eDP if needed */
4536 } else {
4537 /* Enable SSC on PCH eDP if needed */
4538 if (intel_panel_use_ssc(dev_priv)) {
4539 DRM_ERROR("enabling SSC on PCH\n");
4540 temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; 4534 temp |= DREF_SUPERSPREAD_SOURCE_ENABLE;
4541 } 4535 }
4536 I915_WRITE(PCH_DREF_CONTROL, temp);
4542 } 4537 }
4543 I915_WRITE(PCH_DREF_CONTROL, temp); 4538 if (!dev_priv->display_clock_mode)
4544 POSTING_READ(PCH_DREF_CONTROL); 4539 temp |= DREF_SSC1_ENABLE;
4545 udelay(200); 4540 } else {
4541 if (dev_priv->display_clock_mode)
4542 temp |= DREF_NONSPREAD_CK505_ENABLE;
4543 else
4544 temp |= DREF_NONSPREAD_SOURCE_ENABLE;
4545 if (has_edp_encoder &&
4546 !intel_encoder_is_pch_edp(&has_edp_encoder->base))
4547 temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
4546 } 4548 }
4549
4550 I915_WRITE(PCH_DREF_CONTROL, temp);
4551 POSTING_READ(PCH_DREF_CONTROL);
4552 udelay(200);
4547 } 4553 }
4548 4554
4549 if (IS_PINEVIEW(dev)) { 4555 if (IS_PINEVIEW(dev)) {