Commit d7ffaeef authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Use cdclk_state->voltage on BDW

Track the system agent voltage we request from pcode in the cdclk state
on BDW. Annoyingly we can't actually read out the current value since
there's no pcode command to do that, so we'll have to just assume that
it worked.

v2: Keep the WARN_ON (Rodrigo)
v3: s/voltage/voltage_level/ (Rodrigo)

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171024095216.1638-5-ville.syrjala@linux.intel.com
parent 999c5766
...@@ -639,6 +639,21 @@ static int bdw_calc_cdclk(int min_cdclk) ...@@ -639,6 +639,21 @@ static int bdw_calc_cdclk(int min_cdclk)
return 337500; return 337500;
} }
static u8 bdw_calc_voltage_level(int cdclk)
{
switch (cdclk) {
default:
case 337500:
return 2;
case 450000:
return 0;
case 540000:
return 1;
case 675000:
return 3;
}
}
static void bdw_get_cdclk(struct drm_i915_private *dev_priv, static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
struct intel_cdclk_state *cdclk_state) struct intel_cdclk_state *cdclk_state)
{ {
...@@ -657,13 +672,20 @@ static void bdw_get_cdclk(struct drm_i915_private *dev_priv, ...@@ -657,13 +672,20 @@ static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
cdclk_state->cdclk = 337500; cdclk_state->cdclk = 337500;
else else
cdclk_state->cdclk = 675000; cdclk_state->cdclk = 675000;
/*
* Can't read this out :( Let's assume it's
* at least what the CDCLK frequency requires.
*/
cdclk_state->voltage_level =
bdw_calc_voltage_level(cdclk_state->cdclk);
} }
static void bdw_set_cdclk(struct drm_i915_private *dev_priv, static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
const struct intel_cdclk_state *cdclk_state) const struct intel_cdclk_state *cdclk_state)
{ {
int cdclk = cdclk_state->cdclk; int cdclk = cdclk_state->cdclk;
uint32_t val, data; uint32_t val;
int ret; int ret;
if (WARN((I915_READ(LCPLL_CTL) & if (WARN((I915_READ(LCPLL_CTL) &
...@@ -704,19 +726,15 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv, ...@@ -704,19 +726,15 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
/* fall through */ /* fall through */
case 337500: case 337500:
val |= LCPLL_CLK_FREQ_337_5_BDW; val |= LCPLL_CLK_FREQ_337_5_BDW;
data = 2;
break; break;
case 450000: case 450000:
val |= LCPLL_CLK_FREQ_450; val |= LCPLL_CLK_FREQ_450;
data = 0;
break; break;
case 540000: case 540000:
val |= LCPLL_CLK_FREQ_54O_BDW; val |= LCPLL_CLK_FREQ_54O_BDW;
data = 1;
break; break;
case 675000: case 675000:
val |= LCPLL_CLK_FREQ_675_BDW; val |= LCPLL_CLK_FREQ_675_BDW;
data = 3;
break; break;
} }
...@@ -731,7 +749,8 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv, ...@@ -731,7 +749,8 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
DRM_ERROR("Switching back to LCPLL failed\n"); DRM_ERROR("Switching back to LCPLL failed\n");
mutex_lock(&dev_priv->pcu_lock); mutex_lock(&dev_priv->pcu_lock);
sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data); sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
cdclk_state->voltage_level);
mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->pcu_lock);
I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1); I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
...@@ -1910,11 +1929,15 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state) ...@@ -1910,11 +1929,15 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state)
cdclk = bdw_calc_cdclk(min_cdclk); cdclk = bdw_calc_cdclk(min_cdclk);
intel_state->cdclk.logical.cdclk = cdclk; intel_state->cdclk.logical.cdclk = cdclk;
intel_state->cdclk.logical.voltage_level =
bdw_calc_voltage_level(cdclk);
if (!intel_state->active_crtcs) { if (!intel_state->active_crtcs) {
cdclk = bdw_calc_cdclk(0); cdclk = bdw_calc_cdclk(0);
intel_state->cdclk.actual.cdclk = cdclk; intel_state->cdclk.actual.cdclk = cdclk;
intel_state->cdclk.actual.voltage_level =
bdw_calc_voltage_level(cdclk);
} else { } else {
intel_state->cdclk.actual = intel_state->cdclk.actual =
intel_state->cdclk.logical; intel_state->cdclk.logical;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment