Commit 62297b71 authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher

drm/amd/display: optimize dml2 pipe resource allocation order

[why]
There could be cases that we are transition from MPC to ODM combine.
In this case if we map pipes before unmapping MPC pipes, we might
temporarly run out of pipes. The change reorders pipe resource
allocation. So we unmapping pipes before mapping new pipes.
Reviewed-by: default avatarDillon Varone <dillon.varone@amd.com>
Acked-by: default avatarRoman Li <roman.li@amd.com>
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 7ae0caf3
......@@ -5052,7 +5052,9 @@ void resource_init_common_dml2_callbacks(struct dc *dc, struct dml2_configuratio
dml2_options->callbacks.update_pipes_for_stream_with_slice_count = &resource_update_pipes_for_stream_with_slice_count;
dml2_options->callbacks.update_pipes_for_plane_with_slice_count = &resource_update_pipes_for_plane_with_slice_count;
dml2_options->callbacks.get_mpc_slice_index = &resource_get_mpc_slice_index;
dml2_options->callbacks.get_mpc_slice_count = &resource_get_mpc_slice_count;
dml2_options->callbacks.get_odm_slice_index = &resource_get_odm_slice_index;
dml2_options->callbacks.get_odm_slice_count = &resource_get_odm_slice_count;
dml2_options->callbacks.get_opp_head = &resource_get_opp_head;
dml2_options->callbacks.get_otg_master_for_stream = &resource_get_otg_master_for_stream;
dml2_options->callbacks.get_opp_heads_for_otg_master = &resource_get_opp_heads_for_otg_master;
......
......@@ -793,7 +793,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, stream->stream_id, plane_index);
}
static unsigned int get_mpc_factor(struct dml2_context *ctx,
static unsigned int get_target_mpc_factor(struct dml2_context *ctx,
struct dc_state *state,
const struct dml_display_cfg_st *disp_cfg,
struct dml2_dml_to_dc_pipe_mapping *mapping,
......@@ -822,7 +822,7 @@ static unsigned int get_mpc_factor(struct dml2_context *ctx,
return mpc_factor;
}
static unsigned int get_odm_factor(
static unsigned int get_target_odm_factor(
const struct dml2_context *ctx,
struct dc_state *state,
const struct dml_display_cfg_st *disp_cfg,
......@@ -849,79 +849,117 @@ static unsigned int get_odm_factor(
return 1;
}
static unsigned int get_source_odm_factor(const struct dml2_context *ctx,
struct dc_state *state,
const struct dc_stream_state *stream)
{
struct pipe_ctx *otg_master = ctx->config.callbacks.get_otg_master_for_stream(&state->res_ctx, stream);
return ctx->config.callbacks.get_odm_slice_count(otg_master);
}
static unsigned int get_source_mpc_factor(const struct dml2_context *ctx,
struct dc_state *state,
const struct dc_plane_state *plane)
{
struct pipe_ctx *dpp_pipes[MAX_PIPES];
int dpp_pipe_count = ctx->config.callbacks.get_dpp_pipes_for_plane(plane,
&state->res_ctx, dpp_pipes);
ASSERT(dpp_pipe_count > 0);
return ctx->config.callbacks.get_mpc_slice_count(dpp_pipes[0]);
}
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,
struct dc_state *state,
unsigned int stream_idx,
unsigned int odm_factor,
unsigned int mpc_factors[MAX_PIPES])
struct dml2_pipe_combine_factor odm_factor,
struct dml2_pipe_combine_factor mpc_factors[MAX_PIPES])
{
const struct dc_stream_status *status = &state->stream_status[stream_idx];
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,
state->streams[stream_idx], i);
else
mpc_factors[i] = 1;
for (i = 0; i < status->plane_count; i++) {
mpc_factors[i].source = get_source_mpc_factor(ctx, state, status->plane_states[i]);
mpc_factors[i].target = (odm_factor.target == 1) ?
get_target_mpc_factor(ctx, state, disp_cfg, mapping, status, state->streams[stream_idx], 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,
struct dc_state *state,
unsigned int odm_factors[MAX_PIPES])
struct dml2_pipe_combine_factor odm_factors[MAX_PIPES])
{
int i;
for (i = 0; i < state->stream_count; i++)
odm_factors[i] = get_odm_factor(
for (i = 0; i < state->stream_count; i++) {
odm_factors[i].source = get_source_odm_factor(ctx, state, state->streams[i]);
odm_factors[i].target = get_target_odm_factor(
ctx, state, disp_cfg, mapping, state->streams[i]);
}
}
static bool map_dc_pipes_for_stream(struct dml2_context *ctx,
static bool unmap_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])
struct dml2_pipe_combine_factor odm_factor,
struct dml2_pipe_combine_factor 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.
*/
for (plane_idx = 0; plane_idx < status->plane_count; plane_idx++)
if (mpc_factors[plane_idx].target < mpc_factors[plane_idx].source)
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].target);
if (odm_factor.target < odm_factor.source)
result &= ctx->config.callbacks.update_pipes_for_stream_with_slice_count(
state,
existing_state,
ctx->config.callbacks.dc->res_pool,
stream,
odm_factor);
odm_factor.target);
return result;
}
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,
struct dml2_pipe_combine_factor odm_factor,
struct dml2_pipe_combine_factor mpc_factors[MAX_PIPES])
{
int plane_idx;
bool result = true;
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)
if (mpc_factors[plane_idx].target > mpc_factors[plane_idx].source)
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].target);
if (odm_factor.target > odm_factor.source)
result &= ctx->config.callbacks.update_pipes_for_stream_with_slice_count(
state,
existing_state,
ctx->config.callbacks.dc->res_pool,
stream,
odm_factor);
odm_factor.target);
return result;
}
......@@ -931,20 +969,20 @@ static bool map_dc_pipes_with_callbacks(struct dml2_context *ctx,
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_odm_factors(ctx, disp_cfg, mapping, state, ctx->pipe_combine_scratch.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);
}
i, ctx->pipe_combine_scratch.odm_factors[i], ctx->pipe_combine_scratch.mpc_factors[i]);
for (i = 0; i < state->stream_count; i++)
result &= unmap_dc_pipes_for_stream(ctx, state, existing_state, state->streams[i],
&state->stream_status[i], ctx->pipe_combine_scratch.odm_factors[i], ctx->pipe_combine_scratch.mpc_factors[i]);
for (i = 0; i < state->stream_count; i++)
result &= map_dc_pipes_for_stream(ctx, state, existing_state, state->streams[i],
&state->stream_status[i], ctx->pipe_combine_scratch.odm_factors[i], ctx->pipe_combine_scratch.mpc_factors[i]);
return result;
}
......
......@@ -109,10 +109,21 @@ enum dml2_architecture {
dml2_architecture_20,
};
struct dml2_pipe_combine_factor {
unsigned int source;
unsigned int target;
};
struct dml2_pipe_combine_scratch {
struct dml2_pipe_combine_factor odm_factors[MAX_PIPES];
struct dml2_pipe_combine_factor mpc_factors[MAX_PIPES][MAX_PIPES];
};
struct dml2_context {
enum dml2_architecture architecture;
struct dml2_configuration_options config;
struct dml2_helper_det_policy_scratch det_helper_scratch;
struct dml2_pipe_combine_scratch pipe_combine_scratch;
union {
struct {
struct display_mode_lib_st dml_core_ctx;
......
......@@ -86,7 +86,9 @@ struct dml2_dc_callbacks {
const struct dc_plane_state *plane,
int slice_count);
int (*get_odm_slice_index)(const struct pipe_ctx *opp_head);
int (*get_odm_slice_count)(const struct pipe_ctx *opp_head);
int (*get_mpc_slice_index)(const struct pipe_ctx *dpp_pipe);
int (*get_mpc_slice_count)(const struct pipe_ctx *dpp_pipe);
struct pipe_ctx *(*get_opp_head)(const struct pipe_ctx *pipe_ctx);
struct pipe_ctx *(*get_otg_master_for_stream)(
struct resource_context *res_ctx,
......
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