aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c6
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h12
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h4
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c81
-rw-r--r--include/drm/i915_powerwell.h36
5 files changed, 132 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 22534c3b4fe5..fd8898c8f8e3 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1656,6 +1656,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1656 /* Start out suspended */ 1656 /* Start out suspended */
1657 dev_priv->mm.suspended = 1; 1657 dev_priv->mm.suspended = 1;
1658 1658
1659 if (HAS_POWER_WELL(dev))
1660 i915_init_power_well(dev);
1661
1659 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 1662 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
1660 ret = i915_load_modeset_init(dev); 1663 ret = i915_load_modeset_init(dev);
1661 if (ret < 0) { 1664 if (ret < 0) {
@@ -1712,6 +1715,9 @@ int i915_driver_unload(struct drm_device *dev)
1712 1715
1713 intel_gpu_ips_teardown(); 1716 intel_gpu_ips_teardown();
1714 1717
1718 if (HAS_POWER_WELL(dev))
1719 i915_remove_power_well(dev);
1720
1715 i915_teardown_sysfs(dev); 1721 i915_teardown_sysfs(dev);
1716 1722
1717 if (dev_priv->mm.inactive_shrinker.shrink) 1723 if (dev_priv->mm.inactive_shrinker.shrink)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 215aa63e3f47..87f7f88b1030 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -740,6 +740,15 @@ struct intel_ilk_power_mgmt {
740 struct drm_i915_gem_object *renderctx; 740 struct drm_i915_gem_object *renderctx;
741}; 741};
742 742
743/* Power well structure for haswell */
744struct i915_power_well {
745 struct drm_device *device;
746 spinlock_t lock;
747 /* power well enable/disable usage count */
748 int count;
749 int i915_request;
750};
751
743struct i915_dri1_state { 752struct i915_dri1_state {
744 unsigned allow_batchbuffer : 1; 753 unsigned allow_batchbuffer : 1;
745 u32 __iomem *gfx_hws_cpu_addr; 754 u32 __iomem *gfx_hws_cpu_addr;
@@ -1099,6 +1108,9 @@ typedef struct drm_i915_private {
1099 * mchdev_lock in intel_pm.c */ 1108 * mchdev_lock in intel_pm.c */
1100 struct intel_ilk_power_mgmt ips; 1109 struct intel_ilk_power_mgmt ips;
1101 1110
1111 /* Haswell power well */
1112 struct i915_power_well power_well;
1113
1102 enum no_fbc_reason no_fbc_reason; 1114 enum no_fbc_reason no_fbc_reason;
1103 1115
1104 struct drm_mm_node *compressed_fb; 1116 struct drm_mm_node *compressed_fb;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6bbebf824078..1735cdc86770 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -768,6 +768,10 @@ extern void intel_update_fbc(struct drm_device *dev);
768extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv); 768extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
769extern void intel_gpu_ips_teardown(void); 769extern void intel_gpu_ips_teardown(void);
770 770
771/* Power well */
772extern int i915_init_power_well(struct drm_device *dev);
773extern void i915_remove_power_well(struct drm_device *dev);
774
771extern bool intel_display_power_enabled(struct drm_device *dev, 775extern bool intel_display_power_enabled(struct drm_device *dev,
772 enum intel_display_power_domain domain); 776 enum intel_display_power_domain domain);
773extern void intel_init_power_well(struct drm_device *dev); 777extern void intel_init_power_well(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1e1b48ec6c46..a417d7b196c2 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5024,18 +5024,12 @@ bool intel_display_power_enabled(struct drm_device *dev,
5024 } 5024 }
5025} 5025}
5026 5026
5027void intel_set_power_well(struct drm_device *dev, bool enable) 5027static void __intel_set_power_well(struct drm_device *dev, bool enable)
5028{ 5028{
5029 struct drm_i915_private *dev_priv = dev->dev_private; 5029 struct drm_i915_private *dev_priv = dev->dev_private;
5030 bool is_enabled, enable_requested; 5030 bool is_enabled, enable_requested;
5031 uint32_t tmp; 5031 uint32_t tmp;
5032 5032
5033 if (!HAS_POWER_WELL(dev))
5034 return;
5035
5036 if (!i915_disable_power_well && !enable)
5037 return;
5038
5039 tmp = I915_READ(HSW_PWR_WELL_DRIVER); 5033 tmp = I915_READ(HSW_PWR_WELL_DRIVER);
5040 is_enabled = tmp & HSW_PWR_WELL_STATE; 5034 is_enabled = tmp & HSW_PWR_WELL_STATE;
5041 enable_requested = tmp & HSW_PWR_WELL_ENABLE; 5035 enable_requested = tmp & HSW_PWR_WELL_ENABLE;
@@ -5058,6 +5052,79 @@ void intel_set_power_well(struct drm_device *dev, bool enable)
5058 } 5052 }
5059} 5053}
5060 5054
5055static struct i915_power_well *hsw_pwr;
5056
5057/* Display audio driver power well request */
5058void i915_request_power_well(void)
5059{
5060 if (WARN_ON(!hsw_pwr))
5061 return;
5062
5063 spin_lock_irq(&hsw_pwr->lock);
5064 if (!hsw_pwr->count++ &&
5065 !hsw_pwr->i915_request)
5066 __intel_set_power_well(hsw_pwr->device, true);
5067 spin_unlock_irq(&hsw_pwr->lock);
5068}
5069EXPORT_SYMBOL_GPL(i915_request_power_well);
5070
5071/* Display audio driver power well release */
5072void i915_release_power_well(void)
5073{
5074 if (WARN_ON(!hsw_pwr))
5075 return;
5076
5077 spin_lock_irq(&hsw_pwr->lock);
5078 WARN_ON(!hsw_pwr->count);
5079 if (!--hsw_pwr->count &&
5080 !hsw_pwr->i915_request)
5081 __intel_set_power_well(hsw_pwr->device, false);
5082 spin_unlock_irq(&hsw_pwr->lock);
5083}
5084EXPORT_SYMBOL_GPL(i915_release_power_well);
5085
5086int i915_init_power_well(struct drm_device *dev)
5087{
5088 struct drm_i915_private *dev_priv = dev->dev_private;
5089
5090 hsw_pwr = &dev_priv->power_well;
5091
5092 hsw_pwr->device = dev;
5093 spin_lock_init(&hsw_pwr->lock);
5094 hsw_pwr->count = 0;
5095
5096 return 0;
5097}
5098
5099void i915_remove_power_well(struct drm_device *dev)
5100{
5101 hsw_pwr = NULL;
5102}
5103
5104void intel_set_power_well(struct drm_device *dev, bool enable)
5105{
5106 struct drm_i915_private *dev_priv = dev->dev_private;
5107 struct i915_power_well *power_well = &dev_priv->power_well;
5108
5109 if (!HAS_POWER_WELL(dev))
5110 return;
5111
5112 if (!i915_disable_power_well && !enable)
5113 return;
5114
5115 spin_lock_irq(&power_well->lock);
5116 power_well->i915_request = enable;
5117
5118 /* only reject "disable" power well request */
5119 if (power_well->count && !enable) {
5120 spin_unlock_irq(&power_well->lock);
5121 return;
5122 }
5123
5124 __intel_set_power_well(dev, enable);
5125 spin_unlock_irq(&power_well->lock);
5126}
5127
5061/* 5128/*
5062 * Starting with Haswell, we have a "Power Down Well" that can be turned off 5129 * Starting with Haswell, we have a "Power Down Well" that can be turned off
5063 * when not needed anymore. We have 4 registers that can request the power well 5130 * when not needed anymore. We have 4 registers that can request the power well
diff --git a/include/drm/i915_powerwell.h b/include/drm/i915_powerwell.h
new file mode 100644
index 000000000000..cfdc884405b7
--- /dev/null
+++ b/include/drm/i915_powerwell.h
@@ -0,0 +1,36 @@
1/**************************************************************************
2 *
3 * Copyright 2013 Intel Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 *
27 **************************************************************************/
28
29#ifndef _I915_POWERWELL_H_
30#define _I915_POWERWELL_H_
31
32/* For use by hda_i915 driver */
33extern void i915_request_power_well(void);
34extern void i915_release_power_well(void);
35
36#endif /* _I915_POWERWELL_H_ */