]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/amd/display: add exit training mode and update channel coding in LT
authorWenjing Liu <wenjing.liu@amd.com>
Mon, 3 May 2021 23:35:54 +0000 (19:35 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 27 May 2021 16:25:43 +0000 (12:25 -0400)
[why]
As recommended by DP specs, source needs to make sure
DPRX exits previous LT mode before configuring new LT params
Nofity what channel coding mode we will use for current link training.

Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dc_link.h
drivers/gpu/drm/amd/display/include/link_service_types.h

index 425409ea5a7e1545a78fd0a2b6beee71d97dbf4b..b6b84f00fda8734efd36f73d0477f8ba4ff087c1 100644 (file)
@@ -1324,6 +1324,11 @@ static inline void decide_8b_10b_training_settings(
                lt_settings->enhanced_framing = *overrides->enhanced_framing;
        else
                lt_settings->enhanced_framing = 1;
+
+       if (link->preferred_training_settings.fec_enable != NULL)
+               lt_settings->should_set_fec_ready = *link->preferred_training_settings.fec_enable;
+       else
+               lt_settings->should_set_fec_ready = true;
 }
 
 void dp_decide_training_settings(
@@ -1614,29 +1619,68 @@ enum dc_status dpcd_configure_lttpr_mode(struct dc_link *link, struct link_train
        return status;
 }
 
+static void dpcd_exit_training_mode(struct dc_link *link)
+{
+       const uint8_t clear_pattern = 0;
+
+       /* clear training pattern set */
+       core_link_write_dpcd(
+                       link,
+                       DP_TRAINING_PATTERN_SET,
+                       &clear_pattern,
+                       sizeof(clear_pattern));
+       DC_LOG_HW_LINK_TRAINING("%s\n %x pattern = %x\n",
+                       __func__,
+                       DP_TRAINING_PATTERN_SET,
+                       clear_pattern);
+}
+
+enum dc_status dpcd_configure_channel_coding(struct dc_link *link,
+               struct link_training_settings *lt_settings)
+{
+       enum dp_link_encoding encoding =
+                       dp_get_link_encoding_format(
+                                       &lt_settings->link_settings);
+       enum dc_status status;
+
+       status = core_link_write_dpcd(
+                       link,
+                       DP_MAIN_LINK_CHANNEL_CODING_SET,
+                       (uint8_t *) &encoding,
+                       1);
+       DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X MAIN_LINK_CHANNEL_CODING_SET = %x\n",
+                                       __func__,
+                                       DP_MAIN_LINK_CHANNEL_CODING_SET,
+                                       encoding);
+
+       return status;
+}
+
 enum link_training_result dc_link_dp_perform_link_training(
        struct dc_link *link,
-       const struct dc_link_settings *link_setting,
+       const struct dc_link_settings *link_settings,
        bool skip_video_pattern)
 {
        enum link_training_result status = LINK_TRAINING_SUCCESS;
        struct link_training_settings lt_settings;
 
-       bool fec_enable;
-       uint8_t repeater_cnt;
-       uint8_t repeater_id;
+       /* reset previous training states */
+       dpcd_exit_training_mode(link);
 
+       /* decide training settings */
        dp_decide_training_settings(
                        link,
-                       link_setting,
+                       link_settings,
                        &link->preferred_training_settings,
                        &lt_settings);
+       dpcd_configure_lttpr_mode(link, &lt_settings);
+       dp_set_fec_ready(link, lt_settings.should_set_fec_ready);
+       dpcd_configure_channel_coding(link, &lt_settings);
 
-       /* Configure lttpr mode */
-       if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
-               configure_lttpr_mode_non_transparent(link, &lt_settings);
-       else if (link->lttpr_mode == LTTPR_MODE_TRANSPARENT)
-               configure_lttpr_mode_transparent(link);
+       /* enter training mode:
+        * Per DP specs starting from here, DPTX device shall not issue
+        * Non-LT AUX transactions inside training mode.
+        */
 
        if (link->ctx->dc->work_arounds.lt_early_cr_pattern)
                start_clock_recovery_pattern_early(link, &lt_settings, DPRX);
@@ -1644,14 +1688,9 @@ enum link_training_result dc_link_dp_perform_link_training(
        /* 1. set link rate, lane count and spread. */
        dpcd_set_link_settings(link, &lt_settings);
 
-       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);
-
        if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
+               uint8_t repeater_cnt;
+               uint8_t repeater_id;
 
                /* 2. perform link training (set link training done
                 *  to false is done as well)
index c617e9ae68a31acfefd979722adb8b2f1aa2c960..83845d006c54a29607295b4fca458247fd6f871e 100644 (file)
@@ -333,7 +333,7 @@ bool dc_link_dp_perform_link_training_skip_aux(
 
 enum link_training_result dc_link_dp_perform_link_training(
        struct dc_link *link,
-       const struct dc_link_settings *link_setting,
+       const struct dc_link_settings *link_settings,
        bool skip_video_pattern);
 
 bool dc_link_dp_sync_lt_begin(struct dc_link *link);
index 7a30ca01e7d4719946d09e8a91e161dee66f2cf8..32f5274ed34e22dcf756dee67930429be3debe85 100644 (file)
@@ -85,6 +85,7 @@ struct link_training_settings {
        enum dc_voltage_swing *voltage_swing;
        enum dc_pre_emphasis *pre_emphasis;
        enum dc_post_cursor2 *post_cursor2;
+       bool should_set_fec_ready;
 
        uint16_t cr_pattern_time;
        uint16_t eq_pattern_time;