drm/amd/display: Update setting of DP training parameters.
authorJimmy Kizito <Jimmy.Kizito@amd.com>
Mon, 5 Apr 2021 22:05:09 +0000 (18:05 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 10 May 2021 22:09:53 +0000 (18:09 -0400)
[Why]
Some links are dynamically assigned link encoders on stream enablement.

[How]
Update DisplayPort training parameter determination stage that assumes
link encoder statically assigned to link.

Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Stylon Wang <stylon.wang@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.c
drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h

index a2e7747..d040d23 100644 (file)
@@ -48,6 +48,7 @@
 #include "dce/dmub_psr.h"
 #include "dmub/dmub_srv.h"
 #include "inc/hw/panel_cntl.h"
+#include "inc/link_enc_cfg.h"
 
 #define DC_LOGGER_INIT(logger)
 
@@ -3737,8 +3738,22 @@ void dc_link_overwrite_extended_receiver_cap(
 
 bool dc_link_is_fec_supported(const struct dc_link *link)
 {
+       struct link_encoder *link_enc = NULL;
+
+       /* Links supporting dynamically assigned link encoder will be assigned next
+        * available encoder if one not already assigned.
+        */
+       if (link->is_dig_mapping_flexible &&
+                       link->dc->res_pool->funcs->link_encs_assign) {
+               link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+               if (link_enc == NULL)
+                       link_enc = link_enc_cfg_get_next_avail_link_enc(link->dc, link->dc->current_state);
+       } else
+               link_enc = link->link_enc;
+       ASSERT(link_enc);
+
        return (dc_is_dp_signal(link->connector_signal) &&
-                       link->link_enc->features.fec_supported &&
+                       link_enc->features.fec_supported &&
                        link->dpcd_caps.fec_cap.bits.FEC_CAPABLE &&
                        !IS_FPGA_MAXIMUS_DC(link->ctx->dce_environment));
 }
index 3bdd54e..ba6b56f 100644 (file)
@@ -685,6 +685,10 @@ bool dc_link_aux_try_to_configure_timeout(struct ddc_service *ddc,
        bool result = false;
        struct ddc *ddc_pin = ddc->ddc_pin;
 
+       /* Do not try to access nonexistent DDC pin. */
+       if (ddc->link->ep_type != DISPLAY_ENDPOINT_PHY)
+               return true;
+
        if (ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout) {
                ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout);
                result = true;
index ced552e..a87613f 100644 (file)
@@ -14,6 +14,7 @@
 #include "dpcd_defs.h"
 #include "dc_dmub_srv.h"
 #include "dce/dmub_hw_lock_mgr.h"
+#include "inc/link_enc_cfg.h"
 
 /*Travis*/
 static const uint8_t DP_VGA_LVDS_CONVERTER_ID_2[] = "sivarT";
@@ -132,10 +133,22 @@ static enum dc_dp_training_pattern decide_cr_training_pattern(
 static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *link,
                const struct dc_link_settings *link_settings)
 {
+       struct link_encoder *link_enc;
        enum dc_dp_training_pattern highest_tp = DP_TRAINING_PATTERN_SEQUENCE_2;
-       struct encoder_feature_support *features = &link->link_enc->features;
+       struct encoder_feature_support *features;
        struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
 
+       /* Access link encoder capability based on whether it is statically
+        * or dynamically assigned to a link.
+        */
+       if (link->is_dig_mapping_flexible &&
+                       link->dc->res_pool->funcs->link_encs_assign)
+               link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+       else
+               link_enc = link->link_enc;
+       ASSERT(link_enc);
+       features = &link_enc->features;
+
        if (features->flags.bits.IS_TPS3_CAPABLE)
                highest_tp = DP_TRAINING_PATTERN_SEQUENCE_3;
 
@@ -1366,6 +1379,7 @@ static void configure_lttpr_mode_non_transparent(struct dc_link *link)
                }
 
                repeater_cnt = convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
+
                for (repeater_id = repeater_cnt; repeater_id > 0; repeater_id--) {
                        aux_interval_address = DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 +
                                                ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (repeater_id - 1));
@@ -3585,7 +3599,9 @@ static bool retrieve_link_cap(struct dc_link *link)
                                lttpr_dpcd_data[DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT -
                                                                DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
 
+               /* Attempt to train in LTTPR transparent mode if repeater count exceeds 8. */
                is_lttpr_present = (link->dpcd_caps.lttpr_caps.phy_repeater_cnt > 0 &&
+                               link->dpcd_caps.lttpr_caps.phy_repeater_cnt < 0xff &&
                                link->dpcd_caps.lttpr_caps.max_lane_count > 0 &&
                                link->dpcd_caps.lttpr_caps.max_lane_count <= 4 &&
                                link->dpcd_caps.lttpr_caps.revision.raw >= 0x14);
index 1361b87..1a89d56 100644 (file)
@@ -112,8 +112,8 @@ static void update_link_enc_assignment(
 
 /* Return first available DIG link encoder. */
 static enum engine_id find_first_avail_link_enc(
-               struct dc_context *ctx,
-               struct dc_state *state)
+               const struct dc_context *ctx,
+               const struct dc_state *state)
 {
        enum engine_id eng_id = ENGINE_ID_UNKNOWN;
        int i;
@@ -270,7 +270,7 @@ struct dc_link *link_enc_cfg_get_link_using_link_enc(
 
 struct link_encoder *link_enc_cfg_get_link_enc_used_by_link(
                struct dc_state *state,
-               struct dc_link *link)
+               const struct dc_link *link)
 {
        struct link_encoder *link_enc = NULL;
        struct display_endpoint_id ep_id;
@@ -296,8 +296,20 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_link(
 
        if (stream_idx != -1)
                link_enc = state->streams[stream_idx]->link_enc;
-       else
-               dm_output_to_console("%s: No link encoder used by link(%d).\n", __func__, link->link_index);
+
+       return link_enc;
+}
+
+struct link_encoder *link_enc_cfg_get_next_avail_link_enc(
+       const struct dc *dc,
+       const struct dc_state *state)
+{
+       struct link_encoder *link_enc = NULL;
+       enum engine_id eng_id = ENGINE_ID_UNKNOWN;
+
+       eng_id = find_first_avail_link_enc(dc->ctx, state);
+       if (eng_id != ENGINE_ID_UNKNOWN)
+               link_enc = dc->res_pool->link_encoders[eng_id - ENGINE_ID_DIGA];
 
        return link_enc;
 }
index 7d36e55..883dd87 100644 (file)
@@ -81,6 +81,11 @@ struct dc_link *link_enc_cfg_get_link_using_link_enc(
 /* Return DIG link encoder used by link. NULL if unused. */
 struct link_encoder *link_enc_cfg_get_link_enc_used_by_link(
                struct dc_state *state,
-               struct dc_link *link);
+               const struct dc_link *link);
+
+/* Return next available DIG link encoder. NULL if none available. */
+struct link_encoder *link_enc_cfg_get_next_avail_link_enc(
+       const struct dc *dc,
+       const struct dc_state *state);
 
 #endif /* DC_INC_LINK_ENC_CFG_H_ */