aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_pm.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2015-03-18 05:48:21 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-03-20 06:48:13 -0400
commitaed242ff7ebb697e4dff912bd4dc7ec7192f7581 (patch)
tree9bf4cf8bef001d27088e37d037f55f1149802964 /drivers/gpu/drm/i915/intel_pm.c
parentedf4427b8055dc93eb5222d8174b07a75ba24fb5 (diff)
drm/i915: Relax RPS contraints to allows setting minfreq on idle
When we idle, we set the GPU frequency to the hardware minimum (not user minimum). We introduce a new variable to distinguish between the different roles, and to allow easy tuning of the idle frequency without impacting over aspects of RPS. Setting the minimum frequency should be a safety blanket as the pcu on the GPU should be power gating itself anyway. However, in order for us to do set the absolute minimum frequency, we need to relax a few of our assertions that we do not exceed the user limits. v2: Add idle_freq v3: Init idle_freq for vlv and add a bunch of WARNs Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Deepak S <deepak.s@linux.intel.com> Reviewed-by: Deepak S<deepak.s@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c44
1 files changed, 28 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 288c9d24098e..beab305e320d 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3855,9 +3855,9 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
3855 break; 3855 break;
3856 } 3856 }
3857 /* Max/min bins are special */ 3857 /* Max/min bins are special */
3858 if (val == dev_priv->rps.min_freq_softlimit) 3858 if (val <= dev_priv->rps.min_freq_softlimit)
3859 new_power = LOW_POWER; 3859 new_power = LOW_POWER;
3860 if (val == dev_priv->rps.max_freq_softlimit) 3860 if (val >= dev_priv->rps.max_freq_softlimit)
3861 new_power = HIGH_POWER; 3861 new_power = HIGH_POWER;
3862 if (new_power == dev_priv->rps.power) 3862 if (new_power == dev_priv->rps.power)
3863 return; 3863 return;
@@ -3940,8 +3940,8 @@ static void gen6_set_rps(struct drm_device *dev, u8 val)
3940 struct drm_i915_private *dev_priv = dev->dev_private; 3940 struct drm_i915_private *dev_priv = dev->dev_private;
3941 3941
3942 WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); 3942 WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
3943 WARN_ON(val > dev_priv->rps.max_freq_softlimit); 3943 WARN_ON(val > dev_priv->rps.max_freq);
3944 WARN_ON(val < dev_priv->rps.min_freq_softlimit); 3944 WARN_ON(val < dev_priv->rps.min_freq);
3945 3945
3946 /* min/max delay may still have been modified so be sure to 3946 /* min/max delay may still have been modified so be sure to
3947 * write the limits value. 3947 * write the limits value.
@@ -3979,8 +3979,8 @@ static void valleyview_set_rps(struct drm_device *dev, u8 val)
3979 struct drm_i915_private *dev_priv = dev->dev_private; 3979 struct drm_i915_private *dev_priv = dev->dev_private;
3980 3980
3981 WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); 3981 WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
3982 WARN_ON(val > dev_priv->rps.max_freq_softlimit); 3982 WARN_ON(val > dev_priv->rps.max_freq);
3983 WARN_ON(val < dev_priv->rps.min_freq_softlimit); 3983 WARN_ON(val < dev_priv->rps.min_freq);
3984 3984
3985 if (WARN_ONCE(IS_CHERRYVIEW(dev) && (val & 1), 3985 if (WARN_ONCE(IS_CHERRYVIEW(dev) && (val & 1),
3986 "Odd GPU freq value\n")) 3986 "Odd GPU freq value\n"))
@@ -4007,10 +4007,11 @@ static void valleyview_set_rps(struct drm_device *dev, u8 val)
4007static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) 4007static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
4008{ 4008{
4009 struct drm_device *dev = dev_priv->dev; 4009 struct drm_device *dev = dev_priv->dev;
4010 u32 val = dev_priv->rps.idle_freq;
4010 4011
4011 /* CHV and latest VLV don't need to force the gfx clock */ 4012 /* CHV and latest VLV don't need to force the gfx clock */
4012 if (IS_CHERRYVIEW(dev) || dev->pdev->revision >= 0xd) { 4013 if (IS_CHERRYVIEW(dev) || dev->pdev->revision >= 0xd) {
4013 valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); 4014 valleyview_set_rps(dev_priv->dev, val);
4014 return; 4015 return;
4015 } 4016 }
4016 4017
@@ -4018,7 +4019,7 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
4018 * When we are idle. Drop to min voltage state. 4019 * When we are idle. Drop to min voltage state.
4019 */ 4020 */
4020 4021
4021 if (dev_priv->rps.cur_freq <= dev_priv->rps.min_freq_softlimit) 4022 if (dev_priv->rps.cur_freq <= val)
4022 return; 4023 return;
4023 4024
4024 /* Mask turbo interrupt so that they will not come in between */ 4025 /* Mask turbo interrupt so that they will not come in between */
@@ -4027,10 +4028,9 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
4027 4028
4028 vlv_force_gfx_clock(dev_priv, true); 4029 vlv_force_gfx_clock(dev_priv, true);
4029 4030
4030 dev_priv->rps.cur_freq = dev_priv->rps.min_freq_softlimit; 4031 dev_priv->rps.cur_freq = val;
4031 4032
4032 vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, 4033 vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val);
4033 dev_priv->rps.min_freq_softlimit);
4034 4034
4035 if (wait_for(((vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS)) 4035 if (wait_for(((vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS))
4036 & GENFREQSTATUS) == 0, 100)) 4036 & GENFREQSTATUS) == 0, 100))
@@ -4038,8 +4038,7 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
4038 4038
4039 vlv_force_gfx_clock(dev_priv, false); 4039 vlv_force_gfx_clock(dev_priv, false);
4040 4040
4041 I915_WRITE(GEN6_PMINTRMSK, 4041 I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
4042 gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq));
4043} 4042}
4044 4043
4045void gen6_rps_idle(struct drm_i915_private *dev_priv) 4044void gen6_rps_idle(struct drm_i915_private *dev_priv)
@@ -4051,7 +4050,7 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
4051 if (IS_VALLEYVIEW(dev)) 4050 if (IS_VALLEYVIEW(dev))
4052 vlv_set_rps_idle(dev_priv); 4051 vlv_set_rps_idle(dev_priv);
4053 else 4052 else
4054 gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); 4053 gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
4055 dev_priv->rps.last_adj = 0; 4054 dev_priv->rps.last_adj = 0;
4056 } 4055 }
4057 mutex_unlock(&dev_priv->rps.hw_lock); 4056 mutex_unlock(&dev_priv->rps.hw_lock);
@@ -4209,6 +4208,8 @@ static void gen6_init_rps_frequencies(struct drm_device *dev)
4209 dev_priv->rps.max_freq); 4208 dev_priv->rps.max_freq);
4210 } 4209 }
4211 4210
4211 dev_priv->rps.idle_freq = dev_priv->rps.min_freq;
4212
4212 /* Preserve min/max settings in case of re-init */ 4213 /* Preserve min/max settings in case of re-init */
4213 if (dev_priv->rps.max_freq_softlimit == 0) 4214 if (dev_priv->rps.max_freq_softlimit == 0)
4214 dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq; 4215 dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq;
@@ -4375,7 +4376,7 @@ static void gen8_enable_rps(struct drm_device *dev)
4375 /* 6: Ring frequency + overclocking (our driver does this later */ 4376 /* 6: Ring frequency + overclocking (our driver does this later */
4376 4377
4377 dev_priv->rps.power = HIGH_POWER; /* force a reset */ 4378 dev_priv->rps.power = HIGH_POWER; /* force a reset */
4378 gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); 4379 gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
4379 4380
4380 intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); 4381 intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
4381} 4382}
@@ -4469,7 +4470,7 @@ static void gen6_enable_rps(struct drm_device *dev)
4469 } 4470 }
4470 4471
4471 dev_priv->rps.power = HIGH_POWER; /* force a reset */ 4472 dev_priv->rps.power = HIGH_POWER; /* force a reset */
4472 gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); 4473 gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
4473 4474
4474 rc6vids = 0; 4475 rc6vids = 0;
4475 ret = sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids); 4476 ret = sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids);
@@ -4834,6 +4835,8 @@ static void valleyview_init_gt_powersave(struct drm_device *dev)
4834 intel_gpu_freq(dev_priv, dev_priv->rps.min_freq), 4835 intel_gpu_freq(dev_priv, dev_priv->rps.min_freq),
4835 dev_priv->rps.min_freq); 4836 dev_priv->rps.min_freq);
4836 4837
4838 dev_priv->rps.idle_freq = dev_priv->rps.min_freq;
4839
4837 /* Preserve min/max settings in case of re-init */ 4840 /* Preserve min/max settings in case of re-init */
4838 if (dev_priv->rps.max_freq_softlimit == 0) 4841 if (dev_priv->rps.max_freq_softlimit == 0)
4839 dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq; 4842 dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq;
@@ -4909,6 +4912,8 @@ static void cherryview_init_gt_powersave(struct drm_device *dev)
4909 dev_priv->rps.min_freq) & 1, 4912 dev_priv->rps.min_freq) & 1,
4910 "Odd GPU freq values\n"); 4913 "Odd GPU freq values\n");
4911 4914
4915 dev_priv->rps.idle_freq = dev_priv->rps.min_freq;
4916
4912 /* Preserve min/max settings in case of re-init */ 4917 /* Preserve min/max settings in case of re-init */
4913 if (dev_priv->rps.max_freq_softlimit == 0) 4918 if (dev_priv->rps.max_freq_softlimit == 0)
4914 dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq; 4919 dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq;
@@ -5686,6 +5691,13 @@ static void intel_gen6_powersave_work(struct work_struct *work)
5686 gen6_enable_rps(dev); 5691 gen6_enable_rps(dev);
5687 __gen6_update_ring_freq(dev); 5692 __gen6_update_ring_freq(dev);
5688 } 5693 }
5694
5695 WARN_ON(dev_priv->rps.max_freq < dev_priv->rps.min_freq);
5696 WARN_ON(dev_priv->rps.idle_freq > dev_priv->rps.max_freq);
5697
5698 WARN_ON(dev_priv->rps.efficient_freq < dev_priv->rps.min_freq);
5699 WARN_ON(dev_priv->rps.efficient_freq > dev_priv->rps.max_freq);
5700
5689 dev_priv->rps.enabled = true; 5701 dev_priv->rps.enabled = true;
5690 5702
5691 gen6_enable_rps_interrupts(dev); 5703 gen6_enable_rps_interrupts(dev);