Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: Force VDD off on the new power seqeuencer before starting to use it

Apparently some VLV BIOSen like to leave the VDD force bit enabled
even for power seqeuncers that aren't properly hooked up to any
port. That will result in a imbalance in the AUX power domain
refcount when we stat to use said power sequencer as edp_panel_vdd_on()
will not grab the power domain reference if it sees that the VDD is
already on.

To fix this let's make sure we turn off the VDD force bit when we
initialize the power sequencer registers. That is, unless it's
being done from the init path since there we are actually
initializing the registers for the current power sequencer and
we don't want to turn VDD off needlessly as that would require
waiting for the power cycle delay before we turn it back on.

This fixes the following kind of warnings:
WARNING: CPU: 0 PID: 123 at ../drivers/gpu/drm/i915/intel_runtime_pm.c:1455 intel_display_power_put+0x13a/0x170 [i915]()
WARN_ON(!power_domains->domain_use_count[domain])
...

v2: Fix typos in comment (David)

Cc: stable@vger.kernel.org
Cc: Matwey V. Kornilov <matwey.kornilov@gmail.com>
Tested-by: Matwey V. Kornilov <matwey.kornilov@gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98695
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20161220165117.24801-1-ville.syrjala@linux.intel.com
Reviewed-by: David Weinehall <david.weinehall@linux.intel.com>
(cherry picked from commit 5d5ab2d26f32bdaa5872b938658e0bf8d341bc4c)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>

authored by

Ville Syrjälä and committed by
Jani Nikula
8581f1b5 ade4d441

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