summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
diff options
context:
space:
mode:
authorDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>2020-05-11 15:21:02 -0400
committerAlex Deucher <alexander.deucher@amd.com>2020-09-29 16:11:23 -0400
commit69fc1f4b976ceafe91c64e1fc4ec2a2fe8b916aa (patch)
treec1f398d78b510a93db55d822ee2da9823d4c4fc3 /drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
parent8353d30e747f4e5cdd867c6b054dbb85cdcc76a9 (diff)
downloadlinux-69fc1f4b976ceafe91c64e1fc4ec2a2fe8b916aa.tar.bz2
amd/drm/display: avoid dcn3 on flip opp change for slave pipes
At the moment on flip opp reassignment does not work in all cases for non root pipes. This change simply makes sure we prefer pipes not used previously when splitting in dcn3. Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Reviewed-by: Eric Bernstein <eric.bernstein@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c43
1 files changed, 40 insertions, 3 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 7f3354b3512d..c223f8af2084 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
@@ -1899,6 +1899,41 @@ static bool dcn30_split_stream_for_mpc_or_odm(
return true;
}
+static struct pipe_ctx *dcn30_find_split_pipe(
+ struct dc *dc,
+ struct dc_state *context)
+{
+ struct pipe_ctx *pipe = NULL;
+ int i;
+
+ for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
+ if (dc->current_state->res_ctx.pipe_ctx[i].top_pipe == NULL
+ && dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe == NULL) {
+ if (context->res_ctx.pipe_ctx[i].stream == NULL) {
+ pipe = &context->res_ctx.pipe_ctx[i];
+ pipe->pipe_idx = i;
+ break;
+ }
+ }
+ }
+
+ /*
+ * May need to fix pipes getting tossed from 1 opp to another on flip
+ * Add for debugging transient underflow during topology updates:
+ * ASSERT(pipe);
+ */
+ if (!pipe)
+ for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
+ if (context->res_ctx.pipe_ctx[i].stream == NULL) {
+ pipe = &context->res_ctx.pipe_ctx[i];
+ pipe->pipe_idx = i;
+ break;
+ }
+ }
+
+ return pipe;
+}
+
static bool dcn30_internal_validate_bw(
struct dc *dc,
struct dc_state *context,
@@ -2024,6 +2059,7 @@ static bool dcn30_internal_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));
+ repopulate_pipes = true;
} 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;
@@ -2038,6 +2074,7 @@ static bool dcn30_internal_validate_bw(
pipe->stream = NULL;
memset(&pipe->plane_res, 0, sizeof(pipe->plane_res));
memset(&pipe->stream_res, 0, sizeof(pipe->stream_res));
+ repopulate_pipes = true;
} else
ASSERT(0); /* Should never try to merge master pipe */
@@ -2058,7 +2095,7 @@ static bool dcn30_internal_validate_bw(
continue;
if (split[i]) {
- hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
+ hsplit_pipe = dcn30_find_split_pipe(dc, context);
ASSERT(hsplit_pipe);
if (!hsplit_pipe)
goto validate_fail;
@@ -2072,7 +2109,7 @@ static bool dcn30_internal_validate_bw(
repopulate_pipes = true;
}
if (split[i] == 4) {
- struct pipe_ctx *pipe_4to1 = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
+ struct pipe_ctx *pipe_4to1 = dcn30_find_split_pipe(dc, context);
ASSERT(pipe_4to1);
if (!pipe_4to1)
@@ -2083,7 +2120,7 @@ static bool dcn30_internal_validate_bw(
goto validate_fail;
newly_split[pipe_4to1->pipe_idx] = true;
- pipe_4to1 = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
+ pipe_4to1 = dcn30_find_split_pipe(dc, context);
ASSERT(pipe_4to1);
if (!pipe_4to1)
goto validate_fail;