[PATCH 06/17] drm/amd/display: add setup/reset stream encoder to link_hwss

Stylon Wang stylon.wang at amd.com
Fri Jan 28 14:04:00 UTC 2022


From: Wenjing Liu <wenjing.liu at amd.com>

[why]
Factor setup/reset stream encoder to link hwss.

Acked-by: Wayne Lin <wayne.lin at amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu at amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  64 +++----
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  23 +--
 .../drm/amd/display/dc/core/dc_link_hwss.c    | 170 +++++++++++-------
 .../display/dc/dce110/dce110_hw_sequencer.c   |  44 ++---
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |  40 +----
 .../gpu/drm/amd/display/dc/inc/link_hwss.h    |  22 ++-
 6 files changed, 180 insertions(+), 183 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 1e596f1ea494..2c5d67abad3e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3441,7 +3441,7 @@ static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx,
 	struct link_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp;
 	const struct dc_link_settings empty_link_settings = {0};
-	const struct link_hwss *link_hwss = dc_link_hwss_get(link, &pipe_ctx->link_res);
+	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
 	DC_LOGGER_INIT(link->ctx->logger);
 
 	/* slot X.Y for SST payload deallocate */
@@ -3450,9 +3450,11 @@ static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx,
 
 		dc_log_vcp_x_y(link, avg_time_slots_per_mtp);
 
-		link_hwss->set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
-		if (link_hwss->set_hblank_min_symbol_width)
-			link_hwss->set_hblank_min_symbol_width(pipe_ctx,
+		if (link_hwss->ext.set_throttled_vcp_size)
+			link_hwss->ext.set_throttled_vcp_size(pipe_ctx,
+					avg_time_slots_per_mtp);
+		if (link_hwss->ext.set_hblank_min_symbol_width)
+			link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
 					&empty_link_settings,
 					avg_time_slots_per_mtp);
 	}
@@ -3498,9 +3500,11 @@ static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx,
 
 		dc_log_vcp_x_y(link, avg_time_slots_per_mtp);
 
-		link_hwss->set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
-		if (link_hwss->set_hblank_min_symbol_width)
-			link_hwss->set_hblank_min_symbol_width(pipe_ctx,
+		if (link_hwss->ext.set_throttled_vcp_size)
+			link_hwss->ext.set_throttled_vcp_size(pipe_ctx,
+					avg_time_slots_per_mtp);
+		if (link_hwss->ext.set_hblank_min_symbol_width)
+			link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
 					&link->cur_link_settings,
 					avg_time_slots_per_mtp);
 	}
@@ -3526,7 +3530,7 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct fixed31_32 pbn_per_slot;
 	int i;
 	enum act_return_status ret;
-	const struct link_hwss *link_hwss = dc_link_hwss_get(link, &pipe_ctx->link_res);
+	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
 	DC_LOGGER_INIT(link->ctx->logger);
 
 	/* Link encoder may have been dynamically assigned to non-physical display endpoint. */
@@ -3634,9 +3638,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 
 	dc_log_vcp_x_y(link, avg_time_slots_per_mtp);
 
-	link_hwss->set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
-	if (link_hwss->set_hblank_min_symbol_width)
-		link_hwss->set_hblank_min_symbol_width(pipe_ctx,
+	if (link_hwss->ext.set_throttled_vcp_size)
+		link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
+	if (link_hwss->ext.set_hblank_min_symbol_width)
+		link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
 				&link->cur_link_settings,
 				avg_time_slots_per_mtp);
 
@@ -3655,7 +3660,7 @@ enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	uint8_t i;
 	enum act_return_status ret;
-	const struct link_hwss *link_hwss = dc_link_hwss_get(link, &pipe_ctx->link_res);
+	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
 	DC_LOGGER_INIT(link->ctx->logger);
 
 	/* decrease throttled vcp size */
@@ -3663,9 +3668,10 @@ enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw
 	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
 	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
 
-	link_hwss->set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
-	if (link_hwss->set_hblank_min_symbol_width)
-		link_hwss->set_hblank_min_symbol_width(pipe_ctx,
+	if (link_hwss->ext.set_throttled_vcp_size)
+		link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
+	if (link_hwss->ext.set_hblank_min_symbol_width)
+		link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
 				&link->cur_link_settings,
 				avg_time_slots_per_mtp);
 
