aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-02-17 12:14:34 -0500
committerChris Wilson <chris@chris-wilson.co.uk>2011-02-22 10:55:28 -0500
commitfc9a2228ac208dc2b6033cfc6c56b6f7655fbdfa (patch)
tree3e75c38b2bf0f6d15a81e7fc1c6609e1d00a8643 /drivers/gpu/drm/i915
parent9035a97a32836d0e456ddafaaf249a844e6e4b5e (diff)
Revert "drm/i915: Disable SSC for outputs other than LVDS or DP"
This reverts commit 633f2ea26665d37bb3c8ae30799aa14988622653 and the attempted fix dcbe6f2b3d136995915e2f9ecc7d4f3b28f47b6c. There is a single clock source used for both SSC (some LVDS and DP) and non-SSC (VGA, DVI) outputs. So we need to be careful to only enable SSC as necessary. However, fiddling with DREFCLK was causing DP links to be dropped and we do not have a fix ready, so revert. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915')
-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.c117
4 files changed, 41 insertions, 82 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 92f4d33216cd..0c91262d259b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -346,7 +346,6 @@ typedef struct drm_i915_private {
346 unsigned int lvds_vbt:1; 346 unsigned int lvds_vbt:1;
347 unsigned int int_crt_support:1; 347 unsigned int int_crt_support:1;
348 unsigned int lvds_use_ssc:1; 348 unsigned int lvds_use_ssc:1;
349 unsigned int display_clock_mode:1;
350 int lvds_ssc_freq; 349 int lvds_ssc_freq;
351 struct { 350 struct {
352 int rate; 351 int rate;
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 48a0f03b60c3..fb5b4d426ae0 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -285,7 +285,6 @@ parse_general_features(struct drm_i915_private *dev_priv,
285 dev_priv->lvds_use_ssc = general->enable_ssc; 285 dev_priv->lvds_use_ssc = general->enable_ssc;
286 dev_priv->lvds_ssc_freq = 286 dev_priv->lvds_ssc_freq =
287 intel_bios_ssc_frequency(dev, general->ssc_freq); 287 intel_bios_ssc_frequency(dev, general->ssc_freq);
288 dev_priv->display_clock_mode = general->display_clock_mode;
289 } 288 }
290} 289}
291 290
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 02b1b62415df..5f8e4edcbbb9 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -120,9 +120,7 @@ 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 rsvd7:1; 123 u8 rsvd8:3; /* finish byte */
124 u8 display_clock_mode:1;
125 u8 rsvd8:1; /* finish byte */
126 124
127 /* bits 3 */ 125 /* bits 3 */
128 u8 disable_smooth_vision:1; 126 u8 disable_smooth_vision:1;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5e478338dc0a..6bda30dae400 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4506,81 +4506,6 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
4506 return dev_priv->lvds_use_ssc && i915_panel_use_ssc; 4506 return dev_priv->lvds_use_ssc && i915_panel_use_ssc;
4507} 4507}
4508 4508
4509static void intel_update_dref(struct drm_i915_private *dev_priv)
4510{
4511 struct drm_device *dev = dev_priv->dev;
4512 struct drm_mode_config *mode_config = &dev->mode_config;
4513 struct intel_encoder *encoder;
4514 struct drm_crtc *crtc;
4515 u32 temp;
4516 bool lvds_on = false, edp_on = false, pch_edp_on = false, other_on = false;
4517
4518 list_for_each_entry(encoder, &mode_config->encoder_list, base.head) {
4519 crtc = encoder->base.crtc;
4520
4521 if (!crtc || !crtc->enabled)
4522 continue;
4523
4524 switch (encoder->type) {
4525 case INTEL_OUTPUT_LVDS:
4526 lvds_on = true;
4527 break;
4528 case INTEL_OUTPUT_EDP:
4529 edp_on = true;
4530 if (!pch_edp_on)
4531 pch_edp_on = intel_encoder_is_pch_edp(&encoder->base);
4532 break;
4533 default:
4534 other_on = true;
4535 break;
4536 }
4537 }
4538
4539 /*XXX BIOS treats 16:31 as a mask for 0:15 */
4540
4541 temp = I915_READ(PCH_DREF_CONTROL);
4542
4543 /* First clear the current state for output switching */
4544 temp &= ~DREF_SSC1_ENABLE;
4545 temp &= ~DREF_SSC4_ENABLE;
4546 temp &= ~DREF_SUPERSPREAD_SOURCE_MASK;
4547 temp &= ~DREF_NONSPREAD_SOURCE_MASK;
4548 temp &= ~DREF_SSC_SOURCE_MASK;
4549 temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
4550 I915_WRITE(PCH_DREF_CONTROL, temp);
4551
4552 POSTING_READ(PCH_DREF_CONTROL);
4553 udelay(200);
4554
4555 if ((lvds_on || edp_on) && intel_panel_use_ssc(dev_priv)) {
4556 temp |= DREF_SSC_SOURCE_ENABLE;
4557 if (edp_on) {
4558 if (!pch_edp_on) {
4559 /* Enable CPU source on CPU attached eDP */
4560 temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
4561 } else {
4562 /* Enable SSC on PCH eDP if needed */
4563 temp |= DREF_SUPERSPREAD_SOURCE_ENABLE;
4564 }
4565 I915_WRITE(PCH_DREF_CONTROL, temp);
4566 }
4567 if (!dev_priv->display_clock_mode)
4568 temp |= DREF_SSC1_ENABLE;
4569 }
4570
4571 if (other_on && dev_priv->display_clock_mode)
4572 temp |= DREF_NONSPREAD_CK505_ENABLE;
4573 else if (other_on) {
4574 temp |= DREF_NONSPREAD_SOURCE_ENABLE;
4575 if (edp_on && !pch_edp_on)
4576 temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
4577 }
4578
4579 I915_WRITE(PCH_DREF_CONTROL, temp);
4580 POSTING_READ(PCH_DREF_CONTROL);
4581 udelay(200);
4582}
4583
4584static int intel_crtc_mode_set(struct drm_crtc *crtc, 4509static int intel_crtc_mode_set(struct drm_crtc *crtc,
4585 struct drm_display_mode *mode, 4510 struct drm_display_mode *mode,
4586 struct drm_display_mode *adjusted_mode, 4511 struct drm_display_mode *adjusted_mode,
@@ -4806,8 +4731,46 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
4806 * PCH B stepping, previous chipset stepping should be 4731 * PCH B stepping, previous chipset stepping should be
4807 * ignoring this setting. 4732 * ignoring this setting.
4808 */ 4733 */
4809 if (HAS_PCH_SPLIT(dev)) 4734 if (HAS_PCH_SPLIT(dev)) {
4810 intel_update_dref(dev_priv); 4735 temp = I915_READ(PCH_DREF_CONTROL);
4736 /* Always enable nonspread source */
4737 temp &= ~DREF_NONSPREAD_SOURCE_MASK;
4738 temp |= DREF_NONSPREAD_SOURCE_ENABLE;
4739 temp &= ~DREF_SSC_SOURCE_MASK;
4740 temp |= DREF_SSC_SOURCE_ENABLE;
4741 I915_WRITE(PCH_DREF_CONTROL, temp);
4742
4743 POSTING_READ(PCH_DREF_CONTROL);
4744 udelay(200);
4745
4746 if (has_edp_encoder) {
4747 if (intel_panel_use_ssc(dev_priv)) {
4748 temp |= DREF_SSC1_ENABLE;
4749 I915_WRITE(PCH_DREF_CONTROL, temp);
4750
4751 POSTING_READ(PCH_DREF_CONTROL);
4752 udelay(200);
4753 }
4754 temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
4755
4756 /* Enable CPU source on CPU attached eDP */
4757 if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
4758 if (intel_panel_use_ssc(dev_priv))
4759 temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
4760 else
4761 temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
4762 } else {
4763 /* Enable SSC on PCH eDP if needed */
4764 if (intel_panel_use_ssc(dev_priv)) {
4765 DRM_ERROR("enabling SSC on PCH\n");
4766 temp |= DREF_SUPERSPREAD_SOURCE_ENABLE;
4767 }
4768 }
4769 I915_WRITE(PCH_DREF_CONTROL, temp);
4770 POSTING_READ(PCH_DREF_CONTROL);
4771 udelay(200);
4772 }
4773 }
4811 4774
4812 if (IS_PINEVIEW(dev)) { 4775 if (IS_PINEVIEW(dev)) {
4813 fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; 4776 fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;