Skip to content

Commit

Permalink
drm/i915: Add tracking for CDCLK bypass frequency
Browse files Browse the repository at this point in the history
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: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180117172508.15993-1-imre.deak@intel.com
  • Loading branch information
Imre Deak committed Jan 18, 2018
1 parent 29d384e commit b6c51c3
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 18 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1791,7 +1791,7 @@ struct i915_oa_ops {
};

struct intel_cdclk_state {
unsigned int cdclk, vco, ref;
unsigned int cdclk, vco, ref, bypass;
u8 voltage_level;
};

Expand Down
35 changes: 18 additions & 17 deletions drivers/gpu/drm/i915/intel_cdclk.c
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ static void skl_get_cdclk(struct drm_i915_private *dev_priv,

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)
goto out;
Expand Down Expand Up @@ -1006,7 +1006,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
/* Choose frequency for this cdclk */
switch (cdclk) {
default:
WARN_ON(cdclk != dev_priv->cdclk.hw.ref);
WARN_ON(cdclk != dev_priv->cdclk.hw.bypass);
WARN_ON(vco != 0);
/* fall through */
case 308571:
Expand Down Expand Up @@ -1085,7 +1085,7 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)

/* Is PLL enabled and locked ? */
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;

/* DPLL okay; verify the cdclock
Expand Down Expand Up @@ -1159,7 +1159,7 @@ void skl_uninit_cdclk(struct drm_i915_private *dev_priv)
{
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.voltage_level = skl_calc_voltage_level(cdclk_state.cdclk);

Expand Down Expand Up @@ -1199,7 +1199,7 @@ static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
{
int ratio;

if (cdclk == dev_priv->cdclk.hw.ref)
if (cdclk == dev_priv->cdclk.hw.bypass)
return 0;

switch (cdclk) {
Expand All @@ -1224,7 +1224,7 @@ static int glk_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
{
int ratio;

if (cdclk == dev_priv->cdclk.hw.ref)
if (cdclk == dev_priv->cdclk.hw.bypass)
return 0;

switch (cdclk) {
Expand Down Expand Up @@ -1268,7 +1268,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,

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)
goto out;
Expand Down Expand Up @@ -1352,7 +1352,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
/* cdclk = vco / 2 / div{1,1.5,2,4} */
switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
default:
WARN_ON(cdclk != dev_priv->cdclk.hw.ref);
WARN_ON(cdclk != dev_priv->cdclk.hw.bypass);
WARN_ON(vco != 0);
/* fall through */
case 2:
Expand Down Expand Up @@ -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");

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;

/* DPLL okay; verify the cdclock
Expand Down Expand Up @@ -1514,7 +1514,7 @@ void bxt_uninit_cdclk(struct drm_i915_private *dev_priv)
{
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.voltage_level = bxt_calc_voltage_level(cdclk_state.cdclk);

Expand Down Expand Up @@ -1574,7 +1574,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv,

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)
goto out;
Expand Down Expand Up @@ -1660,7 +1660,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
/* cdclk = vco / 2 / div{1,2} */
switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
default:
WARN_ON(cdclk != dev_priv->cdclk.hw.ref);
WARN_ON(cdclk != dev_priv->cdclk.hw.bypass);
WARN_ON(vco != 0);
/* fall through */
case 2:
Expand Down Expand Up @@ -1705,7 +1705,7 @@ static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
{
int ratio;

if (cdclk == dev_priv->cdclk.hw.ref)
if (cdclk == dev_priv->cdclk.hw.bypass)
return 0;

switch (cdclk) {
Expand All @@ -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");

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;

/* DPLL okay; verify the cdclock
Expand Down Expand Up @@ -1805,7 +1805,7 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv)
{
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.voltage_level = cnl_calc_voltage_level(cdclk_state.cdclk);

Expand Down Expand Up @@ -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,
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,
cdclk_state->ref, cdclk_state->voltage_level);
cdclk_state->ref, cdclk_state->bypass,
cdclk_state->voltage_level);
}

/**
Expand Down

0 comments on commit b6c51c3

Please sign in to comment.