diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2015-03-18 05:48:21 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-03-20 06:48:13 -0400 |
commit | aed242ff7ebb697e4dff912bd4dc7ec7192f7581 (patch) | |
tree | 9bf4cf8bef001d27088e37d037f55f1149802964 /drivers/gpu/drm/i915/intel_pm.c | |
parent | edf4427b8055dc93eb5222d8174b07a75ba24fb5 (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.c | 44 |
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) | |||
4007 | static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) | 4007 | static 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 | ||
4045 | void gen6_rps_idle(struct drm_i915_private *dev_priv) | 4044 | void 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); |