[PATCH 205/207] drm/amd/display: fix and simplify pipe split logic for DCN3
Alex Deucher
alexdeucher at gmail.com
Mon Jun 1 18:29:24 UTC 2020
From: Dmytro Laktyushkin <Dmytro.Laktyushkin at amd.com>
This was done already done for DCN
From:
f7a695da88cf ("drm/amd/display: fix and simplify pipe split logic")
Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin at amd.com>
Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
---
.../drm/amd/display/dc/dcn30/dcn30_resource.c | 213 ++++++++----------
1 file changed, 93 insertions(+), 120 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
index 9ae0f4399e5a..bddd671fb196 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
@@ -1875,19 +1875,57 @@ static bool init_soc_bounding_box(struct dc *dc,
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;
+
+ *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;
+ }
+ } 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;
- while (current_pipe) {
- if (!resource_build_scaling_params(current_pipe))
- return false;
- current_pipe = current_pipe->bottom_pipe;
+ ASSERT(pri_pipe->plane_state);
}
return true;
}
-
static bool dcn30_fast_validate_bw(
struct dc *dc,
struct dc_state *context,
@@ -1945,7 +1983,7 @@ static bool dcn30_fast_validate_bw(
continue;
/* 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
&& memcmp(&mpo_pipe->plane_res.scl_data.recout,
&pipe->plane_res.scl_data.recout,
@@ -1966,10 +2004,13 @@ static bool dcn30_fast_validate_bw(
if (!merge[i])
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) {
/*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->next_odm_pipe = NULL;
pipe->plane_state = NULL;
@@ -1980,15 +2021,11 @@ static bool dcn30_fast_validate_bw(
dcn20_release_dsc(&context->res_ctx, dc->res_pool, &pipe->stream_res.dsc);
memset(&pipe->plane_res, 0, sizeof(pipe->plane_res));
memset(&pipe->stream_res, 0, sizeof(pipe->stream_res));
- } else if (pipe->next_odm_pipe) {
- /*initial odm pipe*/
- pipe->next_odm_pipe = NULL;
- } else {
+ } else if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) {
struct pipe_ctx *top_pipe = pipe->top_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)
bottom_pipe->top_pipe = top_pipe;
@@ -1998,141 +2035,77 @@ static bool dcn30_fast_validate_bw(
pipe->stream = NULL;
memset(&pipe->plane_res, 0, sizeof(pipe->plane_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++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
struct pipe_ctx *hsplit_pipe = NULL;
+ bool odm;
if (!pipe->stream || newly_split[i])
continue;
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
- && vba->ODMCombineEnabled[pipe_idx] != dm_odm_combine_mode_disabled) {
+ if (!pipe->plane_state && !odm)
+ continue;
+
+ if (split[i]) {
hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
ASSERT(hsplit_pipe);
if (!hsplit_pipe)
goto validate_fail;
- if (!dcn20_split_stream_for_odm(
+
+ if (!dcn30_split_stream_for_mpc_or_odm(
dc, &context->res_ctx,
- pipe, hsplit_pipe))
+ pipe, hsplit_pipe, odm))
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 (!dcn20_split_stream_for_odm(
- dc, &context->res_ctx,
- pipe, pipe_4to1))
- goto validate_fail;
- newly_split[pipe_4to1->pipe_idx] = true;
-
- pipe_4to1 = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
- 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;
}
+ if (split[i] == 4) {
+ struct pipe_ctx *pipe_4to1 = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
- 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)
+ ASSERT(pipe_4to1);
+ if (!pipe_4to1)
goto validate_fail;
+ if (!dcn30_split_stream_for_mpc_or_odm(
+ dc, &context->res_ctx,
+ pipe, pipe_4to1, odm))
+ goto validate_fail;
+ newly_split[pipe_4to1->pipe_idx] = true;
- 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);
-
- ASSERT(pipe_4to1);
- if (!pipe_4to1)
- goto validate_fail;
- if (!dcn20_split_stream_for_odm(
- dc, &context->res_ctx,
- pipe, pipe_4to1))
- goto validate_fail;
- newly_split[pipe_4to1->pipe_idx] = true;
-
- pipe_4to1 = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
- ASSERT(pipe_4to1);
- if (!pipe_4to1)
- goto validate_fail;
- 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);
- } 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;
+ pipe_4to1 = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
+ ASSERT(pipe_4to1);
+ if (!pipe_4to1)
+ goto validate_fail;
+ if (!dcn30_split_stream_for_mpc_or_odm(
+ dc, &context->res_ctx,
+ hsplit_pipe, pipe_4to1, odm))
+ goto validate_fail;
+ newly_split[pipe_4to1->pipe_idx] = true;
}
- if (split[i] == 4) {
- struct pipe_ctx *pipe_4to1;
+ if (odm)
+ dcn20_build_mapped_resource(dc, context, pipe->stream);
+ }
- hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
- for (i = 0; i < 3; i++) {
- pipe_4to1 = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
- ASSERT(pipe_4to1);
- dcn20_split_stream_for_mpc(&context->res_ctx, dc->res_pool, pipe, pipe_4to1);
- newly_split[pipe_4to1->pipe_idx] = true;
- }
- if (!dcn30_build_params_mpc_split(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;
- repopulate_pipes = true;
}
}
+
/* Actual dsc count per stream dsc validation*/
if (!dcn20_validate_dsc(dc, context)) {
- context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states] =
- DML_FAIL_DSC_VALIDATION_FAILURE;
+ vba->ValidationStatus[vba->soc.num_states] = DML_FAIL_DSC_VALIDATION_FAILURE;
goto validate_fail;
}
--
2.25.4
More information about the amd-gfx
mailing list