aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulo Zanoni <paulo.r.zanoni@intel.com>2014-04-22 18:55:42 -0400
committerJani Nikula <jani.nikula@intel.com>2014-04-23 04:13:25 -0400
commit636352173a0dd127636fe331c97b117a8004bf50 (patch)
treeb1b41a0c7c2a170198b61ac49704feb2937e6feb
parent9953599bc02dbc1d3330e6a0bfc6c50e9dffcac6 (diff)
drm/i915: get power domain in case the BIOS enabled eDP VDD
If I unplug the eDP monitor, the BIOS of my machine will enable the VDD bit, then when the driver loads it will think VDD is enabled. It will detect that the eDP is not enabled and return false from intel_edp_init_connector. This will trigger a call to edp_panel_vdd_off_sync(), which trigger a WARN saying that the refcount of the power domain is less than zero. The problem happens because the driver gets a refcount whenever it enables the VDD bit, and puts the refcount whenever it disables the VDD bit. But on this case, the BIOS enabled VDD, so all we do is to call put() without calling get() first, so the code added is there to make sure we always have the get() in case the BIOS enabled the bit. This regression was introduced in commit e9cb81a22841908b1c075156b409a538d09c8466 Author: Paulo Zanoni <paulo.r.zanoni@intel.com> Date: Thu Nov 21 13:47:23 2013 -0200 drm/i915: get a runtime PM reference when the panel VDD is on v2: - Rebase Tested-by: Chris Wilson <chris@chris-wilson.co.uk> (v1) Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: stable@vger.kernel.org (v3.13+) Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index d2a55884ad52..dfa85289f28f 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3619,7 +3619,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
3619{ 3619{
3620 struct drm_connector *connector = &intel_connector->base; 3620 struct drm_connector *connector = &intel_connector->base;
3621 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); 3621 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
3622 struct drm_device *dev = intel_dig_port->base.base.dev; 3622 struct intel_encoder *intel_encoder = &intel_dig_port->base;
3623 struct drm_device *dev = intel_encoder->base.dev;
3623 struct drm_i915_private *dev_priv = dev->dev_private; 3624 struct drm_i915_private *dev_priv = dev->dev_private;
3624 struct drm_display_mode *fixed_mode = NULL; 3625 struct drm_display_mode *fixed_mode = NULL;
3625 bool has_dpcd; 3626 bool has_dpcd;
@@ -3629,6 +3630,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
3629 if (!is_edp(intel_dp)) 3630 if (!is_edp(intel_dp))
3630 return true; 3631 return true;
3631 3632
3633 /* The VDD bit needs a power domain reference, so if the bit is already
3634 * enabled when we boot, grab this reference. */
3635 if (edp_have_panel_vdd(intel_dp)) {
3636 enum intel_display_power_domain power_domain;
3637 power_domain = intel_display_port_power_domain(intel_encoder);
3638 intel_display_power_get(dev_priv, power_domain);
3639 }
3640
3632 /* Cache DPCD and EDID for edp. */ 3641 /* Cache DPCD and EDID for edp. */
3633 intel_edp_panel_vdd_on(intel_dp); 3642 intel_edp_panel_vdd_on(intel_dp);
3634 has_dpcd = intel_dp_get_dpcd(intel_dp); 3643 has_dpcd = intel_dp_get_dpcd(intel_dp);