aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2014-08-18 07:42:45 -0400
committerJani Nikula <jani.nikula@intel.com>2014-08-18 09:49:36 -0400
commit07f9cd0b3870e306ddc5abcc3af2d748c9bd378c (patch)
tree7facf7045d5be69199077786fe4dd633b441c3e6 /drivers
parent1d0d343abb70922adebebc1cfcef6622f4c7edec (diff)
drm/i915: make sure VDD is turned off during system suspend
Atm we may leave eDP VDD enabled during system suspend after the CRTCs are disabled through an HPD->DPCD read event. So disable VDD during suspend at a point when no HPDs can occur. Note that runtime suspend doesn't have the same problem, since there the RPM ref held by VDD provides already the needed serialization. v2: - add note to commit message about the runtime suspend path (Ville) - use edp_panel_vdd_off_sync(), so we can keep the WARN in edp_panel_vdd_off() (Ville) v3: - rebased on -fixes (for_each_intel_encoder()->list_for_each_entry()) (Imre) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> (v2) Cc: stable@vger.kernel.org (3.16+) [Jani: fix sparse warning reported by Fengguang Wu] Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c17
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c11
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h6
3 files changed, 34 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 3f9c8f6b2418..e27cdbe9d524 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -509,6 +509,21 @@ void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
509 cancel_delayed_work_sync(&dev_priv->hotplug_reenable_work); 509 cancel_delayed_work_sync(&dev_priv->hotplug_reenable_work);
510} 510}
511 511
512static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
513{
514 struct drm_device *dev = dev_priv->dev;
515 struct drm_encoder *encoder;
516
517 drm_modeset_lock_all(dev);
518 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
519 struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
520
521 if (intel_encoder->suspend)
522 intel_encoder->suspend(intel_encoder);
523 }
524 drm_modeset_unlock_all(dev);
525}
526
512static int i915_drm_freeze(struct drm_device *dev) 527static int i915_drm_freeze(struct drm_device *dev)
513{ 528{
514 struct drm_i915_private *dev_priv = dev->dev_private; 529 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -555,6 +570,8 @@ static int i915_drm_freeze(struct drm_device *dev)
555 intel_runtime_pm_disable_interrupts(dev); 570 intel_runtime_pm_disable_interrupts(dev);
556 intel_hpd_cancel_work(dev_priv); 571 intel_hpd_cancel_work(dev_priv);
557 572
573 intel_suspend_encoders(dev_priv);
574
558 intel_suspend_gt_powersave(dev); 575 intel_suspend_gt_powersave(dev);
559 576
560 intel_modeset_suspend_hw(dev); 577 intel_modeset_suspend_hw(dev);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index a520188e6d97..39b643163846 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4003,6 +4003,16 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
4003 kfree(intel_dig_port); 4003 kfree(intel_dig_port);
4004} 4004}
4005 4005
4006static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
4007{
4008 struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
4009
4010 if (!is_edp(intel_dp))
4011 return;
4012
4013 edp_panel_vdd_off_sync(intel_dp);
4014}
4015
4006static void intel_dp_encoder_reset(struct drm_encoder *encoder) 4016static void intel_dp_encoder_reset(struct drm_encoder *encoder)
4007{ 4017{
4008 intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder)); 4018 intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder));
@@ -4731,6 +4741,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
4731 intel_encoder->disable = intel_disable_dp; 4741 intel_encoder->disable = intel_disable_dp;
4732 intel_encoder->get_hw_state = intel_dp_get_hw_state; 4742 intel_encoder->get_hw_state = intel_dp_get_hw_state;
4733 intel_encoder->get_config = intel_dp_get_config; 4743 intel_encoder->get_config = intel_dp_get_config;
4744 intel_encoder->suspend = intel_dp_encoder_suspend;
4734 if (IS_CHERRYVIEW(dev)) { 4745 if (IS_CHERRYVIEW(dev)) {
4735 intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable; 4746 intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable;
4736 intel_encoder->pre_enable = chv_pre_enable_dp; 4747 intel_encoder->pre_enable = chv_pre_enable_dp;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index fe3431f96900..b8c8bbd8e5f9 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -153,6 +153,12 @@ struct intel_encoder {
153 * be set correctly before calling this function. */ 153 * be set correctly before calling this function. */
154 void (*get_config)(struct intel_encoder *, 154 void (*get_config)(struct intel_encoder *,
155 struct intel_crtc_config *pipe_config); 155 struct intel_crtc_config *pipe_config);
156 /*
157 * Called during system suspend after all pending requests for the
158 * encoder are flushed (for example for DP AUX transactions) and
159 * device interrupts are disabled.
160 */
161 void (*suspend)(struct intel_encoder *);
156 int crtc_mask; 162 int crtc_mask;
157 enum hpd_pin hpd_pin; 163 enum hpd_pin hpd_pin;
158}; 164};