Skip to content

Commit 488bb99

Browse files
Wenjing Liualexdeucher
authored andcommitted
drm/amd/display: implement map dc pipe with callback in DML2
[why] Unify pipe resource management logic in dc resource layer. V2: Add default case for switch. CC: Hamza Mahfooz <hamza.mahfooz@amd.com> Reviewed-by: Chaitanya Dhere <chaitanya.dhere@amd.com> Signed-off-by: Wenjing Liu <wenjing.liu@amd.com> Reviewed-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com> Reviewed-by: Jun Lei <jun.lei@amd.com> Acked-by: Roman Li <roman.li@amd.com> Signed-off-by: Qingqing Zhuo <qingqing.zhuo@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent 2c071ca commit 488bb99

3 files changed

Lines changed: 148 additions & 0 deletions

File tree

drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2481,6 +2481,7 @@ static bool dcn32_resource_construct(
24812481

24822482
dc->dml2_options.max_segments_per_hubp = 18;
24832483
dc->dml2_options.det_segment_size = DCN3_2_DET_SEG_SIZE;
2484+
dc->dml2_options.map_dc_pipes_with_callbacks = true;
24842485

24852486
if (ASICREV_IS_GC_11_0_3(dc->ctx->asic_id.hw_internal_rev) && (dc->config.sdpif_request_limit_words_per_umc == 0))
24862487
dc->config.sdpif_request_limit_words_per_umc = 16;

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

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,148 @@ static void map_pipes_for_plane(struct dml2_context *ctx, struct dc_state *state
758758
free_unused_pipes_for_plane(ctx, state, plane, &scratch->pipe_pool, stream->stream_id);
759759
}
760760

761+
static unsigned int get_mpc_factor(struct dml2_context *ctx,
762+
const struct dc_state *state,
763+
const struct dml_display_cfg_st *disp_cfg,
764+
struct dml2_dml_to_dc_pipe_mapping *mapping,
765+
const struct dc_stream_status *status, unsigned int stream_id,
766+
int plane_idx)
767+
{
768+
unsigned int plane_id;
769+
unsigned int cfg_idx;
770+
771+
get_plane_id(state, status->plane_states[plane_idx], stream_id, &plane_id);
772+
cfg_idx = find_disp_cfg_idx_by_plane_id(mapping, plane_id);
773+
if (ctx->architecture == dml2_architecture_20)
774+
return (unsigned int)disp_cfg->hw.DPPPerSurface[cfg_idx];
775+
ASSERT(false);
776+
return 1;
777+
}
778+
779+
static unsigned int get_odm_factor(
780+
const struct dml2_context *ctx,
781+
const struct dml_display_cfg_st *disp_cfg,
782+
struct dml2_dml_to_dc_pipe_mapping *mapping,
783+
const struct dc_stream_state *stream)
784+
{
785+
unsigned int cfg_idx = find_disp_cfg_idx_by_stream_id(
786+
mapping, stream->stream_id);
787+
788+
if (ctx->architecture == dml2_architecture_20)
789+
switch (disp_cfg->hw.ODMMode[cfg_idx]) {
790+
case dml_odm_mode_bypass:
791+
return 1;
792+
case dml_odm_mode_combine_2to1:
793+
return 2;
794+
case dml_odm_mode_combine_4to1:
795+
return 4;
796+
default:
797+
break;
798+
}
799+
ASSERT(false);
800+
return 1;
801+
}
802+
803+
static void populate_mpc_factors_for_stream(
804+
struct dml2_context *ctx,
805+
const struct dml_display_cfg_st *disp_cfg,
806+
struct dml2_dml_to_dc_pipe_mapping *mapping,
807+
const struct dc_state *state,
808+
unsigned int stream_idx,
809+
unsigned int odm_factor,
810+
unsigned int mpc_factors[MAX_PIPES])
811+
{
812+
const struct dc_stream_status *status = &state->stream_status[stream_idx];
813+
unsigned int stream_id = state->streams[stream_idx]->stream_id;
814+
int i;
815+
816+
for (i = 0; i < status->plane_count; i++)
817+
if (odm_factor == 1)
818+
mpc_factors[i] = get_mpc_factor(
819+
ctx, state, disp_cfg, mapping, status,
820+
stream_id, i);
821+
else
822+
mpc_factors[i] = 1;
823+
}
824+
825+
static void populate_odm_factors(const struct dml2_context *ctx,
826+
const struct dml_display_cfg_st *disp_cfg,
827+
struct dml2_dml_to_dc_pipe_mapping *mapping,
828+
const struct dc_state *state,
829+
unsigned int odm_factors[MAX_PIPES])
830+
{
831+
int i;
832+
833+
for (i = 0; i < state->stream_count; i++)
834+
odm_factors[i] = get_odm_factor(
835+
ctx, disp_cfg, mapping, state->streams[i]);
836+
}
837+
838+
static bool map_dc_pipes_for_stream(struct dml2_context *ctx,
839+
struct dc_state *state,
840+
const struct dc_state *existing_state,
841+
const struct dc_stream_state *stream,
842+
const struct dc_stream_status *status,
843+
unsigned int odm_factor,
844+
unsigned int mpc_factors[MAX_PIPES])
845+
{
846+
int plane_idx;
847+
bool result = true;
848+
849+
if (odm_factor == 1)
850+
/*
851+
* ODM and MPC combines are by DML design mutually exclusive.
852+
* ODM factor of 1 means MPC factors may be greater than 1.
853+
* In this case, we want to set ODM factor to 1 first to free up
854+
* pipe resources from previous ODM configuration before setting
855+
* up MPC combine to acquire more pipe resources.
856+
*/
857+
result &= ctx->config.callbacks.update_pipes_for_stream_with_slice_count(
858+
state,
859+
existing_state,
860+
ctx->config.callbacks.dc->res_pool,
861+
stream,
862+
odm_factor);
863+
for (plane_idx = 0; plane_idx < status->plane_count; plane_idx++)
864+
result &= ctx->config.callbacks.update_pipes_for_plane_with_slice_count(
865+
state,
866+
existing_state,
867+
ctx->config.callbacks.dc->res_pool,
868+
status->plane_states[plane_idx],
869+
mpc_factors[plane_idx]);
870+
if (odm_factor > 1)
871+
result &= ctx->config.callbacks.update_pipes_for_stream_with_slice_count(
872+
state,
873+
existing_state,
874+
ctx->config.callbacks.dc->res_pool,
875+
stream,
876+
odm_factor);
877+
return result;
878+
}
879+
880+
static bool map_dc_pipes_with_callbacks(struct dml2_context *ctx,
881+
struct dc_state *state,
882+
const struct dml_display_cfg_st *disp_cfg,
883+
struct dml2_dml_to_dc_pipe_mapping *mapping,
884+
const struct dc_state *existing_state)
885+
{
886+
unsigned int odm_factors[MAX_PIPES];
887+
unsigned int mpc_factors_for_stream[MAX_PIPES];
888+
int i;
889+
bool result = true;
890+
891+
populate_odm_factors(ctx, disp_cfg, mapping, state, odm_factors);
892+
for (i = 0; i < state->stream_count; i++) {
893+
populate_mpc_factors_for_stream(ctx, disp_cfg, mapping, state,
894+
i, odm_factors[i], mpc_factors_for_stream);
895+
result &= map_dc_pipes_for_stream(ctx, state, existing_state,
896+
state->streams[i],
897+
&state->stream_status[i],
898+
odm_factors[i], mpc_factors_for_stream);
899+
}
900+
return result;
901+
}
902+
761903
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)
762904
{
763905
int stream_index, plane_index, i;
@@ -772,6 +914,10 @@ bool dml2_map_dc_pipes(struct dml2_context *ctx, struct dc_state *state, const s
772914
unsigned int odm_mode_array[__DML2_WRAPPER_MAX_STREAMS_PLANES__] = {0}, dpp_per_surface_array[__DML2_WRAPPER_MAX_STREAMS_PLANES__] = {0};
773915
struct dc_pipe_mapping_scratch scratch;
774916

917+
if (ctx->config.map_dc_pipes_with_callbacks)
918+
return map_dc_pipes_with_callbacks(
919+
ctx, state, disp_cfg, mapping, existing_state);
920+
775921
if (ctx->architecture == dml2_architecture_21) {
776922
/*
777923
* Extract ODM and DPP outputs from DML2.1 and map them in an array as required for pipe mapping in dml2_map_dc_pipes.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ struct dml2_configuration_options {
169169
struct dml2_soc_bbox_overrides bbox_overrides;
170170
unsigned int max_segments_per_hubp;
171171
unsigned int det_segment_size;
172+
bool map_dc_pipes_with_callbacks;
172173
};
173174

174175
/*

0 commit comments

Comments
 (0)