]> www.infradead.org Git - nvme.git/commitdiff
drm/amd/display: Add available bandwidth calculation for audio
authorRyan Seto <ryanseto@amd.com>
Thu, 20 Jun 2024 17:40:43 +0000 (13:40 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 1 Jul 2024 20:10:02 +0000 (16:10 -0400)
[Why]
Audio for 8K 240Hz monitor was not available when it should be

[How]
Added calculation based on stream state

Co-developed-by: Ryan Seto <ryanseto@amd.com>
Reviewed-by: George Shen <george.shen@amd.com>
Signed-off-by: Jerry Zuo <jerry.zuo@amd.com>
Signed-off-by: Ryan Seto <ryanseto@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/dce/dce_audio.c
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c

index c3deb4ab3992cd038329e92030c012221daf7a28..cf5f84fb9c69a168ae07883b77da921908ce5ecc 100644 (file)
@@ -455,7 +455,8 @@ static uint32_t calculate_available_hblank_bw_in_symbols(
        available_hblank_bw -= crtc_info->dsc_num_slices * 4; /* EOC overhead */
 
        if (available_hblank_bw < dp_link_info->hblank_min_symbol_width)
-               available_hblank_bw = dp_link_info->hblank_min_symbol_width;
+               /* Each symbol takes 4 frames */
+               available_hblank_bw = 4 * dp_link_info->hblank_min_symbol_width;
 
        if (available_hblank_bw < 12)
                available_hblank_bw = 0;
index 1b410aff6c565fa68820b3a1eb7632a98e2135af..1f2eb2f727dc1ebb53c6aaca3ac1fb50c65fc2fa 100644 (file)
@@ -1305,13 +1305,65 @@ static void populate_audio_dp_link_info(
 
        dp_link_info->link_bandwidth_kbps = dc_fixpt_floor(link_bw_kbps);
 
-       /* HW minimum for 128b/132b HBlank is 4 frame symbols.
-        * TODO: Plumb the actual programmed HBlank min symbol width to here.
+       /* Calculates hblank_min_symbol_width for 128b/132b
+        * Corresponding HBLANK_MIN_SYMBOL_WIDTH register is calculated as:
+        *   floor(h_blank * bits_per_pixel / 128)
         */
-       if (dp_link_info->encoding == DP_128b_132b_ENCODING)
-               dp_link_info->hblank_min_symbol_width = 4;
-       else
+       if (dp_link_info->encoding == DP_128b_132b_ENCODING) {
+               struct dc_crtc_timing *crtc_timing = &pipe_ctx->stream->timing;
+
+               uint32_t h_active = crtc_timing->h_addressable + crtc_timing->h_border_left
+                               + crtc_timing->h_border_right;
+               uint32_t h_blank = crtc_timing->h_total - h_active;
+
+               uint32_t bpp;
+
+               if (crtc_timing->flags.DSC) {
+                       bpp = crtc_timing->dsc_cfg.bits_per_pixel;
+               } else {
+                       /* When the timing is using DSC, dsc_cfg.bits_per_pixel is in 16th bits.
+                        * The bpp in this path is scaled to 16th bits so the final calculation
+                        * is correct for both cases.
+                        */
+                       bpp = 16;
+                       switch (crtc_timing->display_color_depth) {
+                       case COLOR_DEPTH_666:
+                               bpp *= 18;
+                               break;
+                       case COLOR_DEPTH_888:
+                               bpp *= 24;
+                               break;
+                       case COLOR_DEPTH_101010:
+                               bpp *= 30;
+                               break;
+                       case COLOR_DEPTH_121212:
+                               bpp *= 36;
+                               break;
+                       default:
+                               bpp = 0;
+                               break;
+                       }
+
+                       switch (crtc_timing->pixel_encoding) {
+                       case PIXEL_ENCODING_YCBCR422:
+                               bpp = bpp * 2 / 3;
+                               break;
+                       case PIXEL_ENCODING_YCBCR420:
+                               bpp /= 2;
+                               break;
+                       default:
+                               break;
+                       }
+               }
+
+               /* Min symbol width = floor(h_blank * (bpp/16) / 128) */
+               dp_link_info->hblank_min_symbol_width = dc_fixpt_floor(
+                               dc_fixpt_div(dc_fixpt_from_int(h_blank * bpp),
+                                               dc_fixpt_from_int(128 / 16)));
+
+       } else {
                dp_link_info->hblank_min_symbol_width = 0;
+       }
 }
 
 static void build_audio_output(