[PATCH v3 08/16] drm/amd/display: Handle multiple streams sourcing same surface

Rodrigo Siqueira Rodrigo.Siqueira at amd.com
Wed Oct 4 21:21:02 UTC 2023


From: Sung Joon Kim <sungkim at amd.com>

[why]
There are cases where more than 1 stream can be mapped to the same
surface. DML2.0 does not seem to handle these cases.

[how]
Make sure to account for the stream id when deriving the plane id. By
doing this, each plane id will be unique based on the stream id.

Reviewed-by: Charlene Liu <charlene.liu at amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo at amd.com>
Signed-off-by: Sung Joon Kim <sungkim at amd.com>
Signed-off-by: Qingqing Zhuo <Qingqing.Zhuo at amd.com>
---
 .../display/dc/dml2/dml2_dc_resource_mgmt.c   | 41 ++++++++++++-------
 .../display/dc/dml2/dml2_translation_helper.c | 25 ++++++-----
 .../gpu/drm/amd/display/dc/dml2/dml2_utils.c  | 19 +++++----
 3 files changed, 53 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
index 7fd0e1c3d552..8da145fd4d7b 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
@@ -53,7 +53,8 @@ struct dc_pipe_mapping_scratch {
 	struct dc_plane_pipe_pool pipe_pool;
 };
 
