drm/i915: Refactor vlv/chv GPU frequency divider setup
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 10 Nov 2014 20:55:12 +0000 (22:55 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Mon, 17 Nov 2014 14:33:51 +0000 (15:33 +0100)
The divider used in the GPU frequency calculations is compatible between
vlv and chv. vlv just wants doubled values compared to chv.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Deepak S<deepak.s@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_pm.c

index eaae801..feda281 100644 (file)
@@ -7206,99 +7206,65 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val)
        return 0;
 }
 
-static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
+static int vlv_gpu_freq_div(unsigned int czclk_freq)
 {
-       int div;
-
-       /* 4 x czclk */
-       switch (dev_priv->mem_freq) {
-       case 800:
-               div = 10;
-               break;
-       case 1066:
-               div = 12;
-               break;
-       case 1333:
-               div = 16;
-               break;
+       switch (czclk_freq) {
+       case 200:
+               return 10;
+       case 267:
+               return 12;
+       case 320:
+       case 333:
+       case 400:
+               return 16;
        default:
                return -1;
        }
+}
 
-       return DIV_ROUND_CLOSEST(dev_priv->mem_freq * (val + 6 - 0xbd), 4 * div);
+static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
+{
+       int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4);
+
+       div = vlv_gpu_freq_div(czclk_freq);
+       if (div < 0)
+               return div;
+
+       return DIV_ROUND_CLOSEST(czclk_freq * (val + 6 - 0xbd), div);
 }
 
 static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)
 {
-       int mul;
+       int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4);
 
-       /* 4 x czclk */
-       switch (dev_priv->mem_freq) {
-       case 800:
-               mul = 10;
-               break;
-       case 1066:
-               mul = 12;
-               break;
-       case 1333:
-               mul = 16;
-               break;
-       default:
-               return -1;
-       }
+       mul = vlv_gpu_freq_div(czclk_freq);
+       if (mul < 0)
+               return mul;
 
-       return DIV_ROUND_CLOSEST(4 * mul * val, dev_priv->mem_freq) + 0xbd - 6;
+       return DIV_ROUND_CLOSEST(mul * val, czclk_freq) + 0xbd - 6;
 }
 
 static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)
 {
-       int div, freq;
-
-       switch (dev_priv->rps.cz_freq) {
-       case 200:
-               div = 5;
-               break;
-       case 267:
-               div = 6;
-               break;
-       case 320:
-       case 333:
-       case 400:
-               div = 8;
-               break;
-       default:
-               return -1;
-       }
+       int div, czclk_freq = dev_priv->rps.cz_freq;
 
-       freq = (DIV_ROUND_CLOSEST((dev_priv->rps.cz_freq * val), 2 * div) / 2);
+       div = vlv_gpu_freq_div(czclk_freq) / 2;
+       if (div < 0)
+               return div;
 
-       return freq;
+       return DIV_ROUND_CLOSEST(czclk_freq * val, 2 * div) / 2;
 }
 
 static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
 {
-       int mul, opcode;
+       int mul, czclk_freq = dev_priv->rps.cz_freq;
 
-       switch (dev_priv->rps.cz_freq) {
-       case 200:
-               mul = 5;
-               break;
-       case 267:
-               mul = 6;
-               break;
-       case 320:
-       case 333:
-       case 400:
-               mul = 8;
-               break;
-       default:
-               return -1;
-       }
+       mul = vlv_gpu_freq_div(czclk_freq) / 2;
+       if (mul < 0)
+               return mul;
 
        /* CHV needs even values */
-       opcode = (DIV_ROUND_CLOSEST((val * 2 * mul), dev_priv->rps.cz_freq) * 2);
-
-       return opcode;
+       return DIV_ROUND_CLOSEST(val * 2 * mul, czclk_freq) * 2;
 }
 
 int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val)