@@ -3737,7 +3743,7 @@ enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	uint8_t i;
 	enum act_return_status ret;
-	const struct link_hwss *link_hwss = dc_link_hwss_get(link, &pipe_ctx->link_res);
+	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
 	DC_LOGGER_INIT(link->ctx->logger);
 
 	/* notify immediate branch device table update */
@@ -3796,9 +3802,10 @@ enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t
 	pbn_per_slot = get_pbn_per_slot(stream);
 	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
 
-	link_hwss->set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
-	if (link_hwss->set_hblank_min_symbol_width)
-		link_hwss->set_hblank_min_symbol_width(pipe_ctx,
+	if (link_hwss->ext.set_throttled_vcp_size)
+		link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
+	if (link_hwss->ext.set_hblank_min_symbol_width)
+		link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
 				&link->cur_link_settings,
 				avg_time_slots_per_mtp);
 
@@ -3815,7 +3822,7 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
 	int i;
 	bool mst_mode = (link->type == dc_connection_mst_branch);
-	const struct link_hwss *link_hwss = dc_link_hwss_get(link, &pipe_ctx->link_res);
+	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
 	const struct dc_link_settings empty_link_settings = {0};
 	DC_LOGGER_INIT(link->ctx->logger);
 
@@ -3834,9 +3841,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	 */
 
 	/* slot X.Y */
-	link_hwss->set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
-	if (link_hwss->set_hblank_min_symbol_width)
-		link_hwss->set_hblank_min_symbol_width(pipe_ctx,
+	if (link_hwss->ext.set_throttled_vcp_size)
+		link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
+	if (link_hwss->ext.set_hblank_min_symbol_width)
+		link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
 				&empty_link_settings,
 				avg_time_slots_per_mtp);
 
@@ -4004,8 +4012,8 @@ static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pi
 	struct fixed31_32 avg_time_slots_per_mtp;
 	uint8_t req_slot_count = 0;
 	uint8_t vc_id = 1; /// VC ID always 1 for SST
-
 	struct dc_link_settings link_settings = {0};
+	const struct link_hwss *link_hwss = get_link_hwss(stream->link, &pipe_ctx->link_res);
 	DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
 
 	decide_link_settings(stream, &link_settings);
@@ -4066,12 +4074,8 @@ static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pi
 			pipe_ctx->link_res.hpo_dp_link_enc,
 			&proposed_table);
 
