diff mbox

[1/4] drm/i915: Improve vlv_gpu_freq() and vlv_freq_opcode()

Message ID 1383684151-595-2-git-send-email-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ville Syrjälä Nov. 5, 2013, 8:42 p.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

We're currently miscalculating the VLV graphics clock a little bit.
This is caused by rounding the step to integer MHz, which does not
match reality. Change the formula to match the GUnit HAS to give
more accurate answers.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 35 ++++++++++++-----------------------
 1 file changed, 12 insertions(+), 23 deletions(-)

Comments

Jesse Barnes Nov. 6, 2013, 4:56 p.m. UTC | #1
On Tue,  5 Nov 2013 22:42:28 +0200
ville.syrjala@linux.intel.com wrote:

> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> We're currently miscalculating the VLV graphics clock a little bit.
> This is caused by rounding the step to integer MHz, which does not
> match reality. Change the formula to match the GUnit HAS to give
> more accurate answers.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 35 ++++++++++++-----------------------
>  1 file changed, 12 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index a5778e5..865035b 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5947,57 +5947,46 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val)
>  
>  int vlv_gpu_freq(int ddr_freq, int val)
>  {
> -	int mult, base;
> +	int div;
>  
> +	/* 4 x czclk */
>  	switch (ddr_freq) {
>  	case 800:
> -		mult = 20;
> -		base = 120;
> +		div = 10;
>  		break;
>  	case 1066:
> -		mult = 22;
> -		base = 133;
> +		div = 12;
>  		break;
>  	case 1333:
> -		mult = 21;
> -		base = 125;
> +		div = 16;
>  		break;
>  	default:
>  		return -1;
>  	}
>  
> -	return ((val - 0xbd) * mult) + base;
> +	return DIV_ROUND_CLOSEST(ddr_freq * (val + 6 - 0xbd), 4 * div);
>  }
>  
>  int vlv_freq_opcode(int ddr_freq, int val)
>  {
> -	int mult, base;
> +	int mul;
>  
> +	/* 4 x czclk */
>  	switch (ddr_freq) {
>  	case 800:
> -		mult = 20;
> -		base = 120;
> +		mul = 10;
>  		break;
>  	case 1066:
> -		mult = 22;
> -		base = 133;
> +		mul = 12;
>  		break;
>  	case 1333:
> -		mult = 21;
> -		base = 125;
> +		mul = 16;
>  		break;
>  	default:
>  		return -1;
>  	}
>  
> -	val /= mult;
> -	val -= base / mult;
> -	val += 0xbd;
> -
> -	if (val > 0xea)
> -		val = 0xea;
> -
> -	return val;
> +	return DIV_ROUND_CLOSEST(4 * mul * val, ddr_freq) + 0xbd - 6;
>  }
>  
>  void intel_pm_init(struct drm_device *dev)

Yeah these values look better at 1066 and 1333.  No differences at 800
though.

Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a5778e5..865035b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5947,57 +5947,46 @@  int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val)
 
 int vlv_gpu_freq(int ddr_freq, int val)
 {
-	int mult, base;
+	int div;
 
+	/* 4 x czclk */
 	switch (ddr_freq) {
 	case 800:
-		mult = 20;
-		base = 120;
+		div = 10;
 		break;
 	case 1066:
-		mult = 22;
-		base = 133;
+		div = 12;
 		break;
 	case 1333:
-		mult = 21;
-		base = 125;
+		div = 16;
 		break;
 	default:
 		return -1;
 	}
 
-	return ((val - 0xbd) * mult) + base;
+	return DIV_ROUND_CLOSEST(ddr_freq * (val + 6 - 0xbd), 4 * div);
 }
 
 int vlv_freq_opcode(int ddr_freq, int val)
 {
-	int mult, base;
+	int mul;
 
+	/* 4 x czclk */
 	switch (ddr_freq) {
 	case 800:
-		mult = 20;
-		base = 120;
+		mul = 10;
 		break;
 	case 1066:
-		mult = 22;
-		base = 133;
+		mul = 12;
 		break;
 	case 1333:
-		mult = 21;
-		base = 125;
+		mul = 16;
 		break;
 	default:
 		return -1;
 	}
 
-	val /= mult;
-	val -= base / mult;
-	val += 0xbd;
-
-	if (val > 0xea)
-		val = 0xea;
-
-	return val;
+	return DIV_ROUND_CLOSEST(4 * mul * val, ddr_freq) + 0xbd - 6;
 }
 
 void intel_pm_init(struct drm_device *dev)