]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/dp: Calculate DSC slice count based on per-slice peak throughput
authorImre Deak <imre.deak@intel.com>
Tue, 30 Sep 2025 18:24:47 +0000 (21:24 +0300)
committerImre Deak <imre.deak@intel.com>
Thu, 2 Oct 2025 15:51:36 +0000 (18:51 +0300)
Use the DSC sink device's actual per-slice peak throughput to calculate
the minimum number of required DSC slices, falling back to the
hard-coded throughput values (as suggested by the DP Standard) if the
device's reported throughput value is 0.

For now use the minimum of the two throughput values, which is ok,
potentially resulting in a higher than required minimum slice count.
This doesn't change the current way of using the same minimum throughput
value regardless of the RGB/YUV output format used.

While at it add a TODO comment for MST tiled displays to calculate the
slice count for these based on the total pixel rate of all the tiles.

v2: Use drm helpers to query the throughput caps. (Ville)
v3: Add TODO comment to account for MST tiled displays. (Ville)

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reported-and-tested-by: Swati Sharma <swati2.sharma@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Link: https://lore.kernel.org/r/20250930182450.563016-4-imre.deak@intel.com
drivers/gpu/drm/i915/display/intel_dp.c

index 2eab591a8ef5681419e11b0fcc89c1a37e9d0db0..491a804c1f6a0d92278662616dc365dd371aa81e 100644 (file)
 #include "intel_vdsc.h"
 #include "intel_vrr.h"
 
-/* DP DSC throughput values used for slice count calculations KPixels/s */
-#define DP_DSC_PEAK_PIXEL_RATE                 2720000
-#define DP_DSC_MAX_ENC_THROUGHPUT_0            340000
-#define DP_DSC_MAX_ENC_THROUGHPUT_1            400000
-
 /* Max DSC line buffer depth supported by HW. */
 #define INTEL_DP_DSC_MAX_LINE_BUF_DEPTH                13
 
@@ -1018,13 +1013,29 @@ u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector,
        struct intel_display *display = to_intel_display(connector);
        u8 min_slice_count, i;
        int max_slice_width;
+       int tp_rgb_yuv444;
+       int tp_yuv422_420;
 
-       if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
-               min_slice_count = DIV_ROUND_UP(mode_clock,
-                                              DP_DSC_MAX_ENC_THROUGHPUT_0);
-       else
-               min_slice_count = DIV_ROUND_UP(mode_clock,
-                                              DP_DSC_MAX_ENC_THROUGHPUT_1);
+       /*
+        * TODO: Pass the total pixel rate of all the streams transferred to
+        * an MST tiled display, calculate the total slice count for all tiles
+        * from this and the per-tile slice count from the total slice count.
+        */
+       tp_rgb_yuv444 = drm_dp_dsc_sink_max_slice_throughput(connector->dp.dsc_dpcd,
+                                                            mode_clock, true);
+       tp_yuv422_420 = drm_dp_dsc_sink_max_slice_throughput(connector->dp.dsc_dpcd,
+                                                            mode_clock, false);
+
+       /*
+        * TODO: Use the throughput value specific to the actual RGB/YUV
+        * format of the output.
+        * For now use the smaller of these, which is ok, potentially
+        * resulting in a higher than required minimum slice count.
+        * The RGB/YUV444 throughput value should be always either equal
+        * or smaller than the YUV422/420 value, but let's not depend on
+        * this assumption.
+        */
+       min_slice_count = DIV_ROUND_UP(mode_clock, min(tp_rgb_yuv444, tp_yuv422_420));
 
        /*
         * Due to some DSC engine BW limitations, we need to enable second