aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/intel_display.c123
1 files changed, 77 insertions, 46 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 84f3054a066f..cc431f4581c3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4463,6 +4463,81 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
4463 return dev_priv->lvds_use_ssc && i915_panel_use_ssc; 4463 return dev_priv->lvds_use_ssc && i915_panel_use_ssc;
4464} 4464}
4465 4465
4466static void intel_update_dref(struct drm_i915_private *dev_priv)
4467{
4468 struct drm_device *dev = dev_priv->dev;
4469 struct drm_mode_config *mode_config = &dev->mode_config;
4470 struct intel_encoder *encoder;
4471 struct drm_crtc *crtc;
4472 u32 temp;
4473 bool lvds_on = false, edp_on = false, pch_edp_on = false, other_on = false;
4474
4475 list_for_each_entry(encoder, &mode_config->encoder_list, base.head) {
4476 crtc = encoder->base.crtc;
4477
4478 if (!crtc || !crtc->enabled)
4479 continue;
4480
4481 switch (encoder->type) {
4482 case INTEL_OUTPUT_LVDS:
4483 lvds_on = true;
4484 break;
4485 case INTEL_OUTPUT_EDP:
4486 edp_on = true;
4487 if (!pch_edp_on)
4488 pch_edp_on = intel_encoder_is_pch_edp(&encoder->base);
4489 break;
4490 default:
4491 other_on = true;
4492 break;
4493 }
4494 }
4495
4496 /*XXX BIOS treats 16:31 as a mask for 0:15 */
4497
4498 temp = I915_READ(PCH_DREF_CONTROL);
4499
4500 /* First clear the current state for output switching */
4501 temp &= ~DREF_SSC1_ENABLE;
4502 temp &= ~DREF_SSC4_ENABLE;
4503 temp &= ~DREF_SUPERSPREAD_SOURCE_MASK;
4504 temp &= ~DREF_NONSPREAD_SOURCE_MASK;
4505 temp &= ~DREF_SSC_SOURCE_MASK;
4506 temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
4507 I915_WRITE(PCH_DREF_CONTROL, temp);
4508
4509 POSTING_READ(PCH_DREF_CONTROL);
4510 udelay(200);
4511
4512 if ((lvds_on || edp_on) && intel_panel_use_ssc(dev_priv)) {
4513 temp |= DREF_SSC_SOURCE_ENABLE;
4514 if (edp_on) {
4515 if (!pch_edp_on) {
4516 /* Enable CPU source on CPU attached eDP */
4517 temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
4518 } else {
4519 /* Enable SSC on PCH eDP if needed */
4520 temp |= DREF_SUPERSPREAD_SOURCE_ENABLE;
4521 }
4522 I915_WRITE(PCH_DREF_CONTROL, temp);
4523 }
4524 if (!dev_priv->display_clock_mode)
4525 temp |= DREF_SSC1_ENABLE;
4526 }
4527
4528 if (other_on && dev_priv->display_clock_mode)
4529 temp |= DREF_NONSPREAD_CK505_ENABLE;
4530 else if (other_on) {
4531 temp |= DREF_NONSPREAD_SOURCE_ENABLE;
4532 if (edp_on && !pch_edp_on)
4533 temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
4534 }
4535
4536 I915_WRITE(PCH_DREF_CONTROL, temp);
4537 POSTING_READ(PCH_DREF_CONTROL);
4538 udelay(200);
4539}
4540
4466static int intel_crtc_mode_set(struct drm_crtc *crtc, 4541static int intel_crtc_mode_set(struct drm_crtc *crtc,
4467 struct drm_display_mode *mode, 4542 struct drm_display_mode *mode,
4468 struct drm_display_mode *adjusted_mode, 4543 struct drm_display_mode *adjusted_mode,
@@ -4688,52 +4763,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
4688 * PCH B stepping, previous chipset stepping should be 4763 * PCH B stepping, previous chipset stepping should be
4689 * ignoring this setting. 4764 * ignoring this setting.
4690 */ 4765 */
4691 if (HAS_PCH_SPLIT(dev)) { 4766 if (HAS_PCH_SPLIT(dev))
4692 /*XXX BIOS treats 16:31 as a mask for 0:15 */ 4767 intel_update_dref(dev_priv);
4693
4694 temp = I915_READ(PCH_DREF_CONTROL);
4695
4696 /* First clear the current state for output switching */
4697 temp &= ~DREF_SSC1_ENABLE;
4698 temp &= ~DREF_SSC4_ENABLE;
4699 temp &= ~DREF_SUPERSPREAD_SOURCE_MASK;
4700 temp &= ~DREF_NONSPREAD_SOURCE_MASK;
4701 temp &= ~DREF_SSC_SOURCE_MASK;
4702 temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
4703 I915_WRITE(PCH_DREF_CONTROL, temp);
4704
4705 POSTING_READ(PCH_DREF_CONTROL);
4706 udelay(200);
4707
4708 if ((is_lvds || has_edp_encoder) &&
4709 intel_panel_use_ssc(dev_priv)) {
4710 temp |= DREF_SSC_SOURCE_ENABLE;
4711 if (has_edp_encoder) {
4712 if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
4713 /* Enable CPU source on CPU attached eDP */
4714 temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
4715 } else {
4716 /* Enable SSC on PCH eDP if needed */
4717 temp |= DREF_SUPERSPREAD_SOURCE_ENABLE;
4718 }
4719 I915_WRITE(PCH_DREF_CONTROL, temp);
4720 }
4721 if (!dev_priv->display_clock_mode)
4722 temp |= DREF_SSC1_ENABLE;
4723 } else {
4724 if (dev_priv->display_clock_mode)
4725 temp |= DREF_NONSPREAD_CK505_ENABLE;
4726 else
4727 temp |= DREF_NONSPREAD_SOURCE_ENABLE;
4728 if (has_edp_encoder &&
4729 !intel_encoder_is_pch_edp(&has_edp_encoder->base))
4730 temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
4731 }
4732
4733 I915_WRITE(PCH_DREF_CONTROL, temp);
4734 POSTING_READ(PCH_DREF_CONTROL);
4735 udelay(200);
4736 }
4737 4768
4738 if (IS_PINEVIEW(dev)) { 4769 if (IS_PINEVIEW(dev)) {
4739 fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; 4770 fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;