drm/i915/display: Add missing checks for cdclk crawling
authorAnusha Srivatsa <anusha.srivatsa@intel.com>
Thu, 17 Nov 2022 23:00:00 +0000 (15:00 -0800)
committerAnusha Srivatsa <anusha.srivatsa@intel.com>
Mon, 21 Nov 2022 22:37:30 +0000 (14:37 -0800)
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: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221117230002.792096-1-anusha.srivatsa@intel.com
drivers/gpu/drm/i915/display/intel_cdclk.c

index b74e36d..25d0127 100644 (file)
@@ -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)