Skip to content

Commit

Permalink
drm/i915/adl_p: CDCLK crawl support for ADL
Browse files Browse the repository at this point in the history
CDCLK crawl feature allows to change CDCLK frequency
without disabling the actual PLL and doesn't require
a full modeset.

v2: - Added has_cdclk_crawl as a feature flag to
      intel_device_info(Matt Roper)
    - s/gen13_cdclk_pll_crawl/adlp_cdclk_pll_crawl/
      (Matt Roper)

Cc: Mika Kahola <mika.kahola@intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Signed-off-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210603065038.7298-1-stanislav.lisovskiy@intel.com
  • Loading branch information
Stanislav Lisovskiy authored and Jani Nikula committed Jun 9, 2021
1 parent 5131743 commit d62686b
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 9 deletions.
72 changes: 63 additions & 9 deletions drivers/gpu/drm/i915/display/intel_cdclk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1548,6 +1548,35 @@ static void cnl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco)
dev_priv->cdclk.hw.vco = vco;
}

static bool has_cdclk_crawl(struct drm_i915_private *i915)
{
return INTEL_INFO(i915)->has_cdclk_crawl;
}

static void adlp_cdclk_pll_crawl(struct drm_i915_private *dev_priv, int vco)
{
int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk.hw.ref);
u32 val;

/* Write PLL ratio without disabling */
val = CNL_CDCLK_PLL_RATIO(ratio) | BXT_DE_PLL_PLL_ENABLE;
intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);

/* Submit freq change request */
val |= BXT_DE_PLL_FREQ_REQ;
intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);

/* Timeout 200us */
if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE,
BXT_DE_PLL_LOCK | BXT_DE_PLL_FREQ_REQ_ACK, 1))
DRM_ERROR("timeout waiting for FREQ change request ack\n");

val &= ~BXT_DE_PLL_FREQ_REQ;
intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);

dev_priv->cdclk.hw.vco = vco;
}

static u32 bxt_cdclk_cd2x_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
{
if (DISPLAY_VER(dev_priv) >= 12) {
Expand Down Expand Up @@ -1620,14 +1649,16 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
return;
}

if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) {
if (has_cdclk_crawl(dev_priv) && dev_priv->cdclk.hw.vco > 0 && vco > 0) {
if (dev_priv->cdclk.hw.vco != vco)
adlp_cdclk_pll_crawl(dev_priv, vco);
} else if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) {
if (dev_priv->cdclk.hw.vco != 0 &&
dev_priv->cdclk.hw.vco != vco)
cnl_cdclk_pll_disable(dev_priv);

if (dev_priv->cdclk.hw.vco != vco)
cnl_cdclk_pll_enable(dev_priv, vco);

} else {
if (dev_priv->cdclk.hw.vco != 0 &&
dev_priv->cdclk.hw.vco != vco)
Expand Down Expand Up @@ -1820,6 +1851,28 @@ void intel_cdclk_uninit_hw(struct drm_i915_private *i915)
skl_cdclk_uninit_hw(i915);
}

static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv,
const struct intel_cdclk_config *a,
const struct intel_cdclk_config *b)
{
int a_div, b_div;

if (!has_cdclk_crawl(dev_priv))
return false;

/*
* The vco and cd2x divider will change independently
* from each, so we disallow cd2x change when crawling.
*/
a_div = DIV_ROUND_CLOSEST(a->vco, a->cdclk);
b_div = DIV_ROUND_CLOSEST(b->vco, b->cdclk);

return a->vco != 0 && b->vco != 0 &&
a->vco != b->vco &&
a_div == b_div &&
a->ref == b->ref;
}

/**
* intel_cdclk_needs_modeset - Determine if changong between the CDCLK
* configurations requires a modeset on all pipes
Expand Down Expand Up @@ -2475,7 +2528,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
const struct intel_cdclk_state *old_cdclk_state;
struct intel_cdclk_state *new_cdclk_state;
enum pipe pipe;
enum pipe pipe = INVALID_PIPE;
int ret;

new_cdclk_state = intel_atomic_get_cdclk_state(state);
Expand Down Expand Up @@ -2527,15 +2580,18 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)

if (drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
pipe = INVALID_PIPE;
} else {
pipe = INVALID_PIPE;
}

if (pipe != INVALID_PIPE) {
if (intel_cdclk_can_crawl(dev_priv,
&old_cdclk_state->actual,
&new_cdclk_state->actual)) {
drm_dbg_kms(&dev_priv->drm,
"Can change cdclk via crawl\n");
} else if (pipe != INVALID_PIPE) {
new_cdclk_state->pipe = pipe;

drm_dbg_kms(&dev_priv->drm,
"Can change cdclk with pipe %c active\n",
"Can change cdclk cd2x divider with pipe %c active\n",
pipe_name(pipe));
} else if (intel_cdclk_needs_modeset(&old_cdclk_state->actual,
&new_cdclk_state->actual)) {
Expand All @@ -2544,8 +2600,6 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
if (ret)
return ret;

new_cdclk_state->pipe = INVALID_PIPE;

drm_dbg_kms(&dev_priv->drm,
"Modeset required for cdclk change\n");
}
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,7 @@ static const struct intel_device_info adl_p_info = {
GEN12_FEATURES,
XE_LPD_FEATURES,
PLATFORM(INTEL_ALDERLAKE_P),
.has_cdclk_crawl = 1,
.require_force_probe = 1,
.display.has_modular_fia = 1,
.platform_engine_mask =
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -10981,6 +10981,8 @@ enum skl_power_gate {
#define BXT_DE_PLL_ENABLE _MMIO(0x46070)
#define BXT_DE_PLL_PLL_ENABLE (1 << 31)
#define BXT_DE_PLL_LOCK (1 << 30)
#define BXT_DE_PLL_FREQ_REQ (1 << 23)
#define BXT_DE_PLL_FREQ_REQ_ACK (1 << 22)
#define CNL_CDCLK_PLL_RATIO(x) (x)
#define CNL_CDCLK_PLL_RATIO_MASK 0xff

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/intel_device_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ struct intel_device_info {

u8 abox_mask;

u8 has_cdclk_crawl; /* does support CDCLK crawling */

#define DEFINE_FLAG(name) u8 name:1
DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG);
#undef DEFINE_FLAG
Expand Down

0 comments on commit d62686b

Please sign in to comment.