drm/i915: Allow cdclk squasher to be reconfigured live
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 19 Nov 2021 13:13:48 +0000 (15:13 +0200)
committerStanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Tue, 7 Dec 2021 14:54:07 +0000 (16:54 +0200)
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
drivers/gpu/drm/i915/display/intel_cdclk.c

index 728263c..a5569f2 100644 (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) {