root/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_training_aux_rd_interval
  2. wait_for_training_aux_rd_interval
  3. dpcd_set_training_pattern
  4. get_supported_tp
  5. dpcd_set_link_settings
  6. dc_dp_training_pattern_to_dpcd_training_pattern
  7. dpcd_set_lt_pattern_and_lane_settings
  8. is_cr_done
  9. is_ch_eq_done
  10. update_drive_settings
  11. get_nibble_at_index
  12. get_max_pre_emphasis_for_voltage_swing
  13. find_max_drive_settings
  14. get_lane_status_and_drive_settings
  15. dpcd_set_lane_settings
  16. is_max_vs_reached
  17. dc_link_dp_set_drive_settings
  18. perform_post_lt_adj_req_sequence
  19. get_cr_failure
  20. perform_channel_equalization_sequence
  21. perform_clock_recovery_sequence
  22. perform_link_training_int
  23. initialize_training_settings
  24. print_status_message
  25. dc_link_dp_perform_link_training_skip_aux
  26. dc_link_dp_perform_link_training
  27. perform_link_training_with_retries
  28. get_clock_source_id
  29. set_dp_mst_mode
  30. dc_link_dp_sync_lt_begin
  31. dc_link_dp_sync_lt_attempt
  32. dc_link_dp_sync_lt_end
  33. get_max_link_cap
  34. read_hpd_rx_irq_data
  35. hpd_rx_irq_check_link_loss_status
  36. dp_verify_link_cap
  37. dp_verify_link_cap_with_retries
  38. get_common_supported_link_settings
  39. reached_minimum_lane_count
  40. reached_minimum_link_rate
  41. reduce_lane_count
  42. reduce_link_rate
  43. increase_lane_count
  44. increase_link_rate
  45. decide_fallback_link_setting
  46. dp_validate_mode_timing
  47. decide_dp_link_settings
  48. decide_edp_link_settings
  49. decide_link_settings
  50. allow_hpd_rx_irq
  51. handle_hpd_irq_psr_sink
  52. dp_test_send_link_training
  53. dp_test_send_phy_test_pattern
  54. dp_test_send_link_test_pattern
  55. handle_automated_test
  56. dc_link_handle_hpd_rx_irq
  57. is_mst_supported
  58. is_dp_active_dongle
  59. translate_dpcd_max_bpc
  60. read_dp_device_vendor_id
  61. get_active_converter_info
  62. dp_wa_power_up_0010FA
  63. retrieve_link_cap
  64. detect_dp_sink_caps
  65. linkRateInKHzToLinkRateMultiplier
  66. detect_edp_sink_caps
  67. dc_link_dp_enable_hpd
  68. dc_link_dp_disable_hpd
  69. is_dp_phy_pattern
  70. set_crtc_test_pattern
  71. dc_link_dp_set_test_pattern
  72. dp_enable_mst_on_sink
  73. dp_set_panel_mode
  74. dp_get_panel_mode
  75. dp_set_fec_ready
  76. dp_set_fec_enable

   1 /* Copyright 2015 Advanced Micro Devices, Inc. */
   2 #include "dm_services.h"
   3 #include "dc.h"
   4 #include "dc_link_dp.h"
   5 #include "dm_helpers.h"
   6 #include "opp.h"
   7 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
   8 #include "dsc.h"
   9 #endif
  10 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
  11 #include "resource.h"
  12 #endif
  13 
  14 #include "inc/core_types.h"
  15 #include "link_hwss.h"
  16 #include "dc_link_ddc.h"
  17 #include "core_status.h"
  18 #include "dpcd_defs.h"
  19 
  20 #include "resource.h"
  21 #define DC_LOGGER \
  22         link->ctx->logger
  23 
  24 /* maximum pre emphasis level allowed for each voltage swing level*/
  25 static const enum dc_pre_emphasis voltage_swing_to_pre_emphasis[] = {
  26                 PRE_EMPHASIS_LEVEL3,
  27                 PRE_EMPHASIS_LEVEL2,
  28                 PRE_EMPHASIS_LEVEL1,
  29                 PRE_EMPHASIS_DISABLED };
  30 
  31 enum {
  32         POST_LT_ADJ_REQ_LIMIT = 6,
  33         POST_LT_ADJ_REQ_TIMEOUT = 200
  34 };
  35 
  36 enum {
  37         LINK_TRAINING_MAX_RETRY_COUNT = 5,
  38         /* to avoid infinite loop where-in the receiver
  39          * switches between different VS
  40          */
  41         LINK_TRAINING_MAX_CR_RETRY = 100
  42 };
  43 
  44 static bool decide_fallback_link_setting(
  45                 struct dc_link_settings initial_link_settings,
  46                 struct dc_link_settings *current_link_setting,
  47                 enum link_training_result training_result);
  48 static struct dc_link_settings get_common_supported_link_settings(
  49                 struct dc_link_settings link_setting_a,
  50                 struct dc_link_settings link_setting_b);
  51 
  52 static uint32_t get_training_aux_rd_interval(
  53         struct dc_link *link,
  54         uint32_t default_wait_in_micro_secs)
  55 {
  56         union training_aux_rd_interval training_rd_interval;
  57 
  58         memset(&training_rd_interval, 0, sizeof(training_rd_interval));
  59 
  60         /* overwrite the delay if rev > 1.1*/
  61         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
  62                 /* DP 1.2 or later - retrieve delay through
  63                  * "DPCD_ADDR_TRAINING_AUX_RD_INTERVAL" register */
  64                 core_link_read_dpcd(
  65                         link,
  66                         DP_TRAINING_AUX_RD_INTERVAL,
  67                         (uint8_t *)&training_rd_interval,
  68                         sizeof(training_rd_interval));
  69 
  70                 if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL)
  71                         default_wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
  72         }
  73 
  74         return default_wait_in_micro_secs;
  75 }
  76 
  77 static void wait_for_training_aux_rd_interval(
  78         struct dc_link *link,
  79         uint32_t wait_in_micro_secs)
  80 {
  81         udelay(wait_in_micro_secs);
  82 
  83         DC_LOG_HW_LINK_TRAINING("%s:\n wait = %d\n",
  84                 __func__,
  85                 wait_in_micro_secs);
  86 }
  87 
  88 static void dpcd_set_training_pattern(
  89         struct dc_link *link,
  90         union dpcd_training_pattern dpcd_pattern)
  91 {
  92         core_link_write_dpcd(
  93                 link,
  94                 DP_TRAINING_PATTERN_SET,
  95                 &dpcd_pattern.raw,
  96                 1);
  97 
  98         DC_LOG_HW_LINK_TRAINING("%s\n %x pattern = %x\n",
  99                 __func__,
 100                 DP_TRAINING_PATTERN_SET,
 101                 dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
 102 }
 103 
 104 static enum dc_dp_training_pattern get_supported_tp(struct dc_link *link)
 105 {
 106         enum dc_dp_training_pattern highest_tp = DP_TRAINING_PATTERN_SEQUENCE_2;
 107         struct encoder_feature_support *features = &link->link_enc->features;
 108         struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
 109 
 110         if (features->flags.bits.IS_TPS3_CAPABLE)
 111                 highest_tp = DP_TRAINING_PATTERN_SEQUENCE_3;
 112 
 113         if (features->flags.bits.IS_TPS4_CAPABLE)
 114                 highest_tp = DP_TRAINING_PATTERN_SEQUENCE_4;
 115 
 116         if (dpcd_caps->max_down_spread.bits.TPS4_SUPPORTED &&
 117                 highest_tp >= DP_TRAINING_PATTERN_SEQUENCE_4)
 118                 return DP_TRAINING_PATTERN_SEQUENCE_4;
 119 
 120         if (dpcd_caps->max_ln_count.bits.TPS3_SUPPORTED &&
 121                 highest_tp >= DP_TRAINING_PATTERN_SEQUENCE_3)
 122                 return DP_TRAINING_PATTERN_SEQUENCE_3;
 123 
 124         return DP_TRAINING_PATTERN_SEQUENCE_2;
 125 }
 126 
 127 static void dpcd_set_link_settings(
 128         struct dc_link *link,
 129         const struct link_training_settings *lt_settings)
 130 {
 131         uint8_t rate;
 132 
 133         union down_spread_ctrl downspread = { {0} };
 134         union lane_count_set lane_count_set = { {0} };
 135         enum dc_dp_training_pattern dp_tr_pattern;
 136 
 137         downspread.raw = (uint8_t)
 138         (lt_settings->link_settings.link_spread);
 139 
 140         lane_count_set.bits.LANE_COUNT_SET =
 141         lt_settings->link_settings.lane_count;
 142 
 143         lane_count_set.bits.ENHANCED_FRAMING = lt_settings->enhanced_framing;
 144         lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
 145 
 146         dp_tr_pattern = get_supported_tp(link);
 147 
 148         if (dp_tr_pattern != DP_TRAINING_PATTERN_SEQUENCE_4) {
 149                 lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED =
 150                                 link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED;
 151         }
 152 
 153         core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
 154                 &downspread.raw, sizeof(downspread));
 155 
 156         core_link_write_dpcd(link, DP_LANE_COUNT_SET,
 157                 &lane_count_set.raw, 1);
 158 
 159         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 &&
 160                         lt_settings->link_settings.use_link_rate_set == true) {
 161                 rate = 0;
 162                 core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
 163                 core_link_write_dpcd(link, DP_LINK_RATE_SET,
 164                                 &lt_settings->link_settings.link_rate_set, 1);
 165         } else {
 166                 rate = (uint8_t) (lt_settings->link_settings.link_rate);
 167                 core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
 168         }
 169 
 170         if (rate) {
 171                 DC_LOG_HW_LINK_TRAINING("%s\n %x rate = %x\n %x lane = %x framing = %x\n %x spread = %x\n",
 172                         __func__,
 173                         DP_LINK_BW_SET,
 174                         lt_settings->link_settings.link_rate,
 175                         DP_LANE_COUNT_SET,
 176                         lt_settings->link_settings.lane_count,
 177                         lt_settings->enhanced_framing,
 178                         DP_DOWNSPREAD_CTRL,
 179                         lt_settings->link_settings.link_spread);
 180         } else {
 181                 DC_LOG_HW_LINK_TRAINING("%s\n %x rate set = %x\n %x lane = %x framing = %x\n %x spread = %x\n",
 182                         __func__,
 183                         DP_LINK_RATE_SET,
 184                         lt_settings->link_settings.link_rate_set,
 185                         DP_LANE_COUNT_SET,
 186                         lt_settings->link_settings.lane_count,
 187                         lt_settings->enhanced_framing,
 188                         DP_DOWNSPREAD_CTRL,
 189                         lt_settings->link_settings.link_spread);
 190         }
 191 }
 192 
 193 static enum dpcd_training_patterns
 194         dc_dp_training_pattern_to_dpcd_training_pattern(
 195         struct dc_link *link,
 196         enum dc_dp_training_pattern pattern)
 197 {
 198         enum dpcd_training_patterns dpcd_tr_pattern =
 199         DPCD_TRAINING_PATTERN_VIDEOIDLE;
 200 
 201         switch (pattern) {
 202         case DP_TRAINING_PATTERN_SEQUENCE_1:
 203                 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_1;
 204                 break;
 205         case DP_TRAINING_PATTERN_SEQUENCE_2:
 206                 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_2;
 207                 break;
 208         case DP_TRAINING_PATTERN_SEQUENCE_3:
 209                 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_3;
 210                 break;
 211         case DP_TRAINING_PATTERN_SEQUENCE_4:
 212                 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_4;
 213                 break;
 214         default:
 215                 ASSERT(0);
 216                 DC_LOG_HW_LINK_TRAINING("%s: Invalid HW Training pattern: %d\n",
 217                         __func__, pattern);
 218                 break;
 219         }
 220 
 221         return dpcd_tr_pattern;
 222 }
 223 
 224 static void dpcd_set_lt_pattern_and_lane_settings(
 225         struct dc_link *link,
 226         const struct link_training_settings *lt_settings,
 227         enum dc_dp_training_pattern pattern)
 228 {
 229         union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = { { {0} } };
 230         const uint32_t dpcd_base_lt_offset =
 231         DP_TRAINING_PATTERN_SET;
 232         uint8_t dpcd_lt_buffer[5] = {0};
 233         union dpcd_training_pattern dpcd_pattern = { {0} };
 234         uint32_t lane;
 235         uint32_t size_in_bytes;
 236         bool edp_workaround = false; /* TODO link_prop.INTERNAL */
 237 
 238         /*****************************************************************
 239         * DpcdAddress_TrainingPatternSet
 240         *****************************************************************/
 241         dpcd_pattern.v1_4.TRAINING_PATTERN_SET =
 242                 dc_dp_training_pattern_to_dpcd_training_pattern(link, pattern);
 243 
 244         dpcd_lt_buffer[DP_TRAINING_PATTERN_SET - dpcd_base_lt_offset]
 245                 = dpcd_pattern.raw;
 246 
 247         DC_LOG_HW_LINK_TRAINING("%s\n %x pattern = %x\n",
 248                 __func__,
 249                 DP_TRAINING_PATTERN_SET,
 250                 dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
 251 
 252         /*****************************************************************
 253         * DpcdAddress_Lane0Set -> DpcdAddress_Lane3Set
 254         *****************************************************************/
 255         for (lane = 0; lane <
 256                 (uint32_t)(lt_settings->link_settings.lane_count); lane++) {
 257 
 258                 dpcd_lane[lane].bits.VOLTAGE_SWING_SET =
 259                 (uint8_t)(lt_settings->lane_settings[lane].VOLTAGE_SWING);
 260                 dpcd_lane[lane].bits.PRE_EMPHASIS_SET =
 261                 (uint8_t)(lt_settings->lane_settings[lane].PRE_EMPHASIS);
 262 
 263                 dpcd_lane[lane].bits.MAX_SWING_REACHED =
 264                 (lt_settings->lane_settings[lane].VOLTAGE_SWING ==
 265                 VOLTAGE_SWING_MAX_LEVEL ? 1 : 0);
 266                 dpcd_lane[lane].bits.MAX_PRE_EMPHASIS_REACHED =
 267                 (lt_settings->lane_settings[lane].PRE_EMPHASIS ==
 268                 PRE_EMPHASIS_MAX_LEVEL ? 1 : 0);
 269         }
 270 
 271         /* concatinate everything into one buffer*/
 272 
 273         size_in_bytes = lt_settings->link_settings.lane_count * sizeof(dpcd_lane[0]);
 274 
 275          // 0x00103 - 0x00102
 276         memmove(
 277                 &dpcd_lt_buffer[DP_TRAINING_LANE0_SET - dpcd_base_lt_offset],
 278                 dpcd_lane,
 279                 size_in_bytes);
 280 
 281         DC_LOG_HW_LINK_TRAINING("%s:\n %x VS set = %x  PE set = %x max VS Reached = %x  max PE Reached = %x\n",
 282                 __func__,
 283                 DP_TRAINING_LANE0_SET,
 284                 dpcd_lane[0].bits.VOLTAGE_SWING_SET,
 285                 dpcd_lane[0].bits.PRE_EMPHASIS_SET,
 286                 dpcd_lane[0].bits.MAX_SWING_REACHED,
 287                 dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
 288 
 289         if (edp_workaround) {
 290                 /* for eDP write in 2 parts because the 5-byte burst is
 291                 * causing issues on some eDP panels (EPR#366724)
 292                 */
 293                 core_link_write_dpcd(
 294                         link,
 295                         DP_TRAINING_PATTERN_SET,
 296                         &dpcd_pattern.raw,
 297                         sizeof(dpcd_pattern.raw));
 298 
 299                 core_link_write_dpcd(
 300                         link,
 301                         DP_TRAINING_LANE0_SET,
 302                         (uint8_t *)(dpcd_lane),
 303                         size_in_bytes);
 304 
 305                 } else
 306                 /* write it all in (1 + number-of-lanes)-byte burst*/
 307                         core_link_write_dpcd(
 308                                 link,
 309                                 dpcd_base_lt_offset,
 310                                 dpcd_lt_buffer,
 311                                 size_in_bytes + sizeof(dpcd_pattern.raw));
 312 
 313         link->cur_lane_setting = lt_settings->lane_settings[0];
 314 }
 315 
 316 static bool is_cr_done(enum dc_lane_count ln_count,
 317         union lane_status *dpcd_lane_status)
 318 {
 319         bool done = true;
 320         uint32_t lane;
 321         /*LANEx_CR_DONE bits All 1's?*/
 322         for (lane = 0; lane < (uint32_t)(ln_count); lane++) {
 323                 if (!dpcd_lane_status[lane].bits.CR_DONE_0)
 324                         done = false;
 325         }
 326         return done;
 327 
 328 }
 329 
 330 static bool is_ch_eq_done(enum dc_lane_count ln_count,
 331         union lane_status *dpcd_lane_status,
 332         union lane_align_status_updated *lane_status_updated)
 333 {
 334         bool done = true;
 335         uint32_t lane;
 336         if (!lane_status_updated->bits.INTERLANE_ALIGN_DONE)
 337                 done = false;
 338         else {
 339                 for (lane = 0; lane < (uint32_t)(ln_count); lane++) {
 340                         if (!dpcd_lane_status[lane].bits.SYMBOL_LOCKED_0 ||
 341                                 !dpcd_lane_status[lane].bits.CHANNEL_EQ_DONE_0)
 342                                 done = false;
 343                 }
 344         }
 345         return done;
 346 
 347 }
 348 
 349 static void update_drive_settings(
 350                 struct link_training_settings *dest,
 351                 struct link_training_settings src)
 352 {
 353         uint32_t lane;
 354         for (lane = 0; lane < src.link_settings.lane_count; lane++) {
 355                 if (dest->voltage_swing == NULL)
 356                         dest->lane_settings[lane].VOLTAGE_SWING = src.lane_settings[lane].VOLTAGE_SWING;
 357                 else
 358                         dest->lane_settings[lane].VOLTAGE_SWING = *dest->voltage_swing;
 359 
 360                 if (dest->pre_emphasis == NULL)
 361                         dest->lane_settings[lane].PRE_EMPHASIS = src.lane_settings[lane].PRE_EMPHASIS;
 362                 else
 363                         dest->lane_settings[lane].PRE_EMPHASIS = *dest->pre_emphasis;
 364 
 365                 if (dest->post_cursor2 == NULL)
 366                         dest->lane_settings[lane].POST_CURSOR2 = src.lane_settings[lane].POST_CURSOR2;
 367                 else
 368                         dest->lane_settings[lane].POST_CURSOR2 = *dest->post_cursor2;
 369         }
 370 }
 371 
 372 static uint8_t get_nibble_at_index(const uint8_t *buf,
 373         uint32_t index)
 374 {
 375         uint8_t nibble;
 376         nibble = buf[index / 2];
 377 
 378         if (index % 2)
 379                 nibble >>= 4;
 380         else
 381                 nibble &= 0x0F;
 382 
 383         return nibble;
 384 }
 385 
 386 static enum dc_pre_emphasis get_max_pre_emphasis_for_voltage_swing(
 387         enum dc_voltage_swing voltage)
 388 {
 389         enum dc_pre_emphasis pre_emphasis;
 390         pre_emphasis = PRE_EMPHASIS_MAX_LEVEL;
 391 
 392         if (voltage <= VOLTAGE_SWING_MAX_LEVEL)
 393                 pre_emphasis = voltage_swing_to_pre_emphasis[voltage];
 394 
 395         return pre_emphasis;
 396 
 397 }
 398 
 399 static void find_max_drive_settings(
 400         const struct link_training_settings *link_training_setting,
 401         struct link_training_settings *max_lt_setting)
 402 {
 403         uint32_t lane;
 404         struct dc_lane_settings max_requested;
 405 
 406         max_requested.VOLTAGE_SWING =
 407                 link_training_setting->
 408                 lane_settings[0].VOLTAGE_SWING;
 409         max_requested.PRE_EMPHASIS =
 410                 link_training_setting->
 411                 lane_settings[0].PRE_EMPHASIS;
 412         /*max_requested.postCursor2 =
 413          * link_training_setting->laneSettings[0].postCursor2;*/
 414 
 415         /* Determine what the maximum of the requested settings are*/
 416         for (lane = 1; lane < link_training_setting->link_settings.lane_count;
 417                         lane++) {
 418                 if (link_training_setting->lane_settings[lane].VOLTAGE_SWING >
 419                         max_requested.VOLTAGE_SWING)
 420 
 421                         max_requested.VOLTAGE_SWING =
 422                         link_training_setting->
 423                         lane_settings[lane].VOLTAGE_SWING;
 424 
 425                 if (link_training_setting->lane_settings[lane].PRE_EMPHASIS >
 426                                 max_requested.PRE_EMPHASIS)
 427                         max_requested.PRE_EMPHASIS =
 428                         link_training_setting->
 429                         lane_settings[lane].PRE_EMPHASIS;
 430 
 431                 /*
 432                 if (link_training_setting->laneSettings[lane].postCursor2 >
 433                  max_requested.postCursor2)
 434                 {
 435                 max_requested.postCursor2 =
 436                 link_training_setting->laneSettings[lane].postCursor2;
 437                 }
 438                 */
 439         }
 440 
 441         /* make sure the requested settings are
 442          * not higher than maximum settings*/
 443         if (max_requested.VOLTAGE_SWING > VOLTAGE_SWING_MAX_LEVEL)
 444                 max_requested.VOLTAGE_SWING = VOLTAGE_SWING_MAX_LEVEL;
 445 
 446         if (max_requested.PRE_EMPHASIS > PRE_EMPHASIS_MAX_LEVEL)
 447                 max_requested.PRE_EMPHASIS = PRE_EMPHASIS_MAX_LEVEL;
 448         /*
 449         if (max_requested.postCursor2 > PostCursor2_MaxLevel)
 450         max_requested.postCursor2 = PostCursor2_MaxLevel;
 451         */
 452 
 453         /* make sure the pre-emphasis matches the voltage swing*/
 454         if (max_requested.PRE_EMPHASIS >
 455                 get_max_pre_emphasis_for_voltage_swing(
 456                         max_requested.VOLTAGE_SWING))
 457                 max_requested.PRE_EMPHASIS =
 458                 get_max_pre_emphasis_for_voltage_swing(
 459                         max_requested.VOLTAGE_SWING);
 460 
 461         /*
 462          * Post Cursor2 levels are completely independent from
 463          * pre-emphasis (Post Cursor1) levels. But Post Cursor2 levels
 464          * can only be applied to each allowable combination of voltage
 465          * swing and pre-emphasis levels */
 466          /* if ( max_requested.postCursor2 >
 467           *  getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing))
 468           *  max_requested.postCursor2 =
 469           *  getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing);
 470           */
 471 
 472         max_lt_setting->link_settings.link_rate =
 473                 link_training_setting->link_settings.link_rate;
 474         max_lt_setting->link_settings.lane_count =
 475         link_training_setting->link_settings.lane_count;
 476         max_lt_setting->link_settings.link_spread =
 477                 link_training_setting->link_settings.link_spread;
 478 
 479         for (lane = 0; lane <
 480                 link_training_setting->link_settings.lane_count;
 481                 lane++) {
 482                 max_lt_setting->lane_settings[lane].VOLTAGE_SWING =
 483                         max_requested.VOLTAGE_SWING;
 484                 max_lt_setting->lane_settings[lane].PRE_EMPHASIS =
 485                         max_requested.PRE_EMPHASIS;
 486                 /*max_lt_setting->laneSettings[lane].postCursor2 =
 487                  * max_requested.postCursor2;
 488                  */
 489         }
 490 
 491 }
 492 
 493 static void get_lane_status_and_drive_settings(
 494         struct dc_link *link,
 495         const struct link_training_settings *link_training_setting,
 496         union lane_status *ln_status,
 497         union lane_align_status_updated *ln_status_updated,
 498         struct link_training_settings *req_settings)
 499 {
 500         uint8_t dpcd_buf[6] = {0};
 501         union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
 502         struct link_training_settings request_settings = { {0} };
 503         uint32_t lane;
 504 
 505         memset(req_settings, '\0', sizeof(struct link_training_settings));
 506 
 507         core_link_read_dpcd(
 508                 link,
 509                 DP_LANE0_1_STATUS,
 510                 (uint8_t *)(dpcd_buf),
 511                 sizeof(dpcd_buf));
 512 
 513         for (lane = 0; lane <
 514                 (uint32_t)(link_training_setting->link_settings.lane_count);
 515                 lane++) {
 516 
 517                 ln_status[lane].raw =
 518                         get_nibble_at_index(&dpcd_buf[0], lane);
 519                 dpcd_lane_adjust[lane].raw =
 520                         get_nibble_at_index(&dpcd_buf[4], lane);
 521         }
 522 
 523         ln_status_updated->raw = dpcd_buf[2];
 524 
 525         DC_LOG_HW_LINK_TRAINING("%s:\n%x Lane01Status = %x\n %x Lane23Status = %x\n ",
 526                 __func__,
 527                 DP_LANE0_1_STATUS, dpcd_buf[0],
 528                 DP_LANE2_3_STATUS, dpcd_buf[1]);
 529 
 530         DC_LOG_HW_LINK_TRAINING("%s:\n %x Lane01AdjustRequest = %x\n %x Lane23AdjustRequest = %x\n",
 531                 __func__,
 532                 DP_ADJUST_REQUEST_LANE0_1,
 533                 dpcd_buf[4],
 534                 DP_ADJUST_REQUEST_LANE2_3,
 535                 dpcd_buf[5]);
 536 
 537         /*copy to req_settings*/
 538         request_settings.link_settings.lane_count =
 539                 link_training_setting->link_settings.lane_count;
 540         request_settings.link_settings.link_rate =
 541                 link_training_setting->link_settings.link_rate;
 542         request_settings.link_settings.link_spread =
 543                 link_training_setting->link_settings.link_spread;
 544 
 545         for (lane = 0; lane <
 546                 (uint32_t)(link_training_setting->link_settings.lane_count);
 547                 lane++) {
 548 
 549                 request_settings.lane_settings[lane].VOLTAGE_SWING =
 550                         (enum dc_voltage_swing)(dpcd_lane_adjust[lane].bits.
 551                                 VOLTAGE_SWING_LANE);
 552                 request_settings.lane_settings[lane].PRE_EMPHASIS =
 553                         (enum dc_pre_emphasis)(dpcd_lane_adjust[lane].bits.
 554                                 PRE_EMPHASIS_LANE);
 555         }
 556 
 557         /*Note: for postcursor2, read adjusted
 558          * postcursor2 settings from*/
 559         /*DpcdAddress_AdjustRequestPostCursor2 =
 560          *0x020C (not implemented yet)*/
 561 
 562         /* we find the maximum of the requested settings across all lanes*/
 563         /* and set this maximum for all lanes*/
 564         find_max_drive_settings(&request_settings, req_settings);
 565 
 566         /* if post cursor 2 is needed in the future,
 567          * read DpcdAddress_AdjustRequestPostCursor2 = 0x020C
 568          */
 569 
 570 }
 571 
 572 static void dpcd_set_lane_settings(
 573         struct dc_link *link,
 574         const struct link_training_settings *link_training_setting)
 575 {
 576         union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = {{{0}}};
 577         uint32_t lane;
 578 
 579         for (lane = 0; lane <
 580                 (uint32_t)(link_training_setting->
 581                 link_settings.lane_count);
 582                 lane++) {
 583                 dpcd_lane[lane].bits.VOLTAGE_SWING_SET =
 584                         (uint8_t)(link_training_setting->
 585                         lane_settings[lane].VOLTAGE_SWING);
 586                 dpcd_lane[lane].bits.PRE_EMPHASIS_SET =
 587                         (uint8_t)(link_training_setting->
 588                         lane_settings[lane].PRE_EMPHASIS);
 589                 dpcd_lane[lane].bits.MAX_SWING_REACHED =
 590                         (link_training_setting->
 591                         lane_settings[lane].VOLTAGE_SWING ==
 592                         VOLTAGE_SWING_MAX_LEVEL ? 1 : 0);
 593                 dpcd_lane[lane].bits.MAX_PRE_EMPHASIS_REACHED =
 594                         (link_training_setting->
 595                         lane_settings[lane].PRE_EMPHASIS ==
 596                         PRE_EMPHASIS_MAX_LEVEL ? 1 : 0);
 597         }
 598 
 599         core_link_write_dpcd(link,
 600                 DP_TRAINING_LANE0_SET,
 601                 (uint8_t *)(dpcd_lane),
 602                 link_training_setting->link_settings.lane_count);
 603 
 604         /*
 605         if (LTSettings.link.rate == LinkRate_High2)
 606         {
 607                 DpcdTrainingLaneSet2 dpcd_lane2[lane_count_DPMax] = {0};
 608                 for ( uint32_t lane = 0;
 609                 lane < lane_count_DPMax; lane++)
 610                 {
 611                         dpcd_lane2[lane].bits.post_cursor2_set =
 612                         static_cast<unsigned char>(
 613                         LTSettings.laneSettings[lane].postCursor2);
 614                         dpcd_lane2[lane].bits.max_post_cursor2_reached = 0;
 615                 }
 616                 m_pDpcdAccessSrv->WriteDpcdData(
 617                 DpcdAddress_Lane0Set2,
 618                 reinterpret_cast<unsigned char*>(dpcd_lane2),
 619                 LTSettings.link.lanes);
 620         }
 621         */
 622 
 623         DC_LOG_HW_LINK_TRAINING("%s\n %x VS set = %x  PE set = %x max VS Reached = %x  max PE Reached = %x\n",
 624                 __func__,
 625                 DP_TRAINING_LANE0_SET,
 626                 dpcd_lane[0].bits.VOLTAGE_SWING_SET,
 627                 dpcd_lane[0].bits.PRE_EMPHASIS_SET,
 628                 dpcd_lane[0].bits.MAX_SWING_REACHED,
 629                 dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
 630 
 631         link->cur_lane_setting = link_training_setting->lane_settings[0];
 632 
 633 }
 634 
 635 static bool is_max_vs_reached(
 636         const struct link_training_settings *lt_settings)
 637 {
 638         uint32_t lane;
 639         for (lane = 0; lane <
 640                 (uint32_t)(lt_settings->link_settings.lane_count);
 641                 lane++) {
 642                 if (lt_settings->lane_settings[lane].VOLTAGE_SWING
 643                         == VOLTAGE_SWING_MAX_LEVEL)
 644                         return true;
 645         }
 646         return false;
 647 
 648 }
 649 
 650 void dc_link_dp_set_drive_settings(
 651         struct dc_link *link,
 652         struct link_training_settings *lt_settings)
 653 {
 654         /* program ASIC PHY settings*/
 655         dp_set_hw_lane_settings(link, lt_settings);
 656 
 657         /* Notify DP sink the PHY settings from source */
 658         dpcd_set_lane_settings(link, lt_settings);
 659 }
 660 
 661 static bool perform_post_lt_adj_req_sequence(
 662         struct dc_link *link,
 663         struct link_training_settings *lt_settings)
 664 {
 665         enum dc_lane_count lane_count =
 666         lt_settings->link_settings.lane_count;
 667 
 668         uint32_t adj_req_count;
 669         uint32_t adj_req_timer;
 670         bool req_drv_setting_changed;
 671         uint32_t lane;
 672 
 673         req_drv_setting_changed = false;
 674         for (adj_req_count = 0; adj_req_count < POST_LT_ADJ_REQ_LIMIT;
 675         adj_req_count++) {
 676 
 677                 req_drv_setting_changed = false;
 678 
 679                 for (adj_req_timer = 0;
 680                         adj_req_timer < POST_LT_ADJ_REQ_TIMEOUT;
 681                         adj_req_timer++) {
 682 
 683                         struct link_training_settings req_settings;
 684                         union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
 685                         union lane_align_status_updated
 686                                 dpcd_lane_status_updated;
 687 
 688                         get_lane_status_and_drive_settings(
 689                         link,
 690                         lt_settings,
 691                         dpcd_lane_status,
 692                         &dpcd_lane_status_updated,
 693                         &req_settings);
 694 
 695                         if (dpcd_lane_status_updated.bits.
 696                                         POST_LT_ADJ_REQ_IN_PROGRESS == 0)
 697                                 return true;
 698 
 699                         if (!is_cr_done(lane_count, dpcd_lane_status))
 700                                 return false;
 701 
 702                         if (!is_ch_eq_done(
 703                                 lane_count,
 704                                 dpcd_lane_status,
 705                                 &dpcd_lane_status_updated))
 706                                 return false;
 707 
 708                         for (lane = 0; lane < (uint32_t)(lane_count); lane++) {
 709 
 710                                 if (lt_settings->
 711                                 lane_settings[lane].VOLTAGE_SWING !=
 712                                 req_settings.lane_settings[lane].
 713                                 VOLTAGE_SWING ||
 714                                 lt_settings->lane_settings[lane].PRE_EMPHASIS !=
 715                                 req_settings.lane_settings[lane].PRE_EMPHASIS) {
 716 
 717                                         req_drv_setting_changed = true;
 718                                         break;
 719                                 }
 720                         }
 721 
 722                         if (req_drv_setting_changed) {
 723                                 update_drive_settings(
 724                                         lt_settings, req_settings);
 725 
 726                                 dc_link_dp_set_drive_settings(link,
 727                                                 lt_settings);
 728                                 break;
 729                         }
 730 
 731                         msleep(1);
 732                 }
 733 
 734                 if (!req_drv_setting_changed) {
 735                         DC_LOG_WARNING("%s: Post Link Training Adjust Request Timed out\n",
 736                                 __func__);
 737 
 738                         ASSERT(0);
 739                         return true;
 740                 }
 741         }
 742         DC_LOG_WARNING("%s: Post Link Training Adjust Request limit reached\n",
 743                 __func__);
 744 
 745         ASSERT(0);
 746         return true;
 747 
 748 }
 749 
 750 static enum link_training_result get_cr_failure(enum dc_lane_count ln_count,
 751                                         union lane_status *dpcd_lane_status)
 752 {
 753         enum link_training_result result = LINK_TRAINING_SUCCESS;
 754 
 755         if (ln_count >= LANE_COUNT_ONE && !dpcd_lane_status[0].bits.CR_DONE_0)
 756                 result = LINK_TRAINING_CR_FAIL_LANE0;
 757         else if (ln_count >= LANE_COUNT_TWO && !dpcd_lane_status[1].bits.CR_DONE_0)
 758                 result = LINK_TRAINING_CR_FAIL_LANE1;
 759         else if (ln_count >= LANE_COUNT_FOUR && !dpcd_lane_status[2].bits.CR_DONE_0)
 760                 result = LINK_TRAINING_CR_FAIL_LANE23;
 761         else if (ln_count >= LANE_COUNT_FOUR && !dpcd_lane_status[3].bits.CR_DONE_0)
 762                 result = LINK_TRAINING_CR_FAIL_LANE23;
 763         return result;
 764 }
 765 
 766 static enum link_training_result perform_channel_equalization_sequence(
 767         struct dc_link *link,
 768         struct link_training_settings *lt_settings)
 769 {
 770         struct link_training_settings req_settings;
 771         enum dc_dp_training_pattern tr_pattern;
 772         uint32_t retries_ch_eq;
 773         enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
 774         union lane_align_status_updated dpcd_lane_status_updated = { {0} };
 775         union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
 776 
 777         tr_pattern = lt_settings->pattern_for_eq;
 778 
 779         dp_set_hw_training_pattern(link, tr_pattern);
 780 
 781         for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT;
 782                 retries_ch_eq++) {
 783 
 784                 dp_set_hw_lane_settings(link, lt_settings);
 785 
 786                 /* 2. update DPCD*/
 787                 if (!retries_ch_eq)
 788                         /* EPR #361076 - write as a 5-byte burst,
 789                          * but only for the 1-st iteration*/
 790                         dpcd_set_lt_pattern_and_lane_settings(
 791                                 link,
 792                                 lt_settings,
 793                                 tr_pattern);
 794                 else
 795                         dpcd_set_lane_settings(link, lt_settings);
 796 
 797                 /* 3. wait for receiver to lock-on*/
 798                 wait_for_training_aux_rd_interval(link, lt_settings->eq_pattern_time);
 799 
 800                 /* 4. Read lane status and requested
 801                  * drive settings as set by the sink*/
 802 
 803                 get_lane_status_and_drive_settings(
 804                         link,
 805                         lt_settings,
 806                         dpcd_lane_status,
 807                         &dpcd_lane_status_updated,
 808                         &req_settings);
 809 
 810                 /* 5. check CR done*/
 811                 if (!is_cr_done(lane_count, dpcd_lane_status))
 812                         return LINK_TRAINING_EQ_FAIL_CR;
 813 
 814                 /* 6. check CHEQ done*/
 815                 if (is_ch_eq_done(lane_count,
 816                         dpcd_lane_status,
 817                         &dpcd_lane_status_updated))
 818                         return LINK_TRAINING_SUCCESS;
 819 
 820                 /* 7. update VS/PE/PC2 in lt_settings*/
 821                 update_drive_settings(lt_settings, req_settings);
 822         }
 823 
 824         return LINK_TRAINING_EQ_FAIL_EQ;
 825 
 826 }
 827 
 828 static enum link_training_result perform_clock_recovery_sequence(
 829         struct dc_link *link,
 830         struct link_training_settings *lt_settings)
 831 {
 832         uint32_t retries_cr;
 833         uint32_t retry_count;
 834         struct link_training_settings req_settings;
 835         enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
 836         enum dc_dp_training_pattern tr_pattern = DP_TRAINING_PATTERN_SEQUENCE_1;
 837         union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
 838         union lane_align_status_updated dpcd_lane_status_updated;
 839 
 840         retries_cr = 0;
 841         retry_count = 0;
 842 
 843         dp_set_hw_training_pattern(link, tr_pattern);
 844 
 845         /* najeeb - The synaptics MST hub can put the LT in
 846         * infinite loop by switching the VS
 847         */
 848         /* between level 0 and level 1 continuously, here
 849         * we try for CR lock for LinkTrainingMaxCRRetry count*/
 850         while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) &&
 851                 (retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
 852 
 853                 memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status));
 854                 memset(&dpcd_lane_status_updated, '\0',
 855                 sizeof(dpcd_lane_status_updated));
 856 
 857                 /* 1. call HWSS to set lane settings*/
 858                 dp_set_hw_lane_settings(
 859                                 link,
 860                                 lt_settings);
 861 
 862                 /* 2. update DPCD of the receiver*/
 863                 if (!retries_cr)
 864                         /* EPR #361076 - write as a 5-byte burst,
 865                          * but only for the 1-st iteration.*/
 866                         dpcd_set_lt_pattern_and_lane_settings(
 867                                         link,
 868                                         lt_settings,
 869                                         tr_pattern);
 870                 else
 871                         dpcd_set_lane_settings(
 872                                         link,
 873                                         lt_settings);
 874 
 875                 /* 3. wait receiver to lock-on*/
 876                 wait_for_training_aux_rd_interval(
 877                                 link,
 878                                 lt_settings->cr_pattern_time);
 879 
 880                 /* 4. Read lane status and requested drive
 881                 * settings as set by the sink
 882                 */
 883                 get_lane_status_and_drive_settings(
 884                                 link,
 885                                 lt_settings,
 886                                 dpcd_lane_status,
 887                                 &dpcd_lane_status_updated,
 888                                 &req_settings);
 889 
 890                 /* 5. check CR done*/
 891                 if (is_cr_done(lane_count, dpcd_lane_status))
 892                         return LINK_TRAINING_SUCCESS;
 893 
 894                 /* 6. max VS reached*/
 895                 if (is_max_vs_reached(lt_settings))
 896                         break;
 897 
 898                 /* 7. same voltage*/
 899                 /* Note: VS same for all lanes,
 900                 * so comparing first lane is sufficient*/
 901                 if (lt_settings->lane_settings[0].VOLTAGE_SWING ==
 902                         req_settings.lane_settings[0].VOLTAGE_SWING)
 903                         retries_cr++;
 904                 else
 905                         retries_cr = 0;
 906 
 907                 /* 8. update VS/PE/PC2 in lt_settings*/
 908                 update_drive_settings(lt_settings, req_settings);
 909 
 910                 retry_count++;
 911         }
 912 
 913         if (retry_count >= LINK_TRAINING_MAX_CR_RETRY) {
 914                 ASSERT(0);
 915                 DC_LOG_ERROR("%s: Link Training Error, could not get CR after %d tries. Possibly voltage swing issue",
 916                         __func__,
 917                         LINK_TRAINING_MAX_CR_RETRY);
 918 
 919         }
 920 
 921         return get_cr_failure(lane_count, dpcd_lane_status);
 922 }
 923 
 924 static inline enum link_training_result perform_link_training_int(
 925         struct dc_link *link,
 926         struct link_training_settings *lt_settings,
 927         enum link_training_result status)
 928 {
 929         union lane_count_set lane_count_set = { {0} };
 930         union dpcd_training_pattern dpcd_pattern = { {0} };
 931 
 932         /* 3. set training not in progress*/
 933         dpcd_pattern.v1_4.TRAINING_PATTERN_SET = DPCD_TRAINING_PATTERN_VIDEOIDLE;
 934         dpcd_set_training_pattern(link, dpcd_pattern);
 935 
 936         /* 4. mainlink output idle pattern*/
 937         dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
 938 
 939         /*
 940          * 5. post training adjust if required
 941          * If the upstream DPTX and downstream DPRX both support TPS4,
 942          * TPS4 must be used instead of POST_LT_ADJ_REQ.
 943          */
 944         if (link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED != 1 ||
 945                         get_supported_tp(link) == DP_TRAINING_PATTERN_SEQUENCE_4)
 946                 return status;
 947 
 948         if (status == LINK_TRAINING_SUCCESS &&
 949                 perform_post_lt_adj_req_sequence(link, lt_settings) == false)
 950                 status = LINK_TRAINING_LQA_FAIL;
 951 
 952         lane_count_set.bits.LANE_COUNT_SET = lt_settings->link_settings.lane_count;
 953         lane_count_set.bits.ENHANCED_FRAMING = lt_settings->enhanced_framing;
 954         lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
 955 
 956         core_link_write_dpcd(
 957                 link,
 958                 DP_LANE_COUNT_SET,
 959                 &lane_count_set.raw,
 960                 sizeof(lane_count_set));
 961 
 962         return status;
 963 }
 964 
 965 static void initialize_training_settings(
 966          struct dc_link *link,
 967         const struct dc_link_settings *link_setting,
 968         const struct dc_link_training_overrides *overrides,
 969         struct link_training_settings *lt_settings)
 970 {
 971         uint32_t lane;
 972 
 973         memset(lt_settings, '\0', sizeof(struct link_training_settings));
 974 
 975         /* Initialize link settings */
 976         lt_settings->link_settings.use_link_rate_set = link_setting->use_link_rate_set;
 977         lt_settings->link_settings.link_rate_set = link_setting->link_rate_set;
 978 
 979         if (link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN)
 980                 lt_settings->link_settings.link_rate = link->preferred_link_setting.link_rate;
 981         else
 982                 lt_settings->link_settings.link_rate = link_setting->link_rate;
 983 
 984         if (link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN)
 985                 lt_settings->link_settings.lane_count = link->preferred_link_setting.lane_count;
 986         else
 987                 lt_settings->link_settings.lane_count = link_setting->lane_count;
 988 
 989         /*@todo[vdevulap] move SS to LS, should not be handled by displaypath*/
 990 
 991         /* TODO hard coded to SS for now
 992          * lt_settings.link_settings.link_spread =
 993          * dal_display_path_is_ss_supported(
 994          * path_mode->display_path) ?
 995          * LINK_SPREAD_05_DOWNSPREAD_30KHZ :
 996          * LINK_SPREAD_DISABLED;
 997          */
 998         /* Initialize link spread */
 999         if (link->dp_ss_off)
1000                 lt_settings->link_settings.link_spread = LINK_SPREAD_DISABLED;
1001         else if (overrides->downspread != NULL)
1002                 lt_settings->link_settings.link_spread
1003                         = *overrides->downspread
1004                         ? LINK_SPREAD_05_DOWNSPREAD_30KHZ
1005                         : LINK_SPREAD_DISABLED;
1006         else
1007                 lt_settings->link_settings.link_spread = LINK_SPREAD_05_DOWNSPREAD_30KHZ;
1008 
1009         /* Initialize lane settings overrides */
1010         if (overrides->voltage_swing != NULL)
1011                 lt_settings->voltage_swing = overrides->voltage_swing;
1012 
1013         if (overrides->pre_emphasis != NULL)
1014                 lt_settings->pre_emphasis = overrides->pre_emphasis;
1015 
1016         if (overrides->post_cursor2 != NULL)
1017                 lt_settings->post_cursor2 = overrides->post_cursor2;
1018 
1019         /* Initialize lane settings (VS/PE/PC2) */
1020         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
1021                 lt_settings->lane_settings[lane].VOLTAGE_SWING =
1022                         lt_settings->voltage_swing != NULL ?
1023                         *lt_settings->voltage_swing :
1024                         VOLTAGE_SWING_LEVEL0;
1025                 lt_settings->lane_settings[lane].PRE_EMPHASIS =
1026                         lt_settings->pre_emphasis != NULL ?
1027                         *lt_settings->pre_emphasis
1028                         : PRE_EMPHASIS_DISABLED;
1029                 lt_settings->lane_settings[lane].POST_CURSOR2 =
1030                         lt_settings->post_cursor2 != NULL ?
1031                         *lt_settings->post_cursor2
1032                         : POST_CURSOR2_DISABLED;
1033         }
1034 
1035         /* Initialize training timings */
1036         if (overrides->cr_pattern_time != NULL)
1037                 lt_settings->cr_pattern_time = *overrides->cr_pattern_time;
1038         else
1039                 lt_settings->cr_pattern_time = get_training_aux_rd_interval(link, 100);
1040 
1041         if (overrides->eq_pattern_time != NULL)
1042                 lt_settings->eq_pattern_time = *overrides->eq_pattern_time;
1043         else
1044                 lt_settings->eq_pattern_time = get_training_aux_rd_interval(link, 400);
1045 
1046         if (overrides->pattern_for_eq != NULL)
1047                 lt_settings->pattern_for_eq = *overrides->pattern_for_eq;
1048         else
1049                 lt_settings->pattern_for_eq = get_supported_tp(link);
1050 
1051         if (overrides->enhanced_framing != NULL)
1052                 lt_settings->enhanced_framing = *overrides->enhanced_framing;
1053         else
1054                 lt_settings->enhanced_framing = 1;
1055 }
1056 
1057 static void print_status_message(
1058         struct dc_link *link,
1059         const struct link_training_settings *lt_settings,
1060         enum link_training_result status)
1061 {
1062         char *link_rate = "Unknown";
1063         char *lt_result = "Unknown";
1064         char *lt_spread = "Disabled";
1065 
1066         switch (lt_settings->link_settings.link_rate) {
1067         case LINK_RATE_LOW:
1068                 link_rate = "RBR";
1069                 break;
1070         case LINK_RATE_HIGH:
1071                 link_rate = "HBR";
1072                 break;
1073         case LINK_RATE_HIGH2:
1074                 link_rate = "HBR2";
1075                 break;
1076         case LINK_RATE_RBR2:
1077                 link_rate = "RBR2";
1078                 break;
1079         case LINK_RATE_HIGH3:
1080                 link_rate = "HBR3";
1081                 break;
1082         default:
1083                 break;
1084         }
1085 
1086         switch (status) {
1087         case LINK_TRAINING_SUCCESS:
1088                 lt_result = "pass";
1089                 break;
1090         case LINK_TRAINING_CR_FAIL_LANE0:
1091                 lt_result = "CR failed lane0";
1092                 break;
1093         case LINK_TRAINING_CR_FAIL_LANE1:
1094                 lt_result = "CR failed lane1";
1095                 break;
1096         case LINK_TRAINING_CR_FAIL_LANE23:
1097                 lt_result = "CR failed lane23";
1098                 break;
1099         case LINK_TRAINING_EQ_FAIL_CR:
1100                 lt_result = "CR failed in EQ";
1101                 break;
1102         case LINK_TRAINING_EQ_FAIL_EQ:
1103                 lt_result = "EQ failed";
1104                 break;
1105         case LINK_TRAINING_LQA_FAIL:
1106                 lt_result = "LQA failed";
1107                 break;
1108         default:
1109                 break;
1110         }
1111 
1112         switch (lt_settings->link_settings.link_spread) {
1113         case LINK_SPREAD_DISABLED:
1114                 lt_spread = "Disabled";
1115                 break;
1116         case LINK_SPREAD_05_DOWNSPREAD_30KHZ:
1117                 lt_spread = "0.5% 30KHz";
1118                 break;
1119         case LINK_SPREAD_05_DOWNSPREAD_33KHZ:
1120                 lt_spread = "0.5% 33KHz";
1121                 break;
1122         default:
1123                 break;
1124         }
1125 
1126         /* Connectivity log: link training */
1127         CONN_MSG_LT(link, "%sx%d %s VS=%d, PE=%d, DS=%s",
1128                                 link_rate,
1129                                 lt_settings->link_settings.lane_count,
1130                                 lt_result,
1131                                 lt_settings->lane_settings[0].VOLTAGE_SWING,
1132                                 lt_settings->lane_settings[0].PRE_EMPHASIS,
1133                                 lt_spread);
1134 }
1135 
1136 bool dc_link_dp_perform_link_training_skip_aux(
1137         struct dc_link *link,
1138         const struct dc_link_settings *link_setting)
1139 {
1140         struct link_training_settings lt_settings;
1141         enum dc_dp_training_pattern pattern_for_cr = DP_TRAINING_PATTERN_SEQUENCE_1;
1142 
1143         initialize_training_settings(
1144                         link,
1145                         link_setting,
1146                         &link->preferred_training_settings,
1147                         &lt_settings);
1148 
1149         /* 1. Perform_clock_recovery_sequence. */
1150 
1151         /* transmit training pattern for clock recovery */
1152         dp_set_hw_training_pattern(link, pattern_for_cr);
1153 
1154         /* call HWSS to set lane settings*/
1155         dp_set_hw_lane_settings(link, &lt_settings);
1156 
1157         /* wait receiver to lock-on*/
1158         wait_for_training_aux_rd_interval(link, lt_settings.cr_pattern_time);
1159 
1160         /* 2. Perform_channel_equalization_sequence. */
1161 
1162         /* transmit training pattern for channel equalization. */
1163         dp_set_hw_training_pattern(link, lt_settings.pattern_for_eq);
1164 
1165         /* call HWSS to set lane settings*/
1166         dp_set_hw_lane_settings(link, &lt_settings);
1167 
1168         /* wait receiver to lock-on. */
1169         wait_for_training_aux_rd_interval(link, lt_settings.eq_pattern_time);
1170 
1171         /* 3. Perform_link_training_int. */
1172 
1173         /* Mainlink output idle pattern. */
1174         dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
1175 
1176         print_status_message(link, &lt_settings, LINK_TRAINING_SUCCESS);
1177 
1178         return true;
1179 }
1180 
1181 enum link_training_result dc_link_dp_perform_link_training(
1182         struct dc_link *link,
1183         const struct dc_link_settings *link_setting,
1184         bool skip_video_pattern)
1185 {
1186         enum link_training_result status = LINK_TRAINING_SUCCESS;
1187         struct link_training_settings lt_settings;
1188 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
1189         bool fec_enable;
1190 #endif
1191 
1192         initialize_training_settings(
1193                         link,
1194                         link_setting,
1195                         &link->preferred_training_settings,
1196                         &lt_settings);
1197 
1198         /* 1. set link rate, lane count and spread. */
1199         dpcd_set_link_settings(link, &lt_settings);
1200 
1201 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
1202         if (link->preferred_training_settings.fec_enable != NULL)
1203                 fec_enable = *link->preferred_training_settings.fec_enable;
1204         else
1205                 fec_enable = true;
1206 
1207         dp_set_fec_ready(link, fec_enable);
1208 #endif
1209 
1210 
1211         /* 2. perform link training (set link training done
1212          *  to false is done as well)
1213          */
1214         status = perform_clock_recovery_sequence(link, &lt_settings);
1215         if (status == LINK_TRAINING_SUCCESS) {
1216                 status = perform_channel_equalization_sequence(link,
1217                                 &lt_settings);
1218         }
1219 
1220         if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern) {
1221                 status = perform_link_training_int(link,
1222                                 &lt_settings,
1223                                 status);
1224         }
1225 
1226         /* 6. print status message*/
1227         print_status_message(link, &lt_settings, status);
1228 
1229         if (status != LINK_TRAINING_SUCCESS)
1230                 link->ctx->dc->debug_data.ltFailCount++;
1231 
1232         return status;
1233 }
1234 
1235 bool perform_link_training_with_retries(
1236         struct dc_link *link,
1237         const struct dc_link_settings *link_setting,
1238         bool skip_video_pattern,
1239         int attempts)
1240 {
1241         uint8_t j;
1242         uint8_t delay_between_attempts = LINK_TRAINING_RETRY_DELAY;
1243 
1244         for (j = 0; j < attempts; ++j) {
1245 
1246                 if (dc_link_dp_perform_link_training(
1247                                 link,
1248                                 link_setting,
1249                                 skip_video_pattern) == LINK_TRAINING_SUCCESS)
1250                         return true;
1251 
1252                 msleep(delay_between_attempts);
1253                 delay_between_attempts += LINK_TRAINING_RETRY_DELAY;
1254         }
1255 
1256         return false;
1257 }
1258 
1259 static enum clock_source_id get_clock_source_id(struct dc_link *link)
1260 {
1261         enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_UNDEFINED;
1262         struct clock_source *dp_cs = link->dc->res_pool->dp_clock_source;
1263 
1264         if (dp_cs != NULL) {
1265                 dp_cs_id = dp_cs->id;
1266         } else {
1267                 /*
1268                  * dp clock source is not initialized for some reason.
1269                  * Should not happen, CLOCK_SOURCE_ID_EXTERNAL will be used
1270                  */
1271                 ASSERT(dp_cs);
1272         }
1273 
1274         return dp_cs_id;
1275 }
1276 
1277 static void set_dp_mst_mode(struct dc_link *link, bool mst_enable)
1278 {
1279         if (mst_enable == false &&
1280                 link->type == dc_connection_mst_branch) {
1281                 /* Disable MST on link. Use only local sink. */
1282                 dp_disable_link_phy_mst(link, link->connector_signal);
1283 
1284                 link->type = dc_connection_single;
1285                 link->local_sink = link->remote_sinks[0];
1286                 link->local_sink->sink_signal = SIGNAL_TYPE_DISPLAY_PORT;
1287         } else if (mst_enable == true &&
1288                         link->type == dc_connection_single &&
1289                         link->remote_sinks[0] != NULL) {
1290                 /* Re-enable MST on link. */
1291                 dp_disable_link_phy(link, link->connector_signal);
1292                 dp_enable_mst_on_sink(link, true);
1293 
1294                 link->type = dc_connection_mst_branch;
1295                 link->local_sink->sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
1296         }
1297 }
1298 
1299 bool dc_link_dp_sync_lt_begin(struct dc_link *link)
1300 {
1301         /* Begin Sync LT. During this time,
1302          * DPCD:600h must not be powered down.
1303          */
1304         link->sync_lt_in_progress = true;
1305 
1306         /*Clear any existing preferred settings.*/
1307         memset(&link->preferred_training_settings, 0,
1308                 sizeof(struct dc_link_training_overrides));
1309         memset(&link->preferred_link_setting, 0,
1310                 sizeof(struct dc_link_settings));
1311 
1312         return true;
1313 }
1314 
1315 enum link_training_result dc_link_dp_sync_lt_attempt(
1316     struct dc_link *link,
1317     struct dc_link_settings *link_settings,
1318     struct dc_link_training_overrides *lt_overrides)
1319 {
1320         struct link_training_settings lt_settings;
1321         enum link_training_result lt_status = LINK_TRAINING_SUCCESS;
1322         enum dp_panel_mode panel_mode = DP_PANEL_MODE_DEFAULT;
1323         enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL;
1324 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
1325         bool fec_enable = false;
1326 #endif
1327 
1328         initialize_training_settings(
1329                 link,
1330                 link_settings,
1331                 lt_overrides,
1332                 &lt_settings);
1333 
1334         /* Setup MST Mode */
1335         if (lt_overrides->mst_enable)
1336                 set_dp_mst_mode(link, *lt_overrides->mst_enable);
1337 
1338         /* Disable link */
1339         dp_disable_link_phy(link, link->connector_signal);
1340 
1341         /* Enable link */
1342         dp_cs_id = get_clock_source_id(link);
1343         dp_enable_link_phy(link, link->connector_signal,
1344                 dp_cs_id, link_settings);
1345 
1346 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
1347         /* Set FEC enable */
1348         fec_enable = lt_overrides->fec_enable && *lt_overrides->fec_enable;
1349         dp_set_fec_ready(link, fec_enable);
1350 #endif
1351 
1352         if (lt_overrides->alternate_scrambler_reset) {
1353                 if (*lt_overrides->alternate_scrambler_reset)
1354                         panel_mode = DP_PANEL_MODE_EDP;
1355                 else
1356                         panel_mode = DP_PANEL_MODE_DEFAULT;
1357         } else
1358                 panel_mode = dp_get_panel_mode(link);
1359 
1360         dp_set_panel_mode(link, panel_mode);
1361 
1362         /* Attempt to train with given link training settings */
1363 
1364         /* Set link rate, lane count and spread. */
1365         dpcd_set_link_settings(link, &lt_settings);
1366 
1367         /* 2. perform link training (set link training done
1368          *  to false is done as well)
1369          */
1370         lt_status = perform_clock_recovery_sequence(link, &lt_settings);
1371         if (lt_status == LINK_TRAINING_SUCCESS) {
1372                 lt_status = perform_channel_equalization_sequence(link,
1373                                                 &lt_settings);
1374         }
1375 
1376         /* 3. Sync LT must skip TRAINING_PATTERN_SET:0 (video pattern)*/
1377         /* 4. print status message*/
1378         print_status_message(link, &lt_settings, lt_status);
1379 
1380         return lt_status;
1381 }
1382 
1383 bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down)
1384 {
1385         /* If input parameter is set, shut down phy.
1386          * Still shouldn't turn off dp_receiver (DPCD:600h)
1387          */
1388         if (link_down == true) {
1389                 dp_disable_link_phy(link, link->connector_signal);
1390 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
1391                 dp_set_fec_ready(link, false);
1392 #endif
1393         }
1394 
1395         link->sync_lt_in_progress = false;
1396         return true;
1397 }
1398 
1399 static struct dc_link_settings get_max_link_cap(struct dc_link *link)
1400 {
1401         /* Set Default link settings */
1402         struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
1403                         LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
1404 
1405         /* Higher link settings based on feature supported */
1406         if (link->link_enc->features.flags.bits.IS_HBR2_CAPABLE)
1407                 max_link_cap.link_rate = LINK_RATE_HIGH2;
1408 
1409         if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE)
1410                 max_link_cap.link_rate = LINK_RATE_HIGH3;
1411 
1412         /* Lower link settings based on sink's link cap */
1413         if (link->reported_link_cap.lane_count < max_link_cap.lane_count)
1414                 max_link_cap.lane_count =
1415                                 link->reported_link_cap.lane_count;
1416         if (link->reported_link_cap.link_rate < max_link_cap.link_rate)
1417                 max_link_cap.link_rate =
1418                                 link->reported_link_cap.link_rate;
1419         if (link->reported_link_cap.link_spread <
1420                         max_link_cap.link_spread)
1421                 max_link_cap.link_spread =
1422                                 link->reported_link_cap.link_spread;
1423         return max_link_cap;
1424 }
1425 
1426 static enum dc_status read_hpd_rx_irq_data(
1427         struct dc_link *link,
1428         union hpd_irq_data *irq_data)
1429 {
1430         static enum dc_status retval;
1431 
1432         /* The HW reads 16 bytes from 200h on HPD,
1433          * but if we get an AUX_DEFER, the HW cannot retry
1434          * and this causes the CTS tests 4.3.2.1 - 3.2.4 to
1435          * fail, so we now explicitly read 6 bytes which is
1436          * the req from the above mentioned test cases.
1437          *
1438          * For DP 1.4 we need to read those from 2002h range.
1439          */
1440         if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14)
1441                 retval = core_link_read_dpcd(
1442                         link,
1443                         DP_SINK_COUNT,
1444                         irq_data->raw,
1445                         sizeof(union hpd_irq_data));
1446         else {
1447                 /* Read 14 bytes in a single read and then copy only the required fields.
1448                  * This is more efficient than doing it in two separate AUX reads. */
1449 
1450                 uint8_t tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI + 1];
1451 
1452                 retval = core_link_read_dpcd(
1453                         link,
1454                         DP_SINK_COUNT_ESI,
1455                         tmp,
1456                         sizeof(tmp));
1457 
1458                 if (retval != DC_OK)
1459                         return retval;
1460 
1461                 irq_data->bytes.sink_cnt.raw = tmp[DP_SINK_COUNT_ESI - DP_SINK_COUNT_ESI];
1462                 irq_data->bytes.device_service_irq.raw = tmp[DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 - DP_SINK_COUNT_ESI];
1463                 irq_data->bytes.lane01_status.raw = tmp[DP_LANE0_1_STATUS_ESI - DP_SINK_COUNT_ESI];
1464                 irq_data->bytes.lane23_status.raw = tmp[DP_LANE2_3_STATUS_ESI - DP_SINK_COUNT_ESI];
1465                 irq_data->bytes.lane_status_updated.raw = tmp[DP_LANE_ALIGN_STATUS_UPDATED_ESI - DP_SINK_COUNT_ESI];
1466                 irq_data->bytes.sink_status.raw = tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI];
1467         }
1468 
1469         return retval;
1470 }
1471 
1472 static bool hpd_rx_irq_check_link_loss_status(
1473         struct dc_link *link,
1474         union hpd_irq_data *hpd_irq_dpcd_data)
1475 {
1476         uint8_t irq_reg_rx_power_state = 0;
1477         enum dc_status dpcd_result = DC_ERROR_UNEXPECTED;
1478         union lane_status lane_status;
1479         uint32_t lane;
1480         bool sink_status_changed;
1481         bool return_code;
1482 
1483         sink_status_changed = false;
1484         return_code = false;
1485 
1486         if (link->cur_link_settings.lane_count == 0)
1487                 return return_code;
1488 
1489         /*1. Check that Link Status changed, before re-training.*/
1490 
1491         /*parse lane status*/
1492         for (lane = 0; lane < link->cur_link_settings.lane_count; lane++) {
1493                 /* check status of lanes 0,1
1494                  * changed DpcdAddress_Lane01Status (0x202)
1495                  */
1496                 lane_status.raw = get_nibble_at_index(
1497                         &hpd_irq_dpcd_data->bytes.lane01_status.raw,
1498                         lane);
1499 
1500                 if (!lane_status.bits.CHANNEL_EQ_DONE_0 ||
1501                         !lane_status.bits.CR_DONE_0 ||
1502                         !lane_status.bits.SYMBOL_LOCKED_0) {
1503                         /* if one of the channel equalization, clock
1504                          * recovery or symbol lock is dropped
1505                          * consider it as (link has been
1506                          * dropped) dp sink status has changed
1507                          */
1508                         sink_status_changed = true;
1509                         break;
1510                 }
1511         }
1512 
1513         /* Check interlane align.*/
1514         if (sink_status_changed ||
1515                 !hpd_irq_dpcd_data->bytes.lane_status_updated.bits.INTERLANE_ALIGN_DONE) {
1516 
1517                 DC_LOG_HW_HPD_IRQ("%s: Link Status changed.\n", __func__);
1518 
1519                 return_code = true;
1520 
1521                 /*2. Check that we can handle interrupt: Not in FS DOS,
1522                  *  Not in "Display Timeout" state, Link is trained.
1523                  */
1524                 dpcd_result = core_link_read_dpcd(link,
1525                         DP_SET_POWER,
1526                         &irq_reg_rx_power_state,
1527                         sizeof(irq_reg_rx_power_state));
1528 
1529                 if (dpcd_result != DC_OK) {
1530                         DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain power state.\n",
1531                                 __func__);
1532                 } else {
1533                         if (irq_reg_rx_power_state != DP_SET_POWER_D0)
1534                                 return_code = false;
1535                 }
1536         }
1537 
1538         return return_code;
1539 }
1540 
1541 bool dp_verify_link_cap(
1542         struct dc_link *link,
1543         struct dc_link_settings *known_limit_link_setting,
1544         int *fail_count)
1545 {
1546         struct dc_link_settings max_link_cap = {0};
1547         struct dc_link_settings cur_link_setting = {0};
1548         struct dc_link_settings *cur = &cur_link_setting;
1549         struct dc_link_settings initial_link_settings = {0};
1550         bool success;
1551         bool skip_link_training;
1552         bool skip_video_pattern;
1553         enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL;
1554         enum link_training_result status;
1555         union hpd_irq_data irq_data;
1556 
1557         if (link->dc->debug.skip_detection_link_training) {
1558                 link->verified_link_cap = *known_limit_link_setting;
1559                 return true;
1560         }
1561 
1562         memset(&irq_data, 0, sizeof(irq_data));
1563         success = false;
1564         skip_link_training = false;
1565 
1566         max_link_cap = get_max_link_cap(link);
1567 
1568         /* TODO implement override and monitor patch later */
1569 
1570         /* try to train the link from high to low to
1571          * find the physical link capability
1572          */
1573         /* disable PHY done possible by BIOS, will be done by driver itself */
1574         dp_disable_link_phy(link, link->connector_signal);
1575 
1576         dp_cs_id = get_clock_source_id(link);
1577 
1578         /* link training starts with the maximum common settings
1579          * supported by both sink and ASIC.
1580          */
1581         initial_link_settings = get_common_supported_link_settings(
1582                         *known_limit_link_setting,
1583                         max_link_cap);
1584         cur_link_setting = initial_link_settings;
1585         do {
1586                 skip_video_pattern = true;
1587 
1588                 if (cur->link_rate == LINK_RATE_LOW)
1589                         skip_video_pattern = false;
1590 
1591                 dp_enable_link_phy(
1592                                 link,
1593                                 link->connector_signal,
1594                                 dp_cs_id,
1595                                 cur);
1596 
1597 
1598                 if (skip_link_training)
1599                         success = true;
1600                 else {
1601                         status = dc_link_dp_perform_link_training(
1602                                                         link,
1603                                                         cur,
1604                                                         skip_video_pattern);
1605                         if (status == LINK_TRAINING_SUCCESS)
1606                                 success = true;
1607                         else
1608                                 (*fail_count)++;
1609                 }
1610 
1611                 if (success) {
1612                         link->verified_link_cap = *cur;
1613                         udelay(1000);
1614                         if (read_hpd_rx_irq_data(link, &irq_data) == DC_OK)
1615                                 if (hpd_rx_irq_check_link_loss_status(
1616                                                 link,
1617                                                 &irq_data))
1618                                         (*fail_count)++;
1619                 }
1620                 /* always disable the link before trying another
1621                  * setting or before returning we'll enable it later
1622                  * based on the actual mode we're driving
1623                  */
1624                 dp_disable_link_phy(link, link->connector_signal);
1625         } while (!success && decide_fallback_link_setting(
1626                         initial_link_settings, cur, status));
1627 
1628         /* Link Training failed for all Link Settings
1629          *  (Lane Count is still unknown)
1630          */
1631         if (!success) {
1632                 /* If all LT fails for all settings,
1633                  * set verified = failed safe (1 lane low)
1634                  */
1635                 link->verified_link_cap.lane_count = LANE_COUNT_ONE;
1636                 link->verified_link_cap.link_rate = LINK_RATE_LOW;
1637 
1638                 link->verified_link_cap.link_spread =
1639                 LINK_SPREAD_DISABLED;
1640         }
1641 
1642 
1643         return success;
1644 }
1645 
1646 bool dp_verify_link_cap_with_retries(
1647         struct dc_link *link,
1648         struct dc_link_settings *known_limit_link_setting,
1649         int attempts)
1650 {
1651         uint8_t i = 0;
1652         bool success = false;
1653 
1654         for (i = 0; i < attempts; i++) {
1655                 int fail_count = 0;
1656                 enum dc_connection_type type;
1657 
1658                 memset(&link->verified_link_cap, 0,
1659                                 sizeof(struct dc_link_settings));
1660                 if (!dc_link_detect_sink(link, &type)) {
1661                         break;
1662                 } else if (dp_verify_link_cap(link,
1663                                 &link->reported_link_cap,
1664                                 &fail_count) && fail_count == 0) {
1665                         success = true;
1666                         break;
1667                 }
1668                 msleep(10);
1669         }
1670         return success;
1671 }
1672 
1673 static struct dc_link_settings get_common_supported_link_settings(
1674                 struct dc_link_settings link_setting_a,
1675                 struct dc_link_settings link_setting_b)
1676 {
1677         struct dc_link_settings link_settings = {0};
1678 
1679         link_settings.lane_count =
1680                 (link_setting_a.lane_count <=
1681                         link_setting_b.lane_count) ?
1682                         link_setting_a.lane_count :
1683                         link_setting_b.lane_count;
1684         link_settings.link_rate =
1685                 (link_setting_a.link_rate <=
1686                         link_setting_b.link_rate) ?
1687                         link_setting_a.link_rate :
1688                         link_setting_b.link_rate;
1689         link_settings.link_spread = LINK_SPREAD_DISABLED;
1690 
1691         /* in DP compliance test, DPR-120 may have
1692          * a random value in its MAX_LINK_BW dpcd field.
1693          * We map it to the maximum supported link rate that
1694          * is smaller than MAX_LINK_BW in this case.
1695          */
1696         if (link_settings.link_rate > LINK_RATE_HIGH3) {
1697                 link_settings.link_rate = LINK_RATE_HIGH3;
1698         } else if (link_settings.link_rate < LINK_RATE_HIGH3
1699                         && link_settings.link_rate > LINK_RATE_HIGH2) {
1700                 link_settings.link_rate = LINK_RATE_HIGH2;
1701         } else if (link_settings.link_rate < LINK_RATE_HIGH2
1702                         && link_settings.link_rate > LINK_RATE_HIGH) {
1703                 link_settings.link_rate = LINK_RATE_HIGH;
1704         } else if (link_settings.link_rate < LINK_RATE_HIGH
1705                         && link_settings.link_rate > LINK_RATE_LOW) {
1706                 link_settings.link_rate = LINK_RATE_LOW;
1707         } else if (link_settings.link_rate < LINK_RATE_LOW) {
1708                 link_settings.link_rate = LINK_RATE_UNKNOWN;
1709         }
1710 
1711         return link_settings;
1712 }
1713 
1714 static inline bool reached_minimum_lane_count(enum dc_lane_count lane_count)
1715 {
1716         return lane_count <= LANE_COUNT_ONE;
1717 }
1718 
1719 static inline bool reached_minimum_link_rate(enum dc_link_rate link_rate)
1720 {
1721         return link_rate <= LINK_RATE_LOW;
1722 }
1723 
1724 static enum dc_lane_count reduce_lane_count(enum dc_lane_count lane_count)
1725 {
1726         switch (lane_count) {
1727         case LANE_COUNT_FOUR:
1728                 return LANE_COUNT_TWO;
1729         case LANE_COUNT_TWO:
1730                 return LANE_COUNT_ONE;
1731         case LANE_COUNT_ONE:
1732                 return LANE_COUNT_UNKNOWN;
1733         default:
1734                 return LANE_COUNT_UNKNOWN;
1735         }
1736 }
1737 
1738 static enum dc_link_rate reduce_link_rate(enum dc_link_rate link_rate)
1739 {
1740         switch (link_rate) {
1741         case LINK_RATE_HIGH3:
1742                 return LINK_RATE_HIGH2;
1743         case LINK_RATE_HIGH2:
1744                 return LINK_RATE_HIGH;
1745         case LINK_RATE_HIGH:
1746                 return LINK_RATE_LOW;
1747         case LINK_RATE_LOW:
1748                 return LINK_RATE_UNKNOWN;
1749         default:
1750                 return LINK_RATE_UNKNOWN;
1751         }
1752 }
1753 
1754 static enum dc_lane_count increase_lane_count(enum dc_lane_count lane_count)
1755 {
1756         switch (lane_count) {
1757         case LANE_COUNT_ONE:
1758                 return LANE_COUNT_TWO;
1759         case LANE_COUNT_TWO:
1760                 return LANE_COUNT_FOUR;
1761         default:
1762                 return LANE_COUNT_UNKNOWN;
1763         }
1764 }
1765 
1766 static enum dc_link_rate increase_link_rate(enum dc_link_rate link_rate)
1767 {
1768         switch (link_rate) {
1769         case LINK_RATE_LOW:
1770                 return LINK_RATE_HIGH;
1771         case LINK_RATE_HIGH:
1772                 return LINK_RATE_HIGH2;
1773         case LINK_RATE_HIGH2:
1774                 return LINK_RATE_HIGH3;
1775         default:
1776                 return LINK_RATE_UNKNOWN;
1777         }
1778 }
1779 
1780 /*
1781  * function: set link rate and lane count fallback based
1782  * on current link setting and last link training result
1783  * return value:
1784  *                      true - link setting could be set
1785  *                      false - has reached minimum setting
1786  *                                      and no further fallback could be done
1787  */
1788 static bool decide_fallback_link_setting(
1789                 struct dc_link_settings initial_link_settings,
1790                 struct dc_link_settings *current_link_setting,
1791                 enum link_training_result training_result)
1792 {
1793         if (!current_link_setting)
1794                 return false;
1795 
1796         switch (training_result) {
1797         case LINK_TRAINING_CR_FAIL_LANE0:
1798         case LINK_TRAINING_CR_FAIL_LANE1:
1799         case LINK_TRAINING_CR_FAIL_LANE23:
1800         case LINK_TRAINING_LQA_FAIL:
1801         {
1802                 if (!reached_minimum_link_rate
1803                                 (current_link_setting->link_rate)) {
1804                         current_link_setting->link_rate =
1805                                 reduce_link_rate(
1806                                         current_link_setting->link_rate);
1807                 } else if (!reached_minimum_lane_count
1808                                 (current_link_setting->lane_count)) {
1809                         current_link_setting->link_rate =
1810                                 initial_link_settings.link_rate;
1811                         if (training_result == LINK_TRAINING_CR_FAIL_LANE0)
1812                                 return false;
1813                         else if (training_result == LINK_TRAINING_CR_FAIL_LANE1)
1814                                 current_link_setting->lane_count =
1815                                                 LANE_COUNT_ONE;
1816                         else if (training_result ==
1817                                         LINK_TRAINING_CR_FAIL_LANE23)
1818                                 current_link_setting->lane_count =
1819                                                 LANE_COUNT_TWO;
1820                         else
1821                                 current_link_setting->lane_count =
1822                                         reduce_lane_count(
1823                                         current_link_setting->lane_count);
1824                 } else {
1825                         return false;
1826                 }
1827                 break;
1828         }
1829         case LINK_TRAINING_EQ_FAIL_EQ:
1830         {
1831                 if (!reached_minimum_lane_count
1832                                 (current_link_setting->lane_count)) {
1833                         current_link_setting->lane_count =
1834                                 reduce_lane_count(
1835                                         current_link_setting->lane_count);
1836                 } else if (!reached_minimum_link_rate
1837                                 (current_link_setting->link_rate)) {
1838                         current_link_setting->link_rate =
1839                                 reduce_link_rate(
1840                                         current_link_setting->link_rate);
1841                 } else {
1842                         return false;
1843                 }
1844                 break;
1845         }
1846         case LINK_TRAINING_EQ_FAIL_CR:
1847         {
1848                 if (!reached_minimum_link_rate
1849                                 (current_link_setting->link_rate)) {
1850                         current_link_setting->link_rate =
1851                                 reduce_link_rate(
1852                                         current_link_setting->link_rate);
1853                 } else {
1854                         return false;
1855                 }
1856                 break;
1857         }
1858         default:
1859                 return false;
1860         }
1861         return true;
1862 }
1863 
1864 bool dp_validate_mode_timing(
1865         struct dc_link *link,
1866         const struct dc_crtc_timing *timing)
1867 {
1868         uint32_t req_bw;
1869         uint32_t max_bw;
1870 
1871         const struct dc_link_settings *link_setting;
1872 
1873         /*always DP fail safe mode*/
1874         if ((timing->pix_clk_100hz / 10) == (uint32_t) 25175 &&
1875                 timing->h_addressable == (uint32_t) 640 &&
1876                 timing->v_addressable == (uint32_t) 480)
1877                 return true;
1878 
1879         link_setting = dc_link_get_link_cap(link);
1880 
1881         /* TODO: DYNAMIC_VALIDATION needs to be implemented */
1882         /*if (flags.DYNAMIC_VALIDATION == 1 &&
1883                 link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)
1884                 link_setting = &link->verified_link_cap;
1885         */
1886 
1887         req_bw = dc_bandwidth_in_kbps_from_timing(timing);
1888         max_bw = dc_link_bandwidth_kbps(link, link_setting);
1889 
1890         if (req_bw <= max_bw) {
1891                 /* remember the biggest mode here, during
1892                  * initial link training (to get
1893                  * verified_link_cap), LS sends event about
1894                  * cannot train at reported cap to upper
1895                  * layer and upper layer will re-enumerate modes.
1896                  * this is not necessary if the lower
1897                  * verified_link_cap is enough to drive
1898                  * all the modes */
1899 
1900                 /* TODO: DYNAMIC_VALIDATION needs to be implemented */
1901                 /* if (flags.DYNAMIC_VALIDATION == 1)
1902                         dpsst->max_req_bw_for_verified_linkcap = dal_max(
1903                                 dpsst->max_req_bw_for_verified_linkcap, req_bw); */
1904                 return true;
1905         } else
1906                 return false;
1907 }
1908 
1909 static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw)
1910 {
1911         struct dc_link_settings initial_link_setting = {
1912                 LANE_COUNT_ONE, LINK_RATE_LOW, LINK_SPREAD_DISABLED, false, 0};
1913         struct dc_link_settings current_link_setting =
1914                         initial_link_setting;
1915         uint32_t link_bw;
1916 
1917         /* search for the minimum link setting that:
1918          * 1. is supported according to the link training result
1919          * 2. could support the b/w requested by the timing
1920          */
1921         while (current_link_setting.link_rate <=
1922                         link->verified_link_cap.link_rate) {
1923                 link_bw = dc_link_bandwidth_kbps(
1924                                 link,
1925                                 &current_link_setting);
1926                 if (req_bw <= link_bw) {
1927                         *link_setting = current_link_setting;
1928                         return true;
1929                 }
1930 
1931                 if (current_link_setting.lane_count <
1932                                 link->verified_link_cap.lane_count) {
1933                         current_link_setting.lane_count =
1934                                         increase_lane_count(
1935                                                         current_link_setting.lane_count);
1936                 } else {
1937                         current_link_setting.link_rate =
1938                                         increase_link_rate(
1939                                                         current_link_setting.link_rate);
1940                         current_link_setting.lane_count =
1941                                         initial_link_setting.lane_count;
1942                 }
1943         }
1944 
1945         return false;
1946 }
1947 
1948 static bool decide_edp_link_settings(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw)
1949 {
1950         struct dc_link_settings initial_link_setting;
1951         struct dc_link_settings current_link_setting;
1952         uint32_t link_bw;
1953 
1954         if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14 ||
1955                         link->dpcd_caps.edp_supported_link_rates_count == 0) {
1956                 *link_setting = link->verified_link_cap;
1957                 return true;
1958         }
1959 
1960         memset(&initial_link_setting, 0, sizeof(initial_link_setting));
1961         initial_link_setting.lane_count = LANE_COUNT_ONE;
1962         initial_link_setting.link_rate = link->dpcd_caps.edp_supported_link_rates[0];
1963         initial_link_setting.link_spread = LINK_SPREAD_DISABLED;
1964         initial_link_setting.use_link_rate_set = true;
1965         initial_link_setting.link_rate_set = 0;
1966         current_link_setting = initial_link_setting;
1967 
1968         /* search for the minimum link setting that:
1969          * 1. is supported according to the link training result
1970          * 2. could support the b/w requested by the timing
1971          */
1972         while (current_link_setting.link_rate <=
1973                         link->verified_link_cap.link_rate) {
1974                 link_bw = dc_link_bandwidth_kbps(
1975                                 link,
1976                                 &current_link_setting);
1977                 if (req_bw <= link_bw) {
1978                         *link_setting = current_link_setting;
1979                         return true;
1980                 }
1981 
1982                 if (current_link_setting.lane_count <
1983                                 link->verified_link_cap.lane_count) {
1984                         current_link_setting.lane_count =
1985                                         increase_lane_count(
1986                                                         current_link_setting.lane_count);
1987                 } else {
1988                         if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
1989                                 current_link_setting.link_rate_set++;
1990                                 current_link_setting.link_rate =
1991                                         link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
1992                                 current_link_setting.lane_count =
1993                                                                         initial_link_setting.lane_count;
1994                         } else
1995                                 break;
1996                 }
1997         }
1998         return false;
1999 }
2000 
2001 void decide_link_settings(struct dc_stream_state *stream,
2002         struct dc_link_settings *link_setting)
2003 {
2004         struct dc_link *link;
2005         uint32_t req_bw;
2006 
2007         req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing);
2008 
2009         link = stream->link;
2010 
2011         /* if preferred is specified through AMDDP, use it, if it's enough
2012          * to drive the mode
2013          */
2014         if (link->preferred_link_setting.lane_count !=
2015                         LANE_COUNT_UNKNOWN &&
2016                         link->preferred_link_setting.link_rate !=
2017                                         LINK_RATE_UNKNOWN) {
2018                 *link_setting =  link->preferred_link_setting;
2019                 return;
2020         }
2021 
2022         /* MST doesn't perform link training for now
2023          * TODO: add MST specific link training routine
2024          */
2025         if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
2026                 *link_setting = link->verified_link_cap;
2027                 return;
2028         }
2029 
2030         if (link->connector_signal == SIGNAL_TYPE_EDP) {
2031                 if (decide_edp_link_settings(link, link_setting, req_bw))
2032                         return;
2033         } else if (decide_dp_link_settings(link, link_setting, req_bw))
2034                 return;
2035 
2036         BREAK_TO_DEBUGGER();
2037         ASSERT(link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN);
2038 
2039         *link_setting = link->verified_link_cap;
2040 }
2041 
2042 /*************************Short Pulse IRQ***************************/
2043 static bool allow_hpd_rx_irq(const struct dc_link *link)
2044 {
2045         /*
2046          * Don't handle RX IRQ unless one of following is met:
2047          * 1) The link is established (cur_link_settings != unknown)
2048          * 2) We kicked off MST detection
2049          * 3) We know we're dealing with an active dongle
2050          */
2051 
2052         if ((link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) ||
2053                 (link->type == dc_connection_mst_branch) ||
2054                 is_dp_active_dongle(link))
2055                 return true;
2056 
2057         return false;
2058 }
2059 
2060 static bool handle_hpd_irq_psr_sink(const struct dc_link *link)
2061 {
2062         union dpcd_psr_configuration psr_configuration;
2063 
2064         if (!link->psr_enabled)
2065                 return false;
2066 
2067         dm_helpers_dp_read_dpcd(
2068                 link->ctx,
2069                 link,
2070                 368,/*DpcdAddress_PSR_Enable_Cfg*/
2071                 &psr_configuration.raw,
2072                 sizeof(psr_configuration.raw));
2073 
2074 
2075         if (psr_configuration.bits.ENABLE) {
2076                 unsigned char dpcdbuf[3] = {0};
2077                 union psr_error_status psr_error_status;
2078                 union psr_sink_psr_status psr_sink_psr_status;
2079 
2080                 dm_helpers_dp_read_dpcd(
2081                         link->ctx,
2082                         link,
2083                         0x2006, /*DpcdAddress_PSR_Error_Status*/
2084                         (unsigned char *) dpcdbuf,
2085                         sizeof(dpcdbuf));
2086 
2087                 /*DPCD 2006h   ERROR STATUS*/
2088                 psr_error_status.raw = dpcdbuf[0];
2089                 /*DPCD 2008h   SINK PANEL SELF REFRESH STATUS*/
2090                 psr_sink_psr_status.raw = dpcdbuf[2];
2091 
2092                 if (psr_error_status.bits.LINK_CRC_ERROR ||
2093                                 psr_error_status.bits.RFB_STORAGE_ERROR) {
2094                         /* Acknowledge and clear error bits */
2095                         dm_helpers_dp_write_dpcd(
2096                                 link->ctx,
2097                                 link,
2098                                 8198,/*DpcdAddress_PSR_Error_Status*/
2099                                 &psr_error_status.raw,
2100                                 sizeof(psr_error_status.raw));
2101 
2102                         /* PSR error, disable and re-enable PSR */
2103                         dc_link_set_psr_enable(link, false, true);
2104                         dc_link_set_psr_enable(link, true, true);
2105 
2106                         return true;
2107                 } else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
2108                                 PSR_SINK_STATE_ACTIVE_DISPLAY_FROM_SINK_RFB){
2109                         /* No error is detect, PSR is active.
2110                          * We should return with IRQ_HPD handled without
2111                          * checking for loss of sync since PSR would have
2112                          * powered down main link.
2113                          */
2114                         return true;
2115                 }
2116         }
2117         return false;
2118 }
2119 
2120 static void dp_test_send_link_training(struct dc_link *link)
2121 {
2122         struct dc_link_settings link_settings = {0};
2123 
2124         core_link_read_dpcd(
2125                         link,
2126                         DP_TEST_LANE_COUNT,
2127                         (unsigned char *)(&link_settings.lane_count),
2128                         1);
2129         core_link_read_dpcd(
2130                         link,
2131                         DP_TEST_LINK_RATE,
2132                         (unsigned char *)(&link_settings.link_rate),
2133                         1);
2134 
2135         /* Set preferred link settings */
2136         link->verified_link_cap.lane_count = link_settings.lane_count;
2137         link->verified_link_cap.link_rate = link_settings.link_rate;
2138 
2139         dp_retrain_link_dp_test(link, &link_settings, false);
2140 }
2141 
2142 /* TODO Raven hbr2 compliance eye output is unstable
2143  * (toggling on and off) with debugger break
2144  * This caueses intermittent PHY automation failure
2145  * Need to look into the root cause */
2146 static void dp_test_send_phy_test_pattern(struct dc_link *link)
2147 {
2148         union phy_test_pattern dpcd_test_pattern;
2149         union lane_adjust dpcd_lane_adjustment[2];
2150         unsigned char dpcd_post_cursor_2_adjustment = 0;
2151         unsigned char test_80_bit_pattern[
2152                         (DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
2153                         DP_TEST_80BIT_CUSTOM_PATTERN_7_0)+1] = {0};
2154         enum dp_test_pattern test_pattern;
2155         struct dc_link_training_settings link_settings;
2156         union lane_adjust dpcd_lane_adjust;
2157         unsigned int lane;
2158         struct link_training_settings link_training_settings;
2159         int i = 0;
2160 
2161         dpcd_test_pattern.raw = 0;
2162         memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment));
2163         memset(&link_settings, 0, sizeof(link_settings));
2164 
2165         /* get phy test pattern and pattern parameters from DP receiver */
2166         core_link_read_dpcd(
2167                         link,
2168                         DP_TEST_PHY_PATTERN,
2169                         &dpcd_test_pattern.raw,
2170                         sizeof(dpcd_test_pattern));
2171         core_link_read_dpcd(
2172                         link,
2173                         DP_ADJUST_REQUEST_LANE0_1,
2174                         &dpcd_lane_adjustment[0].raw,
2175                         sizeof(dpcd_lane_adjustment));
2176 
2177         /*get post cursor 2 parameters
2178          * For DP 1.1a or eariler, this DPCD register's value is 0
2179          * For DP 1.2 or later:
2180          * Bits 1:0 = POST_CURSOR2_LANE0; Bits 3:2 = POST_CURSOR2_LANE1
2181          * Bits 5:4 = POST_CURSOR2_LANE2; Bits 7:6 = POST_CURSOR2_LANE3
2182          */
2183         core_link_read_dpcd(
2184                         link,
2185                         DP_ADJUST_REQUEST_POST_CURSOR2,
2186                         &dpcd_post_cursor_2_adjustment,
2187                         sizeof(dpcd_post_cursor_2_adjustment));
2188 
2189         /* translate request */
2190         switch (dpcd_test_pattern.bits.PATTERN) {
2191         case PHY_TEST_PATTERN_D10_2:
2192                 test_pattern = DP_TEST_PATTERN_D102;
2193                 break;
2194         case PHY_TEST_PATTERN_SYMBOL_ERROR:
2195                 test_pattern = DP_TEST_PATTERN_SYMBOL_ERROR;
2196                 break;
2197         case PHY_TEST_PATTERN_PRBS7:
2198                 test_pattern = DP_TEST_PATTERN_PRBS7;
2199                 break;
2200         case PHY_TEST_PATTERN_80BIT_CUSTOM:
2201                 test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
2202                 break;
2203         case PHY_TEST_PATTERN_CP2520_1:
2204                 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
2205                 test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
2206                                 DP_TEST_PATTERN_TRAINING_PATTERN4 :
2207                                 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
2208                 break;
2209         case PHY_TEST_PATTERN_CP2520_2:
2210                 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
2211                 test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
2212                                 DP_TEST_PATTERN_TRAINING_PATTERN4 :
2213                                 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
2214                 break;
2215         case PHY_TEST_PATTERN_CP2520_3:
2216                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
2217                 break;
2218         default:
2219                 test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
2220         break;
2221         }
2222 
2223         if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM)
2224                 core_link_read_dpcd(
2225                                 link,
2226                                 DP_TEST_80BIT_CUSTOM_PATTERN_7_0,
2227                                 test_80_bit_pattern,
2228                                 sizeof(test_80_bit_pattern));
2229 
2230         /* prepare link training settings */
2231         link_settings.link = link->cur_link_settings;
2232 
2233         for (lane = 0; lane <
2234                 (unsigned int)(link->cur_link_settings.lane_count);
2235                 lane++) {
2236                 dpcd_lane_adjust.raw =
2237                         get_nibble_at_index(&dpcd_lane_adjustment[0].raw, lane);
2238                 link_settings.lane_settings[lane].VOLTAGE_SWING =
2239                         (enum dc_voltage_swing)
2240                         (dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE);
2241                 link_settings.lane_settings[lane].PRE_EMPHASIS =
2242                         (enum dc_pre_emphasis)
2243                         (dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE);
2244                 link_settings.lane_settings[lane].POST_CURSOR2 =
2245                         (enum dc_post_cursor2)
2246                         ((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
2247         }
2248 
2249         for (i = 0; i < 4; i++)
2250                 link_training_settings.lane_settings[i] =
2251                                 link_settings.lane_settings[i];
2252         link_training_settings.link_settings = link_settings.link;
2253         link_training_settings.allow_invalid_msa_timing_param = false;
2254         /*Usage: Measure DP physical lane signal
2255          * by DP SI test equipment automatically.
2256          * PHY test pattern request is generated by equipment via HPD interrupt.
2257          * HPD needs to be active all the time. HPD should be active
2258          * all the time. Do not touch it.
2259          * forward request to DS
2260          */
2261         dc_link_dp_set_test_pattern(
2262                 link,
2263                 test_pattern,
2264                 &link_training_settings,
2265                 test_80_bit_pattern,
2266                 (DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
2267                 DP_TEST_80BIT_CUSTOM_PATTERN_7_0)+1);
2268 }
2269 
2270 static void dp_test_send_link_test_pattern(struct dc_link *link)
2271 {
2272         union link_test_pattern dpcd_test_pattern;
2273         union test_misc dpcd_test_params;
2274         enum dp_test_pattern test_pattern;
2275 
2276         memset(&dpcd_test_pattern, 0, sizeof(dpcd_test_pattern));
2277         memset(&dpcd_test_params, 0, sizeof(dpcd_test_params));
2278 
2279         /* get link test pattern and pattern parameters */
2280         core_link_read_dpcd(
2281                         link,
2282                         DP_TEST_PATTERN,
2283                         &dpcd_test_pattern.raw,
2284                         sizeof(dpcd_test_pattern));
2285         core_link_read_dpcd(
2286                         link,
2287                         DP_TEST_MISC0,
2288                         &dpcd_test_params.raw,
2289                         sizeof(dpcd_test_params));
2290 
2291         switch (dpcd_test_pattern.bits.PATTERN) {
2292         case LINK_TEST_PATTERN_COLOR_RAMP:
2293                 test_pattern = DP_TEST_PATTERN_COLOR_RAMP;
2294         break;
2295         case LINK_TEST_PATTERN_VERTICAL_BARS:
2296                 test_pattern = DP_TEST_PATTERN_VERTICAL_BARS;
2297         break; /* black and white */
2298         case LINK_TEST_PATTERN_COLOR_SQUARES:
2299                 test_pattern = (dpcd_test_params.bits.DYN_RANGE ==
2300                                 TEST_DYN_RANGE_VESA ?
2301                                 DP_TEST_PATTERN_COLOR_SQUARES :
2302                                 DP_TEST_PATTERN_COLOR_SQUARES_CEA);
2303         break;
2304         default:
2305                 test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
2306         break;
2307         }
2308 
2309         dc_link_dp_set_test_pattern(
2310                         link,
2311                         test_pattern,
2312                         NULL,
2313                         NULL,
2314                         0);
2315 }
2316 
2317 static void handle_automated_test(struct dc_link *link)
2318 {
2319         union test_request test_request;
2320         union test_response test_response;
2321 
2322         memset(&test_request, 0, sizeof(test_request));
2323         memset(&test_response, 0, sizeof(test_response));
2324 
2325         core_link_read_dpcd(
2326                 link,
2327                 DP_TEST_REQUEST,
2328                 &test_request.raw,
2329                 sizeof(union test_request));
2330         if (test_request.bits.LINK_TRAINING) {
2331                 /* ACK first to let DP RX test box monitor LT sequence */
2332                 test_response.bits.ACK = 1;
2333                 core_link_write_dpcd(
2334                         link,
2335                         DP_TEST_RESPONSE,
2336                         &test_response.raw,
2337                         sizeof(test_response));
2338                 dp_test_send_link_training(link);
2339                 /* no acknowledge request is needed again */
2340                 test_response.bits.ACK = 0;
2341         }
2342         if (test_request.bits.LINK_TEST_PATTRN) {
2343                 dp_test_send_link_test_pattern(link);
2344                 test_response.bits.ACK = 1;
2345         }
2346         if (test_request.bits.PHY_TEST_PATTERN) {
2347                 dp_test_send_phy_test_pattern(link);
2348                 test_response.bits.ACK = 1;
2349         }
2350 
2351         /* send request acknowledgment */
2352         if (test_response.bits.ACK)
2353                 core_link_write_dpcd(
2354                         link,
2355                         DP_TEST_RESPONSE,
2356                         &test_response.raw,
2357                         sizeof(test_response));
2358 }
2359 
2360 bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss)
2361 {
2362         union hpd_irq_data hpd_irq_dpcd_data = { { { {0} } } };
2363         union device_service_irq device_service_clear = { { 0 } };
2364         enum dc_status result;
2365 
2366         bool status = false;
2367 
2368         if (out_link_loss)
2369                 *out_link_loss = false;
2370         /* For use cases related to down stream connection status change,
2371          * PSR and device auto test, refer to function handle_sst_hpd_irq
2372          * in DAL2.1*/
2373 
2374         DC_LOG_HW_HPD_IRQ("%s: Got short pulse HPD on link %d\n",
2375                 __func__, link->link_index);
2376 
2377 
2378          /* All the "handle_hpd_irq_xxx()" methods
2379                  * should be called only after
2380                  * dal_dpsst_ls_read_hpd_irq_data
2381                  * Order of calls is important too
2382                  */
2383         result = read_hpd_rx_irq_data(link, &hpd_irq_dpcd_data);
2384         if (out_hpd_irq_dpcd_data)
2385                 *out_hpd_irq_dpcd_data = hpd_irq_dpcd_data;
2386 
2387         if (result != DC_OK) {
2388                 DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain irq data\n",
2389                         __func__);
2390                 return false;
2391         }
2392 
2393         if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.AUTOMATED_TEST) {
2394                 device_service_clear.bits.AUTOMATED_TEST = 1;
2395                 core_link_write_dpcd(
2396                         link,
2397                         DP_DEVICE_SERVICE_IRQ_VECTOR,
2398                         &device_service_clear.raw,
2399                         sizeof(device_service_clear.raw));
2400                 device_service_clear.raw = 0;
2401                 handle_automated_test(link);
2402                 return false;
2403         }
2404 
2405         if (!allow_hpd_rx_irq(link)) {
2406                 DC_LOG_HW_HPD_IRQ("%s: skipping HPD handling on %d\n",
2407                         __func__, link->link_index);
2408                 return false;
2409         }
2410 
2411         if (handle_hpd_irq_psr_sink(link))
2412                 /* PSR-related error was detected and handled */
2413                 return true;
2414 
2415         /* If PSR-related error handled, Main link may be off,
2416          * so do not handle as a normal sink status change interrupt.
2417          */
2418 
2419         if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY)
2420                 return true;
2421 
2422         /* check if we have MST msg and return since we poll for it */
2423         if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY)
2424                 return false;
2425 
2426         /* For now we only handle 'Downstream port status' case.
2427          * If we got sink count changed it means
2428          * Downstream port status changed,
2429          * then DM should call DC to do the detection. */
2430         if (hpd_rx_irq_check_link_loss_status(
2431                 link,
2432                 &hpd_irq_dpcd_data)) {
2433                 /* Connectivity log: link loss */
2434                 CONN_DATA_LINK_LOSS(link,
2435                                         hpd_irq_dpcd_data.raw,
2436                                         sizeof(hpd_irq_dpcd_data),
2437                                         "Status: ");
2438 
2439                 perform_link_training_with_retries(link,
2440                         &link->cur_link_settings,
2441                         true, LINK_TRAINING_ATTEMPTS);
2442 
2443                 status = false;
2444                 if (out_link_loss)
2445                         *out_link_loss = true;
2446         }
2447 
2448         if (link->type == dc_connection_active_dongle &&
2449                 hpd_irq_dpcd_data.bytes.sink_cnt.bits.SINK_COUNT
2450                         != link->dpcd_sink_count)
2451                 status = true;
2452 
2453         /* reasons for HPD RX:
2454          * 1. Link Loss - ie Re-train the Link
2455          * 2. MST sideband message
2456          * 3. Automated Test - ie. Internal Commit
2457          * 4. CP (copy protection) - (not interesting for DM???)
2458          * 5. DRR
2459          * 6. Downstream Port status changed
2460          * -ie. Detect - this the only one
2461          * which is interesting for DM because
2462          * it must call dc_link_detect.
2463          */
2464         return status;
2465 }
2466 
2467 /*query dpcd for version and mst cap addresses*/
2468 bool is_mst_supported(struct dc_link *link)
2469 {
2470         bool mst          = false;
2471         enum dc_status st = DC_OK;
2472         union dpcd_rev rev;
2473         union mstm_cap cap;
2474 
2475         if (link->preferred_training_settings.mst_enable &&
2476                 *link->preferred_training_settings.mst_enable == false) {
2477                 return false;
2478         }
2479 
2480         rev.raw  = 0;
2481         cap.raw  = 0;
2482 
2483         st = core_link_read_dpcd(link, DP_DPCD_REV, &rev.raw,
2484                         sizeof(rev));
2485 
2486         if (st == DC_OK && rev.raw >= DPCD_REV_12) {
2487 
2488                 st = core_link_read_dpcd(link, DP_MSTM_CAP,
2489                                 &cap.raw, sizeof(cap));
2490                 if (st == DC_OK && cap.bits.MST_CAP == 1)
2491                         mst = true;
2492         }
2493         return mst;
2494 
2495 }
2496 
2497 bool is_dp_active_dongle(const struct dc_link *link)
2498 {
2499         return link->dpcd_caps.is_branch_dev;
2500 }
2501 
2502 static int translate_dpcd_max_bpc(enum dpcd_downstream_port_max_bpc bpc)
2503 {
2504         switch (bpc) {
2505         case DOWN_STREAM_MAX_8BPC:
2506                 return 8;
2507         case DOWN_STREAM_MAX_10BPC:
2508                 return 10;
2509         case DOWN_STREAM_MAX_12BPC:
2510                 return 12;
2511         case DOWN_STREAM_MAX_16BPC:
2512                 return 16;
2513         default:
2514                 break;
2515         }
2516 
2517         return -1;
2518 }
2519 
2520 static void read_dp_device_vendor_id(struct dc_link *link)
2521 {
2522         struct dp_device_vendor_id dp_id;
2523 
2524         /* read IEEE branch device id */
2525         core_link_read_dpcd(
2526                 link,
2527                 DP_BRANCH_OUI,
2528                 (uint8_t *)&dp_id,
2529                 sizeof(dp_id));
2530 
2531         link->dpcd_caps.branch_dev_id =
2532                 (dp_id.ieee_oui[0] << 16) +
2533                 (dp_id.ieee_oui[1] << 8) +
2534                 dp_id.ieee_oui[2];
2535 
2536         memmove(
2537                 link->dpcd_caps.branch_dev_name,
2538                 dp_id.ieee_device_id,
2539                 sizeof(dp_id.ieee_device_id));
2540 }
2541 
2542 
2543 
2544 static void get_active_converter_info(
2545         uint8_t data, struct dc_link *link)
2546 {
2547         union dp_downstream_port_present ds_port = { .byte = data };
2548         memset(&link->dpcd_caps.dongle_caps, 0, sizeof(link->dpcd_caps.dongle_caps));
2549 
2550         /* decode converter info*/
2551         if (!ds_port.fields.PORT_PRESENT) {
2552                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
2553                 ddc_service_set_dongle_type(link->ddc,
2554                                 link->dpcd_caps.dongle_type);
2555                 link->dpcd_caps.is_branch_dev = false;
2556                 return;
2557         }
2558 
2559         /* DPCD 0x5 bit 0 = 1, it indicate it's branch device */
2560         if (ds_port.fields.PORT_TYPE == DOWNSTREAM_DP) {
2561                 link->dpcd_caps.is_branch_dev = false;
2562         }
2563 
2564         else {
2565                 link->dpcd_caps.is_branch_dev = ds_port.fields.PORT_PRESENT;
2566         }
2567 
2568         switch (ds_port.fields.PORT_TYPE) {
2569         case DOWNSTREAM_VGA:
2570                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_VGA_CONVERTER;
2571                 break;
2572         case DOWNSTREAM_DVI_HDMI_DP_PLUS_PLUS:
2573                 /* At this point we don't know is it DVI or HDMI or DP++,
2574                  * assume DVI.*/
2575                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_DVI_CONVERTER;
2576                 break;
2577         default:
2578                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
2579                 break;
2580         }
2581 
2582         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_11) {
2583                 uint8_t det_caps[16]; /* CTS 4.2.2.7 expects source to read Detailed Capabilities Info : 00080h-0008F.*/
2584                 union dwnstream_port_caps_byte0 *port_caps =
2585                         (union dwnstream_port_caps_byte0 *)det_caps;
2586                 core_link_read_dpcd(link, DP_DOWNSTREAM_PORT_0,
2587                                 det_caps, sizeof(det_caps));
2588 
2589                 switch (port_caps->bits.DWN_STRM_PORTX_TYPE) {
2590                 /*Handle DP case as DONGLE_NONE*/
2591                 case DOWN_STREAM_DETAILED_DP:
2592                         link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
2593                         break;
2594                 case DOWN_STREAM_DETAILED_VGA:
2595                         link->dpcd_caps.dongle_type =
2596                                 DISPLAY_DONGLE_DP_VGA_CONVERTER;
2597                         break;
2598                 case DOWN_STREAM_DETAILED_DVI:
2599                         link->dpcd_caps.dongle_type =
2600                                 DISPLAY_DONGLE_DP_DVI_CONVERTER;
2601                         break;
2602                 case DOWN_STREAM_DETAILED_HDMI:
2603                 case DOWN_STREAM_DETAILED_DP_PLUS_PLUS:
2604                         /*Handle DP++ active converter case, process DP++ case as HDMI case according DP1.4 spec*/
2605                         link->dpcd_caps.dongle_type =
2606                                 DISPLAY_DONGLE_DP_HDMI_CONVERTER;
2607 
2608                         link->dpcd_caps.dongle_caps.dongle_type = link->dpcd_caps.dongle_type;
2609                         if (ds_port.fields.DETAILED_CAPS) {
2610 
2611                                 union dwnstream_port_caps_byte3_hdmi
2612                                         hdmi_caps = {.raw = det_caps[3] };
2613                                 union dwnstream_port_caps_byte2
2614                                         hdmi_color_caps = {.raw = det_caps[2] };
2615                                 link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz =
2616                                         det_caps[1] * 2500;
2617 
2618                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_s3d_converter =
2619                                         hdmi_caps.bits.FRAME_SEQ_TO_FRAME_PACK;
2620                                 /*YCBCR capability only for HDMI case*/
2621                                 if (port_caps->bits.DWN_STRM_PORTX_TYPE
2622                                                 == DOWN_STREAM_DETAILED_HDMI) {
2623                                         link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_pass_through =
2624                                                         hdmi_caps.bits.YCrCr422_PASS_THROUGH;
2625                                         link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_pass_through =
2626                                                         hdmi_caps.bits.YCrCr420_PASS_THROUGH;
2627                                         link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_converter =
2628                                                         hdmi_caps.bits.YCrCr422_CONVERSION;
2629                                         link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_converter =
2630                                                         hdmi_caps.bits.YCrCr420_CONVERSION;
2631                                 }
2632 
2633                                 link->dpcd_caps.dongle_caps.dp_hdmi_max_bpc =
2634                                         translate_dpcd_max_bpc(
2635                                                 hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT);
2636 
2637                                 if (link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz != 0)
2638                                         link->dpcd_caps.dongle_caps.extendedCapValid = true;
2639                         }
2640 
2641                         break;
2642                 }
2643         }
2644 
2645         ddc_service_set_dongle_type(link->ddc, link->dpcd_caps.dongle_type);
2646 
2647         {
2648                 struct dp_sink_hw_fw_revision dp_hw_fw_revision;
2649 
2650                 core_link_read_dpcd(
2651                         link,
2652                         DP_BRANCH_REVISION_START,
2653                         (uint8_t *)&dp_hw_fw_revision,
2654                         sizeof(dp_hw_fw_revision));
2655 
2656                 link->dpcd_caps.branch_hw_revision =
2657                         dp_hw_fw_revision.ieee_hw_rev;
2658 
2659                 memmove(
2660                         link->dpcd_caps.branch_fw_revision,
2661                         dp_hw_fw_revision.ieee_fw_rev,
2662                         sizeof(dp_hw_fw_revision.ieee_fw_rev));
2663         }
2664 }
2665 
2666 static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data,
2667                 int length)
2668 {
2669         int retry = 0;
2670         union dp_downstream_port_present ds_port = { 0 };
2671 
2672         if (!link->dpcd_caps.dpcd_rev.raw) {
2673                 do {
2674                         dp_receiver_power_ctrl(link, true);
2675                         core_link_read_dpcd(link, DP_DPCD_REV,
2676                                                         dpcd_data, length);
2677                         link->dpcd_caps.dpcd_rev.raw = dpcd_data[
2678                                 DP_DPCD_REV -
2679                                 DP_DPCD_REV];
2680                 } while (retry++ < 4 && !link->dpcd_caps.dpcd_rev.raw);
2681         }
2682 
2683         ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
2684                                  DP_DPCD_REV];
2685 
2686         if (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER) {
2687                 switch (link->dpcd_caps.branch_dev_id) {
2688                 /* 0010FA active dongles (DP-VGA, DP-DLDVI converters) power down
2689                  * all internal circuits including AUX communication preventing
2690                  * reading DPCD table and EDID (spec violation).
2691                  * Encoder will skip DP RX power down on disable_output to
2692                  * keep receiver powered all the time.*/
2693                 case DP_BRANCH_DEVICE_ID_0010FA:
2694                 case DP_BRANCH_DEVICE_ID_0080E1:
2695                 case DP_BRANCH_DEVICE_ID_00E04C:
2696                         link->wa_flags.dp_keep_receiver_powered = true;
2697                         break;
2698 
2699                 /* TODO: May need work around for other dongles. */
2700                 default:
2701                         link->wa_flags.dp_keep_receiver_powered = false;
2702                         break;
2703                 }
2704         } else
2705                 link->wa_flags.dp_keep_receiver_powered = false;
2706 }
2707 
2708 static bool retrieve_link_cap(struct dc_link *link)
2709 {
2710         uint8_t dpcd_data[DP_ADAPTER_CAP - DP_DPCD_REV + 1];
2711 
2712         /*Only need to read 1 byte starting from DP_DPRX_FEATURE_ENUMERATION_LIST.
2713          */
2714         uint8_t dpcd_dprx_data = '\0';
2715         uint8_t dpcd_power_state = '\0';
2716 
2717         struct dp_device_vendor_id sink_id;
2718         union down_stream_port_count down_strm_port_count;
2719         union edp_configuration_cap edp_config_cap;
2720         union dp_downstream_port_present ds_port = { 0 };
2721         enum dc_status status = DC_ERROR_UNEXPECTED;
2722         uint32_t read_dpcd_retry_cnt = 3;
2723         int i;
2724         struct dp_sink_hw_fw_revision dp_hw_fw_revision;
2725 
2726         memset(dpcd_data, '\0', sizeof(dpcd_data));
2727         memset(&down_strm_port_count,
2728                 '\0', sizeof(union down_stream_port_count));
2729         memset(&edp_config_cap, '\0',
2730                 sizeof(union edp_configuration_cap));
2731 
2732         status = core_link_read_dpcd(link, DP_SET_POWER,
2733                                 &dpcd_power_state, sizeof(dpcd_power_state));
2734 
2735         /* Delay 1 ms if AUX CH is in power down state. Based on spec
2736          * section 2.3.1.2, if AUX CH may be powered down due to
2737          * write to DPCD 600h = 2. Sink AUX CH is monitoring differential
2738          * signal and may need up to 1 ms before being able to reply.
2739          */
2740         if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3)
2741                 udelay(1000);
2742 
2743         for (i = 0; i < read_dpcd_retry_cnt; i++) {
2744                 status = core_link_read_dpcd(
2745                                 link,
2746                                 DP_DPCD_REV,
2747                                 dpcd_data,
2748                                 sizeof(dpcd_data));
2749                 if (status == DC_OK)
2750                         break;
2751         }
2752 
2753         if (status != DC_OK) {
2754                 dm_error("%s: Read dpcd data failed.\n", __func__);
2755                 return false;
2756         }
2757 
2758         {
2759                 union training_aux_rd_interval aux_rd_interval;
2760 
2761                 aux_rd_interval.raw =
2762                         dpcd_data[DP_TRAINING_AUX_RD_INTERVAL];
2763 
2764                 link->dpcd_caps.ext_receiver_cap_field_present =
2765                                 aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1 ? true:false;
2766 
2767                 if (aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1) {
2768                         uint8_t ext_cap_data[16];
2769 
2770                         memset(ext_cap_data, '\0', sizeof(ext_cap_data));
2771                         for (i = 0; i < read_dpcd_retry_cnt; i++) {
2772                                 status = core_link_read_dpcd(
2773                                 link,
2774                                 DP_DP13_DPCD_REV,
2775                                 ext_cap_data,
2776                                 sizeof(ext_cap_data));
2777                                 if (status == DC_OK) {
2778                                         memcpy(dpcd_data, ext_cap_data, sizeof(dpcd_data));
2779                                         break;
2780                                 }
2781                         }
2782                         if (status != DC_OK)
2783                                 dm_error("%s: Read extend caps data failed, use cap from dpcd 0.\n", __func__);
2784                 }
2785         }
2786 
2787         link->dpcd_caps.dpcd_rev.raw =
2788                         dpcd_data[DP_DPCD_REV - DP_DPCD_REV];
2789 
2790         if (link->dpcd_caps.dpcd_rev.raw >= 0x14) {
2791                 for (i = 0; i < read_dpcd_retry_cnt; i++) {
2792                         status = core_link_read_dpcd(
2793                                         link,
2794                                         DP_DPRX_FEATURE_ENUMERATION_LIST,
2795                                         &dpcd_dprx_data,
2796                                         sizeof(dpcd_dprx_data));
2797                         if (status == DC_OK)
2798                                 break;
2799                 }
2800 
2801                 link->dpcd_caps.dprx_feature.raw = dpcd_dprx_data;
2802 
2803                 if (status != DC_OK)
2804                         dm_error("%s: Read DPRX caps data failed.\n", __func__);
2805         }
2806 
2807         else {
2808                 link->dpcd_caps.dprx_feature.raw = 0;
2809         }
2810 
2811 
2812         /* Error condition checking...
2813          * It is impossible for Sink to report Max Lane Count = 0.
2814          * It is possible for Sink to report Max Link Rate = 0, if it is
2815          * an eDP device that is reporting specialized link rates in the
2816          * SUPPORTED_LINK_RATE table.
2817          */
2818         if (dpcd_data[DP_MAX_LANE_COUNT - DP_DPCD_REV] == 0)
2819                 return false;
2820 
2821         ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
2822                                  DP_DPCD_REV];
2823 
2824         read_dp_device_vendor_id(link);
2825 
2826         get_active_converter_info(ds_port.byte, link);
2827 
2828         dp_wa_power_up_0010FA(link, dpcd_data, sizeof(dpcd_data));
2829 
2830         down_strm_port_count.raw = dpcd_data[DP_DOWN_STREAM_PORT_COUNT -
2831                                  DP_DPCD_REV];
2832 
2833         link->dpcd_caps.allow_invalid_MSA_timing_param =
2834                 down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
2835 
2836         link->dpcd_caps.max_ln_count.raw = dpcd_data[
2837                 DP_MAX_LANE_COUNT - DP_DPCD_REV];
2838 
2839         link->dpcd_caps.max_down_spread.raw = dpcd_data[
2840                 DP_MAX_DOWNSPREAD - DP_DPCD_REV];
2841 
2842         link->reported_link_cap.lane_count =
2843                 link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
2844         link->reported_link_cap.link_rate = dpcd_data[
2845                 DP_MAX_LINK_RATE - DP_DPCD_REV];
2846         link->reported_link_cap.link_spread =
2847                 link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ?
2848                 LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
2849 
2850         edp_config_cap.raw = dpcd_data[
2851                 DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV];
2852         link->dpcd_caps.panel_mode_edp =
2853                 edp_config_cap.bits.ALT_SCRAMBLER_RESET;
2854         link->dpcd_caps.dpcd_display_control_capable =
2855                 edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE;
2856 
2857         link->test_pattern_enabled = false;
2858         link->compliance_test_state.raw = 0;
2859 
2860         /* read sink count */
2861         core_link_read_dpcd(link,
2862                         DP_SINK_COUNT,
2863                         &link->dpcd_caps.sink_count.raw,
2864                         sizeof(link->dpcd_caps.sink_count.raw));
2865 
2866         /* read sink ieee oui */
2867         core_link_read_dpcd(link,
2868                         DP_SINK_OUI,
2869                         (uint8_t *)(&sink_id),
2870                         sizeof(sink_id));
2871 
2872         link->dpcd_caps.sink_dev_id =
2873                         (sink_id.ieee_oui[0] << 16) +
2874                         (sink_id.ieee_oui[1] << 8) +
2875                         (sink_id.ieee_oui[2]);
2876 
2877         memmove(
2878                 link->dpcd_caps.sink_dev_id_str,
2879                 sink_id.ieee_device_id,
2880                 sizeof(sink_id.ieee_device_id));
2881 
2882         /* Quirk Apple MBP 2017 15" Retina panel: Wrong DP_MAX_LINK_RATE */
2883         {
2884                 uint8_t str_mbp_2017[] = { 101, 68, 21, 101, 98, 97 };
2885 
2886                 if ((link->dpcd_caps.sink_dev_id == 0x0010fa) &&
2887                     !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2017,
2888                             sizeof(str_mbp_2017))) {
2889                         link->reported_link_cap.link_rate = 0x0c;
2890                 }
2891         }
2892 
2893         core_link_read_dpcd(
2894                 link,
2895                 DP_SINK_HW_REVISION_START,
2896                 (uint8_t *)&dp_hw_fw_revision,
2897                 sizeof(dp_hw_fw_revision));
2898 
2899         link->dpcd_caps.sink_hw_revision =
2900                 dp_hw_fw_revision.ieee_hw_rev;
2901 
2902         memmove(
2903                 link->dpcd_caps.sink_fw_revision,
2904                 dp_hw_fw_revision.ieee_fw_rev,
2905                 sizeof(dp_hw_fw_revision.ieee_fw_rev));
2906 
2907 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
2908         memset(&link->dpcd_caps.dsc_caps, '\0',
2909                         sizeof(link->dpcd_caps.dsc_caps));
2910         memset(&link->dpcd_caps.fec_cap, '\0', sizeof(link->dpcd_caps.fec_cap));
2911         /* Read DSC and FEC sink capabilities if DP revision is 1.4 and up */
2912         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14) {
2913                 status = core_link_read_dpcd(
2914                                 link,
2915                                 DP_FEC_CAPABILITY,
2916                                 &link->dpcd_caps.fec_cap.raw,
2917                                 sizeof(link->dpcd_caps.fec_cap.raw));
2918                 status = core_link_read_dpcd(
2919                                 link,
2920                                 DP_DSC_SUPPORT,
2921                                 link->dpcd_caps.dsc_caps.dsc_basic_caps.raw,
2922                                 sizeof(link->dpcd_caps.dsc_caps.dsc_basic_caps.raw));
2923                 status = core_link_read_dpcd(
2924                                 link,
2925                                 DP_DSC_BRANCH_OVERALL_THROUGHPUT_0,
2926                                 link->dpcd_caps.dsc_caps.dsc_ext_caps.raw,
2927                                 sizeof(link->dpcd_caps.dsc_caps.dsc_ext_caps.raw));
2928         }
2929 #endif
2930 
2931         /* Connectivity log: detection */
2932         CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: ");
2933 
2934         return true;
2935 }
2936 
2937 bool detect_dp_sink_caps(struct dc_link *link)
2938 {
2939         return retrieve_link_cap(link);
2940 
2941         /* dc init_hw has power encoder using default
2942          * signal for connector. For native DP, no
2943          * need to power up encoder again. If not native
2944          * DP, hw_init may need check signal or power up
2945          * encoder here.
2946          */
2947         /* TODO save sink caps in link->sink */
2948 }
2949 
2950 enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in_khz)
2951 {
2952         enum dc_link_rate link_rate;
2953         // LinkRate is normally stored as a multiplier of 0.27 Gbps per lane. Do the translation.
2954         switch (link_rate_in_khz) {
2955         case 1620000:
2956                 link_rate = LINK_RATE_LOW;              // Rate_1 (RBR)         - 1.62 Gbps/Lane
2957                 break;
2958         case 2160000:
2959                 link_rate = LINK_RATE_RATE_2;   // Rate_2                       - 2.16 Gbps/Lane
2960                 break;
2961         case 2430000:
2962                 link_rate = LINK_RATE_RATE_3;   // Rate_3                       - 2.43 Gbps/Lane
2963                 break;
2964         case 2700000:
2965                 link_rate = LINK_RATE_HIGH;             // Rate_4 (HBR)         - 2.70 Gbps/Lane
2966                 break;
2967         case 3240000:
2968                 link_rate = LINK_RATE_RBR2;             // Rate_5 (RBR2)        - 3.24 Gbps/Lane
2969                 break;
2970         case 4320000:
2971                 link_rate = LINK_RATE_RATE_6;   // Rate_6                       - 4.32 Gbps/Lane
2972                 break;
2973         case 5400000:
2974                 link_rate = LINK_RATE_HIGH2;    // Rate_7 (HBR2)        - 5.40 Gbps/Lane
2975                 break;
2976         case 8100000:
2977                 link_rate = LINK_RATE_HIGH3;    // Rate_8 (HBR3)        - 8.10 Gbps/Lane
2978                 break;
2979         default:
2980                 link_rate = LINK_RATE_UNKNOWN;
2981                 break;
2982         }
2983         return link_rate;
2984 }
2985 
2986 void detect_edp_sink_caps(struct dc_link *link)
2987 {
2988         uint8_t supported_link_rates[16];
2989         uint32_t entry;
2990         uint32_t link_rate_in_khz;
2991         enum dc_link_rate link_rate = LINK_RATE_UNKNOWN;
2992 
2993         retrieve_link_cap(link);
2994         link->dpcd_caps.edp_supported_link_rates_count = 0;
2995         memset(supported_link_rates, 0, sizeof(supported_link_rates));
2996 
2997         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 &&
2998                         (link->dc->config.optimize_edp_link_rate ||
2999                         link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)) {
3000                 // Read DPCD 00010h - 0001Fh 16 bytes at one shot
3001                 core_link_read_dpcd(link, DP_SUPPORTED_LINK_RATES,
3002                                                         supported_link_rates, sizeof(supported_link_rates));
3003 
3004                 for (entry = 0; entry < 16; entry += 2) {
3005                         // DPCD register reports per-lane link rate = 16-bit link rate capability
3006                         // value X 200 kHz. Need multiplier to find link rate in kHz.
3007                         link_rate_in_khz = (supported_link_rates[entry+1] * 0x100 +
3008                                                                                 supported_link_rates[entry]) * 200;
3009 
3010                         if (link_rate_in_khz != 0) {
3011                                 link_rate = linkRateInKHzToLinkRateMultiplier(link_rate_in_khz);
3012                                 link->dpcd_caps.edp_supported_link_rates[link->dpcd_caps.edp_supported_link_rates_count] = link_rate;
3013                                 link->dpcd_caps.edp_supported_link_rates_count++;
3014 
3015                                 if (link->reported_link_cap.link_rate < link_rate)
3016                                         link->reported_link_cap.link_rate = link_rate;
3017                         }
3018                 }
3019         }
3020         link->verified_link_cap = link->reported_link_cap;
3021 }
3022 
3023 void dc_link_dp_enable_hpd(const struct dc_link *link)
3024 {
3025         struct link_encoder *encoder = link->link_enc;
3026 
3027         if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
3028                 encoder->funcs->enable_hpd(encoder);
3029 }
3030 
3031 void dc_link_dp_disable_hpd(const struct dc_link *link)
3032 {
3033         struct link_encoder *encoder = link->link_enc;
3034 
3035         if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
3036                 encoder->funcs->disable_hpd(encoder);
3037 }
3038 
3039 static bool is_dp_phy_pattern(enum dp_test_pattern test_pattern)
3040 {
3041         if ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern &&
3042                         test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) ||
3043                         test_pattern == DP_TEST_PATTERN_VIDEO_MODE)
3044                 return true;
3045         else
3046                 return false;
3047 }
3048 
3049 static void set_crtc_test_pattern(struct dc_link *link,
3050                                 struct pipe_ctx *pipe_ctx,
3051                                 enum dp_test_pattern test_pattern)
3052 {
3053         enum controller_dp_test_pattern controller_test_pattern;
3054         enum dc_color_depth color_depth = pipe_ctx->
3055                 stream->timing.display_color_depth;
3056         struct bit_depth_reduction_params params;
3057         struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
3058 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
3059         int width = pipe_ctx->stream->timing.h_addressable +
3060                 pipe_ctx->stream->timing.h_border_left +
3061                 pipe_ctx->stream->timing.h_border_right;
3062         int height = pipe_ctx->stream->timing.v_addressable +
3063                 pipe_ctx->stream->timing.v_border_bottom +
3064                 pipe_ctx->stream->timing.v_border_top;
3065 #endif
3066 
3067         memset(&params, 0, sizeof(params));
3068 
3069         switch (test_pattern) {
3070         case DP_TEST_PATTERN_COLOR_SQUARES:
3071                 controller_test_pattern =
3072                                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
3073         break;
3074         case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
3075                 controller_test_pattern =
3076                                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA;
3077         break;
3078         case DP_TEST_PATTERN_VERTICAL_BARS:
3079                 controller_test_pattern =
3080                                 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS;
3081         break;
3082         case DP_TEST_PATTERN_HORIZONTAL_BARS:
3083                 controller_test_pattern =
3084                                 CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS;
3085         break;
3086         case DP_TEST_PATTERN_COLOR_RAMP:
3087                 controller_test_pattern =
3088                                 CONTROLLER_DP_TEST_PATTERN_COLORRAMP;
3089         break;
3090         default:
3091                 controller_test_pattern =
3092                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
3093         break;
3094         }
3095 
3096         switch (test_pattern) {
3097         case DP_TEST_PATTERN_COLOR_SQUARES:
3098         case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
3099         case DP_TEST_PATTERN_VERTICAL_BARS:
3100         case DP_TEST_PATTERN_HORIZONTAL_BARS:
3101         case DP_TEST_PATTERN_COLOR_RAMP:
3102         {
3103                 /* disable bit depth reduction */
3104                 pipe_ctx->stream->bit_depth_params = params;
3105                 opp->funcs->opp_program_bit_depth_reduction(opp, &params);
3106                 if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
3107                         pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
3108                                 controller_test_pattern, color_depth);
3109 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
3110                 else if (opp->funcs->opp_set_disp_pattern_generator) {
3111                         struct pipe_ctx *odm_pipe;
3112                         int opp_cnt = 1;
3113 
3114                         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
3115                                 opp_cnt++;
3116 
3117                         width /= opp_cnt;
3118 
3119                         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
3120                                 struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
3121 
3122                                 odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
3123                                 odm_opp->funcs->opp_set_disp_pattern_generator(odm_opp,
3124                                         controller_test_pattern,
3125                                         color_depth,
3126                                         NULL,
3127                                         width,
3128                                         height);
3129                         }
3130                         opp->funcs->opp_set_disp_pattern_generator(opp,
3131                                 controller_test_pattern,
3132                                 color_depth,
3133                                 NULL,
3134                                 width,
3135                                 height);
3136                 }
3137 #endif
3138         }
3139         break;
3140         case DP_TEST_PATTERN_VIDEO_MODE:
3141         {
3142                 /* restore bitdepth reduction */
3143                 resource_build_bit_depth_reduction_params(pipe_ctx->stream, &params);
3144                 pipe_ctx->stream->bit_depth_params = params;
3145                 opp->funcs->opp_program_bit_depth_reduction(opp, &params);
3146                 if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
3147                         pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
3148                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
3149                                 color_depth);
3150 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
3151                 else if (opp->funcs->opp_set_disp_pattern_generator) {
3152                         struct pipe_ctx *odm_pipe;
3153                         int opp_cnt = 1;
3154 
3155                         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
3156                                 opp_cnt++;
3157 
3158                         width /= opp_cnt;
3159                         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
3160                                 struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
3161 
3162                                 odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
3163                                 odm_opp->funcs->opp_set_disp_pattern_generator(odm_opp,
3164                                         CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
3165                                         color_depth,
3166                                         NULL,
3167                                         width,
3168                                         height);
3169                         }
3170                         opp->funcs->opp_set_disp_pattern_generator(opp,
3171                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
3172                                 color_depth,
3173                                 NULL,
3174                                 width,
3175                                 height);
3176                 }
3177 #endif
3178         }
3179         break;
3180 
3181         default:
3182         break;
3183         }
3184 }
3185 
3186 bool dc_link_dp_set_test_pattern(
3187         struct dc_link *link,
3188         enum dp_test_pattern test_pattern,
3189         const struct link_training_settings *p_link_settings,
3190         const unsigned char *p_custom_pattern,
3191         unsigned int cust_pattern_size)
3192 {
3193         struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
3194         struct pipe_ctx *pipe_ctx = &pipes[0];
3195         unsigned int lane;
3196         unsigned int i;
3197         unsigned char link_qual_pattern[LANE_COUNT_DP_MAX] = {0};
3198         union dpcd_training_pattern training_pattern;
3199         enum dpcd_phy_test_patterns pattern;
3200 
3201         memset(&training_pattern, 0, sizeof(training_pattern));
3202 
3203         for (i = 0; i < MAX_PIPES; i++) {
3204                 if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) {
3205                         pipe_ctx = &pipes[i];
3206                         break;
3207                 }
3208         }
3209 
3210         /* Reset CRTC Test Pattern if it is currently running and request
3211          * is VideoMode Reset DP Phy Test Pattern if it is currently running
3212          * and request is VideoMode
3213          */
3214         if (link->test_pattern_enabled && test_pattern ==
3215                         DP_TEST_PATTERN_VIDEO_MODE) {
3216                 /* Set CRTC Test Pattern */
3217                 set_crtc_test_pattern(link, pipe_ctx, test_pattern);
3218                 dp_set_hw_test_pattern(link, test_pattern,
3219                                 (uint8_t *)p_custom_pattern,
3220                                 (uint32_t)cust_pattern_size);
3221 
3222                 /* Unblank Stream */
3223                 link->dc->hwss.unblank_stream(
3224                         pipe_ctx,
3225                         &link->verified_link_cap);
3226                 /* TODO:m_pHwss->MuteAudioEndpoint
3227                  * (pPathMode->pDisplayPath, false);
3228                  */
3229 
3230                 /* Reset Test Pattern state */
3231                 link->test_pattern_enabled = false;
3232 
3233                 return true;
3234         }
3235 
3236         /* Check for PHY Test Patterns */
3237         if (is_dp_phy_pattern(test_pattern)) {
3238                 /* Set DPCD Lane Settings before running test pattern */
3239                 if (p_link_settings != NULL) {
3240                         dp_set_hw_lane_settings(link, p_link_settings);
3241                         dpcd_set_lane_settings(link, p_link_settings);
3242                 }
3243 
3244                 /* Blank stream if running test pattern */
3245                 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
3246                         /*TODO:
3247                          * m_pHwss->
3248                          * MuteAudioEndpoint(pPathMode->pDisplayPath, true);
3249                          */
3250                         /* Blank stream */
3251                         pipes->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
3252                 }
3253 
3254                 dp_set_hw_test_pattern(link, test_pattern,
3255                                 (uint8_t *)p_custom_pattern,
3256                                 (uint32_t)cust_pattern_size);
3257 
3258                 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
3259                         /* Set Test Pattern state */
3260                         link->test_pattern_enabled = true;
3261                         if (p_link_settings != NULL)
3262                                 dpcd_set_link_settings(link,
3263                                                 p_link_settings);
3264                 }
3265 
3266                 switch (test_pattern) {
3267                 case DP_TEST_PATTERN_VIDEO_MODE:
3268                         pattern = PHY_TEST_PATTERN_NONE;
3269                         break;
3270                 case DP_TEST_PATTERN_D102:
3271                         pattern = PHY_TEST_PATTERN_D10_2;
3272                         break;
3273                 case DP_TEST_PATTERN_SYMBOL_ERROR:
3274                         pattern = PHY_TEST_PATTERN_SYMBOL_ERROR;
3275                         break;
3276                 case DP_TEST_PATTERN_PRBS7:
3277                         pattern = PHY_TEST_PATTERN_PRBS7;
3278                         break;
3279                 case DP_TEST_PATTERN_80BIT_CUSTOM:
3280                         pattern = PHY_TEST_PATTERN_80BIT_CUSTOM;
3281                         break;
3282                 case DP_TEST_PATTERN_CP2520_1:
3283                         pattern = PHY_TEST_PATTERN_CP2520_1;
3284                         break;
3285                 case DP_TEST_PATTERN_CP2520_2:
3286                         pattern = PHY_TEST_PATTERN_CP2520_2;
3287                         break;
3288                 case DP_TEST_PATTERN_CP2520_3:
3289                         pattern = PHY_TEST_PATTERN_CP2520_3;
3290                         break;
3291                 default:
3292                         return false;
3293                 }
3294 
3295                 if (test_pattern == DP_TEST_PATTERN_VIDEO_MODE
3296                 /*TODO:&& !pPathMode->pDisplayPath->IsTargetPoweredOn()*/)
3297                         return false;
3298 
3299                 if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
3300                         /* tell receiver that we are sending qualification
3301                          * pattern DP 1.2 or later - DP receiver's link quality
3302                          * pattern is set using DPCD LINK_QUAL_LANEx_SET
3303                          * register (0x10B~0x10E)\
3304                          */
3305                         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++)
3306                                 link_qual_pattern[lane] =
3307                                                 (unsigned char)(pattern);
3308 
3309                         core_link_write_dpcd(link,
3310                                         DP_LINK_QUAL_LANE0_SET,
3311                                         link_qual_pattern,
3312                                         sizeof(link_qual_pattern));
3313                 } else if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_10 ||
3314                            link->dpcd_caps.dpcd_rev.raw == 0) {
3315                         /* tell receiver that we are sending qualification
3316                          * pattern DP 1.1a or earlier - DP receiver's link
3317                          * quality pattern is set using
3318                          * DPCD TRAINING_PATTERN_SET -> LINK_QUAL_PATTERN_SET
3319                          * register (0x102). We will use v_1.3 when we are
3320                          * setting test pattern for DP 1.1.
3321                          */
3322                         core_link_read_dpcd(link, DP_TRAINING_PATTERN_SET,
3323                                             &training_pattern.raw,
3324                                             sizeof(training_pattern));
3325                         training_pattern.v1_3.LINK_QUAL_PATTERN_SET = pattern;
3326                         core_link_write_dpcd(link, DP_TRAINING_PATTERN_SET,
3327                                              &training_pattern.raw,
3328                                              sizeof(training_pattern));
3329                 }
3330         } else {
3331         /* CRTC Patterns */
3332                 set_crtc_test_pattern(link, pipe_ctx, test_pattern);
3333                 /* Set Test Pattern state */
3334                 link->test_pattern_enabled = true;
3335         }
3336 
3337         return true;
3338 }
3339 
3340 void dp_enable_mst_on_sink(struct dc_link *link, bool enable)
3341 {
3342         unsigned char mstmCntl;
3343 
3344         core_link_read_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
3345         if (enable)
3346                 mstmCntl |= DP_MST_EN;
3347         else
3348                 mstmCntl &= (~DP_MST_EN);
3349 
3350         core_link_write_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
3351 }
3352 
3353 void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode)
3354 {
3355         union dpcd_edp_config edp_config_set;
3356         bool panel_mode_edp = false;
3357 
3358         memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config));
3359 
3360         if (panel_mode != DP_PANEL_MODE_DEFAULT) {
3361 
3362                 switch (panel_mode) {
3363                 case DP_PANEL_MODE_EDP:
3364                 case DP_PANEL_MODE_SPECIAL:
3365                         panel_mode_edp = true;
3366                         break;
3367 
3368                 default:
3369                                 break;
3370                 }
3371 
3372                 /*set edp panel mode in receiver*/
3373                 core_link_read_dpcd(
3374                         link,
3375                         DP_EDP_CONFIGURATION_SET,
3376                         &edp_config_set.raw,
3377                         sizeof(edp_config_set.raw));
3378 
3379                 if (edp_config_set.bits.PANEL_MODE_EDP
3380                         != panel_mode_edp) {
3381                         enum ddc_result result = DDC_RESULT_UNKNOWN;
3382 
3383                         edp_config_set.bits.PANEL_MODE_EDP =
3384                         panel_mode_edp;
3385                         result = core_link_write_dpcd(
3386                                 link,
3387                                 DP_EDP_CONFIGURATION_SET,
3388                                 &edp_config_set.raw,
3389                                 sizeof(edp_config_set.raw));
3390 
3391                         ASSERT(result == DDC_RESULT_SUCESSFULL);
3392                 }
3393         }
3394         DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d "
3395                  "eDP panel mode enabled: %d \n",
3396                  link->link_index,
3397                  link->dpcd_caps.panel_mode_edp,
3398                  panel_mode_edp);
3399 }
3400 
3401 enum dp_panel_mode dp_get_panel_mode(struct dc_link *link)
3402 {
3403         /* We need to explicitly check that connector
3404          * is not DP. Some Travis_VGA get reported
3405          * by video bios as DP.
3406          */
3407         if (link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
3408 
3409                 switch (link->dpcd_caps.branch_dev_id) {
3410                 case DP_BRANCH_DEVICE_ID_0022B9:
3411                         /* alternate scrambler reset is required for Travis
3412                          * for the case when external chip does not
3413                          * provide sink device id, alternate scrambler
3414                          * scheme will  be overriden later by querying
3415                          * Encoder features
3416                          */
3417                         if (strncmp(
3418                                 link->dpcd_caps.branch_dev_name,
3419                                 DP_VGA_LVDS_CONVERTER_ID_2,
3420                                 sizeof(
3421                                 link->dpcd_caps.
3422                                 branch_dev_name)) == 0) {
3423                                         return DP_PANEL_MODE_SPECIAL;
3424                         }
3425                         break;
3426                 case DP_BRANCH_DEVICE_ID_00001A:
3427                         /* alternate scrambler reset is required for Travis
3428                          * for the case when external chip does not provide
3429                          * sink device id, alternate scrambler scheme will
3430                          * be overriden later by querying Encoder feature
3431                          */
3432                         if (strncmp(link->dpcd_caps.branch_dev_name,
3433                                 DP_VGA_LVDS_CONVERTER_ID_3,
3434                                 sizeof(
3435                                 link->dpcd_caps.
3436                                 branch_dev_name)) == 0) {
3437                                         return DP_PANEL_MODE_SPECIAL;
3438                         }
3439                         break;
3440                 default:
3441                         break;
3442                 }
3443         }
3444 
3445         if (link->dpcd_caps.panel_mode_edp) {
3446                 return DP_PANEL_MODE_EDP;
3447         }
3448 
3449         return DP_PANEL_MODE_DEFAULT;
3450 }
3451 
3452 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
3453 void dp_set_fec_ready(struct dc_link *link, bool ready)
3454 {
3455         /* FEC has to be "set ready" before the link training.
3456          * The policy is to always train with FEC
3457          * if the sink supports it and leave it enabled on link.
3458          * If FEC is not supported, disable it.
3459          */
3460         struct link_encoder *link_enc = link->link_enc;
3461         uint8_t fec_config = 0;
3462 
3463         if (link->dc->debug.disable_fec ||
3464                         IS_FPGA_MAXIMUS_DC(link->ctx->dce_environment))
3465                 return;
3466 
3467         if (link_enc->funcs->fec_set_ready &&
3468                         link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
3469                 if (ready) {
3470                         fec_config = 1;
3471                         if (core_link_write_dpcd(link,
3472                                         DP_FEC_CONFIGURATION,
3473                                         &fec_config,
3474                                         sizeof(fec_config)) == DC_OK) {
3475                                 link_enc->funcs->fec_set_ready(link_enc, true);
3476                                 link->fec_state = dc_link_fec_ready;
3477                         } else {
3478                                 link->link_enc->funcs->fec_set_ready(link->link_enc, false);
3479                                 link->fec_state = dc_link_fec_not_ready;
3480                                 dm_error("dpcd write failed to set fec_ready");
3481                         }
3482                 } else if (link->fec_state == dc_link_fec_ready) {
3483                         fec_config = 0;
3484                         core_link_write_dpcd(link,
3485                                         DP_FEC_CONFIGURATION,
3486                                         &fec_config,
3487                                         sizeof(fec_config));
3488                         link->link_enc->funcs->fec_set_ready(
3489                                         link->link_enc, false);
3490                         link->fec_state = dc_link_fec_not_ready;
3491                 }
3492         }
3493 }
3494 
3495 void dp_set_fec_enable(struct dc_link *link, bool enable)
3496 {
3497         struct link_encoder *link_enc = link->link_enc;
3498 
3499         if (link->dc->debug.disable_fec ||
3500                         IS_FPGA_MAXIMUS_DC(link->ctx->dce_environment))
3501                 return;
3502 
3503         if (link_enc->funcs->fec_set_enable &&
3504                         link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
3505                 if (link->fec_state == dc_link_fec_ready && enable) {
3506                         /* Accord to DP spec, FEC enable sequence can first
3507                          * be transmitted anytime after 1000 LL codes have
3508                          * been transmitted on the link after link training
3509                          * completion. Using 1 lane RBR should have the maximum
3510                          * time for transmitting 1000 LL codes which is 6.173 us.
3511                          * So use 7 microseconds delay instead.
3512                          */
3513                         udelay(7);
3514                         link_enc->funcs->fec_set_enable(link_enc, true);
3515                         link->fec_state = dc_link_fec_enabled;
3516                 } else if (link->fec_state == dc_link_fec_enabled && !enable) {
3517                         link_enc->funcs->fec_set_enable(link_enc, false);
3518                         link->fec_state = dc_link_fec_ready;
3519                 }
3520         }
3521 }
3522 #endif
3523 

/* [<][>][^][v][top][bottom][index][help] */