-	pipe_ctx->link_res.hpo_dp_link_enc->funcs->set_throttled_vcp_size(
-			pipe_ctx->link_res.hpo_dp_link_enc,
-			pipe_ctx->stream_res.hpo_dp_stream_enc->inst,
-			avg_time_slots_per_mtp);
-
-
+	if (link_hwss->ext.set_throttled_vcp_size)
+		link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
 
 	dc->hwss.unblank_stream(pipe_ctx, &stream->link->cur_link_settings);
 }
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 117183b5ab44..f1082674bcbf 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -2700,26 +2700,15 @@ bool perform_link_training_with_retries(
 	struct dc_stream_state *stream = pipe_ctx->stream;
 	struct dc_link *link = stream->link;
 	enum dp_panel_mode panel_mode = dp_get_panel_mode(link);
-	struct link_encoder *link_enc;
 	enum link_training_result status = LINK_TRAINING_CR_FAIL_LANE0;
 	struct dc_link_settings current_setting = *link_setting;
+	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
 
-	/* Dynamically assigned link encoders associated with stream rather than
-	 * link.
-	 */
-	if (link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign)
-		link_enc = link_enc_cfg_get_link_enc_used_by_stream(link->ctx->dc, pipe_ctx->stream);
-	else
-		link_enc = link->link_enc;
-
-	/* We need to do this before the link training to ensure the idle pattern in SST
-	 * mode will be sent right after the link training
-	 */
-	if (dp_get_link_encoding_format(&current_setting) == DP_8b_10b_ENCODING) {
-		link_enc->funcs->connect_dig_be_to_fe(link_enc,
-							pipe_ctx->stream_res.stream_enc->id, true);
-		dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
-	}
+	if (dp_get_link_encoding_format(&current_setting) == DP_8b_10b_ENCODING)
+		/* We need to do this before the link training to ensure the idle
+		 * pattern in SST mode will be sent right after the link training
+		 */
+		link_hwss->setup_stream_encoder(pipe_ctx);
 
 	for (j = 0; j < attempts; ++j) {
 
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
index 5e9054fdb339..c26df0a78664 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -784,54 +784,8 @@ void disable_dp_hpo_output(struct dc_link *link,
 	}
 }
 
-void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable)
-{
-	struct dc_stream_state *stream = pipe_ctx->stream;
-	struct dc *dc = pipe_ctx->stream->ctx->dc;
-	struct pipe_ctx *odm_pipe;
-	int odm_combine_num_segments = 1;
-	enum phyd32clk_clock_source phyd32clk;
-
-	if (enable) {
-		for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
-				odm_combine_num_segments++;
-
-		dc->res_pool->dccg->funcs->set_dpstreamclk(
-				dc->res_pool->dccg,
-				DTBCLK0,
-				pipe_ctx->stream_res.tg->inst);
-
-		phyd32clk = get_phyd32clk_src(stream->link);
-		dc->res_pool->dccg->funcs->enable_symclk32_se(
-				dc->res_pool->dccg,
-				pipe_ctx->stream_res.hpo_dp_stream_enc->inst,
-				phyd32clk);
-
-		dc->res_pool->dccg->funcs->set_dtbclk_dto(
-				dc->res_pool->dccg,
-				pipe_ctx->stream_res.tg->inst,
-				stream->phy_pix_clk,
-				odm_combine_num_segments,
-				&stream->timing);
-	} else {
-		dc->res_pool->dccg->funcs->set_dtbclk_dto(
-				dc->res_pool->dccg,
-				pipe_ctx->stream_res.tg->inst,
-				0,
-				0,
-				&stream->timing);
-		dc->res_pool->dccg->funcs->disable_symclk32_se(
-				dc->res_pool->dccg,
-				pipe_ctx->stream_res.hpo_dp_stream_enc->inst);
-		dc->res_pool->dccg->funcs->set_dpstreamclk(
-				dc->res_pool->dccg,
-				REFCLK,
-				pipe_ctx->stream_res.tg->inst);
-	}
-}
-
-static void set_dummy_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
-		struct fixed31_32 throttled_vcp_size);
+static void virtual_setup_stream_encoder(struct pipe_ctx *pipe_ctx);
+static void virtual_reset_stream_encoder(struct pipe_ctx *pipe_ctx);
 
 /************************* below goes to dio_link_hwss ************************/
 static bool can_use_dio_link_hwss(const struct dc_link *link,
@@ -850,8 +804,48 @@ static void set_dio_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
 				throttled_vcp_size);
 }
 
+static struct link_encoder *get_dio_link_encoder(const struct dc_link *link)
+{
+	/* Link encoder may have been dynamically assigned to non-physical display endpoint. */
+	if (link->is_dig_mapping_flexible &&
+			link->dc->res_pool->funcs->link_encs_assign)
+		return link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
+	else
+		return link->link_enc;
+}
+
+static void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
+{
+	struct link_encoder *link_enc = get_dio_link_encoder(pipe_ctx->stream->link);
+
+	ASSERT(link_enc);
+	link_enc->funcs->connect_dig_be_to_fe(link_enc,
+			pipe_ctx->stream_res.stream_enc->id, true);
+	if (dc_is_dp_signal(pipe_ctx->stream->signal))
+		dp_source_sequence_trace(pipe_ctx->stream->link,
+				DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
+}
+
+static void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
+{
+	struct link_encoder *link_enc = get_dio_link_encoder(pipe_ctx->stream->link);
+
+	link_enc->funcs->connect_dig_be_to_fe(
+			link_enc,
+			pipe_ctx->stream_res.stream_enc->id,
+			false);
+	if (dc_is_dp_signal(pipe_ctx->stream->signal))
+		dp_source_sequence_trace(pipe_ctx->stream->link,
+				DPCD_SOURCE_SEQ_AFTER_DISCONNECT_DIG_FE_BE);
+
+}
+
 static const struct link_hwss dio_link_hwss = {
-	.set_throttled_vcp_size = set_dio_throttled_vcp_size,
+	.setup_stream_encoder = setup_dio_stream_encoder,
+	.reset_stream_encoder = reset_dio_stream_encoder,
+	.ext = {
+		.set_throttled_vcp_size = set_dio_throttled_vcp_size,
+	},
 };
 
 /*********************** below goes to hpo_dp_link_hwss ***********************/
@@ -895,13 +889,57 @@ static void set_dp_hpo_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx,
 			hblank_min_symbol_width);
 }
 
