drm/amd/display: Per plane validation context build.
authorAndrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Fri, 11 Aug 2017 14:43:45 +0000 (10:43 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 Sep 2017 22:17:06 +0000 (18:17 -0400)
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.

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>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
drivers/gpu/drm/amd/display/dc/inc/core_types.h

index e037ed8..e8835e7 100644 (file)
@@ -4304,77 +4304,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.
@@ -4438,10 +4367,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
@@ -4460,16 +4388,44 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
        ASSERT(dm_state->context);
        dc_resource_validate_ctx_copy_construct_current(dc, dm_state->context);
 
-       /* 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);
                }
        }
 
@@ -4513,11 +4469,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;
 
@@ -4576,13 +4527,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,
@@ -4639,32 +4583,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;
 
@@ -4677,10 +4621,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;
                        }
@@ -4708,7 +4659,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;
                }
index ab2b8f2..79980cb 100644 (file)
@@ -1305,10 +1305,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;
                }
index fbfe15f..6eee1b1 100644 (file)
@@ -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)
index 9cc1c28..55fc581 100644 (file)
@@ -619,15 +619,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
@@ -644,8 +669,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);
 
 /*
index c9dad4e..c991610 100644 (file)
@@ -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;
index d682180..18c67f8 100644 (file)
@@ -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;
index 85a396e..d5a8ee6 100644 (file)
@@ -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;
index ac3f42a..945ff7e 100644 (file)
@@ -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;
index 62bd11d..bd1a636 100644 (file)
@@ -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)(