Commit 0e8cf83a authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher

drm/amd/display: allow hpo and dio encoder switching during dp retrain test

[why]
During DP2.1 LL CTS if test equipment requests to change between
DP2.1 and DP1.4 link rates, we need to swap between HPO and DIO
encoders by remapping encoder resource.

[how]
Add a function dc resource to update encoder resources and toggle
dpms state for all enabled stream associated witht the link under test.
Acked-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a10a22b0
......@@ -4649,9 +4649,6 @@ void dc_link_set_preferred_training_settings(struct dc *dc,
if (link_setting != NULL) {
link->preferred_link_setting = *link_setting;
if (dp_get_link_encoding_format(link_setting) == DP_128b_132b_ENCODING)
/* TODO: add dc update for acquiring link res */
skip_immediate_retrain = true;
} else {
link->preferred_link_setting.lane_count = LANE_COUNT_UNKNOWN;
link->preferred_link_setting.link_rate = LINK_RATE_UNKNOWN;
......
......@@ -7276,51 +7276,35 @@ void dp_retrain_link_dp_test(struct dc_link *link,
struct dc_link_settings *link_setting,
bool skip_video_pattern)
{
struct pipe_ctx *pipes =
&link->dc->current_state->res_ctx.pipe_ctx[0];
struct pipe_ctx *pipe;
unsigned int i;
bool do_fallback = false;
udelay(100);
for (i = 0; i < MAX_PIPES; i++) {
if (pipes[i].stream != NULL &&
!pipes[i].top_pipe && !pipes[i].prev_odm_pipe &&
pipes[i].stream->link != NULL &&
pipes[i].stream_res.stream_enc != NULL &&
pipes[i].stream->link == link) {
udelay(100);
link->dc->hwss.blank_stream(&pipes[i]);
/* disable any test pattern that might be active */
dp_set_hw_test_pattern(link, &pipes[i].link_res,
DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
dp_receiver_power_ctrl(link, false);
link->dc->hwss.disable_stream(&pipes[i]);
if (pipes[i].stream_res.audio && !link->dc->debug.az_endpoint_mute_only)
pipes[i].stream_res.audio->funcs->az_disable(pipes[i].stream_res.audio);
link->dc->hwss.disable_link_output(link, &pipes[i].link_res, SIGNAL_TYPE_DISPLAY_PORT);
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
do_fallback = true;
perform_link_training_with_retries(
link_setting,
skip_video_pattern,
LINK_TRAINING_ATTEMPTS,
&pipes[i],
SIGNAL_TYPE_DISPLAY_PORT,
do_fallback);
link->dc->hwss.enable_stream(&pipes[i]);
link->dc->hwss.unblank_stream(&pipes[i],
link_setting);
pipe = &link->dc->current_state->res_ctx.pipe_ctx[i];
if (pipe->stream != NULL &&
pipe->stream->link == link &&
!pipe->stream->dpms_off &&
!pipe->top_pipe && !pipe->prev_odm_pipe) {
core_link_disable_stream(pipe);
pipe->link_config.dp_link_settings = *link_setting;
update_dp_encoder_resources_for_test_harness(
link->dc,
pipe->stream->ctx->dc->current_state,
pipe);
}
}
link->dc->hwss.enable_audio_stream(&pipes[i]);
for (i = 0; i < MAX_PIPES; i++) {
pipe = &link->dc->current_state->res_ctx.pipe_ctx[i];
if (pipe->stream != NULL &&
pipe->stream->link == link &&
!pipe->stream->dpms_off &&
!pipe->top_pipe && !pipe->prev_odm_pipe) {
core_link_enable_stream(
pipe->stream->ctx->dc->current_state,
pipe);
}
}
}
......
......@@ -3990,3 +3990,42 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm(
return true;
}
enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,
struct dc_state *context,
struct pipe_ctx *pipe_ctx)
{
if (dp_get_link_encoding_format(&pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) {
if (pipe_ctx->stream_res.hpo_dp_stream_enc == NULL) {
pipe_ctx->stream_res.hpo_dp_stream_enc =
find_first_free_match_hpo_dp_stream_enc_for_link(
&context->res_ctx, dc->res_pool, pipe_ctx->stream);
if (!pipe_ctx->stream_res.hpo_dp_stream_enc)
return DC_NO_STREAM_ENC_RESOURCE;
update_hpo_dp_stream_engine_usage(
&context->res_ctx, dc->res_pool,
pipe_ctx->stream_res.hpo_dp_stream_enc,
true);
}
if (pipe_ctx->link_res.hpo_dp_link_enc == NULL) {
if (!add_hpo_dp_link_enc_to_ctx(&context->res_ctx, dc->res_pool, pipe_ctx, pipe_ctx->stream))
return DC_NO_LINK_ENC_RESOURCE;
}
} else {
if (pipe_ctx->stream_res.hpo_dp_stream_enc) {
update_hpo_dp_stream_engine_usage(
&context->res_ctx, dc->res_pool,
pipe_ctx->stream_res.hpo_dp_stream_enc,
false);
pipe_ctx->stream_res.hpo_dp_stream_enc = NULL;
}
if (pipe_ctx->link_res.hpo_dp_link_enc)
remove_hpo_dp_link_enc_from_ctx(&context->res_ctx, pipe_ctx, pipe_ctx->stream);
}
return DC_OK;
}
......@@ -236,4 +236,13 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm(
struct pipe_ctx *pri_pipe,
struct pipe_ctx *sec_pipe,
bool odm);
/* A test harness interface that modifies dp encoder resources in the given dc
* state and bypasses the need to revalidate. The interface assumes that the
* test harness interface is called with pre-validated link config stored in the
* pipe_ctx and updates dp encoder resources according to the link config.
*/
enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,
struct dc_state *context,
struct pipe_ctx *pipe_ctx);
#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */
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