aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index d9bc19be855e..0b8e8eb85c19 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -355,7 +355,8 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
355 struct intel_dp *intel_dp); 355 struct intel_dp *intel_dp);
356static void 356static void
357intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, 357intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
358 struct intel_dp *intel_dp); 358 struct intel_dp *intel_dp,
359 bool force_disable_vdd);
359static void 360static void
360intel_dp_pps_init(struct drm_device *dev, struct intel_dp *intel_dp); 361intel_dp_pps_init(struct drm_device *dev, struct intel_dp *intel_dp);
361 362
@@ -516,7 +517,7 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
516 517
517 /* init power sequencer on this pipe and port */ 518 /* init power sequencer on this pipe and port */
518 intel_dp_init_panel_power_sequencer(dev, intel_dp); 519 intel_dp_init_panel_power_sequencer(dev, intel_dp);
519 intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); 520 intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, true);
520 521
521 /* 522 /*
522 * Even vdd force doesn't work until we've made 523 * Even vdd force doesn't work until we've made
@@ -553,7 +554,7 @@ bxt_power_sequencer_idx(struct intel_dp *intel_dp)
553 * Only the HW needs to be reprogrammed, the SW state is fixed and 554 * Only the HW needs to be reprogrammed, the SW state is fixed and
554 * has been setup during connector init. 555 * has been setup during connector init.
555 */ 556 */
556 intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); 557 intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false);
557 558
558 return 0; 559 return 0;
559} 560}
@@ -636,7 +637,7 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp)
636 port_name(port), pipe_name(intel_dp->pps_pipe)); 637 port_name(port), pipe_name(intel_dp->pps_pipe));
637 638
638 intel_dp_init_panel_power_sequencer(dev, intel_dp); 639 intel_dp_init_panel_power_sequencer(dev, intel_dp);
639 intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); 640 intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false);
640} 641}
641 642
642void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) 643void intel_power_sequencer_reset(struct drm_i915_private *dev_priv)
@@ -2912,7 +2913,7 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp)
2912 2913
2913 /* init power sequencer on this pipe and port */ 2914 /* init power sequencer on this pipe and port */
2914 intel_dp_init_panel_power_sequencer(dev, intel_dp); 2915 intel_dp_init_panel_power_sequencer(dev, intel_dp);
2915 intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); 2916 intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, true);
2916} 2917}
2917 2918
2918static void vlv_pre_enable_dp(struct intel_encoder *encoder, 2919static void vlv_pre_enable_dp(struct intel_encoder *encoder,
@@ -5055,7 +5056,8 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
5055 5056
5056static void 5057static void
5057intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, 5058intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
5058 struct intel_dp *intel_dp) 5059 struct intel_dp *intel_dp,
5060 bool force_disable_vdd)
5059{ 5061{
5060 struct drm_i915_private *dev_priv = to_i915(dev); 5062 struct drm_i915_private *dev_priv = to_i915(dev);
5061 u32 pp_on, pp_off, pp_div, port_sel = 0; 5063 u32 pp_on, pp_off, pp_div, port_sel = 0;
@@ -5068,6 +5070,31 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
5068 5070
5069 intel_pps_get_registers(dev_priv, intel_dp, &regs); 5071 intel_pps_get_registers(dev_priv, intel_dp, &regs);
5070 5072
5073 /*
5074 * On some VLV machines the BIOS can leave the VDD
5075 * enabled even on power seqeuencers which aren't
5076 * hooked up to any port. This would mess up the
5077 * power domain tracking the first time we pick
5078 * one of these power sequencers for use since
5079 * edp_panel_vdd_on() would notice that the VDD was
5080 * already on and therefore wouldn't grab the power
5081 * domain reference. Disable VDD first to avoid this.
5082 * This also avoids spuriously turning the VDD on as
5083 * soon as the new power seqeuencer gets initialized.
5084 */
5085 if (force_disable_vdd) {
5086 u32 pp = ironlake_get_pp_control(intel_dp);
5087
5088 WARN(pp & PANEL_POWER_ON, "Panel power already on\n");
5089
5090 if (pp & EDP_FORCE_VDD)
5091 DRM_DEBUG_KMS("VDD already on, disabling first\n");
5092
5093 pp &= ~EDP_FORCE_VDD;
5094
5095 I915_WRITE(regs.pp_ctrl, pp);
5096 }
5097
5071 pp_on = (seq->t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) | 5098 pp_on = (seq->t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) |
5072 (seq->t8 << PANEL_LIGHT_ON_DELAY_SHIFT); 5099 (seq->t8 << PANEL_LIGHT_ON_DELAY_SHIFT);
5073 pp_off = (seq->t9 << PANEL_LIGHT_OFF_DELAY_SHIFT) | 5100 pp_off = (seq->t9 << PANEL_LIGHT_OFF_DELAY_SHIFT) |
@@ -5122,7 +5149,7 @@ static void intel_dp_pps_init(struct drm_device *dev,
5122 vlv_initial_power_sequencer_setup(intel_dp); 5149 vlv_initial_power_sequencer_setup(intel_dp);
5123 } else { 5150 } else {
5124 intel_dp_init_panel_power_sequencer(dev, intel_dp); 5151 intel_dp_init_panel_power_sequencer(dev, intel_dp);
5125 intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); 5152 intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false);
5126 } 5153 }
5127} 5154}
5128 5155