Skip to content

Commit 35c1d96

Browse files
Sung Joon Kimalexdeucher
authored andcommitted
drm/amd/display: Fix handling duplicate planes on one stream
[why] DML2 does not handle the case when we have a single stream sourcing 2 or more planes that are duplicates of one another. To properly handle this scenario, pipe index to plane index mapping is used to decide which plane is being processed and programmed. [how] Create static array of pipe index to plane index map. Populate the array properly and use in appropriate places. Reviewed-by: Xi (Alex) Liu <xi.liu@amd.com> Acked-by: Hersen Wu <hersenxs.wu@amd.com> Signed-off-by: Sung Joon Kim <sungkim@amd.com> Signed-off-by: Hersen Wu <hersenxs.wu@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent ed6e278 commit 35c1d96

6 files changed

Lines changed: 90 additions & 34 deletions

File tree

drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,20 @@ struct dc_pipe_mapping_scratch {
5555
struct dc_plane_pipe_pool pipe_pool;
5656
};
5757

58-
static bool get_plane_id(const struct dc_state *state, const struct dc_plane_state *plane,
59-
unsigned int stream_id, unsigned int *plane_id)
58+
static bool get_plane_id(struct dml2_context *dml2, const struct dc_state *state, const struct dc_plane_state *plane,
59+
unsigned int stream_id, unsigned int plane_index, unsigned int *plane_id)
6060
{
6161
int i, j;
62+
bool is_plane_duplicate = dml2->v20.scratch.plane_duplicate_exists;
6263

6364
if (!plane_id)
6465
return false;
6566

6667
for (i = 0; i < state->stream_count; i++) {
6768
if (state->streams[i]->stream_id == stream_id) {
6869
for (j = 0; j < state->stream_status[i].plane_count; j++) {
69-
if (state->stream_status[i].plane_states[j] == plane) {
70+
if (state->stream_status[i].plane_states[j] == plane &&
71+
(!is_plane_duplicate || (is_plane_duplicate && (j == plane_index)))) {
7072
*plane_id = (i << 16) | j;
7173
return true;
7274
}
@@ -123,8 +125,9 @@ static struct pipe_ctx *find_master_pipe_of_plane(struct dml2_context *ctx,
123125
unsigned int plane_id_assigned_to_pipe;
124126

125127
for (i = 0; i < ctx->config.dcn_pipe_count; i++) {
126-
if (state->res_ctx.pipe_ctx[i].plane_state && get_plane_id(state, state->res_ctx.pipe_ctx[i].plane_state,
127-
state->res_ctx.pipe_ctx[i].stream->stream_id, &plane_id_assigned_to_pipe)) {
128+
if (state->res_ctx.pipe_ctx[i].plane_state && get_plane_id(ctx, state, state->res_ctx.pipe_ctx[i].plane_state,
129+
state->res_ctx.pipe_ctx[i].stream->stream_id,
130+
ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_index[state->res_ctx.pipe_ctx[i].pipe_idx], &plane_id_assigned_to_pipe)) {
128131
if (plane_id_assigned_to_pipe == plane_id)
129132
return &state->res_ctx.pipe_ctx[i];
130133
}
@@ -141,8 +144,9 @@ static unsigned int find_pipes_assigned_to_plane(struct dml2_context *ctx,
141144
unsigned int plane_id_assigned_to_pipe;
142145

143146
for (i = 0; i < ctx->config.dcn_pipe_count; i++) {
144-
if (state->res_ctx.pipe_ctx[i].plane_state && get_plane_id(state, state->res_ctx.pipe_ctx[i].plane_state,
145-
state->res_ctx.pipe_ctx[i].stream->stream_id, &plane_id_assigned_to_pipe)) {
147+
if (state->res_ctx.pipe_ctx[i].plane_state && get_plane_id(ctx, state, state->res_ctx.pipe_ctx[i].plane_state,
148+
state->res_ctx.pipe_ctx[i].stream->stream_id,
149+
ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_index[state->res_ctx.pipe_ctx[i].pipe_idx], &plane_id_assigned_to_pipe)) {
146150
if (plane_id_assigned_to_pipe == plane_id)
147151
pipes[num_found++] = i;
148152
}
@@ -609,6 +613,7 @@ static struct pipe_ctx *assign_pipes_to_plane(struct dml2_context *ctx, struct d
609613
const struct dc_plane_state *plane,
610614
int odm_factor,
611615
int mpc_factor,
616+
int plane_index,
612617
struct dc_plane_pipe_pool *pipe_pool,
613618
const struct dc_state *existing_state)
614619
{
@@ -620,7 +625,7 @@ static struct pipe_ctx *assign_pipes_to_plane(struct dml2_context *ctx, struct d
620625
unsigned int next_pipe_to_assign;
621626
int odm_slice, mpc_slice;
622627

623-
if (!get_plane_id(state, plane, stream->stream_id, &plane_id)) {
628+
if (!get_plane_id(ctx, state, plane, stream->stream_id, plane_index, &plane_id)) {
624629
ASSERT(false);
625630
return master_pipe;
626631
}
@@ -667,12 +672,16 @@ static void free_pipe(struct pipe_ctx *pipe)
667672
}
668673

669674
static void free_unused_pipes_for_plane(struct dml2_context *ctx, struct dc_state *state,
670-
const struct dc_plane_state *plane, const struct dc_plane_pipe_pool *pool, unsigned int stream_id)
675+
const struct dc_plane_state *plane, const struct dc_plane_pipe_pool *pool, unsigned int stream_id, int plane_index)
671676
{
672677
int i;
678+
bool is_plane_duplicate = ctx->v20.scratch.plane_duplicate_exists;
679+
673680
for (i = 0; i < ctx->config.dcn_pipe_count; i++) {
674681
if (state->res_ctx.pipe_ctx[i].plane_state == plane &&
675682
state->res_ctx.pipe_ctx[i].stream->stream_id == stream_id &&
683+
(!is_plane_duplicate || (is_plane_duplicate &&
684+
ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_index[state->res_ctx.pipe_ctx[i].pipe_idx] == plane_index)) &&
676685
!is_pipe_used(pool, state->res_ctx.pipe_ctx[i].pipe_idx)) {
677686
free_pipe(&state->res_ctx.pipe_ctx[i]);
678687
}
@@ -717,19 +726,20 @@ static void map_pipes_for_stream(struct dml2_context *ctx, struct dc_state *stat
717726
}
718727

719728
static void map_pipes_for_plane(struct dml2_context *ctx, struct dc_state *state, const struct dc_stream_state *stream, const struct dc_plane_state *plane,
720-
struct dc_pipe_mapping_scratch *scratch, const struct dc_state *existing_state)
729+
int plane_index, struct dc_pipe_mapping_scratch *scratch, const struct dc_state *existing_state)
721730
{
722731
int odm_slice_index;
723732
unsigned int plane_id;
724733
struct pipe_ctx *master_pipe = NULL;
725734
int i;
726735

727-
if (!get_plane_id(state, plane, stream->stream_id, &plane_id)) {
736+
if (!get_plane_id(ctx, state, plane, stream->stream_id, plane_index, &plane_id)) {
728737
ASSERT(false);
729738
return;
730739
}
731740

732-
master_pipe = assign_pipes_to_plane(ctx, state, stream, plane, scratch->odm_info.odm_factor, scratch->mpc_info.mpc_factor, &scratch->pipe_pool, existing_state);
741+
master_pipe = assign_pipes_to_plane(ctx, state, stream, plane, scratch->odm_info.odm_factor,
742+
scratch->mpc_info.mpc_factor, plane_index, &scratch->pipe_pool, existing_state);
733743
sort_pipes_for_splitting(&scratch->pipe_pool);
734744

735745
for (odm_slice_index = 0; odm_slice_index < scratch->odm_info.odm_factor; odm_slice_index++) {
@@ -755,7 +765,7 @@ static void map_pipes_for_plane(struct dml2_context *ctx, struct dc_state *state
755765
}
756766
}
757767

758-
free_unused_pipes_for_plane(ctx, state, plane, &scratch->pipe_pool, stream->stream_id);
768+
free_unused_pipes_for_plane(ctx, state, plane, &scratch->pipe_pool, stream->stream_id, plane_index);
759769
}
760770

761771
static unsigned int get_mpc_factor(struct dml2_context *ctx,
@@ -768,7 +778,7 @@ static unsigned int get_mpc_factor(struct dml2_context *ctx,
768778
unsigned int plane_id;
769779
unsigned int cfg_idx;
770780

771-
get_plane_id(state, status->plane_states[plane_idx], stream_id, &plane_id);
781+
get_plane_id(ctx, state, status->plane_states[plane_idx], stream_id, plane_idx, &plane_id);
772782
cfg_idx = find_disp_cfg_idx_by_plane_id(mapping, plane_id);
773783
if (ctx->architecture == dml2_architecture_20)
774784
return (unsigned int)disp_cfg->hw.DPPPerSurface[cfg_idx];
@@ -946,8 +956,8 @@ bool dml2_map_dc_pipes(struct dml2_context *ctx, struct dc_state *state, const s
946956

947957
for (plane_index = 0; plane_index < state->stream_status[stream_index].plane_count; plane_index++) {
948958
// Planes are ordered top to bottom.
949-
if (get_plane_id(state, state->stream_status[stream_index].plane_states[plane_index],
950-
stream_id, &plane_id)) {
959+
if (get_plane_id(ctx, state, state->stream_status[stream_index].plane_states[plane_index],
960+
stream_id, plane_index, &plane_id)) {
951961
plane_disp_cfg_index = find_disp_cfg_idx_by_plane_id(mapping, plane_id);
952962

953963
// Setup mpc_info for this plane
@@ -971,7 +981,8 @@ bool dml2_map_dc_pipes(struct dml2_context *ctx, struct dc_state *state, const s
971981
// Clear the pool assignment scratch (which is per plane)
972982
memset(&scratch.pipe_pool, 0, sizeof(struct dc_plane_pipe_pool));
973983

974-
map_pipes_for_plane(ctx, state, state->streams[stream_index], state->stream_status[stream_index].plane_states[plane_index], &scratch, existing_state);
984+
map_pipes_for_plane(ctx, state, state->streams[stream_index],
985+
state->stream_status[stream_index].plane_states[plane_index], plane_index, &scratch, existing_state);
975986
} else {
976987
// Plane ID cannot be generated, therefore no DML mapping can be performed.
977988
ASSERT(false);

drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ struct dml2_dml_to_dc_pipe_mapping {
7575
bool dml_pipe_idx_to_stream_id_valid[__DML2_WRAPPER_MAX_STREAMS_PLANES__];
7676
unsigned int dml_pipe_idx_to_plane_id[__DML2_WRAPPER_MAX_STREAMS_PLANES__];
7777
bool dml_pipe_idx_to_plane_id_valid[__DML2_WRAPPER_MAX_STREAMS_PLANES__];
78+
unsigned int dml_pipe_idx_to_plane_index[__DML2_WRAPPER_MAX_STREAMS_PLANES__];
79+
bool dml_pipe_idx_to_plane_index_valid[__DML2_WRAPPER_MAX_STREAMS_PLANES__];
7880
};
7981

8082
struct dml2_wrapper_scratch {
@@ -96,6 +98,7 @@ struct dml2_wrapper_scratch {
9698

9799
struct dml2_dml_to_dc_pipe_mapping dml_to_dc_pipe_mapping;
98100
bool enable_flexible_pipe_mapping;
101+
bool plane_duplicate_exists;
99102
};
100103

101104
struct dml2_helper_det_policy_scratch {

drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -931,18 +931,20 @@ static unsigned int map_stream_to_dml_display_cfg(const struct dml2_context *dml
931931
return location;
932932
}
933933

934-
static bool get_plane_id(const struct dc_state *context, const struct dc_plane_state *plane,
935-
unsigned int stream_id, unsigned int *plane_id)
934+
static bool get_plane_id(struct dml2_context *dml2, const struct dc_state *context, const struct dc_plane_state *plane,
935+
unsigned int stream_id, unsigned int plane_index, unsigned int *plane_id)
936936
{
937937
int i, j;
938+
bool is_plane_duplicate = dml2->v20.scratch.plane_duplicate_exists;
938939

939940
if (!plane_id)
940941
return false;
941942

942943
for (i = 0; i < context->stream_count; i++) {
943944
if (context->streams[i]->stream_id == stream_id) {
944945
for (j = 0; j < context->stream_status[i].plane_count; j++) {
945-
if (context->stream_status[i].plane_states[j] == plane) {
946+
if (context->stream_status[i].plane_states[j] == plane &&
947+
(!is_plane_duplicate || (is_plane_duplicate && (j == plane_index)))) {
946948
*plane_id = (i << 16) | j;
947949
return true;
948950
}
@@ -954,13 +956,13 @@ static bool get_plane_id(const struct dc_state *context, const struct dc_plane_s
954956
}
955957

956958
static unsigned int map_plane_to_dml_display_cfg(const struct dml2_context *dml2, const struct dc_plane_state *plane,
957-
const struct dc_state *context, const struct dml_display_cfg_st *dml_dispcfg, unsigned int stream_id)
959+
const struct dc_state *context, const struct dml_display_cfg_st *dml_dispcfg, unsigned int stream_id, int plane_index)
958960
{
959961
unsigned int plane_id;
960962
int i = 0;
961963
int location = -1;
962964

963-
if (!get_plane_id(context, plane, stream_id, &plane_id)) {
965+
if (!get_plane_id(context->bw_ctx.dml2, context, plane, stream_id, plane_index, &plane_id)) {
964966
ASSERT(false);
965967
return -1;
966968
}
@@ -991,7 +993,41 @@ static void apply_legacy_svp_drr_settings(struct dml2_context *dml2, const struc
991993
}
992994
}
993995

994-
void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, const struct dc_state *context, struct dml_display_cfg_st *dml_dispcfg)
996+
static void dml2_populate_pipe_to_plane_index_mapping(struct dml2_context *dml2, struct dc_state *state)
997+
{
998+
unsigned int i;
999+
unsigned int pipe_index = 0;
1000+
unsigned int plane_index = 0;
1001+
struct dml2_dml_to_dc_pipe_mapping *dml_to_dc_pipe_mapping = &dml2->v20.scratch.dml_to_dc_pipe_mapping;
1002+
1003+
for (i = 0; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) {
1004+
dml_to_dc_pipe_mapping->dml_pipe_idx_to_plane_index_valid[i] = false;
1005+
dml_to_dc_pipe_mapping->dml_pipe_idx_to_plane_index[i] = 0;
1006+
}
1007+
1008+
for (i = 0; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) {
1009+
struct pipe_ctx *pipe = &state->res_ctx.pipe_ctx[i];
1010+
1011+
if (!pipe || !pipe->stream || !pipe->plane_state)
1012+
continue;
1013+
1014+
while (pipe) {
1015+
pipe_index = pipe->pipe_idx;
1016+
1017+
if (pipe->stream && dml_to_dc_pipe_mapping->dml_pipe_idx_to_plane_index_valid[pipe_index] == false) {
1018+
dml_to_dc_pipe_mapping->dml_pipe_idx_to_plane_index[pipe_index] = plane_index;
1019+
plane_index++;
1020+
dml_to_dc_pipe_mapping->dml_pipe_idx_to_plane_index_valid[pipe_index] = true;
1021+
}
1022+
1023+
pipe = pipe->bottom_pipe;
1024+
}
1025+
1026+
plane_index = 0;
1027+
}
1028+
}
1029+
1030+
void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_state *context, struct dml_display_cfg_st *dml_dispcfg)
9951031
{
9961032
int i = 0, j = 0;
9971033
int disp_cfg_stream_location, disp_cfg_plane_location;
@@ -1008,6 +1044,8 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, const struct d
10081044
dml_dispcfg->plane.GPUVMMaxPageTableLevels = 4;
10091045
dml_dispcfg->plane.HostVMEnable = false;
10101046

1047+
dml2_populate_pipe_to_plane_index_mapping(dml2, context);
1048+
10111049
for (i = 0; i < context->stream_count; i++) {
10121050
disp_cfg_stream_location = map_stream_to_dml_display_cfg(dml2, context->streams[i], dml_dispcfg);
10131051

@@ -1044,7 +1082,7 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, const struct d
10441082
} else {
10451083
for (j = 0; j < context->stream_status[i].plane_count; j++) {
10461084
disp_cfg_plane_location = map_plane_to_dml_display_cfg(dml2,
1047-
context->stream_status[i].plane_states[j], context, dml_dispcfg, context->streams[i]->stream_id);
1085+
context->stream_status[i].plane_states[j], context, dml_dispcfg, context->streams[i]->stream_id, j);
10481086

10491087
if (disp_cfg_plane_location < 0)
10501088
disp_cfg_plane_location = dml_dispcfg->num_surfaces++;
@@ -1068,7 +1106,7 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, const struct d
10681106

10691107
dml_dispcfg->plane.BlendingAndTiming[disp_cfg_plane_location] = disp_cfg_stream_location;
10701108

1071-
if (get_plane_id(context, context->stream_status[i].plane_states[j], context->streams[i]->stream_id,
1109+
if (get_plane_id(dml2, context, context->stream_status[i].plane_states[j], context->streams[i]->stream_id, j,
10721110
&dml2->v20.scratch.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[disp_cfg_plane_location]))
10731111
dml2->v20.scratch.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id_valid[disp_cfg_plane_location] = true;
10741112

drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ void dml2_init_soc_states(struct dml2_context *dml2, const struct dc *in_dc,
3434
void dml2_translate_ip_params(const struct dc *in_dc, struct ip_params_st *out);
3535
void dml2_translate_socbb_params(const struct dc *in_dc, struct soc_bounding_box_st *out);
3636
void dml2_translate_soc_states(const struct dc *in_dc, struct soc_states_st *out, int num_states);
37-
void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, const struct dc_state *context, struct dml_display_cfg_st *dml_dispcfg);
37+
void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_state *context, struct dml_display_cfg_st *dml_dispcfg);
3838
void dml2_update_pipe_ctx_dchub_regs(struct _vcs_dpi_dml_display_rq_regs_st *rq_regs, struct _vcs_dpi_dml_display_dlg_regs_st *disp_dlg_regs, struct _vcs_dpi_dml_display_ttu_regs_st *disp_ttu_regs, struct pipe_ctx *out);
3939
bool is_dp2p0_output_encoder(const struct pipe_ctx *pipe);
4040

drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,18 +209,20 @@ static int find_dml_pipe_idx_by_plane_id(struct dml2_context *ctx, unsigned int
209209
return -1;
210210
}
211211

212-
static bool get_plane_id(const struct dc_state *state, const struct dc_plane_state *plane,
213-
unsigned int stream_id, unsigned int *plane_id)
212+
static bool get_plane_id(struct dml2_context *dml2, const struct dc_state *state, const struct dc_plane_state *plane,
213+
unsigned int stream_id, unsigned int plane_index, unsigned int *plane_id)
214214
{
215215
int i, j;
216+
bool is_plane_duplicate = dml2->v20.scratch.plane_duplicate_exists;
216217

217218
if (!plane_id)
218219
return false;
219220

220221
for (i = 0; i < state->stream_count; i++) {
221222
if (state->streams[i]->stream_id == stream_id) {
222223
for (j = 0; j < state->stream_status[i].plane_count; j++) {
223-
if (state->stream_status[i].plane_states[j] == plane) {
224+
if (state->stream_status[i].plane_states[j] == plane &&
225+
(!is_plane_duplicate || (is_plane_duplicate && (j == plane_index)))) {
224226
*plane_id = (i << 16) | j;
225227
return true;
226228
}
@@ -304,8 +306,9 @@ void dml2_calculate_rq_and_dlg_params(const struct dc *dc, struct dc_state *cont
304306
* there is a need to know which DML pipe index maps to which DC pipe. The code below
305307
* finds a dml_pipe_index from the plane id if a plane is valid. If a plane is not valid then
306308
* it finds a dml_pipe_index from the stream id. */
307-
if (get_plane_id(context, context->res_ctx.pipe_ctx[dc_pipe_ctx_index].plane_state,
308-
context->res_ctx.pipe_ctx[dc_pipe_ctx_index].stream->stream_id, &plane_id)) {
309+
if (get_plane_id(in_ctx, context, context->res_ctx.pipe_ctx[dc_pipe_ctx_index].plane_state,
310+
context->res_ctx.pipe_ctx[dc_pipe_ctx_index].stream->stream_id,
311+
in_ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_index[context->res_ctx.pipe_ctx[dc_pipe_ctx_index].pipe_idx], &plane_id)) {
309312
dml_pipe_idx = find_dml_pipe_idx_by_plane_id(in_ctx, plane_id);
310313
} else {
311314
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);
@@ -445,8 +448,9 @@ bool dml2_verify_det_buffer_configuration(struct dml2_context *in_ctx, struct dc
445448
for (i = 0; i < MAX_PIPES; i++) {
446449
if (!display_state->res_ctx.pipe_ctx[i].stream)
447450
continue;
448-
if (get_plane_id(display_state, display_state->res_ctx.pipe_ctx[i].plane_state,
449-
display_state->res_ctx.pipe_ctx[i].stream->stream_id, &plane_id))
451+
if (get_plane_id(in_ctx, display_state, display_state->res_ctx.pipe_ctx[i].plane_state,
452+
display_state->res_ctx.pipe_ctx[i].stream->stream_id,
453+
in_ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_index[display_state->res_ctx.pipe_ctx[i].pipe_idx], &plane_id))
450454
dml_pipe_idx = find_dml_pipe_idx_by_plane_id(in_ctx, plane_id);
451455
else
452456
dml_pipe_idx = dml2_helper_find_dml_pipe_idx_by_stream_id(in_ctx, display_state->res_ctx.pipe_ctx[i].stream->stream_id);

drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ static bool dml2_validate_and_build_resource(const struct dc *in_dc, struct dc_s
639639
return result;
640640
}
641641

642-
static bool dml2_validate_only(const struct dc_state *context)
642+
static bool dml2_validate_only(struct dc_state *context)
643643
{
644644
struct dml2_context *dml2 = context->bw_ctx.dml2;
645645
unsigned int result = 0;

0 commit comments

Comments
 (0)