-static const struct link_hwss hpo_dp_link_hwss = {
-	.set_throttled_vcp_size = set_dp_hpo_throttled_vcp_size,
+static int get_odm_segment_count(struct pipe_ctx *pipe_ctx)
+{
+	struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
+	int count = 1;
 
-	/* function pointers below this point require check for NULL
-	 * *********************************************************************
-	 */
-	.set_hblank_min_symbol_width = set_dp_hpo_hblank_min_symbol_width,
+	while (odm_pipe != NULL) {
+		count++;
+		odm_pipe = odm_pipe->next_odm_pipe;
+	}
+
+	return count;
+}
+
+static void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
+{
+	struct dc *dc = pipe_ctx->stream->ctx->dc;
+	struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
+	struct hpo_dp_link_encoder *link_enc = pipe_ctx->link_res.hpo_dp_link_enc;
+	struct dccg *dccg = dc->res_pool->dccg;
+	struct timing_generator *tg = pipe_ctx->stream_res.tg;
+	int odm_segment_count = get_odm_segment_count(pipe_ctx);
+	enum phyd32clk_clock_source phyd32clk = get_phyd32clk_src(pipe_ctx->stream->link);
+
+	dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst);
+	dccg->funcs->enable_symclk32_se(dccg, stream_enc->inst, phyd32clk);
+	dccg->funcs->set_dtbclk_dto(dccg, tg->inst, pipe_ctx->stream->phy_pix_clk,
+			odm_segment_count,
+			&pipe_ctx->stream->timing);
+	stream_enc->funcs->enable_stream(stream_enc);
+	stream_enc->funcs->map_stream_to_link(stream_enc, stream_enc->inst, link_enc->inst);
+}
+
+static void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
+{
+	struct dc *dc = pipe_ctx->stream->ctx->dc;
+	struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
+	struct dccg *dccg = dc->res_pool->dccg;
+	struct timing_generator *tg = pipe_ctx->stream_res.tg;
+
+	stream_enc->funcs->disable(stream_enc);
+	dccg->funcs->set_dtbclk_dto(dccg, tg->inst, 0, 0, &pipe_ctx->stream->timing);
+	dccg->funcs->disable_symclk32_se(dccg, stream_enc->inst);
+	dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst);
+}
+static const struct link_hwss hpo_dp_link_hwss = {
+	.setup_stream_encoder = setup_hpo_dp_stream_encoder,
+	.reset_stream_encoder = reset_hpo_dp_stream_encoder,
+	.ext = {
+		.set_throttled_vcp_size = set_dp_hpo_throttled_vcp_size,
+		.set_hblank_min_symbol_width = set_dp_hpo_hblank_min_symbol_width,
+	},
 };
 /*********************** below goes to dpia_link_hwss *************************/
 static bool can_use_dpia_link_hwss(const struct dc_link *link,
@@ -912,21 +950,27 @@ static bool can_use_dpia_link_hwss(const struct dc_link *link,
 }
 
 static const struct link_hwss dpia_link_hwss = {
-	.set_throttled_vcp_size = set_dio_throttled_vcp_size,
+	.setup_stream_encoder = setup_dio_stream_encoder,
+	.reset_stream_encoder = reset_dio_stream_encoder,
+	.ext = {
+		.set_throttled_vcp_size = set_dio_throttled_vcp_size,
+	},
 };
 
 /*********************** below goes to link_hwss ******************************/
-static void set_dummy_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
-		struct fixed31_32 throttled_vcp_size)
+static void virtual_setup_stream_encoder(struct pipe_ctx *pipe_ctx)
 {
-	return;
 }
 
