Commit 19f89e23 authored by Andrey Grodzovsky's avatar Andrey Grodzovsky Committed by Alex Deucher
Browse files

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: default avatarAndrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <Harry.Wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 577b5c2b
Loading
Loading
Loading
Loading
+58 −107
Original line number Diff line number Diff line
@@ -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;

		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 (old_acrtc_state->stream) {
			dc_stream_retain(old_acrtc_state->stream);
			set[set_count].stream = old_acrtc_state->stream;
			++set_count;
			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,

				if (!dc_add_plane_to_context(
						dc,
						new_acrtc_state->stream,
						     dc_plane_state);
						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;
		}
+9 −3
Original line number Diff line number Diff line
@@ -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;
		}
+227 −135
Original line number Diff line number Diff line
@@ -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,57 +1044,45 @@ 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;


	if (surface_count > MAX_SURFACE_NUM) {
		dm_error("Surface: can not attach %d surfaces! Maximum is: %d\n",
			surface_count, MAX_SURFACE_NUM);
		return false;
	}

	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 attach surface!\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;
	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;
	}

	/* release existing surfaces*/
	for (i = 0; i < stream_status->plane_count; i++)
		dc_plane_state_release(stream_status->plane_states[i]);
	head_pipe = resource_get_head_pipe_for_stream(&context->res_ctx, stream);

	for (i = surface_count; i < stream_status->plane_count; i++)
		stream_status->plane_states[i] = NULL;
	if (!head_pipe) {
		dm_error("Head pipe not found for stream_state %p !\n", stream);
		return false;
	}

	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);
	/* retain new surfaces */
	dc_plane_state_retain(plane_state);

	free_pipe = acquire_free_pipe_for_stream(context, pool, stream);

#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
	if (!free_pipe) {
@@ -1106,7 +1098,11 @@ bool resource_attach_surfaces_to_context(

	free_pipe->plane_state = plane_state;

		if (tail_pipe) {
	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;
@@ -1116,20 +1112,167 @@ bool resource_attach_surfaces_to_context(
		tail_pipe->bottom_pipe = free_pipe;
	}

		tail_pipe = free_pipe;
	/* assign new surfaces*/
	stream_status->plane_states[stream_status->plane_count] = plane_state;

	stream_status->plane_count++;

	return true;
}

	release_free_pipes_for_stream(&context->res_ctx, stream);
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;
		}

	/* assign new surfaces*/
	for (i = 0; i < surface_count; i++)
		stream_status->plane_states[i] = plane_states[i];
	if (stream_status == NULL) {
		dm_error("Existing stream not found; failed to remove plane.\n");
		return false;
	}

	/* release pipe for plane*/
	for (i = pool->pipe_count - 1; i >= 0; i--) {
		struct pipe_ctx *pipe_ctx;

		if (context->res_ctx.pipe_ctx[i].plane_state == plane_state) {
			pipe_ctx = &context->res_ctx.pipe_ctx[i];

			if (pipe_ctx->top_pipe)
				pipe_ctx->top_pipe->bottom_pipe = pipe_ctx->bottom_pipe;

			/* 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;

			/*
			 * 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));
			}
		}
	}


	for (i = 0; i < stream_status->plane_count; i++) {
		if (stream_status->plane_states[i] == plane_state) {

			dc_plane_state_release(stream_status->plane_states[i]);
			break;
		}
	}

	if (i == stream_status->plane_count) {
		dm_error("Existing plane_state not found; failed to detach it!\n");
		return false;
	}

	stream_status->plane_count--;

	stream_status->plane_count = surface_count;
	/* 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;

	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,18 +1500,17 @@ 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)
			ASSERT(del_pipe->stream_res.stream_enc);
			update_stream_engine_usage(
					&new_ctx->res_ctx,
						dc->res_pool,
@@ -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)
+30 −7
Original line number Diff line number Diff line
@@ -619,16 +619,41 @@ 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_add_stream_to_ctx(
bool dc_remove_stream_from_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);

/*
+6 −10
Original line number Diff line number Diff line
@@ -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;
Loading