-static bool get_plane_id(const struct dc_state *state, const struct dc_plane_state *plane, unsigned int *plane_id)
+static bool get_plane_id(const struct dc_state *state, const struct dc_plane_state *plane,
+	unsigned int stream_id, unsigned int *plane_id)
 {
 	int i, j;
 
@@ -61,10 +62,12 @@ static bool get_plane_id(const struct dc_state *state, const struct dc_plane_sta
 		return false;
 
 	for (i = 0; i < state->stream_count; i++) {
-		for (j = 0; j < state->stream_status[i].plane_count; j++) {
-			if (state->stream_status[i].plane_states[j] == plane) {
-				*plane_id = (i << 16) | j;
-				return true;
+		if (state->streams[i]->stream_id == stream_id) {
+			for (j = 0; j < state->stream_status[i].plane_count; j++) {
+				if (state->stream_status[i].plane_states[j] == plane) {
+					*plane_id = (i << 16) | j;
+					return true;
+				}
 			}
 		}
 	}
@@ -111,13 +114,15 @@ static struct pipe_ctx *find_master_pipe_of_stream(struct dml2_context *ctx, str
 	return NULL;
 }
 
-static struct pipe_ctx *find_master_pipe_of_plane(struct dml2_context *ctx, struct dc_state *state, unsigned int plane_id)
+static struct pipe_ctx *find_master_pipe_of_plane(struct dml2_context *ctx,
+	struct dc_state *state, unsigned int plane_id)
 {
 	int i;
 	unsigned int plane_id_assigned_to_pipe;
 
 	for (i = 0; i < ctx->config.dcn_pipe_count; i++) {
-		if (state->res_ctx.pipe_ctx[i].plane_state && get_plane_id(state, state->res_ctx.pipe_ctx[i].plane_state, &plane_id_assigned_to_pipe)) {
+		if (state->res_ctx.pipe_ctx[i].plane_state && get_plane_id(state, state->res_ctx.pipe_ctx[i].plane_state,
+			state->res_ctx.pipe_ctx[i].stream->stream_id, &plane_id_assigned_to_pipe)) {
 			if (plane_id_assigned_to_pipe == plane_id)
 				return &state->res_ctx.pipe_ctx[i];
 		}
@@ -126,14 +131,16 @@ static struct pipe_ctx *find_master_pipe_of_plane(struct dml2_context *ctx, stru
 	return NULL;
 }
 
-static unsigned int find_pipes_assigned_to_plane(struct dml2_context *ctx, struct dc_state *state, unsigned int plane_id, unsigned int *pipes)
+static unsigned int find_pipes_assigned_to_plane(struct dml2_context *ctx,
+	struct dc_state *state, unsigned int plane_id, unsigned int *pipes)
 {
 	int i;
 	unsigned int num_found = 0;
 	unsigned int plane_id_assigned_to_pipe;
 
 	for (i = 0; i < ctx->config.dcn_pipe_count; i++) {
-		if (state->res_ctx.pipe_ctx[i].plane_state && get_plane_id(state, state->res_ctx.pipe_ctx[i].plane_state, &plane_id_assigned_to_pipe)) {
+		if (state->res_ctx.pipe_ctx[i].plane_state && get_plane_id(state, state->res_ctx.pipe_ctx[i].plane_state,
+			state->res_ctx.pipe_ctx[i].stream->stream_id, &plane_id_assigned_to_pipe)) {
 			if (plane_id_assigned_to_pipe == plane_id)
 				pipes[num_found++] = i;
 		}
@@ -499,7 +506,7 @@ static struct pipe_ctx *assign_pipes_to_plane(struct dml2_context *ctx, struct d
 	unsigned int next_pipe_to_assign;
 	int odm_slice, mpc_slice;
 
-	if (!get_plane_id(state, plane, &plane_id)) {
+	if (!get_plane_id(state, plane, stream->stream_id, &plane_id)) {
 		ASSERT(false);
 		return master_pipe;
 	}
@@ -545,11 +552,14 @@ static void free_pipe(struct pipe_ctx *pipe)
 	memset(pipe, 0, sizeof(struct pipe_ctx));
 }
 
-static void free_unused_pipes_for_plane(struct dml2_context *ctx, struct dc_state *state, const struct dc_plane_state *plane, const struct dc_plane_pipe_pool *pool)
+static void free_unused_pipes_for_plane(struct dml2_context *ctx, struct dc_state *state,
+	const struct dc_plane_state *plane, const struct dc_plane_pipe_pool *pool, unsigned int stream_id)
 {
 	int i;
 	for (i = 0; i < ctx->config.dcn_pipe_count; i++) {
-		if (state->res_ctx.pipe_ctx[i].plane_state == plane && !is_pipe_used(pool, state->res_ctx.pipe_ctx[i].pipe_idx)) {
+		if (state->res_ctx.pipe_ctx[i].plane_state == plane &&
+			state->res_ctx.pipe_ctx[i].stream->stream_id == stream_id &&
+			!is_pipe_used(pool, state->res_ctx.pipe_ctx[i].pipe_idx)) {
 			free_pipe(&state->res_ctx.pipe_ctx[i]);
 		}
 	}
@@ -600,7 +610,7 @@ static void map_pipes_for_plane(struct dml2_context *ctx, struct dc_state *state
 	struct pipe_ctx *master_pipe = NULL;
 	int i;
 
-	if (!get_plane_id(state, plane, &plane_id)) {
+	if (!get_plane_id(state, plane, stream->stream_id, &plane_id)) {
 		ASSERT(false);
 		return;
 	}
@@ -631,7 +641,7 @@ static void map_pipes_for_plane(struct dml2_context *ctx, struct dc_state *state
 		}
 	}
 
-	free_unused_pipes_for_plane(ctx, state, plane, &scratch->pipe_pool);
+	free_unused_pipes_for_plane(ctx, state, plane, &scratch->pipe_pool, stream->stream_id);
 }
 
 bool dml2_map_dc_pipes(struct dml2_context *ctx, struct dc_state *state, const struct dml_display_cfg_st *disp_cfg, struct dml2_dml_to_dc_pipe_mapping *mapping, const struct dc_state *existing_state)
@@ -688,7 +698,8 @@ bool dml2_map_dc_pipes(struct dml2_context *ctx, struct dc_state *state, const s
 
 		for (plane_index = 0; plane_index < state->stream_status[stream_index].plane_count; plane_index++) {
 			// Planes are ordered top to bottom.
-			if (get_plane_id(state, state->stream_status[stream_index].plane_states[plane_index], &plane_id)) {
+			if (get_plane_id(state, state->stream_status[stream_index].plane_states[plane_index],
+				stream_id, &plane_id)) {
 				plane_disp_cfg_index = find_disp_cfg_idx_by_plane_id(mapping, plane_id);
 
 				// Setup mpc_info for this plane
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
index de58c7b867e8..2dd8eedfc17d 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
@@ -926,7 +926,8 @@ static unsigned int map_stream_to_dml_display_cfg(const struct dml2_context *dml
 	return location;
 }
 
-static bool get_plane_id(const struct dc_state *context, const struct dc_plane_state *plane, unsigned int *plane_id)
+static bool get_plane_id(const struct dc_state *context, const struct dc_plane_state *plane,
+		unsigned int stream_id, unsigned int *plane_id)
 {
 	int i, j;
 
@@ -934,10 +935,12 @@ static bool get_plane_id(const struct dc_state *context, const struct dc_plane_s
 		return false;
 
 	for (i = 0; i < context->stream_count; i++) {
-		for (j = 0; j < context->stream_status[i].plane_count; j++) {
-			if (context->stream_status[i].plane_states[j] == plane) {
-				*plane_id = (i << 16) | j;
-				return true;
+		if (context->streams[i]->stream_id == stream_id) {
+			for (j = 0; j < context->stream_status[i].plane_count; j++) {
+				if (context->stream_status[i].plane_states[j] == plane) {
+					*plane_id = (i << 16) | j;
+					return true;
+				}
 			}
 		}
 	}
@@ -945,14 +948,14 @@ static bool get_plane_id(const struct dc_state *context, const struct dc_plane_s
 	return false;
 }
 
-static unsigned int map_plane_to_dml_display_cfg(const struct dml2_context *dml2,
-		const struct dc_plane_state *plane, const struct dc_state *context, const struct dml_display_cfg_st *dml_dispcfg)
+static unsigned int map_plane_to_dml_display_cfg(const struct dml2_context *dml2, const struct dc_plane_state *plane,
+		const struct dc_state *context, const struct dml_display_cfg_st *dml_dispcfg, unsigned int stream_id)
 {
 	unsigned int plane_id;
 	int i = 0;
 	int location = -1;
 
-	if (!get_plane_id(context, plane, &plane_id)) {
+	if (!get_plane_id(context, plane, stream_id, &plane_id)) {
 		ASSERT(false);
 		return -1;
 	}
@@ -1035,7 +1038,8 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, const struct d
 			dml2->v20.scratch.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id_valid[disp_cfg_plane_location] = true;
 		} else {
 			for (j = 0; j < context->stream_status[i].plane_count; j++) {
-				disp_cfg_plane_location = map_plane_to_dml_display_cfg(dml2, context->stream_status[i].plane_states[j], context, dml_dispcfg);
+				disp_cfg_plane_location = map_plane_to_dml_display_cfg(dml2,
+					context->stream_status[i].plane_states[j], context, dml_dispcfg, context->streams[i]->stream_id);
 
 				if (disp_cfg_plane_location < 0)
 					disp_cfg_plane_location = dml_dispcfg->num_surfaces++;
@@ -1059,7 +1063,8 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, const struct d
 
 				dml_dispcfg->plane.BlendingAndTiming[disp_cfg_plane_location] = disp_cfg_stream_location;
 
-				if (get_plane_id(context, context->stream_status[i].plane_states[j], &dml2->v20.scratch.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[disp_cfg_plane_location]))
+				if (get_plane_id(context, context->stream_status[i].plane_states[j], context->streams[i]->stream_id,
+					&dml2->v20.scratch.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[disp_cfg_plane_location]))
 					dml2->v20.scratch.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id_valid[disp_cfg_plane_location] = true;
 
 				if (j >= 1) {
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c
index da18c4b8c257..946a98af0020 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c
@@ -207,7 +207,8 @@ static int find_dml_pipe_idx_by_plane_id(struct dml2_context *ctx, unsigned int
 	return -1;
 }
 
-static bool get_plane_id(const struct dc_state *state, const struct dc_plane_state *plane, unsigned int *plane_id)
+static bool get_plane_id(const struct dc_state *state, const struct dc_plane_state *plane,
+	unsigned int stream_id, unsigned int *plane_id)
 {
 	int i, j;
 
@@ -215,10 +216,12 @@ static bool get_plane_id(const struct dc_state *state, const struct dc_plane_sta
 		return false;
 
 	for (i = 0; i < state->stream_count; i++) {
-		for (j = 0; j < state->stream_status[i].plane_count; j++) {
-			if (state->stream_status[i].plane_states[j] == plane) {
-				*plane_id = (i << 16) | j;
-				return true;
+		if (state->streams[i]->stream_id == stream_id) {
+			for (j = 0; j < state->stream_status[i].plane_count; j++) {
+				if (state->stream_status[i].plane_states[j] == plane) {
+					*plane_id = (i << 16) | j;
+					return true;
+				}
 			}
 		}
 	}
@@ -299,7 +302,8 @@ void dml2_calculate_rq_and_dlg_params(const struct dc *dc, struct dc_state *cont
 		 * there is a need to know which DML pipe index maps to which DC pipe. The code below
 		 * finds a dml_pipe_index from the plane id if a plane is valid. If a plane is not valid then
 		 * it finds a dml_pipe_index from the stream id. */
-		if (get_plane_id(context, context->res_ctx.pipe_ctx[dc_pipe_ctx_index].plane_state, &plane_id)) {
+		if (get_plane_id(context, context->res_ctx.pipe_ctx[dc_pipe_ctx_index].plane_state,
+			context->res_ctx.pipe_ctx[dc_pipe_ctx_index].stream->stream_id, &plane_id)) {
 			dml_pipe_idx = find_dml_pipe_idx_by_plane_id(in_ctx, plane_id);
 		} else {
 			dml_pipe_idx = dml2_helper_find_dml_pipe_idx_by_stream_id(in_ctx, context->res_ctx.pipe_ctx[dc_pipe_ctx_index].stream->stream_id);
@@ -435,7 +439,8 @@ bool dml2_verify_det_buffer_configuration(struct dml2_context *in_ctx, struct dc
 	for (i = 0; i < MAX_PIPES; i++) {
 		if (!display_state->res_ctx.pipe_ctx[i].stream)
 			continue;
-		if (get_plane_id(display_state, display_state->res_ctx.pipe_ctx[i].plane_state, &plane_id))
+		if (get_plane_id(display_state, display_state->res_ctx.pipe_ctx[i].plane_state,
+			display_state->res_ctx.pipe_ctx[i].stream->stream_id, &plane_id))
 			dml_pipe_idx = find_dml_pipe_idx_by_plane_id(in_ctx, plane_id);
 		else
 			dml_pipe_idx = dml2_helper_find_dml_pipe_idx_by_stream_id(in_ctx, display_state->res_ctx.pipe_ctx[i].stream->stream_id);
-- 
2.40.1



More information about the amd-gfx mailing list