diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-21 05:38:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-21 05:38:10 +0000 |
commit | 2e7b21ebb8f845570641035f8a7832d33d8e5135 (patch) | |
tree | 3db92cd227f359a58c62582e954a78616c9a3426 /drivers/gpu/drm/amd/display/dc/core | |
parent | Adding debian version 6.10.4-1. (diff) | |
download | linux-2e7b21ebb8f845570641035f8a7832d33d8e5135.tar.xz linux-2e7b21ebb8f845570641035f8a7832d33d8e5135.zip |
Merging upstream version 6.10.6.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 58 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_state.c | 67 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 90 |
3 files changed, 145 insertions, 70 deletions
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 15819416a2..8ed5993246 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -2267,6 +2267,10 @@ void resource_log_pipe_topology_update(struct dc *dc, struct dc_state *state) otg_master = resource_get_otg_master_for_stream( &state->res_ctx, state->streams[stream_idx]); + + if (!otg_master) + continue; + resource_log_pipe_for_stream(dc, state, otg_master, stream_idx); } if (state->phantom_stream_count > 0) { @@ -2508,6 +2512,17 @@ static void remove_hpo_dp_link_enc_from_ctx(struct resource_context *res_ctx, } } +static int get_num_of_free_pipes(const struct resource_pool *pool, const struct dc_state *context) +{ + int i; + int count = 0; + + for (i = 0; i < pool->pipe_count; i++) + if (resource_is_pipe_type(&context->res_ctx.pipe_ctx[i], FREE_PIPE)) + count++; + return count; +} + enum dc_status resource_add_otg_master_for_stream_output(struct dc_state *new_ctx, const struct resource_pool *pool, struct dc_stream_state *stream) @@ -2641,37 +2656,33 @@ static bool acquire_secondary_dpp_pipes_and_add_plane( struct dc_state *cur_ctx, struct resource_pool *pool) { - struct pipe_ctx *opp_head_pipe, *sec_pipe, *tail_pipe; + struct pipe_ctx *sec_pipe, *tail_pipe; + struct pipe_ctx *opp_heads[MAX_PIPES]; + int opp_head_count; + int i; if (!pool->funcs->acquire_free_pipe_as_secondary_dpp_pipe) { ASSERT(0); return false; } - opp_head_pipe = otg_master_pipe; - while (opp_head_pipe) { + opp_head_count = resource_get_opp_heads_for_otg_master(otg_master_pipe, + &new_ctx->res_ctx, opp_heads); + if (get_num_of_free_pipes(pool, new_ctx) < opp_head_count) + /* not enough free pipes */ + return false; + + for (i = 0; i < opp_head_count; i++) { sec_pipe = pool->funcs->acquire_free_pipe_as_secondary_dpp_pipe( cur_ctx, new_ctx, pool, - opp_head_pipe); - if (!sec_pipe) { - /* try tearing down MPCC combine */ - int pipe_idx = acquire_first_split_pipe( - &new_ctx->res_ctx, pool, - otg_master_pipe->stream); - - if (pipe_idx >= 0) - sec_pipe = &new_ctx->res_ctx.pipe_ctx[pipe_idx]; - } - - if (!sec_pipe) - return false; - + opp_heads[i]); + ASSERT(sec_pipe); sec_pipe->plane_state = plane_state; /* establish pipe relationship */ - tail_pipe = get_tail_pipe(opp_head_pipe); + tail_pipe = get_tail_pipe(opp_heads[i]); tail_pipe->bottom_pipe = sec_pipe; sec_pipe->top_pipe = tail_pipe; sec_pipe->bottom_pipe = NULL; @@ -2682,8 +2693,6 @@ static bool acquire_secondary_dpp_pipes_and_add_plane( } else { sec_pipe->prev_odm_pipe = NULL; } - - opp_head_pipe = opp_head_pipe->next_odm_pipe; } return true; } @@ -2696,6 +2705,7 @@ bool resource_append_dpp_pipes_for_plane_composition( struct dc_plane_state *plane_state) { bool success; + if (otg_master_pipe->plane_state == NULL) success = add_plane_to_opp_head_pipes(otg_master_pipe, plane_state, new_ctx); @@ -2703,10 +2713,15 @@ bool resource_append_dpp_pipes_for_plane_composition( success = acquire_secondary_dpp_pipes_and_add_plane( otg_master_pipe, plane_state, new_ctx, cur_ctx, pool); - if (success) + if (success) { /* when appending a plane mpc slice count changes from 0 to 1 */ success = update_pipe_params_after_mpc_slice_count_change( plane_state, new_ctx, pool); + if (!success) + resource_remove_dpp_pipes_for_plane_composition(new_ctx, + pool, plane_state); + } + return success; } @@ -2716,6 +2731,7 @@ void resource_remove_dpp_pipes_for_plane_composition( const struct dc_plane_state *plane_state) { int i; + for (i = pool->pipe_count - 1; i >= 0; i--) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_state.c b/drivers/gpu/drm/amd/display/dc/core/dc_state.c index 76bb05f4d6..52a1cfc5fe 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_state.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_state.c @@ -437,6 +437,19 @@ enum dc_status dc_state_remove_stream( return DC_OK; } +static void remove_mpc_combine_for_stream(const struct dc *dc, + struct dc_state *new_ctx, + const struct dc_state *cur_ctx, + struct dc_stream_status *status) +{ + int i; + + for (i = 0; i < status->plane_count; i++) + resource_update_pipes_for_plane_with_slice_count( + new_ctx, cur_ctx, dc->res_pool, + status->plane_states[i], 1); +} + bool dc_state_add_plane( const struct dc *dc, struct dc_stream_state *stream, @@ -447,8 +460,12 @@ bool dc_state_add_plane( struct pipe_ctx *otg_master_pipe; struct dc_stream_status *stream_status = NULL; bool added = false; + int odm_slice_count; + int i; stream_status = dc_state_get_stream_status(state, stream); + otg_master_pipe = resource_get_otg_master_for_stream( + &state->res_ctx, stream); if (stream_status == NULL) { dm_error("Existing stream not found; failed to attach surface!\n"); goto out; @@ -456,22 +473,39 @@ bool dc_state_add_plane( dm_error("Surface: can not attach plane_state %p! Maximum is: %d\n", plane_state, MAX_SURFACE_NUM); goto out; + } else if (!otg_master_pipe) { + goto out; } - if (stream_status->plane_count == 0 && dc->config.enable_windowed_mpo_odm) - /* ODM combine could prevent us from supporting more planes - * we will reset ODM slice count back to 1 when all planes have - * been removed to maximize the amount of planes supported when - * new planes are added. - */ - resource_update_pipes_for_stream_with_slice_count( - state, dc->current_state, dc->res_pool, stream, 1); + added = resource_append_dpp_pipes_for_plane_composition(state, + dc->current_state, pool, otg_master_pipe, plane_state); - otg_master_pipe = resource_get_otg_master_for_stream( - &state->res_ctx, stream); - if (otg_master_pipe) + if (!added) { + /* try to remove MPC combine to free up pipes */ + for (i = 0; i < state->stream_count; i++) + remove_mpc_combine_for_stream(dc, state, + dc->current_state, + &state->stream_status[i]); added = resource_append_dpp_pipes_for_plane_composition(state, - dc->current_state, pool, otg_master_pipe, plane_state); + dc->current_state, pool, + otg_master_pipe, plane_state); + } + + if (!added) { + /* try to decrease ODM slice count gradually to free up pipes */ + odm_slice_count = resource_get_odm_slice_count(otg_master_pipe); + for (i = odm_slice_count - 1; i > 0; i--) { + resource_update_pipes_for_stream_with_slice_count(state, + dc->current_state, dc->res_pool, stream, + i); + added = resource_append_dpp_pipes_for_plane_composition( + state, + dc->current_state, pool, + otg_master_pipe, plane_state); + if (added) + break; + } + } if (added) { stream_status->plane_states[stream_status->plane_count] = @@ -531,15 +565,6 @@ bool dc_state_remove_plane( stream_status->plane_states[stream_status->plane_count] = NULL; - if (stream_status->plane_count == 0 && dc->config.enable_windowed_mpo_odm) - /* ODM combine could prevent us from supporting more planes - * we will reset ODM slice count back to 1 when all planes have - * been removed to maximize the amount of planes supported when - * new planes are added. - */ - resource_update_pipes_for_stream_with_slice_count( - state, dc->current_state, dc->res_pool, stream, 1); - return true; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 5c7e4884ca..53bc991b6e 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -266,7 +266,6 @@ bool dc_stream_set_cursor_attributes( const struct dc_cursor_attributes *attributes) { struct dc *dc; - bool reset_idle_optimizations = false; if (NULL == stream) { dm_error("DC: dc_stream is NULL!\n"); @@ -297,20 +296,36 @@ bool dc_stream_set_cursor_attributes( stream->cursor_attributes = *attributes; - dc_z10_restore(dc); - /* disable idle optimizations while updating cursor */ - if (dc->idle_optimizations_allowed) { - dc_allow_idle_optimizations(dc, false); - reset_idle_optimizations = true; - } + return true; +} - program_cursor_attributes(dc, stream, attributes); +bool dc_stream_program_cursor_attributes( + struct dc_stream_state *stream, + const struct dc_cursor_attributes *attributes) +{ + struct dc *dc; + bool reset_idle_optimizations = false; - /* re-enable idle optimizations if necessary */ - if (reset_idle_optimizations && !dc->debug.disable_dmub_reallow_idle) - dc_allow_idle_optimizations(dc, true); + dc = stream ? stream->ctx->dc : NULL; - return true; + if (dc_stream_set_cursor_attributes(stream, attributes)) { + dc_z10_restore(dc); + /* disable idle optimizations while updating cursor */ + if (dc->idle_optimizations_allowed) { + dc_allow_idle_optimizations(dc, false); + reset_idle_optimizations = true; + } + + program_cursor_attributes(dc, stream, attributes); + + /* re-enable idle optimizations if necessary */ + if (reset_idle_optimizations && !dc->debug.disable_dmub_reallow_idle) + dc_allow_idle_optimizations(dc, true); + + return true; + } + + return false; } static void program_cursor_position( @@ -355,9 +370,6 @@ bool dc_stream_set_cursor_position( struct dc_stream_state *stream, const struct dc_cursor_position *position) { - struct dc *dc; - bool reset_idle_optimizations = false; - if (NULL == stream) { dm_error("DC: dc_stream is NULL!\n"); return false; @@ -368,24 +380,46 @@ bool dc_stream_set_cursor_position( return false; } + stream->cursor_position = *position; + + + return true; +} + +bool dc_stream_program_cursor_position( + struct dc_stream_state *stream, + const struct dc_cursor_position *position) +{ + struct dc *dc; + bool reset_idle_optimizations = false; + const struct dc_cursor_position *old_position; + + if (!stream) + return false; + + old_position = &stream->cursor_position; dc = stream->ctx->dc; - dc_z10_restore(dc); - /* disable idle optimizations if enabling cursor */ - if (dc->idle_optimizations_allowed && (!stream->cursor_position.enable || dc->debug.exit_idle_opt_for_cursor_updates) - && position->enable) { - dc_allow_idle_optimizations(dc, false); - reset_idle_optimizations = true; - } + if (dc_stream_set_cursor_position(stream, position)) { + dc_z10_restore(dc); - stream->cursor_position = *position; + /* disable idle optimizations if enabling cursor */ + if (dc->idle_optimizations_allowed && + (!old_position->enable || dc->debug.exit_idle_opt_for_cursor_updates) && + position->enable) { + dc_allow_idle_optimizations(dc, false); + reset_idle_optimizations = true; + } - program_cursor_position(dc, stream, position); - /* re-enable idle optimizations if necessary */ - if (reset_idle_optimizations && !dc->debug.disable_dmub_reallow_idle) - dc_allow_idle_optimizations(dc, true); + program_cursor_position(dc, stream, position); + /* re-enable idle optimizations if necessary */ + if (reset_idle_optimizations && !dc->debug.disable_dmub_reallow_idle) + dc_allow_idle_optimizations(dc, true); - return true; + return true; + } + + return false; } bool dc_stream_add_writeback(struct dc *dc, |