Commit ef30f441 authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher

drm/amd/display: define link res and make it accessible to all link interfaces

[why]
There will be a series of re-arch changes in Link Resource Management.
They are more and more muxable link resource objects and the resource is
insufficient for a one to one allocation to all links created.
Therefore a link resource sharing logic is required to determine which
link should use certain link resource.

This commit is the first one in this series that starts by defining a
link resource struct, this struct will be available to all interfaces
that need to perform link programming sequence.

In later commits, we will granduately decouple link resource objects out
of dc link. So instead of access a link resource from dc link. Current
link's resource can be accessible through pipe_ctx->link_res during
commit, or by calling  dc_link_get_cur_link_res function with current
link passed in after commit.
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 19afe66d
...@@ -986,7 +986,7 @@ static bool dc_link_detect_helper(struct dc_link *link, ...@@ -986,7 +986,7 @@ static bool dc_link_detect_helper(struct dc_link *link,
* empty which leads to allocate_mst_payload() has "0" * empty which leads to allocate_mst_payload() has "0"
* pbn_per_slot value leading to exception on dc_fixpt_div() * pbn_per_slot value leading to exception on dc_fixpt_div()
*/ */
dp_verify_mst_link_cap(link); dp_verify_mst_link_cap(link, NULL);
/* /*
* This call will initiate MST topology discovery. Which * This call will initiate MST topology discovery. Which
...@@ -1150,6 +1150,7 @@ static bool dc_link_detect_helper(struct dc_link *link, ...@@ -1150,6 +1150,7 @@ static bool dc_link_detect_helper(struct dc_link *link,
// verify link cap for SST non-seamless boot // verify link cap for SST non-seamless boot
if (!perform_dp_seamless_boot) if (!perform_dp_seamless_boot)
dp_verify_link_cap_with_retries(link, dp_verify_link_cap_with_retries(link,
NULL,
&link->reported_link_cap, &link->reported_link_cap,
LINK_TRAINING_MAX_VERIFY_RETRY); LINK_TRAINING_MAX_VERIFY_RETRY);
} else { } else {
...@@ -2503,7 +2504,8 @@ static void write_i2c_redriver_setting( ...@@ -2503,7 +2504,8 @@ static void write_i2c_redriver_setting(
DC_LOG_DEBUG("Set redriver failed"); DC_LOG_DEBUG("Set redriver failed");
} }
static void disable_link(struct dc_link *link, enum signal_type signal) static void disable_link(struct dc_link *link, const struct link_resource *link_res,
enum signal_type signal)
{ {
/* /*
* TODO: implement call for dp_set_hw_test_pattern * TODO: implement call for dp_set_hw_test_pattern
...@@ -2522,20 +2524,20 @@ static void disable_link(struct dc_link *link, enum signal_type signal) ...@@ -2522,20 +2524,20 @@ static void disable_link(struct dc_link *link, enum signal_type signal)
struct dc_link_settings link_settings = link->cur_link_settings; struct dc_link_settings link_settings = link->cur_link_settings;
#endif #endif
if (dc_is_dp_sst_signal(signal)) if (dc_is_dp_sst_signal(signal))
dp_disable_link_phy(link, signal); dp_disable_link_phy(link, link_res, signal);
else else
dp_disable_link_phy_mst(link, signal); dp_disable_link_phy_mst(link, link_res, signal);
if (dc_is_dp_sst_signal(signal) || if (dc_is_dp_sst_signal(signal) ||
link->mst_stream_alloc_table.stream_count == 0) { link->mst_stream_alloc_table.stream_count == 0) {
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING) { if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING) {
dp_set_fec_enable(link, false); dp_set_fec_enable(link, false);
dp_set_fec_ready(link, false); dp_set_fec_ready(link, link_res, false);
} }
#else #else
dp_set_fec_enable(link, false); dp_set_fec_enable(link, false);
dp_set_fec_ready(link, false); dp_set_fec_ready(link, link_res, false);
#endif #endif
} }
} else { } else {
...@@ -2646,7 +2648,7 @@ static enum dc_status enable_link( ...@@ -2646,7 +2648,7 @@ static enum dc_status enable_link(
* new link settings. * new link settings.
*/ */
if (link->link_status.link_active) { if (link->link_status.link_active) {
disable_link(link, pipe_ctx->stream->signal); disable_link(link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
} }
switch (pipe_ctx->stream->signal) { switch (pipe_ctx->stream->signal) {
...@@ -4109,7 +4111,7 @@ static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pi ...@@ -4109,7 +4111,7 @@ static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pi
stream->link->cur_link_settings = link_settings; stream->link->cur_link_settings = link_settings;
/* Enable clock, Configure lane count, and Enable Link Encoder*/ /* Enable clock, Configure lane count, and Enable Link Encoder*/
enable_dp_hpo_output(stream->link, &stream->link->cur_link_settings); enable_dp_hpo_output(stream->link, &pipe_ctx->link_res, &stream->link->cur_link_settings);
#ifdef DIAGS_BUILD #ifdef DIAGS_BUILD
/* Workaround for FPGA HPO capture DP link data: /* Workaround for FPGA HPO capture DP link data:
...@@ -4353,7 +4355,8 @@ void core_link_enable_stream( ...@@ -4353,7 +4355,8 @@ void core_link_enable_stream(
if (status != DC_FAIL_DP_LINK_TRAINING || if (status != DC_FAIL_DP_LINK_TRAINING ||
pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
if (false == stream->link->link_status.link_active) if (false == stream->link->link_status.link_active)
disable_link(stream->link, pipe_ctx->stream->signal); disable_link(stream->link, &pipe_ctx->link_res,
pipe_ctx->stream->signal);
BREAK_TO_DEBUGGER(); BREAK_TO_DEBUGGER();
return; return;
} }
...@@ -4502,14 +4505,14 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx) ...@@ -4502,14 +4505,14 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
* state machine. * state machine.
* In DP2 or MST mode, our encoder will stay video active * In DP2 or MST mode, our encoder will stay video active
*/ */
disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal); disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
dc->hwss.disable_stream(pipe_ctx); dc->hwss.disable_stream(pipe_ctx);
} else { } else {
dc->hwss.disable_stream(pipe_ctx); dc->hwss.disable_stream(pipe_ctx);
disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal); disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
} }
#else #else
disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal); disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
dc->hwss.disable_stream(pipe_ctx); dc->hwss.disable_stream(pipe_ctx);
#endif #endif
...@@ -4592,16 +4595,22 @@ void dc_link_set_drive_settings(struct dc *dc, ...@@ -4592,16 +4595,22 @@ void dc_link_set_drive_settings(struct dc *dc,
{ {
int i; int i;
struct pipe_ctx *pipe = NULL;
const struct link_resource *link_res;
for (i = 0; i < dc->link_count; i++) { link_res = dc_link_get_cur_link_res(link);
if (dc->links[i] == link)
break;
}
if (i >= dc->link_count) for (i = 0; i < MAX_PIPES; i++) {
pipe = &dc->current_state->res_ctx.pipe_ctx[i];
if (pipe->stream && pipe->stream->link) {
if (pipe->stream->link == link)
break;
}
}
if (pipe && link_res)
dc_link_dp_set_drive_settings(pipe->stream->link, link_res, lt_settings);
else
ASSERT_CRITICAL(false); ASSERT_CRITICAL(false);
dc_link_dp_set_drive_settings(dc->links[i], lt_settings);
} }
void dc_link_set_preferred_link_settings(struct dc *dc, void dc_link_set_preferred_link_settings(struct dc *dc,
...@@ -4793,6 +4802,9 @@ void dc_link_overwrite_extended_receiver_cap( ...@@ -4793,6 +4802,9 @@ void dc_link_overwrite_extended_receiver_cap(
bool dc_link_is_fec_supported(const struct dc_link *link) bool dc_link_is_fec_supported(const struct dc_link *link)
{ {
/* TODO - use asic cap instead of link_enc->features
* we no longer know which link enc to use for this link before commit
*/
struct link_encoder *link_enc = NULL; struct link_encoder *link_enc = NULL;
/* Links supporting dynamically assigned link encoder will be assigned next /* Links supporting dynamically assigned link encoder will be assigned next
...@@ -4887,3 +4899,22 @@ uint32_t dc_bandwidth_in_kbps_from_timing( ...@@ -4887,3 +4899,22 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
return kbps; return kbps;
} }
const struct link_resource *dc_link_get_cur_link_res(const struct dc_link *link)
{
int i;
struct pipe_ctx *pipe = NULL;
const struct link_resource *link_res = NULL;
for (i = 0; i < MAX_PIPES; i++) {
pipe = &link->dc->current_state->res_ctx.pipe_ctx[i];
if (pipe->stream && pipe->stream->link && pipe->top_pipe == NULL) {
if (pipe->stream->link == link) {
link_res = &pipe->link_res;
break;
}
}
}
return link_res;
}
...@@ -1251,6 +1251,7 @@ bool dp_is_max_vs_reached( ...@@ -1251,6 +1251,7 @@ bool dp_is_max_vs_reached(
static bool perform_post_lt_adj_req_sequence( static bool perform_post_lt_adj_req_sequence(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings) struct link_training_settings *lt_settings)
{ {
enum dc_lane_count lane_count = enum dc_lane_count lane_count =
...@@ -1314,6 +1315,7 @@ static bool perform_post_lt_adj_req_sequence( ...@@ -1314,6 +1315,7 @@ static bool perform_post_lt_adj_req_sequence(
lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
dc_link_dp_set_drive_settings(link, dc_link_dp_set_drive_settings(link,
link_res,
lt_settings); lt_settings);
break; break;
} }
...@@ -1388,6 +1390,7 @@ enum link_training_result dp_get_cr_failure(enum dc_lane_count ln_count, ...@@ -1388,6 +1390,7 @@ enum link_training_result dp_get_cr_failure(enum dc_lane_count ln_count,
static enum link_training_result perform_channel_equalization_sequence( static enum link_training_result perform_channel_equalization_sequence(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings, struct link_training_settings *lt_settings,
uint32_t offset) uint32_t offset)
{ {
...@@ -1410,12 +1413,12 @@ static enum link_training_result perform_channel_equalization_sequence( ...@@ -1410,12 +1413,12 @@ static enum link_training_result perform_channel_equalization_sequence(
tr_pattern = DP_TRAINING_PATTERN_SEQUENCE_4; tr_pattern = DP_TRAINING_PATTERN_SEQUENCE_4;
#endif #endif
dp_set_hw_training_pattern(link, tr_pattern, offset); dp_set_hw_training_pattern(link, link_res, tr_pattern, offset);
for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT; for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT;
retries_ch_eq++) { retries_ch_eq++) {
dp_set_hw_lane_settings(link, lt_settings, offset); dp_set_hw_lane_settings(link, link_res, lt_settings, offset);
/* 2. update DPCD*/ /* 2. update DPCD*/
if (!retries_ch_eq) if (!retries_ch_eq)
...@@ -1479,18 +1482,20 @@ static enum link_training_result perform_channel_equalization_sequence( ...@@ -1479,18 +1482,20 @@ static enum link_training_result perform_channel_equalization_sequence(
} }
static void start_clock_recovery_pattern_early(struct dc_link *link, static void start_clock_recovery_pattern_early(struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings, struct link_training_settings *lt_settings,
uint32_t offset) uint32_t offset)
{ {
DC_LOG_HW_LINK_TRAINING("%s\n GPU sends TPS1. Wait 400us.\n", DC_LOG_HW_LINK_TRAINING("%s\n GPU sends TPS1. Wait 400us.\n",
__func__); __func__);
dp_set_hw_training_pattern(link, lt_settings->pattern_for_cr, offset); dp_set_hw_training_pattern(link, link_res, lt_settings->pattern_for_cr, offset);
dp_set_hw_lane_settings(link, lt_settings, offset); dp_set_hw_lane_settings(link, link_res, lt_settings, offset);
udelay(400); udelay(400);
} }
static enum link_training_result perform_clock_recovery_sequence( static enum link_training_result perform_clock_recovery_sequence(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings, struct link_training_settings *lt_settings,
uint32_t offset) uint32_t offset)
{ {
...@@ -1506,7 +1511,7 @@ static enum link_training_result perform_clock_recovery_sequence( ...@@ -1506,7 +1511,7 @@ static enum link_training_result perform_clock_recovery_sequence(
retry_count = 0; retry_count = 0;
if (!link->ctx->dc->work_arounds.lt_early_cr_pattern) if (!link->ctx->dc->work_arounds.lt_early_cr_pattern)
dp_set_hw_training_pattern(link, lt_settings->pattern_for_cr, offset); dp_set_hw_training_pattern(link, link_res, lt_settings->pattern_for_cr, offset);
/* najeeb - The synaptics MST hub can put the LT in /* najeeb - The synaptics MST hub can put the LT in
* infinite loop by switching the VS * infinite loop by switching the VS
...@@ -1523,6 +1528,7 @@ static enum link_training_result perform_clock_recovery_sequence( ...@@ -1523,6 +1528,7 @@ static enum link_training_result perform_clock_recovery_sequence(
/* 1. call HWSS to set lane settings*/ /* 1. call HWSS to set lane settings*/
dp_set_hw_lane_settings( dp_set_hw_lane_settings(
link, link,
link_res,
lt_settings, lt_settings,
offset); offset);
...@@ -1621,13 +1627,14 @@ static enum link_training_result perform_clock_recovery_sequence( ...@@ -1621,13 +1627,14 @@ static enum link_training_result perform_clock_recovery_sequence(
static inline enum link_training_result dp_transition_to_video_idle( static inline enum link_training_result dp_transition_to_video_idle(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings, struct link_training_settings *lt_settings,
enum link_training_result status) enum link_training_result status)
{ {
union lane_count_set lane_count_set = {0}; union lane_count_set lane_count_set = {0};
/* 4. mainlink output idle pattern*/ /* 4. mainlink output idle pattern*/
dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0); dp_set_hw_test_pattern(link, link_res, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
/* /*
* 5. post training adjust if required * 5. post training adjust if required
...@@ -1651,7 +1658,7 @@ static inline enum link_training_result dp_transition_to_video_idle( ...@@ -1651,7 +1658,7 @@ static inline enum link_training_result dp_transition_to_video_idle(
} }
if (status == LINK_TRAINING_SUCCESS && if (status == LINK_TRAINING_SUCCESS &&
perform_post_lt_adj_req_sequence(link, lt_settings) == false) perform_post_lt_adj_req_sequence(link, link_res, lt_settings) == false)
status = LINK_TRAINING_LQA_FAIL; status = LINK_TRAINING_LQA_FAIL;
lane_count_set.bits.LANE_COUNT_SET = lt_settings->link_settings.lane_count; lane_count_set.bits.LANE_COUNT_SET = lt_settings->link_settings.lane_count;
...@@ -2094,10 +2101,11 @@ static void print_status_message( ...@@ -2094,10 +2101,11 @@ static void print_status_message(
void dc_link_dp_set_drive_settings( void dc_link_dp_set_drive_settings(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings) struct link_training_settings *lt_settings)
{ {
/* program ASIC PHY settings*/ /* program ASIC PHY settings*/
dp_set_hw_lane_settings(link, lt_settings, DPRX); dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX);
dp_hw_to_dpcd_lane_settings(lt_settings, dp_hw_to_dpcd_lane_settings(lt_settings,
lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
...@@ -2108,6 +2116,7 @@ void dc_link_dp_set_drive_settings( ...@@ -2108,6 +2116,7 @@ void dc_link_dp_set_drive_settings(
bool dc_link_dp_perform_link_training_skip_aux( bool dc_link_dp_perform_link_training_skip_aux(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
const struct dc_link_settings *link_setting) const struct dc_link_settings *link_setting)
{ {
struct link_training_settings lt_settings = {0}; struct link_training_settings lt_settings = {0};
...@@ -2124,10 +2133,10 @@ bool dc_link_dp_perform_link_training_skip_aux( ...@@ -2124,10 +2133,10 @@ bool dc_link_dp_perform_link_training_skip_aux(
/* 1. Perform_clock_recovery_sequence. */ /* 1. Perform_clock_recovery_sequence. */
/* transmit training pattern for clock recovery */ /* transmit training pattern for clock recovery */
dp_set_hw_training_pattern(link, lt_settings.pattern_for_cr, DPRX); dp_set_hw_training_pattern(link, link_res, lt_settings.pattern_for_cr, DPRX);
/* call HWSS to set lane settings*/ /* call HWSS to set lane settings*/
dp_set_hw_lane_settings(link, &lt_settings, DPRX); dp_set_hw_lane_settings(link, link_res, &lt_settings, DPRX);
/* wait receiver to lock-on*/ /* wait receiver to lock-on*/
dp_wait_for_training_aux_rd_interval(link, lt_settings.cr_pattern_time); dp_wait_for_training_aux_rd_interval(link, lt_settings.cr_pattern_time);
...@@ -2135,10 +2144,10 @@ bool dc_link_dp_perform_link_training_skip_aux( ...@@ -2135,10 +2144,10 @@ bool dc_link_dp_perform_link_training_skip_aux(
/* 2. Perform_channel_equalization_sequence. */ /* 2. Perform_channel_equalization_sequence. */
/* transmit training pattern for channel equalization. */ /* transmit training pattern for channel equalization. */
dp_set_hw_training_pattern(link, lt_settings.pattern_for_eq, DPRX); dp_set_hw_training_pattern(link, link_res, lt_settings.pattern_for_eq, DPRX);
/* call HWSS to set lane settings*/ /* call HWSS to set lane settings*/
dp_set_hw_lane_settings(link, &lt_settings, DPRX); dp_set_hw_lane_settings(link, link_res, &lt_settings, DPRX);
/* wait receiver to lock-on. */ /* wait receiver to lock-on. */
dp_wait_for_training_aux_rd_interval(link, lt_settings.eq_pattern_time); dp_wait_for_training_aux_rd_interval(link, lt_settings.eq_pattern_time);
...@@ -2146,7 +2155,7 @@ bool dc_link_dp_perform_link_training_skip_aux( ...@@ -2146,7 +2155,7 @@ bool dc_link_dp_perform_link_training_skip_aux(
/* 3. Perform_link_training_int. */ /* 3. Perform_link_training_int. */
/* Mainlink output idle pattern. */ /* Mainlink output idle pattern. */
dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0); dp_set_hw_test_pattern(link, link_res, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
print_status_message(link, &lt_settings, LINK_TRAINING_SUCCESS); print_status_message(link, &lt_settings, LINK_TRAINING_SUCCESS);
...@@ -2227,6 +2236,7 @@ static void dpcd_128b_132b_get_aux_rd_interval(struct dc_link *link, ...@@ -2227,6 +2236,7 @@ static void dpcd_128b_132b_get_aux_rd_interval(struct dc_link *link,
static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence( static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings) struct link_training_settings *lt_settings)
{ {
uint8_t loop_count; uint8_t loop_count;
...@@ -2238,7 +2248,7 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence( ...@@ -2238,7 +2248,7 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0}; union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
/* Transmit 128b/132b_TPS1 over Main-Link */ /* Transmit 128b/132b_TPS1 over Main-Link */
dp_set_hw_training_pattern(link, lt_settings->pattern_for_cr, DPRX); dp_set_hw_training_pattern(link, link_res, lt_settings->pattern_for_cr, DPRX);
/* Set TRAINING_PATTERN_SET to 01h */ /* Set TRAINING_PATTERN_SET to 01h */
dpcd_set_training_pattern(link, lt_settings->pattern_for_cr); dpcd_set_training_pattern(link, lt_settings->pattern_for_cr);
...@@ -2248,8 +2258,8 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence( ...@@ -2248,8 +2258,8 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
&dpcd_lane_status_updated, dpcd_lane_adjust, DPRX); &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
dp_decide_lane_settings(lt_settings, dpcd_lane_adjust, dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
dp_set_hw_lane_settings(link, lt_settings, DPRX); dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX);
dp_set_hw_training_pattern(link, lt_settings->pattern_for_eq, DPRX); dp_set_hw_training_pattern(link, link_res, lt_settings->pattern_for_eq, DPRX);
/* Set loop counter to start from 1 */ /* Set loop counter to start from 1 */
loop_count = 1; loop_count = 1;
...@@ -2276,7 +2286,7 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence( ...@@ -2276,7 +2286,7 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
} else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) { } else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) {
status = DP_128b_132b_LT_FAILED; status = DP_128b_132b_LT_FAILED;
} else { } else {
dp_set_hw_lane_settings(link, lt_settings, DPRX); dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX);
dpcd_set_lane_settings(link, lt_settings, DPRX); dpcd_set_lane_settings(link, lt_settings, DPRX);
} }
loop_count++; loop_count++;
...@@ -2305,6 +2315,7 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence( ...@@ -2305,6 +2315,7 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
static enum link_training_result dp_perform_128b_132b_cds_done_sequence( static enum link_training_result dp_perform_128b_132b_cds_done_sequence(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings) struct link_training_settings *lt_settings)
{ {
/* Assumption: assume hardware has transmitted eq pattern */ /* Assumption: assume hardware has transmitted eq pattern */
...@@ -2341,6 +2352,7 @@ static enum link_training_result dp_perform_128b_132b_cds_done_sequence( ...@@ -2341,6 +2352,7 @@ static enum link_training_result dp_perform_128b_132b_cds_done_sequence(
static enum link_training_result dp_perform_8b_10b_link_training( static enum link_training_result dp_perform_8b_10b_link_training(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings) struct link_training_settings *lt_settings)
{ {
enum link_training_result status = LINK_TRAINING_SUCCESS; enum link_training_result status = LINK_TRAINING_SUCCESS;
...@@ -2350,7 +2362,7 @@ static enum link_training_result dp_perform_8b_10b_link_training( ...@@ -2350,7 +2362,7 @@ static enum link_training_result dp_perform_8b_10b_link_training(
uint8_t lane = 0; uint8_t lane = 0;
if (link->ctx->dc->work_arounds.lt_early_cr_pattern) if (link->ctx->dc->work_arounds.lt_early_cr_pattern)
start_clock_recovery_pattern_early(link, lt_settings, DPRX); start_clock_recovery_pattern_early(link, link_res, lt_settings, DPRX);
/* 1. set link rate, lane count and spread. */ /* 1. set link rate, lane count and spread. */
dpcd_set_link_settings(link, lt_settings); dpcd_set_link_settings(link, lt_settings);
...@@ -2364,12 +2376,13 @@ static enum link_training_result dp_perform_8b_10b_link_training( ...@@ -2364,12 +2376,13 @@ static enum link_training_result dp_perform_8b_10b_link_training(
for (repeater_id = repeater_cnt; (repeater_id > 0 && status == LINK_TRAINING_SUCCESS); for (repeater_id = repeater_cnt; (repeater_id > 0 && status == LINK_TRAINING_SUCCESS);
repeater_id--) { repeater_id--) {
status = perform_clock_recovery_sequence(link, lt_settings, repeater_id); status = perform_clock_recovery_sequence(link, link_res, lt_settings, repeater_id);
if (status != LINK_TRAINING_SUCCESS) if (status != LINK_TRAINING_SUCCESS)
break; break;
status = perform_channel_equalization_sequence(link, status = perform_channel_equalization_sequence(link,
link_res,
lt_settings, lt_settings,
repeater_id); repeater_id);
...@@ -2384,9 +2397,10 @@ static enum link_training_result dp_perform_8b_10b_link_training( ...@@ -2384,9 +2397,10 @@ static enum link_training_result dp_perform_8b_10b_link_training(
} }
if (status == LINK_TRAINING_SUCCESS) { if (status == LINK_TRAINING_SUCCESS) {
status = perform_clock_recovery_sequence(link, lt_settings, DPRX); status = perform_clock_recovery_sequence(link, link_res, lt_settings, DPRX);
if (status == LINK_TRAINING_SUCCESS) { if (status == LINK_TRAINING_SUCCESS) {
status = perform_channel_equalization_sequence(link, status = perform_channel_equalization_sequence(link,
link_res,
lt_settings, lt_settings,
DPRX); DPRX);
} }
...@@ -2398,6 +2412,7 @@ static enum link_training_result dp_perform_8b_10b_link_training( ...@@ -2398,6 +2412,7 @@ static enum link_training_result dp_perform_8b_10b_link_training(
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
static enum link_training_result dp_perform_128b_132b_link_training( static enum link_training_result dp_perform_128b_132b_link_training(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings) struct link_training_settings *lt_settings)
{ {
enum link_training_result result = LINK_TRAINING_SUCCESS; enum link_training_result result = LINK_TRAINING_SUCCESS;
...@@ -2409,16 +2424,16 @@ static enum link_training_result dp_perform_128b_132b_link_training( ...@@ -2409,16 +2424,16 @@ static enum link_training_result dp_perform_128b_132b_link_training(
decide_8b_10b_training_settings(link, decide_8b_10b_training_settings(link,
&lt_settings->link_settings, &lt_settings->link_settings,
&legacy_settings); &legacy_settings);
return dp_perform_8b_10b_link_training(link, &legacy_settings); return dp_perform_8b_10b_link_training(link, link_res, &legacy_settings);
} }
dpcd_set_link_settings(link, lt_settings); dpcd_set_link_settings(link, lt_settings);
if (result == LINK_TRAINING_SUCCESS) if (result == LINK_TRAINING_SUCCESS)
result = dp_perform_128b_132b_channel_eq_done_sequence(link, lt_settings); result = dp_perform_128b_132b_channel_eq_done_sequence(link, link_res, lt_settings);
if (result == LINK_TRAINING_SUCCESS) if (result == LINK_TRAINING_SUCCESS)
result = dp_perform_128b_132b_cds_done_sequence(link, lt_settings); result = dp_perform_128b_132b_cds_done_sequence(link, link_res, lt_settings);
return result; return result;
} }
...@@ -2426,6 +2441,7 @@ static enum link_training_result dp_perform_128b_132b_link_training( ...@@ -2426,6 +2441,7 @@ static enum link_training_result dp_perform_128b_132b_link_training(
static enum link_training_result dc_link_dp_perform_fixed_vs_pe_training_sequence( static enum link_training_result dc_link_dp_perform_fixed_vs_pe_training_sequence(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings) struct link_training_settings *lt_settings)
{ {
const uint8_t vendor_lttpr_write_data_reset[4] = {0x1, 0x50, 0x63, 0xFF}; const uint8_t vendor_lttpr_write_data_reset[4] = {0x1, 0x50, 0x63, 0xFF};
...@@ -2554,6 +2570,7 @@ static enum link_training_result dc_link_dp_perform_fixed_vs_pe_training_sequenc ...@@ -2554,6 +2570,7 @@ static enum link_training_result dc_link_dp_perform_fixed_vs_pe_training_sequenc
/* 1. call HWSS to set lane settings */ /* 1. call HWSS to set lane settings */
dp_set_hw_lane_settings( dp_set_hw_lane_settings(
link, link,
link_res,
lt_settings, lt_settings,
0); 0);
...@@ -2670,14 +2687,14 @@ static enum link_training_result dc_link_dp_perform_fixed_vs_pe_training_sequenc ...@@ -2670,14 +2687,14 @@ static enum link_training_result dc_link_dp_perform_fixed_vs_pe_training_sequenc
/* Note: also check that TPS4 is a supported feature*/ /* Note: also check that TPS4 is a supported feature*/
tr_pattern = lt_settings->pattern_for_eq; tr_pattern = lt_settings->pattern_for_eq;
dp_set_hw_training_pattern(link, tr_pattern, 0); dp_set_hw_training_pattern(link, link_res, tr_pattern, 0);
status = LINK_TRAINING_EQ_FAIL_EQ; status = LINK_TRAINING_EQ_FAIL_EQ;
for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT; for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT;
retries_ch_eq++) { retries_ch_eq++) {
dp_set_hw_lane_settings(link, lt_settings, 0); dp_set_hw_lane_settings(link, link_res, lt_settings, 0);
vendor_lttpr_write_data_vs[3] = 0; vendor_lttpr_write_data_vs[3] = 0;
vendor_lttpr_write_data_pe[3] = 0; vendor_lttpr_write_data_pe[3] = 0;
...@@ -2758,6 +2775,7 @@ static enum link_training_result dc_link_dp_perform_fixed_vs_pe_training_sequenc ...@@ -2758,6 +2775,7 @@ static enum link_training_result dc_link_dp_perform_fixed_vs_pe_training_sequenc
enum link_training_result dc_link_dp_perform_link_training( enum link_training_result dc_link_dp_perform_link_training(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
const struct dc_link_settings *link_settings, const struct dc_link_settings *link_settings,
bool skip_video_pattern) bool skip_video_pattern)
{ {
...@@ -2788,7 +2806,7 @@ enum link_training_result dc_link_dp_perform_link_training( ...@@ -2788,7 +2806,7 @@ enum link_training_result dc_link_dp_perform_link_training(
/* configure link prior to entering training mode */ /* configure link prior to entering training mode */
dpcd_configure_lttpr_mode(link, &lt_settings); dpcd_configure_lttpr_mode(link, &lt_settings);
dp_set_fec_ready(link, lt_settings.should_set_fec_ready); dp_set_fec_ready(link, link_res, lt_settings.should_set_fec_ready);
dpcd_configure_channel_coding(link, &lt_settings); dpcd_configure_channel_coding(link, &lt_settings);
/* enter training mode: /* enter training mode:
...@@ -2798,12 +2816,12 @@ enum link_training_result dc_link_dp_perform_link_training( ...@@ -2798,12 +2816,12 @@ enum link_training_result dc_link_dp_perform_link_training(
if (!link->dc->debug.apply_vendor_specific_lttpr_wa && if (!link->dc->debug.apply_vendor_specific_lttpr_wa &&
(link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
link->lttpr_mode == LTTPR_MODE_TRANSPARENT) link->lttpr_mode == LTTPR_MODE_TRANSPARENT)
status = dc_link_dp_perform_fixed_vs_pe_training_sequence(link, &lt_settings); status = dc_link_dp_perform_fixed_vs_pe_training_sequence(link, link_res, &lt_settings);
else if (encoding == DP_8b_10b_ENCODING) else if (encoding == DP_8b_10b_ENCODING)
status = dp_perform_8b_10b_link_training(link, &lt_settings); status = dp_perform_8b_10b_link_training(link, link_res, &lt_settings);
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
else if (encoding == DP_128b_132b_ENCODING) else if (encoding == DP_128b_132b_ENCODING)
status = dp_perform_128b_132b_link_training(link, &lt_settings); status = dp_perform_128b_132b_link_training(link, link_res, &lt_settings);
#endif #endif
else else
ASSERT(0); ASSERT(0);
...@@ -2821,6 +2839,7 @@ enum link_training_result dc_link_dp_perform_link_training( ...@@ -2821,6 +2839,7 @@ enum link_training_result dc_link_dp_perform_link_training(
/* switch to video idle */ /* switch to video idle */
if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern) if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern)
status = dp_transition_to_video_idle(link, status = dp_transition_to_video_idle(link,
link_res,
&lt_settings, &lt_settings,
status); status);
...@@ -2872,6 +2891,7 @@ bool perform_link_training_with_retries( ...@@ -2872,6 +2891,7 @@ bool perform_link_training_with_retries(
dp_enable_link_phy( dp_enable_link_phy(
link, link,
&pipe_ctx->link_res,
signal, signal,
pipe_ctx->clock_source->id, pipe_ctx->clock_source->id,
&current_setting); &current_setting);
...@@ -2899,23 +2919,24 @@ bool perform_link_training_with_retries( ...@@ -2899,23 +2919,24 @@ bool perform_link_training_with_retries(
dp_set_panel_mode(link, panel_mode); dp_set_panel_mode(link, panel_mode);
if (link->aux_access_disabled) { if (link->aux_access_disabled) {
dc_link_dp_perform_link_training_skip_aux(link, &current_setting); dc_link_dp_perform_link_training_skip_aux(link, &pipe_ctx->link_res, &current_setting);
return true; return true;
} else { } else {
/** @todo Consolidate USB4 DP and DPx.x training. */ /** @todo Consolidate USB4 DP and DPx.x training. */
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
status = dc_link_dpia_perform_link_training(link, status = dc_link_dpia_perform_link_training(link,
&current_setting, &pipe_ctx->link_res,
skip_video_pattern); &current_setting,
skip_video_pattern);
/* Transmit idle pattern once training successful. */ /* Transmit idle pattern once training successful. */
if (status == LINK_TRAINING_SUCCESS) if (status == LINK_TRAINING_SUCCESS)
dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, dp_set_hw_test_pattern(link, &pipe_ctx->link_res, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
NULL, 0);
} else { } else {
status = dc_link_dp_perform_link_training(link, status = dc_link_dp_perform_link_training(link,
&current_setting, &pipe_ctx->link_res,
skip_video_pattern); &current_setting,
skip_video_pattern);
} }
if (status == LINK_TRAINING_SUCCESS) if (status == LINK_TRAINING_SUCCESS)
...@@ -2930,7 +2951,7 @@ bool perform_link_training_with_retries( ...@@ -2930,7 +2951,7 @@ bool perform_link_training_with_retries(
DC_LOG_WARNING("%s: Link training attempt %u of %d failed\n", DC_LOG_WARNING("%s: Link training attempt %u of %d failed\n",
__func__, (unsigned int)j + 1, attempts); __func__, (unsigned int)j + 1, attempts);
dp_disable_link_phy(link, signal); dp_disable_link_phy(link, &pipe_ctx->link_res, signal);
/* Abort link training if failure due to sink being unplugged. */ /* Abort link training if failure due to sink being unplugged. */
if (status == LINK_TRAINING_ABORT) { if (status == LINK_TRAINING_ABORT) {
...@@ -2979,12 +3000,13 @@ static enum clock_source_id get_clock_source_id(struct dc_link *link) ...@@ -2979,12 +3000,13 @@ static enum clock_source_id get_clock_source_id(struct dc_link *link)
return dp_cs_id; return dp_cs_id;
} }
static void set_dp_mst_mode(struct dc_link *link, bool mst_enable) static void set_dp_mst_mode(struct dc_link *link, const struct link_resource *link_res,
bool mst_enable)
{ {
if (mst_enable == false && if (mst_enable == false &&
link->type == dc_connection_mst_branch) { link->type == dc_connection_mst_branch) {
/* Disable MST on link. Use only local sink. */ /* Disable MST on link. Use only local sink. */
dp_disable_link_phy_mst(link, link->connector_signal); dp_disable_link_phy_mst(link, link_res, link->connector_signal);
link->type = dc_connection_single; link->type = dc_connection_single;
link->local_sink = link->remote_sinks[0]; link->local_sink = link->remote_sinks[0];
...@@ -2995,7 +3017,7 @@ static void set_dp_mst_mode(struct dc_link *link, bool mst_enable) ...@@ -2995,7 +3017,7 @@ static void set_dp_mst_mode(struct dc_link *link, bool mst_enable)
link->type == dc_connection_single && link->type == dc_connection_single &&
link->remote_sinks[0] != NULL) { link->remote_sinks[0] != NULL) {
/* Re-enable MST on link. */ /* Re-enable MST on link. */
dp_disable_link_phy(link, link->connector_signal); dp_disable_link_phy(link, link_res, link->connector_signal);
dp_enable_mst_on_sink(link, true); dp_enable_mst_on_sink(link, true);
link->type = dc_connection_mst_branch; link->type = dc_connection_mst_branch;
...@@ -3021,6 +3043,7 @@ bool dc_link_dp_sync_lt_begin(struct dc_link *link) ...@@ -3021,6 +3043,7 @@ bool dc_link_dp_sync_lt_begin(struct dc_link *link)
enum link_training_result dc_link_dp_sync_lt_attempt( enum link_training_result dc_link_dp_sync_lt_attempt(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct dc_link_settings *link_settings, struct dc_link_settings *link_settings,
struct dc_link_training_overrides *lt_overrides) struct dc_link_training_overrides *lt_overrides)
{ {
...@@ -3040,14 +3063,14 @@ enum link_training_result dc_link_dp_sync_lt_attempt( ...@@ -3040,14 +3063,14 @@ enum link_training_result dc_link_dp_sync_lt_attempt(
&lt_settings); &lt_settings);
/* Setup MST Mode */ /* Setup MST Mode */
if (lt_overrides->mst_enable) if (lt_overrides->mst_enable)
set_dp_mst_mode(link, *lt_overrides->mst_enable); set_dp_mst_mode(link, link_res, *lt_overrides->mst_enable);
/* Disable link */ /* Disable link */
dp_disable_link_phy(link, link->connector_signal); dp_disable_link_phy(link, link_res, link->connector_signal);
/* Enable link */ /* Enable link */
dp_cs_id = get_clock_source_id(link); dp_cs_id = get_clock_source_id(link);
dp_enable_link_phy(link, link->connector_signal, dp_enable_link_phy(link, link_res, link->connector_signal,
dp_cs_id, link_settings); dp_cs_id, link_settings);
/* Set FEC enable */ /* Set FEC enable */
...@@ -3055,7 +3078,7 @@ enum link_training_result dc_link_dp_sync_lt_attempt( ...@@ -3055,7 +3078,7 @@ enum link_training_result dc_link_dp_sync_lt_attempt(
if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) { if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
#endif #endif
fec_enable = lt_overrides->fec_enable && *lt_overrides->fec_enable; fec_enable = lt_overrides->fec_enable && *lt_overrides->fec_enable;
dp_set_fec_ready(link, fec_enable); dp_set_fec_ready(link, NULL, fec_enable);
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
} }
#endif #endif
...@@ -3072,7 +3095,7 @@ enum link_training_result dc_link_dp_sync_lt_attempt( ...@@ -3072,7 +3095,7 @@ enum link_training_result dc_link_dp_sync_lt_attempt(
/* Attempt to train with given link training settings */ /* Attempt to train with given link training settings */
if (link->ctx->dc->work_arounds.lt_early_cr_pattern) if (link->ctx->dc->work_arounds.lt_early_cr_pattern)
start_clock_recovery_pattern_early(link, &lt_settings, DPRX); start_clock_recovery_pattern_early(link, link_res, &lt_settings, DPRX);
/* Set link rate, lane count and spread. */ /* Set link rate, lane count and spread. */
dpcd_set_link_settings(link, &lt_settings); dpcd_set_link_settings(link, &lt_settings);
...@@ -3080,9 +3103,10 @@ enum link_training_result dc_link_dp_sync_lt_attempt( ...@@ -3080,9 +3103,10 @@ enum link_training_result dc_link_dp_sync_lt_attempt(
/* 2. perform link training (set link training done /* 2. perform link training (set link training done
* to false is done as well) * to false is done as well)
*/ */
lt_status = perform_clock_recovery_sequence(link, &lt_settings, DPRX); lt_status = perform_clock_recovery_sequence(link, link_res, &lt_settings, DPRX);
if (lt_status == LINK_TRAINING_SUCCESS) { if (lt_status == LINK_TRAINING_SUCCESS) {
lt_status = perform_channel_equalization_sequence(link, lt_status = perform_channel_equalization_sequence(link,
link_res,
&lt_settings, &lt_settings,
DPRX); DPRX);
} }
...@@ -3103,11 +3127,11 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down) ...@@ -3103,11 +3127,11 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down)
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_link_settings link_settings = link->cur_link_settings; struct dc_link_settings link_settings = link->cur_link_settings;
#endif #endif
dp_disable_link_phy(link, link->connector_signal); dp_disable_link_phy(link, NULL, link->connector_signal);
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING) if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING)
#endif #endif
dp_set_fec_ready(link, false); dp_set_fec_ready(link, NULL, false);
} }
link->sync_lt_in_progress = false; link->sync_lt_in_progress = false;
...@@ -3162,7 +3186,8 @@ bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_ ...@@ -3162,7 +3186,8 @@ bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_
return false; return false;
} }
static struct dc_link_settings get_max_link_cap(struct dc_link *link) static struct dc_link_settings get_max_link_cap(struct dc_link *link,
const struct link_resource *link_res)
{ {
struct dc_link_settings max_link_cap = {0}; struct dc_link_settings max_link_cap = {0};
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
...@@ -3345,6 +3370,7 @@ bool hpd_rx_irq_check_link_loss_status( ...@@ -3345,6 +3370,7 @@ bool hpd_rx_irq_check_link_loss_status(
bool dp_verify_link_cap( bool dp_verify_link_cap(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct dc_link_settings *known_limit_link_setting, struct dc_link_settings *known_limit_link_setting,
int *fail_count) int *fail_count)
{ {
...@@ -3362,7 +3388,7 @@ bool dp_verify_link_cap( ...@@ -3362,7 +3388,7 @@ bool dp_verify_link_cap(
/* link training starts with the maximum common settings /* link training starts with the maximum common settings
* supported by both sink and ASIC. * supported by both sink and ASIC.
*/ */
max_link_cap = get_max_link_cap(link); max_link_cap = get_max_link_cap(link, link_res);
initial_link_settings = get_common_supported_link_settings( initial_link_settings = get_common_supported_link_settings(
*known_limit_link_setting, *known_limit_link_setting,
max_link_cap); max_link_cap);
...@@ -3402,7 +3428,7 @@ bool dp_verify_link_cap( ...@@ -3402,7 +3428,7 @@ bool dp_verify_link_cap(
* find the physical link capability * find the physical link capability
*/ */
/* disable PHY done possible by BIOS, will be done by driver itself */ /* disable PHY done possible by BIOS, will be done by driver itself */
dp_disable_link_phy(link, link->connector_signal); dp_disable_link_phy(link, link_res, link->connector_signal);
dp_cs_id = get_clock_source_id(link); dp_cs_id = get_clock_source_id(link);
...@@ -3414,8 +3440,8 @@ bool dp_verify_link_cap( ...@@ -3414,8 +3440,8 @@ bool dp_verify_link_cap(
*/ */
if (link->link_enc && link->link_enc->features.flags.bits.DP_IS_USB_C && if (link->link_enc && link->link_enc->features.flags.bits.DP_IS_USB_C &&
link->dc->debug.usbc_combo_phy_reset_wa) { link->dc->debug.usbc_combo_phy_reset_wa) {
dp_enable_link_phy(link, link->connector_signal, dp_cs_id, cur); dp_enable_link_phy(link, link_res, link->connector_signal, dp_cs_id, cur);
dp_disable_link_phy(link, link->connector_signal); dp_disable_link_phy(link, link_res, link->connector_signal);
} }
do { do {
...@@ -3426,6 +3452,7 @@ bool dp_verify_link_cap( ...@@ -3426,6 +3452,7 @@ bool dp_verify_link_cap(
dp_enable_link_phy( dp_enable_link_phy(
link, link,
link_res,
link->connector_signal, link->connector_signal,
dp_cs_id, dp_cs_id,
cur); cur);
...@@ -3436,6 +3463,7 @@ bool dp_verify_link_cap( ...@@ -3436,6 +3463,7 @@ bool dp_verify_link_cap(
else { else {
status = dc_link_dp_perform_link_training( status = dc_link_dp_perform_link_training(
link, link,
link_res,
cur, cur,
skip_video_pattern); skip_video_pattern);
if (status == LINK_TRAINING_SUCCESS) if (status == LINK_TRAINING_SUCCESS)
...@@ -3457,7 +3485,7 @@ bool dp_verify_link_cap( ...@@ -3457,7 +3485,7 @@ bool dp_verify_link_cap(
* setting or before returning we'll enable it later * setting or before returning we'll enable it later
* based on the actual mode we're driving * based on the actual mode we're driving
*/ */
dp_disable_link_phy(link, link->connector_signal); dp_disable_link_phy(link, link_res, link->connector_signal);
} while (!success && decide_fallback_link_setting(link, } while (!success && decide_fallback_link_setting(link,
initial_link_settings, cur, status)); initial_link_settings, cur, status));
...@@ -3481,6 +3509,7 @@ bool dp_verify_link_cap( ...@@ -3481,6 +3509,7 @@ bool dp_verify_link_cap(
bool dp_verify_link_cap_with_retries( bool dp_verify_link_cap_with_retries(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct dc_link_settings *known_limit_link_setting, struct dc_link_settings *known_limit_link_setting,
int attempts) int attempts)
{ {
...@@ -3498,7 +3527,7 @@ bool dp_verify_link_cap_with_retries( ...@@ -3498,7 +3527,7 @@ bool dp_verify_link_cap_with_retries(
link->verified_link_cap.link_rate = LINK_RATE_LOW; link->verified_link_cap.link_rate = LINK_RATE_LOW;
link->verified_link_cap.link_spread = LINK_SPREAD_DISABLED; link->verified_link_cap.link_spread = LINK_SPREAD_DISABLED;
break; break;
} else if (dp_verify_link_cap(link, } else if (dp_verify_link_cap(link, link_res,
known_limit_link_setting, known_limit_link_setting,
&fail_count) && fail_count == 0) { &fail_count) && fail_count == 0) {
success = true; success = true;
...@@ -3510,13 +3539,13 @@ bool dp_verify_link_cap_with_retries( ...@@ -3510,13 +3539,13 @@ bool dp_verify_link_cap_with_retries(
} }
bool dp_verify_mst_link_cap( bool dp_verify_mst_link_cap(
struct dc_link *link) struct dc_link *link, const struct link_resource *link_res)
{ {
struct dc_link_settings max_link_cap = {0}; struct dc_link_settings max_link_cap = {0};
if (dp_get_link_encoding_format(&link->reported_link_cap) == if (dp_get_link_encoding_format(&link->reported_link_cap) ==
DP_8b_10b_ENCODING) { DP_8b_10b_ENCODING) {
max_link_cap = get_max_link_cap(link); max_link_cap = get_max_link_cap(link, link_res);
link->verified_link_cap = get_common_supported_link_settings( link->verified_link_cap = get_common_supported_link_settings(
link->reported_link_cap, link->reported_link_cap,
max_link_cap); max_link_cap);
...@@ -3525,6 +3554,7 @@ bool dp_verify_mst_link_cap( ...@@ -3525,6 +3554,7 @@ bool dp_verify_mst_link_cap(
else if (dp_get_link_encoding_format(&link->reported_link_cap) == else if (dp_get_link_encoding_format(&link->reported_link_cap) ==
DP_128b_132b_ENCODING) { DP_128b_132b_ENCODING) {
dp_verify_link_cap_with_retries(link, dp_verify_link_cap_with_retries(link,
link_res,
&link->reported_link_cap, &link->reported_link_cap,
LINK_TRAINING_MAX_VERIFY_RETRY); LINK_TRAINING_MAX_VERIFY_RETRY);
} }
...@@ -6053,7 +6083,7 @@ bool dc_link_dp_set_test_pattern( ...@@ -6053,7 +6083,7 @@ bool dc_link_dp_set_test_pattern(
DP_TEST_PATTERN_VIDEO_MODE) { DP_TEST_PATTERN_VIDEO_MODE) {
/* Set CRTC Test Pattern */ /* Set CRTC Test Pattern */
set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space); set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
dp_set_hw_test_pattern(link, test_pattern, dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern,
(uint8_t *)p_custom_pattern, (uint8_t *)p_custom_pattern,
(uint32_t)cust_pattern_size); (uint32_t)cust_pattern_size);
...@@ -6084,7 +6114,7 @@ bool dc_link_dp_set_test_pattern( ...@@ -6084,7 +6114,7 @@ bool dc_link_dp_set_test_pattern(
p_link_settings->dpcd_lane_settings, p_link_settings->dpcd_lane_settings,
p_link_settings->link_settings.lane_count); p_link_settings->link_settings.lane_count);
} else { } else {
dp_set_hw_lane_settings(link, p_link_settings, DPRX); dp_set_hw_lane_settings(link, &pipe_ctx->link_res, p_link_settings, DPRX);
dpcd_set_lane_settings(link, p_link_settings, DPRX); dpcd_set_lane_settings(link, p_link_settings, DPRX);
} }
} }
...@@ -6099,7 +6129,7 @@ bool dc_link_dp_set_test_pattern( ...@@ -6099,7 +6129,7 @@ bool dc_link_dp_set_test_pattern(
pipes->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc); pipes->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc);
} }
dp_set_hw_test_pattern(link, test_pattern, dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern,
(uint8_t *)p_custom_pattern, (uint8_t *)p_custom_pattern,
(uint32_t)cust_pattern_size); (uint32_t)cust_pattern_size);
...@@ -6419,7 +6449,7 @@ enum dp_panel_mode dp_get_panel_mode(struct dc_link *link) ...@@ -6419,7 +6449,7 @@ enum dp_panel_mode dp_get_panel_mode(struct dc_link *link)
return DP_PANEL_MODE_DEFAULT; return DP_PANEL_MODE_DEFAULT;
} }
enum dc_status dp_set_fec_ready(struct dc_link *link, bool ready) enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready)
{ {
/* FEC has to be "set ready" before the link training. /* FEC has to be "set ready" before the link training.
* The policy is to always train with FEC * The policy is to always train with FEC
......
...@@ -77,7 +77,9 @@ enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link) ...@@ -77,7 +77,9 @@ enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link)
* @param[in] link_setting Lane count, link rate and downspread control. * @param[in] link_setting Lane count, link rate and downspread control.
* @param[out] lt_settings Link settings and drive settings (voltage swing and pre-emphasis). * @param[out] lt_settings Link settings and drive settings (voltage swing and pre-emphasis).
*/ */
static enum link_training_result dpia_configure_link(struct dc_link *link, static enum link_training_result dpia_configure_link(
struct dc_link *link,
const struct link_resource *link_res,
const struct dc_link_settings *link_setting, const struct dc_link_settings *link_setting,
struct link_training_settings *lt_settings) struct link_training_settings *lt_settings)
{ {
...@@ -111,7 +113,7 @@ static enum link_training_result dpia_configure_link(struct dc_link *link, ...@@ -111,7 +113,7 @@ static enum link_training_result dpia_configure_link(struct dc_link *link,
fec_enable = *link->preferred_training_settings.fec_enable; fec_enable = *link->preferred_training_settings.fec_enable;
else else
fec_enable = true; fec_enable = true;
status = dp_set_fec_ready(link, fec_enable); status = dp_set_fec_ready(link, link_res, fec_enable);
if (status != DC_OK && link->is_hpd_pending) if (status != DC_OK && link->is_hpd_pending)
return LINK_TRAINING_ABORT; return LINK_TRAINING_ABORT;
...@@ -252,7 +254,9 @@ static enum dc_status dpcd_set_lt_pattern(struct dc_link *link, ...@@ -252,7 +254,9 @@ static enum dc_status dpcd_set_lt_pattern(struct dc_link *link,
* @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis). * @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis).
* @param hop The Hop in display path. DPRX = 0. * @param hop The Hop in display path. DPRX = 0.
*/ */
static enum link_training_result dpia_training_cr_non_transparent(struct dc_link *link, static enum link_training_result dpia_training_cr_non_transparent(
struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings, struct link_training_settings *lt_settings,
uint32_t hop) uint32_t hop)
{ {
...@@ -411,7 +415,9 @@ static enum link_training_result dpia_training_cr_non_transparent(struct dc_link ...@@ -411,7 +415,9 @@ static enum link_training_result dpia_training_cr_non_transparent(struct dc_link
* @param link DPIA link being trained. * @param link DPIA link being trained.
* @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis). * @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis).
*/ */
static enum link_training_result dpia_training_cr_transparent(struct dc_link *link, static enum link_training_result dpia_training_cr_transparent(
struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings) struct link_training_settings *lt_settings)
{ {
enum link_training_result result = LINK_TRAINING_CR_FAIL_LANE0; enum link_training_result result = LINK_TRAINING_CR_FAIL_LANE0;
...@@ -511,16 +517,18 @@ static enum link_training_result dpia_training_cr_transparent(struct dc_link *li ...@@ -511,16 +517,18 @@ static enum link_training_result dpia_training_cr_transparent(struct dc_link *li
* @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis). * @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis).
* @param hop The Hop in display path. DPRX = 0. * @param hop The Hop in display path. DPRX = 0.
*/ */
static enum link_training_result dpia_training_cr_phase(struct dc_link *link, static enum link_training_result dpia_training_cr_phase(
struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings, struct link_training_settings *lt_settings,
uint32_t hop) uint32_t hop)
{ {
enum link_training_result result = LINK_TRAINING_CR_FAIL_LANE0; enum link_training_result result = LINK_TRAINING_CR_FAIL_LANE0;
if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
result = dpia_training_cr_non_transparent(link, lt_settings, hop); result = dpia_training_cr_non_transparent(link, link_res, lt_settings, hop);
else else
result = dpia_training_cr_transparent(link, lt_settings); result = dpia_training_cr_transparent(link, link_res, lt_settings);
return result; return result;
} }
...@@ -561,7 +569,9 @@ static uint32_t dpia_get_eq_aux_rd_interval(const struct dc_link *link, ...@@ -561,7 +569,9 @@ static uint32_t dpia_get_eq_aux_rd_interval(const struct dc_link *link,
* @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis). * @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis).
* @param hop The Hop in display path. DPRX = 0. * @param hop The Hop in display path. DPRX = 0.
*/ */
static enum link_training_result dpia_training_eq_non_transparent(struct dc_link *link, static enum link_training_result dpia_training_eq_non_transparent(
struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings, struct link_training_settings *lt_settings,
uint32_t hop) uint32_t hop)
{ {
...@@ -700,7 +710,9 @@ static enum link_training_result dpia_training_eq_non_transparent(struct dc_link ...@@ -700,7 +710,9 @@ static enum link_training_result dpia_training_eq_non_transparent(struct dc_link
* @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis). * @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis).
* @param hop The Hop in display path. DPRX = 0. * @param hop The Hop in display path. DPRX = 0.
*/ */
static enum link_training_result dpia_training_eq_transparent(struct dc_link *link, static enum link_training_result dpia_training_eq_transparent(
struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings) struct link_training_settings *lt_settings)
{ {
enum link_training_result result = LINK_TRAINING_EQ_FAIL_EQ; enum link_training_result result = LINK_TRAINING_EQ_FAIL_EQ;
...@@ -779,16 +791,18 @@ static enum link_training_result dpia_training_eq_transparent(struct dc_link *li ...@@ -779,16 +791,18 @@ static enum link_training_result dpia_training_eq_transparent(struct dc_link *li
* @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis). * @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis).
* @param hop The Hop in display path. DPRX = 0. * @param hop The Hop in display path. DPRX = 0.
*/ */
static enum link_training_result dpia_training_eq_phase(struct dc_link *link, static enum link_training_result dpia_training_eq_phase(
struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings, struct link_training_settings *lt_settings,
uint32_t hop) uint32_t hop)
{ {
enum link_training_result result; enum link_training_result result;
if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
result = dpia_training_eq_non_transparent(link, lt_settings, hop); result = dpia_training_eq_non_transparent(link, link_res, lt_settings, hop);
else else
result = dpia_training_eq_transparent(link, lt_settings); result = dpia_training_eq_transparent(link, link_res, lt_settings);
return result; return result;
} }
...@@ -908,7 +922,9 @@ static void dpia_training_abort(struct dc_link *link, uint32_t hop) ...@@ -908,7 +922,9 @@ static void dpia_training_abort(struct dc_link *link, uint32_t hop)
core_link_send_set_config(link, DPIA_SET_CFG_SET_LINK, data); core_link_send_set_config(link, DPIA_SET_CFG_SET_LINK, data);
} }
enum link_training_result dc_link_dpia_perform_link_training(struct dc_link *link, enum link_training_result dc_link_dpia_perform_link_training(
struct dc_link *link,
const struct link_resource *link_res,
const struct dc_link_settings *link_setting, const struct dc_link_settings *link_setting,
bool skip_video_pattern) bool skip_video_pattern)
{ {
...@@ -918,7 +934,7 @@ enum link_training_result dc_link_dpia_perform_link_training(struct dc_link *lin ...@@ -918,7 +934,7 @@ enum link_training_result dc_link_dpia_perform_link_training(struct dc_link *lin
int8_t repeater_id; /* Current hop. */ int8_t repeater_id; /* Current hop. */
/* Configure link as prescribed in link_setting and set LTTPR mode. */ /* Configure link as prescribed in link_setting and set LTTPR mode. */
result = dpia_configure_link(link, link_setting, &lt_settings); result = dpia_configure_link(link, link_res, link_setting, &lt_settings);
if (result != LINK_TRAINING_SUCCESS) if (result != LINK_TRAINING_SUCCESS)
return result; return result;
...@@ -930,12 +946,12 @@ enum link_training_result dc_link_dpia_perform_link_training(struct dc_link *lin ...@@ -930,12 +946,12 @@ enum link_training_result dc_link_dpia_perform_link_training(struct dc_link *lin
*/ */
for (repeater_id = repeater_cnt; repeater_id >= 0; repeater_id--) { for (repeater_id = repeater_cnt; repeater_id >= 0; repeater_id--) {
/* Clock recovery. */ /* Clock recovery. */
result = dpia_training_cr_phase(link, &lt_settings, repeater_id); result = dpia_training_cr_phase(link, link_res, &lt_settings, repeater_id);
if (result != LINK_TRAINING_SUCCESS) if (result != LINK_TRAINING_SUCCESS)
break; break;
/* Equalization. */ /* Equalization. */
result = dpia_training_eq_phase(link, &lt_settings, repeater_id); result = dpia_training_eq_phase(link, link_res, &lt_settings, repeater_id);
if (result != LINK_TRAINING_SUCCESS) if (result != LINK_TRAINING_SUCCESS)
break; break;
......
...@@ -71,6 +71,7 @@ void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode) ...@@ -71,6 +71,7 @@ void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode)
void dp_enable_link_phy( void dp_enable_link_phy(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
enum signal_type signal, enum signal_type signal,
enum clock_source_id clock_source, enum clock_source_id clock_source,
const struct dc_link_settings *link_settings) const struct dc_link_settings *link_settings)
...@@ -135,7 +136,7 @@ void dp_enable_link_phy( ...@@ -135,7 +136,7 @@ void dp_enable_link_phy(
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) { if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
enable_dp_hpo_output(link, link_settings); enable_dp_hpo_output(link, link_res, link_settings);
} else if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) { } else if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
if (dc_is_dp_sst_signal(signal)) { if (dc_is_dp_sst_signal(signal)) {
link_enc->funcs->enable_dp_output( link_enc->funcs->enable_dp_output(
...@@ -236,7 +237,8 @@ bool edp_receiver_ready_T7(struct dc_link *link) ...@@ -236,7 +237,8 @@ bool edp_receiver_ready_T7(struct dc_link *link)
return result; return result;
} }
void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_res,
enum signal_type signal)
{ {
struct dc *dc = link->ctx->dc; struct dc *dc = link->ctx->dc;
struct dmcu *dmcu = dc->res_pool->dmcu; struct dmcu *dmcu = dc->res_pool->dmcu;
...@@ -260,7 +262,7 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) ...@@ -260,7 +262,7 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
link->dc->hwss.edp_backlight_control(link, false); link->dc->hwss.edp_backlight_control(link, false);
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING) if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING)
disable_dp_hpo_output(link, signal); disable_dp_hpo_output(link, link_res, signal);
else else
link_enc->funcs->disable_output(link_enc, signal); link_enc->funcs->disable_output(link_enc, signal);
#else #else
...@@ -274,7 +276,7 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) ...@@ -274,7 +276,7 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING && if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING &&
hpo_link_enc) hpo_link_enc)
disable_dp_hpo_output(link, signal); disable_dp_hpo_output(link, link_res, signal);
else else
link_enc->funcs->disable_output(link_enc, signal); link_enc->funcs->disable_output(link_enc, signal);
#else #else
...@@ -294,13 +296,14 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) ...@@ -294,13 +296,14 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link); dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
} }
void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal) void dp_disable_link_phy_mst(struct dc_link *link, const struct link_resource *link_res,
enum signal_type signal)
{ {
/* MST disable link only when no stream use the link */ /* MST disable link only when no stream use the link */
if (link->mst_stream_alloc_table.stream_count > 0) if (link->mst_stream_alloc_table.stream_count > 0)
return; return;
dp_disable_link_phy(link, signal); dp_disable_link_phy(link, link_res, signal);
/* set the sink to SST mode after disabling the link */ /* set the sink to SST mode after disabling the link */
dp_enable_mst_on_sink(link, false); dp_enable_mst_on_sink(link, false);
...@@ -308,6 +311,7 @@ void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal) ...@@ -308,6 +311,7 @@ void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal)
bool dp_set_hw_training_pattern( bool dp_set_hw_training_pattern(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
enum dc_dp_training_pattern pattern, enum dc_dp_training_pattern pattern,
uint32_t offset) uint32_t offset)
{ {
...@@ -338,7 +342,7 @@ bool dp_set_hw_training_pattern( ...@@ -338,7 +342,7 @@ bool dp_set_hw_training_pattern(
break; break;
} }
dp_set_hw_test_pattern(link, test_pattern, NULL, 0); dp_set_hw_test_pattern(link, link_res, test_pattern, NULL, 0);
return true; return true;
} }
...@@ -349,6 +353,7 @@ bool dp_set_hw_training_pattern( ...@@ -349,6 +353,7 @@ bool dp_set_hw_training_pattern(
#endif #endif
void dp_set_hw_lane_settings( void dp_set_hw_lane_settings(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
const struct link_training_settings *link_settings, const struct link_training_settings *link_settings,
uint32_t offset) uint32_t offset)
{ {
...@@ -379,6 +384,7 @@ void dp_set_hw_lane_settings( ...@@ -379,6 +384,7 @@ void dp_set_hw_lane_settings(
void dp_set_hw_test_pattern( void dp_set_hw_test_pattern(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
enum dp_test_pattern test_pattern, enum dp_test_pattern test_pattern,
uint8_t *custom_pattern, uint8_t *custom_pattern,
uint32_t custom_pattern_size) uint32_t custom_pattern_size)
...@@ -446,7 +452,7 @@ void dp_retrain_link_dp_test(struct dc_link *link, ...@@ -446,7 +452,7 @@ void dp_retrain_link_dp_test(struct dc_link *link,
pipes[i].stream_res.stream_enc); pipes[i].stream_res.stream_enc);
/* disable any test pattern that might be active */ /* disable any test pattern that might be active */
dp_set_hw_test_pattern(link, dp_set_hw_test_pattern(link, &pipes[i].link_res,
DP_TEST_PATTERN_VIDEO_MODE, NULL, 0); DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
dp_receiver_power_ctrl(link, false); dp_receiver_power_ctrl(link, false);
...@@ -763,7 +769,9 @@ static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link) ...@@ -763,7 +769,9 @@ static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link)
} }
} }
void enable_dp_hpo_output(struct dc_link *link, const struct dc_link_settings *link_settings) void enable_dp_hpo_output(struct dc_link *link,
const struct link_resource *link_res,
const struct dc_link_settings *link_settings)
{ {
const struct dc *dc = link->dc; const struct dc *dc = link->dc;
enum phyd32clk_clock_source phyd32clk; enum phyd32clk_clock_source phyd32clk;
...@@ -814,7 +822,9 @@ void enable_dp_hpo_output(struct dc_link *link, const struct dc_link_settings *l ...@@ -814,7 +822,9 @@ void enable_dp_hpo_output(struct dc_link *link, const struct dc_link_settings *l
} }
} }
void disable_dp_hpo_output(struct dc_link *link, enum signal_type signal) void disable_dp_hpo_output(struct dc_link *link,
const struct link_resource *link_res,
enum signal_type signal)
{ {
const struct dc *dc = link->dc; const struct dc *dc = link->dc;
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include "dc_types.h" #include "dc_types.h"
#include "grph_object_defs.h" #include "grph_object_defs.h"
struct link_resource;
enum dc_link_fec_state { enum dc_link_fec_state {
dc_link_fec_not_ready, dc_link_fec_not_ready,
dc_link_fec_ready, dc_link_fec_ready,
...@@ -359,14 +361,17 @@ void dc_link_remove_remote_sink( ...@@ -359,14 +361,17 @@ void dc_link_remove_remote_sink(
void dc_link_dp_set_drive_settings( void dc_link_dp_set_drive_settings(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings); struct link_training_settings *lt_settings);
bool dc_link_dp_perform_link_training_skip_aux( bool dc_link_dp_perform_link_training_skip_aux(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
const struct dc_link_settings *link_setting); const struct dc_link_settings *link_setting);
enum link_training_result dc_link_dp_perform_link_training( enum link_training_result dc_link_dp_perform_link_training(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
const struct dc_link_settings *link_settings, const struct dc_link_settings *link_settings,
bool skip_video_pattern); bool skip_video_pattern);
...@@ -374,6 +379,7 @@ bool dc_link_dp_sync_lt_begin(struct dc_link *link); ...@@ -374,6 +379,7 @@ bool dc_link_dp_sync_lt_begin(struct dc_link *link);
enum link_training_result dc_link_dp_sync_lt_attempt( enum link_training_result dc_link_dp_sync_lt_attempt(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct dc_link_settings *link_setting, struct dc_link_settings *link_setting,
struct dc_link_training_overrides *lt_settings); struct dc_link_training_overrides *lt_settings);
...@@ -454,4 +460,6 @@ bool dc_link_should_enable_fec(const struct dc_link *link); ...@@ -454,4 +460,6 @@ bool dc_link_should_enable_fec(const struct dc_link *link);
uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw); uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw);
enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link); enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
#endif #endif
const struct link_resource *dc_link_get_cur_link_res(const struct dc_link *link);
#endif /* DC_LINK_H_ */ #endif /* DC_LINK_H_ */
...@@ -334,6 +334,11 @@ struct plane_resource { ...@@ -334,6 +334,11 @@ struct plane_resource {
struct dcn_fe_bandwidth bw; struct dcn_fe_bandwidth bw;
}; };
/* all mappable hardware resources used to enable a link */
struct link_resource {
void *dummy;
};
union pipe_update_flags { union pipe_update_flags {
struct { struct {
uint32_t enable : 1; uint32_t enable : 1;
...@@ -361,6 +366,7 @@ struct pipe_ctx { ...@@ -361,6 +366,7 @@ struct pipe_ctx {
struct plane_resource plane_res; struct plane_resource plane_res;
struct stream_resource stream_res; struct stream_resource stream_res;
struct link_resource link_res;
struct clock_source *clock_source; struct clock_source *clock_source;
......
...@@ -56,16 +56,19 @@ enum { ...@@ -56,16 +56,19 @@ enum {
bool dp_verify_link_cap( bool dp_verify_link_cap(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct dc_link_settings *known_limit_link_setting, struct dc_link_settings *known_limit_link_setting,
int *fail_count); int *fail_count);
bool dp_verify_link_cap_with_retries( bool dp_verify_link_cap_with_retries(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
struct dc_link_settings *known_limit_link_setting, struct dc_link_settings *known_limit_link_setting,
int attempts); int attempts);
bool dp_verify_mst_link_cap( bool dp_verify_mst_link_cap(
struct dc_link *link); struct dc_link *link,
const struct link_resource *link_res);
bool dp_validate_mode_timing( bool dp_validate_mode_timing(
struct dc_link *link, struct dc_link *link,
...@@ -168,7 +171,7 @@ uint8_t dc_dp_initialize_scrambling_data_symbols( ...@@ -168,7 +171,7 @@ uint8_t dc_dp_initialize_scrambling_data_symbols(
struct dc_link *link, struct dc_link *link,
enum dc_dp_training_pattern pattern); enum dc_dp_training_pattern pattern);
enum dc_status dp_set_fec_ready(struct dc_link *link, bool ready); enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready);
void dp_set_fec_enable(struct dc_link *link, bool enable); void dp_set_fec_enable(struct dc_link *link, bool enable);
struct link_encoder *dp_get_link_enc(struct dc_link *link); struct link_encoder *dp_get_link_enc(struct dc_link *link);
bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable); bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable);
...@@ -211,8 +214,12 @@ bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link); ...@@ -211,8 +214,12 @@ bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link);
struct fixed31_32 calculate_sst_avg_time_slots_per_mtp( struct fixed31_32 calculate_sst_avg_time_slots_per_mtp(
const struct dc_stream_state *stream, const struct dc_stream_state *stream,
const struct dc_link *link); const struct dc_link *link);
void enable_dp_hpo_output(struct dc_link *link, const struct dc_link_settings *link_settings); void enable_dp_hpo_output(struct dc_link *link,
void disable_dp_hpo_output(struct dc_link *link, enum signal_type signal); const struct link_resource *link_res,
const struct dc_link_settings *link_settings);
void disable_dp_hpo_output(struct dc_link *link,
const struct link_resource *link_res,
enum signal_type signal);
void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable); void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable);
bool is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx); bool is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx);
void reset_dp_hpo_stream_encoders_for_link(struct dc_link *link); void reset_dp_hpo_stream_encoders_for_link(struct dc_link *link);
......
...@@ -91,8 +91,9 @@ enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link); ...@@ -91,8 +91,9 @@ enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link);
* DPIA equivalent of dc_link_dp_perfrorm_link_training. * DPIA equivalent of dc_link_dp_perfrorm_link_training.
* Aborts link training upon detection of sink unplug. * Aborts link training upon detection of sink unplug.
*/ */
enum link_training_result enum link_training_result dc_link_dpia_perform_link_training(
dc_link_dpia_perform_link_training(struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
const struct dc_link_settings *link_setting, const struct dc_link_settings *link_setting,
bool skip_video_pattern); bool skip_video_pattern);
......
...@@ -32,6 +32,7 @@ struct gpio *get_hpd_gpio(struct dc_bios *dcb, ...@@ -32,6 +32,7 @@ struct gpio *get_hpd_gpio(struct dc_bios *dcb,
void dp_enable_link_phy( void dp_enable_link_phy(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
enum signal_type signal, enum signal_type signal,
enum clock_source_id clock_source, enum clock_source_id clock_source,
const struct dc_link_settings *link_settings); const struct dc_link_settings *link_settings);
...@@ -42,22 +43,27 @@ void edp_add_delay_for_T9(struct dc_link *link); ...@@ -42,22 +43,27 @@ void edp_add_delay_for_T9(struct dc_link *link);
bool edp_receiver_ready_T9(struct dc_link *link); bool edp_receiver_ready_T9(struct dc_link *link);
bool edp_receiver_ready_T7(struct dc_link *link); bool edp_receiver_ready_T7(struct dc_link *link);
void dp_disable_link_phy(struct dc_link *link, enum signal_type signal); void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_res,
enum signal_type signal);
void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal); void dp_disable_link_phy_mst(struct dc_link *link, const struct link_resource *link_res,
enum signal_type signal);
bool dp_set_hw_training_pattern( bool dp_set_hw_training_pattern(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
enum dc_dp_training_pattern pattern, enum dc_dp_training_pattern pattern,
uint32_t offset); uint32_t offset);
void dp_set_hw_lane_settings( void dp_set_hw_lane_settings(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
const struct link_training_settings *link_settings, const struct link_training_settings *link_settings,
uint32_t offset); uint32_t offset);
void dp_set_hw_test_pattern( void dp_set_hw_test_pattern(
struct dc_link *link, struct dc_link *link,
const struct link_resource *link_res,
enum dp_test_pattern test_pattern, enum dp_test_pattern test_pattern,
uint8_t *custom_pattern, uint8_t *custom_pattern,
uint32_t custom_pattern_size); uint32_t custom_pattern_size);
......
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