[PATCH 15/26] drm/amd/display: Add available bandwidth calculation for audio (#16909)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ryan Seto <ryanseto@xxxxxxx>

[Why]
Audio for 8K 240Hz monitor was not available when it should be

[How]
Added calculation based on stream state

Co-authored-by: Ryan Seto <ryanseto@xxxxxxx>
Reviewed-by: George Shen <george.shen@xxxxxxx>
Signed-off-by: Jerry Zuo <jerry.zuo@xxxxxxx>
Signed-off-by: Ryan Seto <ryanseto@xxxxxxx>
---
 .../gpu/drm/amd/display/dc/dce/dce_audio.c    |  3 +-
 .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 62 +++++++++++++++++--
 2 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
index c3deb4ab3992..cf5f84fb9c69 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
@@ -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;
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index 1b410aff6c56..1f2eb2f727dc 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -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(
-- 
2.34.1




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux