From: Sung Joon Kim <sungkim@xxxxxxx> [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@xxxxxxx> Acked-by: Qingqing Zhuo <qingqing.zhuo@xxxxxxx> Signed-off-by: Sung Joon Kim <sungkim@xxxxxxx> Signed-off-by: Qingqing Zhuo <Qingqing.Zhuo@xxxxxxx> --- .../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