diff options
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 41 |
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); |
| 356 | static void | 356 | static void |
| 357 | intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, | 357 | intel_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); | ||
| 359 | static void | 360 | static void |
| 360 | intel_dp_pps_init(struct drm_device *dev, struct intel_dp *intel_dp); | 361 | intel_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 | ||
| 642 | void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) | 643 | void 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 | ||
| 2918 | static void vlv_pre_enable_dp(struct intel_encoder *encoder, | 2919 | static 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 | ||
| 5056 | static void | 5057 | static void |
| 5057 | intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, | 5058 | intel_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, ®s); | 5071 | intel_pps_get_registers(dev_priv, intel_dp, ®s); |
| 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 | ||
