]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/dp_mst: Recompute all MST link CRTCs if DSC gets enabled on the link
authorImre Deak <imre.deak@intel.com>
Wed, 15 Oct 2025 16:19:33 +0000 (19:19 +0300)
committerImre Deak <imre.deak@intel.com>
Fri, 17 Oct 2025 18:48:52 +0000 (21:48 +0300)
The state of all the CRTCs on an MST link must be recomputed, if DSC
gets enabled on any of the CRTCs on the link. For instance an MST
docking station's Panel Replay capability may depend on whether DSC is
enabled on any of the dock's streams (aka CRTCs). To assist the Panel
Replay state computation for a CRTC based on the above, track in the
CRTC state if DSC is enabled on any CRTC on an MST link.

The intel_link_bw_limits::force_fec_pipes mask is used for a reason
similar to the above: enable FEC on all CRTCs of a non-UHBR (8b10b) MST
link if DSC is enabled on any of the link's CRTCs. The FEC enabled state
for a CRTC doesn't indicate if DSC is enabled on a UHBR MST link (FEC is
always enabled by the HW for UHBR, hence it's not tracked by the
intel_crtc_state::fec_enable flag for such links, where this flag is
always false).

Based on the above, to be able to determine the DSC state on both
non-UHBR and UHBR MST links, track the more generic DSC-enabled-on-link
state (instead of the FEC-enabled-on-link state) for each CRTC in
intel_link_bw_limits.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
Link: https://lore.kernel.org/r/20251015161934.262108-7-imre.deak@intel.com
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/display/intel_dp_mst.c
drivers/gpu/drm/i915/display/intel_link_bw.c
drivers/gpu/drm/i915/display/intel_link_bw.h

