Commit 9a0a4ec5 authored by Anusha Srivatsa's avatar Anusha Srivatsa
Browse files

drm/i915/display: Add missing checks for cdclk crawling



cdclk_sanitize() function was written assuming vco was a signed integer.
vco gets assigned to -1 (essentially ~0) for the case where PLL
might be enabled and vco is not a frequency that will ever
get used. In such a scenario the right thing to do is disable the
PLL and re-enable it again with a valid frequency.
However the vco is declared as a unsigned variable.
With the above assumption, driver takes crawl path when not needed.
Add explicit check to not crawl in the case of an invalid PLL.

v2: Move the check from .h to .c (MattR)
- Move check to bxt_set_cdclk() instead of
intel_modeset_calc_cdclk() which is directly in
the path of the sanitize() function (Ville)

v3: remove unwanted parenthesis(Ville)

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Suggested-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarAnusha Srivatsa <anusha.srivatsa@intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221117230002.792096-1-anusha.srivatsa@intel.com
parent f322ed0d
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -1717,6 +1717,16 @@ static void dg2_cdclk_squash_program(struct drm_i915_private *i915,
	intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl);
}

static bool cdclk_pll_is_unknown(unsigned int vco)
{
	/*
	 * Ensure driver does not take the crawl path for the
	 * case when the vco is set to ~0 in the
	 * sanitize path.
	 */
	return vco == ~0;
}

static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
			  const struct intel_cdclk_config *cdclk_config,
			  enum pipe pipe)
@@ -1749,7 +1759,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
		return;
	}

	if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) {
	if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0 &&
	    !cdclk_pll_is_unknown(dev_priv->display.cdclk.hw.vco)) {
		if (dev_priv->display.cdclk.hw.vco != vco)
			adlp_cdclk_pll_crawl(dev_priv, vco);
	} else if (DISPLAY_VER(dev_priv) >= 11)