Commit 488bb99d authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher

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: default avatarChaitanya Dhere <chaitanya.dhere@amd.com>
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Reviewed-by: default avatarRodrigo Siqueira <rodrigo.siqueira@amd.com>
Reviewed-by: default avatarJun Lei <jun.lei@amd.com>
Acked-by: default avatarRoman Li <roman.li@amd.com>
Signed-off-by: default avatarQingqing Zhuo <qingqing.zhuo@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 2c071cae
...@@ -2481,6 +2481,7 @@ static bool dcn32_resource_construct( ...@@ -2481,6 +2481,7 @@ static bool dcn32_resource_construct(
dc->dml2_options.max_segments_per_hubp = 18; dc->dml2_options.max_segments_per_hubp = 18;
dc->dml2_options.det_segment_size = DCN3_2_DET_SEG_SIZE; dc->dml2_options.det_segment_size = DCN3_2_DET_SEG_SIZE;
dc->dml2_options.map_dc_pipes_with_callbacks = true;
if (ASICREV_IS_GC_11_0_3(dc->ctx->asic_id.hw_internal_rev) && (dc->config.sdpif_request_limit_words_per_umc == 0)) if (ASICREV_IS_GC_11_0_3(dc->ctx->asic_id.hw_internal_rev) && (dc->config.sdpif_request_limit_words_per_umc == 0))
dc->config.sdpif_request_limit_words_per_umc = 16; dc->config.sdpif_request_limit_words_per_umc = 16;
......
...@@ -758,6 +758,148 @@ static void map_pipes_for_plane(struct dml2_context *ctx, struct dc_state *state ...@@ -758,6 +758,148 @@ 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, stream->stream_id); free_unused_pipes_for_plane(ctx, state, plane, &scratch->pipe_pool, stream->stream_id);
} }
static unsigned int get_mpc_factor(struct dml2_context *ctx,
const struct dc_state *state,
const struct dml_display_cfg_st *disp_cfg,
struct dml2_dml_to_dc_pipe_mapping *mapping,
const struct dc_stream_status *status, unsigned int stream_id,
int plane_idx)
{
unsigned int plane_id;
unsigned int cfg_idx;
get_plane_id(state, status->plane_states[plane_idx], stream_id, &plane_id);
cfg_idx = find_disp_cfg_idx_by_plane_id(mapping, plane_id);
if (ctx->architecture == dml2_architecture_20)
return (unsigned int)disp_cfg->hw.DPPPerSurface[cfg_idx];
ASSERT(false);
return 1;
}
static unsigned int get_odm_factor(
const struct dml2_context *ctx,
const struct dml_display_cfg_st *disp_cfg,
struct dml2_dml_to_dc_pipe_mapping *mapping,
const struct dc_stream_state *stream)
{
unsigned int cfg_idx = find_disp_cfg_idx_by_stream_id(
mapping, stream->stream_id);
if (ctx->architecture == dml2_architecture_20)
switch (disp_cfg->hw.ODMMode[cfg_idx]) {
case dml_odm_mode_bypass:
return 1;
case dml_odm_mode_combine_2to1:
return 2;
case dml_odm_mode_combine_4to1:
return 4;
default:
break;
}
ASSERT(false);
return 1;
}
static void populate_mpc_factors_for_stream(
struct dml2_context *ctx,
const struct dml_display_cfg_st *disp_cfg,
struct dml2_dml_to_dc_pipe_mapping *mapping,
const struct dc_state *state,
unsigned int stream_idx,
unsigned int odm_factor,
unsigned int mpc_factors[MAX_PIPES])
{
const struct dc_stream_status *status = &state->stream_status[stream_idx];
unsigned int stream_id = state->streams[stream_idx]->stream_id;
int i;
for (i = 0; i < status->plane_count; i++)
if (odm_factor == 1)
mpc_factors[i] = get_mpc_factor(
ctx, state, disp_cfg, mapping, status,
stream_id, i);
else
mpc_factors[i] = 1;
}
static void populate_odm_factors(const struct dml2_context *ctx,
const struct dml_display_cfg_st *disp_cfg,
struct dml2_dml_to_dc_pipe_mapping *mapping,
const struct dc_state *state,
unsigned int odm_factors[MAX_PIPES])
{
int i;
for (i = 0; i < state->stream_count; i++)
odm_factors[i] = get_odm_factor(
ctx, disp_cfg, mapping, state->streams[i]);
}
static bool map_dc_pipes_for_stream(struct dml2_context *ctx,
struct dc_state *state,
const struct dc_state *existing_state,
const struct dc_stream_state *stream,
const struct dc_stream_status *status,
unsigned int odm_factor,
unsigned int mpc_factors[MAX_PIPES])
{
int plane_idx;
bool result = true;
if (odm_factor == 1)
/*
* ODM and MPC combines are by DML design mutually exclusive.
* ODM factor of 1 means MPC factors may be greater than 1.
* In this case, we want to set ODM factor to 1 first to free up
* pipe resources from previous ODM configuration before setting
* up MPC combine to acquire more pipe resources.
*/
result &= ctx->config.callbacks.update_pipes_for_stream_with_slice_count(
state,
existing_state,
ctx->config.callbacks.dc->res_pool,
stream,
odm_factor);
for (plane_idx = 0; plane_idx < status->plane_count; plane_idx++)
result &= ctx->config.callbacks.update_pipes_for_plane_with_slice_count(
state,
existing_state,
ctx->config.callbacks.dc->res_pool,
status->plane_states[plane_idx],
mpc_factors[plane_idx]);
if (odm_factor > 1)
result &= ctx->config.callbacks.update_pipes_for_stream_with_slice_count(
state,
existing_state,
ctx->config.callbacks.dc->res_pool,
stream,
odm_factor);
return result;
}
static bool map_dc_pipes_with_callbacks(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)
{
unsigned int odm_factors[MAX_PIPES];
unsigned int mpc_factors_for_stream[MAX_PIPES];
int i;
bool result = true;
populate_odm_factors(ctx, disp_cfg, mapping, state, odm_factors);
for (i = 0; i < state->stream_count; i++) {
populate_mpc_factors_for_stream(ctx, disp_cfg, mapping, state,
i, odm_factors[i], mpc_factors_for_stream);
result &= map_dc_pipes_for_stream(ctx, state, existing_state,
state->streams[i],
&state->stream_status[i],
odm_factors[i], mpc_factors_for_stream);
}
return result;
}
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) 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)
{ {
int stream_index, plane_index, i; 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 ...@@ -772,6 +914,10 @@ bool dml2_map_dc_pipes(struct dml2_context *ctx, struct dc_state *state, const s
unsigned int odm_mode_array[__DML2_WRAPPER_MAX_STREAMS_PLANES__] = {0}, dpp_per_surface_array[__DML2_WRAPPER_MAX_STREAMS_PLANES__] = {0}; unsigned int odm_mode_array[__DML2_WRAPPER_MAX_STREAMS_PLANES__] = {0}, dpp_per_surface_array[__DML2_WRAPPER_MAX_STREAMS_PLANES__] = {0};
struct dc_pipe_mapping_scratch scratch; struct dc_pipe_mapping_scratch scratch;
if (ctx->config.map_dc_pipes_with_callbacks)
return map_dc_pipes_with_callbacks(
ctx, state, disp_cfg, mapping, existing_state);
if (ctx->architecture == dml2_architecture_21) { if (ctx->architecture == dml2_architecture_21) {
/* /*
* Extract ODM and DPP outputs from DML2.1 and map them in an array as required for pipe mapping in dml2_map_dc_pipes. * Extract ODM and DPP outputs from DML2.1 and map them in an array as required for pipe mapping in dml2_map_dc_pipes.
......
...@@ -169,6 +169,7 @@ struct dml2_configuration_options { ...@@ -169,6 +169,7 @@ struct dml2_configuration_options {
struct dml2_soc_bbox_overrides bbox_overrides; struct dml2_soc_bbox_overrides bbox_overrides;
unsigned int max_segments_per_hubp; unsigned int max_segments_per_hubp;
unsigned int det_segment_size; unsigned int det_segment_size;
bool map_dc_pipes_with_callbacks;
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment