All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mikita Lipski <mikita.lipski@amd.com>
To: <amd-gfx@lists.freedesktop.org>
Cc: <Harry.Wentland@amd.com>, <Sunpeng.Li@amd.com>,
	<Bhawanpreet.Lakha@amd.com>, <Rodrigo.Siqueira@amd.com>,
	<Aurabindo.Pillai@amd.com>, <qingqing.zhuo@amd.com>,
	<mikita.lipski@amd.com>,  <roman.li@amd.com>,
	<Anson.Jacob@amd.com>, <wayne.lin@amd.com>, <stylon.wang@amd.com>,
	<solomon.chiu@amd.com>, Jimmy Kizito <Jimmy.Kizito@amd.com>,
	Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
Subject: [PATCH 09/33] drm/amd/display: Fix dynamic link encoder access.
Date: Wed, 8 Sep 2021 10:54:00 -0400	[thread overview]
Message-ID: <20210908145424.3311-10-mikita.lipski@amd.com> (raw)
In-Reply-To: <20210908145424.3311-1-mikita.lipski@amd.com>

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why]
Assuming DIG link encoders are statically mapped to links can cause
system instability due to null pointer accesses.

[How]
- Add checks for non-null link encoder pointers before trying to access
them.
- When a hardware platform uses dynamic DIG assignment (i.e. resource
function 'link_encs_assign' defined) and a link supports flexible
mapping to DIGs, use the link_enc_cfg API to access the DIG assigned to
a link or stream.

Reviewed-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
Acked-by: Mikita Lipski <mikita.lipski@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 .../display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c  |  2 +-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 42 +++++++++++++++----
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 36 ++++++++++++++--
 .../drm/amd/display/dc/core/dc_link_enc_cfg.c | 25 ++++++-----
 .../drm/amd/display/dc/core/dc_link_hwss.c    |  7 ++--
 .../gpu/drm/amd/display/dc/core/dc_resource.c |  3 +-
 .../display/dc/dce110/dce110_hw_sequencer.c   | 22 +++++++---
 .../drm/amd/display/dc/dcn10/dcn10_resource.c |  2 +-
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    | 13 ++++--
 .../drm/amd/display/dc/dcn20/dcn20_resource.c | 20 ++++++++-
 .../drm/amd/display/dc/dcn31/dcn31_hwseq.c    |  9 +++-
 .../gpu/drm/amd/display/dc/inc/link_enc_cfg.h |  5 +++
 12 files changed, 147 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
