drm/amd/display: Add stream overhead in BW calculations for 128b/132b
authorGeorge Shen <george.shen@amd.com>
Tue, 11 Apr 2023 00:00:46 +0000 (20:00 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 18 Jul 2023 15:15:45 +0000 (11:15 -0400)
[Why]
Current BW calculations do not account for the additional padding added
for uncompressed pixel-to-symbol packing.

This results in X.Y being too low for 128b/132b SST streams in certain
scenarios. If X.Y is too low, end user can observe image corruption.

[How]
Add function to calculate stream overhead to timing BW calculation for
128b/132b SST cases.

Reviewed-by: Wenjing Liu <wenjing.liu@amd.com>
Acked-by: Alan Liu <haoping.liu@amd.com>
Signed-off-by: George Shen <george.shen@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c

index e8c495f28484977d90f8e37006f1453c6b250da4..8a317b7717f780b34a075e5177d1ec6447fbd6f7 100644 (file)
@@ -1410,6 +1410,8 @@ struct dc_plane_state *dc_get_surface_for_mpcc(struct dc *dc,
 
 uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane);
 
+void dc_set_disable_128b_132b_stream_overhead(bool disable);
+
 /* The function returns minimum bandwidth required to drive a given timing
  * return - minimum required timing bandwidth in kbps.
  */
index 58dd62cce4bb9b473cb3197b8b9f7302dacde8a0..aed0d3dafa2472684a97a573e4701fd0f53a1921 100644 (file)
@@ -40,6 +40,8 @@ static bool dsc_policy_enable_dsc_when_not_needed;
 
 static bool dsc_policy_disable_dsc_stream_overhead;
 
+static bool disable_128b_132b_stream_overhead;
+
 #ifndef MAX
 #define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
 #endif
@@ -47,6 +49,41 @@ static bool dsc_policy_disable_dsc_stream_overhead;
 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
 #endif
 
+/* Need to account for padding due to pixel-to-symbol packing
+ * for uncompressed 128b/132b streams.
+ */
+static uint32_t apply_128b_132b_stream_overhead(
+       const struct dc_crtc_timing *timing, const uint32_t kbps)
+{
+       uint32_t total_kbps = kbps;
+
+       if (disable_128b_132b_stream_overhead)
+               return kbps;
+
+       if (!timing->flags.DSC) {
+               struct fixed31_32 bpp;
+               struct fixed31_32 overhead_factor;
+
+               bpp = dc_fixpt_from_int(kbps);
+               bpp = dc_fixpt_div_int(bpp, timing->pix_clk_100hz / 10);
+
+               /* Symbols_per_HActive = HActive * bpp / (4 lanes * 32-bit symbol size)
+                * Overhead_factor = ceil(Symbols_per_HActive) / Symbols_per_HActive
+                */
+               overhead_factor = dc_fixpt_from_int(timing->h_addressable);
+               overhead_factor = dc_fixpt_mul(overhead_factor, bpp);
+               overhead_factor = dc_fixpt_div_int(overhead_factor, 128);
+               overhead_factor = dc_fixpt_div(
+                       dc_fixpt_from_int(dc_fixpt_ceil(overhead_factor)),
+                       overhead_factor);
+
+               total_kbps = dc_fixpt_ceil(
+                       dc_fixpt_mul_int(overhead_factor, total_kbps));
+       }
+
+       return total_kbps;
+}
+
 uint32_t dc_bandwidth_in_kbps_from_timing(
        const struct dc_crtc_timing *timing)
 {
@@ -1165,6 +1202,11 @@ void dc_dsc_policy_set_disable_dsc_stream_overhead(bool disable)
        dsc_policy_disable_dsc_stream_overhead = disable;
 }
 
+void dc_set_disable_128b_132b_stream_overhead(bool disable)
+{
+       disable_128b_132b_stream_overhead = disable;
+}
+
 void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_options *options)
 {
        options->dsc_min_slice_height_override = dc->debug.dsc_min_slice_height_override;