@@ -1510,12 +1510,8 @@ static void cnl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco)
dev_priv->cdclk.hw.vco = vco;
}
-static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
- const struct intel_cdclk_state *cdclk_state)
+static int cnl_dvfs_pre_change(struct drm_i915_private *dev_priv)
{
- int cdclk = cdclk_state->cdclk;
- int vco = cdclk_state->vco;
- u32 val, divider, pcu_ack;
int ret;
mutex_lock(&dev_priv->rps.hw_lock);
@@ -1524,11 +1520,30 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
SKL_CDCLK_READY_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE, 3);
mutex_unlock(&dev_priv->rps.hw_lock);
- if (ret) {
+
+ if (ret)
DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n",
ret);
+
+ return ret;
+}
+
+static void cnl_dvfs_post_change(struct drm_i915_private *dev_priv, int level)
+{
+ mutex_lock(&dev_priv->rps.hw_lock);
+ sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, level);
+ mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
+static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
+ const struct intel_cdclk_state *cdclk_state)
+{
+ int cdclk = cdclk_state->cdclk;
+ int vco = cdclk_state->vco;
+ u32 val, divider, pcu_ack;
+
+ if (cnl_dvfs_pre_change(dev_priv))
return;
- }
/* cdclk = vco / 2 / div{1,2} */
switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
@@ -1575,9 +1590,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
I915_WRITE(CDCLK_CTL, val);
/* inform PCU of the change */
- mutex_lock(&dev_priv->rps.hw_lock);
- sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
- mutex_unlock(&dev_priv->rps.hw_lock);
+ cnl_dvfs_post_change(dev_priv, pcu_ack);
intel_update_cdclk(dev_priv);
}