From: Andrey Grodzovsky <Andrey.Grodzovsky@xxxxxxx> Until now new context would start as empty, then populated with exsisting pipes + new. Now we start with duplication of existing context and then add/delete from the context pipes as needed. This allows to do a per stream resource population, start discarding dc_validation_set and by this brings DC closer to to DRM. v2: Add some fixes and rebase. Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky at amd.com> Reviewed-by: Tony Cheng <Tony.Cheng at amd.com> Acked-by: Harry Wentland <Harry.Wentland at amd.com> --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 68 ++- drivers/gpu/drm/amd/display/dc/core/dc.c | 108 +---- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 468 +++++++++++++++------ drivers/gpu/drm/amd/display/dc/dc.h | 32 +- .../drm/amd/display/dc/dce100/dce100_resource.c | 78 +--- .../drm/amd/display/dc/dce110/dce110_resource.c | 86 +--- .../drm/amd/display/dc/dce112/dce112_resource.c | 143 +++---- .../drm/amd/display/dc/dce112/dce112_resource.h | 5 + .../drm/amd/display/dc/dce120/dce120_resource.c | 4 +- .../gpu/drm/amd/display/dc/dce80/dce80_resource.c | 79 +--- .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 85 ++-- drivers/gpu/drm/amd/display/dc/inc/core_types.h | 19 +- drivers/gpu/drm/amd/display/dc/inc/resource.h | 6 +- 13 files changed, 577 insertions(+), 604 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 73a0fdb98cbd..4c5714dde9a0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -25,6 +25,7 @@ #include "dm_services_types.h" #include "dc.h" +#include "dc/inc/core_types.h" #include "vid.h" #include "amdgpu.h" @@ -690,13 +691,33 @@ struct drm_atomic_state * dm_atomic_state_alloc(struct drm_device *dev) { struct dm_atomic_state *state = kzalloc(sizeof(*state), GFP_KERNEL); + struct validate_context *new_ctx; + struct amdgpu_device *adev = dev->dev_private; + struct dc *dc = adev->dm.dc; - if (!state || drm_atomic_state_init(dev, &state->base) < 0) { - kfree(state); + if (!state) return NULL; - } + + if (drm_atomic_state_init(dev, &state->base) < 0) + goto fail; + + /* copy existing configuration */ + new_ctx = dm_alloc(sizeof(*new_ctx)); + + if (!new_ctx) + goto fail; + + atomic_inc(&new_ctx->ref_count); + + dc_resource_validate_ctx_copy_construct_current(dc, new_ctx); + + state->context = new_ctx; return &state->base; + +fail: + kfree(state); + return NULL; } static void @@ -4518,7 +4539,6 @@ static int do_aquire_global_lock( int amdgpu_dm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) { - struct dm_atomic_state *dm_state; struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; struct drm_plane *plane; @@ -4532,6 +4552,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, int set_count; struct dc_validation_set set[MAX_STREAMS] = { { 0 } }; struct dm_crtc_state *old_acrtc_state, *new_acrtc_state; + struct dm_atomic_state *dm_state = to_dm_atomic_state(state); /* * This bool will be set for true for any modeset/reset @@ -4546,8 +4567,6 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, return ret; } - dm_state = to_dm_atomic_state(state); - /* copy existing configuration */ set_count = 0; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { @@ -4590,8 +4609,17 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, if (modereset_required(crtc_state)) { - /* i.e. reset mode */ + /* i.e. reset mode */ if (new_acrtc_state->stream) { + + if (!dc_remove_stream_from_ctx( + dc, + dm_state->context, + new_acrtc_state->stream)) { + ret = -EINVAL; + goto fail; + } + set_count = remove_from_val_sets( set, set_count, @@ -4639,8 +4667,19 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, if (modeset_required(crtc_state, new_stream, old_acrtc_state->stream)) { - if (new_acrtc_state->stream) + if (new_acrtc_state->stream) { + + if (!dc_remove_stream_from_ctx( + dc, + dm_state->context, + new_acrtc_state->stream)) { + ret = -EINVAL; + goto fail; + } + + dc_stream_release(new_acrtc_state->stream); + } new_acrtc_state->stream = new_stream; @@ -4651,6 +4690,14 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, new_acrtc_state->stream, crtc); + if (!dc_add_stream_to_ctx( + dc, + dm_state->context, + new_acrtc_state->stream)) { + ret = -EINVAL; + goto fail; + } + lock_and_validation_needed = true; } else { /* @@ -4767,9 +4814,8 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, ret = do_aquire_global_lock(dev, state); if (ret) goto fail; - WARN_ON(dm_state->context); - dm_state->context = dc_get_validate_context(dc, set, set_count); - if (!dm_state->context) { + + if (!dc_validate_global_state(dc, set, set_count, dm_state->context)) { ret = -EINVAL; goto fail; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 44c7b52e4a00..10126d9a7233 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -669,41 +669,6 @@ void dc_destroy(struct dc **dc) *dc = NULL; } -static bool is_validation_required( - const struct dc *dc, - const struct dc_validation_set set[], - int set_count) -{ - const struct validate_context *context = dc->current_context; - int i, j; - - if (context->stream_count != set_count) - return true; - - for (i = 0; i < set_count; i++) { - - if (set[i].plane_count != context->stream_status[i].plane_count) - return true; - if (!dc_is_stream_unchanged(set[i].stream, context->streams[i])) - return true; - - for (j = 0; j < set[i].plane_count; j++) { - struct dc_plane_state temp_plane; - memset(&temp_plane, 0, sizeof(temp_plane)); - - temp_plane = *context->stream_status[i].plane_states[j]; - temp_plane.clip_rect = set[i].plane_states[j]->clip_rect; - temp_plane.dst_rect.x = set[i].plane_states[j]->dst_rect.x; - temp_plane.dst_rect.y = set[i].plane_states[j]->dst_rect.y; - - if (memcmp(&temp_plane, set[i].plane_states[j], sizeof(temp_plane)) != 0) - return true; - } - } - - return false; -} - static bool validate_streams ( struct dc *dc, const struct dc_validation_set set[], @@ -733,52 +698,12 @@ static bool validate_surfaces( return true; } -struct validate_context *dc_get_validate_context( - struct dc *dc, - const struct dc_validation_set set[], - uint8_t set_count) -{ - struct dc *core_dc = dc; - enum dc_status result = DC_ERROR_UNEXPECTED; - struct validate_context *context; - - - context = dm_alloc(sizeof(struct validate_context)); - if (context == NULL) - goto context_alloc_fail; - - atomic_inc(&context->ref_count); - - if (!is_validation_required(core_dc, set, set_count)) { - dc_resource_validate_ctx_copy_construct(core_dc->current_context, context); - return context; - } - - result = core_dc->res_pool->funcs->validate_with_context( - core_dc, set, set_count, context, core_dc->current_context); - -context_alloc_fail: - if (result != DC_OK) { - dm_logger_write(core_dc->ctx->logger, LOG_WARNING, - "%s:resource validation failed, dc_status:%d\n", - __func__, - result); - - dc_release_validate_context(context); - context = NULL; - } - - return context; - -} - bool dc_validate_resources( struct dc *dc, const struct dc_validation_set set[], uint8_t set_count) { - struct dc *core_dc = dc; - enum dc_status result = DC_ERROR_UNEXPECTED; + bool result = false; struct validate_context *context; if (!validate_streams(dc, set, set_count)) @@ -793,21 +718,16 @@ bool dc_validate_resources( atomic_inc(&context->ref_count); - result = core_dc->res_pool->funcs->validate_with_context( - core_dc, set, set_count, context, NULL); + dc_resource_validate_ctx_copy_construct_current(dc, context); -context_alloc_fail: - if (result != DC_OK) { - dm_logger_write(core_dc->ctx->logger, LOG_WARNING, - "%s:resource validation failed, dc_status:%d\n", - __func__, - result); - } + result = dc_validate_with_context( + dc, set, set_count, context); +context_alloc_fail: dc_release_validate_context(context); context = NULL; - return result == DC_OK; + return result; } bool dc_validate_guaranteed( @@ -1093,7 +1013,7 @@ bool dc_commit_streams( uint8_t stream_count) { struct dc *core_dc = dc; - enum dc_status result = DC_ERROR_UNEXPECTED; + bool result = false; struct validate_context *context; struct dc_validation_set set[MAX_STREAMS] = { {0, {0} } }; int i; @@ -1135,13 +1055,11 @@ bool dc_commit_streams( atomic_inc(&context->ref_count); - result = core_dc->res_pool->funcs->validate_with_context( - core_dc, set, stream_count, context, core_dc->current_context); - if (result != DC_OK){ - dm_logger_write(core_dc->ctx->logger, LOG_ERROR, - "%s: Context validation failed! dc_status:%d\n", - __func__, - result); + dc_resource_validate_ctx_copy_construct_current(dc, context); + + result = dc_validate_with_context( + dc, set, stream_count, context); + if (!result) { BREAK_TO_DEBUGGER(); goto fail; } @@ -1152,7 +1070,7 @@ bool dc_commit_streams( dc_release_validate_context(context); context_alloc_fail: - return (result == DC_OK); + return result; } bool dc_post_update_surfaces_to_stream(struct dc *dc) 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 e3cf519a6e41..6b4eb4c3a3fd 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -938,7 +938,7 @@ struct pipe_ctx *resource_get_head_pipe_for_stream( int i; for (i = 0; i < MAX_PIPES; i++) { if (res_ctx->pipe_ctx[i].stream == stream && - res_ctx->pipe_ctx[i].stream_res.stream_enc) { + !res_ctx->pipe_ctx[i].top_pipe) { return &res_ctx->pipe_ctx[i]; break; } @@ -1217,29 +1217,31 @@ bool resource_validate_attach_surfaces( #define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000 #define TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST 297000 -static void set_stream_engine_in_use( +static void update_stream_engine_usage( struct resource_context *res_ctx, const struct resource_pool *pool, - struct stream_encoder *stream_enc) + struct stream_encoder *stream_enc, + bool acquired) { int i; for (i = 0; i < pool->stream_enc_count; i++) { if (pool->stream_enc[i] == stream_enc) - res_ctx->is_stream_enc_acquired[i] = true; + res_ctx->is_stream_enc_acquired[i] = acquired; } } /* TODO: release audio object */ -static void set_audio_in_use( +static void update_audio_usage( struct resource_context *res_ctx, const struct resource_pool *pool, - struct audio *audio) + struct audio *audio, + bool acquired) { int i; for (i = 0; i < pool->audio_count; i++) { if (pool->audios[i] == audio) - res_ctx->is_audio_acquired[i] = true; + res_ctx->is_audio_acquired[i] = acquired; } } @@ -1361,6 +1363,100 @@ bool resource_is_stream_unchanged( return false; } +bool dc_add_stream_to_ctx( + struct dc *dc, + struct validate_context *new_ctx, + struct dc_stream_state *stream) +{ + struct dc_context *dc_ctx = dc->ctx; + enum dc_status res; + + if (new_ctx->stream_count >= dc->res_pool->pipe_count) { + DC_ERROR("Max streams reached, can add stream %p !\n", stream); + return DC_ERROR_UNEXPECTED; + } + + new_ctx->streams[new_ctx->stream_count] = stream; + dc_stream_retain(stream); + new_ctx->stream_count++; + + res = dc->res_pool->funcs->add_stream_to_ctx(dc, new_ctx, stream); + if (res != DC_OK) + DC_ERROR("Adding stream %p to context failed with err %d!\n", stream, res); + + return res == DC_OK; +} + +bool dc_remove_stream_from_ctx( + struct dc *dc, + struct validate_context *new_ctx, + struct dc_stream_state *stream) +{ + int i, j; + struct dc_context *dc_ctx = dc->ctx; + struct pipe_ctx *del_pipe = NULL; + + /*TODO MPO to remove extra pipe or in surface remove ?*/ + + /* Release primary and secondary pipe (if exsist) */ + for (i = 0; i < MAX_PIPES; i++) { + if (new_ctx->res_ctx.pipe_ctx[i].stream == stream) { + del_pipe = &new_ctx->res_ctx.pipe_ctx[i]; + + if (del_pipe->stream_res.stream_enc) + update_stream_engine_usage( + &new_ctx->res_ctx, + dc->res_pool, + del_pipe->stream_res.stream_enc, + false); + + if (del_pipe->stream_res.audio) + update_audio_usage( + &new_ctx->res_ctx, + dc->res_pool, + del_pipe->stream_res.audio, + false); + + memset(del_pipe, 0, sizeof(*del_pipe)); + } + } + + if (!del_pipe) { + DC_ERROR("Pipe not found for stream %p !\n", stream); + return DC_ERROR_UNEXPECTED; + } + + for (i = 0; i < new_ctx->stream_count; i++) + if (new_ctx->streams[i] == stream) + break; + + if (new_ctx->streams[i] != stream) { + DC_ERROR("Context doesn't have stream %p !\n", stream); + return DC_ERROR_UNEXPECTED; + } + + dc_stream_release(new_ctx->streams[i]); + new_ctx->stream_count--; + + /*TODO move into dc_remove_surface_from_ctx ?*/ + for (j = 0; j < new_ctx->stream_status[i].plane_count; j++) + dc_plane_state_release(new_ctx->stream_status[i].plane_states[j]); + + /* Trim back arrays */ + for (; i < new_ctx->stream_count; i++) { + new_ctx->streams[i] = new_ctx->streams[i + 1]; + new_ctx->stream_status[i] = new_ctx->stream_status[i + 1]; + } + + new_ctx->streams[new_ctx->stream_count] = NULL; + memset( + &new_ctx->stream_status[new_ctx->stream_count], + 0, + sizeof(new_ctx->stream_status[0])); + + return DC_OK; +} + static void copy_pipe_ctx( const struct pipe_ctx *from_pipe_ctx, struct pipe_ctx *to_pipe_ctx) { @@ -1440,15 +1536,16 @@ static void calculate_phy_pix_clks(struct dc_stream_state *stream) enum dc_status resource_map_pool_resources( const struct dc *dc, struct validate_context *context, - struct validate_context *old_context) + struct dc_stream_state *stream) { const struct resource_pool *pool = dc->res_pool; - int i, j; - - for (i = 0; old_context && i < context->stream_count; i++) { - struct dc_stream_state *stream = context->streams[i]; + int i; + struct dc_context *dc_ctx = dc->ctx; + struct pipe_ctx *pipe_ctx = NULL; + int pipe_idx = -1; - if (!resource_is_stream_unchanged(old_context, stream)) { + /* TODO Check if this is needed */ + /*if (!resource_is_stream_unchanged(old_context, stream)) { if (stream != NULL && old_context->streams[i] != NULL) { stream->bit_depth_params = old_context->streams[i]->bit_depth_params; @@ -1456,119 +1553,228 @@ enum dc_status resource_map_pool_resources( continue; } } + */ - /* mark resources used for stream that is already active */ - for (j = 0; j < pool->pipe_count; j++) { - struct pipe_ctx *pipe_ctx = - &context->res_ctx.pipe_ctx[j]; - const struct pipe_ctx *old_pipe_ctx = - &old_context->res_ctx.pipe_ctx[j]; - - if (!are_stream_backends_same(old_pipe_ctx->stream, stream)) - continue; + /* acquire new resources */ + pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream); - if (old_pipe_ctx->top_pipe) - continue; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + if (pipe_idx < 0) + acquire_first_split_pipe(&context->res_ctx, pool, stream); +#endif + if (pipe_idx < 0) + return DC_NO_CONTROLLER_RESOURCE; + + pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; + + pipe_ctx->stream_res.stream_enc = + find_first_free_match_stream_enc_for_link( + &context->res_ctx, pool, stream); + + if (!pipe_ctx->stream_res.stream_enc) + return DC_NO_STREAM_ENG_RESOURCE; + + update_stream_engine_usage( + &context->res_ctx, pool, + pipe_ctx->stream_res.stream_enc, + true); + + /* TODO: Add check if ASIC support and EDID audio */ + if (!stream->sink->converter_disable_audio && + dc_is_audio_capable_signal(pipe_ctx->stream->signal) && + stream->audio_info.mode_count) { + pipe_ctx->stream_res.audio = find_first_free_audio( + &context->res_ctx, pool); + + /* + * Audio assigned in order first come first get. + * There are asics which has number of audio + * resources less then number of pipes + */ + if (pipe_ctx->stream_res.audio) + update_audio_usage(&context->res_ctx, pool, + pipe_ctx->stream_res.audio, true); + } - pipe_ctx->stream = stream; - copy_pipe_ctx(old_pipe_ctx, pipe_ctx); + for (i = 0; i < context->stream_count; i++) + if (context->streams[i] == stream) { + context->stream_status[i].primary_otg_inst = pipe_ctx->stream_res.tg->inst; + return DC_OK; + } - /* Split pipe resource, do not acquire back end */ - if (!pipe_ctx->stream_res.stream_enc) - continue; + DC_ERROR("Stream %p not found in new ctx!\n", stream); + return DC_ERROR_UNEXPECTED; +} - set_stream_engine_in_use( - &context->res_ctx, pool, - pipe_ctx->stream_res.stream_enc); +/* first stream in the context is used to populate the rest */ +void validate_guaranteed_copy_streams( + struct validate_context *context, + int max_streams) +{ + int i; - /* Switch to dp clock source only if there is - * no non dp stream that shares the same timing - * with the dp stream. - */ - if (dc_is_dp_signal(pipe_ctx->stream->signal) && - !find_pll_sharable_stream(stream, context)) - pipe_ctx->clock_source = pool->dp_clock_source; + for (i = 1; i < max_streams; i++) { + context->streams[i] = context->streams[0]; - resource_reference_clock_source( - &context->res_ctx, pool, - pipe_ctx->clock_source); + copy_pipe_ctx(&context->res_ctx.pipe_ctx[0], + &context->res_ctx.pipe_ctx[i]); + context->res_ctx.pipe_ctx[i].stream = + context->res_ctx.pipe_ctx[0].stream; - set_audio_in_use(&context->res_ctx, pool, - pipe_ctx->stream_res.audio); - } + dc_stream_retain(context->streams[i]); + context->stream_count++; } +} - for (i = 0; i < context->stream_count; i++) { - struct dc_stream_state *stream = context->streams[i]; - struct pipe_ctx *pipe_ctx = NULL; - int pipe_idx = -1; +void dc_resource_validate_ctx_copy_construct_current( + const struct dc *dc, + struct validate_context *dst_ctx) +{ + dc_resource_validate_ctx_copy_construct(dc->current_context, dst_ctx); +} - if (old_context && resource_is_stream_unchanged(old_context, stream)) - continue; - /* acquire new resources */ - pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream); -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) - if (pipe_idx < 0) - acquire_first_split_pipe(&context->res_ctx, pool, stream); -#endif - if (pipe_idx < 0) - return DC_NO_CONTROLLER_RESOURCE; +bool dc_validate_with_context( + struct dc *dc, + const struct dc_validation_set set[], + int set_count, + struct validate_context *context) +{ + int i, j; + enum dc_status res = DC_ERROR_UNEXPECTED; + bool found = false; + int old_stream_count = context->stream_count; + struct dc_stream_state *del_streams[MAX_PIPES] = { 0 }; + struct dc_stream_state *add_streams[MAX_PIPES] = { 0 }; + int del_streams_count = 0; + int add_streams_count = 0; - pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; - pipe_ctx->stream_res.stream_enc = - find_first_free_match_stream_enc_for_link( - &context->res_ctx, pool, stream); + /* First remove from context all deleted streams */ + for (i = 0; i < old_stream_count; i++) { + struct dc_stream_state *stream = context->streams[i]; + + for (j = 0; j < set_count; j++) { + if (stream == set[j].stream) { + found = true; + break; + } + } - if (!pipe_ctx->stream_res.stream_enc) - return DC_NO_STREAM_ENG_RESOURCE; + if (!found) + del_streams[del_streams_count++] = stream; - set_stream_engine_in_use( - &context->res_ctx, pool, - pipe_ctx->stream_res.stream_enc); + found = false; + } - /* TODO: Add check if ASIC support and EDID audio */ - if (!stream->sink->converter_disable_audio && - dc_is_audio_capable_signal(pipe_ctx->stream->signal) && - stream->audio_info.mode_count) { - pipe_ctx->stream_res.audio = find_first_free_audio( - &context->res_ctx, pool); + /* Now add new ones */ + for (i = 0; i < set_count; i++) { + struct dc_stream_state *stream = set[i].stream; - /* - * Audio assigned in order first come first get. - * There are asics which has number of audio - * resources less then number of pipes - */ - if (pipe_ctx->stream_res.audio) - set_audio_in_use( - &context->res_ctx, pool, - pipe_ctx->stream_res.audio); + for (j = 0; j < old_stream_count; j++) { + if (stream == context->streams[j]) { + found = true; + break; + } } - context->stream_status[i].primary_otg_inst = pipe_ctx->stream_res.tg->inst; + if (!found) + add_streams[add_streams_count++] = stream; + + found = false; } - return DC_OK; + for (i = 0; i < del_streams_count; i++) + if (!dc_remove_stream_from_ctx(dc, context, del_streams[i])) + goto fail; + + for (i = 0; i < add_streams_count; i++) + if (!dc_add_stream_to_ctx(dc, context, add_streams[i])) + goto fail; + + if (!dc_validate_global_state(dc, set, set_count, context)) + goto fail; + + res = DC_OK; + +fail: + if (res != DC_OK) { + dm_logger_write(dc->ctx->logger, LOG_WARNING, + "%s:resource validation failed, dc_status:%d\n", + __func__, + res); +} + return res == DC_OK; } -/* first stream in the context is used to populate the rest */ -void validate_guaranteed_copy_streams( - struct validate_context *context, - int max_streams) +bool dc_validate_global_state( + struct dc *dc, + const struct dc_validation_set set[], + int set_count, + struct validate_context *new_ctx) { - int i; + enum dc_status result = DC_ERROR_UNEXPECTED; + struct dc_context *dc_ctx = dc->ctx; + struct validate_context *old_context = dc->current_context; + int i, j; - for (i = 1; i < max_streams; i++) { - context->streams[i] = context->streams[0]; + if (dc->res_pool->funcs->validate_global && + dc->res_pool->funcs->validate_global(dc, set, set_count, + old_context, new_ctx) != DC_OK) + return false; - copy_pipe_ctx(&context->res_ctx.pipe_ctx[0], - &context->res_ctx.pipe_ctx[i]); - context->res_ctx.pipe_ctx[i].stream = - context->res_ctx.pipe_ctx[0].stream; + /* TODO without this SWDEV-114774 brakes */ + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe_ctx = &new_ctx->res_ctx.pipe_ctx[i]; - dc_stream_retain(context->streams[i]); - context->stream_count++; + if (pipe_ctx->top_pipe) + memset(pipe_ctx, 0, sizeof(*pipe_ctx)); + } + + for (i = 0; new_ctx && i < new_ctx->stream_count; i++) { + struct dc_stream_state *stream = new_ctx->streams[i]; + + for (j = 0; j < dc->res_pool->pipe_count; j++) { + struct pipe_ctx *pipe_ctx = &new_ctx->res_ctx.pipe_ctx[j]; + + if (pipe_ctx->stream != stream) + continue; + + /* Switch to dp clock source only if there is + * no non dp stream that shares the same timing + * with the dp stream. + */ + if (dc_is_dp_signal(pipe_ctx->stream->signal) && + !find_pll_sharable_stream(stream, new_ctx)) { + + resource_unreference_clock_source( + &new_ctx->res_ctx, + dc->res_pool, + &pipe_ctx->clock_source); + pipe_ctx->clock_source = dc->res_pool->dp_clock_source; + resource_reference_clock_source( + &new_ctx->res_ctx, + dc->res_pool, + pipe_ctx->clock_source); + } + } + } + + /*TODO This should be ok */ + /* Split pipe resource, do not acquire back end */ + + if (!resource_validate_attach_surfaces( + set, set_count, old_context, new_ctx, dc->res_pool)) { + DC_ERROR("Failed to attach surface to stream!\n"); + return DC_FAIL_ATTACH_SURFACES; } + + result = resource_build_scaling_params_for_context(dc, new_ctx); + + if (result == DC_OK) + if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx)) + result = DC_FAIL_BANDWIDTH_VALIDATE; + + return result; } static void patch_gamut_packet_checksum( @@ -2318,54 +2524,40 @@ void resource_build_info_frame(struct pipe_ctx *pipe_ctx) enum dc_status resource_map_clock_resources( const struct dc *dc, struct validate_context *context, - struct validate_context *old_context) + struct dc_stream_state *stream) { - int i, j; - const struct resource_pool *pool = dc->res_pool; - /* acquire new resources */ - for (i = 0; i < context->stream_count; i++) { - struct dc_stream_state *stream = context->streams[i]; - - if (old_context && resource_is_stream_unchanged(old_context, stream)) - continue; + const struct resource_pool *pool = dc->res_pool; + struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream( + &context->res_ctx, stream); - for (j = 0; j < MAX_PIPES; j++) { - struct pipe_ctx *pipe_ctx = - &context->res_ctx.pipe_ctx[j]; + if (!pipe_ctx) + return DC_ERROR_UNEXPECTED; - if (context->res_ctx.pipe_ctx[j].stream != stream) - continue; + if (dc_is_dp_signal(pipe_ctx->stream->signal) + || pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL) + pipe_ctx->clock_source = pool->dp_clock_source; + else { + pipe_ctx->clock_source = NULL; - if (dc_is_dp_signal(pipe_ctx->stream->signal) - || pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL) - pipe_ctx->clock_source = pool->dp_clock_source; - else { - pipe_ctx->clock_source = NULL; - - if (!dc->config.disable_disp_pll_sharing) - resource_find_used_clk_src_for_sharing( - &context->res_ctx, - pipe_ctx); - - if (pipe_ctx->clock_source == NULL) - pipe_ctx->clock_source = - dc_resource_find_first_free_pll( - &context->res_ctx, - pool); - } + if (!dc->config.disable_disp_pll_sharing) + resource_find_used_clk_src_for_sharing( + &context->res_ctx, + pipe_ctx); - if (pipe_ctx->clock_source == NULL) - return DC_NO_CLOCK_SOURCE_RESOURCE; + if (pipe_ctx->clock_source == NULL) + pipe_ctx->clock_source = + dc_resource_find_first_free_pll( + &context->res_ctx, + pool); + } - resource_reference_clock_source( - &context->res_ctx, pool, - pipe_ctx->clock_source); + if (pipe_ctx->clock_source == NULL) + return DC_NO_CLOCK_SOURCE_RESOURCE; - /* only one cs per stream regardless of mpo */ - break; - } - } + resource_reference_clock_source( + &context->res_ctx, pool, + pipe_ctx->clock_source); return DC_OK; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 629aa3c323ca..2b4fc6616243 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -618,6 +618,16 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream, uint32_t *h_position, uint32_t *v_position); +bool dc_remove_stream_from_ctx( + struct dc *dc, + struct validate_context *new_ctx, + struct dc_stream_state *stream); + +bool dc_add_stream_to_ctx( + struct dc *dc, + struct validate_context *new_ctx, + struct dc_stream_state *stream); + /* * Structure to store surface/stream associations for validation */ @@ -630,16 +640,18 @@ struct dc_validation_set { bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream); bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state); -/* - * This function takes a set of resources and checks that they are cofunctional. - * - * After this call: - * No hardware is programmed for call. Only validation is done. - */ -struct validate_context *dc_get_validate_context( + +bool dc_validate_with_context( struct dc *dc, const struct dc_validation_set set[], - uint8_t set_count); + int set_count, + struct validate_context *context); + +bool dc_validate_global_state( + struct dc *dc, + const struct dc_validation_set set[], + int set_count, + struct validate_context *new_ctx); bool dc_validate_resources( struct dc *dc, @@ -662,6 +674,10 @@ void dc_resource_validate_ctx_copy_construct( const struct validate_context *src_ctx, struct validate_context *dst_ctx); +void dc_resource_validate_ctx_copy_construct_current( + const struct dc *dc, + struct validate_context *dst_ctx); + void dc_resource_validate_ctx_destruct(struct validate_context *context); /* diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index b2b03633eb4f..c9dad4e2a7c8 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c @@ -654,35 +654,20 @@ static void destruct(struct dce110_resource_pool *pool) static enum dc_status build_mapped_resource( const struct dc *dc, struct validate_context *context, - struct validate_context *old_context) + struct dc_stream_state *stream) { enum dc_status status = DC_OK; - uint8_t i, j; + struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); - for (i = 0; i < context->stream_count; i++) { - struct dc_stream_state *stream = context->streams[i]; + if (!pipe_ctx) + return DC_ERROR_UNEXPECTED; - if (old_context && resource_is_stream_unchanged(old_context, stream)) - continue; - - for (j = 0; j < MAX_PIPES; j++) { - struct pipe_ctx *pipe_ctx = - &context->res_ctx.pipe_ctx[j]; - - if (context->res_ctx.pipe_ctx[j].stream != stream) - continue; - - status = dce110_resource_build_pipe_hw_param(pipe_ctx); + status = dce110_resource_build_pipe_hw_param(pipe_ctx); - if (status != DC_OK) - return status; + if (status != DC_OK) + return status; - resource_build_info_frame(pipe_ctx); - - /* do not need to validate non root pipes */ - break; - } - } + resource_build_info_frame(pipe_ctx); return DC_OK; } @@ -719,48 +704,17 @@ static bool dce100_validate_surface_sets( return true; } -enum dc_status dce100_validate_with_context( +enum dc_status dce100_validate_global( struct dc *dc, const struct dc_validation_set set[], int set_count, - struct validate_context *context, - struct validate_context *old_context) + struct validate_context *old_context, + struct validate_context *context) { - struct dc_context *dc_ctx = dc->ctx; - enum dc_status result = DC_ERROR_UNEXPECTED; - int i; - if (!dce100_validate_surface_sets(set, set_count)) return DC_FAIL_SURFACE_VALIDATE; - for (i = 0; i < set_count; i++) { - context->streams[i] = set[i].stream; - dc_stream_retain(context->streams[i]); - context->stream_count++; - } - - result = resource_map_pool_resources(dc, context, old_context); - - if (result == DC_OK) - result = resource_map_clock_resources(dc, context, old_context); - - if (!resource_validate_attach_surfaces(set, set_count, - old_context, context, dc->res_pool)) { - DC_ERROR("Failed to attach surface to stream!\n"); - return DC_FAIL_ATTACH_SURFACES; - } - - if (result == DC_OK) - result = build_mapped_resource(dc, context, old_context); - - if (result == DC_OK) - result = resource_build_scaling_params_for_context(dc, context); - - if (result == DC_OK) - if (!dce100_validate_bandwidth(dc, context)) - result = DC_FAIL_BANDWIDTH_VALIDATE; - - return result; + return DC_OK; } enum dc_status dce100_validate_guaranteed( @@ -774,13 +728,13 @@ enum dc_status dce100_validate_guaranteed( dc_stream_retain(context->streams[0]); context->stream_count++; - result = resource_map_pool_resources(dc, context, NULL); + result = resource_map_pool_resources(dc, context, dc_stream); if (result == DC_OK) - result = resource_map_clock_resources(dc, context, NULL); + result = resource_map_clock_resources(dc, context, dc_stream); if (result == DC_OK) - result = build_mapped_resource(dc, context, NULL); + result = build_mapped_resource(dc, context, dc_stream); if (result == DC_OK) { validate_guaranteed_copy_streams( @@ -816,10 +770,10 @@ enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state) static const struct resource_funcs dce100_res_pool_funcs = { .destroy = dce100_destroy_resource_pool, .link_enc_create = dce100_link_encoder_create, - .validate_with_context = dce100_validate_with_context, .validate_guaranteed = dce100_validate_guaranteed, .validate_bandwidth = dce100_validate_bandwidth, .validate_plane = dce100_validate_plane, + .validate_global = dce100_validate_global }; static bool construct( diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index 2154c2e567f2..d682180f2eaf 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -774,41 +774,26 @@ static bool is_surface_pixel_format_supported(struct pipe_ctx *pipe_ctx, unsigne static enum dc_status build_mapped_resource( const struct dc *dc, struct validate_context *context, - struct validate_context *old_context) + struct dc_stream_state *stream) { enum dc_status status = DC_OK; - uint8_t i, j; - - for (i = 0; i < context->stream_count; i++) { - struct dc_stream_state *stream = context->streams[i]; - - if (old_context && resource_is_stream_unchanged(old_context, stream)) - continue; + struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); - for (j = 0; j < MAX_PIPES; j++) { - struct pipe_ctx *pipe_ctx = - &context->res_ctx.pipe_ctx[j]; + if (!pipe_ctx) + return DC_ERROR_UNEXPECTED; - if (context->res_ctx.pipe_ctx[j].stream != stream) - continue; + if (!is_surface_pixel_format_supported(pipe_ctx, + dc->res_pool->underlay_pipe_index)) + return DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED; - if (!is_surface_pixel_format_supported(pipe_ctx, - dc->res_pool->underlay_pipe_index)) - return DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED; + status = dce110_resource_build_pipe_hw_param(pipe_ctx); - status = dce110_resource_build_pipe_hw_param(pipe_ctx); + if (status != DC_OK) + return status; - if (status != DC_OK) - return status; + /* TODO: validate audio ASIC caps, encoder */ - /* TODO: validate audio ASIC caps, encoder */ - - resource_build_info_frame(pipe_ctx); - - /* do not need to validate non root pipes */ - break; - } - } + resource_build_info_frame(pipe_ctx); return DC_OK; } @@ -927,48 +912,17 @@ static bool dce110_validate_surface_sets( return true; } -static enum dc_status dce110_validate_with_context( +enum dc_status dce110_validate_global( struct dc *dc, const struct dc_validation_set set[], int set_count, - struct validate_context *context, - struct validate_context *old_context) + struct validate_context *old_context, + struct validate_context *context) { - struct dc_context *dc_ctx = dc->ctx; - enum dc_status result = DC_ERROR_UNEXPECTED; - int i; - if (!dce110_validate_surface_sets(set, set_count)) return DC_FAIL_SURFACE_VALIDATE; - for (i = 0; i < set_count; i++) { - context->streams[i] = set[i].stream; - dc_stream_retain(context->streams[i]); - context->stream_count++; - } - - result = resource_map_pool_resources(dc, context, old_context); - - if (result == DC_OK) - result = resource_map_clock_resources(dc, context, old_context); - - if (!resource_validate_attach_surfaces(set, set_count, - old_context, context, dc->res_pool)) { - DC_ERROR("Failed to attach surface to stream!\n"); - return DC_FAIL_ATTACH_SURFACES; - } - - if (result == DC_OK) - result = build_mapped_resource(dc, context, old_context); - - if (result == DC_OK) - result = resource_build_scaling_params_for_context(dc, context); - - if (result == DC_OK) - if (!dce110_validate_bandwidth(dc, context)) - result = DC_FAIL_BANDWIDTH_VALIDATE; - - return result; + return DC_OK; } static enum dc_status dce110_validate_guaranteed( @@ -982,13 +936,13 @@ static enum dc_status dce110_validate_guaranteed( dc_stream_retain(context->streams[0]); context->stream_count++; - result = resource_map_pool_resources(dc, context, NULL); + result = resource_map_pool_resources(dc, context, dc_stream); if (result == DC_OK) - result = resource_map_clock_resources(dc, context, NULL); + result = resource_map_clock_resources(dc, context, dc_stream); if (result == DC_OK) - result = build_mapped_resource(dc, context, NULL); + result = build_mapped_resource(dc, context, dc_stream); if (result == DC_OK) { validate_guaranteed_copy_streams( @@ -1078,10 +1032,10 @@ static void dce110_destroy_resource_pool(struct resource_pool **pool) static const struct resource_funcs dce110_res_pool_funcs = { .destroy = dce110_destroy_resource_pool, .link_enc_create = dce110_link_encoder_create, - .validate_with_context = dce110_validate_with_context, .validate_guaranteed = dce110_validate_guaranteed, .validate_bandwidth = dce110_validate_bandwidth, .acquire_idle_pipe_for_layer = dce110_acquire_underlay, + .validate_global = dce110_validate_global }; static bool underlay_create(struct dc_context *ctx, struct resource_pool *pool) diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index 89a8dfa68c01..85a396ef5aa5 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c @@ -725,35 +725,20 @@ static struct clock_source *find_matching_pll( static enum dc_status build_mapped_resource( const struct dc *dc, struct validate_context *context, - struct validate_context *old_context) + struct dc_stream_state *stream) { enum dc_status status = DC_OK; - uint8_t i, j; + struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); - for (i = 0; i < context->stream_count; i++) { - struct dc_stream_state *stream = context->streams[i]; + if (!pipe_ctx) + return DC_ERROR_UNEXPECTED; - if (old_context && resource_is_stream_unchanged(old_context, stream)) - continue; - - for (j = 0; j < MAX_PIPES; j++) { - struct pipe_ctx *pipe_ctx = - &context->res_ctx.pipe_ctx[j]; - - if (context->res_ctx.pipe_ctx[j].stream != stream) - continue; + status = dce110_resource_build_pipe_hw_param(pipe_ctx); - status = dce110_resource_build_pipe_hw_param(pipe_ctx); + if (status != DC_OK) + return status; - if (status != DC_OK) - return status; - - resource_build_info_frame(pipe_ctx); - - /* do not need to validate non root pipes */ - break; - } - } + resource_build_info_frame(pipe_ctx); return DC_OK; } @@ -839,45 +824,32 @@ bool dce112_validate_bandwidth( enum dc_status resource_map_phy_clock_resources( const struct dc *dc, struct validate_context *context, - struct validate_context *old_context) + struct dc_stream_state *stream) { - uint8_t i, j; /* acquire new resources */ - for (i = 0; i < context->stream_count; i++) { - struct dc_stream_state *stream = context->streams[i]; - - if (old_context && resource_is_stream_unchanged(old_context, stream)) - continue; - - for (j = 0; j < MAX_PIPES; j++) { - struct pipe_ctx *pipe_ctx = - &context->res_ctx.pipe_ctx[j]; - - if (context->res_ctx.pipe_ctx[j].stream != stream) - continue; + struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream( + &context->res_ctx, stream); - if (dc_is_dp_signal(pipe_ctx->stream->signal) - || pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL) - pipe_ctx->clock_source = - dc->res_pool->dp_clock_source; - else - pipe_ctx->clock_source = find_matching_pll( - &context->res_ctx, dc->res_pool, - stream); + if (!pipe_ctx) + return DC_ERROR_UNEXPECTED; - if (pipe_ctx->clock_source == NULL) - return DC_NO_CLOCK_SOURCE_RESOURCE; + if (dc_is_dp_signal(pipe_ctx->stream->signal) + || pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL) + pipe_ctx->clock_source = + dc->res_pool->dp_clock_source; + else + pipe_ctx->clock_source = find_matching_pll( + &context->res_ctx, dc->res_pool, + stream); - resource_reference_clock_source( - &context->res_ctx, - dc->res_pool, - pipe_ctx->clock_source); + if (pipe_ctx->clock_source == NULL) + return DC_NO_CLOCK_SOURCE_RESOURCE; - /* only one cs per stream regardless of mpo */ - break; - } - } + resource_reference_clock_source( + &context->res_ctx, + dc->res_pool, + pipe_ctx->clock_source); return DC_OK; } @@ -903,46 +875,21 @@ static bool dce112_validate_surface_sets( return true; } -enum dc_status dce112_validate_with_context( +enum dc_status dce112_add_stream_to_ctx( struct dc *dc, - const struct dc_validation_set set[], - int set_count, - struct validate_context *context, - struct validate_context *old_context) + struct validate_context *new_ctx, + struct dc_stream_state *dc_stream) { - struct dc_context *dc_ctx = dc->ctx; enum dc_status result = DC_ERROR_UNEXPECTED; - int i; - if (!dce112_validate_surface_sets(set, set_count)) - return DC_FAIL_SURFACE_VALIDATE; - - for (i = 0; i < set_count; i++) { - context->streams[i] = set[i].stream; - dc_stream_retain(context->streams[i]); - context->stream_count++; - } - - result = resource_map_pool_resources(dc, context, old_context); + result = resource_map_pool_resources(dc, new_ctx, dc_stream); if (result == DC_OK) - result = resource_map_phy_clock_resources(dc, context, old_context); - - if (!resource_validate_attach_surfaces(set, set_count, - old_context, context, dc->res_pool)) { - DC_ERROR("Failed to attach surface to stream!\n"); - return DC_FAIL_ATTACH_SURFACES; - } + result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream); - if (result == DC_OK) - result = build_mapped_resource(dc, context, old_context); if (result == DC_OK) - result = resource_build_scaling_params_for_context(dc, context); - - if (result == DC_OK) - if (!dce112_validate_bandwidth(dc, context)) - result = DC_FAIL_BANDWIDTH_VALIDATE; + result = build_mapped_resource(dc, new_ctx, dc_stream); return result; } @@ -958,13 +905,13 @@ enum dc_status dce112_validate_guaranteed( dc_stream_retain(context->streams[0]); context->stream_count++; - result = resource_map_pool_resources(dc, context, NULL); + result = resource_map_pool_resources(dc, context, stream); if (result == DC_OK) - result = resource_map_phy_clock_resources(dc, context, NULL); + result = resource_map_phy_clock_resources(dc, context, stream); if (result == DC_OK) - result = build_mapped_resource(dc, context, NULL); + result = build_mapped_resource(dc, context, stream); if (result == DC_OK) { validate_guaranteed_copy_streams( @@ -979,6 +926,19 @@ enum dc_status dce112_validate_guaranteed( return result; } +enum dc_status dce112_validate_global( + struct dc *dc, + const struct dc_validation_set set[], + int set_count, + struct validate_context *old_context, + struct validate_context *context) +{ + if (!dce112_validate_surface_sets(set, set_count)) + return DC_FAIL_SURFACE_VALIDATE; + + return DC_OK; +} + static void dce112_destroy_resource_pool(struct resource_pool **pool) { struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool); @@ -991,10 +951,11 @@ static void dce112_destroy_resource_pool(struct resource_pool **pool) static const struct resource_funcs dce112_res_pool_funcs = { .destroy = dce112_destroy_resource_pool, .link_enc_create = dce112_link_encoder_create, - .validate_with_context = dce112_validate_with_context, .validate_guaranteed = dce112_validate_guaranteed, .validate_bandwidth = dce112_validate_bandwidth, - .validate_plane = dce100_validate_plane + .validate_plane = dce100_validate_plane, + .add_stream_to_ctx = dce112_add_stream_to_ctx, + .validate_global = dce112_validate_global }; static void bw_calcs_data_update_from_pplib(struct dc *dc) diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h index 69f8f689196d..f1834bfe3d1e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h @@ -51,6 +51,11 @@ bool dce112_validate_bandwidth( struct dc *dc, struct validate_context *context); +enum dc_status dce112_add_stream_to_ctx( + struct dc *dc, + struct validate_context *new_ctx, + struct dc_stream_state *dc_stream); + #endif /* __DC_RESOURCE_DCE112_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c index b8fcdff40db3..e5d2d98982f7 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c @@ -698,10 +698,10 @@ static void dce120_destroy_resource_pool(struct resource_pool **pool) static const struct resource_funcs dce120_res_pool_funcs = { .destroy = dce120_destroy_resource_pool, .link_enc_create = dce120_link_encoder_create, - .validate_with_context = dce112_validate_with_context, .validate_guaranteed = dce112_validate_guaranteed, .validate_bandwidth = dce112_validate_bandwidth, - .validate_plane = dce100_validate_plane + .validate_plane = dce100_validate_plane, + .add_stream_to_ctx = dce112_add_stream_to_ctx }; static void bw_calcs_data_update_from_pplib(struct dc *dc) diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c index 838bfdaee009..ac3f42a44030 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c @@ -686,35 +686,20 @@ static void destruct(struct dce110_resource_pool *pool) static enum dc_status build_mapped_resource( const struct dc *dc, struct validate_context *context, - struct validate_context *old_context) + struct dc_stream_state *stream) { enum dc_status status = DC_OK; - uint8_t i, j; + struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); - for (i = 0; i < context->stream_count; i++) { - struct dc_stream_state *stream = context->streams[i]; + if (!pipe_ctx) + return DC_ERROR_UNEXPECTED; - if (old_context && resource_is_stream_unchanged(old_context, stream)) - continue; - - for (j = 0; j < MAX_PIPES; j++) { - struct pipe_ctx *pipe_ctx = - &context->res_ctx.pipe_ctx[j]; - - if (context->res_ctx.pipe_ctx[j].stream != stream) - continue; - - status = dce110_resource_build_pipe_hw_param(pipe_ctx); + status = dce110_resource_build_pipe_hw_param(pipe_ctx); - if (status != DC_OK) - return status; + if (status != DC_OK) + return status; - resource_build_info_frame(pipe_ctx); - - /* do not need to validate non root pipes */ - break; - } - } + resource_build_info_frame(pipe_ctx); return DC_OK; } @@ -751,47 +736,17 @@ static bool dce80_validate_surface_sets( return true; } -enum dc_status dce80_validate_with_context( +enum dc_status dce80_validate_global( struct dc *dc, const struct dc_validation_set set[], int set_count, - struct validate_context *context, - struct validate_context *old_context) + struct validate_context *old_context, + struct validate_context *context) { - struct dc_context *dc_ctx = dc->ctx; - enum dc_status result = DC_ERROR_UNEXPECTED; - int i; - if (!dce80_validate_surface_sets(set, set_count)) return DC_FAIL_SURFACE_VALIDATE; - for (i = 0; i < set_count; i++) { - context->streams[i] = set[i].stream; - dc_stream_retain(context->streams[i]); - context->stream_count++; - } - - result = resource_map_pool_resources(dc, context, old_context); - - if (result == DC_OK) - result = resource_map_clock_resources(dc, context, old_context); - - if (!resource_validate_attach_surfaces(set, set_count, - old_context, context, dc->res_pool)) { - DC_ERROR("Failed to attach surface to stream!\n"); - return DC_FAIL_ATTACH_SURFACES; - } - - if (result == DC_OK) - result = build_mapped_resource(dc, context, old_context); - - if (result == DC_OK) - result = resource_build_scaling_params_for_context(dc, context); - - if (result == DC_OK) - result = dce80_validate_bandwidth(dc, context); - - return result; + return DC_OK; } enum dc_status dce80_validate_guaranteed( @@ -805,13 +760,13 @@ enum dc_status dce80_validate_guaranteed( dc_stream_retain(context->streams[0]); context->stream_count++; - result = resource_map_pool_resources(dc, context, NULL); + result = resource_map_pool_resources(dc, context, dc_stream); if (result == DC_OK) - result = resource_map_clock_resources(dc, context, NULL); + result = resource_map_clock_resources(dc, context, dc_stream); if (result == DC_OK) - result = build_mapped_resource(dc, context, NULL); + result = build_mapped_resource(dc, context, dc_stream); if (result == DC_OK) { validate_guaranteed_copy_streams( @@ -837,10 +792,10 @@ static void dce80_destroy_resource_pool(struct resource_pool **pool) static const struct resource_funcs dce80_res_pool_funcs = { .destroy = dce80_destroy_resource_pool, .link_enc_create = dce80_link_encoder_create, - .validate_with_context = dce80_validate_with_context, .validate_guaranteed = dce80_validate_guaranteed, .validate_bandwidth = dce80_validate_bandwidth, - .validate_plane = dce100_validate_plane + .validate_plane = dce100_validate_plane, + .validate_global = dce80_validate_global }; static bool dce80_construct( 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 954c234090db..ee43cbc70c8a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -48,6 +48,7 @@ #include "dce/dce_hwseq.h" #include "../virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" +#include "dce112/dce112_resource.h" #include "vega10/soc15ip.h" @@ -840,17 +841,15 @@ static enum dc_status build_pipe_hw_param(struct pipe_ctx *pipe_ctx) static enum dc_status build_mapped_resource( const struct dc *dc, struct validate_context *context, - struct validate_context *old_context) + struct dc_stream_state *stream) { enum dc_status status = DC_OK; - uint8_t i, j; - - for (i = 0; i < context->stream_count; i++) { - struct dc_stream_state *stream = context->streams[i]; + struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); - if (old_context && resource_is_stream_unchanged(old_context, stream)) { + /*TODO Seems unneeded anymore */ + /* if (old_context && resource_is_stream_unchanged(old_context, stream)) { if (stream != NULL && old_context->streams[i] != NULL) { - /* todo: shouldn't have to copy missing parameter here */ + todo: shouldn't have to copy missing parameter here resource_build_bit_depth_reduction_params(stream, &stream->bit_depth_params); stream->clamping.pixel_encoding = @@ -863,68 +862,34 @@ static enum dc_status build_mapped_resource( continue; } } + */ - for (j = 0; j < dc->res_pool->pipe_count ; j++) { - struct pipe_ctx *pipe_ctx = - &context->res_ctx.pipe_ctx[j]; + if (!pipe_ctx) + return DC_ERROR_UNEXPECTED; - if (context->res_ctx.pipe_ctx[j].stream != stream) - continue; + status = build_pipe_hw_param(pipe_ctx); - status = build_pipe_hw_param(pipe_ctx); - - if (status != DC_OK) - return status; - - /* do not need to validate non root pipes */ - break; - } - } + if (status != DC_OK) + return status; return DC_OK; } -enum dc_status dcn10_validate_with_context( +enum dc_status dcn10_add_stream_to_ctx( struct dc *dc, - const struct dc_validation_set set[], - int set_count, - struct validate_context *context, - struct validate_context *old_context) + struct validate_context *new_ctx, + struct dc_stream_state *dc_stream) { - enum dc_status result = DC_OK; - int i; - - if (set_count == 0) - return result; - - for (i = 0; i < set_count; i++) { - context->streams[i] = set[i].stream; - dc_stream_retain(context->streams[i]); - context->stream_count++; - } - - result = resource_map_pool_resources(dc, context, old_context); - if (result != DC_OK) - return result; - - result = resource_map_phy_clock_resources(dc, context, old_context); - if (result != DC_OK) - return result; + enum dc_status result = DC_ERROR_UNEXPECTED; - result = build_mapped_resource(dc, context, old_context); - if (result != DC_OK) - return result; + result = resource_map_pool_resources(dc, new_ctx, dc_stream); - if (!resource_validate_attach_surfaces(set, set_count, - old_context, context, dc->res_pool)) - return DC_FAIL_ATTACH_SURFACES; + if (result == DC_OK) + result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream); - result = resource_build_scaling_params_for_context(dc, context); - if (result != DC_OK) - return result; - if (!dcn_validate_bandwidth(dc, context)) - return DC_FAIL_BANDWIDTH_VALIDATE; + if (result == DC_OK) + result = build_mapped_resource(dc, new_ctx, dc_stream); return result; } @@ -940,13 +905,13 @@ enum dc_status dcn10_validate_guaranteed( dc_stream_retain(context->streams[0]); context->stream_count++; - result = resource_map_pool_resources(dc, context, NULL); + result = resource_map_pool_resources(dc, context, dc_stream); if (result == DC_OK) - result = resource_map_phy_clock_resources(dc, context, NULL); + result = resource_map_phy_clock_resources(dc, context, dc_stream); if (result == DC_OK) - result = build_mapped_resource(dc, context, NULL); + result = build_mapped_resource(dc, context, dc_stream); if (result == DC_OK) { validate_guaranteed_copy_streams( @@ -1226,10 +1191,10 @@ static struct dc_cap_funcs cap_funcs = { static struct resource_funcs dcn10_res_pool_funcs = { .destroy = dcn10_destroy_resource_pool, .link_enc_create = dcn10_link_encoder_create, - .validate_with_context = dcn10_validate_with_context, .validate_guaranteed = dcn10_validate_guaranteed, .validate_bandwidth = dcn_validate_bandwidth, .acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer, + .add_stream_to_ctx = dcn10_add_stream_to_ctx }; static bool construct( diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index a3f0039088ab..9a3239028377 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -87,12 +87,6 @@ struct resource_funcs { void (*destroy)(struct resource_pool **pool); struct link_encoder *(*link_enc_create)( const struct encoder_init_data *init); - enum dc_status (*validate_with_context)( - struct dc *dc, - const struct dc_validation_set set[], - int set_count, - struct validate_context *context, - struct validate_context *old_context); enum dc_status (*validate_guaranteed)( struct dc *dc, @@ -103,11 +97,24 @@ struct resource_funcs { struct dc *dc, struct validate_context *context); + enum dc_status (*validate_global)( + struct dc *dc, + const struct dc_validation_set set[], + int set_count, + struct validate_context *old_context, + struct validate_context *context); + struct pipe_ctx *(*acquire_idle_pipe_for_layer)( struct validate_context *context, const struct resource_pool *pool, struct dc_stream_state *stream); + enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state); + + enum dc_status (*add_stream_to_ctx)( + struct dc *dc, + struct validate_context *new_ctx, + struct dc_stream_state *dc_stream); }; struct audio_support{ diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index 9085ec7ceac7..ebc0f5b02365 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -82,7 +82,7 @@ void dc_destroy_resource_pool(struct dc *dc); enum dc_status resource_map_pool_resources( const struct dc *dc, struct validate_context *context, - struct validate_context *old_context); + struct dc_stream_state *stream); bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx); @@ -150,12 +150,12 @@ void resource_validate_ctx_update_pointer_after_copy( enum dc_status resource_map_clock_resources( const struct dc *dc, struct validate_context *context, - struct validate_context *old_context); + struct dc_stream_state *stream); enum dc_status resource_map_phy_clock_resources( const struct dc *dc, struct validate_context *context, - struct validate_context *old_context); + struct dc_stream_state *stream); bool pipe_need_reprogram( struct pipe_ctx *pipe_ctx_old, -- 2.11.0