]> git.itanic.dy.fi Git - linux-stable/commitdiff
drm/i915/cdclk: Fix CDCLK programming order when pipes are active
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 2 Apr 2024 15:50:03 +0000 (18:50 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Apr 2024 09:23:41 +0000 (11:23 +0200)
commit 7b1f6b5aaec0f849e19c3e99d4eea75876853cdd upstream.

Currently we always reprogram CDCLK from the
intel_set_cdclk_pre_plane_update() when using squash/crawl.
The code only works correctly for the cd2x update or full
modeset cases, and it was simply never updated to deal with
squash/crawl.

If the CDCLK frequency is increasing we must reprogram it
before we do anything else that might depend on the new
higher frequency, and conversely we must not decrease
the frequency until everything that might still depend
on the old higher frequency has been dealt with.

Since cdclk_state->pipe is only relevant when doing a cd2x
update we can't use it to determine the correct sequence
during squash/crawl. To that end introduce cdclk_state->disable_pipes
which simply indicates that we must perform the update
while the pipes are disable (ie. during
intel_set_cdclk_pre_plane_update()). Otherwise we use the
same old vs. new CDCLK frequency comparsiong as for cd2x
updates.

The only remaining problem case is when the voltage_level
needs to increase due to a DDI port, but the CDCLK frequency
is decreasing (and not all pipes are being disabled). The
current approach will not bump the voltage level up until
after the port has already been enabled, which is too late.
But we'll take care of that case separately.

v2: Don't break the "must disable pipes case"
v3: Keep the on stack 'pipe' for future use

Cc: stable@vger.kernel.org
Fixes: d62686ba3b54 ("drm/i915/adl_p: CDCLK crawl support for ADL")
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240402155016.13733-2-ville.syrjala@linux.intel.com
(cherry picked from commit 3aecee90ac12a351905f12dda7643d5b0676d6ca)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/i915/display/intel_cdclk.c
drivers/gpu/drm/i915/display/intel_cdclk.h

index c985ebb6831a3755d14548d9925839cb426bb52d..6e36a15284537e1019671a852ba72033e4a4d651 100644 (file)
@@ -2521,7 +2521,7 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)
        if (IS_DG2(i915))
                intel_cdclk_pcode_pre_notify(state);
 
-       if (pipe == INVALID_PIPE ||
+       if (new_cdclk_state->disable_pipes ||
            old_cdclk_state->actual.cdclk <= new_cdclk_state->actual.cdclk) {
                drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
 
@@ -2553,7 +2553,7 @@ intel_set_cdclk_post_plane_update(struct intel_atomic_state *state)
        if (IS_DG2(i915))
                intel_cdclk_pcode_post_notify(state);
 
-       if (pipe != INVALID_PIPE &&
+       if (!new_cdclk_state->disable_pipes &&
            old_cdclk_state->actual.cdclk > new_cdclk_state->actual.cdclk) {
                drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
 
@@ -3036,6 +3036,7 @@ static struct intel_global_state *intel_cdclk_duplicate_state(struct intel_globa
                return NULL;
 
        cdclk_state->pipe = INVALID_PIPE;
+       cdclk_state->disable_pipes = false;
 
        return &cdclk_state->base;
 }
@@ -3214,6 +3215,8 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
                if (ret)
                        return ret;
 
+               new_cdclk_state->disable_pipes = true;
+
                drm_dbg_kms(&dev_priv->drm,
                            "Modeset required for cdclk change\n");
        }
index 48fd7d39e0cd9c4f6d57970f35531b91aa6ab055..71bc032bfef16efd359757373f256dfc88bd86fc 100644 (file)
@@ -51,6 +51,9 @@ struct intel_cdclk_state {
 
        /* bitmask of active pipes */
        u8 active_pipes;
+
+       /* update cdclk with pipes disabled */
+       bool disable_pipes;
 };
 
 int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state);