summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Grodzovsky <Andrey.Grodzovsky@amd.com>2017-08-11 10:43:45 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-09-26 18:17:06 -0400
commit19f89e2392e692208a0a00465d30b2b2bf43e9a9 (patch)
tree7be949e250c2b3c554e84c14419a201db7594b03
parent577b5c2b51014b3c276ab1d456aaad965dbb4930 (diff)
downloadlinux-stable-19f89e2392e692208a0a00465d30b2b2bf43e9a9.tar.gz
linux-stable-19f89e2392e692208a0a00465d30b2b2bf43e9a9.tar.bz2
linux-stable-19f89e2392e692208a0a00465d30b2b2bf43e9a9.zip
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. 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>
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c165
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c12
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c362
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h37
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c16
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c26
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c16
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c16
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/core_types.h3
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 e037ed85a5cc..e8835e751702 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -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;
}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index ab2b8f23b20a..79980cb0900c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -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;
}
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 fbfe15f783c0..6eee1b1a563e 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 9cc1c28caa4e..55fc58102515 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -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);
/*
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 c9dad4e2a7c8..c991610315b2 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 d682180f2eaf..18c67f89e9b5 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 85a396ef5aa5..d5a8ee69171d 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 ac3f42a44030..945ff7ee6cd9 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 62bd11d250c5..bd1a6367872f 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)(