[PATCH 13/19] drm/amd/display: Add DP audio BW validation

Alex Hung alex.hung at amd.com
Wed Jan 10 21:52:56 UTC 2024


From: George Shen <george.shen at amd.com>

[Why]
Timings with small HBlank (such as CVT RBv2) can result in insufficient
HBlank bandwidth for audio SDP transmission when DSC is active. This
will cause some higher bandwidth audio modes to fail.

The combination of CVT RBv2 timings + DSC can commonly be encountered
in MST scenarios.

[How]
Add DP audio bandwidth validation for 8b/10b MST and 128b/132b SST/MST
cases and filter out modes that cannot be supported with the current
timing config.

Reviewed-by: Wenjing Liu <wenjing.liu at amd.com>
Acked-by: Alex Hung <alex.hung at amd.com>
Signed-off-by: George Shen <george.shen at amd.com>
---
 .../gpu/drm/amd/display/dc/dce/dce_audio.c    | 288 +++++++++++++++++-
 .../gpu/drm/amd/display/dc/dce/dce_audio.h    |   3 +-
 .../amd/display/dc/hwss/dce110/dce110_hwseq.c |  56 +++-
 drivers/gpu/drm/amd/display/dc/inc/hw/audio.h |   3 +-
 .../gpu/drm/amd/display/include/audio_types.h |  15 +
 5 files changed, 349 insertions(+), 16 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 f0458b8f00af..07b507150c51 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
@@ -239,27 +239,289 @@ static void check_audio_bandwidth_hdmi(
 		}
 	}
 }
+static struct fixed31_32 get_link_symbol_clk_freq_mhz(enum dc_link_rate link_rate)
+{
+	switch (link_rate) {
+	case LINK_RATE_LOW:
+		return dc_fixpt_from_int(162); /* 162 MHz */
+	case LINK_RATE_HIGH:
+		return dc_fixpt_from_int(270); /* 270 MHz */
+	case LINK_RATE_HIGH2:
+		return dc_fixpt_from_int(540); /* 540 MHz */
+	case LINK_RATE_HIGH3:
+		return dc_fixpt_from_int(810); /* 810 MHz */
+	case LINK_RATE_UHBR10:
+		return dc_fixpt_from_fraction(3125, 10); /* 312.5 MHz */
+	case LINK_RATE_UHBR13_5:
+		return dc_fixpt_from_fraction(421875, 1000); /* 421.875 MHz */
+	case LINK_RATE_UHBR20:
+		return dc_fixpt_from_int(625); /* 625 MHz */
+	default:
+		/* Unexpected case, this requires debug if encountered. */
+		ASSERT(0);
+		return dc_fixpt_from_int(0);
+	}
+}
+
+struct dp_audio_layout_config {
+	uint8_t layouts_per_sample_denom;
+	uint8_t symbols_per_layout;
+	uint8_t max_layouts_per_audio_sdp;
+};
+
+static void get_audio_layout_config(
+	uint32_t channel_count,
+	enum dp_link_encoding encoding,
+	struct dp_audio_layout_config *output)
+{
+	/* Assuming L-PCM audio. Current implementation uses max 1 layout per SDP,
+	 * with each layout being the same size (8ch layout).
+	 */
+	if (encoding == DP_8b_10b_ENCODING) {
+		if (channel_count == 2) {
+			output->layouts_per_sample_denom = 4;
+			output->symbols_per_layout = 40;
+			output->max_layouts_per_audio_sdp = 1;
+		} else if (channel_count == 8) {
+			output->layouts_per_sample_denom = 1;
+			output->symbols_per_layout = 40;
+			output->max_layouts_per_audio_sdp = 1;
+		}
+	} else if (encoding == DP_128b_132b_ENCODING) {
+		if (channel_count == 2) {
+			output->layouts_per_sample_denom = 4;
+			output->symbols_per_layout = 10;
+			output->max_layouts_per_audio_sdp = 1;
+		} else if (channel_count == 8) {
+			output->layouts_per_sample_denom = 1;
+			output->symbols_per_layout = 10;
+			output->max_layouts_per_audio_sdp = 1;
+		}
+	}
+}
 
