[Intel-gfx] [PATCH] drm/i915: Better overclock support

Mika Kuoppala mika.kuoppala at linux.intel.com
Tue Apr 9 15:42:09 CEST 2013


Ben Widawsky <ben at bwidawsk.net> writes:

> 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.
>
> Reported-by: freezer?
> Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c |  3 +++
>  drivers/gpu/drm/i915/i915_drv.h     |  1 +
>  drivers/gpu/drm/i915/i915_sysfs.c   | 12 ++++++++----
>  drivers/gpu/drm/i915/intel_pm.c     |  3 ++-
>  4 files changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 7df8351..f081bb3 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)
>  		max_freq = rp_state_cap & 0xff;
>  		seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
>  			   max_freq * GT_FREQUENCY_MULTIPLIER);
> +
> +		seq_printf(m, "Max overclocked frequency: %dMHz\n",
> +			   dev_priv->rps.hw_max * GT_FREQUENCY_MULTIPLIER);
>  	} else {
>  		seq_printf(m, "no P-state info available\n");
>  	}
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 1657d873..9b53b39c 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -648,6 +648,7 @@ struct intel_gen6_power_mgmt {
>  	u8 cur_delay;
>  	u8 min_delay;
>  	u8 max_delay;
> +	u8 hw_max;
>  
>  	struct delayed_work delayed_resume_work;
>  
> diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
> index a3a3e22..5faf1a7 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
>  	int ret;
>  
>  	mutex_lock(&dev_priv->rps.hw_lock);
> -	ret = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER;
> +	ret = dev_priv->rps.hw_max * GT_FREQUENCY_MULTIPLIER;
>  	mutex_unlock(&dev_priv->rps.hw_lock);
>  
>  	return snprintf(buf, PAGE_SIZE, "%d\n", ret);
> @@ -251,7 +251,7 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
>  	mutex_lock(&dev_priv->rps.hw_lock);
>  
>  	rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
> -	hw_max = (rp_state_cap & 0xff);
> +	hw_max = dev_priv->rps.hw_max;
>  	hw_min = ((rp_state_cap & 0xff0000) >> 16);
>  
>  	if (val < hw_min || val > hw_max || val < dev_priv->rps.min_delay) {
> @@ -290,7 +290,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
>  	struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
>  	struct drm_device *dev = minor->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	u32 val, rp_state_cap, hw_max, hw_min;
> +	u32 val, rp_state_cap, hw_max, hw_min, non_oc_max;
>  	ssize_t ret;
>  
>  	ret = kstrtou32(buf, 0, &val);
> @@ -302,7 +302,8 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
>  	mutex_lock(&dev_priv->rps.hw_lock);
>  
>  	rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
> -	hw_max = (rp_state_cap & 0xff);
> +	hw_max = dev_priv->rps.hw_max;
> +	non_oc_max = (rp_state_cap & 0xff);
>  	hw_min = ((rp_state_cap & 0xff0000) >> 16);
>  
>  	if (val < hw_min || val > hw_max || val > dev_priv->rps.max_delay) {
> @@ -310,6 +311,9 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
>  		return -EINVAL;
>  	}
>  
> +	if (val > non_oc_max)
> +		DRM_DEBUG("User selected overclocked frequency for min\n");
> +
>  	if (dev_priv->rps.cur_delay < val)
>  		gen6_set_rps(dev_priv->dev, val);
>  
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index ce3db2c..2edb743 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2555,7 +2555,7 @@ static void gen6_enable_rps(struct drm_device *dev)
>  	gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
>  
>  	/* In units of 100MHz */

Not a problem with this patch but the above comment should be
fixed as the freq is in units of 50Mhz right?

> -	dev_priv->rps.max_delay = rp_state_cap & 0xff;
> +	dev_priv->rps.hw_max = dev_priv->rps.max_delay = rp_state_cap & 0xff;
>  	dev_priv->rps.min_delay = (rp_state_cap & 0xff0000) >> 16;
>  	dev_priv->rps.cur_delay = 0;
>  
> @@ -2635,6 +2635,7 @@ static void gen6_enable_rps(struct drm_device *dev)
>  			DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max from %dMHz to %dMHz\n",
>  					 (dev_priv->rps.max_delay & 0xff) * 50,
>  					 (pcu_mbox & 0xff) * 50);
> +			dev_priv->rps.hw_max = pcu_mbox & 0xff;
>  			dev_priv->rps.max_delay = pcu_mbox & 0xff;
>  		}
>  	} else {
> -- 
> 1.8.2

Reviewed-by: Mika Kuoppala <mika.kuoppala at intel.com>



More information about the Intel-gfx mailing list