-static const struct link_hwss dummy_link_hwss = {
-	.set_throttled_vcp_size = set_dummy_throttled_vcp_size,
+static void virtual_reset_stream_encoder(struct pipe_ctx *pipe_ctx)
+{
+}
+static const struct link_hwss virtual_link_hwss = {
+	.setup_stream_encoder = virtual_setup_stream_encoder,
+	.reset_stream_encoder = virtual_reset_stream_encoder,
 };
 
-const struct link_hwss *dc_link_hwss_get(const struct dc_link *link,
+const struct link_hwss *get_link_hwss(const struct dc_link *link,
 		const struct link_resource *link_res)
 {
 	if (can_use_dp_hpo_link_hwss(link, link_res))
@@ -953,7 +997,7 @@ const struct link_hwss *dc_link_hwss_get(const struct dc_link *link,
 	else if (can_use_dio_link_hwss(link, link_res))
 		return &dio_link_hwss;
 	else
-		return &dummy_link_hwss;
+		return &virtual_link_hwss;
 }
 
 #undef DC_LOGGER
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index f28d6c15a4e2..8c32b9cb3b49 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -667,17 +667,12 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
 	struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
 	struct dc_link *link = pipe_ctx->stream->link;
 	const struct dc *dc = link->dc;
-
+	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
 	uint32_t active_total_with_borders;
 	uint32_t early_control = 0;
 	struct timing_generator *tg = pipe_ctx->stream_res.tg;
 
-	/* For MST, there are multiply stream go to only one link.
-	 * connect DIG back_end to front_end while enable_stream and
-	 * disconnect them during disable_stream
-	 * BY this, it is logic clean to separate stream and link */
-	link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
-						    pipe_ctx->stream_res.stream_enc->id, true);
+	link_hwss->setup_stream_encoder(pipe_ctx);
 
 	dc->hwss.update_info_frame(pipe_ctx);
 
@@ -1178,7 +1173,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
 	struct dc_stream_state *stream = pipe_ctx->stream;
 	struct dc_link *link = stream->link;
 	struct dc *dc = pipe_ctx->stream->ctx->dc;
-	struct link_encoder *link_enc = NULL;
+	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
 
 	if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) {
 		pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets(
@@ -1196,34 +1191,17 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
 
 	dc->hwss.disable_audio_stream(pipe_ctx);
 
-	/* Link encoder may have been dynamically assigned to non-physical display endpoint. */
-	if (link->ep_type == DISPLAY_ENDPOINT_PHY)
-		link_enc = link->link_enc;
-	else if (dc->res_pool->funcs->link_encs_assign)
-		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
-	ASSERT(link_enc);
+	link_hwss->reset_stream_encoder(pipe_ctx);
 
 	if (is_dp_128b_132b_signal(pipe_ctx)) {
-		pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->disable(
-				pipe_ctx->stream_res.hpo_dp_stream_enc);
-		setup_dp_hpo_stream(pipe_ctx, false);
-	/* TODO - DP2.0 HW: unmap stream from link encoder here */
-	} else {
-		if (link_enc)
-			link_enc->funcs->connect_dig_be_to_fe(
-				link_enc,
-				pipe_ctx->stream_res.stream_enc->id,
-				false);
+		/* TODO: This looks like a bug to me as we are disabling HPO IO when
+		 * we are just disabling a single HPO stream. Shouldn't we disable HPO
+		 * HW control only when HPOs for all streams are disabled?
+		 */
+		if (pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control)
+			pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control(
+					pipe_ctx->stream->ctx->dc->hwseq, false);
 	}
-
-	if (dc_is_dp_signal(pipe_ctx->stream->signal))
-		dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISCONNECT_DIG_FE_BE);
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
-	if (dc->hwseq->funcs.setup_hpo_hw_control && is_dp_128b_132b_signal(pipe_ctx))
-		dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, false);
-#endif
-
 }
 
 void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 4991e93e5308..013b94c41327 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -2390,46 +2390,22 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
 	uint32_t active_total_with_borders;
 	uint32_t early_control = 0;
 	struct timing_generator *tg = pipe_ctx->stream_res.tg;
