Commit e0a6440a authored by David Galiffi's avatar David Galiffi Committed by Alex Deucher

drm/amd/display: Add ability to set preferred link training parameters.

[WHY]
To add support for OS requirement to set preferred link training
parameters.

[HOW]
Create new structure of dp link training overrides. During link training
processes, these values should be used instead of the default training
parameters.
Signed-off-by: default avatarDavid Galiffi <David.Galiffi@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarAnthony Koo <Anthony.Koo@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 93c25fbd
...@@ -1189,6 +1189,9 @@ static bool construct( ...@@ -1189,6 +1189,9 @@ static bool construct(
link->ctx = dc_ctx; link->ctx = dc_ctx;
link->link_index = init_params->link_index; link->link_index = init_params->link_index;
memset(&link->preferred_training_settings, 0, sizeof(struct dc_link_training_overrides));
memset(&link->preferred_link_setting, 0, sizeof(struct dc_link_settings));
link->link_id = bios->funcs->get_connector_id(bios, init_params->connector_index); link->link_id = bios->funcs->get_connector_id(bios, init_params->connector_index);
if (link->link_id.type != OBJECT_TYPE_CONNECTOR) { if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
...@@ -1467,6 +1470,9 @@ static enum dc_status enable_link_dp( ...@@ -1467,6 +1470,9 @@ static enum dc_status enable_link_dp(
struct dc_link *link = stream->link; struct dc_link *link = stream->link;
struct dc_link_settings link_settings = {0}; struct dc_link_settings link_settings = {0};
enum dp_panel_mode panel_mode; enum dp_panel_mode panel_mode;
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
bool fec_enable;
#endif
/* get link settings for video mode timing */ /* get link settings for video mode timing */
decide_link_settings(stream, &link_settings); decide_link_settings(stream, &link_settings);
...@@ -1511,10 +1517,20 @@ static enum dc_status enable_link_dp( ...@@ -1511,10 +1517,20 @@ static enum dc_status enable_link_dp(
skip_video_pattern = false; skip_video_pattern = false;
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
dp_set_fec_ready(link, true); if (link->preferred_training_settings.fec_enable != NULL)
fec_enable = *link->preferred_training_settings.fec_enable;
else
fec_enable = true;
dp_set_fec_ready(link, fec_enable);
#endif #endif
if (perform_link_training_with_retries( if (link->aux_access_disabled) {
dc_link_dp_perform_link_training_skip_aux(link, &link_settings);
link->cur_link_settings = link_settings;
status = DC_OK;
} else if (perform_link_training_with_retries(
link, link,
&link_settings, &link_settings,
skip_video_pattern, skip_video_pattern,
...@@ -1526,7 +1542,7 @@ static enum dc_status enable_link_dp( ...@@ -1526,7 +1542,7 @@ static enum dc_status enable_link_dp(
status = DC_FAIL_DP_LINK_TRAINING; status = DC_FAIL_DP_LINK_TRAINING;
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
dp_set_fec_enable(link, true); dp_set_fec_enable(link, fec_enable);
#endif #endif
return status; return status;
} }
...@@ -3014,6 +3030,29 @@ void dc_link_set_preferred_link_settings(struct dc *dc, ...@@ -3014,6 +3030,29 @@ void dc_link_set_preferred_link_settings(struct dc *dc,
dp_retrain_link_dp_test(link, &store_settings, false); dp_retrain_link_dp_test(link, &store_settings, false);
} }
void dc_link_set_preferred_training_settings(struct dc *dc,
struct dc_link_settings *link_setting,
struct dc_link_training_overrides *lt_overrides,
struct dc_link *link,
bool skip_immediate_retrain)
{
if (lt_overrides != NULL)
link->preferred_training_settings = *lt_overrides;
else
memset(&link->preferred_training_settings, 0, sizeof(link->preferred_training_settings));
if (link_setting != NULL) {
link->preferred_link_setting = *link_setting;
} else {
link->preferred_link_setting.lane_count = LANE_COUNT_UNKNOWN;
link->preferred_link_setting.link_rate = LINK_RATE_UNKNOWN;
}
/* Retrain now, or wait until next stream update to apply */
if (skip_immediate_retrain == false)
dc_link_set_preferred_link_settings(dc, &link->preferred_link_setting, link);
}
void dc_link_enable_hpd(const struct dc_link *link) void dc_link_enable_hpd(const struct dc_link *link)
{ {
dc_link_dp_enable_hpd(link); dc_link_dp_enable_hpd(link);
...@@ -3024,7 +3063,6 @@ void dc_link_disable_hpd(const struct dc_link *link) ...@@ -3024,7 +3063,6 @@ void dc_link_disable_hpd(const struct dc_link *link)
dc_link_dp_disable_hpd(link); dc_link_dp_disable_hpd(link);
} }
void dc_link_set_test_pattern(struct dc_link *link, void dc_link_set_test_pattern(struct dc_link *link,
enum dp_test_pattern test_pattern, enum dp_test_pattern test_pattern,
const struct link_training_settings *p_link_settings, const struct link_training_settings *p_link_settings,
......
...@@ -25,10 +25,11 @@ enum dc_status core_link_read_dpcd( ...@@ -25,10 +25,11 @@ enum dc_status core_link_read_dpcd(
uint8_t *data, uint8_t *data,
uint32_t size) uint32_t size)
{ {
if (!dm_helpers_dp_read_dpcd(link->ctx, if (!link->aux_access_disabled &&
link, !dm_helpers_dp_read_dpcd(link->ctx,
address, data, size)) link, address, data, size)) {
return DC_ERROR_UNEXPECTED; return DC_ERROR_UNEXPECTED;
}
return DC_OK; return DC_OK;
} }
...@@ -39,10 +40,11 @@ enum dc_status core_link_write_dpcd( ...@@ -39,10 +40,11 @@ enum dc_status core_link_write_dpcd(
const uint8_t *data, const uint8_t *data,
uint32_t size) uint32_t size)
{ {
if (!dm_helpers_dp_write_dpcd(link->ctx, if (!link->aux_access_disabled &&
link, !dm_helpers_dp_write_dpcd(link->ctx,
address, data, size)) link, address, data, size)) {
return DC_ERROR_UNEXPECTED; return DC_ERROR_UNEXPECTED;
}
return DC_OK; return DC_OK;
} }
...@@ -203,21 +205,21 @@ void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal) ...@@ -203,21 +205,21 @@ 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,
enum hw_dp_training_pattern pattern) enum dc_dp_training_pattern pattern)
{ {
enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED; enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
switch (pattern) { switch (pattern) {
case HW_DP_TRAINING_PATTERN_1: case DP_TRAINING_PATTERN_SEQUENCE_1:
test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN1; test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN1;
break; break;
case HW_DP_TRAINING_PATTERN_2: case DP_TRAINING_PATTERN_SEQUENCE_2:
test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN2; test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN2;
break; break;
case HW_DP_TRAINING_PATTERN_3: case DP_TRAINING_PATTERN_SEQUENCE_3:
test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN3; test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN3;
break; break;
case HW_DP_TRAINING_PATTERN_4: case DP_TRAINING_PATTERN_SEQUENCE_4:
test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4; test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
break; break;
default: default:
......
...@@ -90,6 +90,13 @@ enum dc_post_cursor2 { ...@@ -90,6 +90,13 @@ enum dc_post_cursor2 {
POST_CURSOR2_MAX_LEVEL = POST_CURSOR2_LEVEL3, POST_CURSOR2_MAX_LEVEL = POST_CURSOR2_LEVEL3,
}; };
enum dc_dp_training_pattern {
DP_TRAINING_PATTERN_SEQUENCE_1 = 0,
DP_TRAINING_PATTERN_SEQUENCE_2,
DP_TRAINING_PATTERN_SEQUENCE_3,
DP_TRAINING_PATTERN_SEQUENCE_4,
};
struct dc_link_settings { struct dc_link_settings {
enum dc_lane_count lane_count; enum dc_lane_count lane_count;
enum dc_link_rate link_rate; enum dc_link_rate link_rate;
...@@ -109,6 +116,20 @@ struct dc_link_training_settings { ...@@ -109,6 +116,20 @@ struct dc_link_training_settings {
struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]; struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX];
}; };
struct dc_link_training_overrides {
enum dc_voltage_swing *voltage_swing;
enum dc_pre_emphasis *pre_emphasis;
enum dc_post_cursor2 *post_cursor2;
uint16_t *cr_pattern_time;
uint16_t *eq_pattern_time;
enum dc_dp_training_pattern *pattern_for_eq;
enum dc_link_spread *downspread;
bool *alternate_scrambler_reset;
bool *enhanced_framing;
bool *fec_enable;
};
union dpcd_rev { union dpcd_rev {
struct { struct {
......
...@@ -83,6 +83,7 @@ struct dc_link { ...@@ -83,6 +83,7 @@ struct dc_link {
bool is_hpd_filter_disabled; bool is_hpd_filter_disabled;
bool dp_ss_off; bool dp_ss_off;
bool link_state_valid; bool link_state_valid;
bool aux_access_disabled;
/* caps is the same as reported_link_cap. link_traing use /* caps is the same as reported_link_cap. link_traing use
* reported_link_cap. Will clean up. TODO * reported_link_cap. Will clean up. TODO
...@@ -92,6 +93,7 @@ struct dc_link { ...@@ -92,6 +93,7 @@ struct dc_link {
struct dc_link_settings cur_link_settings; struct dc_link_settings cur_link_settings;
struct dc_lane_settings cur_lane_setting; struct dc_lane_settings cur_lane_setting;
struct dc_link_settings preferred_link_setting; struct dc_link_settings preferred_link_setting;
struct dc_link_training_overrides preferred_training_settings;
uint8_t ddc_hw_inst; uint8_t ddc_hw_inst;
...@@ -217,6 +219,10 @@ void dc_link_dp_set_drive_settings( ...@@ -217,6 +219,10 @@ void dc_link_dp_set_drive_settings(
struct dc_link *link, struct dc_link *link,
struct link_training_settings *lt_settings); struct link_training_settings *lt_settings);
bool dc_link_dp_perform_link_training_skip_aux(
struct dc_link *link,
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 dc_link_settings *link_setting, const struct dc_link_settings *link_setting,
...@@ -251,6 +257,11 @@ void dc_link_perform_link_training(struct dc *dc, ...@@ -251,6 +257,11 @@ void dc_link_perform_link_training(struct dc *dc,
void dc_link_set_preferred_link_settings(struct dc *dc, void dc_link_set_preferred_link_settings(struct dc *dc,
struct dc_link_settings *link_setting, struct dc_link_settings *link_setting,
struct dc_link *link); struct dc_link *link);
void dc_link_set_preferred_training_settings(struct dc *dc,
struct dc_link_settings *link_setting,
struct dc_link_training_overrides *lt_overrides,
struct dc_link *link,
bool skip_immediate_retrain);
void dc_link_enable_hpd(const struct dc_link *link); void dc_link_enable_hpd(const struct dc_link *link);
void dc_link_disable_hpd(const struct dc_link *link); void dc_link_disable_hpd(const struct dc_link *link);
void dc_link_set_test_pattern(struct dc_link *link, void dc_link_set_test_pattern(struct dc_link *link,
......
...@@ -60,7 +60,7 @@ void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal); ...@@ -60,7 +60,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,
enum hw_dp_training_pattern pattern); enum dc_dp_training_pattern pattern);
void dp_set_hw_lane_settings( void dp_set_hw_lane_settings(
struct dc_link *link, struct dc_link *link,
......
...@@ -71,14 +71,17 @@ enum link_training_result { ...@@ -71,14 +71,17 @@ enum link_training_result {
struct link_training_settings { struct link_training_settings {
struct dc_link_settings link_settings; struct dc_link_settings link_settings;
struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]; struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX];
bool allow_invalid_msa_timing_param;
};
enum hw_dp_training_pattern { enum dc_voltage_swing *voltage_swing;
HW_DP_TRAINING_PATTERN_1 = 0, enum dc_pre_emphasis *pre_emphasis;
HW_DP_TRAINING_PATTERN_2, enum dc_post_cursor2 *post_cursor2;
HW_DP_TRAINING_PATTERN_3,
HW_DP_TRAINING_PATTERN_4 uint16_t cr_pattern_time;
uint16_t eq_pattern_time;
enum dc_dp_training_pattern pattern_for_eq;
bool enhanced_framing;
bool allow_invalid_msa_timing_param;
}; };
/*TODO: Move this enum test harness*/ /*TODO: Move this enum test harness*/
......
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