diff options
Diffstat (limited to 'drivers/gpu')
4 files changed, 49 insertions, 12 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 0090f7491446..5476b7a55236 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -1141,7 +1141,7 @@ bool dcn_validate_bandwidth( hsplit_pipe->pipe_dlg_param.vblank_end = pipe->pipe_dlg_param.vblank_end; } else { /* pipe not split previously needs split */ - hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, pool); + hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, pool, pipe); ASSERT(hsplit_pipe); split_stream_across_pipes( &context->res_ctx, pool, diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 374ce43096ac..4a651d7dd052 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1038,24 +1038,60 @@ enum dc_status resource_build_scaling_params_for_context( struct pipe_ctx *find_idle_secondary_pipe( struct resource_context *res_ctx, - const struct resource_pool *pool) + const struct resource_pool *pool, + const struct pipe_ctx *primary_pipe) { int i; struct pipe_ctx *secondary_pipe = NULL; /* - * search backwards for the second pipe to keep pipe - * assignment more consistent + * We add a preferred pipe mapping to avoid the chance that + * MPCCs already in use will need to be reassigned to other trees. + * For example, if we went with the strict, assign backwards logic: + * + * (State 1) + * Display A on, no surface, top pipe = 0 + * Display B on, no surface, top pipe = 1 + * + * (State 2) + * Display A on, no surface, top pipe = 0 + * Display B on, surface enable, top pipe = 1, bottom pipe = 5 + * + * (State 3) + * Display A on, surface enable, top pipe = 0, bottom pipe = 5 + * Display B on, surface enable, top pipe = 1, bottom pipe = 4 + * + * The state 2->3 transition requires remapping MPCC 5 from display B + * to display A. + * + * However, with the preferred pipe logic, state 2 would look like: + * + * (State 2) + * Display A on, no surface, top pipe = 0 + * Display B on, surface enable, top pipe = 1, bottom pipe = 4 + * + * This would then cause 2->3 to not require remapping any MPCCs. */ - - for (i = pool->pipe_count - 1; i >= 0; i--) { - if (res_ctx->pipe_ctx[i].stream == NULL) { - secondary_pipe = &res_ctx->pipe_ctx[i]; - secondary_pipe->pipe_idx = i; - break; + if (primary_pipe) { + int preferred_pipe_idx = (pool->pipe_count - 1) - primary_pipe->pipe_idx; + if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) { + secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx]; + secondary_pipe->pipe_idx = preferred_pipe_idx; } } + /* + * search backwards for the second pipe to keep pipe + * assignment more consistent + */ + if (!secondary_pipe) + for (i = pool->pipe_count - 1; i >= 0; i--) { + if (res_ctx->pipe_ctx[i].stream == NULL) { + secondary_pipe = &res_ctx->pipe_ctx[i]; + secondary_pipe->pipe_idx = i; + break; + } + } return secondary_pipe; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index e879829a34b9..29f8893e44b6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1081,7 +1081,7 @@ static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer( { struct resource_context *res_ctx = &context->res_ctx; struct pipe_ctx *head_pipe = resource_get_head_pipe_for_stream(res_ctx, stream); - struct pipe_ctx *idle_pipe = find_idle_secondary_pipe(res_ctx, pool); + struct pipe_ctx *idle_pipe = find_idle_secondary_pipe(res_ctx, pool, head_pipe); if (!head_pipe) { ASSERT(0); diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index 62e00a9f3184..028c63061767 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -131,7 +131,8 @@ bool resource_attach_surfaces_to_context( struct pipe_ctx *find_idle_secondary_pipe( struct resource_context *res_ctx, - const struct resource_pool *pool); + const struct resource_pool *pool, + const struct pipe_ctx *primary_pipe); bool resource_is_stream_unchanged( struct dc_state *old_context, struct dc_stream_state *stream); |