drm/nouveau/disp/gm200-: enforce identity-mapped SOR assignment for LVDS/eDP panels
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / core / dc_link.c
1 /*
2  * Copyright 2012-15 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 #include "dm_services.h"
27 #include "atom.h"
28 #include "dm_helpers.h"
29 #include "dc.h"
30 #include "grph_object_id.h"
31 #include "gpio_service_interface.h"
32 #include "core_status.h"
33 #include "dc_link_dp.h"
34 #include "dc_link_ddc.h"
35 #include "link_hwss.h"
36 #include "opp.h"
37
38 #include "link_encoder.h"
39 #include "hw_sequencer.h"
40 #include "resource.h"
41 #include "abm.h"
42 #include "fixed31_32.h"
43 #include "dpcd_defs.h"
44 #include "dmcu.h"
45
46 #include "dce/dce_11_0_d.h"
47 #include "dce/dce_11_0_enum.h"
48 #include "dce/dce_11_0_sh_mask.h"
49
50 #define DC_LOGGER_INIT(logger)
51
52
53 #define LINK_INFO(...) \
54         DC_LOG_HW_HOTPLUG(  \
55                 __VA_ARGS__)
56
57 /*******************************************************************************
58  * Private structures
59  ******************************************************************************/
60
61 enum {
62         LINK_RATE_REF_FREQ_IN_MHZ = 27,
63         PEAK_FACTOR_X1000 = 1006,
64         /*
65         * Some receivers fail to train on first try and are good
66         * on subsequent tries. 2 retries should be plenty. If we
67         * don't have a successful training then we don't expect to
68         * ever get one.
69         */
70         LINK_TRAINING_MAX_VERIFY_RETRY = 2
71 };
72
73 /*******************************************************************************
74  * Private functions
75  ******************************************************************************/
76 static void destruct(struct dc_link *link)
77 {
78         int i;
79
80         if (link->ddc)
81                 dal_ddc_service_destroy(&link->ddc);
82
83         if(link->link_enc)
84                 link->link_enc->funcs->destroy(&link->link_enc);
85
86         if (link->local_sink)
87                 dc_sink_release(link->local_sink);
88
89         for (i = 0; i < link->sink_count; ++i)
90                 dc_sink_release(link->remote_sinks[i]);
91 }
92
93 struct gpio *get_hpd_gpio(struct dc_bios *dcb,
94                 struct graphics_object_id link_id,
95                 struct gpio_service *gpio_service)
96 {
97         enum bp_result bp_result;
98         struct graphics_object_hpd_info hpd_info;
99         struct gpio_pin_info pin_info;
100
101         if (dcb->funcs->get_hpd_info(dcb, link_id, &hpd_info) != BP_RESULT_OK)
102                 return NULL;
103
104         bp_result = dcb->funcs->get_gpio_pin_info(dcb,
105                 hpd_info.hpd_int_gpio_uid, &pin_info);
106
107         if (bp_result != BP_RESULT_OK) {
108                 ASSERT(bp_result == BP_RESULT_NORECORD);
109                 return NULL;
110         }
111
112         return dal_gpio_service_create_irq(
113                 gpio_service,
114                 pin_info.offset,
115                 pin_info.mask);
116 }
117
118 /*
119  *  Function: program_hpd_filter
120  *
121  *  @brief
122  *     Programs HPD filter on associated HPD line
123  *
124  *  @param [in] delay_on_connect_in_ms: Connect filter timeout
125  *  @param [in] delay_on_disconnect_in_ms: Disconnect filter timeout
126  *
127  *  @return
128  *     true on success, false otherwise
129  */
130 static bool program_hpd_filter(
131         const struct dc_link *link)
132 {
133         bool result = false;
134
135         struct gpio *hpd;
136
137         int delay_on_connect_in_ms = 0;
138         int delay_on_disconnect_in_ms = 0;
139
140         if (link->is_hpd_filter_disabled)
141                 return false;
142         /* Verify feature is supported */
143         switch (link->connector_signal) {
144         case SIGNAL_TYPE_DVI_SINGLE_LINK:
145         case SIGNAL_TYPE_DVI_DUAL_LINK:
146         case SIGNAL_TYPE_HDMI_TYPE_A:
147                 /* Program hpd filter */
148                 delay_on_connect_in_ms = 500;
149                 delay_on_disconnect_in_ms = 100;
150                 break;
151         case SIGNAL_TYPE_DISPLAY_PORT:
152         case SIGNAL_TYPE_DISPLAY_PORT_MST:
153                 /* Program hpd filter to allow DP signal to settle */
154                 /* 500: not able to detect MST <-> SST switch as HPD is low for
155                  *      only 100ms on DELL U2413
156                  * 0:   some passive dongle still show aux mode instead of i2c
157                  * 20-50:not enough to hide bouncing HPD with passive dongle.
158                  *      also see intermittent i2c read issues.
159                  */
160                 delay_on_connect_in_ms = 80;
161                 delay_on_disconnect_in_ms = 0;
162                 break;
163         case SIGNAL_TYPE_LVDS:
164         case SIGNAL_TYPE_EDP:
165         default:
166                 /* Don't program hpd filter */
167                 return false;
168         }
169
170         /* Obtain HPD handle */
171         hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
172
173         if (!hpd)
174                 return result;
175
176         /* Setup HPD filtering */
177         if (dal_gpio_open(hpd, GPIO_MODE_INTERRUPT) == GPIO_RESULT_OK) {
178                 struct gpio_hpd_config config;
179
180                 config.delay_on_connect = delay_on_connect_in_ms;
181                 config.delay_on_disconnect = delay_on_disconnect_in_ms;
182
183                 dal_irq_setup_hpd_filter(hpd, &config);
184
185                 dal_gpio_close(hpd);
186
187                 result = true;
188         } else {
189                 ASSERT_CRITICAL(false);
190         }
191
192         /* Release HPD handle */
193         dal_gpio_destroy_irq(&hpd);
194
195         return result;
196 }
197
198 static bool detect_sink(struct dc_link *link, enum dc_connection_type *type)
199 {
200         uint32_t is_hpd_high = 0;
201         struct gpio *hpd_pin;
202
203         /* todo: may need to lock gpio access */
204         hpd_pin = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
205         if (hpd_pin == NULL)
206                 goto hpd_gpio_failure;
207
208         dal_gpio_open(hpd_pin, GPIO_MODE_INTERRUPT);
209         dal_gpio_get_value(hpd_pin, &is_hpd_high);
210         dal_gpio_close(hpd_pin);
211         dal_gpio_destroy_irq(&hpd_pin);
212
213         if (is_hpd_high) {
214                 *type = dc_connection_single;
215                 /* TODO: need to do the actual detection */
216         } else {
217                 *type = dc_connection_none;
218         }
219
220         return true;
221
222 hpd_gpio_failure:
223         return false;
224 }
225
226 static enum ddc_transaction_type get_ddc_transaction_type(
227                 enum signal_type sink_signal)
228 {
229         enum ddc_transaction_type transaction_type = DDC_TRANSACTION_TYPE_NONE;
230
231         switch (sink_signal) {
232         case SIGNAL_TYPE_DVI_SINGLE_LINK:
233         case SIGNAL_TYPE_DVI_DUAL_LINK:
234         case SIGNAL_TYPE_HDMI_TYPE_A:
235         case SIGNAL_TYPE_LVDS:
236         case SIGNAL_TYPE_RGB:
237                 transaction_type = DDC_TRANSACTION_TYPE_I2C;
238                 break;
239
240         case SIGNAL_TYPE_DISPLAY_PORT:
241         case SIGNAL_TYPE_EDP:
242                 transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
243                 break;
244
245         case SIGNAL_TYPE_DISPLAY_PORT_MST:
246                 /* MST does not use I2COverAux, but there is the
247                  * SPECIAL use case for "immediate dwnstrm device
248                  * access" (EPR#370830). */
249                 transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
250                 break;
251
252         default:
253                 break;
254         }
255
256         return transaction_type;
257 }
258
259 static enum signal_type get_basic_signal_type(
260         struct graphics_object_id encoder,
261         struct graphics_object_id downstream)
262 {
263         if (downstream.type == OBJECT_TYPE_CONNECTOR) {
264                 switch (downstream.id) {
265                 case CONNECTOR_ID_SINGLE_LINK_DVII:
266                         switch (encoder.id) {
267                         case ENCODER_ID_INTERNAL_DAC1:
268                         case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
269                         case ENCODER_ID_INTERNAL_DAC2:
270                         case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
271                                 return SIGNAL_TYPE_RGB;
272                         default:
273                                 return SIGNAL_TYPE_DVI_SINGLE_LINK;
274                         }
275                 break;
276                 case CONNECTOR_ID_DUAL_LINK_DVII:
277                 {
278                         switch (encoder.id) {
279                         case ENCODER_ID_INTERNAL_DAC1:
280                         case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
281                         case ENCODER_ID_INTERNAL_DAC2:
282                         case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
283                                 return SIGNAL_TYPE_RGB;
284                         default:
285                                 return SIGNAL_TYPE_DVI_DUAL_LINK;
286                         }
287                 }
288                 break;
289                 case CONNECTOR_ID_SINGLE_LINK_DVID:
290                         return SIGNAL_TYPE_DVI_SINGLE_LINK;
291                 case CONNECTOR_ID_DUAL_LINK_DVID:
292                         return SIGNAL_TYPE_DVI_DUAL_LINK;
293                 case CONNECTOR_ID_VGA:
294                         return SIGNAL_TYPE_RGB;
295                 case CONNECTOR_ID_HDMI_TYPE_A:
296                         return SIGNAL_TYPE_HDMI_TYPE_A;
297                 case CONNECTOR_ID_LVDS:
298                         return SIGNAL_TYPE_LVDS;
299                 case CONNECTOR_ID_DISPLAY_PORT:
300                         return SIGNAL_TYPE_DISPLAY_PORT;
301                 case CONNECTOR_ID_EDP:
302                         return SIGNAL_TYPE_EDP;
303                 default:
304                         return SIGNAL_TYPE_NONE;
305                 }
306         } else if (downstream.type == OBJECT_TYPE_ENCODER) {
307                 switch (downstream.id) {
308                 case ENCODER_ID_EXTERNAL_NUTMEG:
309                 case ENCODER_ID_EXTERNAL_TRAVIS:
310                         return SIGNAL_TYPE_DISPLAY_PORT;
311                 default:
312                         return SIGNAL_TYPE_NONE;
313                 }
314         }
315
316         return SIGNAL_TYPE_NONE;
317 }
318
319 /*
320  * @brief
321  * Check whether there is a dongle on DP connector
322  */
323 bool dc_link_is_dp_sink_present(struct dc_link *link)
324 {
325         enum gpio_result gpio_result;
326         uint32_t clock_pin = 0;
327
328         struct ddc *ddc;
329
330         enum connector_id connector_id =
331                 dal_graphics_object_id_get_connector_id(link->link_id);
332
333         bool present =
334                 ((connector_id == CONNECTOR_ID_DISPLAY_PORT) ||
335                 (connector_id == CONNECTOR_ID_EDP));
336
337         ddc = dal_ddc_service_get_ddc_pin(link->ddc);
338
339         if (!ddc) {
340                 BREAK_TO_DEBUGGER();
341                 return present;
342         }
343
344         /* Open GPIO and set it to I2C mode */
345         /* Note: this GpioMode_Input will be converted
346          * to GpioConfigType_I2cAuxDualMode in GPIO component,
347          * which indicates we need additional delay */
348
349         if (GPIO_RESULT_OK != dal_ddc_open(
350                 ddc, GPIO_MODE_INPUT, GPIO_DDC_CONFIG_TYPE_MODE_I2C)) {
351                 dal_gpio_destroy_ddc(&ddc);
352
353                 return present;
354         }
355
356         /* Read GPIO: DP sink is present if both clock and data pins are zero */
357         /* [anaumov] in DAL2, there was no check for GPIO failure */
358
359         gpio_result = dal_gpio_get_value(ddc->pin_clock, &clock_pin);
360         ASSERT(gpio_result == GPIO_RESULT_OK);
361
362         present = (gpio_result == GPIO_RESULT_OK) && !clock_pin;
363
364         dal_ddc_close(ddc);
365
366         return present;
367 }
368
369 /*
370  * @brief
371  * Detect output sink type
372  */
373 static enum signal_type link_detect_sink(
374         struct dc_link *link,
375         enum dc_detect_reason reason)
376 {
377         enum signal_type result = get_basic_signal_type(
378                 link->link_enc->id, link->link_id);
379
380         /* Internal digital encoder will detect only dongles
381          * that require digital signal */
382
383         /* Detection mechanism is different
384          * for different native connectors.
385          * LVDS connector supports only LVDS signal;
386          * PCIE is a bus slot, the actual connector needs to be detected first;
387          * eDP connector supports only eDP signal;
388          * HDMI should check straps for audio */
389
390         /* PCIE detects the actual connector on add-on board */
391
392         if (link->link_id.id == CONNECTOR_ID_PCIE) {
393                 /* ZAZTODO implement PCIE add-on card detection */
394         }
395
396         switch (link->link_id.id) {
397         case CONNECTOR_ID_HDMI_TYPE_A: {
398                 /* check audio support:
399                  * if native HDMI is not supported, switch to DVI */
400                 struct audio_support *aud_support = &link->dc->res_pool->audio_support;
401
402                 if (!aud_support->hdmi_audio_native)
403                         if (link->link_id.id == CONNECTOR_ID_HDMI_TYPE_A)
404                                 result = SIGNAL_TYPE_DVI_SINGLE_LINK;
405         }
406         break;
407         case CONNECTOR_ID_DISPLAY_PORT: {
408                 /* DP HPD short pulse. Passive DP dongle will not
409                  * have short pulse
410                  */
411                 if (reason != DETECT_REASON_HPDRX) {
412                         /* Check whether DP signal detected: if not -
413                          * we assume signal is DVI; it could be corrected
414                          * to HDMI after dongle detection
415                          */
416                         if (!dm_helpers_is_dp_sink_present(link))
417                                 result = SIGNAL_TYPE_DVI_SINGLE_LINK;
418                 }
419         }
420         break;
421         default:
422         break;
423         }
424
425         return result;
426 }
427
428 static enum signal_type decide_signal_from_strap_and_dongle_type(
429                 enum display_dongle_type dongle_type,
430                 struct audio_support *audio_support)
431 {
432         enum signal_type signal = SIGNAL_TYPE_NONE;
433
434         switch (dongle_type) {
435         case DISPLAY_DONGLE_DP_HDMI_DONGLE:
436                 if (audio_support->hdmi_audio_on_dongle)
437                         signal =  SIGNAL_TYPE_HDMI_TYPE_A;
438                 else
439                         signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
440                 break;
441         case DISPLAY_DONGLE_DP_DVI_DONGLE:
442                 signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
443                 break;
444         case DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE:
445                 if (audio_support->hdmi_audio_native)
446                         signal =  SIGNAL_TYPE_HDMI_TYPE_A;
447                 else
448                         signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
449                 break;
450         default:
451                 signal = SIGNAL_TYPE_NONE;
452                 break;
453         }
454
455         return signal;
456 }
457
458 static enum signal_type dp_passive_dongle_detection(
459                 struct ddc_service *ddc,
460                 struct display_sink_capability *sink_cap,
461                 struct audio_support *audio_support)
462 {
463         dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
464                                                 ddc, sink_cap);
465         return decide_signal_from_strap_and_dongle_type(
466                         sink_cap->dongle_type,
467                         audio_support);
468 }
469
470 static void link_disconnect_sink(struct dc_link *link)
471 {
472         if (link->local_sink) {
473                 dc_sink_release(link->local_sink);
474                 link->local_sink = NULL;
475         }
476
477         link->dpcd_sink_count = 0;
478 }
479
480 static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *link)
481 {
482         dc_sink_release(link->local_sink);
483         link->local_sink = prev_sink;
484 }
485
486
487 static bool detect_dp(
488         struct dc_link *link,
489         struct display_sink_capability *sink_caps,
490         bool *converter_disable_audio,
491         struct audio_support *audio_support,
492         enum dc_detect_reason reason)
493 {
494         bool boot = false;
495         sink_caps->signal = link_detect_sink(link, reason);
496         sink_caps->transaction_type =
497                 get_ddc_transaction_type(sink_caps->signal);
498
499         if (sink_caps->transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
500                 sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
501                 if (!detect_dp_sink_caps(link))
502                         return false;
503
504                 if (is_mst_supported(link)) {
505                         sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
506                         link->type = dc_connection_mst_branch;
507
508                         dal_ddc_service_set_transaction_type(
509                                                         link->ddc,
510                                                         sink_caps->transaction_type);
511
512                         /*
513                          * This call will initiate MST topology discovery. Which
514                          * will detect MST ports and add new DRM connector DRM
515                          * framework. Then read EDID via remote i2c over aux. In
516                          * the end, will notify DRM detect result and save EDID
517                          * into DRM framework.
518                          *
519                          * .detect is called by .fill_modes.
520                          * .fill_modes is called by user mode ioctl
521                          * DRM_IOCTL_MODE_GETCONNECTOR.
522                          *
523                          * .get_modes is called by .fill_modes.
524                          *
525                          * call .get_modes, AMDGPU DM implementation will create
526                          * new dc_sink and add to dc_link. For long HPD plug
527                          * in/out, MST has its own handle.
528                          *
529                          * Therefore, just after dc_create, link->sink is not
530                          * created for MST until user mode app calls
531                          * DRM_IOCTL_MODE_GETCONNECTOR.
532                          *
533                          * Need check ->sink usages in case ->sink = NULL
534                          * TODO: s3 resume check
535                          */
536                         if (reason == DETECT_REASON_BOOT)
537                                 boot = true;
538
539                         dm_helpers_dp_update_branch_info(
540                                 link->ctx,
541                                 link);
542
543                         if (!dm_helpers_dp_mst_start_top_mgr(
544                                 link->ctx,
545                                 link, boot)) {
546                                 /* MST not supported */
547                                 link->type = dc_connection_single;
548                                 sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
549                         }
550                 }
551
552                 if (link->type != dc_connection_mst_branch &&
553                         is_dp_active_dongle(link)) {
554                         /* DP active dongles */
555                         link->type = dc_connection_active_dongle;
556                         if (!link->dpcd_caps.sink_count.bits.SINK_COUNT) {
557                                 /*
558                                  * active dongle unplug processing for short irq
559                                  */
560                                 link_disconnect_sink(link);
561                                 return true;
562                         }
563
564                         if (link->dpcd_caps.dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER)
565                                 *converter_disable_audio = true;
566                 }
567         } else {
568                 /* DP passive dongles */
569                 sink_caps->signal = dp_passive_dongle_detection(link->ddc,
570                                 sink_caps,
571                                 audio_support);
572         }
573
574         return true;
575 }
576
577 static bool is_same_edid(struct dc_edid *old_edid, struct dc_edid *new_edid)
578 {
579         if (old_edid->length != new_edid->length)
580                 return false;
581
582         if (new_edid->length == 0)
583                 return false;
584
585         return (memcmp(old_edid->raw_edid, new_edid->raw_edid, new_edid->length) == 0);
586 }
587
588 bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
589 {
590         struct dc_sink_init_data sink_init_data = { 0 };
591         struct display_sink_capability sink_caps = { 0 };
592         uint8_t i;
593         bool converter_disable_audio = false;
594         struct audio_support *aud_support = &link->dc->res_pool->audio_support;
595         bool same_edid = false;
596         enum dc_edid_status edid_status;
597         struct dc_context *dc_ctx = link->ctx;
598         struct dc_sink *sink = NULL;
599         struct dc_sink *prev_sink = NULL;
600         struct dpcd_caps prev_dpcd_caps;
601         bool same_dpcd = true;
602         enum dc_connection_type new_connection_type = dc_connection_none;
603         DC_LOGGER_INIT(link->ctx->logger);
604         if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
605                 return false;
606
607         if (false == detect_sink(link, &new_connection_type)) {
608                 BREAK_TO_DEBUGGER();
609                 return false;
610         }
611
612         if (link->connector_signal == SIGNAL_TYPE_EDP &&
613                         link->local_sink)
614                 return true;
615
616         prev_sink = link->local_sink;
617         if (prev_sink != NULL) {
618                 dc_sink_retain(prev_sink);
619                 memcpy(&prev_dpcd_caps, &link->dpcd_caps, sizeof(struct dpcd_caps));
620         }
621         link_disconnect_sink(link);
622
623         if (new_connection_type != dc_connection_none) {
624                 link->type = new_connection_type;
625
626                 /* From Disconnected-to-Connected. */
627                 switch (link->connector_signal) {
628                 case SIGNAL_TYPE_HDMI_TYPE_A: {
629                         sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
630                         if (aud_support->hdmi_audio_native)
631                                 sink_caps.signal = SIGNAL_TYPE_HDMI_TYPE_A;
632                         else
633                                 sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
634                         break;
635                 }
636
637                 case SIGNAL_TYPE_DVI_SINGLE_LINK: {
638                         sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
639                         sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
640                         break;
641                 }
642
643                 case SIGNAL_TYPE_DVI_DUAL_LINK: {
644                         sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
645                         sink_caps.signal = SIGNAL_TYPE_DVI_DUAL_LINK;
646                         break;
647                 }
648
649                 case SIGNAL_TYPE_EDP: {
650                         detect_edp_sink_caps(link);
651                         sink_caps.transaction_type =
652                                 DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
653                         sink_caps.signal = SIGNAL_TYPE_EDP;
654                         break;
655                 }
656
657                 case SIGNAL_TYPE_DISPLAY_PORT: {
658                         if (!detect_dp(
659                                 link,
660                                 &sink_caps,
661                                 &converter_disable_audio,
662                                 aud_support, reason)) {
663                                 if (prev_sink != NULL)
664                                         dc_sink_release(prev_sink);
665                                 return false;
666                         }
667
668                         // Check if dpcp block is the same
669                         if (prev_sink != NULL) {
670                                 if (memcmp(&link->dpcd_caps, &prev_dpcd_caps, sizeof(struct dpcd_caps)))
671                                         same_dpcd = false;
672                         }
673                         /* Active dongle downstream unplug */
674                         if (link->type == dc_connection_active_dongle
675                                         && link->dpcd_caps.sink_count.
676                                         bits.SINK_COUNT == 0) {
677                                 if (prev_sink != NULL)
678                                         dc_sink_release(prev_sink);
679                                 return true;
680                         }
681
682                         if (link->type == dc_connection_mst_branch) {
683                                 LINK_INFO("link=%d, mst branch is now Connected\n",
684                                         link->link_index);
685                                 /* Need to setup mst link_cap struct here
686                                  * otherwise dc_link_detect() will leave mst link_cap
687                                  * empty which leads to allocate_mst_payload() has "0"
688                                  * pbn_per_slot value leading to exception on dc_fixpt_div()
689                                  */
690                                 link->verified_link_cap = link->reported_link_cap;
691                                 if (prev_sink != NULL)
692                                         dc_sink_release(prev_sink);
693                                 return false;
694                         }
695
696                         break;
697                 }
698
699                 default:
700                         DC_ERROR("Invalid connector type! signal:%d\n",
701                                 link->connector_signal);
702                         if (prev_sink != NULL)
703                                 dc_sink_release(prev_sink);
704                         return false;
705                 } /* switch() */
706
707                 if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
708                         link->dpcd_sink_count = link->dpcd_caps.sink_count.
709                                         bits.SINK_COUNT;
710                 else
711                         link->dpcd_sink_count = 1;
712
713                 dal_ddc_service_set_transaction_type(
714                                                 link->ddc,
715                                                 sink_caps.transaction_type);
716
717                 link->aux_mode = dal_ddc_service_is_in_aux_transaction_mode(
718                                 link->ddc);
719
720                 sink_init_data.link = link;
721                 sink_init_data.sink_signal = sink_caps.signal;
722
723                 sink = dc_sink_create(&sink_init_data);
724                 if (!sink) {
725                         DC_ERROR("Failed to create sink!\n");
726                         if (prev_sink != NULL)
727                                 dc_sink_release(prev_sink);
728                         return false;
729                 }
730
731                 sink->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock;
732                 sink->converter_disable_audio = converter_disable_audio;
733
734                 link->local_sink = sink;
735
736                 edid_status = dm_helpers_read_local_edid(
737                                 link->ctx,
738                                 link,
739                                 sink);
740
741                 switch (edid_status) {
742                 case EDID_BAD_CHECKSUM:
743                         DC_LOG_ERROR("EDID checksum invalid.\n");
744                         break;
745                 case EDID_NO_RESPONSE:
746                         DC_LOG_ERROR("No EDID read.\n");
747
748                         /*
749                          * Abort detection for non-DP connectors if we have
750                          * no EDID
751                          *
752                          * DP needs to report as connected if HDP is high
753                          * even if we have no EDID in order to go to
754                          * fail-safe mode
755                          */
756                         if (dc_is_hdmi_signal(link->connector_signal) ||
757                             dc_is_dvi_signal(link->connector_signal))
758                                 return false;
759                 default:
760                         break;
761                 }
762
763                 // Check if edid is the same
764                 if ((prev_sink != NULL) && ((edid_status == EDID_THE_SAME) || (edid_status == EDID_OK)))
765                         same_edid = is_same_edid(&prev_sink->dc_edid, &sink->dc_edid);
766
767                 if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
768                         sink_caps.transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX &&
769                         reason != DETECT_REASON_HPDRX) {
770                         /*
771                          * TODO debug why Dell 2413 doesn't like
772                          *  two link trainings
773                          */
774
775                         /* deal with non-mst cases */
776                         for (i = 0; i < LINK_TRAINING_MAX_VERIFY_RETRY; i++) {
777                                 int fail_count = 0;
778
779                                 dp_verify_link_cap(link,
780                                                   &link->reported_link_cap,
781                                                   &fail_count);
782
783                                 if (fail_count == 0)
784                                         break;
785                         }
786
787                 } else {
788                         // If edid is the same, then discard new sink and revert back to original sink
789                         if (same_edid) {
790                                 link_disconnect_remap(prev_sink, link);
791                                 sink = prev_sink;
792                                 prev_sink = NULL;
793
794                         }
795                 }
796
797                 /* HDMI-DVI Dongle */
798                 if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
799                                 !sink->edid_caps.edid_hdmi)
800                         sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
801
802                 /* Connectivity log: detection */
803                 for (i = 0; i < sink->dc_edid.length / EDID_BLOCK_SIZE; i++) {
804                         CONN_DATA_DETECT(link,
805                                         &sink->dc_edid.raw_edid[i * EDID_BLOCK_SIZE],
806                                         EDID_BLOCK_SIZE,
807                                         "%s: [Block %d] ", sink->edid_caps.display_name, i);
808                 }
809
810                 DC_LOG_DETECTION_EDID_PARSER("%s: "
811                         "manufacturer_id = %X, "
812                         "product_id = %X, "
813                         "serial_number = %X, "
814                         "manufacture_week = %d, "
815                         "manufacture_year = %d, "
816                         "display_name = %s, "
817                         "speaker_flag = %d, "
818                         "audio_mode_count = %d\n",
819                         __func__,
820                         sink->edid_caps.manufacturer_id,
821                         sink->edid_caps.product_id,
822                         sink->edid_caps.serial_number,
823                         sink->edid_caps.manufacture_week,
824                         sink->edid_caps.manufacture_year,
825                         sink->edid_caps.display_name,
826                         sink->edid_caps.speaker_flags,
827                         sink->edid_caps.audio_mode_count);
828
829                 for (i = 0; i < sink->edid_caps.audio_mode_count; i++) {
830                         DC_LOG_DETECTION_EDID_PARSER("%s: mode number = %d, "
831                                 "format_code = %d, "
832                                 "channel_count = %d, "
833                                 "sample_rate = %d, "
834                                 "sample_size = %d\n",
835                                 __func__,
836                                 i,
837                                 sink->edid_caps.audio_modes[i].format_code,
838                                 sink->edid_caps.audio_modes[i].channel_count,
839                                 sink->edid_caps.audio_modes[i].sample_rate,
840                                 sink->edid_caps.audio_modes[i].sample_size);
841                 }
842
843         } else {
844                 /* From Connected-to-Disconnected. */
845                 if (link->type == dc_connection_mst_branch) {
846                         LINK_INFO("link=%d, mst branch is now Disconnected\n",
847                                 link->link_index);
848
849                         dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
850
851                         link->mst_stream_alloc_table.stream_count = 0;
852                         memset(link->mst_stream_alloc_table.stream_allocations, 0, sizeof(link->mst_stream_alloc_table.stream_allocations));
853                 }
854
855                 link->type = dc_connection_none;
856                 sink_caps.signal = SIGNAL_TYPE_NONE;
857         }
858
859         LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p dpcd same=%d edid same=%d\n",
860                 link->link_index, sink,
861                 (sink_caps.signal == SIGNAL_TYPE_NONE ?
862                         "Disconnected":"Connected"), prev_sink,
863                         same_dpcd, same_edid);
864
865         if (prev_sink != NULL)
866                 dc_sink_release(prev_sink);
867
868         return true;
869 }
870
871 static enum hpd_source_id get_hpd_line(
872                 struct dc_link *link)
873 {
874         struct gpio *hpd;
875         enum hpd_source_id hpd_id = HPD_SOURCEID_UNKNOWN;
876
877         hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
878
879         if (hpd) {
880                 switch (dal_irq_get_source(hpd)) {
881                 case DC_IRQ_SOURCE_HPD1:
882                         hpd_id = HPD_SOURCEID1;
883                 break;
884                 case DC_IRQ_SOURCE_HPD2:
885                         hpd_id = HPD_SOURCEID2;
886                 break;
887                 case DC_IRQ_SOURCE_HPD3:
888                         hpd_id = HPD_SOURCEID3;
889                 break;
890                 case DC_IRQ_SOURCE_HPD4:
891                         hpd_id = HPD_SOURCEID4;
892                 break;
893                 case DC_IRQ_SOURCE_HPD5:
894                         hpd_id = HPD_SOURCEID5;
895                 break;
896                 case DC_IRQ_SOURCE_HPD6:
897                         hpd_id = HPD_SOURCEID6;
898                 break;
899                 default:
900                         BREAK_TO_DEBUGGER();
901                 break;
902                 }
903
904                 dal_gpio_destroy_irq(&hpd);
905         }
906
907         return hpd_id;
908 }
909
910 static enum channel_id get_ddc_line(struct dc_link *link)
911 {
912         struct ddc *ddc;
913         enum channel_id channel = CHANNEL_ID_UNKNOWN;
914
915         ddc = dal_ddc_service_get_ddc_pin(link->ddc);
916
917         if (ddc) {
918                 switch (dal_ddc_get_line(ddc)) {
919                 case GPIO_DDC_LINE_DDC1:
920                         channel = CHANNEL_ID_DDC1;
921                         break;
922                 case GPIO_DDC_LINE_DDC2:
923                         channel = CHANNEL_ID_DDC2;
924                         break;
925                 case GPIO_DDC_LINE_DDC3:
926                         channel = CHANNEL_ID_DDC3;
927                         break;
928                 case GPIO_DDC_LINE_DDC4:
929                         channel = CHANNEL_ID_DDC4;
930                         break;
931                 case GPIO_DDC_LINE_DDC5:
932                         channel = CHANNEL_ID_DDC5;
933                         break;
934                 case GPIO_DDC_LINE_DDC6:
935                         channel = CHANNEL_ID_DDC6;
936                         break;
937                 case GPIO_DDC_LINE_DDC_VGA:
938                         channel = CHANNEL_ID_DDC_VGA;
939                         break;
940                 case GPIO_DDC_LINE_I2C_PAD:
941                         channel = CHANNEL_ID_I2C_PAD;
942                         break;
943                 default:
944                         BREAK_TO_DEBUGGER();
945                         break;
946                 }
947         }
948
949         return channel;
950 }
951
952 static enum transmitter translate_encoder_to_transmitter(
953         struct graphics_object_id encoder)
954 {
955         switch (encoder.id) {
956         case ENCODER_ID_INTERNAL_UNIPHY:
957                 switch (encoder.enum_id) {
958                 case ENUM_ID_1:
959                         return TRANSMITTER_UNIPHY_A;
960                 case ENUM_ID_2:
961                         return TRANSMITTER_UNIPHY_B;
962                 default:
963                         return TRANSMITTER_UNKNOWN;
964                 }
965         break;
966         case ENCODER_ID_INTERNAL_UNIPHY1:
967                 switch (encoder.enum_id) {
968                 case ENUM_ID_1:
969                         return TRANSMITTER_UNIPHY_C;
970                 case ENUM_ID_2:
971                         return TRANSMITTER_UNIPHY_D;
972                 default:
973                         return TRANSMITTER_UNKNOWN;
974                 }
975         break;
976         case ENCODER_ID_INTERNAL_UNIPHY2:
977                 switch (encoder.enum_id) {
978                 case ENUM_ID_1:
979                         return TRANSMITTER_UNIPHY_E;
980                 case ENUM_ID_2:
981                         return TRANSMITTER_UNIPHY_F;
982                 default:
983                         return TRANSMITTER_UNKNOWN;
984                 }
985         break;
986         case ENCODER_ID_INTERNAL_UNIPHY3:
987                 switch (encoder.enum_id) {
988                 case ENUM_ID_1:
989                         return TRANSMITTER_UNIPHY_G;
990                 default:
991                         return TRANSMITTER_UNKNOWN;
992                 }
993         break;
994         case ENCODER_ID_EXTERNAL_NUTMEG:
995                 switch (encoder.enum_id) {
996                 case ENUM_ID_1:
997                         return TRANSMITTER_NUTMEG_CRT;
998                 default:
999                         return TRANSMITTER_UNKNOWN;
1000                 }
1001         break;
1002         case ENCODER_ID_EXTERNAL_TRAVIS:
1003                 switch (encoder.enum_id) {
1004                 case ENUM_ID_1:
1005                         return TRANSMITTER_TRAVIS_CRT;
1006                 case ENUM_ID_2:
1007                         return TRANSMITTER_TRAVIS_LCD;
1008                 default:
1009                         return TRANSMITTER_UNKNOWN;
1010                 }
1011         break;
1012         default:
1013                 return TRANSMITTER_UNKNOWN;
1014         }
1015 }
1016
1017 static bool construct(
1018         struct dc_link *link,
1019         const struct link_init_data *init_params)
1020 {
1021         uint8_t i;
1022         struct gpio *hpd_gpio = NULL;
1023         struct ddc_service_init_data ddc_service_init_data = { { 0 } };
1024         struct dc_context *dc_ctx = init_params->ctx;
1025         struct encoder_init_data enc_init_data = { 0 };
1026         struct integrated_info info = {{{ 0 }}};
1027         struct dc_bios *bios = init_params->dc->ctx->dc_bios;
1028         const struct dc_vbios_funcs *bp_funcs = bios->funcs;
1029         DC_LOGGER_INIT(dc_ctx->logger);
1030
1031         link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
1032         link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID;
1033
1034         link->link_status.dpcd_caps = &link->dpcd_caps;
1035
1036         link->dc = init_params->dc;
1037         link->ctx = dc_ctx;
1038         link->link_index = init_params->link_index;
1039
1040         link->link_id = bios->funcs->get_connector_id(bios, init_params->connector_index);
1041
1042         if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
1043                 dm_error("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
1044                          __func__, init_params->connector_index,
1045                          link->link_id.type, OBJECT_TYPE_CONNECTOR);
1046                 goto create_fail;
1047         }
1048
1049         if (link->dc->res_pool->funcs->link_init)
1050                 link->dc->res_pool->funcs->link_init(link);
1051
1052         hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
1053
1054         if (hpd_gpio != NULL)
1055                 link->irq_source_hpd = dal_irq_get_source(hpd_gpio);
1056
1057         switch (link->link_id.id) {
1058         case CONNECTOR_ID_HDMI_TYPE_A:
1059                 link->connector_signal = SIGNAL_TYPE_HDMI_TYPE_A;
1060
1061                 break;
1062         case CONNECTOR_ID_SINGLE_LINK_DVID:
1063         case CONNECTOR_ID_SINGLE_LINK_DVII:
1064                 link->connector_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
1065                 break;
1066         case CONNECTOR_ID_DUAL_LINK_DVID:
1067         case CONNECTOR_ID_DUAL_LINK_DVII:
1068                 link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
1069                 break;
1070         case CONNECTOR_ID_DISPLAY_PORT:
1071                 link->connector_signal =        SIGNAL_TYPE_DISPLAY_PORT;
1072
1073                 if (hpd_gpio != NULL)
1074                         link->irq_source_hpd_rx =
1075                                         dal_irq_get_rx_source(hpd_gpio);
1076
1077                 break;
1078         case CONNECTOR_ID_EDP:
1079                 link->connector_signal = SIGNAL_TYPE_EDP;
1080
1081                 if (hpd_gpio != NULL) {
1082                         link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
1083                         link->irq_source_hpd_rx =
1084                                         dal_irq_get_rx_source(hpd_gpio);
1085                 }
1086                 break;
1087         default:
1088                 DC_LOG_WARNING("Unsupported Connector type:%d!\n", link->link_id.id);
1089                 goto create_fail;
1090         }
1091
1092         if (hpd_gpio != NULL) {
1093                 dal_gpio_destroy_irq(&hpd_gpio);
1094                 hpd_gpio = NULL;
1095         }
1096
1097         /* TODO: #DAL3 Implement id to str function.*/
1098         LINK_INFO("Connector[%d] description:"
1099                         "signal %d\n",
1100                         init_params->connector_index,
1101                         link->connector_signal);
1102
1103         ddc_service_init_data.ctx = link->ctx;
1104         ddc_service_init_data.id = link->link_id;
1105         ddc_service_init_data.link = link;
1106         link->ddc = dal_ddc_service_create(&ddc_service_init_data);
1107
1108         if (link->ddc == NULL) {
1109                 DC_ERROR("Failed to create ddc_service!\n");
1110                 goto ddc_create_fail;
1111         }
1112
1113         link->ddc_hw_inst =
1114                 dal_ddc_get_line(
1115                         dal_ddc_service_get_ddc_pin(link->ddc));
1116
1117         enc_init_data.ctx = dc_ctx;
1118         bp_funcs->get_src_obj(dc_ctx->dc_bios, link->link_id, 0, &enc_init_data.encoder);
1119         enc_init_data.connector = link->link_id;
1120         enc_init_data.channel = get_ddc_line(link);
1121         enc_init_data.hpd_source = get_hpd_line(link);
1122
1123         link->hpd_src = enc_init_data.hpd_source;
1124
1125         enc_init_data.transmitter =
1126                         translate_encoder_to_transmitter(enc_init_data.encoder);
1127         link->link_enc = link->dc->res_pool->funcs->link_enc_create(
1128                                                                 &enc_init_data);
1129
1130         if( link->link_enc == NULL) {
1131                 DC_ERROR("Failed to create link encoder!\n");
1132                 goto link_enc_create_fail;
1133         }
1134
1135         link->link_enc_hw_inst = link->link_enc->transmitter;
1136
1137         for (i = 0; i < 4; i++) {
1138                 if (BP_RESULT_OK !=
1139                                 bp_funcs->get_device_tag(dc_ctx->dc_bios, link->link_id, i, &link->device_tag)) {
1140                         DC_ERROR("Failed to find device tag!\n");
1141                         goto device_tag_fail;
1142                 }
1143
1144                 /* Look for device tag that matches connector signal,
1145                  * CRT for rgb, LCD for other supported signal tyes
1146                  */
1147                 if (!bp_funcs->is_device_id_supported(dc_ctx->dc_bios, link->device_tag.dev_id))
1148                         continue;
1149                 if (link->device_tag.dev_id.device_type == DEVICE_TYPE_CRT
1150                         && link->connector_signal != SIGNAL_TYPE_RGB)
1151                         continue;
1152                 if (link->device_tag.dev_id.device_type == DEVICE_TYPE_LCD
1153                         && link->connector_signal == SIGNAL_TYPE_RGB)
1154                         continue;
1155                 break;
1156         }
1157
1158         if (bios->integrated_info)
1159                 info = *bios->integrated_info;
1160
1161         /* Look for channel mapping corresponding to connector and device tag */
1162         for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; i++) {
1163                 struct external_display_path *path =
1164                         &info.ext_disp_conn_info.path[i];
1165                 if (path->device_connector_id.enum_id == link->link_id.enum_id
1166                         && path->device_connector_id.id == link->link_id.id
1167                         && path->device_connector_id.type == link->link_id.type) {
1168
1169                         if (link->device_tag.acpi_device != 0
1170                                 && path->device_acpi_enum == link->device_tag.acpi_device) {
1171                                 link->ddi_channel_mapping = path->channel_mapping;
1172                                 link->chip_caps = path->caps;
1173                         } else if (path->device_tag ==
1174                                         link->device_tag.dev_id.raw_device_tag) {
1175                                 link->ddi_channel_mapping = path->channel_mapping;
1176                                 link->chip_caps = path->caps;
1177                         }
1178                         break;
1179                 }
1180         }
1181
1182         /*
1183          * TODO check if GPIO programmed correctly
1184          *
1185          * If GPIO isn't programmed correctly HPD might not rise or drain
1186          * fast enough, leading to bounces.
1187          */
1188         program_hpd_filter(link);
1189
1190         return true;
1191 device_tag_fail:
1192         link->link_enc->funcs->destroy(&link->link_enc);
1193 link_enc_create_fail:
1194         dal_ddc_service_destroy(&link->ddc);
1195 ddc_create_fail:
1196 create_fail:
1197
1198         if (hpd_gpio != NULL) {
1199                 dal_gpio_destroy_irq(&hpd_gpio);
1200         }
1201
1202         return false;
1203 }
1204
1205 /*******************************************************************************
1206  * Public functions
1207  ******************************************************************************/
1208 struct dc_link *link_create(const struct link_init_data *init_params)
1209 {
1210         struct dc_link *link =
1211                         kzalloc(sizeof(*link), GFP_KERNEL);
1212
1213         if (NULL == link)
1214                 goto alloc_fail;
1215
1216         if (false == construct(link, init_params))
1217                 goto construct_fail;
1218
1219         return link;
1220
1221 construct_fail:
1222         kfree(link);
1223
1224 alloc_fail:
1225         return NULL;
1226 }
1227
1228 void link_destroy(struct dc_link **link)
1229 {
1230         destruct(*link);
1231         kfree(*link);
1232         *link = NULL;
1233 }
1234
1235 static void dpcd_configure_panel_mode(
1236         struct dc_link *link,
1237         enum dp_panel_mode panel_mode)
1238 {
1239         union dpcd_edp_config edp_config_set;
1240         bool panel_mode_edp = false;
1241         DC_LOGGER_INIT(link->ctx->logger);
1242
1243         memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config));
1244
1245         if (DP_PANEL_MODE_DEFAULT != panel_mode) {
1246
1247                 switch (panel_mode) {
1248                 case DP_PANEL_MODE_EDP:
1249                 case DP_PANEL_MODE_SPECIAL:
1250                         panel_mode_edp = true;
1251                         break;
1252
1253                 default:
1254                         break;
1255                 }
1256
1257                 /*set edp panel mode in receiver*/
1258                 core_link_read_dpcd(
1259                         link,
1260                         DP_EDP_CONFIGURATION_SET,
1261                         &edp_config_set.raw,
1262                         sizeof(edp_config_set.raw));
1263
1264                 if (edp_config_set.bits.PANEL_MODE_EDP
1265                         != panel_mode_edp) {
1266                         enum ddc_result result = DDC_RESULT_UNKNOWN;
1267
1268                         edp_config_set.bits.PANEL_MODE_EDP =
1269                         panel_mode_edp;
1270                         result = core_link_write_dpcd(
1271                                 link,
1272                                 DP_EDP_CONFIGURATION_SET,
1273                                 &edp_config_set.raw,
1274                                 sizeof(edp_config_set.raw));
1275
1276                         ASSERT(result == DDC_RESULT_SUCESSFULL);
1277                 }
1278         }
1279         DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d "
1280                         "eDP panel mode enabled: %d \n",
1281                         link->link_index,
1282                         link->dpcd_caps.panel_mode_edp,
1283                         panel_mode_edp);
1284 }
1285
1286 static void enable_stream_features(struct pipe_ctx *pipe_ctx)
1287 {
1288         struct dc_stream_state *stream = pipe_ctx->stream;
1289         struct dc_link *link = stream->sink->link;
1290         union down_spread_ctrl old_downspread;
1291         union down_spread_ctrl new_downspread;
1292
1293         core_link_read_dpcd(link, DP_DOWNSPREAD_CTRL,
1294                         &old_downspread.raw, sizeof(old_downspread));
1295
1296         new_downspread.raw = old_downspread.raw;
1297
1298         new_downspread.bits.IGNORE_MSA_TIMING_PARAM =
1299                         (stream->ignore_msa_timing_param) ? 1 : 0;
1300
1301         if (new_downspread.raw != old_downspread.raw) {
1302                 core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
1303                         &new_downspread.raw, sizeof(new_downspread));
1304         }
1305 }
1306
1307 static enum dc_status enable_link_dp(
1308                 struct dc_state *state,
1309                 struct pipe_ctx *pipe_ctx)
1310 {
1311         struct dc_stream_state *stream = pipe_ctx->stream;
1312         enum dc_status status;
1313         bool skip_video_pattern;
1314         struct dc_link *link = stream->sink->link;
1315         struct dc_link_settings link_settings = {0};
1316         enum dp_panel_mode panel_mode;
1317         enum dc_link_rate max_link_rate = LINK_RATE_HIGH2;
1318
1319         /* get link settings for video mode timing */
1320         decide_link_settings(stream, &link_settings);
1321
1322         /* raise clock state for HBR3 if required. Confirmed with HW DCE/DPCS
1323          * logic for HBR3 still needs Nominal (0.8V) on VDDC rail
1324          */
1325         if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE)
1326                 max_link_rate = LINK_RATE_HIGH3;
1327
1328         if (link_settings.link_rate == max_link_rate) {
1329                 struct dc_clocks clocks = state->bw.dcn.clk;
1330
1331                 /* dce/dcn compat, do not update dispclk */
1332                 clocks.dispclk_khz = 0;
1333                 /* 27mhz = 27000000hz= 27000khz */
1334                 clocks.phyclk_khz = link_settings.link_rate * 27000;
1335
1336                 state->dis_clk->funcs->update_clocks(
1337                                 state->dis_clk, &clocks, false);
1338         }
1339
1340         dp_enable_link_phy(
1341                 link,
1342                 pipe_ctx->stream->signal,
1343                 pipe_ctx->clock_source->id,
1344                 &link_settings);
1345
1346         if (stream->sink->edid_caps.panel_patch.dppowerup_delay > 0) {
1347                 int delay_dp_power_up_in_ms = stream->sink->edid_caps.panel_patch.dppowerup_delay;
1348
1349                 msleep(delay_dp_power_up_in_ms);
1350         }
1351
1352         panel_mode = dp_get_panel_mode(link);
1353         dpcd_configure_panel_mode(link, panel_mode);
1354
1355         skip_video_pattern = true;
1356
1357         if (link_settings.link_rate == LINK_RATE_LOW)
1358                         skip_video_pattern = false;
1359
1360         if (perform_link_training_with_retries(
1361                         link,
1362                         &link_settings,
1363                         skip_video_pattern,
1364                         LINK_TRAINING_ATTEMPTS)) {
1365                 link->cur_link_settings = link_settings;
1366                 status = DC_OK;
1367         }
1368         else
1369                 status = DC_FAIL_DP_LINK_TRAINING;
1370
1371         enable_stream_features(pipe_ctx);
1372
1373         return status;
1374 }
1375
1376 static enum dc_status enable_link_edp(
1377                 struct dc_state *state,
1378                 struct pipe_ctx *pipe_ctx)
1379 {
1380         enum dc_status status;
1381         struct dc_stream_state *stream = pipe_ctx->stream;
1382         struct dc_link *link = stream->sink->link;
1383         /*in case it is not on*/
1384         link->dc->hwss.edp_power_control(link, true);
1385         link->dc->hwss.edp_wait_for_hpd_ready(link, true);
1386
1387         status = enable_link_dp(state, pipe_ctx);
1388
1389
1390         return status;
1391 }
1392
1393 static enum dc_status enable_link_dp_mst(
1394                 struct dc_state *state,
1395                 struct pipe_ctx *pipe_ctx)
1396 {
1397         struct dc_link *link = pipe_ctx->stream->sink->link;
1398
1399         /* sink signal type after MST branch is MST. Multiple MST sinks
1400          * share one link. Link DP PHY is enable or training only once.
1401          */
1402         if (link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN)
1403                 return DC_OK;
1404
1405         /* clear payload table */
1406         dm_helpers_dp_mst_clear_payload_allocation_table(link->ctx, link);
1407
1408         /* set the sink to MST mode before enabling the link */
1409         dp_enable_mst_on_sink(link, true);
1410
1411         return enable_link_dp(state, pipe_ctx);
1412 }
1413
1414 static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx,
1415                 enum engine_id eng_id,
1416                 struct ext_hdmi_settings *settings)
1417 {
1418         bool result = false;
1419         int i = 0;
1420         struct integrated_info *integrated_info =
1421                         pipe_ctx->stream->ctx->dc_bios->integrated_info;
1422
1423         if (integrated_info == NULL)
1424                 return false;
1425
1426         /*
1427          * Get retimer settings from sbios for passing SI eye test for DCE11
1428          * The setting values are varied based on board revision and port id
1429          * Therefore the setting values of each ports is passed by sbios.
1430          */
1431
1432         // Check if current bios contains ext Hdmi settings
1433         if (integrated_info->gpu_cap_info & 0x20) {
1434                 switch (eng_id) {
1435                 case ENGINE_ID_DIGA:
1436                         settings->slv_addr = integrated_info->dp0_ext_hdmi_slv_addr;
1437                         settings->reg_num = integrated_info->dp0_ext_hdmi_6g_reg_num;
1438                         settings->reg_num_6g = integrated_info->dp0_ext_hdmi_6g_reg_num;
1439                         memmove(settings->reg_settings,
1440                                         integrated_info->dp0_ext_hdmi_reg_settings,
1441                                         sizeof(integrated_info->dp0_ext_hdmi_reg_settings));
1442                         memmove(settings->reg_settings_6g,
1443                                         integrated_info->dp0_ext_hdmi_6g_reg_settings,
1444                                         sizeof(integrated_info->dp0_ext_hdmi_6g_reg_settings));
1445                         result = true;
1446                         break;
1447                 case ENGINE_ID_DIGB:
1448                         settings->slv_addr = integrated_info->dp1_ext_hdmi_slv_addr;
1449                         settings->reg_num = integrated_info->dp1_ext_hdmi_6g_reg_num;
1450                         settings->reg_num_6g = integrated_info->dp1_ext_hdmi_6g_reg_num;
1451                         memmove(settings->reg_settings,
1452                                         integrated_info->dp1_ext_hdmi_reg_settings,
1453                                         sizeof(integrated_info->dp1_ext_hdmi_reg_settings));
1454                         memmove(settings->reg_settings_6g,
1455                                         integrated_info->dp1_ext_hdmi_6g_reg_settings,
1456                                         sizeof(integrated_info->dp1_ext_hdmi_6g_reg_settings));
1457                         result = true;
1458                         break;
1459                 case ENGINE_ID_DIGC:
1460                         settings->slv_addr = integrated_info->dp2_ext_hdmi_slv_addr;
1461                         settings->reg_num = integrated_info->dp2_ext_hdmi_6g_reg_num;
1462                         settings->reg_num_6g = integrated_info->dp2_ext_hdmi_6g_reg_num;
1463                         memmove(settings->reg_settings,
1464                                         integrated_info->dp2_ext_hdmi_reg_settings,
1465                                         sizeof(integrated_info->dp2_ext_hdmi_reg_settings));
1466                         memmove(settings->reg_settings_6g,
1467                                         integrated_info->dp2_ext_hdmi_6g_reg_settings,
1468                                         sizeof(integrated_info->dp2_ext_hdmi_6g_reg_settings));
1469                         result = true;
1470                         break;
1471                 case ENGINE_ID_DIGD:
1472                         settings->slv_addr = integrated_info->dp3_ext_hdmi_slv_addr;
1473                         settings->reg_num = integrated_info->dp3_ext_hdmi_6g_reg_num;
1474                         settings->reg_num_6g = integrated_info->dp3_ext_hdmi_6g_reg_num;
1475                         memmove(settings->reg_settings,
1476                                         integrated_info->dp3_ext_hdmi_reg_settings,
1477                                         sizeof(integrated_info->dp3_ext_hdmi_reg_settings));
1478                         memmove(settings->reg_settings_6g,
1479                                         integrated_info->dp3_ext_hdmi_6g_reg_settings,
1480                                         sizeof(integrated_info->dp3_ext_hdmi_6g_reg_settings));
1481                         result = true;
1482                         break;
1483                 default:
1484                         break;
1485                 }
1486
1487                 if (result == true) {
1488                         // Validate settings from bios integrated info table
1489                         if (settings->slv_addr == 0)
1490                                 return false;
1491                         if (settings->reg_num > 9)
1492                                 return false;
1493                         if (settings->reg_num_6g > 3)
1494                                 return false;
1495
1496                         for (i = 0; i < settings->reg_num; i++) {
1497                                 if (settings->reg_settings[i].i2c_reg_index > 0x20)
1498                                         return false;
1499                         }
1500
1501                         for (i = 0; i < settings->reg_num_6g; i++) {
1502                                 if (settings->reg_settings_6g[i].i2c_reg_index > 0x20)
1503                                         return false;
1504                         }
1505                 }
1506         }
1507
1508         return result;
1509 }
1510
1511 static bool i2c_write(struct pipe_ctx *pipe_ctx,
1512                 uint8_t address, uint8_t *buffer, uint32_t length)
1513 {
1514         struct i2c_command cmd = {0};
1515         struct i2c_payload payload = {0};
1516
1517         memset(&payload, 0, sizeof(payload));
1518         memset(&cmd, 0, sizeof(cmd));
1519
1520         cmd.number_of_payloads = 1;
1521         cmd.engine = I2C_COMMAND_ENGINE_DEFAULT;
1522         cmd.speed = pipe_ctx->stream->ctx->dc->caps.i2c_speed_in_khz;
1523
1524         payload.address = address;
1525         payload.data = buffer;
1526         payload.length = length;
1527         payload.write = true;
1528         cmd.payloads = &payload;
1529
1530         if (dc_submit_i2c(pipe_ctx->stream->ctx->dc,
1531                         pipe_ctx->stream->sink->link->link_index, &cmd))
1532                 return true;
1533
1534         return false;
1535 }
1536
1537 static void write_i2c_retimer_setting(
1538                 struct pipe_ctx *pipe_ctx,
1539                 bool is_vga_mode,
1540                 bool is_over_340mhz,
1541                 struct ext_hdmi_settings *settings)
1542 {
1543         uint8_t slave_address = (settings->slv_addr >> 1);
1544         uint8_t buffer[2];
1545         const uint8_t apply_rx_tx_change = 0x4;
1546         uint8_t offset = 0xA;
1547         uint8_t value = 0;
1548         int i = 0;
1549         bool i2c_success = false;
1550
1551         memset(&buffer, 0, sizeof(buffer));
1552
1553         /* Start Ext-Hdmi programming*/
1554
1555         for (i = 0; i < settings->reg_num; i++) {
1556                 /* Apply 3G settings */
1557                 if (settings->reg_settings[i].i2c_reg_index <= 0x20) {
1558
1559                         buffer[0] = settings->reg_settings[i].i2c_reg_index;
1560                         buffer[1] = settings->reg_settings[i].i2c_reg_val;
1561                         i2c_success = i2c_write(pipe_ctx, slave_address,
1562                                                 buffer, sizeof(buffer));
1563
1564                         if (!i2c_success)
1565                                 /* Write failure */
1566                                 ASSERT(i2c_success);
1567
1568                         /* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A
1569                          * needs to be set to 1 on every 0xA-0xC write.
1570                          */
1571                         if (settings->reg_settings[i].i2c_reg_index == 0xA ||
1572                                 settings->reg_settings[i].i2c_reg_index == 0xB ||
1573                                 settings->reg_settings[i].i2c_reg_index == 0xC) {
1574
1575                                 /* Query current value from offset 0xA */
1576                                 if (settings->reg_settings[i].i2c_reg_index == 0xA)
1577                                         value = settings->reg_settings[i].i2c_reg_val;
1578                                 else {
1579                                         i2c_success =
1580                                                 dal_ddc_service_query_ddc_data(
1581                                                 pipe_ctx->stream->sink->link->ddc,
1582                                                 slave_address, &offset, 1, &value, 1);
1583                                         if (!i2c_success)
1584                                                 /* Write failure */
1585                                                 ASSERT(i2c_success);
1586                                 }
1587
1588                                 buffer[0] = offset;
1589                                 /* Set APPLY_RX_TX_CHANGE bit to 1 */
1590                                 buffer[1] = value | apply_rx_tx_change;
1591                                 i2c_success = i2c_write(pipe_ctx, slave_address,
1592                                                 buffer, sizeof(buffer));
1593                                 if (!i2c_success)
1594                                         /* Write failure */
1595                                         ASSERT(i2c_success);
1596                         }
1597                 }
1598         }
1599
1600         /* Apply 3G settings */
1601         if (is_over_340mhz) {
1602                 for (i = 0; i < settings->reg_num_6g; i++) {
1603                         /* Apply 3G settings */
1604                         if (settings->reg_settings[i].i2c_reg_index <= 0x20) {
1605
1606                                 buffer[0] = settings->reg_settings_6g[i].i2c_reg_index;
1607                                 buffer[1] = settings->reg_settings_6g[i].i2c_reg_val;
1608                                 i2c_success = i2c_write(pipe_ctx, slave_address,
1609                                                         buffer, sizeof(buffer));
1610
1611                                 if (!i2c_success)
1612                                         /* Write failure */
1613                                         ASSERT(i2c_success);
1614
1615                                 /* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A
1616                                  * needs to be set to 1 on every 0xA-0xC write.
1617                                  */
1618                                 if (settings->reg_settings_6g[i].i2c_reg_index == 0xA ||
1619                                         settings->reg_settings_6g[i].i2c_reg_index == 0xB ||
1620                                         settings->reg_settings_6g[i].i2c_reg_index == 0xC) {
1621
1622                                         /* Query current value from offset 0xA */
1623                                         if (settings->reg_settings_6g[i].i2c_reg_index == 0xA)
1624                                                 value = settings->reg_settings_6g[i].i2c_reg_val;
1625                                         else {
1626                                                 i2c_success =
1627                                                                 dal_ddc_service_query_ddc_data(
1628                                                                 pipe_ctx->stream->sink->link->ddc,
1629                                                                 slave_address, &offset, 1, &value, 1);
1630                                                 if (!i2c_success)
1631                                                         /* Write failure */
1632                                                         ASSERT(i2c_success);
1633                                         }
1634
1635                                         buffer[0] = offset;
1636                                         /* Set APPLY_RX_TX_CHANGE bit to 1 */
1637                                         buffer[1] = value | apply_rx_tx_change;
1638                                         i2c_success = i2c_write(pipe_ctx, slave_address,
1639                                                         buffer, sizeof(buffer));
1640                                         if (!i2c_success)
1641                                                 /* Write failure */
1642                                                 ASSERT(i2c_success);
1643                                 }
1644                         }
1645                 }
1646         }
1647
1648         if (is_vga_mode) {
1649                 /* Program additional settings if using 640x480 resolution */
1650
1651                 /* Write offset 0xFF to 0x01 */
1652                 buffer[0] = 0xff;
1653                 buffer[1] = 0x01;
1654                 i2c_success = i2c_write(pipe_ctx, slave_address,
1655                                 buffer, sizeof(buffer));
1656                 if (!i2c_success)
1657                         /* Write failure */
1658                         ASSERT(i2c_success);
1659
1660                 /* Write offset 0x00 to 0x23 */
1661                 buffer[0] = 0x00;
1662                 buffer[1] = 0x23;
1663                 i2c_success = i2c_write(pipe_ctx, slave_address,
1664                                 buffer, sizeof(buffer));
1665                 if (!i2c_success)
1666                         /* Write failure */
1667                         ASSERT(i2c_success);
1668
1669                 /* Write offset 0xff to 0x00 */
1670                 buffer[0] = 0xff;
1671                 buffer[1] = 0x00;
1672                 i2c_success = i2c_write(pipe_ctx, slave_address,
1673                                 buffer, sizeof(buffer));
1674                 if (!i2c_success)
1675                         /* Write failure */
1676                         ASSERT(i2c_success);
1677
1678         }
1679 }
1680
1681 static void write_i2c_default_retimer_setting(
1682                 struct pipe_ctx *pipe_ctx,
1683                 bool is_vga_mode,
1684                 bool is_over_340mhz)
1685 {
1686         uint8_t slave_address = (0xBA >> 1);
1687         uint8_t buffer[2];
1688         bool i2c_success = false;
1689
1690         memset(&buffer, 0, sizeof(buffer));
1691
1692         /* Program Slave Address for tuning single integrity */
1693         /* Write offset 0x0A to 0x13 */
1694         buffer[0] = 0x0A;
1695         buffer[1] = 0x13;
1696         i2c_success = i2c_write(pipe_ctx, slave_address,
1697                         buffer, sizeof(buffer));
1698         if (!i2c_success)
1699                 /* Write failure */
1700                 ASSERT(i2c_success);
1701
1702         /* Write offset 0x0A to 0x17 */
1703         buffer[0] = 0x0A;
1704         buffer[1] = 0x17;
1705         i2c_success = i2c_write(pipe_ctx, slave_address,
1706                         buffer, sizeof(buffer));
1707         if (!i2c_success)
1708                 /* Write failure */
1709                 ASSERT(i2c_success);
1710
1711         /* Write offset 0x0B to 0xDA or 0xD8 */
1712         buffer[0] = 0x0B;
1713         buffer[1] = is_over_340mhz ? 0xDA : 0xD8;
1714         i2c_success = i2c_write(pipe_ctx, slave_address,
1715                         buffer, sizeof(buffer));
1716         if (!i2c_success)
1717                 /* Write failure */
1718                 ASSERT(i2c_success);
1719
1720         /* Write offset 0x0A to 0x17 */
1721         buffer[0] = 0x0A;
1722         buffer[1] = 0x17;
1723         i2c_success = i2c_write(pipe_ctx, slave_address,
1724                         buffer, sizeof(buffer));
1725         if (!i2c_success)
1726                 /* Write failure */
1727                 ASSERT(i2c_success);
1728
1729         /* Write offset 0x0C to 0x1D or 0x91 */
1730         buffer[0] = 0x0C;
1731         buffer[1] = is_over_340mhz ? 0x1D : 0x91;
1732         i2c_success = i2c_write(pipe_ctx, slave_address,
1733                         buffer, sizeof(buffer));
1734         if (!i2c_success)
1735                 /* Write failure */
1736                 ASSERT(i2c_success);
1737
1738         /* Write offset 0x0A to 0x17 */
1739         buffer[0] = 0x0A;
1740         buffer[1] = 0x17;
1741         i2c_success = i2c_write(pipe_ctx, slave_address,
1742                         buffer, sizeof(buffer));
1743         if (!i2c_success)
1744                 /* Write failure */
1745                 ASSERT(i2c_success);
1746
1747
1748         if (is_vga_mode) {
1749                 /* Program additional settings if using 640x480 resolution */
1750
1751                 /* Write offset 0xFF to 0x01 */
1752                 buffer[0] = 0xff;
1753                 buffer[1] = 0x01;
1754                 i2c_success = i2c_write(pipe_ctx, slave_address,
1755                                 buffer, sizeof(buffer));
1756                 if (!i2c_success)
1757                         /* Write failure */
1758                         ASSERT(i2c_success);
1759
1760                 /* Write offset 0x00 to 0x23 */
1761                 buffer[0] = 0x00;
1762                 buffer[1] = 0x23;
1763                 i2c_success = i2c_write(pipe_ctx, slave_address,
1764                                 buffer, sizeof(buffer));
1765                 if (!i2c_success)
1766                         /* Write failure */
1767                         ASSERT(i2c_success);
1768
1769                 /* Write offset 0xff to 0x00 */
1770                 buffer[0] = 0xff;
1771                 buffer[1] = 0x00;
1772                 i2c_success = i2c_write(pipe_ctx, slave_address,
1773                                 buffer, sizeof(buffer));
1774                 if (!i2c_success)
1775                         /* Write failure */
1776                         ASSERT(i2c_success);
1777         }
1778 }
1779
1780 static void write_i2c_redriver_setting(
1781                 struct pipe_ctx *pipe_ctx,
1782                 bool is_over_340mhz)
1783 {
1784         uint8_t slave_address = (0xF0 >> 1);
1785         uint8_t buffer[16];
1786         bool i2c_success = false;
1787
1788         memset(&buffer, 0, sizeof(buffer));
1789
1790         // Program Slave Address for tuning single integrity
1791         buffer[3] = 0x4E;
1792         buffer[4] = 0x4E;
1793         buffer[5] = 0x4E;
1794         buffer[6] = is_over_340mhz ? 0x4E : 0x4A;
1795
1796         i2c_success = i2c_write(pipe_ctx, slave_address,
1797                                         buffer, sizeof(buffer));
1798
1799         if (!i2c_success)
1800                 /* Write failure */
1801                 ASSERT(i2c_success);
1802 }
1803
1804 static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
1805 {
1806         struct dc_stream_state *stream = pipe_ctx->stream;
1807         struct dc_link *link = stream->sink->link;
1808         enum dc_color_depth display_color_depth;
1809         enum engine_id eng_id;
1810         struct ext_hdmi_settings settings = {0};
1811         bool is_over_340mhz = false;
1812         bool is_vga_mode = (stream->timing.h_addressable == 640)
1813                         && (stream->timing.v_addressable == 480);
1814
1815         if (stream->phy_pix_clk == 0)
1816                 stream->phy_pix_clk = stream->timing.pix_clk_khz;
1817         if (stream->phy_pix_clk > 340000)
1818                 is_over_340mhz = true;
1819
1820         if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
1821                 unsigned short masked_chip_caps = pipe_ctx->stream->sink->link->chip_caps &
1822                                 EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
1823                 if (masked_chip_caps == EXT_DISPLAY_PATH_CAPS__HDMI20_TISN65DP159RSBT) {
1824                         /* DP159, Retimer settings */
1825                         eng_id = pipe_ctx->stream_res.stream_enc->id;
1826
1827                         if (get_ext_hdmi_settings(pipe_ctx, eng_id, &settings)) {
1828                                 write_i2c_retimer_setting(pipe_ctx,
1829                                                 is_vga_mode, is_over_340mhz, &settings);
1830                         } else {
1831                                 write_i2c_default_retimer_setting(pipe_ctx,
1832                                                 is_vga_mode, is_over_340mhz);
1833                         }
1834                 } else if (masked_chip_caps == EXT_DISPLAY_PATH_CAPS__HDMI20_PI3EQX1204) {
1835                         /* PI3EQX1204, Redriver settings */
1836                         write_i2c_redriver_setting(pipe_ctx, is_over_340mhz);
1837                 }
1838         }
1839
1840         if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
1841                 dal_ddc_service_write_scdc_data(
1842                         stream->sink->link->ddc,
1843                         stream->phy_pix_clk,
1844                         stream->timing.flags.LTE_340MCSC_SCRAMBLE);
1845
1846         memset(&stream->sink->link->cur_link_settings, 0,
1847                         sizeof(struct dc_link_settings));
1848
1849         display_color_depth = stream->timing.display_color_depth;
1850         if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422)
1851                 display_color_depth = COLOR_DEPTH_888;
1852
1853         link->link_enc->funcs->enable_tmds_output(
1854                         link->link_enc,
1855                         pipe_ctx->clock_source->id,
1856                         display_color_depth,
1857                         pipe_ctx->stream->signal,
1858                         stream->phy_pix_clk);
1859
1860         if (pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
1861                 dal_ddc_service_read_scdc_data(link->ddc);
1862 }
1863
1864 /****************************enable_link***********************************/
1865 static enum dc_status enable_link(
1866                 struct dc_state *state,
1867                 struct pipe_ctx *pipe_ctx)
1868 {
1869         enum dc_status status = DC_ERROR_UNEXPECTED;
1870         switch (pipe_ctx->stream->signal) {
1871         case SIGNAL_TYPE_DISPLAY_PORT:
1872                 status = enable_link_dp(state, pipe_ctx);
1873                 break;
1874         case SIGNAL_TYPE_EDP:
1875                 status = enable_link_edp(state, pipe_ctx);
1876                 break;
1877         case SIGNAL_TYPE_DISPLAY_PORT_MST:
1878                 status = enable_link_dp_mst(state, pipe_ctx);
1879                 msleep(200);
1880                 break;
1881         case SIGNAL_TYPE_DVI_SINGLE_LINK:
1882         case SIGNAL_TYPE_DVI_DUAL_LINK:
1883         case SIGNAL_TYPE_HDMI_TYPE_A:
1884                 enable_link_hdmi(pipe_ctx);
1885                 status = DC_OK;
1886                 break;
1887         case SIGNAL_TYPE_VIRTUAL:
1888                 status = DC_OK;
1889                 break;
1890         default:
1891                 break;
1892         }
1893
1894         return status;
1895 }
1896
1897 static void disable_link(struct dc_link *link, enum signal_type signal)
1898 {
1899         /*
1900          * TODO: implement call for dp_set_hw_test_pattern
1901          * it is needed for compliance testing
1902          */
1903
1904         /* here we need to specify that encoder output settings
1905          * need to be calculated as for the set mode,
1906          * it will lead to querying dynamic link capabilities
1907          * which should be done before enable output */
1908
1909         if (dc_is_dp_signal(signal)) {
1910                 /* SST DP, eDP */
1911                 if (dc_is_dp_sst_signal(signal))
1912                         dp_disable_link_phy(link, signal);
1913                 else
1914                         dp_disable_link_phy_mst(link, signal);
1915         } else
1916                 link->link_enc->funcs->disable_output(link->link_enc, signal);
1917 }
1918
1919 static bool dp_active_dongle_validate_timing(
1920                 const struct dc_crtc_timing *timing,
1921                 const struct dpcd_caps *dpcd_caps)
1922 {
1923         unsigned int required_pix_clk = timing->pix_clk_khz;
1924         const struct dc_dongle_caps *dongle_caps = &dpcd_caps->dongle_caps;
1925
1926         switch (dpcd_caps->dongle_type) {
1927         case DISPLAY_DONGLE_DP_VGA_CONVERTER:
1928         case DISPLAY_DONGLE_DP_DVI_CONVERTER:
1929         case DISPLAY_DONGLE_DP_DVI_DONGLE:
1930                 if (timing->pixel_encoding == PIXEL_ENCODING_RGB)
1931                         return true;
1932                 else
1933                         return false;
1934         default:
1935                 break;
1936         }
1937
1938         if (dongle_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER ||
1939                 dongle_caps->extendedCapValid == false)
1940                 return true;
1941
1942         /* Check Pixel Encoding */
1943         switch (timing->pixel_encoding) {
1944         case PIXEL_ENCODING_RGB:
1945         case PIXEL_ENCODING_YCBCR444:
1946                 break;
1947         case PIXEL_ENCODING_YCBCR422:
1948                 if (!dongle_caps->is_dp_hdmi_ycbcr422_pass_through)
1949                         return false;
1950                 break;
1951         case PIXEL_ENCODING_YCBCR420:
1952                 if (!dongle_caps->is_dp_hdmi_ycbcr420_pass_through)
1953                         return false;
1954                 break;
1955         default:
1956                 /* Invalid Pixel Encoding*/
1957                 return false;
1958         }
1959
1960
1961         /* Check Color Depth and Pixel Clock */
1962         if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
1963                 required_pix_clk /= 2;
1964         else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
1965                 required_pix_clk = required_pix_clk * 2 / 3;
1966
1967         switch (timing->display_color_depth) {
1968         case COLOR_DEPTH_666:
1969         case COLOR_DEPTH_888:
1970                 /*888 and 666 should always be supported*/
1971                 break;
1972         case COLOR_DEPTH_101010:
1973                 if (dongle_caps->dp_hdmi_max_bpc < 10)
1974                         return false;
1975                 required_pix_clk = required_pix_clk * 10 / 8;
1976                 break;
1977         case COLOR_DEPTH_121212:
1978                 if (dongle_caps->dp_hdmi_max_bpc < 12)
1979                         return false;
1980                 required_pix_clk = required_pix_clk * 12 / 8;
1981                 break;
1982
1983         case COLOR_DEPTH_141414:
1984         case COLOR_DEPTH_161616:
1985         default:
1986                 /* These color depths are currently not supported */
1987                 return false;
1988         }
1989
1990         if (required_pix_clk > dongle_caps->dp_hdmi_max_pixel_clk)
1991                 return false;
1992
1993         return true;
1994 }
1995
1996 enum dc_status dc_link_validate_mode_timing(
1997                 const struct dc_stream_state *stream,
1998                 struct dc_link *link,
1999                 const struct dc_crtc_timing *timing)
2000 {
2001         uint32_t max_pix_clk = stream->sink->dongle_max_pix_clk;
2002         struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
2003
2004         /* A hack to avoid failing any modes for EDID override feature on
2005          * topology change such as lower quality cable for DP or different dongle
2006          */
2007         if (link->remote_sinks[0])
2008                 return DC_OK;
2009
2010         /* Passive Dongle */
2011         if (0 != max_pix_clk && timing->pix_clk_khz > max_pix_clk)
2012                 return DC_EXCEED_DONGLE_CAP;
2013
2014         /* Active Dongle*/
2015         if (!dp_active_dongle_validate_timing(timing, dpcd_caps))
2016                 return DC_EXCEED_DONGLE_CAP;
2017
2018         switch (stream->signal) {
2019         case SIGNAL_TYPE_EDP:
2020         case SIGNAL_TYPE_DISPLAY_PORT:
2021                 if (!dp_validate_mode_timing(
2022                                 link,
2023                                 timing))
2024                         return DC_NO_DP_LINK_BANDWIDTH;
2025                 break;
2026
2027         default:
2028                 break;
2029         }
2030
2031         return DC_OK;
2032 }
2033
2034 int dc_link_get_backlight_level(const struct dc_link *link)
2035 {
2036         struct abm *abm = link->ctx->dc->res_pool->abm;
2037
2038         if (abm == NULL || abm->funcs->get_current_backlight_8_bit == NULL)
2039                 return DC_ERROR_UNEXPECTED;
2040
2041         return (int) abm->funcs->get_current_backlight_8_bit(abm);
2042 }
2043
2044 bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level,
2045                 uint32_t frame_ramp, const struct dc_stream_state *stream)
2046 {
2047         struct dc  *core_dc = link->ctx->dc;
2048         struct abm *abm = core_dc->res_pool->abm;
2049         struct dmcu *dmcu = core_dc->res_pool->dmcu;
2050         unsigned int controller_id = 0;
2051         bool use_smooth_brightness = true;
2052         int i;
2053         DC_LOGGER_INIT(link->ctx->logger);
2054
2055         if ((dmcu == NULL) ||
2056                 (abm == NULL) ||
2057                 (abm->funcs->set_backlight_level == NULL))
2058                 return false;
2059
2060         if (stream) {
2061                 if (stream->bl_pwm_level == EDP_BACKLIGHT_RAMP_DISABLE_LEVEL)
2062                         frame_ramp = 0;
2063
2064                 ((struct dc_stream_state *)stream)->bl_pwm_level = level;
2065         }
2066
2067         use_smooth_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
2068
2069         DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", level, level);
2070
2071         if (dc_is_embedded_signal(link->connector_signal)) {
2072                 if (stream != NULL) {
2073                         for (i = 0; i < MAX_PIPES; i++) {
2074                                 if (core_dc->current_state->res_ctx.
2075                                                 pipe_ctx[i].stream
2076                                                 == stream)
2077                                         /* DMCU -1 for all controller id values,
2078                                          * therefore +1 here
2079                                          */
2080                                         controller_id =
2081                                                 core_dc->current_state->
2082                                                 res_ctx.pipe_ctx[i].stream_res.tg->inst +
2083                                                 1;
2084                         }
2085                 }
2086                 abm->funcs->set_backlight_level(
2087                                 abm,
2088                                 level,
2089                                 frame_ramp,
2090                                 controller_id,
2091                                 use_smooth_brightness);
2092         }
2093
2094         return true;
2095 }
2096
2097 bool dc_link_set_abm_disable(const struct dc_link *link)
2098 {
2099         struct dc  *core_dc = link->ctx->dc;
2100         struct abm *abm = core_dc->res_pool->abm;
2101
2102         if ((abm == NULL) || (abm->funcs->set_backlight_level == NULL))
2103                 return false;
2104
2105         abm->funcs->set_abm_immediate_disable(abm);
2106
2107         return true;
2108 }
2109
2110 bool dc_link_set_psr_enable(const struct dc_link *link, bool enable, bool wait)
2111 {
2112         struct dc  *core_dc = link->ctx->dc;
2113         struct dmcu *dmcu = core_dc->res_pool->dmcu;
2114
2115         if (dmcu != NULL && link->psr_enabled)
2116                 dmcu->funcs->set_psr_enable(dmcu, enable, wait);
2117
2118         return true;
2119 }
2120
2121 const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
2122 {
2123         return &link->link_status;
2124 }
2125
2126 void core_link_resume(struct dc_link *link)
2127 {
2128         if (link->connector_signal != SIGNAL_TYPE_VIRTUAL)
2129                 program_hpd_filter(link);
2130 }
2131
2132 static struct fixed31_32 get_pbn_per_slot(struct dc_stream_state *stream)
2133 {
2134         struct dc_link_settings *link_settings =
2135                         &stream->sink->link->cur_link_settings;
2136         uint32_t link_rate_in_mbps =
2137                         link_settings->link_rate * LINK_RATE_REF_FREQ_IN_MHZ;
2138         struct fixed31_32 mbps = dc_fixpt_from_int(
2139                         link_rate_in_mbps * link_settings->lane_count);
2140
2141         return dc_fixpt_div_int(mbps, 54);
2142 }
2143
2144 static int get_color_depth(enum dc_color_depth color_depth)
2145 {
2146         switch (color_depth) {
2147         case COLOR_DEPTH_666: return 6;
2148         case COLOR_DEPTH_888: return 8;
2149         case COLOR_DEPTH_101010: return 10;
2150         case COLOR_DEPTH_121212: return 12;
2151         case COLOR_DEPTH_141414: return 14;
2152         case COLOR_DEPTH_161616: return 16;
2153         default: return 0;
2154         }
2155 }
2156
2157 static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
2158 {
2159         uint32_t bpc;
2160         uint64_t kbps;
2161         struct fixed31_32 peak_kbps;
2162         uint32_t numerator;
2163         uint32_t denominator;
2164
2165         bpc = get_color_depth(pipe_ctx->stream_res.pix_clk_params.color_depth);
2166         kbps = pipe_ctx->stream_res.pix_clk_params.requested_pix_clk * bpc * 3;
2167
2168         /*
2169          * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
2170          * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on
2171          * common multiplier to render an integer PBN for all link rate/lane
2172          * counts combinations
2173          * calculate
2174          * peak_kbps *= (1006/1000)
2175          * peak_kbps *= (64/54)
2176          * peak_kbps *= 8    convert to bytes
2177          */
2178
2179         numerator = 64 * PEAK_FACTOR_X1000;
2180         denominator = 54 * 8 * 1000 * 1000;
2181         kbps *= numerator;
2182         peak_kbps = dc_fixpt_from_fraction(kbps, denominator);
2183
2184         return peak_kbps;
2185 }
2186
2187 static void update_mst_stream_alloc_table(
2188         struct dc_link *link,
2189         struct stream_encoder *stream_enc,
2190         const struct dp_mst_stream_allocation_table *proposed_table)
2191 {
2192         struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = {
2193                         { 0 } };
2194         struct link_mst_stream_allocation *dc_alloc;
2195
2196         int i;
2197         int j;
2198
2199         /* if DRM proposed_table has more than one new payload */
2200         ASSERT(proposed_table->stream_count -
2201                         link->mst_stream_alloc_table.stream_count < 2);
2202
2203         /* copy proposed_table to link, add stream encoder */
2204         for (i = 0; i < proposed_table->stream_count; i++) {
2205
2206                 for (j = 0; j < link->mst_stream_alloc_table.stream_count; j++) {
2207                         dc_alloc =
2208                         &link->mst_stream_alloc_table.stream_allocations[j];
2209
2210                         if (dc_alloc->vcp_id ==
2211                                 proposed_table->stream_allocations[i].vcp_id) {
2212
2213                                 work_table[i] = *dc_alloc;
2214                                 break; /* exit j loop */
2215                         }
2216                 }
2217
2218                 /* new vcp_id */
2219                 if (j == link->mst_stream_alloc_table.stream_count) {
2220                         work_table[i].vcp_id =
2221                                 proposed_table->stream_allocations[i].vcp_id;
2222                         work_table[i].slot_count =
2223                                 proposed_table->stream_allocations[i].slot_count;
2224                         work_table[i].stream_enc = stream_enc;
2225                 }
2226         }
2227
2228         /* update link->mst_stream_alloc_table with work_table */
2229         link->mst_stream_alloc_table.stream_count =
2230                         proposed_table->stream_count;
2231         for (i = 0; i < MAX_CONTROLLER_NUM; i++)
2232                 link->mst_stream_alloc_table.stream_allocations[i] =
2233                                 work_table[i];
2234 }
2235
2236 /* convert link_mst_stream_alloc_table to dm dp_mst_stream_alloc_table
2237  * because stream_encoder is not exposed to dm
2238  */
2239 static enum dc_status allocate_mst_payload(struct pipe_ctx *pipe_ctx)
2240 {
2241         struct dc_stream_state *stream = pipe_ctx->stream;
2242         struct dc_link *link = stream->sink->link;
2243         struct link_encoder *link_encoder = link->link_enc;
2244         struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
2245         struct dp_mst_stream_allocation_table proposed_table = {0};
2246         struct fixed31_32 avg_time_slots_per_mtp;
2247         struct fixed31_32 pbn;
2248         struct fixed31_32 pbn_per_slot;
2249         uint8_t i;
2250         DC_LOGGER_INIT(link->ctx->logger);
2251
2252         /* enable_link_dp_mst already check link->enabled_stream_count
2253          * and stream is in link->stream[]. This is called during set mode,
2254          * stream_enc is available.
2255          */
2256
2257         /* get calculate VC payload for stream: stream_alloc */
2258         if (dm_helpers_dp_mst_write_payload_allocation_table(
2259                 stream->ctx,
2260                 stream,
2261                 &proposed_table,
2262                 true)) {
2263                 update_mst_stream_alloc_table(
2264                                         link, pipe_ctx->stream_res.stream_enc, &proposed_table);
2265         }
2266         else
2267                 DC_LOG_WARNING("Failed to update"
2268                                 "MST allocation table for"
2269                                 "pipe idx:%d\n",
2270                                 pipe_ctx->pipe_idx);
2271
2272         DC_LOG_MST("%s  "
2273                         "stream_count: %d: \n ",
2274                         __func__,
2275                         link->mst_stream_alloc_table.stream_count);
2276
2277         for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
2278                 DC_LOG_MST("stream_enc[%d]: %p      "
2279                 "stream[%d].vcp_id: %d      "
2280                 "stream[%d].slot_count: %d\n",
2281                 i,
2282                 (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
2283                 i,
2284                 link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
2285                 i,
2286                 link->mst_stream_alloc_table.stream_allocations[i].slot_count);
2287         }
2288
2289         ASSERT(proposed_table.stream_count > 0);
2290
2291         /* program DP source TX for payload */
2292         link_encoder->funcs->update_mst_stream_allocation_table(
2293                 link_encoder,
2294                 &link->mst_stream_alloc_table);
2295
2296         /* send down message */
2297         dm_helpers_dp_mst_poll_for_allocation_change_trigger(
2298                         stream->ctx,
2299                         stream);
2300
2301         dm_helpers_dp_mst_send_payload_allocation(
2302                         stream->ctx,
2303                         stream,
2304                         true);
2305
2306         /* slot X.Y for only current stream */
2307         pbn_per_slot = get_pbn_per_slot(stream);
2308         pbn = get_pbn_from_timing(pipe_ctx);
2309         avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
2310
2311         stream_encoder->funcs->set_mst_bandwidth(
2312                 stream_encoder,
2313                 avg_time_slots_per_mtp);
2314
2315         return DC_OK;
2316
2317 }
2318
2319 static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
2320 {
2321         struct dc_stream_state *stream = pipe_ctx->stream;
2322         struct dc_link *link = stream->sink->link;
2323         struct link_encoder *link_encoder = link->link_enc;
2324         struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
2325         struct dp_mst_stream_allocation_table proposed_table = {0};
2326         struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
2327         uint8_t i;
2328         bool mst_mode = (link->type == dc_connection_mst_branch);
2329         DC_LOGGER_INIT(link->ctx->logger);
2330
2331         /* deallocate_mst_payload is called before disable link. When mode or
2332          * disable/enable monitor, new stream is created which is not in link
2333          * stream[] yet. For this, payload is not allocated yet, so de-alloc
2334          * should not done. For new mode set, map_resources will get engine
2335          * for new stream, so stream_enc->id should be validated until here.
2336          */
2337
2338         /* slot X.Y */
2339         stream_encoder->funcs->set_mst_bandwidth(
2340                 stream_encoder,
2341                 avg_time_slots_per_mtp);
2342
2343         /* TODO: which component is responsible for remove payload table? */
2344         if (mst_mode) {
2345                 if (dm_helpers_dp_mst_write_payload_allocation_table(
2346                                 stream->ctx,
2347                                 stream,
2348                                 &proposed_table,
2349                                 false)) {
2350
2351                         update_mst_stream_alloc_table(
2352                                 link, pipe_ctx->stream_res.stream_enc, &proposed_table);
2353                 }
2354                 else {
2355                                 DC_LOG_WARNING("Failed to update"
2356                                                 "MST allocation table for"
2357                                                 "pipe idx:%d\n",
2358                                                 pipe_ctx->pipe_idx);
2359                 }
2360         }
2361
2362         DC_LOG_MST("%s"
2363                         "stream_count: %d: ",
2364                         __func__,
2365                         link->mst_stream_alloc_table.stream_count);
2366
2367         for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
2368                 DC_LOG_MST("stream_enc[%d]: %p      "
2369                 "stream[%d].vcp_id: %d      "
2370                 "stream[%d].slot_count: %d\n",
2371                 i,
2372                 (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
2373                 i,
2374                 link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
2375                 i,
2376                 link->mst_stream_alloc_table.stream_allocations[i].slot_count);
2377         }
2378
2379         link_encoder->funcs->update_mst_stream_allocation_table(
2380                 link_encoder,
2381                 &link->mst_stream_alloc_table);
2382
2383         if (mst_mode) {
2384                 dm_helpers_dp_mst_poll_for_allocation_change_trigger(
2385                         stream->ctx,
2386                         stream);
2387
2388                 dm_helpers_dp_mst_send_payload_allocation(
2389                         stream->ctx,
2390                         stream,
2391                         false);
2392         }
2393
2394         return DC_OK;
2395 }
2396
2397 void core_link_enable_stream(
2398                 struct dc_state *state,
2399                 struct pipe_ctx *pipe_ctx)
2400 {
2401         struct dc  *core_dc = pipe_ctx->stream->ctx->dc;
2402         enum dc_status status;
2403         DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
2404
2405         /* eDP lit up by bios already, no need to enable again. */
2406         if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
2407                 core_dc->apply_edp_fast_boot_optimization) {
2408                 core_dc->apply_edp_fast_boot_optimization = false;
2409                 pipe_ctx->stream->dpms_off = false;
2410                 return;
2411         }
2412
2413         if (pipe_ctx->stream->dpms_off)
2414                 return;
2415
2416         status = enable_link(state, pipe_ctx);
2417
2418         if (status != DC_OK) {
2419                         DC_LOG_WARNING("enabling link %u failed: %d\n",
2420                         pipe_ctx->stream->sink->link->link_index,
2421                         status);
2422
2423                         /* Abort stream enable *unless* the failure was due to
2424                          * DP link training - some DP monitors will recover and
2425                          * show the stream anyway. But MST displays can't proceed
2426                          * without link training.
2427                          */
2428                         if (status != DC_FAIL_DP_LINK_TRAINING ||
2429                                         pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
2430                                 BREAK_TO_DEBUGGER();
2431                                 return;
2432                         }
2433         }
2434
2435         core_dc->hwss.enable_audio_stream(pipe_ctx);
2436
2437         /* turn off otg test pattern if enable */
2438         if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
2439                 pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
2440                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
2441                                 COLOR_DEPTH_UNDEFINED);
2442
2443         core_dc->hwss.enable_stream(pipe_ctx);
2444
2445         if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
2446                 allocate_mst_payload(pipe_ctx);
2447
2448         core_dc->hwss.unblank_stream(pipe_ctx,
2449                 &pipe_ctx->stream->sink->link->cur_link_settings);
2450 }
2451
2452 void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
2453 {
2454         struct dc  *core_dc = pipe_ctx->stream->ctx->dc;
2455
2456         if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
2457                 deallocate_mst_payload(pipe_ctx);
2458
2459         core_dc->hwss.blank_stream(pipe_ctx);
2460
2461         core_dc->hwss.disable_stream(pipe_ctx, option);
2462
2463         disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal);
2464 }
2465
2466 void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
2467 {
2468         struct dc  *core_dc = pipe_ctx->stream->ctx->dc;
2469
2470         if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A)
2471                 return;
2472
2473         core_dc->hwss.set_avmute(pipe_ctx, enable);
2474 }
2475
2476 /**
2477  *****************************************************************************
2478  *  Function: dc_link_enable_hpd_filter
2479  *
2480  *  @brief
2481  *     If enable is true, programs HPD filter on associated HPD line using
2482  *     delay_on_disconnect/delay_on_connect values dependent on
2483  *     link->connector_signal
2484  *
2485  *     If enable is false, programs HPD filter on associated HPD line with no
2486  *     delays on connect or disconnect
2487  *
2488  *  @param [in] link: pointer to the dc link
2489  *  @param [in] enable: boolean specifying whether to enable hbd
2490  *****************************************************************************
2491  */
2492 void dc_link_enable_hpd_filter(struct dc_link *link, bool enable)
2493 {
2494         struct gpio *hpd;
2495
2496         if (enable) {
2497                 link->is_hpd_filter_disabled = false;
2498                 program_hpd_filter(link);
2499         } else {
2500                 link->is_hpd_filter_disabled = true;
2501                 /* Obtain HPD handle */
2502                 hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
2503
2504                 if (!hpd)
2505                         return;
2506
2507                 /* Setup HPD filtering */
2508                 if (dal_gpio_open(hpd, GPIO_MODE_INTERRUPT) == GPIO_RESULT_OK) {
2509                         struct gpio_hpd_config config;
2510
2511                         config.delay_on_connect = 0;
2512                         config.delay_on_disconnect = 0;
2513
2514                         dal_irq_setup_hpd_filter(hpd, &config);
2515
2516                         dal_gpio_close(hpd);
2517                 } else {
2518                         ASSERT_CRITICAL(false);
2519                 }
2520                 /* Release HPD handle */
2521                 dal_gpio_destroy_irq(&hpd);
2522         }
2523 }
2524