Commit b6c51c3e authored by Imre Deak's avatar Imre Deak

drm/i915: Add tracking for CDCLK bypass frequency

The CDCLK bypass frequency can vary on upcoming platforms, so prepare
for that now by tracking its value in the CDCLK state.

Currently on BDW+ the bypass frequency is always the reference clock and
I didn't bother with earlier platforms since it's not all that clear
what's the bypass clock on those.

I also didn't bother adding support for changing this frequency, since
atm I don't see any need for it.
Suggested-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180117172508.15993-1-imre.deak@intel.com
parent 29d384e3
...@@ -1791,7 +1791,7 @@ struct i915_oa_ops { ...@@ -1791,7 +1791,7 @@ struct i915_oa_ops {
}; };
struct intel_cdclk_state { struct intel_cdclk_state {
unsigned int cdclk, vco, ref; unsigned int cdclk, vco, ref, bypass;
u8 voltage_level; u8 voltage_level;
}; };
......
...@@ -858,7 +858,7 @@ static void skl_get_cdclk(struct drm_i915_private *dev_priv, ...@@ -858,7 +858,7 @@ static void skl_get_cdclk(struct drm_i915_private *dev_priv,
skl_dpll0_update(dev_priv, cdclk_state); skl_dpll0_update(dev_priv, cdclk_state);
cdclk_state->cdclk = cdclk_state->ref; cdclk_state->cdclk = cdclk_state->bypass = cdclk_state->ref;
if (cdclk_state->vco == 0) if (cdclk_state->vco == 0)
goto out; goto out;
...@@ -1006,7 +1006,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, ...@@ -1006,7 +1006,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
/* Choose frequency for this cdclk */ /* Choose frequency for this cdclk */
switch (cdclk) { switch (cdclk) {
default: default:
WARN_ON(cdclk != dev_priv->cdclk.hw.ref); WARN_ON(cdclk != dev_priv->cdclk.hw.bypass);
WARN_ON(vco != 0); WARN_ON(vco != 0);
/* fall through */ /* fall through */
case 308571: case 308571:
...@@ -1085,7 +1085,7 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv) ...@@ -1085,7 +1085,7 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
/* Is PLL enabled and locked ? */ /* Is PLL enabled and locked ? */
if (dev_priv->cdclk.hw.vco == 0 || if (dev_priv->cdclk.hw.vco == 0 ||
dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.ref) dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.bypass)
goto sanitize; goto sanitize;
/* DPLL okay; verify the cdclock /* DPLL okay; verify the cdclock
...@@ -1159,7 +1159,7 @@ void skl_uninit_cdclk(struct drm_i915_private *dev_priv) ...@@ -1159,7 +1159,7 @@ void skl_uninit_cdclk(struct drm_i915_private *dev_priv)
{ {
struct intel_cdclk_state cdclk_state = dev_priv->cdclk.hw; struct intel_cdclk_state cdclk_state = dev_priv->cdclk.hw;
cdclk_state.cdclk = cdclk_state.ref; cdclk_state.cdclk = cdclk_state.bypass;
cdclk_state.vco = 0; cdclk_state.vco = 0;
cdclk_state.voltage_level = skl_calc_voltage_level(cdclk_state.cdclk); cdclk_state.voltage_level = skl_calc_voltage_level(cdclk_state.cdclk);
...@@ -1199,7 +1199,7 @@ static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk) ...@@ -1199,7 +1199,7 @@ static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
{ {
int ratio; int ratio;
if (cdclk == dev_priv->cdclk.hw.ref) if (cdclk == dev_priv->cdclk.hw.bypass)
return 0; return 0;
switch (cdclk) { switch (cdclk) {
...@@ -1224,7 +1224,7 @@ static int glk_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk) ...@@ -1224,7 +1224,7 @@ static int glk_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
{ {
int ratio; int ratio;
if (cdclk == dev_priv->cdclk.hw.ref) if (cdclk == dev_priv->cdclk.hw.bypass)
return 0; return 0;
switch (cdclk) { switch (cdclk) {
...@@ -1268,7 +1268,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, ...@@ -1268,7 +1268,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
bxt_de_pll_update(dev_priv, cdclk_state); bxt_de_pll_update(dev_priv, cdclk_state);
cdclk_state->cdclk = cdclk_state->ref; cdclk_state->cdclk = cdclk_state->bypass = cdclk_state->ref;
if (cdclk_state->vco == 0) if (cdclk_state->vco == 0)
goto out; goto out;
...@@ -1352,7 +1352,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, ...@@ -1352,7 +1352,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
/* cdclk = vco / 2 / div{1,1.5,2,4} */ /* cdclk = vco / 2 / div{1,1.5,2,4} */
switch (DIV_ROUND_CLOSEST(vco, cdclk)) { switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
default: default:
WARN_ON(cdclk != dev_priv->cdclk.hw.ref); WARN_ON(cdclk != dev_priv->cdclk.hw.bypass);
WARN_ON(vco != 0); WARN_ON(vco != 0);
/* fall through */ /* fall through */
case 2: case 2:
...@@ -1425,7 +1425,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) ...@@ -1425,7 +1425,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
intel_dump_cdclk_state(&dev_priv->cdclk.hw, "Current CDCLK"); intel_dump_cdclk_state(&dev_priv->cdclk.hw, "Current CDCLK");
if (dev_priv->cdclk.hw.vco == 0 || if (dev_priv->cdclk.hw.vco == 0 ||
dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.ref) dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.bypass)
goto sanitize; goto sanitize;
/* DPLL okay; verify the cdclock /* DPLL okay; verify the cdclock
...@@ -1514,7 +1514,7 @@ void bxt_uninit_cdclk(struct drm_i915_private *dev_priv) ...@@ -1514,7 +1514,7 @@ void bxt_uninit_cdclk(struct drm_i915_private *dev_priv)
{ {
struct intel_cdclk_state cdclk_state = dev_priv->cdclk.hw; struct intel_cdclk_state cdclk_state = dev_priv->cdclk.hw;
cdclk_state.cdclk = cdclk_state.ref; cdclk_state.cdclk = cdclk_state.bypass;
cdclk_state.vco = 0; cdclk_state.vco = 0;
cdclk_state.voltage_level = bxt_calc_voltage_level(cdclk_state.cdclk); cdclk_state.voltage_level = bxt_calc_voltage_level(cdclk_state.cdclk);
...@@ -1574,7 +1574,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv, ...@@ -1574,7 +1574,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
cnl_cdclk_pll_update(dev_priv, cdclk_state); cnl_cdclk_pll_update(dev_priv, cdclk_state);
cdclk_state->cdclk = cdclk_state->ref; cdclk_state->cdclk = cdclk_state->bypass = cdclk_state->ref;
if (cdclk_state->vco == 0) if (cdclk_state->vco == 0)
goto out; goto out;
...@@ -1660,7 +1660,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv, ...@@ -1660,7 +1660,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
/* cdclk = vco / 2 / div{1,2} */ /* cdclk = vco / 2 / div{1,2} */
switch (DIV_ROUND_CLOSEST(vco, cdclk)) { switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
default: default:
WARN_ON(cdclk != dev_priv->cdclk.hw.ref); WARN_ON(cdclk != dev_priv->cdclk.hw.bypass);
WARN_ON(vco != 0); WARN_ON(vco != 0);
/* fall through */ /* fall through */
case 2: case 2:
...@@ -1705,7 +1705,7 @@ static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk) ...@@ -1705,7 +1705,7 @@ static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
{ {
int ratio; int ratio;
if (cdclk == dev_priv->cdclk.hw.ref) if (cdclk == dev_priv->cdclk.hw.bypass)
return 0; return 0;
switch (cdclk) { switch (cdclk) {
...@@ -1732,7 +1732,7 @@ static void cnl_sanitize_cdclk(struct drm_i915_private *dev_priv) ...@@ -1732,7 +1732,7 @@ static void cnl_sanitize_cdclk(struct drm_i915_private *dev_priv)
intel_dump_cdclk_state(&dev_priv->cdclk.hw, "Current CDCLK"); intel_dump_cdclk_state(&dev_priv->cdclk.hw, "Current CDCLK");
if (dev_priv->cdclk.hw.vco == 0 || if (dev_priv->cdclk.hw.vco == 0 ||
dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.ref) dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.bypass)
goto sanitize; goto sanitize;
/* DPLL okay; verify the cdclock /* DPLL okay; verify the cdclock
...@@ -1805,7 +1805,7 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv) ...@@ -1805,7 +1805,7 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
{ {
struct intel_cdclk_state cdclk_state = dev_priv->cdclk.hw; struct intel_cdclk_state cdclk_state = dev_priv->cdclk.hw;
cdclk_state.cdclk = cdclk_state.ref; cdclk_state.cdclk = cdclk_state.bypass;
cdclk_state.vco = 0; cdclk_state.vco = 0;
cdclk_state.voltage_level = cnl_calc_voltage_level(cdclk_state.cdclk); cdclk_state.voltage_level = cnl_calc_voltage_level(cdclk_state.cdclk);
...@@ -1846,9 +1846,10 @@ bool intel_cdclk_changed(const struct intel_cdclk_state *a, ...@@ -1846,9 +1846,10 @@ bool intel_cdclk_changed(const struct intel_cdclk_state *a,
void intel_dump_cdclk_state(const struct intel_cdclk_state *cdclk_state, void intel_dump_cdclk_state(const struct intel_cdclk_state *cdclk_state,
const char *context) const char *context)
{ {
DRM_DEBUG_DRIVER("%s %d kHz, VCO %d kHz, ref %d kHz, voltage level %d\n", DRM_DEBUG_DRIVER("%s %d kHz, VCO %d kHz, ref %d kHz, bypass %d kHz, voltage level %d\n",
context, cdclk_state->cdclk, cdclk_state->vco, context, cdclk_state->cdclk, cdclk_state->vco,
cdclk_state->ref, cdclk_state->voltage_level); cdclk_state->ref, cdclk_state->bypass,
cdclk_state->voltage_level);
} }
/** /**
......
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