@@ -1887,6 +1887,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val)
int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val);
int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val);
int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val);
+int vlv_gpu_freq(int ddr_freq, int val);
+int vlv_freq_opcode(int ddr_freq, int val);
#define __i915_read(x, y) \
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg);
@@ -4620,3 +4620,59 @@ int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val)
{
return vlv_punit_rw(dev_priv, PUNIT_OPCODE_REG_WRITE, addr, &val);
}
+
+int vlv_gpu_freq(int ddr_freq, int val)
+{
+ int mult, base;
+
+ switch (ddr_freq) {
+ case 800:
+ mult = 20;
+ base = 120;
+ break;
+ case 1066:
+ mult = 22;
+ base = 133;
+ break;
+ case 1333:
+ mult = 21;
+ base = 125;
+ break;
+ default:
+ return -1;
+ }
+
+ return ((val - 0xbd) * mult) + base;
+}
+
+int vlv_freq_opcode(int ddr_freq, int val)
+{
+ int mult, base;
+
+ switch (ddr_freq) {
+ case 800:
+ mult = 20;
+ base = 120;
+ break;
+ case 1066:
+ mult = 22;
+ base = 133;
+ break;
+ case 1333:
+ mult = 21;
+ base = 125;
+ break;
+ default:
+ return -1;
+ }
+
+ val /= mult;
+ val -= base / mult;
+ val += 0xbd;
+
+ if (val > 0xea)
+ val = 0xea;
+
+ return val;
+}
+
When requesting frequency changes or querying status from the Punit, we need to use an opcode that corresponds to the frequency, taking into account the memory frequency. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_pm.c | 56 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+)