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

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
...@@ -1646,46 +1646,6 @@ static int acquire_first_free_pipe( ...@@ -1646,46 +1646,6 @@ static int acquire_first_free_pipe(
return -1; 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( static struct audio *find_first_free_audio(
struct resource_context *res_ctx, struct resource_context *res_ctx,
const struct resource_pool *pool, const struct resource_pool *pool,
...@@ -1997,7 +1957,7 @@ enum dc_status resource_map_pool_resources( ...@@ -1997,7 +1957,7 @@ enum dc_status resource_map_pool_resources(
pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
pipe_ctx->stream_res.stream_enc = 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); &context->res_ctx, pool, stream);
if (!pipe_ctx->stream_res.stream_enc) if (!pipe_ctx->stream_res.stream_enc)
......
...@@ -867,13 +867,55 @@ enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, s ...@@ -867,13 +867,55 @@ enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, s
return DC_FAIL_SURFACE_VALIDATE; 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 = { static const struct resource_funcs dce100_res_pool_funcs = {
.destroy = dce100_destroy_resource_pool, .destroy = dce100_destroy_resource_pool,
.link_enc_create = dce100_link_encoder_create, .link_enc_create = dce100_link_encoder_create,
.validate_bandwidth = dce100_validate_bandwidth, .validate_bandwidth = dce100_validate_bandwidth,
.validate_plane = dce100_validate_plane, .validate_plane = dce100_validate_plane,
.add_stream_to_ctx = dce100_add_stream_to_ctx, .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( static bool construct(
......
...@@ -46,4 +46,9 @@ enum dc_status dce100_add_stream_to_ctx( ...@@ -46,4 +46,9 @@ enum dc_status dce100_add_stream_to_ctx(
struct dc_state *new_ctx, struct dc_state *new_ctx,
struct dc_stream_state *dc_stream); 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_ */ #endif /* DCE100_RESOURCE_H_ */
...@@ -1134,6 +1134,38 @@ static void dce110_destroy_resource_pool(struct resource_pool **pool) ...@@ -1134,6 +1134,38 @@ static void dce110_destroy_resource_pool(struct resource_pool **pool)
*pool = NULL; *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 = { static const struct resource_funcs dce110_res_pool_funcs = {
.destroy = dce110_destroy_resource_pool, .destroy = dce110_destroy_resource_pool,
...@@ -1142,7 +1174,8 @@ static const struct resource_funcs dce110_res_pool_funcs = { ...@@ -1142,7 +1174,8 @@ static const struct resource_funcs dce110_res_pool_funcs = {
.validate_plane = dce110_validate_plane, .validate_plane = dce110_validate_plane,
.acquire_idle_pipe_for_layer = dce110_acquire_underlay, .acquire_idle_pipe_for_layer = dce110_acquire_underlay,
.add_stream_to_ctx = dce110_add_stream_to_ctx, .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) static bool underlay_create(struct dc_context *ctx, struct resource_pool *pool)
......
...@@ -45,5 +45,10 @@ struct resource_pool *dce110_create_resource_pool( ...@@ -45,5 +45,10 @@ struct resource_pool *dce110_create_resource_pool(
struct dc *dc, struct dc *dc,
struct hw_asic_id asic_id); 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__ */ #endif /* __DC_RESOURCE_DCE110_H__ */
...@@ -993,7 +993,8 @@ static const struct resource_funcs dce112_res_pool_funcs = { ...@@ -993,7 +993,8 @@ static const struct resource_funcs dce112_res_pool_funcs = {
.validate_bandwidth = dce112_validate_bandwidth, .validate_bandwidth = dce112_validate_bandwidth,
.validate_plane = dce100_validate_plane, .validate_plane = dce100_validate_plane,
.add_stream_to_ctx = dce112_add_stream_to_ctx, .add_stream_to_ctx = dce112_add_stream_to_ctx,
.validate_global = dce112_validate_global .validate_global = dce112_validate_global,
.find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link
}; };
static void bw_calcs_data_update_from_pplib(struct dc *dc) static void bw_calcs_data_update_from_pplib(struct dc *dc)
......
...@@ -837,7 +837,8 @@ static const struct resource_funcs dce120_res_pool_funcs = { ...@@ -837,7 +837,8 @@ static const struct resource_funcs dce120_res_pool_funcs = {
.link_enc_create = dce120_link_encoder_create, .link_enc_create = dce120_link_encoder_create,
.validate_bandwidth = dce112_validate_bandwidth, .validate_bandwidth = dce112_validate_bandwidth,
.validate_plane = dce100_validate_plane, .validate_plane = dce100_validate_plane,
.add_stream_to_ctx = dce112_add_stream_to_ctx .add_stream_to_ctx = dce112_add_stream_to_ctx,
.find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link
}; };
static void bw_calcs_data_update_from_pplib(struct dc *dc) static void bw_calcs_data_update_from_pplib(struct dc *dc)
......
...@@ -880,7 +880,8 @@ static const struct resource_funcs dce80_res_pool_funcs = { ...@@ -880,7 +880,8 @@ static const struct resource_funcs dce80_res_pool_funcs = {
.validate_bandwidth = dce80_validate_bandwidth, .validate_bandwidth = dce80_validate_bandwidth,
.validate_plane = dce100_validate_plane, .validate_plane = dce100_validate_plane,
.add_stream_to_ctx = dce100_add_stream_to_ctx, .add_stream_to_ctx = dce100_add_stream_to_ctx,
.validate_global = dce80_validate_global .validate_global = dce80_validate_global,
.find_first_free_match_stream_enc_for_link = dce100_find_first_free_match_stream_enc_for_link
}; };
static bool dce80_construct( static bool dce80_construct(
......
...@@ -1243,7 +1243,8 @@ static const struct resource_funcs dcn10_res_pool_funcs = { ...@@ -1243,7 +1243,8 @@ static const struct resource_funcs dcn10_res_pool_funcs = {
.validate_plane = dcn10_validate_plane, .validate_plane = dcn10_validate_plane,
.validate_global = dcn10_validate_global, .validate_global = dcn10_validate_global,
.add_stream_to_ctx = dcn10_add_stream_to_ctx, .add_stream_to_ctx = dcn10_add_stream_to_ctx,
.get_default_swizzle_mode = dcn10_get_default_swizzle_mode .get_default_swizzle_mode = dcn10_get_default_swizzle_mode,
.find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link
}; };
static uint32_t read_pipe_fuses(struct dc_context *ctx) static uint32_t read_pipe_fuses(struct dc_context *ctx)
......
...@@ -123,6 +123,11 @@ struct resource_funcs { ...@@ -123,6 +123,11 @@ struct resource_funcs {
enum dc_status (*get_default_swizzle_mode)( enum dc_status (*get_default_swizzle_mode)(
struct dc_plane_state *plane_state); struct dc_plane_state *plane_state);
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);
}; };
struct audio_support{ struct audio_support{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment