Commit 0b226322 authored by David Galiffi's avatar David Galiffi Committed by Alex Deucher

drm/amd/display: Synchronous DisplayPort Link Training

[WHY]
We require a method to perform synchronous link training.

[HOW]
Sync LT is broken into 3 basic steps.
"Begin" starts the state machine, and resets "preferred" link settings.
"Attempt" will attempt to train the link with a given set of training
parameters.
"End" stops the state machine, and will optionally disable the link phy.
Between "Begin" and "End" DPCD:600h must not be set to "2"
(D3:Powered Down).
Between "Begin" and "End", there may be multiple "Attempts" with different
training parameters.
Signed-off-by: default avatarDavid Galiffi <david.galiffi@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 36756dcb
......@@ -1387,57 +1387,6 @@ void link_destroy(struct dc_link **link)
*link = NULL;
}
static void dpcd_configure_panel_mode(
struct dc_link *link,
enum dp_panel_mode panel_mode)
{
union dpcd_edp_config edp_config_set;
bool panel_mode_edp = false;
DC_LOGGER_INIT(link->ctx->logger);
memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config));
if (DP_PANEL_MODE_DEFAULT != panel_mode) {
switch (panel_mode) {
case DP_PANEL_MODE_EDP:
case DP_PANEL_MODE_SPECIAL:
panel_mode_edp = true;
break;
default:
break;
}
/*set edp panel mode in receiver*/
core_link_read_dpcd(
link,
DP_EDP_CONFIGURATION_SET,
&edp_config_set.raw,
sizeof(edp_config_set.raw));
if (edp_config_set.bits.PANEL_MODE_EDP
!= panel_mode_edp) {
enum ddc_result result = DDC_RESULT_UNKNOWN;
edp_config_set.bits.PANEL_MODE_EDP =
panel_mode_edp;
result = core_link_write_dpcd(
link,
DP_EDP_CONFIGURATION_SET,
&edp_config_set.raw,
sizeof(edp_config_set.raw));
ASSERT(result == DDC_RESULT_SUCESSFULL);
}
}
DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d "
"eDP panel mode enabled: %d \n",
link->link_index,
link->dpcd_caps.panel_mode_edp,
panel_mode_edp);
}
static void enable_stream_features(struct pipe_ctx *pipe_ctx)
{
struct dc_stream_state *stream = pipe_ctx->stream;
......@@ -1508,7 +1457,7 @@ static enum dc_status enable_link_dp(
}
panel_mode = dp_get_panel_mode(link);
dpcd_configure_panel_mode(link, panel_mode);
dp_set_panel_mode(link, panel_mode);
skip_video_pattern = true;
......
......@@ -55,6 +55,9 @@ void dp_receiver_power_ctrl(struct dc_link *link, bool on)
state = on ? DP_POWER_STATE_D0 : DP_POWER_STATE_D3;
if (link->sync_lt_in_progress)
return;
core_link_write_dpcd(link, DP_SET_POWER, &state,
sizeof(state));
}
......@@ -245,46 +248,6 @@ void dp_set_hw_lane_settings(
encoder->funcs->dp_set_lane_settings(encoder, link_settings);
}
enum dp_panel_mode dp_get_panel_mode(struct dc_link *link)
{
/* We need to explicitly check that connector
* is not DP. Some Travis_VGA get reported
* by video bios as DP.
*/
if (link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
switch (link->dpcd_caps.branch_dev_id) {
case DP_BRANCH_DEVICE_ID_2:
if (strncmp(
link->dpcd_caps.branch_dev_name,
DP_VGA_LVDS_CONVERTER_ID_2,
sizeof(
link->dpcd_caps.
branch_dev_name)) == 0) {
return DP_PANEL_MODE_SPECIAL;
}
break;
case DP_BRANCH_DEVICE_ID_3:
if (strncmp(link->dpcd_caps.branch_dev_name,
DP_VGA_LVDS_CONVERTER_ID_3,
sizeof(
link->dpcd_caps.
branch_dev_name)) == 0) {
return DP_PANEL_MODE_SPECIAL;
}
break;
default:
break;
}
}
if (link->dpcd_caps.panel_mode_edp) {
return DP_PANEL_MODE_EDP;
}
return DP_PANEL_MODE_DEFAULT;
}
void dp_set_hw_test_pattern(
struct dc_link *link,
enum dp_test_pattern test_pattern,
......
......@@ -128,7 +128,10 @@ struct dc_link_training_overrides {
enum dc_link_spread *downspread;
bool *alternate_scrambler_reset;
bool *enhanced_framing;
bool *mst_enable;
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
bool *fec_enable;
#endif
};
union dpcd_rev {
......
......@@ -84,6 +84,7 @@ struct dc_link {
bool dp_ss_off;
bool link_state_valid;
bool aux_access_disabled;
bool sync_lt_in_progress;
/* caps is the same as reported_link_cap. link_traing use
* reported_link_cap. Will clean up. TODO
......@@ -228,6 +229,15 @@ enum link_training_result dc_link_dp_perform_link_training(
const struct dc_link_settings *link_setting,
bool skip_video_pattern);
bool dc_link_dp_sync_lt_begin(struct dc_link *link);
enum link_training_result dc_link_dp_sync_lt_attempt(
struct dc_link *link,
struct dc_link_settings *link_setting,
struct dc_link_training_overrides *lt_settings);
bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down);
void dc_link_dp_enable_hpd(const struct dc_link *link);
void dc_link_dp_disable_hpd(const struct dc_link *link);
......
......@@ -62,6 +62,9 @@ bool is_dp_active_dongle(const struct dc_link *link);
void dp_enable_mst_on_sink(struct dc_link *link, bool enable);
enum dp_panel_mode dp_get_panel_mode(struct dc_link *link);
void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode);
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
void dp_set_fec_ready(struct dc_link *link, bool ready);
void dp_set_fec_enable(struct dc_link *link, bool enable);
......
......@@ -72,8 +72,6 @@ void dp_set_hw_test_pattern(
uint8_t *custom_pattern,
uint32_t custom_pattern_size);
enum dp_panel_mode dp_get_panel_mode(struct dc_link *link);
void dp_retrain_link_dp_test(struct dc_link *link,
struct dc_link_settings *link_setting,
bool skip_video_pattern);
......
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