drm/amd/display: break down dc_link.c
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / link / link_detection.c
1 /*
2  * Copyright 2022 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25
26 /* FILE POLICY AND INTENDED USAGE:
27  * This file manages link detection states and receiver states by using various
28  * link protocols. It also provides helper functions to interpret certain
29  * capabilities or status based on the states it manages or retrieve them
30  * directly from connected receivers.
31  */
32
33 #include "link_detection.h"
34 #include "link_hwss.h"
35 #include "protocols/link_edp_panel_control.h"
36 #include "protocols/link_ddc.h"
37 #include "protocols/link_hpd.h"
38 #include "protocols/link_dpcd.h"
39 #include "protocols/link_dp_capability.h"
40 #include "protocols/link_dp_dpia.h"
41 #include "protocols/link_dp_phy.h"
42 #include "protocols/link_dp_training.h"
43 #include "accessories/link_dp_trace.h"
44
45 #include "link_enc_cfg.h"
46 #include "dm_helpers.h"
47 #include "clk_mgr.h"
48
49 #define DC_LOGGER_INIT(logger)
50
51 #define LINK_INFO(...) \
52         DC_LOG_HW_HOTPLUG(  \
53                 __VA_ARGS__)
54 /*
55  * Some receivers fail to train on first try and are good
56  * on subsequent tries. 2 retries should be plenty. If we
57  * don't have a successful training then we don't expect to
58  * ever get one.
59  */
60 #define LINK_TRAINING_MAX_VERIFY_RETRY 2
61
62 static enum ddc_transaction_type get_ddc_transaction_type(enum signal_type sink_signal)
63 {
64         enum ddc_transaction_type transaction_type = DDC_TRANSACTION_TYPE_NONE;
65
66         switch (sink_signal) {
67         case SIGNAL_TYPE_DVI_SINGLE_LINK:
68         case SIGNAL_TYPE_DVI_DUAL_LINK:
69         case SIGNAL_TYPE_HDMI_TYPE_A:
70         case SIGNAL_TYPE_LVDS:
71         case SIGNAL_TYPE_RGB:
72                 transaction_type = DDC_TRANSACTION_TYPE_I2C;
73                 break;
74
75         case SIGNAL_TYPE_DISPLAY_PORT:
76         case SIGNAL_TYPE_EDP:
77                 transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
78                 break;
79
80         case SIGNAL_TYPE_DISPLAY_PORT_MST:
81                 /* MST does not use I2COverAux, but there is the
82                  * SPECIAL use case for "immediate dwnstrm device
83                  * access" (EPR#370830).
84                  */
85                 transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
86                 break;
87
88         default:
89                 break;
90         }
91
92         return transaction_type;
93 }
94
95 static enum signal_type get_basic_signal_type(struct graphics_object_id encoder,
96                                               struct graphics_object_id downstream)
97 {
98         if (downstream.type == OBJECT_TYPE_CONNECTOR) {
99                 switch (downstream.id) {
100                 case CONNECTOR_ID_SINGLE_LINK_DVII:
101                         switch (encoder.id) {
102                         case ENCODER_ID_INTERNAL_DAC1:
103                         case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
104                         case ENCODER_ID_INTERNAL_DAC2:
105                         case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
106                                 return SIGNAL_TYPE_RGB;
107                         default:
108                                 return SIGNAL_TYPE_DVI_SINGLE_LINK;
109                         }
110                 break;
111                 case CONNECTOR_ID_DUAL_LINK_DVII:
112                 {
113                         switch (encoder.id) {
114                         case ENCODER_ID_INTERNAL_DAC1:
115                         case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
116                         case ENCODER_ID_INTERNAL_DAC2:
117                         case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
118                                 return SIGNAL_TYPE_RGB;
119                         default:
120                                 return SIGNAL_TYPE_DVI_DUAL_LINK;
121                         }
122                 }
123                 break;
124                 case CONNECTOR_ID_SINGLE_LINK_DVID:
125                         return SIGNAL_TYPE_DVI_SINGLE_LINK;
126                 case CONNECTOR_ID_DUAL_LINK_DVID:
127                         return SIGNAL_TYPE_DVI_DUAL_LINK;
128                 case CONNECTOR_ID_VGA:
129                         return SIGNAL_TYPE_RGB;
130                 case CONNECTOR_ID_HDMI_TYPE_A:
131                         return SIGNAL_TYPE_HDMI_TYPE_A;
132                 case CONNECTOR_ID_LVDS:
133                         return SIGNAL_TYPE_LVDS;
134                 case CONNECTOR_ID_DISPLAY_PORT:
135                 case CONNECTOR_ID_USBC:
136                         return SIGNAL_TYPE_DISPLAY_PORT;
137                 case CONNECTOR_ID_EDP:
138                         return SIGNAL_TYPE_EDP;
139                 default:
140                         return SIGNAL_TYPE_NONE;
141                 }
142         } else if (downstream.type == OBJECT_TYPE_ENCODER) {
143                 switch (downstream.id) {
144                 case ENCODER_ID_EXTERNAL_NUTMEG:
145                 case ENCODER_ID_EXTERNAL_TRAVIS:
146                         return SIGNAL_TYPE_DISPLAY_PORT;
147                 default:
148                         return SIGNAL_TYPE_NONE;
149                 }
150         }
151
152         return SIGNAL_TYPE_NONE;
153 }
154
155 /*
156  * @brief
157  * Detect output sink type
158  */
159 static enum signal_type link_detect_sink_signal_type(struct dc_link *link,
160                                          enum dc_detect_reason reason)
161 {
162         enum signal_type result;
163         struct graphics_object_id enc_id;
164
165         if (link->is_dig_mapping_flexible)
166                 enc_id = (struct graphics_object_id){.id = ENCODER_ID_UNKNOWN};
167         else
168                 enc_id = link->link_enc->id;
169         result = get_basic_signal_type(enc_id, link->link_id);
170
171         /* Use basic signal type for link without physical connector. */
172         if (link->ep_type != DISPLAY_ENDPOINT_PHY)
173                 return result;
174
175         /* Internal digital encoder will detect only dongles
176          * that require digital signal
177          */
178
179         /* Detection mechanism is different
180          * for different native connectors.
181          * LVDS connector supports only LVDS signal;
182          * PCIE is a bus slot, the actual connector needs to be detected first;
183          * eDP connector supports only eDP signal;
184          * HDMI should check straps for audio
185          */
186
187         /* PCIE detects the actual connector on add-on board */
188         if (link->link_id.id == CONNECTOR_ID_PCIE) {
189                 /* ZAZTODO implement PCIE add-on card detection */
190         }
191
192         switch (link->link_id.id) {
193         case CONNECTOR_ID_HDMI_TYPE_A: {
194                 /* check audio support:
195                  * if native HDMI is not supported, switch to DVI
196                  */
197                 struct audio_support *aud_support =
198                                         &link->dc->res_pool->audio_support;
199
200                 if (!aud_support->hdmi_audio_native)
201                         if (link->link_id.id == CONNECTOR_ID_HDMI_TYPE_A)
202                                 result = SIGNAL_TYPE_DVI_SINGLE_LINK;
203         }
204         break;
205         case CONNECTOR_ID_DISPLAY_PORT:
206         case CONNECTOR_ID_USBC: {
207                 /* DP HPD short pulse. Passive DP dongle will not
208                  * have short pulse
209                  */
210                 if (reason != DETECT_REASON_HPDRX) {
211                         /* Check whether DP signal detected: if not -
212                          * we assume signal is DVI; it could be corrected
213                          * to HDMI after dongle detection
214                          */
215                         if (!dm_helpers_is_dp_sink_present(link))
216                                 result = SIGNAL_TYPE_DVI_SINGLE_LINK;
217                 }
218         }
219         break;
220         default:
221         break;
222         }
223
224         return result;
225 }
226
227 static enum signal_type decide_signal_from_strap_and_dongle_type(enum display_dongle_type dongle_type,
228                                                                  struct audio_support *audio_support)
229 {
230         enum signal_type signal = SIGNAL_TYPE_NONE;
231
232         switch (dongle_type) {
233         case DISPLAY_DONGLE_DP_HDMI_DONGLE:
234                 if (audio_support->hdmi_audio_on_dongle)
235                         signal = SIGNAL_TYPE_HDMI_TYPE_A;
236                 else
237                         signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
238                 break;
239         case DISPLAY_DONGLE_DP_DVI_DONGLE:
240                 signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
241                 break;
242         case DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE:
243                 if (audio_support->hdmi_audio_native)
244                         signal =  SIGNAL_TYPE_HDMI_TYPE_A;
245                 else
246                         signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
247                 break;
248         default:
249                 signal = SIGNAL_TYPE_NONE;
250                 break;
251         }
252
253         return signal;
254 }
255
256 static void read_scdc_caps(struct ddc_service *ddc_service,
257                 struct dc_sink *sink)
258 {
259         uint8_t slave_address = HDMI_SCDC_ADDRESS;
260         uint8_t offset = HDMI_SCDC_MANUFACTURER_OUI;
261
262         link_query_ddc_data(ddc_service, slave_address, &offset,
263                         sizeof(offset), sink->scdc_caps.manufacturer_OUI.byte,
264                         sizeof(sink->scdc_caps.manufacturer_OUI.byte));
265
266         offset = HDMI_SCDC_DEVICE_ID;
267
268         link_query_ddc_data(ddc_service, slave_address, &offset,
269                         sizeof(offset), &(sink->scdc_caps.device_id.byte),
270                         sizeof(sink->scdc_caps.device_id.byte));
271 }
272
273 static bool i2c_read(
274         struct ddc_service *ddc,
275         uint32_t address,
276         uint8_t *buffer,
277         uint32_t len)
278 {
279         uint8_t offs_data = 0;
280         struct i2c_payload payloads[2] = {
281                 {
282                 .write = true,
283                 .address = address,
284                 .length = 1,
285                 .data = &offs_data },
286                 {
287                 .write = false,
288                 .address = address,
289                 .length = len,
290                 .data = buffer } };
291
292         struct i2c_command command = {
293                 .payloads = payloads,
294                 .number_of_payloads = 2,
295                 .engine = DDC_I2C_COMMAND_ENGINE,
296                 .speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
297
298         return dm_helpers_submit_i2c(
299                         ddc->ctx,
300                         ddc->link,
301                         &command);
302 }
303
304 enum {
305         DP_SINK_CAP_SIZE =
306                 DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV + 1
307 };
308
309 static void query_dp_dual_mode_adaptor(
310         struct ddc_service *ddc,
311         struct display_sink_capability *sink_cap)
312 {
313         uint8_t i;
314         bool is_valid_hdmi_signature;
315         enum display_dongle_type *dongle = &sink_cap->dongle_type;
316         uint8_t type2_dongle_buf[DP_ADAPTOR_TYPE2_SIZE];
317         bool is_type2_dongle = false;
318         int retry_count = 2;
319         struct dp_hdmi_dongle_signature_data *dongle_signature;
320
321         /* Assume we have no valid DP passive dongle connected */
322         *dongle = DISPLAY_DONGLE_NONE;
323         sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK;
324
325         /* Read DP-HDMI dongle I2c (no response interpreted as DP-DVI dongle)*/
326         if (!i2c_read(
327                 ddc,
328                 DP_HDMI_DONGLE_ADDRESS,
329                 type2_dongle_buf,
330                 sizeof(type2_dongle_buf))) {
331                 /* Passive HDMI dongles can sometimes fail here without retrying*/
332                 while (retry_count > 0) {
333                         if (i2c_read(ddc,
334                                 DP_HDMI_DONGLE_ADDRESS,
335                                 type2_dongle_buf,
336                                 sizeof(type2_dongle_buf)))
337                                 break;
338                         retry_count--;
339                 }
340                 if (retry_count == 0) {
341                         *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
342                         sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
343
344                         CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf),
345                                         "DP-DVI passive dongle %dMhz: ",
346                                         DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
347                         return;
348                 }
349         }
350
351         /* Check if Type 2 dongle.*/
352         if (type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_ID] == DP_ADAPTOR_TYPE2_ID)
353                 is_type2_dongle = true;
354
355         dongle_signature =
356                 (struct dp_hdmi_dongle_signature_data *)type2_dongle_buf;
357
358         is_valid_hdmi_signature = true;
359
360         /* Check EOT */
361         if (dongle_signature->eot != DP_HDMI_DONGLE_SIGNATURE_EOT) {
362                 is_valid_hdmi_signature = false;
363         }
364
365         /* Check signature */
366         for (i = 0; i < sizeof(dongle_signature->id); ++i) {
367                 /* If its not the right signature,
368                  * skip mismatch in subversion byte.*/
369                 if (dongle_signature->id[i] !=
370                         dp_hdmi_dongle_signature_str[i] && i != 3) {
371
372                         if (is_type2_dongle) {
373                                 is_valid_hdmi_signature = false;
374                                 break;
375                         }
376
377                 }
378         }
379
380         if (is_type2_dongle) {
381                 uint32_t max_tmds_clk =
382                         type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK];
383
384                 max_tmds_clk = max_tmds_clk * 2 + max_tmds_clk / 2;
385
386                 if (0 == max_tmds_clk ||
387                                 max_tmds_clk < DP_ADAPTOR_TYPE2_MIN_TMDS_CLK ||
388                                 max_tmds_clk > DP_ADAPTOR_TYPE2_MAX_TMDS_CLK) {
389                         *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
390
391                         CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
392                                         sizeof(type2_dongle_buf),
393                                         "DP-DVI passive dongle %dMhz: ",
394                                         DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
395                 } else {
396                         if (is_valid_hdmi_signature == true) {
397                                 *dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
398
399                                 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
400                                                 sizeof(type2_dongle_buf),
401                                                 "Type 2 DP-HDMI passive dongle %dMhz: ",
402                                                 max_tmds_clk);
403                         } else {
404                                 *dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
405
406                                 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
407                                                 sizeof(type2_dongle_buf),
408                                                 "Type 2 DP-HDMI passive dongle (no signature) %dMhz: ",
409                                                 max_tmds_clk);
410
411                         }
412
413                         /* Multiply by 1000 to convert to kHz. */
414                         sink_cap->max_hdmi_pixel_clock =
415                                 max_tmds_clk * 1000;
416                 }
417                 sink_cap->is_dongle_type_one = false;
418
419         } else {
420                 if (is_valid_hdmi_signature == true) {
421                         *dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
422
423                         CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
424                                         sizeof(type2_dongle_buf),
425                                         "Type 1 DP-HDMI passive dongle %dMhz: ",
426                                         sink_cap->max_hdmi_pixel_clock / 1000);
427                 } else {
428                         *dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
429
430                         CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
431                                         sizeof(type2_dongle_buf),
432                                         "Type 1 DP-HDMI passive dongle (no signature) %dMhz: ",
433                                         sink_cap->max_hdmi_pixel_clock / 1000);
434                 }
435                 sink_cap->is_dongle_type_one = true;
436         }
437
438         return;
439 }
440
441 static enum signal_type dp_passive_dongle_detection(struct ddc_service *ddc,
442                                                     struct display_sink_capability *sink_cap,
443                                                     struct audio_support *audio_support)
444 {
445         query_dp_dual_mode_adaptor(ddc, sink_cap);
446
447         return decide_signal_from_strap_and_dongle_type(sink_cap->dongle_type,
448                                                         audio_support);
449 }
450
451 static void link_disconnect_sink(struct dc_link *link)
452 {
453         if (link->local_sink) {
454                 dc_sink_release(link->local_sink);
455                 link->local_sink = NULL;
456         }
457
458         link->dpcd_sink_count = 0;
459         //link->dpcd_caps.dpcd_rev.raw = 0;
460 }
461
462 static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *link)
463 {
464         dc_sink_release(link->local_sink);
465         link->local_sink = prev_sink;
466 }
467
468 #if defined(CONFIG_DRM_AMD_DC_HDCP)
469 static void query_hdcp_capability(enum signal_type signal, struct dc_link *link)
470 {
471         struct hdcp_protection_message msg22;
472         struct hdcp_protection_message msg14;
473
474         memset(&msg22, 0, sizeof(struct hdcp_protection_message));
475         memset(&msg14, 0, sizeof(struct hdcp_protection_message));
476         memset(link->hdcp_caps.rx_caps.raw, 0,
477                 sizeof(link->hdcp_caps.rx_caps.raw));
478
479         if ((link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
480                         link->ddc->transaction_type ==
481                         DDC_TRANSACTION_TYPE_I2C_OVER_AUX) ||
482                         link->connector_signal == SIGNAL_TYPE_EDP) {
483                 msg22.data = link->hdcp_caps.rx_caps.raw;
484                 msg22.length = sizeof(link->hdcp_caps.rx_caps.raw);
485                 msg22.msg_id = HDCP_MESSAGE_ID_RX_CAPS;
486         } else {
487                 msg22.data = &link->hdcp_caps.rx_caps.fields.version;
488                 msg22.length = sizeof(link->hdcp_caps.rx_caps.fields.version);
489                 msg22.msg_id = HDCP_MESSAGE_ID_HDCP2VERSION;
490         }
491         msg22.version = HDCP_VERSION_22;
492         msg22.link = HDCP_LINK_PRIMARY;
493         msg22.max_retries = 5;
494         dc_process_hdcp_msg(signal, link, &msg22);
495
496         if (signal == SIGNAL_TYPE_DISPLAY_PORT || signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
497                 enum hdcp_message_status status = HDCP_MESSAGE_UNSUPPORTED;
498
499                 msg14.data = &link->hdcp_caps.bcaps.raw;
500                 msg14.length = sizeof(link->hdcp_caps.bcaps.raw);
501                 msg14.msg_id = HDCP_MESSAGE_ID_READ_BCAPS;
502                 msg14.version = HDCP_VERSION_14;
503                 msg14.link = HDCP_LINK_PRIMARY;
504                 msg14.max_retries = 5;
505
506                 status = dc_process_hdcp_msg(signal, link, &msg14);
507         }
508
509 }
510 #endif // CONFIG_DRM_AMD_DC_HDCP
511 static void read_current_link_settings_on_detect(struct dc_link *link)
512 {
513         union lane_count_set lane_count_set = {0};
514         uint8_t link_bw_set;
515         uint8_t link_rate_set;
516         uint32_t read_dpcd_retry_cnt = 10;
517         enum dc_status status = DC_ERROR_UNEXPECTED;
518         int i;
519         union max_down_spread max_down_spread = {0};
520
521         // Read DPCD 00101h to find out the number of lanes currently set
522         for (i = 0; i < read_dpcd_retry_cnt; i++) {
523                 status = core_link_read_dpcd(link,
524                                              DP_LANE_COUNT_SET,
525                                              &lane_count_set.raw,
526                                              sizeof(lane_count_set));
527                 /* First DPCD read after VDD ON can fail if the particular board
528                  * does not have HPD pin wired correctly. So if DPCD read fails,
529                  * which it should never happen, retry a few times. Target worst
530                  * case scenario of 80 ms.
531                  */
532                 if (status == DC_OK) {
533                         link->cur_link_settings.lane_count =
534                                         lane_count_set.bits.LANE_COUNT_SET;
535                         break;
536                 }
537
538                 msleep(8);
539         }
540
541         // Read DPCD 00100h to find if standard link rates are set
542         core_link_read_dpcd(link, DP_LINK_BW_SET,
543                             &link_bw_set, sizeof(link_bw_set));
544
545         if (link_bw_set == 0) {
546                 if (link->connector_signal == SIGNAL_TYPE_EDP) {
547                         /* If standard link rates are not being used,
548                          * Read DPCD 00115h to find the edp link rate set used
549                          */
550                         core_link_read_dpcd(link, DP_LINK_RATE_SET,
551                                             &link_rate_set, sizeof(link_rate_set));
552
553                         // edp_supported_link_rates_count = 0 for DP
554                         if (link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
555                                 link->cur_link_settings.link_rate =
556                                         link->dpcd_caps.edp_supported_link_rates[link_rate_set];
557                                 link->cur_link_settings.link_rate_set = link_rate_set;
558                                 link->cur_link_settings.use_link_rate_set = true;
559                         }
560                 } else {
561                         // Link Rate not found. Seamless boot may not work.
562                         ASSERT(false);
563                 }
564         } else {
565                 link->cur_link_settings.link_rate = link_bw_set;
566                 link->cur_link_settings.use_link_rate_set = false;
567         }
568         // Read DPCD 00003h to find the max down spread.
569         core_link_read_dpcd(link, DP_MAX_DOWNSPREAD,
570                             &max_down_spread.raw, sizeof(max_down_spread));
571         link->cur_link_settings.link_spread =
572                 max_down_spread.bits.MAX_DOWN_SPREAD ?
573                 LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
574 }
575
576 static bool detect_dp(struct dc_link *link,
577                       struct display_sink_capability *sink_caps,
578                       enum dc_detect_reason reason)
579 {
580         struct audio_support *audio_support = &link->dc->res_pool->audio_support;
581
582         sink_caps->signal = link_detect_sink_signal_type(link, reason);
583         sink_caps->transaction_type =
584                 get_ddc_transaction_type(sink_caps->signal);
585
586         if (sink_caps->transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
587                 sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
588                 if (!detect_dp_sink_caps(link))
589                         return false;
590
591                 if (is_dp_branch_device(link))
592                         /* DP SST branch */
593                         link->type = dc_connection_sst_branch;
594         } else {
595                 /* DP passive dongles */
596                 sink_caps->signal = dp_passive_dongle_detection(link->ddc,
597                                                                 sink_caps,
598                                                                 audio_support);
599                 link->dpcd_caps.dongle_type = sink_caps->dongle_type;
600                 link->dpcd_caps.is_dongle_type_one = sink_caps->is_dongle_type_one;
601                 link->dpcd_caps.dpcd_rev.raw = 0;
602         }
603
604         return true;
605 }
606
607 static bool is_same_edid(struct dc_edid *old_edid, struct dc_edid *new_edid)
608 {
609         if (old_edid->length != new_edid->length)
610                 return false;
611
612         if (new_edid->length == 0)
613                 return false;
614
615         return (memcmp(old_edid->raw_edid,
616                        new_edid->raw_edid, new_edid->length) == 0);
617 }
618
619 static bool wait_for_entering_dp_alt_mode(struct dc_link *link)
620 {
621
622         /**
623          * something is terribly wrong if time out is > 200ms. (5Hz)
624          * 500 microseconds * 400 tries us 200 ms
625          **/
626         unsigned int sleep_time_in_microseconds = 500;
627         unsigned int tries_allowed = 400;
628         bool is_in_alt_mode;
629         unsigned long long enter_timestamp;
630         unsigned long long finish_timestamp;
631         unsigned long long time_taken_in_ns;
632         int tries_taken;
633
634         DC_LOGGER_INIT(link->ctx->logger);
635
636         /**
637          * this function will only exist if we are on dcn21 (is_in_alt_mode is a
638          *  function pointer, so checking to see if it is equal to 0 is the same
639          *  as checking to see if it is null
640          **/
641         if (!link->link_enc->funcs->is_in_alt_mode)
642                 return true;
643
644         is_in_alt_mode = link->link_enc->funcs->is_in_alt_mode(link->link_enc);
645         DC_LOG_DC("DP Alt mode state on HPD: %d\n", is_in_alt_mode);
646
647         if (is_in_alt_mode)
648                 return true;
649
650         enter_timestamp = dm_get_timestamp(link->ctx);
651
652         for (tries_taken = 0; tries_taken < tries_allowed; tries_taken++) {
653                 udelay(sleep_time_in_microseconds);
654                 /* ask the link if alt mode is enabled, if so return ok */
655                 if (link->link_enc->funcs->is_in_alt_mode(link->link_enc)) {
656                         finish_timestamp = dm_get_timestamp(link->ctx);
657                         time_taken_in_ns =
658                                 dm_get_elapse_time_in_ns(link->ctx,
659                                                          finish_timestamp,
660                                                          enter_timestamp);
661                         DC_LOG_WARNING("Alt mode entered finished after %llu ms\n",
662                                        div_u64(time_taken_in_ns, 1000000));
663                         return true;
664                 }
665         }
666         finish_timestamp = dm_get_timestamp(link->ctx);
667         time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp,
668                                                     enter_timestamp);
669         DC_LOG_WARNING("Alt mode has timed out after %llu ms\n",
670                         div_u64(time_taken_in_ns, 1000000));
671         return false;
672 }
673
674 static void apply_dpia_mst_dsc_always_on_wa(struct dc_link *link)
675 {
676         /* Apply work around for tunneled MST on certain USB4 docks. Always use DSC if dock
677          * reports DSC support.
678          */
679         if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
680                         link->type == dc_connection_mst_branch &&
681                         link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
682                         link->dpcd_caps.branch_hw_revision == DP_BRANCH_HW_REV_20 &&
683                         link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT &&
684                         !link->dc->debug.dpia_debug.bits.disable_mst_dsc_work_around)
685                 link->wa_flags.dpia_mst_dsc_always_on = true;
686 }
687
688 static void revert_dpia_mst_dsc_always_on_wa(struct dc_link *link)
689 {
690         /* Disable work around which keeps DSC on for tunneled MST on certain USB4 docks. */
691         if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
692                 link->wa_flags.dpia_mst_dsc_always_on = false;
693 }
694
695 static bool discover_dp_mst_topology(struct dc_link *link, enum dc_detect_reason reason)
696 {
697         DC_LOGGER_INIT(link->ctx->logger);
698
699         LINK_INFO("link=%d, mst branch is now Connected\n",
700                   link->link_index);
701
702         link->type = dc_connection_mst_branch;
703         apply_dpia_mst_dsc_always_on_wa(link);
704
705         dm_helpers_dp_update_branch_info(link->ctx, link);
706         if (dm_helpers_dp_mst_start_top_mgr(link->ctx,
707                         link, (reason == DETECT_REASON_BOOT || reason == DETECT_REASON_RESUMEFROMS3S4))) {
708                 link_disconnect_sink(link);
709         } else {
710                 link->type = dc_connection_sst_branch;
711         }
712
713         return link->type == dc_connection_mst_branch;
714 }
715
716 static bool reset_cur_dp_mst_topology(struct dc_link *link)
717 {
718         DC_LOGGER_INIT(link->ctx->logger);
719
720         LINK_INFO("link=%d, mst branch is now Disconnected\n",
721                   link->link_index);
722
723         revert_dpia_mst_dsc_always_on_wa(link);
724         return dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
725 }
726
727 bool dc_link_reset_cur_dp_mst_topology(struct dc_link *link)
728 {
729         return reset_cur_dp_mst_topology(link);
730 }
731 static bool should_prepare_phy_clocks_for_link_verification(const struct dc *dc,
732                 enum dc_detect_reason reason)
733 {
734         int i;
735         bool can_apply_seamless_boot = false;
736
737         for (i = 0; i < dc->current_state->stream_count; i++) {
738                 if (dc->current_state->streams[i]->apply_seamless_boot_optimization) {
739                         can_apply_seamless_boot = true;
740                         break;
741                 }
742         }
743
744         return !can_apply_seamless_boot && reason != DETECT_REASON_BOOT;
745 }
746
747 static void prepare_phy_clocks_for_destructive_link_verification(const struct dc *dc)
748 {
749         dc_z10_restore(dc);
750         clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
751 }
752
753 static void restore_phy_clocks_for_destructive_link_verification(const struct dc *dc)
754 {
755         clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
756 }
757
758 static void set_all_streams_dpms_off_for_link(struct dc_link *link)
759 {
760         int i;
761         struct pipe_ctx *pipe_ctx;
762         struct dc_stream_update stream_update;
763         bool dpms_off = true;
764         struct link_resource link_res = {0};
765
766         memset(&stream_update, 0, sizeof(stream_update));
767         stream_update.dpms_off = &dpms_off;
768
769         for (i = 0; i < MAX_PIPES; i++) {
770                 pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
771                 if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
772                                 pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
773                         stream_update.stream = pipe_ctx->stream;
774                         dc_commit_updates_for_stream(link->ctx->dc, NULL, 0,
775                                         pipe_ctx->stream, &stream_update,
776                                         link->ctx->dc->current_state);
777                 }
778         }
779
780         /* link can be also enabled by vbios. In this case it is not recorded
781          * in pipe_ctx. Disable link phy here to make sure it is completely off
782          */
783         dp_disable_link_phy(link, &link_res, link->connector_signal);
784 }
785
786 static void verify_link_capability_destructive(struct dc_link *link,
787                 struct dc_sink *sink,
788                 enum dc_detect_reason reason)
789 {
790         bool should_prepare_phy_clocks =
791                         should_prepare_phy_clocks_for_link_verification(link->dc, reason);
792
793         if (should_prepare_phy_clocks)
794                 prepare_phy_clocks_for_destructive_link_verification(link->dc);
795
796         if (dc_is_dp_signal(link->local_sink->sink_signal)) {
797                 struct dc_link_settings known_limit_link_setting =
798                                 dp_get_max_link_cap(link);
799                 set_all_streams_dpms_off_for_link(link);
800                 dp_verify_link_cap_with_retries(
801                                 link, &known_limit_link_setting,
802                                 LINK_TRAINING_MAX_VERIFY_RETRY);
803         } else {
804                 ASSERT(0);
805         }
806
807         if (should_prepare_phy_clocks)
808                 restore_phy_clocks_for_destructive_link_verification(link->dc);
809 }
810
811 static void verify_link_capability_non_destructive(struct dc_link *link)
812 {
813         if (dc_is_dp_signal(link->local_sink->sink_signal)) {
814                 if (dc_is_embedded_signal(link->local_sink->sink_signal) ||
815                                 link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
816                         /* TODO - should we check link encoder's max link caps here?
817                          * How do we know which link encoder to check from?
818                          */
819                         link->verified_link_cap = link->reported_link_cap;
820                 else
821                         link->verified_link_cap = dp_get_max_link_cap(link);
822         }
823 }
824
825 static bool should_verify_link_capability_destructively(struct dc_link *link,
826                 enum dc_detect_reason reason)
827 {
828         bool destrictive = false;
829         struct dc_link_settings max_link_cap;
830         bool is_link_enc_unavailable = link->link_enc &&
831                         link->dc->res_pool->funcs->link_encs_assign &&
832                         !link_enc_cfg_is_link_enc_avail(
833                                         link->ctx->dc,
834                                         link->link_enc->preferred_engine,
835                                         link);
836
837         if (dc_is_dp_signal(link->local_sink->sink_signal)) {
838                 max_link_cap = dp_get_max_link_cap(link);
839                 destrictive = true;
840
841                 if (link->dc->debug.skip_detection_link_training ||
842                                 dc_is_embedded_signal(link->local_sink->sink_signal) ||
843                                 link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
844                         destrictive = false;
845                 } else if (link_dp_get_encoding_format(&max_link_cap) ==
846                                 DP_8b_10b_ENCODING) {
847                         if (link->dpcd_caps.is_mst_capable ||
848                                         is_link_enc_unavailable) {
849                                 destrictive = false;
850                         }
851                 }
852         }
853
854         return destrictive;
855 }
856
857 static void verify_link_capability(struct dc_link *link, struct dc_sink *sink,
858                 enum dc_detect_reason reason)
859 {
860         if (should_verify_link_capability_destructively(link, reason))
861                 verify_link_capability_destructive(link, sink, reason);
862         else
863                 verify_link_capability_non_destructive(link);
864 }
865
866 /**
867  * detect_link_and_local_sink() - Detect if a sink is attached to a given link
868  *
869  * link->local_sink is created or destroyed as needed.
870  *
871  * This does not create remote sinks.
872  */
873 static bool detect_link_and_local_sink(struct dc_link *link,
874                                   enum dc_detect_reason reason)
875 {
876         struct dc_sink_init_data sink_init_data = { 0 };
877         struct display_sink_capability sink_caps = { 0 };
878         uint32_t i;
879         bool converter_disable_audio = false;
880         struct audio_support *aud_support = &link->dc->res_pool->audio_support;
881         bool same_edid = false;
882         enum dc_edid_status edid_status;
883         struct dc_context *dc_ctx = link->ctx;
884         struct dc *dc = dc_ctx->dc;
885         struct dc_sink *sink = NULL;
886         struct dc_sink *prev_sink = NULL;
887         struct dpcd_caps prev_dpcd_caps;
888         enum dc_connection_type new_connection_type = dc_connection_none;
889         enum dc_connection_type pre_connection_type = dc_connection_none;
890         const uint32_t post_oui_delay = 30; // 30ms
891
892         DC_LOGGER_INIT(link->ctx->logger);
893
894         if (dc_is_virtual_signal(link->connector_signal))
895                 return false;
896
897         if (((link->connector_signal == SIGNAL_TYPE_LVDS ||
898                 link->connector_signal == SIGNAL_TYPE_EDP) &&
899                 (!link->dc->config.allow_edp_hotplug_detection)) &&
900                 link->local_sink) {
901                 // need to re-write OUI and brightness in resume case
902                 if (link->connector_signal == SIGNAL_TYPE_EDP &&
903                         (link->dpcd_sink_ext_caps.bits.oled == 1)) {
904                         dpcd_set_source_specific_data(link);
905                         msleep(post_oui_delay);
906                         set_default_brightness_aux(link);
907                         //TODO: use cached
908                 }
909
910                 return true;
911         }
912
913         if (!dc_link_detect_connection_type(link, &new_connection_type)) {
914                 BREAK_TO_DEBUGGER();
915                 return false;
916         }
917
918         prev_sink = link->local_sink;
919         if (prev_sink) {
920                 dc_sink_retain(prev_sink);
921                 memcpy(&prev_dpcd_caps, &link->dpcd_caps, sizeof(struct dpcd_caps));
922         }
923
924         link_disconnect_sink(link);
925         if (new_connection_type != dc_connection_none) {
926                 pre_connection_type = link->type;
927                 link->type = new_connection_type;
928                 link->link_state_valid = false;
929
930                 /* From Disconnected-to-Connected. */
931                 switch (link->connector_signal) {
932                 case SIGNAL_TYPE_HDMI_TYPE_A: {
933                         sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
934                         if (aud_support->hdmi_audio_native)
935                                 sink_caps.signal = SIGNAL_TYPE_HDMI_TYPE_A;
936                         else
937                                 sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
938                         break;
939                 }
940
941                 case SIGNAL_TYPE_DVI_SINGLE_LINK: {
942                         sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
943                         sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
944                         break;
945                 }
946
947                 case SIGNAL_TYPE_DVI_DUAL_LINK: {
948                         sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
949                         sink_caps.signal = SIGNAL_TYPE_DVI_DUAL_LINK;
950                         break;
951                 }
952
953                 case SIGNAL_TYPE_LVDS: {
954                         sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
955                         sink_caps.signal = SIGNAL_TYPE_LVDS;
956                         break;
957                 }
958
959                 case SIGNAL_TYPE_EDP: {
960                         detect_edp_sink_caps(link);
961                         read_current_link_settings_on_detect(link);
962
963                         /* Disable power sequence on MIPI panel + converter
964                          */
965                         if (dc->config.enable_mipi_converter_optimization &&
966                                 dc_ctx->dce_version == DCN_VERSION_3_01 &&
967                                 link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_0022B9 &&
968                                 memcmp(&link->dpcd_caps.branch_dev_name, DP_SINK_BRANCH_DEV_NAME_7580,
969                                         sizeof(link->dpcd_caps.branch_dev_name)) == 0) {
970                                 dc->config.edp_no_power_sequencing = true;
971
972                                 if (!link->dpcd_caps.set_power_state_capable_edp)
973                                         link->wa_flags.dp_keep_receiver_powered = true;
974                         }
975
976                         sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
977                         sink_caps.signal = SIGNAL_TYPE_EDP;
978                         break;
979                 }
980
981                 case SIGNAL_TYPE_DISPLAY_PORT: {
982
983                         /* wa HPD high coming too early*/
984                         if (link->ep_type == DISPLAY_ENDPOINT_PHY &&
985                             link->link_enc->features.flags.bits.DP_IS_USB_C == 1) {
986
987                                 /* if alt mode times out, return false */
988                                 if (!wait_for_entering_dp_alt_mode(link))
989                                         return false;
990                         }
991
992                         if (!detect_dp(link, &sink_caps, reason)) {
993                                 if (prev_sink)
994                                         dc_sink_release(prev_sink);
995                                 return false;
996                         }
997
998                         /* Active SST downstream branch device unplug*/
999                         if (link->type == dc_connection_sst_branch &&
1000                             link->dpcd_caps.sink_count.bits.SINK_COUNT == 0) {
1001                                 if (prev_sink)
1002                                         /* Downstream unplug */
1003                                         dc_sink_release(prev_sink);
1004                                 return true;
1005                         }
1006
1007                         /* disable audio for non DP to HDMI active sst converter */
1008                         if (link->type == dc_connection_sst_branch &&
1009                                         is_dp_active_dongle(link) &&
1010                                         (link->dpcd_caps.dongle_type !=
1011                                                         DISPLAY_DONGLE_DP_HDMI_CONVERTER))
1012                                 converter_disable_audio = true;
1013                         break;
1014                 }
1015
1016                 default:
1017                         DC_ERROR("Invalid connector type! signal:%d\n",
1018                                  link->connector_signal);
1019                         if (prev_sink)
1020                                 dc_sink_release(prev_sink);
1021                         return false;
1022                 } /* switch() */
1023
1024                 if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
1025                         link->dpcd_sink_count =
1026                                 link->dpcd_caps.sink_count.bits.SINK_COUNT;
1027                 else
1028                         link->dpcd_sink_count = 1;
1029
1030                 set_ddc_transaction_type(link->ddc,
1031                                                      sink_caps.transaction_type);
1032
1033                 link->aux_mode =
1034                         link_is_in_aux_transaction_mode(link->ddc);
1035
1036                 sink_init_data.link = link;
1037                 sink_init_data.sink_signal = sink_caps.signal;
1038
1039                 sink = dc_sink_create(&sink_init_data);
1040                 if (!sink) {
1041                         DC_ERROR("Failed to create sink!\n");
1042                         if (prev_sink)
1043                                 dc_sink_release(prev_sink);
1044                         return false;
1045                 }
1046
1047                 sink->link->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock;
1048                 sink->converter_disable_audio = converter_disable_audio;
1049
1050                 /* dc_sink_create returns a new reference */
1051                 link->local_sink = sink;
1052
1053                 edid_status = dm_helpers_read_local_edid(link->ctx,
1054                                                          link, sink);
1055
1056                 switch (edid_status) {
1057                 case EDID_BAD_CHECKSUM:
1058                         DC_LOG_ERROR("EDID checksum invalid.\n");
1059                         break;
1060                 case EDID_PARTIAL_VALID:
1061                         DC_LOG_ERROR("Partial EDID valid, abandon invalid blocks.\n");
1062                         break;
1063                 case EDID_NO_RESPONSE:
1064                         DC_LOG_ERROR("No EDID read.\n");
1065                         /*
1066                          * Abort detection for non-DP connectors if we have
1067                          * no EDID
1068                          *
1069                          * DP needs to report as connected if HDP is high
1070                          * even if we have no EDID in order to go to
1071                          * fail-safe mode
1072                          */
1073                         if (dc_is_hdmi_signal(link->connector_signal) ||
1074                             dc_is_dvi_signal(link->connector_signal)) {
1075                                 if (prev_sink)
1076                                         dc_sink_release(prev_sink);
1077
1078                                 return false;
1079                         }
1080
1081                         if (link->type == dc_connection_sst_branch &&
1082                                         link->dpcd_caps.dongle_type ==
1083                                                 DISPLAY_DONGLE_DP_VGA_CONVERTER &&
1084                                         reason == DETECT_REASON_HPDRX) {
1085                                 /* Abort detection for DP-VGA adapters when EDID
1086                                  * can't be read and detection reason is VGA-side
1087                                  * hotplug
1088                                  */
1089                                 if (prev_sink)
1090                                         dc_sink_release(prev_sink);
1091                                 link_disconnect_sink(link);
1092
1093                                 return true;
1094                         }
1095
1096                         break;
1097                 default:
1098                         break;
1099                 }
1100
1101                 // Check if edid is the same
1102                 if ((prev_sink) &&
1103                     (edid_status == EDID_THE_SAME || edid_status == EDID_OK))
1104                         same_edid = is_same_edid(&prev_sink->dc_edid,
1105                                                  &sink->dc_edid);
1106
1107                 if (sink->edid_caps.panel_patch.skip_scdc_overwrite)
1108                         link->ctx->dc->debug.hdmi20_disable = true;
1109
1110                 if (dc_is_hdmi_signal(link->connector_signal))
1111                         read_scdc_caps(link->ddc, link->local_sink);
1112
1113                 if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
1114                     sink_caps.transaction_type ==
1115                     DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
1116                         /*
1117                          * TODO debug why certain monitors don't like
1118                          *  two link trainings
1119                          */
1120 #if defined(CONFIG_DRM_AMD_DC_HDCP)
1121                         query_hdcp_capability(sink->sink_signal, link);
1122 #endif
1123                 } else {
1124                         // If edid is the same, then discard new sink and revert back to original sink
1125                         if (same_edid) {
1126                                 link_disconnect_remap(prev_sink, link);
1127                                 sink = prev_sink;
1128                                 prev_sink = NULL;
1129                         }
1130 #if defined(CONFIG_DRM_AMD_DC_HDCP)
1131                         query_hdcp_capability(sink->sink_signal, link);
1132 #endif
1133                 }
1134
1135                 /* HDMI-DVI Dongle */
1136                 if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
1137                     !sink->edid_caps.edid_hdmi)
1138                         sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
1139
1140                 if (link->local_sink && dc_is_dp_signal(sink_caps.signal))
1141                         dp_trace_init(link);
1142
1143                 /* Connectivity log: detection */
1144                 for (i = 0; i < sink->dc_edid.length / DC_EDID_BLOCK_SIZE; i++) {
1145                         CONN_DATA_DETECT(link,
1146                                          &sink->dc_edid.raw_edid[i * DC_EDID_BLOCK_SIZE],
1147                                          DC_EDID_BLOCK_SIZE,
1148                                          "%s: [Block %d] ", sink->edid_caps.display_name, i);
1149                 }
1150
1151                 DC_LOG_DETECTION_EDID_PARSER("%s: "
1152                         "manufacturer_id = %X, "
1153                         "product_id = %X, "
1154                         "serial_number = %X, "
1155                         "manufacture_week = %d, "
1156                         "manufacture_year = %d, "
1157                         "display_name = %s, "
1158                         "speaker_flag = %d, "
1159                         "audio_mode_count = %d\n",
1160                         __func__,
1161                         sink->edid_caps.manufacturer_id,
1162                         sink->edid_caps.product_id,
1163                         sink->edid_caps.serial_number,
1164                         sink->edid_caps.manufacture_week,
1165                         sink->edid_caps.manufacture_year,
1166                         sink->edid_caps.display_name,
1167                         sink->edid_caps.speaker_flags,
1168                         sink->edid_caps.audio_mode_count);
1169
1170                 for (i = 0; i < sink->edid_caps.audio_mode_count; i++) {
1171                         DC_LOG_DETECTION_EDID_PARSER("%s: mode number = %d, "
1172                                 "format_code = %d, "
1173                                 "channel_count = %d, "
1174                                 "sample_rate = %d, "
1175                                 "sample_size = %d\n",
1176                                 __func__,
1177                                 i,
1178                                 sink->edid_caps.audio_modes[i].format_code,
1179                                 sink->edid_caps.audio_modes[i].channel_count,
1180                                 sink->edid_caps.audio_modes[i].sample_rate,
1181                                 sink->edid_caps.audio_modes[i].sample_size);
1182                 }
1183
1184                 if (link->connector_signal == SIGNAL_TYPE_EDP) {
1185                         // Init dc_panel_config by HW config
1186                         if (dc_ctx->dc->res_pool->funcs->get_panel_config_defaults)
1187                                 dc_ctx->dc->res_pool->funcs->get_panel_config_defaults(&link->panel_config);
1188                         // Pickup base DM settings
1189                         dm_helpers_init_panel_settings(dc_ctx, &link->panel_config, sink);
1190                         // Override dc_panel_config if system has specific settings
1191                         dm_helpers_override_panel_settings(dc_ctx, &link->panel_config);
1192                 }
1193
1194         } else {
1195                 /* From Connected-to-Disconnected. */
1196                 link->type = dc_connection_none;
1197                 sink_caps.signal = SIGNAL_TYPE_NONE;
1198 #if defined(CONFIG_DRM_AMD_DC_HDCP)
1199                 memset(&link->hdcp_caps, 0, sizeof(struct hdcp_caps));
1200 #endif
1201                 /* When we unplug a passive DP-HDMI dongle connection, dongle_max_pix_clk
1202                  *  is not cleared. If we emulate a DP signal on this connection, it thinks
1203                  *  the dongle is still there and limits the number of modes we can emulate.
1204                  *  Clear dongle_max_pix_clk on disconnect to fix this
1205                  */
1206                 link->dongle_max_pix_clk = 0;
1207
1208                 dc_link_clear_dprx_states(link);
1209                 dp_trace_reset(link);
1210         }
1211
1212         LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p edid same=%d\n",
1213                   link->link_index, sink,
1214                   (sink_caps.signal ==
1215                    SIGNAL_TYPE_NONE ? "Disconnected" : "Connected"),
1216                   prev_sink, same_edid);
1217
1218         if (prev_sink)
1219                 dc_sink_release(prev_sink);
1220
1221         return true;
1222 }
1223
1224 /**
1225  * dc_link_detect_connection_type() - Determine if there is a sink connected
1226  *
1227  * @type: Returned connection type
1228  * Does not detect downstream devices, such as MST sinks
1229  * or display connected through active dongles
1230  */
1231 bool dc_link_detect_connection_type(struct dc_link *link, enum dc_connection_type *type)
1232 {
1233         uint32_t is_hpd_high = 0;
1234
1235         if (link->connector_signal == SIGNAL_TYPE_LVDS) {
1236                 *type = dc_connection_single;
1237                 return true;
1238         }
1239
1240         if (link->connector_signal == SIGNAL_TYPE_EDP) {
1241                 /*in case it is not on*/
1242                 if (!link->dc->config.edp_no_power_sequencing)
1243                         link->dc->hwss.edp_power_control(link, true);
1244                 link->dc->hwss.edp_wait_for_hpd_ready(link, true);
1245         }
1246
1247         /* Link may not have physical HPD pin. */
1248         if (link->ep_type != DISPLAY_ENDPOINT_PHY) {
1249                 if (link->is_hpd_pending || !dc_link_dpia_query_hpd_status(link))
1250                         *type = dc_connection_none;
1251                 else
1252                         *type = dc_connection_single;
1253
1254                 return true;
1255         }
1256
1257
1258         if (!query_hpd_status(link, &is_hpd_high))
1259                 goto hpd_gpio_failure;
1260
1261         if (is_hpd_high) {
1262                 *type = dc_connection_single;
1263                 /* TODO: need to do the actual detection */
1264         } else {
1265                 *type = dc_connection_none;
1266         }
1267
1268         return true;
1269
1270 hpd_gpio_failure:
1271         return false;
1272 }
1273
1274 bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
1275 {
1276         bool is_local_sink_detect_success;
1277         bool is_delegated_to_mst_top_mgr = false;
1278         enum dc_connection_type pre_link_type = link->type;
1279
1280         is_local_sink_detect_success = detect_link_and_local_sink(link, reason);
1281
1282         if (is_local_sink_detect_success && link->local_sink)
1283                 verify_link_capability(link, link->local_sink, reason);
1284
1285         if (is_local_sink_detect_success && link->local_sink &&
1286                         dc_is_dp_signal(link->local_sink->sink_signal) &&
1287                         link->dpcd_caps.is_mst_capable)
1288                 is_delegated_to_mst_top_mgr = discover_dp_mst_topology(link, reason);
1289
1290         if (is_local_sink_detect_success &&
1291                         pre_link_type == dc_connection_mst_branch &&
1292                         link->type != dc_connection_mst_branch)
1293                 is_delegated_to_mst_top_mgr = reset_cur_dp_mst_topology(link);
1294
1295         return is_local_sink_detect_success && !is_delegated_to_mst_top_mgr;
1296 }
1297
1298 void dc_link_clear_dprx_states(struct dc_link *link)
1299 {
1300         memset(&link->dprx_states, 0, sizeof(link->dprx_states));
1301 }
1302 #if defined(CONFIG_DRM_AMD_DC_HDCP)
1303
1304 bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal)
1305 {
1306         bool ret = false;
1307
1308         switch (signal) {
1309         case SIGNAL_TYPE_DISPLAY_PORT:
1310         case SIGNAL_TYPE_DISPLAY_PORT_MST:
1311                 ret = link->hdcp_caps.bcaps.bits.HDCP_CAPABLE;
1312                 break;
1313         case SIGNAL_TYPE_DVI_SINGLE_LINK:
1314         case SIGNAL_TYPE_DVI_DUAL_LINK:
1315         case SIGNAL_TYPE_HDMI_TYPE_A:
1316         /* HDMI doesn't tell us its HDCP(1.4) capability, so assume to always be capable,
1317          * we can poll for bksv but some displays have an issue with this. Since its so rare
1318          * for a display to not be 1.4 capable, this assumtion is ok
1319          */
1320                 ret = true;
1321                 break;
1322         default:
1323                 break;
1324         }
1325         return ret;
1326 }
1327
1328 bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal)
1329 {
1330         bool ret = false;
1331
1332         switch (signal) {
1333         case SIGNAL_TYPE_DISPLAY_PORT:
1334         case SIGNAL_TYPE_DISPLAY_PORT_MST:
1335                 ret = (link->hdcp_caps.bcaps.bits.HDCP_CAPABLE &&
1336                                 link->hdcp_caps.rx_caps.fields.byte0.hdcp_capable &&
1337                                 (link->hdcp_caps.rx_caps.fields.version == 0x2)) ? 1 : 0;
1338                 break;
1339         case SIGNAL_TYPE_DVI_SINGLE_LINK:
1340         case SIGNAL_TYPE_DVI_DUAL_LINK:
1341         case SIGNAL_TYPE_HDMI_TYPE_A:
1342                 ret = (link->hdcp_caps.rx_caps.fields.version == 0x4) ? 1:0;
1343                 break;
1344         default:
1345                 break;
1346         }
1347
1348         return ret;
1349 }
1350 #endif // CONFIG_DRM_AMD_DC_HDCP
1351
1352 const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
1353 {
1354         return &link->link_status;
1355 }
1356