Skip to content

Commit

Permalink
drm/i915/cnl: Implement .get_display_clock_speed() for CNL
Browse files Browse the repository at this point in the history
Add support for reading out the cdclk frequency from the hardware on
CNL. Very similar to BXT, with a few new twists and turns:
* the PLL is now called CDCLK PLL, not DE PLL
* reference clock can be 24 MHz in addition to the 19.2 MHz BXT had
* the ratio now lives in the PLL enable register
* Only 1x and 2x CD2X dividers are supported

v2: Deal with PLL lock bit the same way as BXT/SKL do now
v3: DSSM refclk indicator is bit 31 not 24 (Ander)
v4: Rebased by Rodrigo after Ville's cdclk rework.
v5: Set cdclk to the ref clock as previous platforms. (Imre)

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1497047175-27250-1-git-send-email-rodrigo.vivi@intel.com
  • Loading branch information
Ville Syrjälä authored and Rodrigo Vivi committed Jun 12, 2017
1 parent 7d025e0 commit 945f267
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
5 changes: 5 additions & 0 deletions drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -6550,6 +6550,9 @@ enum {
#define SKL_DFSM_PIPE_B_DISABLE (1 << 21)
#define SKL_DFSM_PIPE_C_DISABLE (1 << 28)

#define SKL_DSSM _MMIO(0x51004)
#define CNL_DSSM_CDCLK_PLL_REFCLK_24MHz (1 << 31)

#define GEN7_FF_SLICE_CS_CHICKEN1 _MMIO(0x20e0)
#define GEN9_FFSC_PERCTX_PREEMPT_CTRL (1<<14)

Expand Down Expand Up @@ -8116,6 +8119,8 @@ enum {
#define BXT_DE_PLL_ENABLE _MMIO(0x46070)
#define BXT_DE_PLL_PLL_ENABLE (1 << 31)
#define BXT_DE_PLL_LOCK (1 << 30)
#define CNL_CDCLK_PLL_RATIO(x) (x)
#define CNL_CDCLK_PLL_RATIO_MASK 0xff

/* GEN9 DC */
#define DC_STATE_EN _MMIO(0x45504)
Expand Down
56 changes: 55 additions & 1 deletion drivers/gpu/drm/i915/intel_cdclk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,58 @@ void bxt_uninit_cdclk(struct drm_i915_private *dev_priv)
bxt_set_cdclk(dev_priv, &cdclk_state);
}

static void cnl_cdclk_pll_update(struct drm_i915_private *dev_priv,
struct intel_cdclk_state *cdclk_state)
{
u32 val;

if (I915_READ(SKL_DSSM) & CNL_DSSM_CDCLK_PLL_REFCLK_24MHz)
cdclk_state->ref = 24000;
else
cdclk_state->ref = 19200;

cdclk_state->vco = 0;

val = I915_READ(BXT_DE_PLL_ENABLE);
if ((val & BXT_DE_PLL_PLL_ENABLE) == 0)
return;

if (WARN_ON((val & BXT_DE_PLL_LOCK) == 0))
return;

cdclk_state->vco = (val & CNL_CDCLK_PLL_RATIO_MASK) * cdclk_state->ref;
}

static void cnl_get_cdclk(struct drm_i915_private *dev_priv,
struct intel_cdclk_state *cdclk_state)
{
u32 divider;
int div;

cnl_cdclk_pll_update(dev_priv, cdclk_state);

cdclk_state->cdclk = cdclk_state->ref;

if (cdclk_state->vco == 0)
return;

divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;

switch (divider) {
case BXT_CDCLK_CD2X_DIV_SEL_1:
div = 2;
break;
case BXT_CDCLK_CD2X_DIV_SEL_2:
div = 4;
break;
default:
MISSING_CASE(divider);
return;
}

cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div);
}

/**
* intel_cdclk_state_compare - Determine if two CDCLK states differ
* @a: first CDCLK state
Expand Down Expand Up @@ -1895,7 +1947,9 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
skl_modeset_calc_cdclk;
}

if (IS_GEN9_BC(dev_priv))
if (IS_CANNONLAKE(dev_priv))
dev_priv->display.get_cdclk = cnl_get_cdclk;
else if (IS_GEN9_BC(dev_priv))
dev_priv->display.get_cdclk = skl_get_cdclk;
else if (IS_GEN9_LP(dev_priv))
dev_priv->display.get_cdclk = bxt_get_cdclk;
Expand Down

0 comments on commit 945f267

Please sign in to comment.