-/*For DP SST, calculate if specified sample rates can fit into a given timing */
-static void check_audio_bandwidth_dpsst(
+static uint32_t get_av_stream_map_lane_count(
+	enum dp_link_encoding encoding,
+	enum dc_lane_count lane_count,
+	bool is_mst)
+{
+	uint32_t av_stream_map_lane_count = 0;
+
+	if (encoding == DP_8b_10b_ENCODING) {
+		if (!is_mst)
+			av_stream_map_lane_count = lane_count;
+		else
+			av_stream_map_lane_count = 4;
+	} else if (encoding == DP_128b_132b_ENCODING) {
+		av_stream_map_lane_count = 4;
+	}
+
+	ASSERT(av_stream_map_lane_count != 0);
+
+	return av_stream_map_lane_count;
+}
+
+static uint32_t get_audio_sdp_overhead(
+	enum dp_link_encoding encoding,
+	enum dc_lane_count lane_count,
+	bool is_mst)
+{
+	uint32_t audio_sdp_overhead = 0;
+
+	if (encoding == DP_8b_10b_ENCODING) {
+		if (is_mst)
+			audio_sdp_overhead = 16; /* 4 * 2 + 8 */
+		else
+			audio_sdp_overhead = lane_count * 2 + 8;
+	} else if (encoding == DP_128b_132b_ENCODING) {
+		audio_sdp_overhead = 10; /* 4 x 2.5 */
+	}
+
+	ASSERT(audio_sdp_overhead != 0);
+
+	return audio_sdp_overhead;
+}
+
+static uint32_t calculate_required_audio_bw_in_symbols(
 	const struct audio_crtc_info *crtc_info,
+	const struct dp_audio_layout_config *layout_config,
 	uint32_t channel_count,
-	union audio_sample_rates *sample_rates)
+	uint32_t sample_rate_hz,
+	uint32_t av_stream_map_lane_count,
+	uint32_t audio_sdp_overhead)
 {
-	/* do nothing */
+	/* DP spec recommends between 1.05 to 1.1 safety margin to prevent sample under-run */
+	struct fixed31_32 audio_sdp_margin = dc_fixpt_from_fraction(110, 100);
+	struct fixed31_32 horizontal_line_freq_khz = dc_fixpt_from_fraction(
+			crtc_info->requested_pixel_clock_100Hz, crtc_info->h_total * 10);
+	struct fixed31_32 samples_per_line;
+	struct fixed31_32 layouts_per_line;
+	struct fixed31_32 symbols_per_sdp_max_layout;
+	struct fixed31_32 remainder;
+	uint32_t num_sdp_with_max_layouts;
+	uint32_t required_symbols_per_hblank;
+
+	samples_per_line = dc_fixpt_from_fraction(sample_rate_hz, 1000);
+	samples_per_line = dc_fixpt_div(samples_per_line, horizontal_line_freq_khz);
+	layouts_per_line = dc_fixpt_div_int(samples_per_line, layout_config->layouts_per_sample_denom);
+
+	num_sdp_with_max_layouts = dc_fixpt_floor(
+			dc_fixpt_div_int(layouts_per_line, layout_config->max_layouts_per_audio_sdp));
+	symbols_per_sdp_max_layout = dc_fixpt_from_int(
+			layout_config->max_layouts_per_audio_sdp * layout_config->symbols_per_layout);
+	symbols_per_sdp_max_layout = dc_fixpt_add_int(symbols_per_sdp_max_layout, audio_sdp_overhead);
+	symbols_per_sdp_max_layout = dc_fixpt_mul(symbols_per_sdp_max_layout, audio_sdp_margin);
+	required_symbols_per_hblank = num_sdp_with_max_layouts;
+	required_symbols_per_hblank *= ((dc_fixpt_ceil(symbols_per_sdp_max_layout) + av_stream_map_lane_count) /
+			av_stream_map_lane_count) *	av_stream_map_lane_count;
+
+	if (num_sdp_with_max_layouts !=	dc_fixpt_ceil(
+			dc_fixpt_div_int(layouts_per_line, layout_config->max_layouts_per_audio_sdp))) {
+		remainder = dc_fixpt_sub_int(layouts_per_line,
+				num_sdp_with_max_layouts * layout_config->max_layouts_per_audio_sdp);
+		remainder = dc_fixpt_mul_int(remainder, layout_config->symbols_per_layout);
+		remainder = dc_fixpt_add_int(remainder, audio_sdp_overhead);
+		remainder = dc_fixpt_mul(remainder, audio_sdp_margin);
+		required_symbols_per_hblank += ((dc_fixpt_ceil(remainder) + av_stream_map_lane_count) /
+				av_stream_map_lane_count) * av_stream_map_lane_count;
+	}
+
+	return required_symbols_per_hblank;
 }
 
