diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1006-drm-amd-display-Per-plane-validation-context-build.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1006-drm-amd-display-Per-plane-validation-context-build.patch | 1042 |
1 files changed, 1042 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1006-drm-amd-display-Per-plane-validation-context-build.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1006-drm-amd-display-Per-plane-validation-context-build.patch new file mode 100644 index 00000000..487707c9 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1006-drm-amd-display-Per-plane-validation-context-build.patch @@ -0,0 +1,1042 @@ +From dce4dfc0376dab417aefa307010b2d8d67847070 Mon Sep 17 00:00:00 2001 +From: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com> +Date: Fri, 11 Aug 2017 10:43:45 -0400 +Subject: [PATCH 1006/4131] drm/amd/display: Per plane validation context + build. + +Introduce add/remove plane to/from context. +Make DC wrapper to use them in WIndows/Diags. +Use them in dc_update_surface_to_stream. +Call add/remove plane from Linux DM. + +Remove dc_validation_set from dc_validate_global_state interface +and by this remove clean Linux DM from using it. + +Change-Id: I387a22f63cf67bcdf7f9d86144efc3a8096306a7 +Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com> +Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> +Acked-by: Harry Wentland <Harry.Wentland@amd.com> +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 165 ++++------ + drivers/gpu/drm/amd/display/dc/core/dc.c | 12 +- + drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 362 +++++++++++++-------- + drivers/gpu/drm/amd/display/dc/dc.h | 37 ++- + .../drm/amd/display/dc/dce100/dce100_resource.c | 16 +- + .../drm/amd/display/dc/dce110/dce110_resource.c | 26 +- + .../drm/amd/display/dc/dce112/dce112_resource.c | 16 +- + .../gpu/drm/amd/display/dc/dce80/dce80_resource.c | 16 +- + drivers/gpu/drm/amd/display/dc/inc/core_types.h | 3 - + 9 files changed, 353 insertions(+), 300 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 faca60a..4b817bf 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -4548,77 +4548,6 @@ void dm_restore_drm_connector_state(struct drm_device *dev, struct drm_connector + dm_force_atomic_commit(&aconnector->base); + } + +-static uint32_t add_val_sets_plane( +- struct dc_validation_set *val_sets, +- uint32_t set_count, +- const struct dc_stream_state *stream, +- struct dc_plane_state *plane_state) +-{ +- uint32_t i = 0, j = 0; +- +- while (i < set_count) { +- if (val_sets[i].stream == stream) { +- while (val_sets[i].plane_states[j]) +- j++; +- break; +- } +- ++i; +- } +- +- val_sets[i].plane_states[j] = plane_state; +- val_sets[i].plane_count++; +- +- return val_sets[i].plane_count; +-} +- +-static uint32_t update_in_val_sets_stream( +- struct dc_validation_set *val_sets, +- uint32_t set_count, +- struct dc_stream_state *old_stream, +- struct dc_stream_state *new_stream, +- struct drm_crtc *crtc) +-{ +- uint32_t i = 0; +- +- while (i < set_count) { +- if (val_sets[i].stream == old_stream) +- break; +- ++i; +- } +- +- val_sets[i].stream = new_stream; +- +- if (i == set_count) +- /* nothing found. add new one to the end */ +- return set_count + 1; +- +- return set_count; +-} +- +-static uint32_t remove_from_val_sets( +- struct dc_validation_set *val_sets, +- uint32_t set_count, +- const struct dc_stream_state *stream) +-{ +- int i; +- +- for (i = 0; i < set_count; i++) +- if (val_sets[i].stream == stream) +- break; +- +- if (i == set_count) { +- /* nothing found */ +- return set_count; +- } +- +- set_count--; +- +- for (; i < set_count; i++) +- val_sets[i] = val_sets[i + 1]; +- +- return set_count; +-} +- + /*` + * Grabs all modesetting locks to serialize against any blocking commits, + * Waits for completion of all non blocking commits. +@@ -4682,10 +4611,9 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, + struct dc *dc = adev->dm.dc; + struct drm_connector *connector; + struct drm_connector_state *conn_state; +- 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); ++ bool pflip_needed = !state->allow_modeset; + + /* + * This bool will be set for true for any modeset/reset +@@ -4700,16 +4628,44 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, + return ret; + } + +- /* copy existing configuration */ +- set_count = 0; +- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ /* Remove exiting planes if they are disabled or their CRTC is updated */ ++ for_each_crtc_in_state(state, crtc, crtc_state, i) { ++ new_acrtc_state = to_dm_crtc_state(crtc_state); + +- old_acrtc_state = to_dm_crtc_state(crtc->state); ++ if (pflip_needed) ++ continue; + +- if (old_acrtc_state->stream) { +- dc_stream_retain(old_acrtc_state->stream); +- set[set_count].stream = old_acrtc_state->stream; +- ++set_count; ++ for_each_plane_in_state(state, plane, plane_state, j) { ++ struct drm_crtc *plane_crtc = plane_state->crtc; ++ struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); ++ ++ if (plane->type == DRM_PLANE_TYPE_CURSOR) ++ continue; ++ ++ if (crtc != plane_crtc || !dm_plane_state->dc_state) ++ continue; ++ ++ WARN_ON(!new_acrtc_state->stream); ++ ++ if (drm_atomic_plane_disabling(plane->state, plane_state) || ++ drm_atomic_crtc_needs_modeset(crtc_state)) { ++ if (!dc_remove_plane_from_context( ++ dc, ++ new_acrtc_state->stream, ++ dm_plane_state->dc_state, ++ dm_state->context)) { ++ ++ ret = EINVAL; ++ goto fail; ++ } ++ ++ } ++ ++ dc_plane_state_release(dm_plane_state->dc_state); ++ dm_plane_state->dc_state = NULL; ++ ++ DRM_DEBUG_KMS("Disabling DRM plane: %d on DRM crtc %d\n", ++ plane->base.id, crtc->base.id); + } + } + +@@ -4753,11 +4709,6 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, + goto fail; + } + +- set_count = remove_from_val_sets( +- set, +- set_count, +- new_acrtc_state->stream); +- + dc_stream_release(new_acrtc_state->stream); + new_acrtc_state->stream = NULL; + +@@ -4816,13 +4767,6 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, + + new_acrtc_state->stream = new_stream; + +- set_count = update_in_val_sets_stream( +- set, +- set_count, +- old_acrtc_state->stream, +- new_acrtc_state->stream, +- crtc); +- + if (!dc_add_stream_to_ctx( + dc, + dm_state->context, +@@ -4879,32 +4823,32 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, + lock_and_validation_needed = true; + } + ++ /* Add new planes */ + for_each_crtc_in_state(state, crtc, crtc_state, i) { + new_acrtc_state = to_dm_crtc_state(crtc_state); + ++ if (pflip_needed) ++ continue; ++ + for_each_plane_in_state(state, plane, plane_state, j) { + struct drm_crtc *plane_crtc = plane_state->crtc; +- struct drm_framebuffer *fb = plane_state->fb; +- bool pflip_needed; + struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); + + /*TODO Implement atomic check for cursor plane */ + if (plane->type == DRM_PLANE_TYPE_CURSOR) + continue; + +- if (!fb || !plane_crtc || crtc != plane_crtc || !crtc_state->active) ++ if (crtc != plane_crtc) + continue; + +- WARN_ON(!new_acrtc_state->stream); +- +- pflip_needed = !state->allow_modeset; +- if (!pflip_needed) { ++ if (!drm_atomic_plane_disabling(plane->state, plane_state)) { + struct dc_plane_state *dc_plane_state; + ++ WARN_ON(!new_acrtc_state->stream); ++ + dc_plane_state = dc_create_plane_state(dc); + +- if (dm_plane_state->dc_state) +- dc_plane_state_release(dm_plane_state->dc_state); ++ WARN_ON(dm_plane_state->dc_state); + + dm_plane_state->dc_state = dc_plane_state; + +@@ -4917,10 +4861,17 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, + if (ret) + goto fail; + +- add_val_sets_plane(set, +- set_count, +- new_acrtc_state->stream, +- dc_plane_state); ++ ++ if (!dc_add_plane_to_context( ++ dc, ++ new_acrtc_state->stream, ++ dc_plane_state, ++ dm_state->context)) { ++ ++ ret = EINVAL; ++ goto fail; ++ } ++ + + lock_and_validation_needed = true; + } +@@ -4948,7 +4899,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, + if (ret) + goto fail; + +- if (!dc_validate_global_state(dc, set, set_count, dm_state->context)) { ++ if (!dc_validate_global_state(dc, 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 c6fdf62..e5bafe2 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1298,10 +1298,16 @@ void dc_update_planes_and_stream(struct dc *dc, + dc_resource_validate_ctx_copy_construct( + core_dc->current_context, context); + ++ /*remove old surfaces from context */ ++ if (!dc_rem_all_planes_for_stream(dc, stream, context)) { ++ ++ BREAK_TO_DEBUGGER(); ++ goto fail; ++ } ++ + /* add surface to context */ +- if (!resource_attach_surfaces_to_context( +- new_planes, surface_count, stream, +- context, core_dc->res_pool)) { ++ if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) { ++ + BREAK_TO_DEBUGGER(); + goto fail; + } +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 9415629..d21e8d3 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +@@ -946,6 +946,26 @@ struct pipe_ctx *resource_get_head_pipe_for_stream( + return NULL; + } + ++static struct pipe_ctx *resource_get_tail_pipe_for_stream( ++ struct resource_context *res_ctx, ++ struct dc_stream_state *stream) ++{ ++ struct pipe_ctx *head_pipe, *tail_pipe; ++ head_pipe = resource_get_head_pipe_for_stream(res_ctx, stream); ++ ++ if (!head_pipe) ++ return NULL; ++ ++ tail_pipe = head_pipe->bottom_pipe; ++ ++ while (tail_pipe) { ++ head_pipe = tail_pipe; ++ tail_pipe = tail_pipe->bottom_pipe; ++ } ++ ++ return head_pipe; ++} ++ + /* + * A free_pipe for a stream is defined here as a pipe + * that has no surface attached yet +@@ -990,22 +1010,6 @@ static struct pipe_ctx *acquire_free_pipe_for_stream( + + } + +-static void release_free_pipes_for_stream( +- struct resource_context *res_ctx, +- struct dc_stream_state *stream) +-{ +- int i; +- +- for (i = MAX_PIPES - 1; i >= 0; i--) { +- /* never release the topmost pipe*/ +- if (res_ctx->pipe_ctx[i].stream == stream && +- res_ctx->pipe_ctx[i].top_pipe && +- !res_ctx->pipe_ctx[i].plane_state) { +- memset(&res_ctx->pipe_ctx[i], 0, sizeof(struct pipe_ctx)); +- } +- } +-} +- + #if defined(CONFIG_DRM_AMD_DC_DCN1_0) + static int acquire_first_split_pipe( + struct resource_context *res_ctx, +@@ -1040,96 +1044,235 @@ static int acquire_first_split_pipe( + } + #endif + +-bool resource_attach_surfaces_to_context( +- struct dc_plane_state * const *plane_states, +- int surface_count, ++bool dc_add_plane_to_context( ++ const struct dc *dc, + struct dc_stream_state *stream, +- struct validate_context *context, +- const struct resource_pool *pool) ++ struct dc_plane_state *plane_state, ++ struct validate_context *context) + { + int i; +- struct pipe_ctx *tail_pipe; ++ struct resource_pool *pool = dc->res_pool; ++ struct pipe_ctx *head_pipe, *tail_pipe, *free_pipe; + struct dc_stream_status *stream_status = NULL; + ++ for (i = 0; i < context->stream_count; i++) ++ if (context->streams[i] == stream) { ++ stream_status = &context->stream_status[i]; ++ break; ++ } ++ if (stream_status == NULL) { ++ dm_error("Existing stream not found; failed to attach surface!\n"); ++ return false; ++ } ++ ++ ++ if (stream_status->plane_count == MAX_SURFACE_NUM) { ++ dm_error("Surface: can not attach plane_state %p! Maximum is: %d\n", ++ plane_state, MAX_SURFACE_NUM); ++ return false; ++ } ++ ++ head_pipe = resource_get_head_pipe_for_stream(&context->res_ctx, stream); ++ ++ if (!head_pipe) { ++ dm_error("Head pipe not found for stream_state %p !\n", stream); ++ return false; ++ } ++ ++ /* retain new surfaces */ ++ dc_plane_state_retain(plane_state); ++ ++ free_pipe = acquire_free_pipe_for_stream(context, pool, stream); + +- if (surface_count > MAX_SURFACE_NUM) { +- dm_error("Surface: can not attach %d surfaces! Maximum is: %d\n", +- surface_count, MAX_SURFACE_NUM); ++#if defined(CONFIG_DRM_AMD_DC_DCN1_0) ++ if (!free_pipe) { ++ int pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream); ++ if (pipe_idx >= 0) ++ free_pipe = &context->res_ctx.pipe_ctx[pipe_idx]; ++ } ++#endif ++ if (!free_pipe) { ++ stream_status->plane_states[i] = NULL; + return false; + } + ++ free_pipe->plane_state = plane_state; ++ ++ if (head_pipe != free_pipe) { ++ ++ tail_pipe = resource_get_tail_pipe_for_stream(&context->res_ctx, stream); ++ ASSERT(tail_pipe); ++ ++ free_pipe->stream_res.tg = tail_pipe->stream_res.tg; ++ free_pipe->stream_res.opp = tail_pipe->stream_res.opp; ++ free_pipe->stream_res.stream_enc = tail_pipe->stream_res.stream_enc; ++ free_pipe->stream_res.audio = tail_pipe->stream_res.audio; ++ free_pipe->clock_source = tail_pipe->clock_source; ++ free_pipe->top_pipe = tail_pipe; ++ tail_pipe->bottom_pipe = free_pipe; ++ } ++ ++ /* assign new surfaces*/ ++ stream_status->plane_states[stream_status->plane_count] = plane_state; ++ ++ stream_status->plane_count++; ++ ++ return true; ++} ++ ++bool dc_remove_plane_from_context( ++ const struct dc *dc, ++ struct dc_stream_state *stream, ++ struct dc_plane_state *plane_state, ++ struct validate_context *context) ++{ ++ int i; ++ struct dc_stream_status *stream_status = NULL; ++ struct resource_pool *pool = dc->res_pool; ++ + for (i = 0; i < context->stream_count; i++) + if (context->streams[i] == stream) { + stream_status = &context->stream_status[i]; + break; + } ++ + if (stream_status == NULL) { +- dm_error("Existing stream not found; failed to attach surfaces\n"); ++ dm_error("Existing stream not found; failed to remove plane.\n"); + return false; + } + +- /* retain new surfaces */ +- for (i = 0; i < surface_count; i++) +- dc_plane_state_retain(plane_states[i]); +- +- /* detach surfaces from pipes */ +- for (i = 0; i < pool->pipe_count; i++) +- if (context->res_ctx.pipe_ctx[i].stream == stream) { +- context->res_ctx.pipe_ctx[i].plane_state = NULL; +- context->res_ctx.pipe_ctx[i].bottom_pipe = NULL; +- } ++ /* release pipe for plane*/ ++ for (i = pool->pipe_count - 1; i >= 0; i--) { ++ struct pipe_ctx *pipe_ctx; + +- /* release existing surfaces*/ +- for (i = 0; i < stream_status->plane_count; i++) +- dc_plane_state_release(stream_status->plane_states[i]); ++ if (context->res_ctx.pipe_ctx[i].plane_state == plane_state) { ++ pipe_ctx = &context->res_ctx.pipe_ctx[i]; + +- for (i = surface_count; i < stream_status->plane_count; i++) +- stream_status->plane_states[i] = NULL; ++ if (pipe_ctx->top_pipe) ++ pipe_ctx->top_pipe->bottom_pipe = pipe_ctx->bottom_pipe; + +- tail_pipe = NULL; +- for (i = 0; i < surface_count; i++) { +- struct dc_plane_state *plane_state = plane_states[i]; +- struct pipe_ctx *free_pipe = acquire_free_pipe_for_stream( +- context, pool, stream); ++ /* Second condition is to avoid setting NULL to top pipe ++ * of tail pipe making it look like head pipe in subsequent ++ * deletes ++ */ ++ if (pipe_ctx->bottom_pipe && pipe_ctx->top_pipe) ++ pipe_ctx->bottom_pipe->top_pipe = pipe_ctx->top_pipe; + +-#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +- if (!free_pipe) { +- int pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream); +- if (pipe_idx >= 0) +- free_pipe = &context->res_ctx.pipe_ctx[pipe_idx]; +- } +-#endif +- if (!free_pipe) { +- stream_status->plane_states[i] = NULL; +- return false; ++ /* ++ * For head pipe detach surfaces from pipe for tail ++ * pipe just zero it out ++ */ ++ if (!pipe_ctx->top_pipe) { ++ pipe_ctx->plane_state = NULL; ++ pipe_ctx->bottom_pipe = NULL; ++ } else { ++ memset(pipe_ctx, 0, sizeof(*pipe_ctx)); ++ } + } ++ } ++ + +- free_pipe->plane_state = plane_state; ++ for (i = 0; i < stream_status->plane_count; i++) { ++ if (stream_status->plane_states[i] == plane_state) { + +- if (tail_pipe) { +- free_pipe->stream_res.tg = tail_pipe->stream_res.tg; +- free_pipe->stream_res.opp = tail_pipe->stream_res.opp; +- free_pipe->stream_res.stream_enc = tail_pipe->stream_res.stream_enc; +- free_pipe->stream_res.audio = tail_pipe->stream_res.audio; +- free_pipe->clock_source = tail_pipe->clock_source; +- free_pipe->top_pipe = tail_pipe; +- tail_pipe->bottom_pipe = free_pipe; ++ dc_plane_state_release(stream_status->plane_states[i]); ++ break; + } ++ } + +- tail_pipe = free_pipe; ++ if (i == stream_status->plane_count) { ++ dm_error("Existing plane_state not found; failed to detach it!\n"); ++ return false; + } + +- release_free_pipes_for_stream(&context->res_ctx, stream); ++ stream_status->plane_count--; + +- /* assign new surfaces*/ +- for (i = 0; i < surface_count; i++) +- stream_status->plane_states[i] = plane_states[i]; ++ /* Trim back arrays */ ++ for (i = 0; i < stream_status->plane_count; i++) ++ stream_status->plane_states[i] = stream_status->plane_states[i + 1]; ++ ++ stream_status->plane_states[stream_status->plane_count] = NULL; ++ ++ return true; ++} ++ ++bool dc_rem_all_planes_for_stream( ++ const struct dc *dc, ++ struct dc_stream_state *stream, ++ struct validate_context *context) ++{ ++ int i, old_plane_count; ++ struct dc_stream_status *stream_status = NULL; ++ struct dc_plane_state *del_planes[MAX_SURFACE_NUM] = { 0 }; ++ ++ for (i = 0; i < context->stream_count; i++) ++ if (context->streams[i] == stream) { ++ stream_status = &context->stream_status[i]; ++ break; ++ } ++ ++ if (stream_status == NULL) { ++ dm_error("Existing stream %p not found!\n", stream); ++ return false; ++ } ++ ++ old_plane_count = stream_status->plane_count; + +- stream_status->plane_count = surface_count; ++ for (i = 0; i < old_plane_count; i++) ++ del_planes[i] = stream_status->plane_states[i]; ++ ++ for (i = 0; i < old_plane_count; i++) ++ if (!dc_remove_plane_from_context(dc, stream, del_planes[i], context)) ++ return false; + + return true; + } + ++static bool add_all_planes_for_stream( ++ const struct dc *dc, ++ struct dc_stream_state *stream, ++ const struct dc_validation_set set[], ++ int set_count, ++ struct validate_context *context) ++{ ++ int i, j; ++ ++ for (i = 0; i < set_count; i++) ++ if (set[i].stream == stream) ++ break; ++ ++ if (i == set_count) { ++ dm_error("Stream %p not found in set!\n", stream); ++ return false; ++ } ++ ++ for (j = 0; j < set[i].plane_count; j++) ++ if (!dc_add_plane_to_context(dc, stream, set[i].plane_states[j], context)) ++ return false; ++ ++ return true; ++} ++ ++bool dc_add_all_planes_for_stream( ++ const struct dc *dc, ++ struct dc_stream_state *stream, ++ struct dc_plane_state * const *plane_states, ++ int plane_count, ++ struct validate_context *context) ++{ ++ struct dc_validation_set set; ++ int i; ++ ++ set.stream = stream; ++ set.plane_count = plane_count; ++ ++ for (i = 0; i < plane_count; i++) ++ set.plane_states[i] = plane_states[i]; ++ ++ return add_all_planes_for_stream(dc, stream, &set, 1, context); ++} ++ ++ + + static bool is_timing_changed(struct dc_stream_state *cur_stream, + struct dc_stream_state *new_stream) +@@ -1178,41 +1321,6 @@ bool dc_is_stream_unchanged( + return true; + } + +-bool resource_validate_attach_surfaces( +- const struct dc_validation_set set[], +- int set_count, +- const struct validate_context *old_context, +- struct validate_context *context, +- const struct resource_pool *pool) +-{ +- int i, j; +- +- for (i = 0; i < set_count; i++) { +- for (j = 0; old_context && j < old_context->stream_count; j++) +- if (dc_is_stream_unchanged( +- old_context->streams[j], +- context->streams[i])) { +- if (!resource_attach_surfaces_to_context( +- old_context->stream_status[j].plane_states, +- old_context->stream_status[j].plane_count, +- context->streams[i], +- context, pool)) +- return false; +- context->stream_status[i] = old_context->stream_status[j]; +- } +- if (set[i].plane_count != 0) +- if (!resource_attach_surfaces_to_context( +- set[i].plane_states, +- set[i].plane_count, +- context->streams[i], +- context, pool)) +- return false; +- +- } +- +- return true; +-} +- + /* Maximum TMDS single link pixel clock 165MHz */ + #define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000 + #define TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST 297000 +@@ -1392,23 +1500,22 @@ bool dc_remove_stream_from_ctx( + struct validate_context *new_ctx, + struct dc_stream_state *stream) + { +- int i, j; ++ int i; + 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) */ ++ /* Release primary pipe */ + for (i = 0; i < MAX_PIPES; i++) { +- if (new_ctx->res_ctx.pipe_ctx[i].stream == stream) { ++ if (new_ctx->res_ctx.pipe_ctx[i].stream == stream && ++ !new_ctx->res_ctx.pipe_ctx[i].top_pipe) { + del_pipe = &new_ctx->res_ctx.pipe_ctx[i]; + +- if (del_pipe->stream_res.stream_enc) +- update_stream_engine_usage( +- &new_ctx->res_ctx, ++ ASSERT(del_pipe->stream_res.stream_enc); ++ update_stream_engine_usage( ++ &new_ctx->res_ctx, + dc->res_pool, +- del_pipe->stream_res.stream_enc, +- false); ++ del_pipe->stream_res.stream_enc, ++ false); + + if (del_pipe->stream_res.audio) + update_audio_usage( +@@ -1418,6 +1525,8 @@ bool dc_remove_stream_from_ctx( + false); + + memset(del_pipe, 0, sizeof(*del_pipe)); ++ ++ break; + } + } + +@@ -1438,10 +1547,6 @@ bool dc_remove_stream_from_ctx( + 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]; +@@ -1636,18 +1741,14 @@ void dc_resource_validate_ctx_copy_construct_current( + + bool dc_validate_global_state( + struct dc *dc, +- const struct dc_validation_set set[], +- int set_count, + struct validate_context *new_ctx) + { + 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; + + if (dc->res_pool->funcs->validate_global && +- dc->res_pool->funcs->validate_global(dc, set, set_count, +- old_context, new_ctx) != DC_OK) ++ dc->res_pool->funcs->validate_global( ++ dc, new_ctx) != DC_OK) + return false; + + /* TODO without this SWDEV-114774 brakes */ +@@ -1687,15 +1788,6 @@ bool dc_validate_global_state( + } + } + +- /*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) +diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h +index 69bd67b..d01d54e 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc.h ++++ b/drivers/gpu/drm/amd/display/dc/dc.h +@@ -635,15 +635,40 @@ 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( ++bool dc_add_stream_to_ctx( + struct dc *dc, ++ struct validate_context *new_ctx, ++ struct dc_stream_state *stream); ++ ++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); ++ ++bool dc_add_plane_to_context( ++ const struct dc *dc, ++ struct dc_stream_state *stream, ++ struct dc_plane_state *plane_state, ++ struct validate_context *context); ++ ++bool dc_remove_plane_from_context( ++ const struct dc *dc, ++ struct dc_stream_state *stream, ++ struct dc_plane_state *plane_state, ++ struct validate_context *context); ++ ++bool dc_rem_all_planes_for_stream( ++ const struct dc *dc, ++ struct dc_stream_state *stream, ++ struct validate_context *context); ++ ++bool dc_add_all_planes_for_stream( ++ const struct dc *dc, ++ struct dc_stream_state *stream, ++ struct dc_plane_state * const *plane_states, ++ int plane_count, ++ struct validate_context *context); + + /* + * Structure to store surface/stream associations for validation +@@ -660,8 +685,6 @@ bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state); + + bool dc_validate_global_state( + struct dc *dc, +- const struct dc_validation_set set[], +- int set_count, + struct validate_context *new_ctx); + + /* +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 c9dad4e..c991610 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +@@ -684,19 +684,18 @@ bool dce100_validate_bandwidth( + } + + static bool dce100_validate_surface_sets( +- const struct dc_validation_set set[], +- int set_count) ++ struct validate_context *context) + { + int i; + +- for (i = 0; i < set_count; i++) { +- if (set[i].plane_count == 0) ++ for (i = 0; i < context->stream_count; i++) { ++ if (context->stream_status[i].plane_count == 0) + continue; + +- if (set[i].plane_count > 1) ++ if (context->stream_status[i].plane_count > 1) + return false; + +- if (set[i].plane_states[0]->format ++ if (context->stream_status[i].plane_states[0]->format + >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) + return false; + } +@@ -706,12 +705,9 @@ static bool dce100_validate_surface_sets( + + enum dc_status dce100_validate_global( + struct dc *dc, +- const struct dc_validation_set set[], +- int set_count, +- struct validate_context *old_context, + struct validate_context *context) + { +- if (!dce100_validate_surface_sets(set, set_count)) ++ if (!dce100_validate_surface_sets(context)) + return DC_FAIL_SURFACE_VALIDATE; + + return DC_OK; +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 d682180..18c67f8 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +@@ -880,31 +880,30 @@ static bool dce110_validate_bandwidth( + } + + static bool dce110_validate_surface_sets( +- const struct dc_validation_set set[], +- int set_count) ++ struct validate_context *context) + { + int i; + +- for (i = 0; i < set_count; i++) { +- if (set[i].plane_count == 0) ++ for (i = 0; i < context->stream_count; i++) { ++ if (context->stream_status[i].plane_count == 0) + continue; + +- if (set[i].plane_count > 2) ++ if (context->stream_status[i].plane_count > 2) + return false; + +- if (set[i].plane_states[0]->format ++ if (context->stream_status[i].plane_states[0]->format + >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) + return false; + +- if (set[i].plane_count == 2) { +- if (set[i].plane_states[1]->format ++ if (context->stream_status[i].plane_count == 2) { ++ if (context->stream_status[i].plane_states[1]->format + < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) + return false; +- if (set[i].plane_states[1]->src_rect.width > 1920 +- || set[i].plane_states[1]->src_rect.height > 1080) ++ if (context->stream_status[i].plane_states[1]->src_rect.width > 1920 ++ || context->stream_status[i].plane_states[1]->src_rect.height > 1080) + return false; + +- if (set[i].stream->timing.pixel_encoding != PIXEL_ENCODING_RGB) ++ if (context->streams[i]->timing.pixel_encoding != PIXEL_ENCODING_RGB) + return false; + } + } +@@ -914,12 +913,9 @@ static bool dce110_validate_surface_sets( + + enum dc_status dce110_validate_global( + struct dc *dc, +- const struct dc_validation_set set[], +- int set_count, +- struct validate_context *old_context, + struct validate_context *context) + { +- if (!dce110_validate_surface_sets(set, set_count)) ++ if (!dce110_validate_surface_sets(context)) + return DC_FAIL_SURFACE_VALIDATE; + + return DC_OK; +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 85a396e..d5a8ee6 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +@@ -855,19 +855,18 @@ enum dc_status resource_map_phy_clock_resources( + } + + static bool dce112_validate_surface_sets( +- const struct dc_validation_set set[], +- int set_count) ++ struct validate_context *context) + { + int i; + +- for (i = 0; i < set_count; i++) { +- if (set[i].plane_count == 0) ++ for (i = 0; i < context->stream_count; i++) { ++ if (context->stream_status[i].plane_count == 0) + continue; + +- if (set[i].plane_count > 1) ++ if (context->stream_status[i].plane_count > 1) + return false; + +- if (set[i].plane_states[0]->format ++ if (context->stream_status[i].plane_states[0]->format + >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) + return false; + } +@@ -928,12 +927,9 @@ enum dc_status dce112_validate_guaranteed( + + 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)) ++ if (!dce112_validate_surface_sets(context)) + return DC_FAIL_SURFACE_VALIDATE; + + return DC_OK; +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 ac3f42a..945ff7e 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +@@ -716,19 +716,18 @@ bool dce80_validate_bandwidth( + } + + static bool dce80_validate_surface_sets( +- const struct dc_validation_set set[], +- int set_count) ++ struct validate_context *context) + { + int i; + +- for (i = 0; i < set_count; i++) { +- if (set[i].plane_count == 0) ++ for (i = 0; i < context->stream_count; i++) { ++ if (context->stream_status[i].plane_count == 0) + continue; + +- if (set[i].plane_count > 1) ++ if (context->stream_status[i].plane_count > 1) + return false; + +- if (set[i].plane_states[0]->format ++ if (context->stream_status[i].plane_states[0]->format + >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) + return false; + } +@@ -738,12 +737,9 @@ static bool dce80_validate_surface_sets( + + enum dc_status dce80_validate_global( + struct dc *dc, +- const struct dc_validation_set set[], +- int set_count, +- struct validate_context *old_context, + struct validate_context *context) + { +- if (!dce80_validate_surface_sets(set, set_count)) ++ if (!dce80_validate_surface_sets(context)) + return DC_FAIL_SURFACE_VALIDATE; + + return DC_OK; +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 62bd11d..bd1a636 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h +@@ -99,9 +99,6 @@ struct resource_funcs { + + 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)( +-- +2.7.4 + |