Commit e844cc25 authored by Michael Strauss's avatar Michael Strauss Committed by Alex Deucher

drm/amd/display: Refactor LTTPR mode selection

[WHY]
Previously, LTTPR mode was decided during detection which makes
link training inflexible as mode can't be dynamically changed.

[HOW]
-Remove lttpr_mode from link struct, and move to link training settings
-Defer choosing LTTPR mode until link training

Other DP changes included:
-Only use fixed vs/pe link training sequence for 8b/10b encoding
-Restrict fixed vs aux timeout workaround to Yellow Carp family
Reviewed-by: default avatarWenjing Liu <Wenjing.Liu@amd.com>
Signed-off-by: default avatarMichael Strauss <michael.strauss@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ce438e99
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#include "dc_link_ddc.h" #include "dc_link_ddc.h"
#include "dce/dce_aux.h" #include "dce/dce_aux.h"
#include "dmub/inc/dmub_cmd.h" #include "dmub/inc/dmub_cmd.h"
#include "link_dpcd.h"
#include "include/dal_asic_id.h"
#define DC_LOGGER_INIT(logger) #define DC_LOGGER_INIT(logger)
...@@ -683,6 +685,21 @@ bool dc_link_aux_try_to_configure_timeout(struct ddc_service *ddc, ...@@ -683,6 +685,21 @@ bool dc_link_aux_try_to_configure_timeout(struct ddc_service *ddc,
bool result = false; bool result = false;
struct ddc *ddc_pin = ddc->ddc_pin; struct ddc *ddc_pin = ddc->ddc_pin;
if ((ddc->link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
!ddc->link->dc->debug.disable_fixed_vs_aux_timeout_wa &&
ASICREV_IS_YELLOW_CARP(ddc->ctx->asic_id.hw_internal_rev)) {
/* Fixed VS workaround for AUX timeout */
const uint32_t fixed_vs_address = 0xF004F;
const uint8_t fixed_vs_data[4] = {0x1, 0x22, 0x63, 0xc};
core_link_write_dpcd(ddc->link,
fixed_vs_address,
fixed_vs_data,
sizeof(fixed_vs_data));
timeout = 3072;
}
/* Do not try to access nonexistent DDC pin. */ /* Do not try to access nonexistent DDC pin. */
if (ddc->link->ep_type != DISPLAY_ENDPOINT_PHY) if (ddc->link->ep_type != DISPLAY_ENDPOINT_PHY)
return true; return true;
...@@ -691,6 +708,7 @@ bool dc_link_aux_try_to_configure_timeout(struct ddc_service *ddc, ...@@ -691,6 +708,7 @@ bool dc_link_aux_try_to_configure_timeout(struct ddc_service *ddc,
ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout); ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout);
result = true; result = true;
} }
return result; return result;
} }
......
...@@ -115,12 +115,14 @@ static enum link_training_result dpia_configure_link( ...@@ -115,12 +115,14 @@ static enum link_training_result dpia_configure_link(
DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) configuring\n - LTTPR mode(%d)\n", DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) configuring\n - LTTPR mode(%d)\n",
__func__, __func__,
link->link_id.enum_id - ENUM_ID_1, link->link_id.enum_id - ENUM_ID_1,
link->lttpr_mode); lt_settings->lttpr_mode);
dp_decide_training_settings(link, dp_decide_training_settings(link,
link_setting, link_setting,
lt_settings); lt_settings);
dp_get_lttpr_mode_override(link, &lt_settings->lttpr_mode);
status = dpcd_configure_channel_coding(link, lt_settings); status = dpcd_configure_channel_coding(link, lt_settings);
if (status != DC_OK && link->is_hpd_pending) if (status != DC_OK && link->is_hpd_pending)
return LINK_TRAINING_ABORT; return LINK_TRAINING_ABORT;
...@@ -178,7 +180,7 @@ static uint8_t dpia_build_set_config_data(enum dpia_set_config_type type, ...@@ -178,7 +180,7 @@ static uint8_t dpia_build_set_config_data(enum dpia_set_config_type type,
switch (type) { switch (type) {
case DPIA_SET_CFG_SET_LINK: case DPIA_SET_CFG_SET_LINK:
data.set_link.mode = link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT ? 1 : 0; data.set_link.mode = lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT ? 1 : 0;
break; break;
case DPIA_SET_CFG_SET_PHY_TEST_MODE: case DPIA_SET_CFG_SET_PHY_TEST_MODE:
break; break;
...@@ -553,7 +555,7 @@ static enum link_training_result dpia_training_cr_phase( ...@@ -553,7 +555,7 @@ static enum link_training_result dpia_training_cr_phase(
{ {
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 (lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
result = dpia_training_cr_non_transparent(link, link_res, lt_settings, hop); result = dpia_training_cr_non_transparent(link, link_res, lt_settings, hop);
else else
result = dpia_training_cr_transparent(link, link_res, lt_settings); result = dpia_training_cr_transparent(link, link_res, lt_settings);
...@@ -830,7 +832,7 @@ static enum link_training_result dpia_training_eq_phase( ...@@ -830,7 +832,7 @@ static enum link_training_result dpia_training_eq_phase(
{ {
enum link_training_result result; enum link_training_result result;
if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) if (lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
result = dpia_training_eq_non_transparent(link, link_res, lt_settings, hop); result = dpia_training_eq_non_transparent(link, link_res, lt_settings, hop);
else else
result = dpia_training_eq_transparent(link, link_res, lt_settings); result = dpia_training_eq_transparent(link, link_res, lt_settings);
...@@ -870,13 +872,14 @@ static enum dc_status dpcd_clear_lt_pattern(struct dc_link *link, uint32_t hop) ...@@ -870,13 +872,14 @@ static enum dc_status dpcd_clear_lt_pattern(struct dc_link *link, uint32_t hop)
* @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_end(struct dc_link *link, static enum link_training_result dpia_training_end(struct dc_link *link,
struct link_training_settings *lt_settings,
uint32_t hop) uint32_t hop)
{ {
enum link_training_result result = LINK_TRAINING_SUCCESS; enum link_training_result result = LINK_TRAINING_SUCCESS;
uint8_t repeater_cnt = 0; /* Number of hops/repeaters in display path. */ uint8_t repeater_cnt = 0; /* Number of hops/repeaters in display path. */
enum dc_status status; enum dc_status status;
if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) { if (lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt); repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
if (hop == repeater_cnt) { /* DPTX-to-DPIA */ if (hop == repeater_cnt) { /* DPTX-to-DPIA */
...@@ -916,7 +919,7 @@ static enum link_training_result dpia_training_end(struct dc_link *link, ...@@ -916,7 +919,7 @@ static enum link_training_result dpia_training_end(struct dc_link *link,
link->link_id.enum_id - ENUM_ID_1, link->link_id.enum_id - ENUM_ID_1,
hop, hop,
result, result,
link->lttpr_mode); lt_settings->lttpr_mode);
return result; return result;
} }
...@@ -928,7 +931,9 @@ static enum link_training_result dpia_training_end(struct dc_link *link, ...@@ -928,7 +931,9 @@ static enum link_training_result dpia_training_end(struct dc_link *link,
* @param link DPIA link being trained. * @param link DPIA link being trained.
* @param hop The Hop in display path. DPRX = 0. * @param hop The Hop in display path. DPRX = 0.
*/ */
static void dpia_training_abort(struct dc_link *link, uint32_t hop) static void dpia_training_abort(struct dc_link *link,
struct link_training_settings *lt_settings,
uint32_t hop)
{ {
uint8_t data = 0; uint8_t data = 0;
uint32_t dpcd_tps_offset = DP_TRAINING_PATTERN_SET; uint32_t dpcd_tps_offset = DP_TRAINING_PATTERN_SET;
...@@ -936,7 +941,7 @@ static void dpia_training_abort(struct dc_link *link, uint32_t hop) ...@@ -936,7 +941,7 @@ static void dpia_training_abort(struct dc_link *link, uint32_t hop)
DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) aborting\n - LTTPR mode(%d)\n - HPD(%d)\n", DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) aborting\n - LTTPR mode(%d)\n - HPD(%d)\n",
__func__, __func__,
link->link_id.enum_id - ENUM_ID_1, link->link_id.enum_id - ENUM_ID_1,
link->lttpr_mode, lt_settings->lttpr_mode,
link->is_hpd_pending); link->is_hpd_pending);
/* Abandon clean-up if sink unplugged. */ /* Abandon clean-up if sink unplugged. */
...@@ -964,12 +969,16 @@ enum link_training_result dc_link_dpia_perform_link_training( ...@@ -964,12 +969,16 @@ enum link_training_result dc_link_dpia_perform_link_training(
uint8_t repeater_cnt = 0; /* Number of hops/repeaters in display path. */ uint8_t repeater_cnt = 0; /* Number of hops/repeaters in display path. */
int8_t repeater_id; /* Current hop. */ int8_t repeater_id; /* Current hop. */
struct dc_link_settings link_settings = *link_setting; // non-const copy to pass in
lt_settings.lttpr_mode = dp_decide_lttpr_mode(link, &link_settings);
/* 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_res, 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;
if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) if (lt_settings.lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt); repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
/* Train each hop in turn starting with the one closest to DPTX. /* Train each hop in turn starting with the one closest to DPTX.
...@@ -987,7 +996,7 @@ enum link_training_result dc_link_dpia_perform_link_training( ...@@ -987,7 +996,7 @@ enum link_training_result dc_link_dpia_perform_link_training(
break; break;
/* Stop training hop. */ /* Stop training hop. */
result = dpia_training_end(link, repeater_id); result = dpia_training_end(link, &lt_settings, repeater_id);
if (result != LINK_TRAINING_SUCCESS) if (result != LINK_TRAINING_SUCCESS)
break; break;
} }
...@@ -1001,9 +1010,9 @@ enum link_training_result dc_link_dpia_perform_link_training( ...@@ -1001,9 +1010,9 @@ enum link_training_result dc_link_dpia_perform_link_training(
msleep(5); msleep(5);
result = dp_check_link_loss_status(link, &lt_settings); result = dp_check_link_loss_status(link, &lt_settings);
} else if (result == LINK_TRAINING_ABORT) { } else if (result == LINK_TRAINING_ABORT) {
dpia_training_abort(link, repeater_id); dpia_training_abort(link, &lt_settings, repeater_id);
} else { } else {
dpia_training_end(link, repeater_id); dpia_training_end(link, &lt_settings, repeater_id);
} }
return result; return result;
} }
...@@ -157,7 +157,6 @@ struct dc_link { ...@@ -157,7 +157,6 @@ struct dc_link {
bool link_state_valid; bool link_state_valid;
bool aux_access_disabled; bool aux_access_disabled;
bool sync_lt_in_progress; bool sync_lt_in_progress;
enum lttpr_mode lttpr_mode;
bool is_internal_display; bool is_internal_display;
/* TODO: Rename. Flag an endpoint as having a programmable mapping to a /* TODO: Rename. Flag an endpoint as having a programmable mapping to a
......
...@@ -194,6 +194,11 @@ enum dc_status dpcd_configure_lttpr_mode( ...@@ -194,6 +194,11 @@ enum dc_status dpcd_configure_lttpr_mode(
enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings *link_settings); enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings *link_settings);
bool dp_retrieve_lttpr_cap(struct dc_link *link); bool dp_retrieve_lttpr_cap(struct dc_link *link);
bool dp_is_lttpr_present(struct dc_link *link);
enum lttpr_mode dp_decide_lttpr_mode(struct dc_link *link, struct dc_link_settings *link_setting);
void dp_get_lttpr_mode_override(struct dc_link *link, enum lttpr_mode *override);
enum lttpr_mode dp_decide_8b_10b_lttpr_mode(struct dc_link *link);
enum lttpr_mode dp_decide_128b_132b_lttpr_mode(struct dc_link *link);
bool dpcd_write_128b_132b_sst_payload_allocation_table( bool dpcd_write_128b_132b_sst_payload_allocation_table(
const struct dc_stream_state *stream, const struct dc_stream_state *stream,
struct dc_link *link, struct dc_link *link,
......
...@@ -83,6 +83,7 @@ enum link_training_result { ...@@ -83,6 +83,7 @@ enum link_training_result {
}; };
enum lttpr_mode { enum lttpr_mode {
LTTPR_MODE_UNKNOWN,
LTTPR_MODE_NON_LTTPR, LTTPR_MODE_NON_LTTPR,
LTTPR_MODE_TRANSPARENT, LTTPR_MODE_TRANSPARENT,
LTTPR_MODE_NON_TRANSPARENT, LTTPR_MODE_NON_TRANSPARENT,
......
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