-/*For DP MST, calculate if specified sample rates can fit into a given timing */
-static void check_audio_bandwidth_dpmst(
+/* Current calculation only applicable for 8b/10b MST and 128b/132b SST/MST.
+ */
+static uint32_t calculate_available_hblank_bw_in_symbols(
 	const struct audio_crtc_info *crtc_info,
+	const struct audio_dp_link_info *dp_link_info)
+{
+	uint64_t hblank = crtc_info->h_total - crtc_info->h_active;
+	struct fixed31_32 hblank_time_msec =
+			dc_fixpt_from_fraction(hblank * 10, crtc_info->requested_pixel_clock_100Hz);
+	struct fixed31_32 lsclkfreq_mhz =
+			get_link_symbol_clk_freq_mhz(dp_link_info->link_rate);
+	struct fixed31_32 average_stream_sym_bw_frac;
+	struct fixed31_32 peak_stream_bw_kbps;
+	struct fixed31_32 bits_per_pixel;
+	struct fixed31_32 link_bw_kbps;
+	struct fixed31_32 available_stream_sym_count;
+	uint32_t available_hblank_bw = 0; /* in stream symbols */
+
+	if (crtc_info->dsc_bits_per_pixel) {
+		bits_per_pixel = dc_fixpt_from_fraction(crtc_info->dsc_bits_per_pixel, 16);
+	} else {
+		switch (crtc_info->color_depth) {
+		case COLOR_DEPTH_666:
+			bits_per_pixel = dc_fixpt_from_int(6);
+			break;
+		case COLOR_DEPTH_888:
+			bits_per_pixel = dc_fixpt_from_int(8);
+			break;
+		case COLOR_DEPTH_101010:
+			bits_per_pixel = dc_fixpt_from_int(10);
+			break;
+		case COLOR_DEPTH_121212:
+			bits_per_pixel = dc_fixpt_from_int(12);
+			break;
+		default:
+			/* Default to commonly supported color depth. */
+			bits_per_pixel = dc_fixpt_from_int(8);
+			break;
+		}
+
+		bits_per_pixel = dc_fixpt_mul_int(bits_per_pixel, 3);
+
+		if (crtc_info->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
+			bits_per_pixel = dc_fixpt_div_int(bits_per_pixel, 3);
+			bits_per_pixel = dc_fixpt_mul_int(bits_per_pixel, 2);
+		} else if (crtc_info->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
+			bits_per_pixel = dc_fixpt_div_int(bits_per_pixel, 2);
+		}
+	}
+
+	/* Use simple stream BW calculation because mainlink overhead is
+	 * accounted for separately in the audio BW calculations.
+	 */
+	peak_stream_bw_kbps = dc_fixpt_from_fraction(crtc_info->requested_pixel_clock_100Hz, 10);
+	peak_stream_bw_kbps = dc_fixpt_mul(peak_stream_bw_kbps, bits_per_pixel);
+	link_bw_kbps = dc_fixpt_from_int(dp_link_info->link_bandwidth_kbps);
+	average_stream_sym_bw_frac = dc_fixpt_div(peak_stream_bw_kbps, link_bw_kbps);
+
+	available_stream_sym_count = dc_fixpt_mul_int(hblank_time_msec, 1000);
+	available_stream_sym_count = dc_fixpt_mul(available_stream_sym_count, lsclkfreq_mhz);
+	available_stream_sym_count = dc_fixpt_mul(available_stream_sym_count, average_stream_sym_bw_frac);
+	available_hblank_bw = dc_fixpt_floor(available_stream_sym_count);
+	available_hblank_bw *= dp_link_info->lane_count;
+	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;
+
+	if (available_hblank_bw < 12)
+		available_hblank_bw = 0;
+	else
+		available_hblank_bw -= 12; /* Main link overhead */
+
+	return available_hblank_bw;
+}
+
+static void check_audio_bandwidth_dp(
+	const struct audio_crtc_info *crtc_info,
+	const struct audio_dp_link_info *dp_link_info,
 	uint32_t channel_count,
 	union audio_sample_rates *sample_rates)
 {
-	/* do nothing  */
+	struct dp_audio_layout_config layout_config = {0};
+	uint32_t available_hblank_bw;
+	uint32_t av_stream_map_lane_count;
+	uint32_t audio_sdp_overhead;
+
+	/* TODO: Add validation for SST 8b/10 case  */
+	if (!dp_link_info->is_mst && dp_link_info->encoding == DP_8b_10b_ENCODING)
+		return;
+
+	available_hblank_bw = calculate_available_hblank_bw_in_symbols(
+			crtc_info, dp_link_info);
+	av_stream_map_lane_count = get_av_stream_map_lane_count(
+			dp_link_info->encoding, dp_link_info->lane_count, dp_link_info->is_mst);
+	audio_sdp_overhead = get_audio_sdp_overhead(
+			dp_link_info->encoding, dp_link_info->lane_count, dp_link_info->is_mst);
+	get_audio_layout_config(
+			channel_count, dp_link_info->encoding, &layout_config);
+
+	if (available_hblank_bw < calculate_required_audio_bw_in_symbols(
+			crtc_info, &layout_config, channel_count, 192000,
+			av_stream_map_lane_count, audio_sdp_overhead))
+		sample_rates->rate.RATE_192 = 0;
+	if (available_hblank_bw < calculate_required_audio_bw_in_symbols(
+			crtc_info, &layout_config, channel_count, 176400,
+			av_stream_map_lane_count, audio_sdp_overhead))
+		sample_rates->rate.RATE_176_4 = 0;
+	if (available_hblank_bw < calculate_required_audio_bw_in_symbols(
+			crtc_info, &layout_config, channel_count, 96000,
+			av_stream_map_lane_count, audio_sdp_overhead))
+		sample_rates->rate.RATE_96 = 0;
+	if (available_hblank_bw < calculate_required_audio_bw_in_symbols(
+			crtc_info, &layout_config, channel_count, 88200,
+			av_stream_map_lane_count, audio_sdp_overhead))
+		sample_rates->rate.RATE_88_2 = 0;
+	if (available_hblank_bw < calculate_required_audio_bw_in_symbols(
+			crtc_info, &layout_config, channel_count, 48000,
+			av_stream_map_lane_count, audio_sdp_overhead))
+		sample_rates->rate.RATE_48 = 0;
+	if (available_hblank_bw < calculate_required_audio_bw_in_symbols(
+			crtc_info, &layout_config, channel_count, 44100,
+			av_stream_map_lane_count, audio_sdp_overhead))
+		sample_rates->rate.RATE_44_1 = 0;
+	if (available_hblank_bw < calculate_required_audio_bw_in_symbols(
+			crtc_info, &layout_config, channel_count, 32000,
+			av_stream_map_lane_count, audio_sdp_overhead))
+		sample_rates->rate.RATE_32 = 0;
 }
 
 static void check_audio_bandwidth(
 	const struct audio_crtc_info *crtc_info,
+	const struct audio_dp_link_info *dp_link_info,
 	uint32_t channel_count,
 	enum signal_type signal,
 	union audio_sample_rates *sample_rates)
@@ -271,12 +533,9 @@ static void check_audio_bandwidth(
 		break;
 	case SIGNAL_TYPE_EDP:
 	case SIGNAL_TYPE_DISPLAY_PORT:
-		check_audio_bandwidth_dpsst(
-			crtc_info, channel_count, sample_rates);
-		break;
 	case SIGNAL_TYPE_DISPLAY_PORT_MST:
-		check_audio_bandwidth_dpmst(
-			crtc_info, channel_count, sample_rates);
+		check_audio_bandwidth_dp(
+			crtc_info, dp_link_info, channel_count, sample_rates);
 		break;
 	default:
 		break;
@@ -394,7 +653,8 @@ void dce_aud_az_configure(
 	struct audio *audio,
 	enum signal_type signal,
 	const struct audio_crtc_info *crtc_info,
-	const struct audio_info *audio_info)
+	const struct audio_info *audio_info,
+	const struct audio_dp_link_info *dp_link_info)
 {
 	struct dce_audio *aud = DCE_AUD(audio);
 
@@ -529,6 +789,7 @@ void dce_aud_az_configure(
 
 				check_audio_bandwidth(
 					crtc_info,
+					dp_link_info,
 					channel_count,
 					signal,
 					&sample_rates);
@@ -588,6 +849,7 @@ void dce_aud_az_configure(
 
 	check_audio_bandwidth(
 		crtc_info,
+		dp_link_info,
 		8,
 		signal,
 		&sample_rate);
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h
index dbd2cfed0603..539f881928d1 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h
@@ -170,7 +170,8 @@ void dce_aud_az_disable(struct audio *audio);
 void dce_aud_az_configure(struct audio *audio,
 	enum signal_type signal,
 	const struct audio_crtc_info *crtc_info,
-	const struct audio_info *audio_info);
+	const struct audio_info *audio_info,
+	const struct audio_dp_link_info *dp_link_info);
 
 void dce_aud_wall_dto_setup(struct audio *audio,
 	enum signal_type signal,
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 4078e6be8810..db71a261e9da 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
@@ -1290,6 +1290,46 @@ static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id)
 	}
 }
 
+static void populate_audio_dp_link_info(
+	const struct pipe_ctx *pipe_ctx,
+	struct audio_dp_link_info *dp_link_info)
+{
+	const struct dc_stream_state *stream = pipe_ctx->stream;
+	const struct dc_link *link = stream->link;
+	struct fixed31_32 link_bw_kbps;
+
+	dp_link_info->encoding = link->dc->link_srv->dp_get_encoding_format(
+				&pipe_ctx->link_config.dp_link_settings);
+	dp_link_info->is_mst = (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST);
+	dp_link_info->lane_count = pipe_ctx->link_config.dp_link_settings.lane_count;
+	dp_link_info->link_rate = pipe_ctx->link_config.dp_link_settings.link_rate;
+
+	link_bw_kbps = dc_fixpt_from_int(dc_link_bandwidth_kbps(link,
+			&pipe_ctx->link_config.dp_link_settings));
+
+	/* For audio stream calculations, the video stream should not include FEC or SSC
+	 * in order to get the most pessimistic values.
+	 */
+	if (dp_link_info->encoding == DP_8b_10b_ENCODING &&
+			link->dc->link_srv->dp_is_fec_supported(link)) {
+		link_bw_kbps = dc_fixpt_mul(link_bw_kbps,
+				dc_fixpt_from_fraction(100, DATA_EFFICIENCY_8b_10b_FEC_EFFICIENCY_x100));
+	} else if (dp_link_info->encoding == DP_128b_132b_ENCODING) {
+		link_bw_kbps = dc_fixpt_mul(link_bw_kbps,
+				dc_fixpt_from_fraction(10000, 9975)); /* 99.75% SSC overhead*/
+	}
+
+	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.
+	 */
+	if (dp_link_info->encoding == DP_128b_132b_ENCODING)
+		dp_link_info->hblank_min_symbol_width = 4;
+	else
+		dp_link_info->hblank_min_symbol_width = 0;
+}
+
 static void build_audio_output(
 	struct dc_state *state,
 	const struct pipe_ctx *pipe_ctx,
@@ -1337,6 +1377,15 @@ static void build_audio_output(
 	audio_output->crtc_info.calculated_pixel_clock_100Hz =
 			pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz;
 
+	audio_output->crtc_info.pixel_encoding =
+		stream->timing.pixel_encoding;
+
+	audio_output->crtc_info.dsc_bits_per_pixel =
+			stream->timing.dsc_cfg.bits_per_pixel;
+
+	audio_output->crtc_info.dsc_num_slices =
+			stream->timing.dsc_cfg.num_slices_h;
+
 /*for HDMI, audio ACR is with deep color ratio factor*/
 	if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) &&
 		audio_output->crtc_info.requested_pixel_clock_100Hz ==
@@ -1370,6 +1419,10 @@ static void build_audio_output(
 
 	audio_output->pll_info.ss_percentage =
 			pipe_ctx->pll_settings.ss_percentage;
+
+	if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
+		populate_audio_dp_link_info(pipe_ctx, &audio_output->dp_link_info);
+	}
 }
 
 static void program_scaler(const struct dc *dc,
@@ -1506,7 +1559,8 @@ static enum dc_status apply_single_controller_ctx_to_hw(
 				pipe_ctx->stream_res.audio,
 				pipe_ctx->stream->signal,
 				&audio_output.crtc_info,
-				&pipe_ctx->stream->audio_info);
+				&pipe_ctx->stream->audio_info,
+				&audio_output.dp_link_info);
 	}
 
 	/* make sure no pipes syncd to the pipe being enabled */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h b/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h
