aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Widawsky <ben@bwidawsk.net>2013-04-05 17:29:22 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-04-18 03:43:17 -0400
commit31c77388662de2efe1dd74a3b7e106e633e8a833 (patch)
tree2cbc0482b69fa7bda7687b733f084f3fc2b58384 /drivers
parent2c55c336a71cb32ae837dc829d216dc86ed9d84f (diff)
drm/i915: Better overclock support
Most importantly this will allow users to set overclock frequencies in sysfs. Previously the max was limited by the RP0 max as opposed to the overclock max. This is useful if one wants to either limit the max overclock frequency, or set the minimum frequency to be in the overclock range. It also fixes an issue where if one sets the max frequency to be below the overclock max, they wouldn't be able to set back the proper overclock max. In addition I've added a couple of other bits: Show the overclock freq. as max in sysfs Print the overclock max in debugfs. Print a warning if the user sets the min frequency to be in the overclock range. In this patch I've decided to store the hw_max when we read it from the pcode at init. The reason I do this is the pcode reads can fail, and are slow. v2: Report when user requested overclocked max (Daniel) Remove when user sets min to overclock range (Daniel) Reported-by: freezer from #intel-gfx on irc Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com> [danvet: Fixup the s/100MHz/50MHz/ confusion in an unrelated comment that Mika spotted.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/i915_sysfs.c13
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c5
4 files changed, 16 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index be88532b35cf..7da45aa2dbee 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1006,6 +1006,9 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
1006 max_freq = rp_state_cap & 0xff; 1006 max_freq = rp_state_cap & 0xff;
1007 seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", 1007 seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
1008 max_freq * GT_FREQUENCY_MULTIPLIER); 1008 max_freq * GT_FREQUENCY_MULTIPLIER);
1009
1010 seq_printf(m, "Max overclocked frequency: %dMHz\n",
1011 dev_priv->rps.hw_max * GT_FREQUENCY_MULTIPLIER);
1009 } else { 1012 } else {
1010 seq_printf(m, "no P-state info available\n"); 1013 seq_printf(m, "no P-state info available\n");
1011 } 1014 }
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f59a388a9e8c..a4a8e608649f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -668,6 +668,7 @@ struct intel_gen6_power_mgmt {
668 u8 cur_delay; 668 u8 cur_delay;
669 u8 min_delay; 669 u8 min_delay;
670 u8 max_delay; 670 u8 max_delay;
671 u8 hw_max;
671 672
672 struct delayed_work delayed_resume_work; 673 struct delayed_work delayed_resume_work;
673 674
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index a3a3e22f1a84..fa4b4e881401 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -226,7 +226,7 @@ static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute
226 int ret; 226 int ret;
227 227
228 mutex_lock(&dev_priv->rps.hw_lock); 228 mutex_lock(&dev_priv->rps.hw_lock);
229 ret = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER; 229 ret = dev_priv->rps.hw_max * GT_FREQUENCY_MULTIPLIER;
230 mutex_unlock(&dev_priv->rps.hw_lock); 230 mutex_unlock(&dev_priv->rps.hw_lock);
231 231
232 return snprintf(buf, PAGE_SIZE, "%d\n", ret); 232 return snprintf(buf, PAGE_SIZE, "%d\n", ret);
@@ -239,7 +239,7 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
239 struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev); 239 struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
240 struct drm_device *dev = minor->dev; 240 struct drm_device *dev = minor->dev;
241 struct drm_i915_private *dev_priv = dev->dev_private; 241 struct drm_i915_private *dev_priv = dev->dev_private;
242 u32 val, rp_state_cap, hw_max, hw_min; 242 u32 val, rp_state_cap, hw_max, hw_min, non_oc_max;
243 ssize_t ret; 243 ssize_t ret;
244 244
245 ret = kstrtou32(buf, 0, &val); 245 ret = kstrtou32(buf, 0, &val);
@@ -251,7 +251,8 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
251 mutex_lock(&dev_priv->rps.hw_lock); 251 mutex_lock(&dev_priv->rps.hw_lock);
252 252
253 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); 253 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
254 hw_max = (rp_state_cap & 0xff); 254 hw_max = dev_priv->rps.hw_max;
255 non_oc_max = (rp_state_cap & 0xff);
255 hw_min = ((rp_state_cap & 0xff0000) >> 16); 256 hw_min = ((rp_state_cap & 0xff0000) >> 16);
256 257
257 if (val < hw_min || val > hw_max || val < dev_priv->rps.min_delay) { 258 if (val < hw_min || val > hw_max || val < dev_priv->rps.min_delay) {
@@ -259,6 +260,10 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
259 return -EINVAL; 260 return -EINVAL;
260 } 261 }
261 262
263 if (val > non_oc_max)
264 DRM_DEBUG("User requested overclocking to %d\n",
265 val * GT_FREQUENCY_MULTIPLIER);
266
262 if (dev_priv->rps.cur_delay > val) 267 if (dev_priv->rps.cur_delay > val)
263 gen6_set_rps(dev_priv->dev, val); 268 gen6_set_rps(dev_priv->dev, val);
264 269
@@ -302,7 +307,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
302 mutex_lock(&dev_priv->rps.hw_lock); 307 mutex_lock(&dev_priv->rps.hw_lock);
303 308
304 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); 309 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
305 hw_max = (rp_state_cap & 0xff); 310 hw_max = dev_priv->rps.hw_max;
306 hw_min = ((rp_state_cap & 0xff0000) >> 16); 311 hw_min = ((rp_state_cap & 0xff0000) >> 16);
307 312
308 if (val < hw_min || val > hw_max || val > dev_priv->rps.max_delay) { 313 if (val < hw_min || val > hw_max || val > dev_priv->rps.max_delay) {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 17f157a7b640..059c77367701 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2558,8 +2558,8 @@ static void gen6_enable_rps(struct drm_device *dev)
2558 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); 2558 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
2559 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); 2559 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
2560 2560
2561 /* In units of 100MHz */ 2561 /* In units of 50MHz */
2562 dev_priv->rps.max_delay = rp_state_cap & 0xff; 2562 dev_priv->rps.hw_max = dev_priv->rps.max_delay = rp_state_cap & 0xff;
2563 dev_priv->rps.min_delay = (rp_state_cap & 0xff0000) >> 16; 2563 dev_priv->rps.min_delay = (rp_state_cap & 0xff0000) >> 16;
2564 dev_priv->rps.cur_delay = 0; 2564 dev_priv->rps.cur_delay = 0;
2565 2565
@@ -2646,6 +2646,7 @@ static void gen6_enable_rps(struct drm_device *dev)
2646 DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max from %dMHz to %dMHz\n", 2646 DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max from %dMHz to %dMHz\n",
2647 (dev_priv->rps.max_delay & 0xff) * 50, 2647 (dev_priv->rps.max_delay & 0xff) * 50,
2648 (pcu_mbox & 0xff) * 50); 2648 (pcu_mbox & 0xff) * 50);
2649 dev_priv->rps.hw_max = pcu_mbox & 0xff;
2649 dev_priv->rps.max_delay = pcu_mbox & 0xff; 2650 dev_priv->rps.max_delay = pcu_mbox & 0xff;
2650 } 2651 }
2651 } else { 2652 } else {