Commit 9d1e1722 authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher

drm/amd/display: use new pipe allocation interface in dcn32 fpu

This commit implements a new pipe resource allocation logic for DCN32
when windowed ODM MPO flag is set to enable testing. By default the
flag is not set. It will be toggled on after we complete testing.
Reviewed-by: default avatarJun Lei <jun.lei@amd.com>
Acked-by: default avatarHamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 21741810
......@@ -1654,6 +1654,188 @@ static bool dcn32_split_stream_for_mpc_or_odm(
return true;
}
struct pipe_slice_table {
struct {
struct dc_stream_state *stream;
int slice_count;
} odm_combines[MAX_STREAMS];
int odm_combine_count;
struct {
struct dc_plane_state *plane;
int slice_count;
} mpc_combines[MAX_SURFACES];
int mpc_combine_count;
};
static void update_slice_table_for_stream(struct pipe_slice_table *table,
struct dc_stream_state *stream, int diff)
{
int i;
for (i = 0; i < table->odm_combine_count; i++) {
if (table->odm_combines[i].stream == stream) {
table->odm_combines[i].slice_count += diff;
break;
}
}
if (i == table->odm_combine_count) {
table->odm_combine_count++;
table->odm_combines[i].stream = stream;
table->odm_combines[i].slice_count = diff;
}
}
static void update_slice_table_for_plane(struct pipe_slice_table *table,
struct dc_plane_state *plane, int diff)
{
int i;
for (i = 0; i < table->mpc_combine_count; i++) {
if (table->mpc_combines[i].plane == plane) {
table->mpc_combines[i].slice_count += diff;
break;
}
}
if (i == table->mpc_combine_count) {
table->mpc_combine_count++;
table->mpc_combines[i].plane = plane;
table->mpc_combines[i].slice_count = diff;
}
}
static void init_pipe_slice_table_from_context(
struct pipe_slice_table *table,
struct dc_state *context)
{
int i, j;
struct pipe_ctx *otg_master;
struct pipe_ctx *dpp_pipes[MAX_PIPES];
struct dc_stream_state *stream;
int count;
memset(table, 0, sizeof(*table));
for (i = 0; i < context->stream_count; i++) {
stream = context->streams[i];
otg_master = resource_get_otg_master_for_stream(
&context->res_ctx, stream);
count = resource_get_odm_slice_count(otg_master);
update_slice_table_for_stream(table, stream, count);
count = resource_get_dpp_pipes_for_opp_head(otg_master,
&context->res_ctx, dpp_pipes);
for (j = 0; j < count; j++)
if (dpp_pipes[j]->plane_state)
update_slice_table_for_plane(table,
dpp_pipes[j]->plane_state, 1);
}
}
static bool update_pipe_slice_table_with_split_flags(
struct pipe_slice_table *table,
struct dc *dc,
struct dc_state *context,
struct vba_vars_st *vba,
int split[MAX_PIPES],
bool merge[MAX_PIPES])
{
/* NOTE: we are deprecating the support for the concept of pipe splitting
* or pipe merging. Instead we append slices to the end and remove
* slices from the end. The following code converts a pipe split or
* merge to an append or remove operation.
*
* For example:
* When split flags describe the following pipe connection transition
*
* from:
* pipe 0 (split=2) -> pipe 1 (split=2)
* to: (old behavior)
* pipe 0 -> pipe 2 -> pipe 1 -> pipe 3
*
* the code below actually does:
* pipe 0 -> pipe 1 -> pipe 2 -> pipe 3
*
* This is the new intended behavior and for future DCNs we will retire
* the old concept completely.
*/
struct pipe_ctx *pipe;
bool odm;
int i;
bool updated = false;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
pipe = &context->res_ctx.pipe_ctx[i];
if (merge[i]) {
if (resource_is_pipe_type(pipe, OPP_HEAD))
/* merging OPP head means reducing ODM slice
* count by 1
*/
update_slice_table_for_stream(table, pipe->stream, -1);
else if (resource_is_pipe_type(pipe, DPP_PIPE) &&
resource_get_odm_slice_index(resource_get_opp_head(pipe)) == 0)
/* merging DPP pipe of the first ODM slice means
* reducing MPC slice count by 1
*/
update_slice_table_for_plane(table, pipe->plane_state, -1);
updated = true;
}
if (split[i]) {
odm = vba->ODMCombineEnabled[vba->pipe_plane[i]] !=
dm_odm_combine_mode_disabled;
if (odm && resource_is_pipe_type(pipe, OPP_HEAD))
update_slice_table_for_stream(
table, pipe->stream, split[i] - 1);
else if (!odm && resource_is_pipe_type(pipe, DPP_PIPE))
update_slice_table_for_plane(
table, pipe->plane_state, split[i] - 1);
updated = true;
}
}
return updated;
}
static void update_pipes_with_slice_table(struct dc *dc, struct dc_state *context,
struct pipe_slice_table *table)
{
int i;
for (i = 0; i < table->odm_combine_count; i++) {
resource_update_pipes_for_stream_with_slice_count(context,
dc->current_state, dc->res_pool,
table->odm_combines[i].stream,
table->odm_combines[i].slice_count);
/* TODO: move this into the function above */
dcn20_build_mapped_resource(dc, context,
table->odm_combines[i].stream);
}
for (i = 0; i < table->mpc_combine_count; i++)
resource_update_pipes_for_plane_with_slice_count(context,
dc->current_state, dc->res_pool,
table->mpc_combines[i].plane,
table->mpc_combines[i].slice_count);
}
static bool update_pipes_with_split_flags(struct dc *dc, struct dc_state *context,
struct vba_vars_st *vba, int split[MAX_PIPES],
bool merge[MAX_PIPES])
{
struct pipe_slice_table slice_table;
bool updated;
init_pipe_slice_table_from_context(&slice_table, context);
updated = update_pipe_slice_table_with_split_flags(
&slice_table, dc, context, vba,
split, merge);
update_pipes_with_slice_table(dc, context, &slice_table);
return updated;
}
bool dcn32_internal_validate_bw(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
......@@ -1749,6 +1931,13 @@ bool dcn32_internal_validate_bw(struct dc *dc,
pipe_idx++;
}
if (dc->config.enable_windowed_mpo_odm) {
repopulate_pipes = update_pipes_with_split_flags(
dc, context, vba, split, merge);
} else {
/* the code below will be removed once windowed mpo odm is fully
* enabled.
*/
/* merge pipes if necessary */
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
......@@ -1918,6 +2107,7 @@ bool dcn32_internal_validate_bw(struct dc *dc,
goto validate_fail;
}
}
}
/* Actual dsc count per stream dsc validation*/
if (!dcn20_validate_dsc(dc, context)) {
......
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