]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/dmc: Do not enable the pipe DMC on TGL when PSR is possible
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 17 Jun 2025 17:07:59 +0000 (20:07 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 23 Jun 2025 14:50:07 +0000 (17:50 +0300)
On TGL/derivatives the pipe DMC state is lost when PG1 is disabled,
and the main DMC does not restore any of it. This means the state will
also be lost during PSR+DC5/6. It seems safest to not even enable the
pipe DMC in that case (the main DMC does restore the pipe DMC enable
bit in PIPEDMC_CONTROL_A for some reason).

Since pipe DMC is only needed for "fast LACE" on these platforms we aren't
actually losing anything here. In the future if we do want to enable
"fast LACE" we'll just have to remember that it won't be compatible with
PSR.

Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250617170759.19552-10-ville.syrjala@linux.intel.com
drivers/gpu/drm/i915/display/intel_dmc.c

index 5cd68c2912fe83968deba8ab9c336ed752e1dcd7..4572e87d9bfa0bc7e23e8ab30de0cf66229a26a9 100644 (file)
@@ -699,6 +699,21 @@ static bool need_pipedmc_load_mmio(struct intel_display *display, enum pipe pipe
        return false;
 }
 
+static bool can_enable_pipedmc(const struct intel_crtc_state *crtc_state)
+{
+       struct intel_display *display = to_intel_display(crtc_state);
+
+       /*
+        * On TGL/derivatives pipe DMC state is lost when PG1 is disabled.
+        * Do not even enable the pipe DMC when that can happen outside
+        * of driver control (PSR+DC5/6).
+        */
+       if (DISPLAY_VER(display) == 12 && crtc_state->has_psr)
+               return false;
+
+       return true;
+}
+
 void intel_dmc_enable_pipe(const struct intel_crtc_state *crtc_state)
 {
        struct intel_display *display = to_intel_display(crtc_state);
@@ -709,6 +724,11 @@ void intel_dmc_enable_pipe(const struct intel_crtc_state *crtc_state)
        if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(display, dmc_id))
                return;
 
+       if (!can_enable_pipedmc(crtc_state)) {
+               intel_dmc_disable_pipe(crtc_state);
+               return;
+       }
+
        if (need_pipedmc_load_program(display))
                dmc_load_program(display, dmc_id);
        else if (need_pipedmc_load_mmio(display, pipe))