aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2013-10-25 10:36:48 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-10-27 12:38:13 -0400
commitbaa707073b6f5374a917f86f4a681149cd39dc64 (patch)
treebce25b2b87eb45f28d650c8126affff881144a69
parent83c00f55302219fdac1f8628e61f2b63cffc58d5 (diff)
drm/i915: use power get/put instead of set for power on after init
Currently we make sure that all power domains are enabled during driver init and turn off unneded ones only after the first modeset. Similarly during suspend we enable all power domains, which will remain on through the following resume until the first modeset. This logic is supported by intel_set_power_well() in the power domain framework. It would be nice to simplify the API, so that we only have get/put functions and make it more explicit on the higher level how this "power well on during init" logic works. This will make it also easier if in the future we want to shorten the time the power wells are on. For this add a new device private flag tracking whether we have the power wells on because of init/suspend and use only intel_display_power_get()/put(). As nothing else uses intel_set_power_well() we can remove it. This also fixes commit 6efdf354ddb186c6604d1692075421e8d2c740e9 Author: Imre Deak <imre.deak@intel.com> Date: Wed Oct 16 17:25:52 2013 +0300 drm/i915: enable only the needed power domains during modeset where removing intel_set_power_well() resulted in not releasing the reference on the power well that was taken during init and thus leaving the power well on all the time. Regression reported by Paulo. v2: - move the init_power_on flag to the power_domains struct (Daniel) v3: - add note about this being a regression fix too (Paulo) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c2
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c2
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h8
-rw-r--r--drivers/gpu/drm/i915/intel_display.c17
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c37
6 files changed, 28 insertions, 39 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 437886641d90..bec1fe93cf24 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1723,7 +1723,7 @@ int i915_driver_unload(struct drm_device *dev)
1723 /* The i915.ko module is still not prepared to be loaded when 1723 /* The i915.ko module is still not prepared to be loaded when
1724 * the power well is not enabled, so just enable it in case 1724 * the power well is not enabled, so just enable it in case
1725 * we're going to unload/reload. */ 1725 * we're going to unload/reload. */
1726 intel_set_power_well(dev, true); 1726 intel_display_set_init_power(dev, true);
1727 i915_remove_power_well(dev); 1727 i915_remove_power_well(dev);
1728 } 1728 }
1729 1729
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 1060a96d2184..b764f7b7eb6b 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -477,7 +477,7 @@ static int i915_drm_freeze(struct drm_device *dev)
477 /* We do a lot of poking in a lot of registers, make sure they work 477 /* We do a lot of poking in a lot of registers, make sure they work
478 * properly. */ 478 * properly. */
479 hsw_disable_package_c8(dev_priv); 479 hsw_disable_package_c8(dev_priv);
480 intel_set_power_well(dev, true); 480 intel_display_set_init_power(dev, true);
481 481
482 drm_kms_helper_poll_disable(dev); 482 drm_kms_helper_poll_disable(dev);
483 483
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8371182f7480..43dbf6a06a9d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -100,6 +100,7 @@ enum intel_display_power_domain {
100 POWER_DOMAIN_TRANSCODER_C, 100 POWER_DOMAIN_TRANSCODER_C,
101 POWER_DOMAIN_TRANSCODER_EDP, 101 POWER_DOMAIN_TRANSCODER_EDP,
102 POWER_DOMAIN_VGA, 102 POWER_DOMAIN_VGA,
103 POWER_DOMAIN_INIT,
103 104
104 POWER_DOMAIN_NUM, 105 POWER_DOMAIN_NUM,
105}; 106};
@@ -911,12 +912,17 @@ struct i915_power_well {
911 struct drm_device *device; 912 struct drm_device *device;
912 /* power well enable/disable usage count */ 913 /* power well enable/disable usage count */
913 int count; 914 int count;
914 int i915_request;
915}; 915};
916 916
917#define I915_MAX_POWER_WELLS 1 917#define I915_MAX_POWER_WELLS 1
918 918
919struct i915_power_domains { 919struct i915_power_domains {
920 /*
921 * Power wells needed for initialization at driver init and suspend
922 * time are on. They are kept on until after the first modeset.
923 */
924 bool init_power_on;
925
920 struct mutex lock; 926 struct mutex lock;
921 struct i915_power_well power_wells[I915_MAX_POWER_WELLS]; 927 struct i915_power_well power_wells[I915_MAX_POWER_WELLS];
922}; 928};
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cfe9e7093b2a..8c3bf8a89cb7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6577,6 +6577,21 @@ static unsigned long get_pipe_power_domains(struct drm_device *dev,
6577 return mask; 6577 return mask;
6578} 6578}
6579 6579
6580void intel_display_set_init_power(struct drm_device *dev, bool enable)
6581{
6582 struct drm_i915_private *dev_priv = dev->dev_private;
6583
6584 if (dev_priv->power_domains.init_power_on == enable)
6585 return;
6586
6587 if (enable)
6588 intel_display_power_get(dev, POWER_DOMAIN_INIT);
6589 else
6590 intel_display_power_put(dev, POWER_DOMAIN_INIT);
6591
6592 dev_priv->power_domains.init_power_on = enable;
6593}
6594
6580static void modeset_update_power_wells(struct drm_device *dev) 6595static void modeset_update_power_wells(struct drm_device *dev)
6581{ 6596{
6582 unsigned long pipe_domains[I915_MAX_PIPES] = { 0, }; 6597 unsigned long pipe_domains[I915_MAX_PIPES] = { 0, };
@@ -6608,6 +6623,8 @@ static void modeset_update_power_wells(struct drm_device *dev)
6608 6623
6609 crtc->enabled_power_domains = pipe_domains[crtc->pipe]; 6624 crtc->enabled_power_domains = pipe_domains[crtc->pipe];
6610 } 6625 }
6626
6627 intel_display_set_init_power(dev, false);
6611} 6628}
6612 6629
6613static void haswell_modeset_global_resources(struct drm_device *dev) 6630static void haswell_modeset_global_resources(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index af1553ca0f4e..bf4394a144a5 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -692,6 +692,7 @@ bool intel_crtc_active(struct drm_crtc *crtc);
692void i915_disable_vga_mem(struct drm_device *dev); 692void i915_disable_vga_mem(struct drm_device *dev);
693void hsw_enable_ips(struct intel_crtc *crtc); 693void hsw_enable_ips(struct intel_crtc *crtc);
694void hsw_disable_ips(struct intel_crtc *crtc); 694void hsw_disable_ips(struct intel_crtc *crtc);
695void intel_display_set_init_power(struct drm_device *dev, bool enable);
695 696
696 697
697/* intel_dp.c */ 698/* intel_dp.c */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 5869482f3f69..5ae6d533ebcd 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5679,41 +5679,6 @@ void i915_remove_power_well(struct drm_device *dev)
5679 hsw_pwr = NULL; 5679 hsw_pwr = NULL;
5680} 5680}
5681 5681
5682void intel_set_power_well(struct drm_device *dev, bool enable)
5683{
5684 struct drm_i915_private *dev_priv = dev->dev_private;
5685 struct i915_power_domains *power_domains = &dev_priv->power_domains;
5686 struct i915_power_well *power_well;
5687
5688 if (!HAS_POWER_WELL(dev))
5689 return;
5690
5691 if (!i915_disable_power_well && !enable)
5692 return;
5693
5694 mutex_lock(&power_domains->lock);
5695
5696 power_well = &power_domains->power_wells[0];
5697 /*
5698 * This function will only ever contribute one
5699 * to the power well reference count. i915_request
5700 * is what tracks whether we have or have not
5701 * added the one to the reference count.
5702 */
5703 if (power_well->i915_request == enable)
5704 goto out;
5705
5706 power_well->i915_request = enable;
5707
5708 if (enable)
5709 __intel_power_well_get(power_well);
5710 else
5711 __intel_power_well_put(power_well);
5712
5713 out:
5714 mutex_unlock(&power_domains->lock);
5715}
5716
5717static void intel_resume_power_well(struct drm_device *dev) 5682static void intel_resume_power_well(struct drm_device *dev)
5718{ 5683{
5719 struct drm_i915_private *dev_priv = dev->dev_private; 5684 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5745,7 +5710,7 @@ void intel_init_power_well(struct drm_device *dev)
5745 return; 5710 return;
5746 5711
5747 /* For now, we need the power well to be always enabled. */ 5712 /* For now, we need the power well to be always enabled. */
5748 intel_set_power_well(dev, true); 5713 intel_display_set_init_power(dev, true);
5749 intel_resume_power_well(dev); 5714 intel_resume_power_well(dev);
5750 5715
5751 /* We're taking over the BIOS, so clear any requests made by it since 5716 /* We're taking over the BIOS, so clear any requests made by it since