-	struct link_encoder *link_enc;
+	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
+	struct dc *dc = pipe_ctx->stream->ctx->dc;
 
-	if (link->is_dig_mapping_flexible &&
-			link->dc->res_pool->funcs->link_encs_assign)
-		link_enc = link_enc_cfg_get_link_enc_used_by_stream(link->ctx->dc, pipe_ctx->stream);
-	else
-		link_enc = link->link_enc;
-	ASSERT(link_enc);
-
-	/* For MST, there are multiply stream go to only one link.
-	 * connect DIG back_end to front_end while enable_stream and
-	 * disconnect them during disable_stream
-	 * BY this, it is logic clean to separate stream and link
-	 */
 	if (is_dp_128b_132b_signal(pipe_ctx)) {
-		if (pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control)
-			pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control(
-				pipe_ctx->stream->ctx->dc->hwseq, true);
-		setup_dp_hpo_stream(pipe_ctx, true);
-		pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->enable_stream(
-				pipe_ctx->stream_res.hpo_dp_stream_enc);
-		pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->map_stream_to_link(
-				pipe_ctx->stream_res.hpo_dp_stream_enc,
-				pipe_ctx->stream_res.hpo_dp_stream_enc->inst,
-				pipe_ctx->link_res.hpo_dp_link_enc->inst);
+		if (dc->hwseq->funcs.setup_hpo_hw_control)
+			dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, true);
 	}
 
-	if (!is_dp_128b_132b_signal(pipe_ctx) && link_enc)
-		link_enc->funcs->connect_dig_be_to_fe(
-			link_enc, pipe_ctx->stream_res.stream_enc->id, true);
-
-	if (dc_is_dp_signal(pipe_ctx->stream->signal))
-		dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
+	link_hwss->setup_stream_encoder(pipe_ctx);
 
 	if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) {
-		if (link->dc->hwss.program_dmdata_engine)
-			link->dc->hwss.program_dmdata_engine(pipe_ctx);
+		if (dc->hwss.program_dmdata_engine)
+			dc->hwss.program_dmdata_engine(pipe_ctx);
 	}
 
-	link->dc->hwss.update_info_frame(pipe_ctx);
+	dc->hwss.update_info_frame(pipe_ctx);
 
 	if (dc_is_dp_signal(pipe_ctx->stream->signal))
 		dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
index 5b361924ed8f..e9cad1c78b5e 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
@@ -77,21 +77,27 @@ struct link_resource;
 struct fixed31_32;
 struct pipe_ctx;
 
-struct link_hwss {
-	/* you must define a dummy implementation and assign the function to
-	 * dummy_link_hwss if you don't want to check for NULL pointer
+struct link_hwss_ext {
+	/* function pointers below require check for NULL at all time
+	 * *********************************************************************
 	 */
+	void (*set_hblank_min_symbol_width)(struct pipe_ctx *pipe_ctx,
+			const struct dc_link_settings *link_settings,
+			struct fixed31_32 throttled_vcp_size);
 	void (*set_throttled_vcp_size)(struct pipe_ctx *pipe_ctx,
 			struct fixed31_32 throttled_vcp_size);
+};
 
-	/* function pointers below this point require check for NULL
+struct link_hwss {
+	struct link_hwss_ext ext;
+
+	/* function pointers below MUST be assigned to all types of link_hwss
 	 * *********************************************************************
 	 */
-	void (*set_hblank_min_symbol_width)(struct pipe_ctx *pipe_ctx,
-			const struct dc_link_settings *link_settings,
-			struct fixed31_32 throttled_vcp_size);
+	void (*setup_stream_encoder)(struct pipe_ctx *pipe_ctx);
+	void (*reset_stream_encoder)(struct pipe_ctx *pipe_ctx);
 };
 
-const struct link_hwss *dc_link_hwss_get(const struct dc_link *link, const struct link_resource *link_res);
+const struct link_hwss *get_link_hwss(const struct dc_link *link, const struct link_resource *link_res);
 
 #endif /* __DC_LINK_HWSS_H__ */
-- 
2.34.1



More information about the amd-gfx mailing list