Commit f0bfa78b authored by Dmytro Laktyushkin's avatar Dmytro Laktyushkin Committed by Alex Deucher

drm/amd/display: fix and simplify pipe split logic for DCN3

This was done already done for other DCN blocks.
Signed-off-by: default avatarDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Signed-off-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 464ab91a
...@@ -1875,19 +1875,57 @@ static bool init_soc_bounding_box(struct dc *dc, ...@@ -1875,19 +1875,57 @@ static bool init_soc_bounding_box(struct dc *dc,
return true; return true;
} }
bool dcn30_build_params_mpc_split(struct pipe_ctx *primary_pipe) static bool dcn30_split_stream_for_mpc_or_odm(
const struct dc *dc,
struct resource_context *res_ctx,
struct pipe_ctx *pri_pipe,
struct pipe_ctx *sec_pipe,
bool odm)
{ {
struct pipe_ctx *current_pipe = primary_pipe; int pipe_idx = sec_pipe->pipe_idx;
const struct resource_pool *pool = dc->res_pool;
while (current_pipe) {
if (!resource_build_scaling_params(current_pipe)) *sec_pipe = *pri_pipe;
sec_pipe->pipe_idx = pipe_idx;
sec_pipe->plane_res.mi = pool->mis[pipe_idx];
sec_pipe->plane_res.hubp = pool->hubps[pipe_idx];
sec_pipe->plane_res.ipp = pool->ipps[pipe_idx];
sec_pipe->plane_res.xfm = pool->transforms[pipe_idx];
sec_pipe->plane_res.dpp = pool->dpps[pipe_idx];
sec_pipe->plane_res.mpcc_inst = pool->dpps[pipe_idx]->inst;
sec_pipe->stream_res.dsc = NULL;
if (odm) {
if (pri_pipe->next_odm_pipe) {
ASSERT(pri_pipe->next_odm_pipe != sec_pipe);
sec_pipe->next_odm_pipe = pri_pipe->next_odm_pipe;
sec_pipe->next_odm_pipe->prev_odm_pipe = sec_pipe;
}
pri_pipe->next_odm_pipe = sec_pipe;
sec_pipe->prev_odm_pipe = pri_pipe;
ASSERT(sec_pipe->top_pipe == NULL);
sec_pipe->stream_res.opp = pool->opps[pipe_idx];
if (sec_pipe->stream->timing.flags.DSC == 1) {
dcn20_acquire_dsc(dc, res_ctx, &sec_pipe->stream_res.dsc, pipe_idx);
ASSERT(sec_pipe->stream_res.dsc);
if (sec_pipe->stream_res.dsc == NULL)
return false; return false;
current_pipe = current_pipe->bottom_pipe; }
} else {
if (pri_pipe->bottom_pipe) {
ASSERT(pri_pipe->bottom_pipe != sec_pipe);
sec_pipe->bottom_pipe = pri_pipe->bottom_pipe;
sec_pipe->bottom_pipe->top_pipe = sec_pipe;
}
pri_pipe->bottom_pipe = sec_pipe;
sec_pipe->top_pipe = pri_pipe;
ASSERT(pri_pipe->plane_state);
} }
return true; return true;
} }
static bool dcn30_fast_validate_bw( static bool dcn30_fast_validate_bw(
struct dc *dc, struct dc *dc,
struct dc_state *context, struct dc_state *context,
...@@ -1945,7 +1983,7 @@ static bool dcn30_fast_validate_bw( ...@@ -1945,7 +1983,7 @@ static bool dcn30_fast_validate_bw(
continue; continue;
/* We only support full screen mpo with ODM */ /* We only support full screen mpo with ODM */
if (vba->ODMCombineEnabled[pipe_idx] != dm_odm_combine_mode_disabled if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled
&& pipe->plane_state && mpo_pipe && pipe->plane_state && mpo_pipe
&& memcmp(&mpo_pipe->plane_res.scl_data.recout, && memcmp(&mpo_pipe->plane_res.scl_data.recout,
&pipe->plane_res.scl_data.recout, &pipe->plane_res.scl_data.recout,
...@@ -1966,10 +2004,13 @@ static bool dcn30_fast_validate_bw( ...@@ -1966,10 +2004,13 @@ static bool dcn30_fast_validate_bw(
if (!merge[i]) if (!merge[i])
continue; continue;
/* if ODM merge we ignore mpc tree, mpo pipes will have their own flags /* if ODM merge we ignore mpc tree, mpo pipes will have their own flags */
*/
if (pipe->prev_odm_pipe) { if (pipe->prev_odm_pipe) {
/*split off odm pipe*/ /*split off odm pipe*/
pipe->prev_odm_pipe->next_odm_pipe = pipe->next_odm_pipe;
if (pipe->next_odm_pipe)
pipe->next_odm_pipe->prev_odm_pipe = pipe->prev_odm_pipe;
pipe->bottom_pipe = NULL; pipe->bottom_pipe = NULL;
pipe->next_odm_pipe = NULL; pipe->next_odm_pipe = NULL;
pipe->plane_state = NULL; pipe->plane_state = NULL;
...@@ -1980,14 +2021,10 @@ static bool dcn30_fast_validate_bw( ...@@ -1980,14 +2021,10 @@ static bool dcn30_fast_validate_bw(
dcn20_release_dsc(&context->res_ctx, dc->res_pool, &pipe->stream_res.dsc); dcn20_release_dsc(&context->res_ctx, dc->res_pool, &pipe->stream_res.dsc);
memset(&pipe->plane_res, 0, sizeof(pipe->plane_res)); memset(&pipe->plane_res, 0, sizeof(pipe->plane_res));
memset(&pipe->stream_res, 0, sizeof(pipe->stream_res)); memset(&pipe->stream_res, 0, sizeof(pipe->stream_res));
} else if (pipe->next_odm_pipe) { } else if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) {
/*initial odm pipe*/
pipe->next_odm_pipe = NULL;
} else {
struct pipe_ctx *top_pipe = pipe->top_pipe; struct pipe_ctx *top_pipe = pipe->top_pipe;
struct pipe_ctx *bottom_pipe = pipe->bottom_pipe; struct pipe_ctx *bottom_pipe = pipe->bottom_pipe;
if (top_pipe)
top_pipe->bottom_pipe = bottom_pipe; top_pipe->bottom_pipe = bottom_pipe;
if (bottom_pipe) if (bottom_pipe)
bottom_pipe->top_pipe = top_pipe; bottom_pipe->top_pipe = top_pipe;
...@@ -1998,84 +2035,48 @@ static bool dcn30_fast_validate_bw( ...@@ -1998,84 +2035,48 @@ static bool dcn30_fast_validate_bw(
pipe->stream = NULL; pipe->stream = NULL;
memset(&pipe->plane_res, 0, sizeof(pipe->plane_res)); memset(&pipe->plane_res, 0, sizeof(pipe->plane_res));
memset(&pipe->stream_res, 0, sizeof(pipe->stream_res)); memset(&pipe->stream_res, 0, sizeof(pipe->stream_res));
} } else
ASSERT(0); /* Should never try to merge master pipe */
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
if (pipe->plane_state) {
if (!resource_build_scaling_params(pipe))
goto validate_fail;
}
} }
for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) { for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
struct pipe_ctx *hsplit_pipe = NULL; struct pipe_ctx *hsplit_pipe = NULL;
bool odm;
if (!pipe->stream || newly_split[i]) if (!pipe->stream || newly_split[i])
continue; continue;
pipe_idx++; pipe_idx++;
odm = vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled;
if (!pipe->top_pipe && !pipe->plane_state && split[i] != 0 if (!pipe->plane_state && !odm)
&& vba->ODMCombineEnabled[pipe_idx] != dm_odm_combine_mode_disabled) { continue;
if (split[i]) {
hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe); hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
ASSERT(hsplit_pipe); ASSERT(hsplit_pipe);
if (!hsplit_pipe) if (!hsplit_pipe)
goto validate_fail; goto validate_fail;
if (!dcn20_split_stream_for_odm(
dc, &context->res_ctx,
pipe, hsplit_pipe))
goto validate_fail;
newly_split[hsplit_pipe->pipe_idx] = true;
if (vba->ODMCombineEnabled[pipe_idx] == dm_odm_combine_mode_4to1) {
struct pipe_ctx *pipe_4to1 = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
ASSERT(pipe_4to1); if (!dcn30_split_stream_for_mpc_or_odm(
if (!dcn20_split_stream_for_odm(
dc, &context->res_ctx, dc, &context->res_ctx,
pipe, pipe_4to1)) pipe, hsplit_pipe, odm))
goto validate_fail; goto validate_fail;
newly_split[pipe_4to1->pipe_idx] = true;
pipe_4to1 = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe); newly_split[hsplit_pipe->pipe_idx] = true;
ASSERT(pipe_4to1);
if (!dcn20_split_stream_for_odm(
dc, &context->res_ctx,
hsplit_pipe, pipe_4to1))
goto validate_fail;
newly_split[pipe_4to1->pipe_idx] = true;
}
dcn20_build_mapped_resource(dc, context, pipe->stream);
repopulate_pipes = true; repopulate_pipes = true;
} }
if (split[i] == 4) {
if (!pipe->plane_state)
continue;
if (split[i] == 2) {
hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
ASSERT(hsplit_pipe);
if (!hsplit_pipe)
goto validate_fail;
if (vba->ODMCombineEnabled[pipe_idx] != dm_odm_combine_mode_disabled) {
if (!dcn20_split_stream_for_odm(
dc, &context->res_ctx,
pipe, hsplit_pipe))
goto validate_fail;
if (vba->ODMCombineEnabled[pipe_idx] == dm_odm_combine_mode_4to1) {
struct pipe_ctx *pipe_4to1 = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe); struct pipe_ctx *pipe_4to1 = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
ASSERT(pipe_4to1); ASSERT(pipe_4to1);
if (!pipe_4to1) if (!pipe_4to1)
goto validate_fail; goto validate_fail;
if (!dcn20_split_stream_for_odm( if (!dcn30_split_stream_for_mpc_or_odm(
dc, &context->res_ctx, dc, &context->res_ctx,
pipe, pipe_4to1)) pipe, pipe_4to1, odm))
goto validate_fail; goto validate_fail;
newly_split[pipe_4to1->pipe_idx] = true; newly_split[pipe_4to1->pipe_idx] = true;
...@@ -2083,56 +2084,28 @@ static bool dcn30_fast_validate_bw( ...@@ -2083,56 +2084,28 @@ static bool dcn30_fast_validate_bw(
ASSERT(pipe_4to1); ASSERT(pipe_4to1);
if (!pipe_4to1) if (!pipe_4to1)
goto validate_fail; goto validate_fail;
if (!dcn20_split_stream_for_odm( if (!dcn30_split_stream_for_mpc_or_odm(
dc, &context->res_ctx, dc, &context->res_ctx,
hsplit_pipe, pipe_4to1)) hsplit_pipe, pipe_4to1, odm))
goto validate_fail; goto validate_fail;
newly_split[pipe_4to1->pipe_idx] = true; newly_split[pipe_4to1->pipe_idx] = true;
} }
if (odm)
dcn20_build_mapped_resource(dc, context, pipe->stream); dcn20_build_mapped_resource(dc, context, pipe->stream);
} else {
/* Going from 2 pipe split to 4 pipe split case */
if (dcn20_find_previous_split_count(pipe) == 2) {
dcn20_split_stream_for_mpc(
&context->res_ctx, dc->res_pool,
pipe, hsplit_pipe);
newly_split[hsplit_pipe->pipe_idx] = true;
hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
dcn20_split_stream_for_mpc(
&context->res_ctx, dc->res_pool,
pipe, hsplit_pipe);
if (!dcn30_build_params_mpc_split(pipe))
goto validate_fail;
} else {
dcn20_split_stream_for_mpc(
&context->res_ctx, dc->res_pool,
pipe, hsplit_pipe);
if (!resource_build_scaling_params(pipe) || !resource_build_scaling_params(hsplit_pipe))
goto validate_fail;
}
}
newly_split[hsplit_pipe->pipe_idx] = true;
repopulate_pipes = true;
} }
if (split[i] == 4) {
struct pipe_ctx *pipe_4to1;
hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe); for (i = 0; i < dc->res_pool->pipe_count; i++) {
for (i = 0; i < 3; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
pipe_4to1 = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
ASSERT(pipe_4to1); if (pipe->plane_state) {
dcn20_split_stream_for_mpc(&context->res_ctx, dc->res_pool, pipe, pipe_4to1); if (!resource_build_scaling_params(pipe))
newly_split[pipe_4to1->pipe_idx] = true;
}
if (!dcn30_build_params_mpc_split(pipe))
goto validate_fail; goto validate_fail;
repopulate_pipes = true;
} }
} }
/* Actual dsc count per stream dsc validation*/ /* Actual dsc count per stream dsc validation*/
if (!dcn20_validate_dsc(dc, context)) { if (!dcn20_validate_dsc(dc, context)) {
context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states] = vba->ValidationStatus[vba->soc.num_states] = DML_FAIL_DSC_VALIDATION_FAILURE;
DML_FAIL_DSC_VALIDATION_FAILURE;
goto validate_fail; goto validate_fail;
} }
......
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