index 15491e3ca11a..1414da4b95d7 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
@@ -87,7 +87,7 @@ int dcn31_get_active_display_cnt_wa(
 		const struct dc_link *link = dc->links[i];
 
 		/* abusing the fact that the dig and phy are coupled to see if the phy is enabled */
-		if (link->link_enc->funcs->is_dig_enabled &&
+		if (link->link_enc && link->link_enc->funcs->is_dig_enabled &&
 				link->link_enc->funcs->is_dig_enabled(link->link_enc))
 			display_count++;
 	}
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 5d9460e0dbab..3c8eb3e659af 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3457,6 +3457,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
 {
 	struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct link_encoder *link_enc = NULL;
+#endif
+
 	if (cp_psp && cp_psp->funcs.update_stream_config) {
 		struct cp_psp_stream_config config = {0};
 		enum dp_panel_mode panel_mode =
@@ -3468,8 +3472,21 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
 		config.dig_be = pipe_ctx->stream->link->link_enc_hw_inst;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 		config.stream_enc_idx = pipe_ctx->stream_res.stream_enc->id - ENGINE_ID_DIGA;
-		config.link_enc_idx = pipe_ctx->stream->link->link_enc->transmitter - TRANSMITTER_UNIPHY_A;
-		config.phy_idx = pipe_ctx->stream->link->link_enc->transmitter - TRANSMITTER_UNIPHY_A;
+		if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_PHY) {
+			link_enc = pipe_ctx->stream->link->link_enc;
+			config.phy_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
+		} else if (pipe_ctx->stream->link->dc->res_pool->funcs->link_encs_assign) {
+			/* Use link encoder assignment from current DC state - which may differ from the DC state to be
+			 * committed - when updating PSP config.
+			 */
+			link_enc = link_enc_cfg_get_link_enc_used_by_stream(
+					pipe_ctx->stream->link->dc->current_state,
+					pipe_ctx->stream);
+			config.phy_idx = 0; /* Clear phy_idx for non-physical display endpoints. */
+		}
+		ASSERT(link_enc);
+		if (link_enc)
+			config.link_enc_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
 		if (is_dp_128b_132b_signal(pipe_ctx)) {
 			config.stream_enc_idx = pipe_ctx->stream_res.hpo_dp_stream_enc->id - ENGINE_ID_HPO_DP_0;
 			config.link_enc_idx = pipe_ctx->stream->link->hpo_dp_link_enc->inst;
@@ -3576,6 +3593,7 @@ void core_link_enable_stream(
 	struct dc_stream_state *stream = pipe_ctx->stream;
 	struct dc_link *link = stream->sink->link;
 	enum dc_status status;
+	struct link_encoder *link_enc;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO;
 #endif
@@ -3585,15 +3603,22 @@ void core_link_enable_stream(
 			dc_is_virtual_signal(pipe_ctx->stream->signal))
 		return;
 
+	if (dc->res_pool->funcs->link_encs_assign && stream->link->ep_type != DISPLAY_ENDPOINT_PHY)
+		link_enc = stream->link_enc;
+	else
+		link_enc = stream->link->link_enc;
+	ASSERT(link_enc);
+
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	if (!dc_is_virtual_signal(pipe_ctx->stream->signal)
 			&& !is_dp_128b_132b_signal(pipe_ctx)) {
 #else
 	if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) {
 #endif
-		stream->link->link_enc->funcs->setup(
-			stream->link->link_enc,
-			pipe_ctx->stream->signal);
+		if (link_enc)
+			link_enc->funcs->setup(
+				link_enc,
+				pipe_ctx->stream->signal);
 		pipe_ctx->stream_res.stream_enc->funcs->setup_stereo_sync(
 			pipe_ctx->stream_res.stream_enc,
 			pipe_ctx->stream_res.tg->inst,
@@ -3748,9 +3773,10 @@ void core_link_enable_stream(
 #else
 		if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
 #endif
-			stream->link->link_enc->funcs->setup(
-				stream->link->link_enc,
-				pipe_ctx->stream->signal);
+			if (link_enc)
+				link_enc->funcs->setup(
+					link_enc,
+					pipe_ctx->stream->signal);
 
 		dc->hwss.enable_stream(pipe_ctx);
 
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 4d1ac9836dca..6fc0e12a715a 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
@@ -2625,13 +2625,27 @@ static enum dc_link_rate get_lttpr_max_link_rate(struct dc_link *link)
 
 bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap)
 {
+	struct link_encoder *link_enc = NULL;
+
 	if (!max_link_enc_cap) {
 		DC_LOG_ERROR("%s: Could not return max link encoder caps", __func__);
 		return false;
 	}
 
-	if (link->link_enc->funcs->get_max_link_cap) {
-		link->link_enc->funcs->get_max_link_cap(link->link_enc, max_link_enc_cap);
+	/* Links supporting dynamically assigned link encoder will be assigned next
+	 * available encoder if one not already assigned.
+	 */
+	if (link->is_dig_mapping_flexible &&
+			link->dc->res_pool->funcs->link_encs_assign) {
+		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+		if (link_enc == NULL)
+			link_enc = link_enc_cfg_get_next_avail_link_enc(link->dc, link->dc->current_state);
+	} else
+		link_enc = link->link_enc;
+	ASSERT(link_enc);
+
+	if (link_enc && link_enc->funcs->get_max_link_cap) {
+		link_enc->funcs->get_max_link_cap(link_enc, max_link_enc_cap);
 		return true;
 	}
 
@@ -2647,9 +2661,23 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link)
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	enum dc_link_rate lttpr_max_link_rate;
 #endif
+	struct link_encoder *link_enc = NULL;
+
+	/* Links supporting dynamically assigned link encoder will be assigned next
+	 * available encoder if one not already assigned.
+	 */
+	if (link->is_dig_mapping_flexible &&
+			link->dc->res_pool->funcs->link_encs_assign) {
+		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+		if (link_enc == NULL)
+			link_enc = link_enc_cfg_get_next_avail_link_enc(link->dc, link->dc->current_state);
+	} else
+		link_enc = link->link_enc;
+	ASSERT(link_enc);
 
 	/* get max link encoder capability */
-	link->link_enc->funcs->get_max_link_cap(link->link_enc, &max_link_cap);
+	if (link_enc)
+		link_enc->funcs->get_max_link_cap(link_enc, &max_link_cap);
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	if (max_link_cap.link_rate >= LINK_RATE_UHBR10 &&
 			!link->hpo_dp_link_enc)
@@ -2868,7 +2896,7 @@ bool dp_verify_link_cap(
 	 * PHY will sometimes be in bad state on hotplugging display from certain USB-C dongle,
 	 * so add extra cycle of enabling and disabling the PHY before first link training.
 	 */
-	if (link->link_enc->features.flags.bits.DP_IS_USB_C &&
+	if (link->link_enc && link->link_enc->features.flags.bits.DP_IS_USB_C &&
 			link->dc->debug.usbc_combo_phy_reset_wa) {
 		dp_enable_link_phy(link, link->connector_signal, dp_cs_id, cur);
 		dp_disable_link_phy(link, link->connector_signal);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
index de80a9ea4cfa..49b17bbea8d1 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
@@ -139,7 +139,7 @@ static struct dc_stream_state *get_stream_using_link_enc(
 	for (i = 0; i < state->stream_count; i++) {
 		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
 
-		if (assignment.valid && (assignment.eng_id == eng_id)) {
+		if ((assignment.valid == true) && (assignment.eng_id == eng_id)) {
 			stream_idx = i;
 			break;
 		}
@@ -254,7 +254,7 @@ struct dc_link *link_enc_cfg_get_link_using_link_enc(
 	for (i = 0; i < state->stream_count; i++) {
 		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
 
-		if (assignment.valid && (assignment.eng_id == eng_id)) {
+		if ((assignment.valid == true) && (assignment.eng_id == eng_id)) {
 			stream_idx = i;
 			break;
 		}
@@ -274,7 +274,6 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_link(
 {
 	struct link_encoder *link_enc = NULL;
 	struct display_endpoint_id ep_id;
-	int stream_idx = -1;
 	int i;
 
 	ep_id = (struct display_endpoint_id) {
@@ -283,20 +282,15 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_link(
 
 	for (i = 0; i < state->stream_count; i++) {
 		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
-
-		if (assignment.valid &&
+		if (assignment.valid == true &&
 				assignment.ep_id.link_id.id == ep_id.link_id.id &&
 				assignment.ep_id.link_id.enum_id == ep_id.link_id.enum_id &&
 				assignment.ep_id.link_id.type == ep_id.link_id.type &&
 				assignment.ep_id.ep_type == ep_id.ep_type) {
-			stream_idx = i;
-			break;
+			link_enc = link->dc->res_pool->link_encoders[assignment.eng_id - ENGINE_ID_DIGA];
 		}
 	}
 
-	if (stream_idx != -1)
-		link_enc = state->streams[stream_idx]->link_enc;
-
 	return link_enc;
 }
 
@@ -313,3 +307,14 @@ struct link_encoder *link_enc_cfg_get_next_avail_link_enc(
 
 	return link_enc;
 }
+
+struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
+		struct dc_state *state,
+		const struct dc_stream_state *stream)
+{
+	struct link_encoder *link_enc;
+
+	link_enc = link_enc_cfg_get_link_enc_used_by_link(state, stream->link);
+
+	return link_enc;
+}
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 b9570b7c557b..dae0ab761b61 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
@@ -452,9 +452,10 @@ void dp_retrain_link_dp_test(struct dc_link *link,
 			if ((&pipes[i])->stream_res.audio && !link->dc->debug.az_endpoint_mute_only)
 				(&pipes[i])->stream_res.audio->funcs->az_disable((&pipes[i])->stream_res.audio);
 
-			link->link_enc->funcs->disable_output(
-					link->link_enc,
-					SIGNAL_TYPE_DISPLAY_PORT);
+			if (link->link_enc)
+				link->link_enc->funcs->disable_output(
+						link->link_enc,
+						SIGNAL_TYPE_DISPLAY_PORT);
 
 			/* Clear current link setting. */
 			memset(&link->cur_link_settings, 0,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 57420bf10786..8766b124d4b0 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -2970,7 +2970,8 @@ enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
 		res = DC_FAIL_CONTROLLER_VALIDATE;
 
 	if (res == DC_OK) {
-		if (!link->link_enc->funcs->validate_output_with_stream(
+		if (link->ep_type == DISPLAY_ENDPOINT_PHY &&
+				!link->link_enc->funcs->validate_output_with_stream(
 						link->link_enc, stream))
 			res = DC_FAIL_ENC_VALIDATE;
 	}
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 2ce668a23fe8..102f76462752 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
@@ -46,6 +46,7 @@
 #include "transform.h"
 #include "stream_encoder.h"
 #include "link_encoder.h"
+#include "link_enc_cfg.h"
 #include "link_hwss.h"
 #include "dc_link_dp.h"
 #if defined(CONFIG_DRM_AMD_DC_DCN)
@@ -1192,6 +1193,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;
 
 	if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) {
 		pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets(
@@ -1213,6 +1215,13 @@ 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->dc->current_state, link);
+	ASSERT(link_enc);
+
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	if (is_dp_128b_132b_signal(pipe_ctx)) {
 		pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->disable(
@@ -1220,13 +1229,15 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
 		setup_dp_hpo_stream(pipe_ctx, false);
 	/* TODO - DP2.0 HW: unmap stream from link encoder here */
 	} else {
-		link->link_enc->funcs->connect_dig_be_to_fe(
-				link->link_enc,
+		if (link_enc)
+			link_enc->funcs->connect_dig_be_to_fe(
+				link_enc,
 				pipe_ctx->stream_res.stream_enc->id,
 				false);
 	}
 #else
-	link->link_enc->funcs->connect_dig_be_to_fe(
+	if (link_enc)
+		link_enc->funcs->connect_dig_be_to_fe(
 			link->link_enc,
 			pipe_ctx->stream_res.stream_enc->id,
 			false);
@@ -1666,8 +1677,9 @@ static void power_down_encoders(struct dc *dc)
 		if (signal != SIGNAL_TYPE_EDP)
 			signal = SIGNAL_TYPE_NONE;
 
-		dc->links[i]->link_enc->funcs->disable_output(
-				dc->links[i]->link_enc, signal);
+		if (dc->links[i]->ep_type == DISPLAY_ENDPOINT_PHY)
+			dc->links[i]->link_enc->funcs->disable_output(
+					dc->links[i]->link_enc, signal);
 
 		dc->links[i]->link_status.link_active = false;
 		memset(&dc->links[i]->cur_link_settings, 0,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index 7daadb6a5233..f37551e00023 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -1296,7 +1296,7 @@ struct stream_encoder *dcn10_find_first_free_match_stream_enc_for_link(
 			 * in daisy chain use case
 			 */
 			j = i;
-			if (pool->stream_enc[i]->id ==
+			if (link->ep_type == DISPLAY_ENDPOINT_PHY && pool->stream_enc[i]->id ==
 					link->link_enc->preferred_engine)
 				return pool->stream_enc[i];
 		}
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 ffc0b9ab976f..c0aed7d07eeb 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -2381,6 +2381,13 @@ 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;
+
+	if (link->is_dig_mapping_flexible &&
+			link->dc->res_pool->funcs->link_encs_assign)
+		link_enc = pipe_ctx->stream->link_enc;
+	else
+		link_enc = link->link_enc;
 
 	/* For MST, there are multiply stream go to only one link.
 	 * connect DIG back_end to front_end while enable_stream and
@@ -2397,9 +2404,9 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
 				link->hpo_dp_link_enc->inst);
 	}
 
-	if (!is_dp_128b_132b_signal(pipe_ctx))
-		link->link_enc->funcs->connect_dig_be_to_fe(
-			link->link_enc, pipe_ctx->stream_res.stream_enc->id, 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);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 7bab88356df4..e69f553d680f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -87,6 +87,7 @@
 #include "dce/dce_aux.h"
 #include "dce/dce_i2c.h"
 #include "vm_helper.h"
+#include "link_enc_cfg.h"
 
 #include "amdgpu_socbb.h"
 
@@ -1596,12 +1597,29 @@ static void get_pixel_clock_parameters(
 	const struct dc_stream_state *stream = pipe_ctx->stream;
 	struct pipe_ctx *odm_pipe;
 	int opp_cnt = 1;
+	struct dc_link *link = stream->link;
+	struct link_encoder *link_enc = NULL;
 
 	for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
 		opp_cnt++;
 
 	pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz;
-	pixel_clk_params->encoder_object_id = stream->link->link_enc->id;
+
+	/* Links supporting dynamically assigned link encoder will be assigned next
+	 * available encoder if one not already assigned.
+	 */
+	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(stream->link->dc->current_state, stream);
+		if (link_enc == NULL)
+			link_enc = link_enc_cfg_get_next_avail_link_enc(stream->link->dc,
+				stream->link->dc->current_state);
+	} else
+		link_enc = stream->link->link_enc;
+	ASSERT(link_enc);
+
+	if (link_enc)
+		pixel_clk_params->encoder_object_id = link_enc->id;
 	pixel_clk_params->signal_type = pipe_ctx->stream->signal;
 	pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
 	/* TODO: un-hardcode*/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
index 2434232fb3f5..83f223d745fa 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
@@ -157,6 +157,9 @@ void dcn31_init_hw(struct dc *dc)
 		 */
 		struct dc_link *link = dc->links[i];
 
+		if (link->ep_type != DISPLAY_ENDPOINT_PHY)
+			continue;
+
 		link->link_enc->funcs->hw_init(link->link_enc);
 
 		/* Check for enabled DIG to identify enabled display */
@@ -184,7 +187,8 @@ void dcn31_init_hw(struct dc *dc)
 						     &dpcd_power_state, sizeof(dpcd_power_state));
 			if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) {
 				/* blank dp stream before power off receiver*/
-				if (dc->links[i]->link_enc->funcs->get_dig_frontend) {
+				if (dc->links[i]->ep_type == DISPLAY_ENDPOINT_PHY &&
+						dc->links[i]->link_enc->funcs->get_dig_frontend) {
 					unsigned int fe;
 
 					fe = dc->links[i]->link_enc->funcs->get_dig_frontend(
@@ -248,7 +252,8 @@ void dcn31_init_hw(struct dc *dc)
 			for (i = 0; i < dc->link_count; i++) {
 				struct dc_link *link = dc->links[i];
 
-				if (link->link_enc->funcs->is_dig_enabled &&
+				if (link->ep_type == DISPLAY_ENDPOINT_PHY &&
+						link->link_enc->funcs->is_dig_enabled &&
 						link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
 						dc->hwss.power_down) {
 					dc->hwss.power_down(dc);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h
index 883dd8733ea4..2472c9aed095 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h
@@ -88,4 +88,9 @@ struct link_encoder *link_enc_cfg_get_next_avail_link_enc(
 	const struct dc *dc,
 	const struct dc_state *state);
 
+/* Return DIG link encoder used by stream. NULL if unused. */
+struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
+		struct dc_state *state,
+		const struct dc_stream_state *stream);
+
 #endif /* DC_INC_LINK_ENC_CFG_H_ */
-- 
2.25.1


  parent reply	other threads:[~2021-09-08 14:54 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-08 14:53 [PATCH 00/33] DC Patches September 08, 2021 Mikita Lipski
2021-09-08 14:53 ` [PATCH 01/33] drm/amd/display: Add DPCD writes at key points Mikita Lipski
2021-09-08 14:53 ` [PATCH 02/33] drm/amd/display: Fix system hang at boot Mikita Lipski
2021-09-08 14:53 ` [PATCH 03/33] drm/amd/display: move bpp range decision in decide dsc bw range function Mikita Lipski
2021-09-08 14:53 ` [PATCH 04/33] drm/amd/display: update conditions to do dfp cap ext validation Mikita Lipski
2021-09-08 14:53 ` [PATCH 05/33] drm/amd/display: Add option to defer works of hpd_rx_irq Mikita Lipski
2021-09-08 14:53 ` [PATCH 06/33] drm/amd/display: Fork thread to offload work " Mikita Lipski
2021-09-08 14:53 ` [PATCH 07/33] drm/amd/display: unblock abm when odm is enabled only on configs that support it Mikita Lipski
2021-09-08 14:53 ` [PATCH 08/33] drm/amd/display: Add flag to detect dpms force off during HPD Mikita Lipski
2021-09-08 14:54 ` Mikita Lipski [this message]
2021-09-08 14:54 ` [PATCH 10/33] drm/amd/display: Fix false BAD_FREE warning from Coverity Mikita Lipski
2021-09-08 14:54 ` [PATCH 11/33] drm/amd/display: Fix for null pointer access for ddc pin and aux engine Mikita Lipski
2021-09-08 14:54 ` [PATCH 12/33] drm/amd/display: [FW Promotion] Release 0.0.81 Mikita Lipski
2021-09-08 14:54 ` [PATCH 13/33] drm/amd/display: Revert "dc: w/a for hard hang on HPD on native DP" Mikita Lipski
2021-09-08 14:54 ` [PATCH 14/33] drm/amd/display: 3.2.151 Mikita Lipski
2021-09-08 14:54 ` [PATCH 15/33] drm/amd/display: Fix multiple memory leaks reported by coverity Mikita Lipski
2021-09-08 14:54 ` [PATCH 16/33] drm/amd/display: Get backlight from PWM if DMCU is not initialized Mikita Lipski
2021-09-08 14:54   ` Mikita Lipski
2021-09-08 14:54 ` [PATCH 17/33] drm/amd/display: Revert "Directly retrain link from debugfs" Mikita Lipski
2021-09-08 14:54 ` [PATCH 18/33] drm/amd/display: Add regamma/degamma coefficients and set sRGB when TF is BT709 Mikita Lipski
2021-09-08 14:54 ` [PATCH 19/33] drm/amd/display: Apply w/a for hard hang on HPD Mikita Lipski
2021-09-08 14:54 ` [PATCH 20/33] drm/amd/display: Optimize bandwidth on following fast update Mikita Lipski
2021-09-08 14:54 ` [PATCH 21/33] drm/amd/display: Refine condition of cursor visibility for pipe-split Mikita Lipski
2021-09-08 14:54 ` [PATCH 22/33] drm/amd/display: dsc mst 2 4K displays go dark with 2 lane HBR3 Mikita Lipski
2021-09-08 14:54   ` Mikita Lipski
2021-09-08 14:54 ` [PATCH 23/33] drm/amd/display: Add periodic detection when zstate is enabled Mikita Lipski
2021-09-08 14:54 ` [PATCH 24/33] drm/amd/display: Add helper for blanking all dp displays Mikita Lipski
2021-09-08 14:54 ` [PATCH 25/33] drm/amd/display: [FW Promotion] Release 0.0.82 Mikita Lipski
2021-09-08 14:54 ` [PATCH 26/33] drm/amd/display: Correct degamma coefficients Mikita Lipski
2021-09-08 14:54 ` [PATCH 27/33] drm/amd/display: 3.2.152 Mikita Lipski
2021-09-08 14:54 ` [PATCH 28/33] drm/amd/display: Fix unstable HPCP compliance on Chrome Barcelo Mikita Lipski
2021-09-08 14:54 ` [PATCH 29/33] drm/amd/display: Link training retry fix for abort case Mikita Lipski
2021-09-08 14:54 ` [PATCH 30/33] drm/amd/display: Revert adding degamma coefficients Mikita Lipski
2021-09-08 14:54 ` [PATCH 31/33] drm/amd/display: Add VPG and AFMT low power support for DCN3.1 Mikita Lipski
2021-09-08 14:54 ` [PATCH 32/33] drm/amd/display: remove force_enable_edp_fec param Mikita Lipski
2021-09-08 14:54 ` [PATCH 33/33] drm/amd/display: Enable mem low power control for DCN3.1 sub-IP blocks Mikita Lipski
2021-09-10 15:11 ` [PATCH 00/33] DC Patches September 08, 2021 Wheeler, Daniel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210908145424.3311-10-mikita.lipski@amd.com \
    --to=mikita.lipski@amd.com \
    --cc=Anson.Jacob@amd.com \
    --cc=Aurabindo.Pillai@amd.com \
    --cc=Bhawanpreet.Lakha@amd.com \
    --cc=Harry.Wentland@amd.com \
    --cc=Jimmy.Kizito@amd.com \
    --cc=Rodrigo.Siqueira@amd.com \
    --cc=Sunpeng.Li@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=meenakshikumar.somasundaram@amd.com \
    --cc=qingqing.zhuo@amd.com \
    --cc=roman.li@amd.com \
    --cc=solomon.chiu@amd.com \
    --cc=stylon.wang@amd.com \
    --cc=wayne.lin@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.