aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_pm.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2013-11-05 15:42:28 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-11-06 12:05:20 -0500
commit07ab118b393410c65146f44c17b0ae5373eb972e (patch)
tree0ad0fd4e2a99f2151cc9de35f8beec9c2f70deb0 /drivers/gpu/drm/i915/intel_pm.c
parentc164f833cc842b427f817c3a6f30d806b1d57ef1 (diff)
drm/i915: Improve vlv_gpu_freq() and vlv_freq_opcode()
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> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> 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.c35
1 files changed, 12 insertions, 23 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a5778e59cc15..865035beccc7 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)
5947 5947
5948int vlv_gpu_freq(int ddr_freq, int val) 5948int vlv_gpu_freq(int ddr_freq, int val)
5949{ 5949{
5950 int mult, base; 5950 int div;
5951 5951
5952 /* 4 x czclk */
5952 switch (ddr_freq) { 5953 switch (ddr_freq) {
5953 case 800: 5954 case 800:
5954 mult = 20; 5955 div = 10;
5955 base = 120;
5956 break; 5956 break;
5957 case 1066: 5957 case 1066:
5958 mult = 22; 5958 div = 12;
5959 base = 133;
5960 break; 5959 break;
5961 case 1333: 5960 case 1333:
5962 mult = 21; 5961 div = 16;
5963 base = 125;
5964 break; 5962 break;
5965 default: 5963 default:
5966 return -1; 5964 return -1;
5967 } 5965 }
5968 5966
5969 return ((val - 0xbd) * mult) + base; 5967 return DIV_ROUND_CLOSEST(ddr_freq * (val + 6 - 0xbd), 4 * div);
5970} 5968}
5971 5969
5972int vlv_freq_opcode(int ddr_freq, int val) 5970int vlv_freq_opcode(int ddr_freq, int val)
5973{ 5971{
5974 int mult, base; 5972 int mul;
5975 5973
5974 /* 4 x czclk */
5976 switch (ddr_freq) { 5975 switch (ddr_freq) {
5977 case 800: 5976 case 800:
5978 mult = 20; 5977 mul = 10;
5979 base = 120;
5980 break; 5978 break;
5981 case 1066: 5979 case 1066:
5982 mult = 22; 5980 mul = 12;
5983 base = 133;
5984 break; 5981 break;
5985 case 1333: 5982 case 1333:
5986 mult = 21; 5983 mul = 16;
5987 base = 125;
5988 break; 5984 break;
5989 default: 5985 default:
5990 return -1; 5986 return -1;
5991 } 5987 }
5992 5988
5993 val /= mult; 5989 return DIV_ROUND_CLOSEST(4 * mul * val, ddr_freq) + 0xbd - 6;
5994 val -= base / mult;
5995 val += 0xbd;
5996
5997 if (val > 0xea)
5998 val = 0xea;
5999
6000 return val;
6001} 5990}
6002 5991
6003void intel_pm_init(struct drm_device *dev) 5992void intel_pm_init(struct drm_device *dev)