Commit 78cc70b1 authored by Wesley Chalmers's avatar Wesley Chalmers Committed by Alex Deucher
Browse files

drm/amd/display: Engine-specific encoder allocation



[WHY]
From DCE110 onward, we have the ability to assign DIG BE and FE
separately for any display connector type; before, we could only do this
for DP.

Signed-off-by: default avatarWesley Chalmers <Wesley.Chalmers@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent eed928dc
Loading
Loading
Loading
Loading
+1 −41
Original line number Diff line number Diff line
@@ -1646,46 +1646,6 @@ static int acquire_first_free_pipe(
	return -1;
}

static struct stream_encoder *find_first_free_match_stream_enc_for_link(
		struct resource_context *res_ctx,
		const struct resource_pool *pool,
		struct dc_stream_state *stream)
{
	int i;
	int j = -1;
	struct dc_link *link = stream->link;

	for (i = 0; i < pool->stream_enc_count; i++) {
		if (!res_ctx->is_stream_enc_acquired[i] &&
				pool->stream_enc[i]) {
			/* Store first available for MST second display
			 * in daisy chain use case */
			j = i;
			if (pool->stream_enc[i]->id ==
					link->link_enc->preferred_engine)
				return pool->stream_enc[i];
		}
	}

	/*
	 * below can happen in cases when stream encoder is acquired:
	 * 1) for second MST display in chain, so preferred engine already
	 * acquired;
	 * 2) for another link, which preferred engine already acquired by any
	 * MST configuration.
	 *
	 * If signal is of DP type and preferred engine not found, return last available
	 *
	 * TODO - This is just a patch up and a generic solution is
	 * required for non DP connectors.
	 */

	if (j >= 0 && link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT)
		return pool->stream_enc[j];

	return NULL;
}

static struct audio *find_first_free_audio(
		struct resource_context *res_ctx,
		const struct resource_pool *pool,
@@ -1997,7 +1957,7 @@ enum dc_status resource_map_pool_resources(
	pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];

	pipe_ctx->stream_res.stream_enc =
		find_first_free_match_stream_enc_for_link(
		dc->res_pool->funcs->find_first_free_match_stream_enc_for_link(
			&context->res_ctx, pool, stream);

	if (!pipe_ctx->stream_res.stream_enc)
+43 −1
Original line number Diff line number Diff line
@@ -867,13 +867,55 @@ enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, s
	return DC_FAIL_SURFACE_VALIDATE;
}

struct stream_encoder *dce100_find_first_free_match_stream_enc_for_link(
		struct resource_context *res_ctx,
		const struct resource_pool *pool,
		struct dc_stream_state *stream)
{
	int i;
	int j = -1;
	struct dc_link *link = stream->link;

	for (i = 0; i < pool->stream_enc_count; i++) {
		if (!res_ctx->is_stream_enc_acquired[i] &&
				pool->stream_enc[i]) {
			/* Store first available for MST second display
			 * in daisy chain use case
			 */
			j = i;
			if (pool->stream_enc[i]->id ==
					link->link_enc->preferred_engine)
				return pool->stream_enc[i];
		}
	}

	/*
	 * below can happen in cases when stream encoder is acquired:
	 * 1) for second MST display in chain, so preferred engine already
	 * acquired;
	 * 2) for another link, which preferred engine already acquired by any
	 * MST configuration.
	 *
	 * If signal is of DP type and preferred engine not found, return last available
	 *
	 * TODO - This is just a patch up and a generic solution is
	 * required for non DP connectors.
	 */

	if (j >= 0 && link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT)
		return pool->stream_enc[j];

	return NULL;
}

static const struct resource_funcs dce100_res_pool_funcs = {
	.destroy = dce100_destroy_resource_pool,
	.link_enc_create = dce100_link_encoder_create,
	.validate_bandwidth = dce100_validate_bandwidth,
	.validate_plane = dce100_validate_plane,
	.add_stream_to_ctx = dce100_add_stream_to_ctx,
	.validate_global = dce100_validate_global
	.validate_global = dce100_validate_global,
	.find_first_free_match_stream_enc_for_link = dce100_find_first_free_match_stream_enc_for_link
};

static bool construct(
+5 −0
Original line number Diff line number Diff line
@@ -46,4 +46,9 @@ enum dc_status dce100_add_stream_to_ctx(
		struct dc_state *new_ctx,
		struct dc_stream_state *dc_stream);

struct stream_encoder *dce100_find_first_free_match_stream_enc_for_link(
		struct resource_context *res_ctx,
		const struct resource_pool *pool,
		struct dc_stream_state *stream);

#endif /* DCE100_RESOURCE_H_ */
+34 −1
Original line number Diff line number Diff line
@@ -1134,6 +1134,38 @@ static void dce110_destroy_resource_pool(struct resource_pool **pool)
	*pool = NULL;
}

struct stream_encoder *dce110_find_first_free_match_stream_enc_for_link(
		struct resource_context *res_ctx,
		const struct resource_pool *pool,
		struct dc_stream_state *stream)
{
	int i;
	int j = -1;
	struct dc_link *link = stream->link;

	for (i = 0; i < pool->stream_enc_count; i++) {
		if (!res_ctx->is_stream_enc_acquired[i] &&
				pool->stream_enc[i]) {
			/* Store first available for MST second display
			 * in daisy chain use case
			 */
			j = i;
			if (pool->stream_enc[i]->id ==
					link->link_enc->preferred_engine)
				return pool->stream_enc[i];
		}
	}

	/*
	 * For CZ and later, we can allow DIG FE and BE to differ for all display types
	 */

	if (j >= 0)
		return pool->stream_enc[j];

	return NULL;
}


static const struct resource_funcs dce110_res_pool_funcs = {
	.destroy = dce110_destroy_resource_pool,
@@ -1142,7 +1174,8 @@ static const struct resource_funcs dce110_res_pool_funcs = {
	.validate_plane = dce110_validate_plane,
	.acquire_idle_pipe_for_layer = dce110_acquire_underlay,
	.add_stream_to_ctx = dce110_add_stream_to_ctx,
	.validate_global = dce110_validate_global
	.validate_global = dce110_validate_global,
	.find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link
};

static bool underlay_create(struct dc_context *ctx, struct resource_pool *pool)
+5 −0
Original line number Diff line number Diff line
@@ -45,5 +45,10 @@ struct resource_pool *dce110_create_resource_pool(
	struct dc *dc,
	struct hw_asic_id asic_id);

struct stream_encoder *dce110_find_first_free_match_stream_enc_for_link(
		struct resource_context *res_ctx,
		const struct resource_pool *pool,
		struct dc_stream_state *stream);

#endif /* __DC_RESOURCE_DCE110_H__ */
Loading