drm/i915: Allow cdclk squasher to be reconfigured live

Supposedly we should be able to change the cdclk squasher waveform
even when many pipes are active. Make it so.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211119131348.725220-6-mika.kahola@intel.com
This commit is contained in:
Ville Syrjälä 2021-11-19 15:13:48 +02:00 committed by Stanislav Lisovskiy
parent 77ab3a1ecb
commit d4a2393049

View File

@ -1951,6 +1951,25 @@ static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv,
a->ref == b->ref;
}
static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv,
const struct intel_cdclk_config *a,
const struct intel_cdclk_config *b)
{
/*
* FIXME should store a bit more state in intel_cdclk_config
* to differentiate squasher vs. cd2x divider properly. For
* the moment all platforms with squasher use a fixed cd2x
* divider.
*/
if (!has_cdclk_squasher(dev_priv))
return false;
return a->cdclk != b->cdclk &&
a->vco != 0 &&
a->vco == b->vco &&
a->ref == b->ref;
}
/**
* intel_cdclk_needs_modeset - Determine if changong between the CDCLK
* configurations requires a modeset on all pipes
@ -1988,7 +2007,17 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv,
if (DISPLAY_VER(dev_priv) < 10 && !IS_BROXTON(dev_priv))
return false;
/*
* FIXME should store a bit more state in intel_cdclk_config
* to differentiate squasher vs. cd2x divider properly. For
* the moment all platforms with squasher use a fixed cd2x
* divider.
*/
if (has_cdclk_squasher(dev_priv))
return false;
return a->cdclk != b->cdclk &&
a->vco != 0 &&
a->vco == b->vco &&
a->ref == b->ref;
}
@ -2672,9 +2701,14 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
pipe = INVALID_PIPE;
}
if (intel_cdclk_can_crawl(dev_priv,
&old_cdclk_state->actual,
&new_cdclk_state->actual)) {
if (intel_cdclk_can_squash(dev_priv,
&old_cdclk_state->actual,
&new_cdclk_state->actual)) {
drm_dbg_kms(&dev_priv->drm,
"Can change cdclk via squasher\n");
} else 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) {