index bbb6ff929d6429154e193d267d8a5d44e8a2e0ef..a8b4619de347301aa1fd933a98f87db36d41f8ee 100644 (file)
@@ -4603,7 +4603,7 @@ intel_modeset_pipe_config(struct intel_atomic_state *state,
        if (ret)
                return ret;
 
-       crtc_state->fec_enable = limits->force_fec_pipes & BIT(crtc->pipe);
+       crtc_state->dsc.compression_enabled_on_link = limits->link_dsc_pipes & BIT(crtc->pipe);
        crtc_state->max_link_bpp_x16 = limits->max_bpp_x16[crtc->pipe];
 
        if (crtc_state->pipe_bpp > fxp_q4_to_int(crtc_state->max_link_bpp_x16)) {
index 0cbb4c3a8e22f705e8f6931e9240eefa5eb5e877..a845b2612a3fa8c0bc3c42704f2702994cca25e1 100644 (file)
@@ -814,14 +814,14 @@ static u8 get_pipes_downstream_of_mst_port(struct intel_atomic_state *state,
        return mask;
 }
 
-static int intel_dp_mst_check_fec_change(struct intel_atomic_state *state,
+static int intel_dp_mst_check_dsc_change(struct intel_atomic_state *state,
                                         struct drm_dp_mst_topology_mgr *mst_mgr,
                                         struct intel_link_bw_limits *limits)
 {
        struct intel_display *display = to_intel_display(state);
        struct intel_crtc *crtc;
        u8 mst_pipe_mask;
-       u8 fec_pipe_mask = 0;
+       u8 dsc_pipe_mask = 0;
        int ret;
 
        mst_pipe_mask = get_pipes_downstream_of_mst_port(state, mst_mgr, NULL);
@@ -834,16 +834,16 @@ static int intel_dp_mst_check_fec_change(struct intel_atomic_state *state,
                if (drm_WARN_ON(display->drm, !crtc_state))
                        return -EINVAL;
 
-               if (crtc_state->fec_enable)
-                       fec_pipe_mask |= BIT(crtc->pipe);
+               if (intel_dsc_enabled_on_link(crtc_state))
+                       dsc_pipe_mask |= BIT(crtc->pipe);
        }
 
-       if (!fec_pipe_mask || mst_pipe_mask == fec_pipe_mask)
+       if (!dsc_pipe_mask || mst_pipe_mask == dsc_pipe_mask)
                return 0;
 
-       limits->force_fec_pipes |= mst_pipe_mask;
+       limits->link_dsc_pipes |= mst_pipe_mask;
 
-       ret = intel_modeset_pipes_in_mask_early(state, "MST FEC",
+       ret = intel_modeset_pipes_in_mask_early(state, "MST DSC",
                                                mst_pipe_mask);
 
        return ret ? : -EAGAIN;
@@ -897,7 +897,7 @@ int intel_dp_mst_atomic_check_link(struct intel_atomic_state *state,
        int i;
 
        for_each_new_mst_mgr_in_state(&state->base, mgr, mst_state, i) {
-               ret = intel_dp_mst_check_fec_change(state, mgr, limits);
+               ret = intel_dp_mst_check_dsc_change(state, mgr, limits);
                if (ret)
                        return ret;
 
index f52dee0ea412f164ff6757520417c90f6d95c924..d2862de894fa7f778bff12a755d7227d5ec99b38 100644 (file)
@@ -20,6 +20,7 @@
 #include "intel_dp_tunnel.h"
 #include "intel_fdi.h"
 #include "intel_link_bw.h"
+#include "intel_vdsc.h"
 
 static int get_forced_link_bpp_x16(struct intel_atomic_state *state,
                                   const struct intel_crtc *crtc)
@@ -55,7 +56,7 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state,
        struct intel_display *display = to_intel_display(state);
        enum pipe pipe;
 
-       limits->force_fec_pipes = 0;
+       limits->link_dsc_pipes = 0;
        limits->bpp_limit_reached_pipes = 0;
        for_each_pipe(display, pipe) {
                struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
@@ -65,8 +66,8 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state,
 
                if (state->base.duplicated && crtc_state) {
                        limits->max_bpp_x16[pipe] = crtc_state->max_link_bpp_x16;
-                       if (crtc_state->fec_enable)
-                               limits->force_fec_pipes |= BIT(pipe);
+                       if (intel_dsc_enabled_on_link(crtc_state))
+                               limits->link_dsc_pipes |= BIT(pipe);
                } else {
                        limits->max_bpp_x16[pipe] = INT_MAX;
                }
@@ -265,10 +266,10 @@ assert_link_limit_change_valid(struct intel_display *display,
        bool bpps_changed = false;
        enum pipe pipe;
 
-       /* FEC can't be forced off after it was forced on. */
+       /* DSC can't be disabled after it was enabled. */
        if (drm_WARN_ON(display->drm,
-                       (old_limits->force_fec_pipes & new_limits->force_fec_pipes) !=
-                       old_limits->force_fec_pipes))
+                       (old_limits->link_dsc_pipes & new_limits->link_dsc_pipes) !=
+                       old_limits->link_dsc_pipes))
                return false;
 
        for_each_pipe(display, pipe) {
@@ -286,8 +287,8 @@ assert_link_limit_change_valid(struct intel_display *display,
        /* At least one limit must change. */
        if (drm_WARN_ON(display->drm,
                        !bpps_changed &&
-                       new_limits->force_fec_pipes ==
-                       old_limits->force_fec_pipes))
+                       new_limits->link_dsc_pipes ==
+                       old_limits->link_dsc_pipes))
                return false;
 
        return true;
index 95ab7c50c61d05424afb78fe529096b2be5040c9..cb18e171037cff6b773aadfb50a133eee3b9ab31 100644 (file)
@@ -15,7 +15,7 @@ struct intel_connector;
 struct intel_crtc_state;
 
 struct intel_link_bw_limits {
-       u8 force_fec_pipes;
+       u8 link_dsc_pipes;
        u8 bpp_limit_reached_pipes;
        /* in 1/16 bpp units */
        int max_bpp_x16[I915_MAX_PIPES];