index 6ed1fb8c9300..b6203253111c 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h
@@ -43,7 +43,8 @@ struct audio_funcs {
 	void (*az_configure)(struct audio *audio,
 		enum signal_type signal,
 		const struct audio_crtc_info *crtc_info,
-		const struct audio_info *audio_info);
+		const struct audio_info *audio_info,
+		const struct audio_dp_link_info *dp_link_info);
 
 	void (*wall_dto_setup)(struct audio *audio,
 		enum signal_type signal,
diff --git a/drivers/gpu/drm/amd/display/include/audio_types.h b/drivers/gpu/drm/amd/display/include/audio_types.h
index 915a031a43cb..e4a26143f14c 100644
--- a/drivers/gpu/drm/amd/display/include/audio_types.h
+++ b/drivers/gpu/drm/amd/display/include/audio_types.h
@@ -27,11 +27,21 @@
 #define __AUDIO_TYPES_H__
 
 #include "signal_types.h"
+#include "fixed31_32.h"
+#include "dc_dp_types.h"
 
 #define AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS 20
 #define MAX_HW_AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS 18
 #define MULTI_CHANNEL_SPLIT_NO_ASSO_INFO 0xFFFFFFFF
 
+struct audio_dp_link_info {
+	uint32_t link_bandwidth_kbps;
+	uint32_t hblank_min_symbol_width;
+	enum dp_link_encoding encoding;
+	enum dc_link_rate link_rate;
+	enum dc_lane_count lane_count;
+	bool is_mst;
+};
 
 struct audio_crtc_info {
 	uint32_t h_total;
@@ -42,7 +52,10 @@ struct audio_crtc_info {
 	uint32_t calculated_pixel_clock_100Hz; /* in 100Hz */
 	uint32_t refresh_rate;
 	enum dc_color_depth color_depth;
+	enum dc_pixel_encoding pixel_encoding;
 	bool interlaced;
+	uint32_t dsc_bits_per_pixel;
+	uint32_t dsc_num_slices;
 };
 struct azalia_clock_info {
 	uint32_t pixel_clock_in_10khz;
@@ -95,6 +108,8 @@ struct audio_output {
 	enum signal_type signal;
 	/* video timing */
 	struct audio_crtc_info crtc_info;
+	/* DP link info */
+	struct audio_dp_link_info dp_link_info;
 	/* PLL for audio */
 	struct audio_pll_info pll_info;
 };
-- 
2.34.1



More information about the amd-gfx mailing list