forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/gpu/drm/amd/display/dc/core/dc_link.c
....@@ -23,8 +23,10 @@
2323 *
2424 */
2525
26
+#include <linux/slab.h>
27
+
2628 #include "dm_services.h"
27
-#include "atom.h"
29
+#include "atomfirmware.h"
2830 #include "dm_helpers.h"
2931 #include "dc.h"
3032 #include "grph_object_id.h"
....@@ -42,45 +44,54 @@
4244 #include "fixed31_32.h"
4345 #include "dpcd_defs.h"
4446 #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"
47
+#include "hw/clk_mgr.h"
48
+#include "dce/dmub_psr.h"
49
+#include "dmub/dmub_srv.h"
50
+#include "inc/hw/panel_cntl.h"
4951
5052 #define DC_LOGGER_INIT(logger)
51
-
5253
5354 #define LINK_INFO(...) \
5455 DC_LOG_HW_HOTPLUG( \
5556 __VA_ARGS__)
5657
58
+#define RETIMER_REDRIVER_INFO(...) \
59
+ DC_LOG_RETIMER_REDRIVER( \
60
+ __VA_ARGS__)
5761 /*******************************************************************************
5862 * Private structures
5963 ******************************************************************************/
6064
6165 enum {
62
- LINK_RATE_REF_FREQ_IN_MHZ = 27,
6366 PEAK_FACTOR_X1000 = 1006,
6467 /*
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
- */
68
+ * Some receivers fail to train on first try and are good
69
+ * on subsequent tries. 2 retries should be plenty. If we
70
+ * don't have a successful training then we don't expect to
71
+ * ever get one.
72
+ */
7073 LINK_TRAINING_MAX_VERIFY_RETRY = 2
7174 };
7275
7376 /*******************************************************************************
7477 * Private functions
7578 ******************************************************************************/
76
-static void destruct(struct dc_link *link)
79
+static void dc_link_destruct(struct dc_link *link)
7780 {
7881 int i;
82
+
83
+ if (link->hpd_gpio) {
84
+ dal_gpio_destroy_irq(&link->hpd_gpio);
85
+ link->hpd_gpio = NULL;
86
+ }
7987
8088 if (link->ddc)
8189 dal_ddc_service_destroy(&link->ddc);
8290
83
- if(link->link_enc)
91
+ if (link->panel_cntl)
92
+ link->panel_cntl->funcs->destroy(&link->panel_cntl);
93
+
94
+ if (link->link_enc)
8495 link->link_enc->funcs->destroy(&link->link_enc);
8596
8697 if (link->local_sink)
....@@ -91,8 +102,8 @@
91102 }
92103
93104 struct gpio *get_hpd_gpio(struct dc_bios *dcb,
94
- struct graphics_object_id link_id,
95
- struct gpio_service *gpio_service)
105
+ struct graphics_object_id link_id,
106
+ struct gpio_service *gpio_service)
96107 {
97108 enum bp_result bp_result;
98109 struct graphics_object_hpd_info hpd_info;
....@@ -109,10 +120,9 @@
109120 return NULL;
110121 }
111122
112
- return dal_gpio_service_create_irq(
113
- gpio_service,
114
- pin_info.offset,
115
- pin_info.mask);
123
+ return dal_gpio_service_create_irq(gpio_service,
124
+ pin_info.offset,
125
+ pin_info.mask);
116126 }
117127
118128 /*
....@@ -127,13 +137,10 @@
127137 * @return
128138 * true on success, false otherwise
129139 */
130
-static bool program_hpd_filter(
131
- const struct dc_link *link)
140
+static bool program_hpd_filter(const struct dc_link *link)
132141 {
133142 bool result = false;
134
-
135143 struct gpio *hpd;
136
-
137144 int delay_on_connect_in_ms = 0;
138145 int delay_on_disconnect_in_ms = 0;
139146
....@@ -152,10 +159,10 @@
152159 case SIGNAL_TYPE_DISPLAY_PORT_MST:
153160 /* Program hpd filter to allow DP signal to settle */
154161 /* 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.
162
+ * only 100ms on DELL U2413
163
+ * 0: some passive dongle still show aux mode instead of i2c
164
+ * 20-50: not enough to hide bouncing HPD with passive dongle.
165
+ * also see intermittent i2c read issues.
159166 */
160167 delay_on_connect_in_ms = 80;
161168 delay_on_disconnect_in_ms = 0;
....@@ -168,7 +175,8 @@
168175 }
169176
170177 /* Obtain HPD handle */
171
- hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
178
+ hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id,
179
+ link->ctx->gpio_service);
172180
173181 if (!hpd)
174182 return result;
....@@ -195,14 +203,33 @@
195203 return result;
196204 }
197205
206
+/**
207
+ * dc_link_detect_sink() - Determine if there is a sink connected
208
+ *
209
+ * @type: Returned connection type
210
+ * Does not detect downstream devices, such as MST sinks
211
+ * or display connected through active dongles
212
+ */
198213 bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type)
199214 {
200215 uint32_t is_hpd_high = 0;
201216 struct gpio *hpd_pin;
202217
218
+ if (link->connector_signal == SIGNAL_TYPE_LVDS) {
219
+ *type = dc_connection_single;
220
+ return true;
221
+ }
222
+
223
+ if (link->connector_signal == SIGNAL_TYPE_EDP) {
224
+ /*in case it is not on*/
225
+ link->dc->hwss.edp_power_control(link, true);
226
+ link->dc->hwss.edp_wait_for_hpd_ready(link, true);
227
+ }
228
+
203229 /* 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)
230
+ hpd_pin = get_hpd_gpio(link->ctx->dc_bios, link->link_id,
231
+ link->ctx->gpio_service);
232
+ if (!hpd_pin)
206233 goto hpd_gpio_failure;
207234
208235 dal_gpio_open(hpd_pin, GPIO_MODE_INTERRUPT);
....@@ -223,8 +250,7 @@
223250 return false;
224251 }
225252
226
-static enum ddc_transaction_type get_ddc_transaction_type(
227
- enum signal_type sink_signal)
253
+static enum ddc_transaction_type get_ddc_transaction_type(enum signal_type sink_signal)
228254 {
229255 enum ddc_transaction_type transaction_type = DDC_TRANSACTION_TYPE_NONE;
230256
....@@ -245,7 +271,8 @@
245271 case SIGNAL_TYPE_DISPLAY_PORT_MST:
246272 /* MST does not use I2COverAux, but there is the
247273 * SPECIAL use case for "immediate dwnstrm device
248
- * access" (EPR#370830). */
274
+ * access" (EPR#370830).
275
+ */
249276 transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
250277 break;
251278
....@@ -256,9 +283,8 @@
256283 return transaction_type;
257284 }
258285
259
-static enum signal_type get_basic_signal_type(
260
- struct graphics_object_id encoder,
261
- struct graphics_object_id downstream)
286
+static enum signal_type get_basic_signal_type(struct graphics_object_id encoder,
287
+ struct graphics_object_id downstream)
262288 {
263289 if (downstream.type == OBJECT_TYPE_CONNECTOR) {
264290 switch (downstream.id) {
....@@ -316,9 +342,9 @@
316342 return SIGNAL_TYPE_NONE;
317343 }
318344
319
-/*
320
- * @brief
321
- * Check whether there is a dongle on DP connector
345
+/**
346
+ * dc_link_is_dp_sink_present() - Check if there is a native DP
347
+ * or passive DP-HDMI dongle connected
322348 */
323349 bool dc_link_is_dp_sink_present(struct dc_link *link)
324350 {
....@@ -344,10 +370,11 @@
344370 /* Open GPIO and set it to I2C mode */
345371 /* Note: this GpioMode_Input will be converted
346372 * to GpioConfigType_I2cAuxDualMode in GPIO component,
347
- * which indicates we need additional delay */
373
+ * which indicates we need additional delay
374
+ */
348375
349
- if (GPIO_RESULT_OK != dal_ddc_open(
350
- ddc, GPIO_MODE_INPUT, GPIO_DDC_CONFIG_TYPE_MODE_I2C)) {
376
+ if (dal_ddc_open(ddc, GPIO_MODE_INPUT,
377
+ GPIO_DDC_CONFIG_TYPE_MODE_I2C) != GPIO_RESULT_OK) {
351378 dal_ddc_close(ddc);
352379
353380 return present;
....@@ -381,25 +408,25 @@
381408 * @brief
382409 * Detect output sink type
383410 */
384
-static enum signal_type link_detect_sink(
385
- struct dc_link *link,
386
- enum dc_detect_reason reason)
411
+static enum signal_type link_detect_sink(struct dc_link *link,
412
+ enum dc_detect_reason reason)
387413 {
388
- enum signal_type result = get_basic_signal_type(
389
- link->link_enc->id, link->link_id);
414
+ enum signal_type result = get_basic_signal_type(link->link_enc->id,
415
+ link->link_id);
390416
391417 /* Internal digital encoder will detect only dongles
392
- * that require digital signal */
418
+ * that require digital signal
419
+ */
393420
394421 /* Detection mechanism is different
395422 * for different native connectors.
396423 * LVDS connector supports only LVDS signal;
397424 * PCIE is a bus slot, the actual connector needs to be detected first;
398425 * eDP connector supports only eDP signal;
399
- * HDMI should check straps for audio */
426
+ * HDMI should check straps for audio
427
+ */
400428
401429 /* PCIE detects the actual connector on add-on board */
402
-
403430 if (link->link_id.id == CONNECTOR_ID_PCIE) {
404431 /* ZAZTODO implement PCIE add-on card detection */
405432 }
....@@ -407,8 +434,10 @@
407434 switch (link->link_id.id) {
408435 case CONNECTOR_ID_HDMI_TYPE_A: {
409436 /* check audio support:
410
- * if native HDMI is not supported, switch to DVI */
411
- struct audio_support *aud_support = &link->dc->res_pool->audio_support;
437
+ * if native HDMI is not supported, switch to DVI
438
+ */
439
+ struct audio_support *aud_support =
440
+ &link->dc->res_pool->audio_support;
412441
413442 if (!aud_support->hdmi_audio_native)
414443 if (link->link_id.id == CONNECTOR_ID_HDMI_TYPE_A)
....@@ -436,16 +465,15 @@
436465 return result;
437466 }
438467
439
-static enum signal_type decide_signal_from_strap_and_dongle_type(
440
- enum display_dongle_type dongle_type,
441
- struct audio_support *audio_support)
468
+static enum signal_type decide_signal_from_strap_and_dongle_type(enum display_dongle_type dongle_type,
469
+ struct audio_support *audio_support)
442470 {
443471 enum signal_type signal = SIGNAL_TYPE_NONE;
444472
445473 switch (dongle_type) {
446474 case DISPLAY_DONGLE_DP_HDMI_DONGLE:
447475 if (audio_support->hdmi_audio_on_dongle)
448
- signal = SIGNAL_TYPE_HDMI_TYPE_A;
476
+ signal = SIGNAL_TYPE_HDMI_TYPE_A;
449477 else
450478 signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
451479 break;
....@@ -466,16 +494,14 @@
466494 return signal;
467495 }
468496
469
-static enum signal_type dp_passive_dongle_detection(
470
- struct ddc_service *ddc,
471
- struct display_sink_capability *sink_cap,
472
- struct audio_support *audio_support)
497
+static enum signal_type dp_passive_dongle_detection(struct ddc_service *ddc,
498
+ struct display_sink_capability *sink_cap,
499
+ struct audio_support *audio_support)
473500 {
474
- dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
475
- ddc, sink_cap);
476
- return decide_signal_from_strap_and_dongle_type(
477
- sink_cap->dongle_type,
478
- audio_support);
501
+ dal_ddc_service_i2c_query_dp_dual_mode_adaptor(ddc, sink_cap);
502
+
503
+ return decide_signal_from_strap_and_dongle_type(sink_cap->dongle_type,
504
+ audio_support);
479505 }
480506
481507 static void link_disconnect_sink(struct dc_link *link)
....@@ -494,15 +520,170 @@
494520 link->local_sink = prev_sink;
495521 }
496522
523
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
524
+bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal)
525
+{
526
+ bool ret = false;
497527
498
-static bool detect_dp(
499
- struct dc_link *link,
500
- struct display_sink_capability *sink_caps,
501
- bool *converter_disable_audio,
502
- struct audio_support *audio_support,
503
- enum dc_detect_reason reason)
528
+ switch (signal) {
529
+ case SIGNAL_TYPE_DISPLAY_PORT:
530
+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
531
+ ret = link->hdcp_caps.bcaps.bits.HDCP_CAPABLE;
532
+ break;
533
+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
534
+ case SIGNAL_TYPE_DVI_DUAL_LINK:
535
+ case SIGNAL_TYPE_HDMI_TYPE_A:
536
+ /* HDMI doesn't tell us its HDCP(1.4) capability, so assume to always be capable,
537
+ * we can poll for bksv but some displays have an issue with this. Since its so rare
538
+ * for a display to not be 1.4 capable, this assumtion is ok
539
+ */
540
+ ret = true;
541
+ break;
542
+ default:
543
+ break;
544
+ }
545
+ return ret;
546
+}
547
+
548
+bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal)
549
+{
550
+ bool ret = false;
551
+
552
+ switch (signal) {
553
+ case SIGNAL_TYPE_DISPLAY_PORT:
554
+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
555
+ ret = (link->hdcp_caps.bcaps.bits.HDCP_CAPABLE &&
556
+ link->hdcp_caps.rx_caps.fields.byte0.hdcp_capable &&
557
+ (link->hdcp_caps.rx_caps.fields.version == 0x2)) ? 1 : 0;
558
+ break;
559
+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
560
+ case SIGNAL_TYPE_DVI_DUAL_LINK:
561
+ case SIGNAL_TYPE_HDMI_TYPE_A:
562
+ ret = (link->hdcp_caps.rx_caps.fields.version == 0x4) ? 1:0;
563
+ break;
564
+ default:
565
+ break;
566
+ }
567
+
568
+ return ret;
569
+}
570
+
571
+static void query_hdcp_capability(enum signal_type signal, struct dc_link *link)
572
+{
573
+ struct hdcp_protection_message msg22;
574
+ struct hdcp_protection_message msg14;
575
+
576
+ memset(&msg22, 0, sizeof(struct hdcp_protection_message));
577
+ memset(&msg14, 0, sizeof(struct hdcp_protection_message));
578
+ memset(link->hdcp_caps.rx_caps.raw, 0,
579
+ sizeof(link->hdcp_caps.rx_caps.raw));
580
+
581
+ if ((link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
582
+ link->ddc->transaction_type ==
583
+ DDC_TRANSACTION_TYPE_I2C_OVER_AUX) ||
584
+ link->connector_signal == SIGNAL_TYPE_EDP) {
585
+ msg22.data = link->hdcp_caps.rx_caps.raw;
586
+ msg22.length = sizeof(link->hdcp_caps.rx_caps.raw);
587
+ msg22.msg_id = HDCP_MESSAGE_ID_RX_CAPS;
588
+ } else {
589
+ msg22.data = &link->hdcp_caps.rx_caps.fields.version;
590
+ msg22.length = sizeof(link->hdcp_caps.rx_caps.fields.version);
591
+ msg22.msg_id = HDCP_MESSAGE_ID_HDCP2VERSION;
592
+ }
593
+ msg22.version = HDCP_VERSION_22;
594
+ msg22.link = HDCP_LINK_PRIMARY;
595
+ msg22.max_retries = 5;
596
+ dc_process_hdcp_msg(signal, link, &msg22);
597
+
598
+ if (signal == SIGNAL_TYPE_DISPLAY_PORT || signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
599
+ enum hdcp_message_status status = HDCP_MESSAGE_UNSUPPORTED;
600
+
601
+ msg14.data = &link->hdcp_caps.bcaps.raw;
602
+ msg14.length = sizeof(link->hdcp_caps.bcaps.raw);
603
+ msg14.msg_id = HDCP_MESSAGE_ID_READ_BCAPS;
604
+ msg14.version = HDCP_VERSION_14;
605
+ msg14.link = HDCP_LINK_PRIMARY;
606
+ msg14.max_retries = 5;
607
+
608
+ status = dc_process_hdcp_msg(signal, link, &msg14);
609
+ }
610
+
611
+}
612
+#endif
613
+
614
+static void read_current_link_settings_on_detect(struct dc_link *link)
615
+{
616
+ union lane_count_set lane_count_set = { {0} };
617
+ uint8_t link_bw_set;
618
+ uint8_t link_rate_set;
619
+ uint32_t read_dpcd_retry_cnt = 10;
620
+ enum dc_status status = DC_ERROR_UNEXPECTED;
621
+ int i;
622
+ union max_down_spread max_down_spread = { {0} };
623
+
624
+ // Read DPCD 00101h to find out the number of lanes currently set
625
+ for (i = 0; i < read_dpcd_retry_cnt; i++) {
626
+ status = core_link_read_dpcd(link,
627
+ DP_LANE_COUNT_SET,
628
+ &lane_count_set.raw,
629
+ sizeof(lane_count_set));
630
+ /* First DPCD read after VDD ON can fail if the particular board
631
+ * does not have HPD pin wired correctly. So if DPCD read fails,
632
+ * which it should never happen, retry a few times. Target worst
633
+ * case scenario of 80 ms.
634
+ */
635
+ if (status == DC_OK) {
636
+ link->cur_link_settings.lane_count =
637
+ lane_count_set.bits.LANE_COUNT_SET;
638
+ break;
639
+ }
640
+
641
+ msleep(8);
642
+ }
643
+
644
+ // Read DPCD 00100h to find if standard link rates are set
645
+ core_link_read_dpcd(link, DP_LINK_BW_SET,
646
+ &link_bw_set, sizeof(link_bw_set));
647
+
648
+ if (link_bw_set == 0) {
649
+ if (link->connector_signal == SIGNAL_TYPE_EDP) {
650
+ /* If standard link rates are not being used,
651
+ * Read DPCD 00115h to find the edp link rate set used
652
+ */
653
+ core_link_read_dpcd(link, DP_LINK_RATE_SET,
654
+ &link_rate_set, sizeof(link_rate_set));
655
+
656
+ // edp_supported_link_rates_count = 0 for DP
657
+ if (link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
658
+ link->cur_link_settings.link_rate =
659
+ link->dpcd_caps.edp_supported_link_rates[link_rate_set];
660
+ link->cur_link_settings.link_rate_set = link_rate_set;
661
+ link->cur_link_settings.use_link_rate_set = true;
662
+ }
663
+ } else {
664
+ // Link Rate not found. Seamless boot may not work.
665
+ ASSERT(false);
666
+ }
667
+ } else {
668
+ link->cur_link_settings.link_rate = link_bw_set;
669
+ link->cur_link_settings.use_link_rate_set = false;
670
+ }
671
+ // Read DPCD 00003h to find the max down spread.
672
+ core_link_read_dpcd(link, DP_MAX_DOWNSPREAD,
673
+ &max_down_spread.raw, sizeof(max_down_spread));
674
+ link->cur_link_settings.link_spread =
675
+ max_down_spread.bits.MAX_DOWN_SPREAD ?
676
+ LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
677
+}
678
+
679
+static bool detect_dp(struct dc_link *link,
680
+ struct display_sink_capability *sink_caps,
681
+ bool *converter_disable_audio,
682
+ struct audio_support *audio_support,
683
+ enum dc_detect_reason reason)
504684 {
505685 bool boot = false;
686
+
506687 sink_caps->signal = link_detect_sink(link, reason);
507688 sink_caps->transaction_type =
508689 get_ddc_transaction_type(sink_caps->signal);
....@@ -511,15 +692,19 @@
511692 sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
512693 if (!detect_dp_sink_caps(link))
513694 return false;
514
-
515695 if (is_mst_supported(link)) {
516696 sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
517697 link->type = dc_connection_mst_branch;
518698
519
- dal_ddc_service_set_transaction_type(
520
- link->ddc,
521
- sink_caps->transaction_type);
699
+ dal_ddc_service_set_transaction_type(link->ddc,
700
+ sink_caps->transaction_type);
522701
702
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
703
+ /* In case of fallback to SST when topology discovery below fails
704
+ * HDCP caps will be querried again later by the upper layer (caller
705
+ * of this function). */
706
+ query_hdcp_capability(SIGNAL_TYPE_DISPLAY_PORT_MST, link);
707
+#endif
523708 /*
524709 * This call will initiate MST topology discovery. Which
525710 * will detect MST ports and add new DRM connector DRM
....@@ -547,13 +732,10 @@
547732 if (reason == DETECT_REASON_BOOT)
548733 boot = true;
549734
550
- dm_helpers_dp_update_branch_info(
551
- link->ctx,
552
- link);
735
+ dm_helpers_dp_update_branch_info(link->ctx, link);
553736
554
- if (!dm_helpers_dp_mst_start_top_mgr(
555
- link->ctx,
556
- link, boot)) {
737
+ if (!dm_helpers_dp_mst_start_top_mgr(link->ctx,
738
+ link, boot)) {
557739 /* MST not supported */
558740 link->type = dc_connection_single;
559741 sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
....@@ -561,7 +743,7 @@
561743 }
562744
563745 if (link->type != dc_connection_mst_branch &&
564
- is_dp_active_dongle(link)) {
746
+ is_dp_active_dongle(link)) {
565747 /* DP active dongles */
566748 link->type = dc_connection_active_dongle;
567749 if (!link->dpcd_caps.sink_count.bits.SINK_COUNT) {
....@@ -572,14 +754,16 @@
572754 return true;
573755 }
574756
575
- if (link->dpcd_caps.dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER)
757
+ if (link->dpcd_caps.dongle_type !=
758
+ DISPLAY_DONGLE_DP_HDMI_CONVERTER)
576759 *converter_disable_audio = true;
577760 }
578761 } else {
579762 /* DP passive dongles */
580763 sink_caps->signal = dp_passive_dongle_detection(link->ddc,
581
- sink_caps,
582
- audio_support);
764
+ sink_caps,
765
+ audio_support);
766
+ link->dpcd_caps.dongle_type = sink_caps->dongle_type;
583767 }
584768
585769 return true;
....@@ -593,10 +777,69 @@
593777 if (new_edid->length == 0)
594778 return false;
595779
596
- return (memcmp(old_edid->raw_edid, new_edid->raw_edid, new_edid->length) == 0);
780
+ return (memcmp(old_edid->raw_edid,
781
+ new_edid->raw_edid, new_edid->length) == 0);
597782 }
598783
599
-bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
784
+static bool wait_for_entering_dp_alt_mode(struct dc_link *link)
785
+{
786
+ /**
787
+ * something is terribly wrong if time out is > 200ms. (5Hz)
788
+ * 500 microseconds * 400 tries us 200 ms
789
+ **/
790
+ unsigned int sleep_time_in_microseconds = 500;
791
+ unsigned int tries_allowed = 400;
792
+ bool is_in_alt_mode;
793
+ unsigned long long enter_timestamp;
794
+ unsigned long long finish_timestamp;
795
+ unsigned long long time_taken_in_ns;
796
+ int tries_taken;
797
+
798
+ DC_LOGGER_INIT(link->ctx->logger);
799
+
800
+ if (!link->link_enc->funcs->is_in_alt_mode)
801
+ return true;
802
+
803
+ is_in_alt_mode = link->link_enc->funcs->is_in_alt_mode(link->link_enc);
804
+ DC_LOG_WARNING("DP Alt mode state on HPD: %d\n", is_in_alt_mode);
805
+
806
+ if (is_in_alt_mode)
807
+ return true;
808
+
809
+ enter_timestamp = dm_get_timestamp(link->ctx);
810
+
811
+ for (tries_taken = 0; tries_taken < tries_allowed; tries_taken++) {
812
+ udelay(sleep_time_in_microseconds);
813
+ /* ask the link if alt mode is enabled, if so return ok */
814
+ if (link->link_enc->funcs->is_in_alt_mode(link->link_enc)) {
815
+ finish_timestamp = dm_get_timestamp(link->ctx);
816
+ time_taken_in_ns =
817
+ dm_get_elapse_time_in_ns(link->ctx,
818
+ finish_timestamp,
819
+ enter_timestamp);
820
+ DC_LOG_WARNING("Alt mode entered finished after %llu ms\n",
821
+ div_u64(time_taken_in_ns, 1000000));
822
+ return true;
823
+ }
824
+ }
825
+ finish_timestamp = dm_get_timestamp(link->ctx);
826
+ time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp,
827
+ enter_timestamp);
828
+ DC_LOG_WARNING("Alt mode has timed out after %llu ms\n",
829
+ div_u64(time_taken_in_ns, 1000000));
830
+ return false;
831
+}
832
+
833
+/**
834
+ * dc_link_detect() - Detect if a sink is attached to a given link
835
+ *
836
+ * link->local_sink is created or destroyed as needed.
837
+ *
838
+ * This does not create remote sinks but will trigger DM
839
+ * to start MST detection if a branch is detected.
840
+ */
841
+static bool dc_link_detect_helper(struct dc_link *link,
842
+ enum dc_detect_reason reason)
600843 {
601844 struct dc_sink_init_data sink_init_data = { 0 };
602845 struct display_sink_capability sink_caps = { 0 };
....@@ -611,28 +854,43 @@
611854 struct dpcd_caps prev_dpcd_caps;
612855 bool same_dpcd = true;
613856 enum dc_connection_type new_connection_type = dc_connection_none;
857
+ bool perform_dp_seamless_boot = false;
858
+ const uint32_t post_oui_delay = 30; // 30ms
859
+
614860 DC_LOGGER_INIT(link->ctx->logger);
615
- if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
861
+
862
+ if (dc_is_virtual_signal(link->connector_signal))
616863 return false;
617864
618
- if (false == dc_link_detect_sink(link, &new_connection_type)) {
865
+ if ((link->connector_signal == SIGNAL_TYPE_LVDS ||
866
+ link->connector_signal == SIGNAL_TYPE_EDP) &&
867
+ link->local_sink) {
868
+ // need to re-write OUI and brightness in resume case
869
+ if (link->connector_signal == SIGNAL_TYPE_EDP) {
870
+ dpcd_set_source_specific_data(link);
871
+ msleep(post_oui_delay);
872
+ dc_link_set_default_brightness_aux(link);
873
+ //TODO: use cached
874
+ }
875
+
876
+ return true;
877
+ }
878
+
879
+ if (!dc_link_detect_sink(link, &new_connection_type)) {
619880 BREAK_TO_DEBUGGER();
620881 return false;
621882 }
622883
623
- if (link->connector_signal == SIGNAL_TYPE_EDP &&
624
- link->local_sink)
625
- return true;
626
-
627884 prev_sink = link->local_sink;
628
- if (prev_sink != NULL) {
885
+ if (prev_sink) {
629886 dc_sink_retain(prev_sink);
630887 memcpy(&prev_dpcd_caps, &link->dpcd_caps, sizeof(struct dpcd_caps));
631888 }
632
- link_disconnect_sink(link);
633889
890
+ link_disconnect_sink(link);
634891 if (new_connection_type != dc_connection_none) {
635892 link->type = new_connection_type;
893
+ link->link_state_valid = false;
636894
637895 /* From Disconnected-to-Connected. */
638896 switch (link->connector_signal) {
....@@ -657,51 +915,77 @@
657915 break;
658916 }
659917
918
+ case SIGNAL_TYPE_LVDS: {
919
+ sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
920
+ sink_caps.signal = SIGNAL_TYPE_LVDS;
921
+ break;
922
+ }
923
+
660924 case SIGNAL_TYPE_EDP: {
925
+ read_current_link_settings_on_detect(link);
926
+
661927 detect_edp_sink_caps(link);
662
- sink_caps.transaction_type =
663
- DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
928
+ read_current_link_settings_on_detect(link);
929
+ sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
664930 sink_caps.signal = SIGNAL_TYPE_EDP;
665931 break;
666932 }
667933
668934 case SIGNAL_TYPE_DISPLAY_PORT: {
669
- if (!detect_dp(
670
- link,
671
- &sink_caps,
672
- &converter_disable_audio,
673
- aud_support, reason)) {
674
- if (prev_sink != NULL)
935
+ /* wa HPD high coming too early*/
936
+ if (link->link_enc->features.flags.bits.DP_IS_USB_C == 1) {
937
+ /* if alt mode times out, return false */
938
+ if (!wait_for_entering_dp_alt_mode(link))
939
+ return false;
940
+ }
941
+
942
+ if (!detect_dp(link, &sink_caps,
943
+ &converter_disable_audio,
944
+ aud_support, reason)) {
945
+ if (prev_sink)
675946 dc_sink_release(prev_sink);
676947 return false;
677948 }
678949
679950 // Check if dpcp block is the same
680
- if (prev_sink != NULL) {
681
- if (memcmp(&link->dpcd_caps, &prev_dpcd_caps, sizeof(struct dpcd_caps)))
951
+ if (prev_sink) {
952
+ if (memcmp(&link->dpcd_caps, &prev_dpcd_caps,
953
+ sizeof(struct dpcd_caps)))
682954 same_dpcd = false;
683955 }
684
- /* Active dongle downstream unplug */
685
- if (link->type == dc_connection_active_dongle
686
- && link->dpcd_caps.sink_count.
687
- bits.SINK_COUNT == 0) {
688
- if (prev_sink != NULL)
956
+ /* Active dongle downstream unplug*/
957
+ if (link->type == dc_connection_active_dongle &&
958
+ link->dpcd_caps.sink_count.bits.SINK_COUNT == 0) {
959
+ if (prev_sink)
960
+ /* Downstream unplug */
689961 dc_sink_release(prev_sink);
690962 return true;
691963 }
692964
693965 if (link->type == dc_connection_mst_branch) {
694966 LINK_INFO("link=%d, mst branch is now Connected\n",
695
- link->link_index);
967
+ link->link_index);
696968 /* Need to setup mst link_cap struct here
697969 * otherwise dc_link_detect() will leave mst link_cap
698970 * empty which leads to allocate_mst_payload() has "0"
699971 * pbn_per_slot value leading to exception on dc_fixpt_div()
700972 */
701
- link->verified_link_cap = link->reported_link_cap;
702
- if (prev_sink != NULL)
973
+ dp_verify_mst_link_cap(link);
974
+
975
+ if (prev_sink)
703976 dc_sink_release(prev_sink);
704977 return false;
978
+ }
979
+
980
+ // For seamless boot, to skip verify link cap, we read UEFI settings and set them as verified.
981
+ if (reason == DETECT_REASON_BOOT &&
982
+ !dc_ctx->dc->config.power_down_display_on_boot &&
983
+ link->link_status.link_active)
984
+ perform_dp_seamless_boot = true;
985
+
986
+ if (perform_dp_seamless_boot) {
987
+ read_current_link_settings_on_detect(link);
988
+ link->verified_link_cap = link->reported_link_cap;
705989 }
706990
707991 break;
....@@ -709,24 +993,23 @@
709993
710994 default:
711995 DC_ERROR("Invalid connector type! signal:%d\n",
712
- link->connector_signal);
713
- if (prev_sink != NULL)
996
+ link->connector_signal);
997
+ if (prev_sink)
714998 dc_sink_release(prev_sink);
715999 return false;
7161000 } /* switch() */
7171001
7181002 if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
719
- link->dpcd_sink_count = link->dpcd_caps.sink_count.
720
- bits.SINK_COUNT;
1003
+ link->dpcd_sink_count =
1004
+ link->dpcd_caps.sink_count.bits.SINK_COUNT;
7211005 else
7221006 link->dpcd_sink_count = 1;
7231007
724
- dal_ddc_service_set_transaction_type(
725
- link->ddc,
726
- sink_caps.transaction_type);
1008
+ dal_ddc_service_set_transaction_type(link->ddc,
1009
+ sink_caps.transaction_type);
7271010
728
- link->aux_mode = dal_ddc_service_is_in_aux_transaction_mode(
729
- link->ddc);
1011
+ link->aux_mode =
1012
+ dal_ddc_service_is_in_aux_transaction_mode(link->ddc);
7301013
7311014 sink_init_data.link = link;
7321015 sink_init_data.sink_signal = sink_caps.signal;
....@@ -734,20 +1017,19 @@
7341017 sink = dc_sink_create(&sink_init_data);
7351018 if (!sink) {
7361019 DC_ERROR("Failed to create sink!\n");
737
- if (prev_sink != NULL)
1020
+ if (prev_sink)
7381021 dc_sink_release(prev_sink);
7391022 return false;
7401023 }
7411024
742
- sink->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock;
1025
+ sink->link->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock;
7431026 sink->converter_disable_audio = converter_disable_audio;
7441027
1028
+ /* dc_sink_create returns a new reference */
7451029 link->local_sink = sink;
7461030
747
- edid_status = dm_helpers_read_local_edid(
748
- link->ctx,
749
- link,
750
- sink);
1031
+ edid_status = dm_helpers_read_local_edid(link->ctx,
1032
+ link, sink);
7511033
7521034 switch (edid_status) {
7531035 case EDID_BAD_CHECKSUM:
....@@ -755,7 +1037,6 @@
7551037 break;
7561038 case EDID_NO_RESPONSE:
7571039 DC_LOG_ERROR("No EDID read.\n");
758
-
7591040 /*
7601041 * Abort detection for non-DP connectors if we have
7611042 * no EDID
....@@ -766,7 +1047,7 @@
7661047 */
7671048 if (dc_is_hdmi_signal(link->connector_signal) ||
7681049 dc_is_dvi_signal(link->connector_signal)) {
769
- if (prev_sink != NULL)
1050
+ if (prev_sink)
7701051 dc_sink_release(prev_sink);
7711052 link_disconnect_sink(link);
7721053
....@@ -793,50 +1074,57 @@
7931074 break;
7941075 }
7951076
1077
+ if (link->local_sink->edid_caps.panel_patch.disable_fec)
1078
+ link->ctx->dc->debug.disable_fec = true;
1079
+
7961080 // Check if edid is the same
797
- if ((prev_sink != NULL) && ((edid_status == EDID_THE_SAME) || (edid_status == EDID_OK)))
798
- same_edid = is_same_edid(&prev_sink->dc_edid, &sink->dc_edid);
1081
+ if ((prev_sink) &&
1082
+ (edid_status == EDID_THE_SAME || edid_status == EDID_OK))
1083
+ same_edid = is_same_edid(&prev_sink->dc_edid,
1084
+ &sink->dc_edid);
1085
+
1086
+ if (sink->edid_caps.panel_patch.skip_scdc_overwrite)
1087
+ link->ctx->dc->debug.hdmi20_disable = true;
7991088
8001089 if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
801
- sink_caps.transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
1090
+ sink_caps.transaction_type ==
1091
+ DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
8021092 /*
8031093 * TODO debug why Dell 2413 doesn't like
8041094 * two link trainings
8051095 */
1096
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
1097
+ query_hdcp_capability(sink->sink_signal, link);
1098
+#endif
8061099
807
- /* deal with non-mst cases */
808
- for (i = 0; i < LINK_TRAINING_MAX_VERIFY_RETRY; i++) {
809
- int fail_count = 0;
810
-
811
- dp_verify_link_cap(link,
812
- &link->reported_link_cap,
813
- &fail_count);
814
-
815
- if (fail_count == 0)
816
- break;
817
- }
818
-
1100
+ // verify link cap for SST non-seamless boot
1101
+ if (!perform_dp_seamless_boot)
1102
+ dp_verify_link_cap_with_retries(link,
1103
+ &link->reported_link_cap,
1104
+ LINK_TRAINING_MAX_VERIFY_RETRY);
8191105 } else {
8201106 // If edid is the same, then discard new sink and revert back to original sink
8211107 if (same_edid) {
8221108 link_disconnect_remap(prev_sink, link);
8231109 sink = prev_sink;
8241110 prev_sink = NULL;
825
-
8261111 }
1112
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
1113
+ query_hdcp_capability(sink->sink_signal, link);
1114
+#endif
8271115 }
8281116
8291117 /* HDMI-DVI Dongle */
8301118 if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
831
- !sink->edid_caps.edid_hdmi)
1119
+ !sink->edid_caps.edid_hdmi)
8321120 sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
8331121
8341122 /* Connectivity log: detection */
835
- for (i = 0; i < sink->dc_edid.length / EDID_BLOCK_SIZE; i++) {
1123
+ for (i = 0; i < sink->dc_edid.length / DC_EDID_BLOCK_SIZE; i++) {
8361124 CONN_DATA_DETECT(link,
837
- &sink->dc_edid.raw_edid[i * EDID_BLOCK_SIZE],
838
- EDID_BLOCK_SIZE,
839
- "%s: [Block %d] ", sink->edid_caps.display_name, i);
1125
+ &sink->dc_edid.raw_edid[i * DC_EDID_BLOCK_SIZE],
1126
+ DC_EDID_BLOCK_SIZE,
1127
+ "%s: [Block %d] ", sink->edid_caps.display_name, i);
8401128 }
8411129
8421130 DC_LOG_DETECTION_EDID_PARSER("%s: "
....@@ -871,42 +1159,76 @@
8711159 sink->edid_caps.audio_modes[i].sample_rate,
8721160 sink->edid_caps.audio_modes[i].sample_size);
8731161 }
874
-
8751162 } else {
8761163 /* From Connected-to-Disconnected. */
8771164 if (link->type == dc_connection_mst_branch) {
8781165 LINK_INFO("link=%d, mst branch is now Disconnected\n",
879
- link->link_index);
1166
+ link->link_index);
8801167
8811168 dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
8821169
8831170 link->mst_stream_alloc_table.stream_count = 0;
884
- memset(link->mst_stream_alloc_table.stream_allocations, 0, sizeof(link->mst_stream_alloc_table.stream_allocations));
1171
+ memset(link->mst_stream_alloc_table.stream_allocations,
1172
+ 0,
1173
+ sizeof(link->mst_stream_alloc_table.stream_allocations));
8851174 }
8861175
8871176 link->type = dc_connection_none;
8881177 sink_caps.signal = SIGNAL_TYPE_NONE;
1178
+ /* When we unplug a passive DP-HDMI dongle connection, dongle_max_pix_clk
1179
+ * is not cleared. If we emulate a DP signal on this connection, it thinks
1180
+ * the dongle is still there and limits the number of modes we can emulate.
1181
+ * Clear dongle_max_pix_clk on disconnect to fix this
1182
+ */
1183
+ link->dongle_max_pix_clk = 0;
8891184 }
8901185
8911186 LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p dpcd same=%d edid same=%d\n",
892
- link->link_index, sink,
893
- (sink_caps.signal == SIGNAL_TYPE_NONE ?
894
- "Disconnected":"Connected"), prev_sink,
895
- same_dpcd, same_edid);
1187
+ link->link_index, sink,
1188
+ (sink_caps.signal ==
1189
+ SIGNAL_TYPE_NONE ? "Disconnected" : "Connected"),
1190
+ prev_sink, same_dpcd, same_edid);
8961191
897
- if (prev_sink != NULL)
1192
+ if (prev_sink)
8981193 dc_sink_release(prev_sink);
8991194
9001195 return true;
9011196 }
9021197
903
-static enum hpd_source_id get_hpd_line(
904
- struct dc_link *link)
1198
+bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
1199
+{
1200
+ const struct dc *dc = link->dc;
1201
+ bool ret;
1202
+
1203
+ /* get out of low power state */
1204
+ clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
1205
+
1206
+ ret = dc_link_detect_helper(link, reason);
1207
+
1208
+ /* Go back to power optimized state */
1209
+ clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
1210
+
1211
+ return ret;
1212
+}
1213
+
1214
+bool dc_link_get_hpd_state(struct dc_link *dc_link)
1215
+{
1216
+ uint32_t state;
1217
+
1218
+ dal_gpio_lock_pin(dc_link->hpd_gpio);
1219
+ dal_gpio_get_value(dc_link->hpd_gpio, &state);
1220
+ dal_gpio_unlock_pin(dc_link->hpd_gpio);
1221
+
1222
+ return state;
1223
+}
1224
+
1225
+static enum hpd_source_id get_hpd_line(struct dc_link *link)
9051226 {
9061227 struct gpio *hpd;
9071228 enum hpd_source_id hpd_id = HPD_SOURCEID_UNKNOWN;
9081229
909
- hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
1230
+ hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id,
1231
+ link->ctx->gpio_service);
9101232
9111233 if (hpd) {
9121234 switch (dal_irq_get_source(hpd)) {
....@@ -981,8 +1303,7 @@
9811303 return channel;
9821304 }
9831305
984
-static enum transmitter translate_encoder_to_transmitter(
985
- struct graphics_object_id encoder)
1306
+static enum transmitter translate_encoder_to_transmitter(struct graphics_object_id encoder)
9861307 {
9871308 switch (encoder.id) {
9881309 case ENCODER_ID_INTERNAL_UNIPHY:
....@@ -1046,18 +1367,18 @@
10461367 }
10471368 }
10481369
1049
-static bool construct(
1050
- struct dc_link *link,
1051
- const struct link_init_data *init_params)
1370
+static bool dc_link_construct(struct dc_link *link,
1371
+ const struct link_init_data *init_params)
10521372 {
10531373 uint8_t i;
1054
- struct gpio *hpd_gpio = NULL;
10551374 struct ddc_service_init_data ddc_service_init_data = { { 0 } };
10561375 struct dc_context *dc_ctx = init_params->ctx;
10571376 struct encoder_init_data enc_init_data = { 0 };
1377
+ struct panel_cntl_init_data panel_cntl_init_data = { 0 };
10581378 struct integrated_info info = {{{ 0 }}};
10591379 struct dc_bios *bios = init_params->dc->ctx->dc_bios;
10601380 const struct dc_vbios_funcs *bp_funcs = bios->funcs;
1381
+
10611382 DC_LOGGER_INIT(dc_ctx->logger);
10621383
10631384 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
....@@ -1069,22 +1390,31 @@
10691390 link->ctx = dc_ctx;
10701391 link->link_index = init_params->link_index;
10711392
1072
- link->link_id = bios->funcs->get_connector_id(bios, init_params->connector_index);
1393
+ memset(&link->preferred_training_settings, 0,
1394
+ sizeof(struct dc_link_training_overrides));
1395
+ memset(&link->preferred_link_setting, 0,
1396
+ sizeof(struct dc_link_settings));
1397
+
1398
+ link->link_id =
1399
+ bios->funcs->get_connector_id(bios, init_params->connector_index);
10731400
10741401 if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
1075
- dm_error("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
1076
- __func__, init_params->connector_index,
1077
- link->link_id.type, OBJECT_TYPE_CONNECTOR);
1402
+ dm_output_to_console("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
1403
+ __func__, init_params->connector_index,
1404
+ link->link_id.type, OBJECT_TYPE_CONNECTOR);
10781405 goto create_fail;
10791406 }
10801407
10811408 if (link->dc->res_pool->funcs->link_init)
10821409 link->dc->res_pool->funcs->link_init(link);
10831410
1084
- hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
1085
-
1086
- if (hpd_gpio != NULL)
1087
- link->irq_source_hpd = dal_irq_get_source(hpd_gpio);
1411
+ link->hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id,
1412
+ link->ctx->gpio_service);
1413
+ if (link->hpd_gpio) {
1414
+ dal_gpio_open(link->hpd_gpio, GPIO_MODE_INTERRUPT);
1415
+ dal_gpio_unlock_pin(link->hpd_gpio);
1416
+ link->irq_source_hpd = dal_irq_get_source(link->hpd_gpio);
1417
+ }
10881418
10891419 switch (link->link_id.id) {
10901420 case CONNECTOR_ID_HDMI_TYPE_A:
....@@ -1100,44 +1430,44 @@
11001430 link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
11011431 break;
11021432 case CONNECTOR_ID_DISPLAY_PORT:
1103
- link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
1433
+ link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
11041434
1105
- if (hpd_gpio != NULL)
1435
+ if (link->hpd_gpio)
11061436 link->irq_source_hpd_rx =
1107
- dal_irq_get_rx_source(hpd_gpio);
1437
+ dal_irq_get_rx_source(link->hpd_gpio);
11081438
11091439 break;
11101440 case CONNECTOR_ID_EDP:
11111441 link->connector_signal = SIGNAL_TYPE_EDP;
11121442
1113
- if (hpd_gpio != NULL) {
1443
+ if (link->hpd_gpio) {
11141444 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
11151445 link->irq_source_hpd_rx =
1116
- dal_irq_get_rx_source(hpd_gpio);
1446
+ dal_irq_get_rx_source(link->hpd_gpio);
11171447 }
1448
+
1449
+ break;
1450
+ case CONNECTOR_ID_LVDS:
1451
+ link->connector_signal = SIGNAL_TYPE_LVDS;
11181452 break;
11191453 default:
1120
- DC_LOG_WARNING("Unsupported Connector type:%d!\n", link->link_id.id);
1454
+ DC_LOG_WARNING("Unsupported Connector type:%d!\n",
1455
+ link->link_id.id);
11211456 goto create_fail;
1122
- }
1123
-
1124
- if (hpd_gpio != NULL) {
1125
- dal_gpio_destroy_irq(&hpd_gpio);
1126
- hpd_gpio = NULL;
11271457 }
11281458
11291459 /* TODO: #DAL3 Implement id to str function.*/
11301460 LINK_INFO("Connector[%d] description:"
1131
- "signal %d\n",
1132
- init_params->connector_index,
1133
- link->connector_signal);
1461
+ "signal %d\n",
1462
+ init_params->connector_index,
1463
+ link->connector_signal);
11341464
11351465 ddc_service_init_data.ctx = link->ctx;
11361466 ddc_service_init_data.id = link->link_id;
11371467 ddc_service_init_data.link = link;
11381468 link->ddc = dal_ddc_service_create(&ddc_service_init_data);
11391469
1140
- if (link->ddc == NULL) {
1470
+ if (!link->ddc) {
11411471 DC_ERROR("Failed to create ddc_service!\n");
11421472 goto ddc_create_fail;
11431473 }
....@@ -1148,11 +1478,27 @@
11481478 }
11491479
11501480 link->ddc_hw_inst =
1151
- dal_ddc_get_line(
1152
- dal_ddc_service_get_ddc_pin(link->ddc));
1481
+ dal_ddc_get_line(dal_ddc_service_get_ddc_pin(link->ddc));
1482
+
1483
+
1484
+ if (link->dc->res_pool->funcs->panel_cntl_create &&
1485
+ (link->link_id.id == CONNECTOR_ID_EDP ||
1486
+ link->link_id.id == CONNECTOR_ID_LVDS)) {
1487
+ panel_cntl_init_data.ctx = dc_ctx;
1488
+ panel_cntl_init_data.inst = 0;
1489
+ link->panel_cntl =
1490
+ link->dc->res_pool->funcs->panel_cntl_create(
1491
+ &panel_cntl_init_data);
1492
+
1493
+ if (link->panel_cntl == NULL) {
1494
+ DC_ERROR("Failed to create link panel_cntl!\n");
1495
+ goto panel_cntl_create_fail;
1496
+ }
1497
+ }
11531498
11541499 enc_init_data.ctx = dc_ctx;
1155
- bp_funcs->get_src_obj(dc_ctx->dc_bios, link->link_id, 0, &enc_init_data.encoder);
1500
+ bp_funcs->get_src_obj(dc_ctx->dc_bios, link->link_id, 0,
1501
+ &enc_init_data.encoder);
11561502 enc_init_data.connector = link->link_id;
11571503 enc_init_data.channel = get_ddc_line(link);
11581504 enc_init_data.hpd_source = get_hpd_line(link);
....@@ -1160,11 +1506,11 @@
11601506 link->hpd_src = enc_init_data.hpd_source;
11611507
11621508 enc_init_data.transmitter =
1163
- translate_encoder_to_transmitter(enc_init_data.encoder);
1164
- link->link_enc = link->dc->res_pool->funcs->link_enc_create(
1165
- &enc_init_data);
1509
+ translate_encoder_to_transmitter(enc_init_data.encoder);
1510
+ link->link_enc =
1511
+ link->dc->res_pool->funcs->link_enc_create(&enc_init_data);
11661512
1167
- if( link->link_enc == NULL) {
1513
+ if (!link->link_enc) {
11681514 DC_ERROR("Failed to create link encoder!\n");
11691515 goto link_enc_create_fail;
11701516 }
....@@ -1172,8 +1518,9 @@
11721518 link->link_enc_hw_inst = link->link_enc->transmitter;
11731519
11741520 for (i = 0; i < 4; i++) {
1175
- if (BP_RESULT_OK !=
1176
- bp_funcs->get_device_tag(dc_ctx->dc_bios, link->link_id, i, &link->device_tag)) {
1521
+ if (bp_funcs->get_device_tag(dc_ctx->dc_bios,
1522
+ link->link_id, i,
1523
+ &link->device_tag) != BP_RESULT_OK) {
11771524 DC_ERROR("Failed to find device tag!\n");
11781525 goto device_tag_fail;
11791526 }
....@@ -1181,13 +1528,14 @@
11811528 /* Look for device tag that matches connector signal,
11821529 * CRT for rgb, LCD for other supported signal tyes
11831530 */
1184
- if (!bp_funcs->is_device_id_supported(dc_ctx->dc_bios, link->device_tag.dev_id))
1531
+ if (!bp_funcs->is_device_id_supported(dc_ctx->dc_bios,
1532
+ link->device_tag.dev_id))
11851533 continue;
1186
- if (link->device_tag.dev_id.device_type == DEVICE_TYPE_CRT
1187
- && link->connector_signal != SIGNAL_TYPE_RGB)
1534
+ if (link->device_tag.dev_id.device_type == DEVICE_TYPE_CRT &&
1535
+ link->connector_signal != SIGNAL_TYPE_RGB)
11881536 continue;
1189
- if (link->device_tag.dev_id.device_type == DEVICE_TYPE_LCD
1190
- && link->connector_signal == SIGNAL_TYPE_RGB)
1537
+ if (link->device_tag.dev_id.device_type == DEVICE_TYPE_LCD &&
1538
+ link->connector_signal == SIGNAL_TYPE_RGB)
11911539 continue;
11921540 break;
11931541 }
....@@ -1199,22 +1547,25 @@
11991547 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; i++) {
12001548 struct external_display_path *path =
12011549 &info.ext_disp_conn_info.path[i];
1202
- if (path->device_connector_id.enum_id == link->link_id.enum_id
1203
- && path->device_connector_id.id == link->link_id.id
1204
- && path->device_connector_id.type == link->link_id.type) {
12051550
1206
- if (link->device_tag.acpi_device != 0
1207
- && path->device_acpi_enum == link->device_tag.acpi_device) {
1551
+ if (path->device_connector_id.enum_id == link->link_id.enum_id &&
1552
+ path->device_connector_id.id == link->link_id.id &&
1553
+ path->device_connector_id.type == link->link_id.type) {
1554
+ if (link->device_tag.acpi_device != 0 &&
1555
+ path->device_acpi_enum == link->device_tag.acpi_device) {
12081556 link->ddi_channel_mapping = path->channel_mapping;
12091557 link->chip_caps = path->caps;
12101558 } else if (path->device_tag ==
1211
- link->device_tag.dev_id.raw_device_tag) {
1559
+ link->device_tag.dev_id.raw_device_tag) {
12121560 link->ddi_channel_mapping = path->channel_mapping;
12131561 link->chip_caps = path->caps;
12141562 }
12151563 break;
12161564 }
12171565 }
1566
+
1567
+ if (bios->funcs->get_atom_dc_golden_table)
1568
+ bios->funcs->get_atom_dc_golden_table(bios);
12181569
12191570 /*
12201571 * TODO check if GPIO programmed correctly
....@@ -1224,16 +1575,22 @@
12241575 */
12251576 program_hpd_filter(link);
12261577
1578
+ link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
1579
+
12271580 return true;
12281581 device_tag_fail:
12291582 link->link_enc->funcs->destroy(&link->link_enc);
12301583 link_enc_create_fail:
1584
+ if (link->panel_cntl != NULL)
1585
+ link->panel_cntl->funcs->destroy(&link->panel_cntl);
1586
+panel_cntl_create_fail:
12311587 dal_ddc_service_destroy(&link->ddc);
12321588 ddc_create_fail:
12331589 create_fail:
12341590
1235
- if (hpd_gpio != NULL) {
1236
- dal_gpio_destroy_irq(&hpd_gpio);
1591
+ if (link->hpd_gpio) {
1592
+ dal_gpio_destroy_irq(&link->hpd_gpio);
1593
+ link->hpd_gpio = NULL;
12371594 }
12381595
12391596 return false;
....@@ -1250,7 +1607,7 @@
12501607 if (NULL == link)
12511608 goto alloc_fail;
12521609
1253
- if (false == construct(link, init_params))
1610
+ if (false == dc_link_construct(link, init_params))
12541611 goto construct_fail;
12551612
12561613 return link;
....@@ -1264,66 +1621,15 @@
12641621
12651622 void link_destroy(struct dc_link **link)
12661623 {
1267
- destruct(*link);
1624
+ dc_link_destruct(*link);
12681625 kfree(*link);
12691626 *link = NULL;
1270
-}
1271
-
1272
-static void dpcd_configure_panel_mode(
1273
- struct dc_link *link,
1274
- enum dp_panel_mode panel_mode)
1275
-{
1276
- union dpcd_edp_config edp_config_set;
1277
- bool panel_mode_edp = false;
1278
- DC_LOGGER_INIT(link->ctx->logger);
1279
-
1280
- memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config));
1281
-
1282
- if (DP_PANEL_MODE_DEFAULT != panel_mode) {
1283
-
1284
- switch (panel_mode) {
1285
- case DP_PANEL_MODE_EDP:
1286
- case DP_PANEL_MODE_SPECIAL:
1287
- panel_mode_edp = true;
1288
- break;
1289
-
1290
- default:
1291
- break;
1292
- }
1293
-
1294
- /*set edp panel mode in receiver*/
1295
- core_link_read_dpcd(
1296
- link,
1297
- DP_EDP_CONFIGURATION_SET,
1298
- &edp_config_set.raw,
1299
- sizeof(edp_config_set.raw));
1300
-
1301
- if (edp_config_set.bits.PANEL_MODE_EDP
1302
- != panel_mode_edp) {
1303
- enum ddc_result result = DDC_RESULT_UNKNOWN;
1304
-
1305
- edp_config_set.bits.PANEL_MODE_EDP =
1306
- panel_mode_edp;
1307
- result = core_link_write_dpcd(
1308
- link,
1309
- DP_EDP_CONFIGURATION_SET,
1310
- &edp_config_set.raw,
1311
- sizeof(edp_config_set.raw));
1312
-
1313
- ASSERT(result == DDC_RESULT_SUCESSFULL);
1314
- }
1315
- }
1316
- DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d "
1317
- "eDP panel mode enabled: %d \n",
1318
- link->link_index,
1319
- link->dpcd_caps.panel_mode_edp,
1320
- panel_mode_edp);
13211627 }
13221628
13231629 static void enable_stream_features(struct pipe_ctx *pipe_ctx)
13241630 {
13251631 struct dc_stream_state *stream = pipe_ctx->stream;
1326
- struct dc_link *link = stream->sink->link;
1632
+ struct dc_link *link = stream->link;
13271633 union down_spread_ctrl old_downspread;
13281634 union down_spread_ctrl new_downspread;
13291635
....@@ -1341,71 +1647,80 @@
13411647 }
13421648 }
13431649
1344
-static enum dc_status enable_link_dp(
1345
- struct dc_state *state,
1346
- struct pipe_ctx *pipe_ctx)
1650
+static enum dc_status enable_link_dp(struct dc_state *state,
1651
+ struct pipe_ctx *pipe_ctx)
13471652 {
13481653 struct dc_stream_state *stream = pipe_ctx->stream;
13491654 enum dc_status status;
13501655 bool skip_video_pattern;
1351
- struct dc_link *link = stream->sink->link;
1656
+ struct dc_link *link = stream->link;
13521657 struct dc_link_settings link_settings = {0};
1353
- enum dp_panel_mode panel_mode;
1354
- enum dc_link_rate max_link_rate = LINK_RATE_HIGH2;
1658
+ bool fec_enable;
1659
+ int i;
1660
+ bool apply_seamless_boot_optimization = false;
1661
+ uint32_t bl_oled_enable_delay = 50; // in ms
1662
+ const uint32_t post_oui_delay = 30; // 30ms
1663
+
1664
+ // check for seamless boot
1665
+ for (i = 0; i < state->stream_count; i++) {
1666
+ if (state->streams[i]->apply_seamless_boot_optimization) {
1667
+ apply_seamless_boot_optimization = true;
1668
+ break;
1669
+ }
1670
+ }
13551671
13561672 /* get link settings for video mode timing */
13571673 decide_link_settings(stream, &link_settings);
13581674
1359
- /* raise clock state for HBR3 if required. Confirmed with HW DCE/DPCS
1360
- * logic for HBR3 still needs Nominal (0.8V) on VDDC rail
1361
- */
1362
- if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE)
1363
- max_link_rate = LINK_RATE_HIGH3;
1364
-
1365
- if (link_settings.link_rate == max_link_rate) {
1366
- struct dc_clocks clocks = state->bw.dcn.clk;
1367
-
1368
- /* dce/dcn compat, do not update dispclk */
1369
- clocks.dispclk_khz = 0;
1370
- /* 27mhz = 27000000hz= 27000khz */
1371
- clocks.phyclk_khz = link_settings.link_rate * 27000;
1372
-
1373
- state->dis_clk->funcs->update_clocks(
1374
- state->dis_clk, &clocks, false);
1675
+ if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
1676
+ /*in case it is not on*/
1677
+ link->dc->hwss.edp_power_control(link, true);
1678
+ link->dc->hwss.edp_wait_for_hpd_ready(link, true);
13751679 }
13761680
1377
- dp_enable_link_phy(
1378
- link,
1379
- pipe_ctx->stream->signal,
1380
- pipe_ctx->clock_source->id,
1381
- &link_settings);
1681
+ pipe_ctx->stream_res.pix_clk_params.requested_sym_clk =
1682
+ link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
1683
+ if (state->clk_mgr && !apply_seamless_boot_optimization)
1684
+ state->clk_mgr->funcs->update_clocks(state->clk_mgr,
1685
+ state, false);
13821686
1383
- if (stream->sink->edid_caps.panel_patch.dppowerup_delay > 0) {
1384
- int delay_dp_power_up_in_ms = stream->sink->edid_caps.panel_patch.dppowerup_delay;
1385
-
1386
- msleep(delay_dp_power_up_in_ms);
1387
- }
1388
-
1389
- panel_mode = dp_get_panel_mode(link);
1390
- dpcd_configure_panel_mode(link, panel_mode);
1687
+ // during mode switch we do DP_SET_POWER off then on, and OUI is lost
1688
+ dpcd_set_source_specific_data(link);
1689
+ if (link->dpcd_sink_ext_caps.raw != 0)
1690
+ msleep(post_oui_delay);
13911691
13921692 skip_video_pattern = true;
13931693
13941694 if (link_settings.link_rate == LINK_RATE_LOW)
1395
- skip_video_pattern = false;
1695
+ skip_video_pattern = false;
13961696
1397
- if (perform_link_training_with_retries(
1398
- link,
1399
- &link_settings,
1400
- skip_video_pattern,
1401
- LINK_TRAINING_ATTEMPTS)) {
1697
+ if (perform_link_training_with_retries(&link_settings,
1698
+ skip_video_pattern,
1699
+ LINK_TRAINING_ATTEMPTS,
1700
+ pipe_ctx,
1701
+ pipe_ctx->stream->signal)) {
14021702 link->cur_link_settings = link_settings;
14031703 status = DC_OK;
1404
- }
1405
- else
1704
+ } else {
14061705 status = DC_FAIL_DP_LINK_TRAINING;
1706
+ }
14071707
1408
- enable_stream_features(pipe_ctx);
1708
+ if (link->preferred_training_settings.fec_enable)
1709
+ fec_enable = *link->preferred_training_settings.fec_enable;
1710
+ else
1711
+ fec_enable = true;
1712
+
1713
+ dp_set_fec_enable(link, fec_enable);
1714
+
1715
+ // during mode set we do DP_SET_POWER off then on, aux writes are lost
1716
+ if (link->dpcd_sink_ext_caps.bits.oled == 1 ||
1717
+ link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1 ||
1718
+ link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1) {
1719
+ dc_link_set_default_brightness_aux(link); // TODO: use cached if known
1720
+ if (link->dpcd_sink_ext_caps.bits.oled == 1)
1721
+ msleep(bl_oled_enable_delay);
1722
+ dc_link_backlight_enable_aux(link, true);
1723
+ }
14091724
14101725 return status;
14111726 }
....@@ -1415,14 +1730,8 @@
14151730 struct pipe_ctx *pipe_ctx)
14161731 {
14171732 enum dc_status status;
1418
- struct dc_stream_state *stream = pipe_ctx->stream;
1419
- struct dc_link *link = stream->sink->link;
1420
- /*in case it is not on*/
1421
- link->dc->hwss.edp_power_control(link, true);
1422
- link->dc->hwss.edp_wait_for_hpd_ready(link, true);
14231733
14241734 status = enable_link_dp(state, pipe_ctx);
1425
-
14261735
14271736 return status;
14281737 }
....@@ -1431,7 +1740,7 @@
14311740 struct dc_state *state,
14321741 struct pipe_ctx *pipe_ctx)
14331742 {
1434
- struct dc_link *link = pipe_ctx->stream->sink->link;
1743
+ struct dc_link *link = pipe_ctx->stream->link;
14351744
14361745 /* sink signal type after MST branch is MST. Multiple MST sinks
14371746 * share one link. Link DP PHY is enable or training only once.
....@@ -1441,6 +1750,11 @@
14411750
14421751 /* clear payload table */
14431752 dm_helpers_dp_mst_clear_payload_allocation_table(link->ctx, link);
1753
+
1754
+ /* to make sure the pending down rep can be processed
1755
+ * before enabling the link
1756
+ */
1757
+ dm_helpers_dp_mst_poll_pending_down_reply(link->ctx, link);
14441758
14451759 /* set the sink to MST mode before enabling the link */
14461760 dp_enable_mst_on_sink(link, true);
....@@ -1564,8 +1878,8 @@
15641878 payload.write = true;
15651879 cmd.payloads = &payload;
15661880
1567
- if (dc_submit_i2c(pipe_ctx->stream->ctx->dc,
1568
- pipe_ctx->stream->sink->link->link_index, &cmd))
1881
+ if (dm_helpers_submit_i2c(pipe_ctx->stream->ctx,
1882
+ pipe_ctx->stream->link, &cmd))
15691883 return true;
15701884
15711885 return false;
....@@ -1584,6 +1898,7 @@
15841898 uint8_t value = 0;
15851899 int i = 0;
15861900 bool i2c_success = false;
1901
+ DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
15871902
15881903 memset(&buffer, 0, sizeof(buffer));
15891904
....@@ -1597,6 +1912,9 @@
15971912 buffer[1] = settings->reg_settings[i].i2c_reg_val;
15981913 i2c_success = i2c_write(pipe_ctx, slave_address,
15991914 buffer, sizeof(buffer));
1915
+ RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
1916
+ offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n",
1917
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
16001918
16011919 if (!i2c_success)
16021920 goto i2c_write_fail;
....@@ -1614,7 +1932,7 @@
16141932 else {
16151933 i2c_success =
16161934 dal_ddc_service_query_ddc_data(
1617
- pipe_ctx->stream->sink->link->ddc,
1935
+ pipe_ctx->stream->link->ddc,
16181936 slave_address, &offset, 1, &value, 1);
16191937 if (!i2c_success)
16201938 goto i2c_write_fail;
....@@ -1625,6 +1943,9 @@
16251943 buffer[1] = value | apply_rx_tx_change;
16261944 i2c_success = i2c_write(pipe_ctx, slave_address,
16271945 buffer, sizeof(buffer));
1946
+ RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
1947
+ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1948
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
16281949 if (!i2c_success)
16291950 goto i2c_write_fail;
16301951 }
....@@ -1641,6 +1962,9 @@
16411962 buffer[1] = settings->reg_settings_6g[i].i2c_reg_val;
16421963 i2c_success = i2c_write(pipe_ctx, slave_address,
16431964 buffer, sizeof(buffer));
1965
+ RETIMER_REDRIVER_INFO("above 340Mhz: retimer write to slave_address = 0x%x,\
1966
+ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1967
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
16441968
16451969 if (!i2c_success)
16461970 goto i2c_write_fail;
....@@ -1658,7 +1982,7 @@
16581982 else {
16591983 i2c_success =
16601984 dal_ddc_service_query_ddc_data(
1661
- pipe_ctx->stream->sink->link->ddc,
1985
+ pipe_ctx->stream->link->ddc,
16621986 slave_address, &offset, 1, &value, 1);
16631987 if (!i2c_success)
16641988 goto i2c_write_fail;
....@@ -1669,6 +1993,9 @@
16691993 buffer[1] = value | apply_rx_tx_change;
16701994 i2c_success = i2c_write(pipe_ctx, slave_address,
16711995 buffer, sizeof(buffer));
1996
+ RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
1997
+ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1998
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
16721999 if (!i2c_success)
16732000 goto i2c_write_fail;
16742001 }
....@@ -1684,6 +2011,9 @@
16842011 buffer[1] = 0x01;
16852012 i2c_success = i2c_write(pipe_ctx, slave_address,
16862013 buffer, sizeof(buffer));
2014
+ RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
2015
+ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2016
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
16872017 if (!i2c_success)
16882018 goto i2c_write_fail;
16892019
....@@ -1692,6 +2022,9 @@
16922022 buffer[1] = 0x23;
16932023 i2c_success = i2c_write(pipe_ctx, slave_address,
16942024 buffer, sizeof(buffer));
2025
+ RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
2026
+ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2027
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
16952028 if (!i2c_success)
16962029 goto i2c_write_fail;
16972030
....@@ -1700,6 +2033,9 @@
17002033 buffer[1] = 0x00;
17012034 i2c_success = i2c_write(pipe_ctx, slave_address,
17022035 buffer, sizeof(buffer));
2036
+ RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
2037
+ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2038
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
17032039 if (!i2c_success)
17042040 goto i2c_write_fail;
17052041
....@@ -1719,6 +2055,7 @@
17192055 uint8_t slave_address = (0xBA >> 1);
17202056 uint8_t buffer[2];
17212057 bool i2c_success = false;
2058
+ DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
17222059
17232060 memset(&buffer, 0, sizeof(buffer));
17242061
....@@ -1728,6 +2065,9 @@
17282065 buffer[1] = 0x13;
17292066 i2c_success = i2c_write(pipe_ctx, slave_address,
17302067 buffer, sizeof(buffer));
2068
+ RETIMER_REDRIVER_INFO("retimer writes default setting to slave_address = 0x%x,\
2069
+ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2070
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
17312071 if (!i2c_success)
17322072 goto i2c_write_fail;
17332073
....@@ -1736,6 +2076,9 @@
17362076 buffer[1] = 0x17;
17372077 i2c_success = i2c_write(pipe_ctx, slave_address,
17382078 buffer, sizeof(buffer));
2079
+ RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2080
+ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2081
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
17392082 if (!i2c_success)
17402083 goto i2c_write_fail;
17412084
....@@ -1744,6 +2087,9 @@
17442087 buffer[1] = is_over_340mhz ? 0xDA : 0xD8;
17452088 i2c_success = i2c_write(pipe_ctx, slave_address,
17462089 buffer, sizeof(buffer));
2090
+ RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2091
+ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2092
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
17472093 if (!i2c_success)
17482094 goto i2c_write_fail;
17492095
....@@ -1752,6 +2098,9 @@
17522098 buffer[1] = 0x17;
17532099 i2c_success = i2c_write(pipe_ctx, slave_address,
17542100 buffer, sizeof(buffer));
2101
+ RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2102
+ offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n",
2103
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
17552104 if (!i2c_success)
17562105 goto i2c_write_fail;
17572106
....@@ -1760,6 +2109,9 @@
17602109 buffer[1] = is_over_340mhz ? 0x1D : 0x91;
17612110 i2c_success = i2c_write(pipe_ctx, slave_address,
17622111 buffer, sizeof(buffer));
2112
+ RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2113
+ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2114
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
17632115 if (!i2c_success)
17642116 goto i2c_write_fail;
17652117
....@@ -1768,6 +2120,9 @@
17682120 buffer[1] = 0x17;
17692121 i2c_success = i2c_write(pipe_ctx, slave_address,
17702122 buffer, sizeof(buffer));
2123
+ RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2124
+ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2125
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
17712126 if (!i2c_success)
17722127 goto i2c_write_fail;
17732128
....@@ -1780,6 +2135,9 @@
17802135 buffer[1] = 0x01;
17812136 i2c_success = i2c_write(pipe_ctx, slave_address,
17822137 buffer, sizeof(buffer));
2138
+ RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2139
+ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2140
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
17832141 if (!i2c_success)
17842142 goto i2c_write_fail;
17852143
....@@ -1788,6 +2146,9 @@
17882146 buffer[1] = 0x23;
17892147 i2c_success = i2c_write(pipe_ctx, slave_address,
17902148 buffer, sizeof(buffer));
2149
+ RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2150
+ offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n",
2151
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
17912152 if (!i2c_success)
17922153 goto i2c_write_fail;
17932154
....@@ -1796,6 +2157,9 @@
17962157 buffer[1] = 0x00;
17972158 i2c_success = i2c_write(pipe_ctx, slave_address,
17982159 buffer, sizeof(buffer));
2160
+ RETIMER_REDRIVER_INFO("retimer write default setting to slave_addr = 0x%x,\
2161
+ offset = 0x%x, reg_val= 0x%x, i2c_success = %d end here\n",
2162
+ slave_address, buffer[0], buffer[1], i2c_success?1:0);
17992163 if (!i2c_success)
18002164 goto i2c_write_fail;
18012165 }
....@@ -1813,6 +2177,7 @@
18132177 uint8_t slave_address = (0xF0 >> 1);
18142178 uint8_t buffer[16];
18152179 bool i2c_success = false;
2180
+ DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
18162181
18172182 memset(&buffer, 0, sizeof(buffer));
18182183
....@@ -1824,15 +2189,59 @@
18242189
18252190 i2c_success = i2c_write(pipe_ctx, slave_address,
18262191 buffer, sizeof(buffer));
2192
+ RETIMER_REDRIVER_INFO("redriver write 0 to all 16 reg offset expect following:\n\
2193
+ \t slave_addr = 0x%x, offset[3] = 0x%x, offset[4] = 0x%x,\
2194
+ offset[5] = 0x%x,offset[6] is_over_340mhz = 0x%x,\
2195
+ i2c_success = %d\n",
2196
+ slave_address, buffer[3], buffer[4], buffer[5], buffer[6], i2c_success?1:0);
18272197
18282198 if (!i2c_success)
18292199 DC_LOG_DEBUG("Set redriver failed");
18302200 }
18312201
2202
+static void disable_link(struct dc_link *link, enum signal_type signal)
2203
+{
2204
+ /*
2205
+ * TODO: implement call for dp_set_hw_test_pattern
2206
+ * it is needed for compliance testing
2207
+ */
2208
+
2209
+ /* Here we need to specify that encoder output settings
2210
+ * need to be calculated as for the set mode,
2211
+ * it will lead to querying dynamic link capabilities
2212
+ * which should be done before enable output
2213
+ */
2214
+
2215
+ if (dc_is_dp_signal(signal)) {
2216
+ /* SST DP, eDP */
2217
+ if (dc_is_dp_sst_signal(signal))
2218
+ dp_disable_link_phy(link, signal);
2219
+ else
2220
+ dp_disable_link_phy_mst(link, signal);
2221
+
2222
+ if (dc_is_dp_sst_signal(signal) ||
2223
+ link->mst_stream_alloc_table.stream_count == 0) {
2224
+ dp_set_fec_enable(link, false);
2225
+ dp_set_fec_ready(link, false);
2226
+ }
2227
+ } else {
2228
+ if (signal != SIGNAL_TYPE_VIRTUAL)
2229
+ link->link_enc->funcs->disable_output(link->link_enc, signal);
2230
+ }
2231
+
2232
+ if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
2233
+ /* MST disable link only when no stream use the link */
2234
+ if (link->mst_stream_alloc_table.stream_count <= 0)
2235
+ link->link_status.link_active = false;
2236
+ } else {
2237
+ link->link_status.link_active = false;
2238
+ }
2239
+}
2240
+
18322241 static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
18332242 {
18342243 struct dc_stream_state *stream = pipe_ctx->stream;
1835
- struct dc_link *link = stream->sink->link;
2244
+ struct dc_link *link = stream->link;
18362245 enum dc_color_depth display_color_depth;
18372246 enum engine_id eng_id;
18382247 struct ext_hdmi_settings settings = {0};
....@@ -1841,12 +2250,12 @@
18412250 && (stream->timing.v_addressable == 480);
18422251
18432252 if (stream->phy_pix_clk == 0)
1844
- stream->phy_pix_clk = stream->timing.pix_clk_khz;
2253
+ stream->phy_pix_clk = stream->timing.pix_clk_100hz / 10;
18452254 if (stream->phy_pix_clk > 340000)
18462255 is_over_340mhz = true;
18472256
18482257 if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
1849
- unsigned short masked_chip_caps = pipe_ctx->stream->sink->link->chip_caps &
2258
+ unsigned short masked_chip_caps = pipe_ctx->stream->link->chip_caps &
18502259 EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
18512260 if (masked_chip_caps == EXT_DISPLAY_PATH_CAPS__HDMI20_TISN65DP159RSBT) {
18522261 /* DP159, Retimer settings */
....@@ -1867,11 +2276,11 @@
18672276
18682277 if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
18692278 dal_ddc_service_write_scdc_data(
1870
- stream->sink->link->ddc,
2279
+ stream->link->ddc,
18712280 stream->phy_pix_clk,
18722281 stream->timing.flags.LTE_340MCSC_SCRAMBLE);
18732282
1874
- memset(&stream->sink->link->cur_link_settings, 0,
2283
+ memset(&stream->link->cur_link_settings, 0,
18752284 sizeof(struct dc_link_settings));
18762285
18772286 display_color_depth = stream->timing.display_color_depth;
....@@ -1885,8 +2294,26 @@
18852294 pipe_ctx->stream->signal,
18862295 stream->phy_pix_clk);
18872296
1888
- if (pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
2297
+ if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
18892298 dal_ddc_service_read_scdc_data(link->ddc);
2299
+}
2300
+
2301
+static void enable_link_lvds(struct pipe_ctx *pipe_ctx)
2302
+{
2303
+ struct dc_stream_state *stream = pipe_ctx->stream;
2304
+ struct dc_link *link = stream->link;
2305
+
2306
+ if (stream->phy_pix_clk == 0)
2307
+ stream->phy_pix_clk = stream->timing.pix_clk_100hz / 10;
2308
+
2309
+ memset(&stream->link->cur_link_settings, 0,
2310
+ sizeof(struct dc_link_settings));
2311
+
2312
+ link->link_enc->funcs->enable_lvds_output(
2313
+ link->link_enc,
2314
+ pipe_ctx->clock_source->id,
2315
+ stream->phy_pix_clk);
2316
+
18902317 }
18912318
18922319 /****************************enable_link***********************************/
....@@ -1895,6 +2322,19 @@
18952322 struct pipe_ctx *pipe_ctx)
18962323 {
18972324 enum dc_status status = DC_ERROR_UNEXPECTED;
2325
+ struct dc_stream_state *stream = pipe_ctx->stream;
2326
+ struct dc_link *link = stream->link;
2327
+
2328
+ /* There's some scenarios where driver is unloaded with display
2329
+ * still enabled. When driver is reloaded, it may cause a display
2330
+ * to not light up if there is a mismatch between old and new
2331
+ * link settings. Need to call disable first before enabling at
2332
+ * new link settings.
2333
+ */
2334
+ if (link->link_status.link_active) {
2335
+ disable_link(link, pipe_ctx->stream->signal);
2336
+ }
2337
+
18982338 switch (pipe_ctx->stream->signal) {
18992339 case SIGNAL_TYPE_DISPLAY_PORT:
19002340 status = enable_link_dp(state, pipe_ctx);
....@@ -1912,6 +2352,10 @@
19122352 enable_link_hdmi(pipe_ctx);
19132353 status = DC_OK;
19142354 break;
2355
+ case SIGNAL_TYPE_LVDS:
2356
+ enable_link_lvds(pipe_ctx);
2357
+ status = DC_OK;
2358
+ break;
19152359 case SIGNAL_TYPE_VIRTUAL:
19162360 status = DC_OK;
19172361 break;
....@@ -1919,36 +2363,34 @@
19192363 break;
19202364 }
19212365
2366
+ if (status == DC_OK)
2367
+ pipe_ctx->stream->link->link_status.link_active = true;
2368
+
19222369 return status;
19232370 }
19242371
1925
-static void disable_link(struct dc_link *link, enum signal_type signal)
2372
+static uint32_t get_timing_pixel_clock_100hz(const struct dc_crtc_timing *timing)
19262373 {
1927
- /*
1928
- * TODO: implement call for dp_set_hw_test_pattern
1929
- * it is needed for compliance testing
1930
- */
19312374
1932
- /* here we need to specify that encoder output settings
1933
- * need to be calculated as for the set mode,
1934
- * it will lead to querying dynamic link capabilities
1935
- * which should be done before enable output */
2375
+ uint32_t pxl_clk = timing->pix_clk_100hz;
19362376
1937
- if (dc_is_dp_signal(signal)) {
1938
- /* SST DP, eDP */
1939
- if (dc_is_dp_sst_signal(signal))
1940
- dp_disable_link_phy(link, signal);
1941
- else
1942
- dp_disable_link_phy_mst(link, signal);
1943
- } else
1944
- link->link_enc->funcs->disable_output(link->link_enc, signal);
2377
+ if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
2378
+ pxl_clk /= 2;
2379
+ else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
2380
+ pxl_clk = pxl_clk * 2 / 3;
2381
+
2382
+ if (timing->display_color_depth == COLOR_DEPTH_101010)
2383
+ pxl_clk = pxl_clk * 10 / 8;
2384
+ else if (timing->display_color_depth == COLOR_DEPTH_121212)
2385
+ pxl_clk = pxl_clk * 12 / 8;
2386
+
2387
+ return pxl_clk;
19452388 }
19462389
19472390 static bool dp_active_dongle_validate_timing(
19482391 const struct dc_crtc_timing *timing,
19492392 const struct dpcd_caps *dpcd_caps)
19502393 {
1951
- unsigned int required_pix_clk = timing->pix_clk_khz;
19522394 const struct dc_dongle_caps *dongle_caps = &dpcd_caps->dongle_caps;
19532395
19542396 switch (dpcd_caps->dongle_type) {
....@@ -1985,13 +2427,6 @@
19852427 return false;
19862428 }
19872429
1988
-
1989
- /* Check Color Depth and Pixel Clock */
1990
- if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
1991
- required_pix_clk /= 2;
1992
- else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
1993
- required_pix_clk = required_pix_clk * 2 / 3;
1994
-
19952430 switch (timing->display_color_depth) {
19962431 case COLOR_DEPTH_666:
19972432 case COLOR_DEPTH_888:
....@@ -2000,14 +2435,11 @@
20002435 case COLOR_DEPTH_101010:
20012436 if (dongle_caps->dp_hdmi_max_bpc < 10)
20022437 return false;
2003
- required_pix_clk = required_pix_clk * 10 / 8;
20042438 break;
20052439 case COLOR_DEPTH_121212:
20062440 if (dongle_caps->dp_hdmi_max_bpc < 12)
20072441 return false;
2008
- required_pix_clk = required_pix_clk * 12 / 8;
20092442 break;
2010
-
20112443 case COLOR_DEPTH_141414:
20122444 case COLOR_DEPTH_161616:
20132445 default:
....@@ -2015,7 +2447,7 @@
20152447 return false;
20162448 }
20172449
2018
- if (required_pix_clk > dongle_caps->dp_hdmi_max_pixel_clk)
2450
+ if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10))
20192451 return false;
20202452
20212453 return true;
....@@ -2026,7 +2458,7 @@
20262458 struct dc_link *link,
20272459 const struct dc_crtc_timing *timing)
20282460 {
2029
- uint32_t max_pix_clk = stream->sink->dongle_max_pix_clk;
2461
+ uint32_t max_pix_clk = stream->link->dongle_max_pix_clk * 10;
20302462 struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
20312463
20322464 /* A hack to avoid failing any modes for EDID override feature on
....@@ -2036,7 +2468,7 @@
20362468 return DC_OK;
20372469
20382470 /* Passive Dongle */
2039
- if (0 != max_pix_clk && timing->pix_clk_khz > max_pix_clk)
2471
+ if (max_pix_clk != 0 && get_timing_pixel_clock_100hz(timing) > max_pix_clk)
20402472 return DC_EXCEED_DONGLE_CAP;
20412473
20422474 /* Active Dongle*/
....@@ -2059,91 +2491,308 @@
20592491 return DC_OK;
20602492 }
20612493
2494
+static struct abm *get_abm_from_stream_res(const struct dc_link *link)
2495
+{
2496
+ int i;
2497
+ struct dc *dc = NULL;
2498
+ struct abm *abm = NULL;
2499
+
2500
+ if (!link || !link->ctx)
2501
+ return NULL;
2502
+
2503
+ dc = link->ctx->dc;
2504
+
2505
+ for (i = 0; i < MAX_PIPES; i++) {
2506
+ struct pipe_ctx pipe_ctx = dc->current_state->res_ctx.pipe_ctx[i];
2507
+ struct dc_stream_state *stream = pipe_ctx.stream;
2508
+
2509
+ if (stream && stream->link == link) {
2510
+ abm = pipe_ctx.stream_res.abm;
2511
+ break;
2512
+ }
2513
+ }
2514
+ return abm;
2515
+}
2516
+
20622517 int dc_link_get_backlight_level(const struct dc_link *link)
20632518 {
2064
- struct abm *abm = link->ctx->dc->res_pool->abm;
20652519
2066
- if (abm == NULL || abm->funcs->get_current_backlight_8_bit == NULL)
2520
+ struct abm *abm = get_abm_from_stream_res(link);
2521
+
2522
+ if (abm == NULL || abm->funcs->get_current_backlight == NULL)
20672523 return DC_ERROR_UNEXPECTED;
20682524
2069
- return (int) abm->funcs->get_current_backlight_8_bit(abm);
2525
+ return (int) abm->funcs->get_current_backlight(abm);
20702526 }
20712527
2072
-bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level,
2073
- uint32_t frame_ramp, const struct dc_stream_state *stream)
2528
+int dc_link_get_target_backlight_pwm(const struct dc_link *link)
20742529 {
2075
- struct dc *core_dc = link->ctx->dc;
2076
- struct abm *abm = core_dc->res_pool->abm;
2077
- struct dmcu *dmcu = core_dc->res_pool->dmcu;
2078
- unsigned int controller_id = 0;
2079
- bool use_smooth_brightness = true;
2530
+ struct abm *abm = get_abm_from_stream_res(link);
2531
+
2532
+ if (abm == NULL || abm->funcs->get_target_backlight == NULL)
2533
+ return DC_ERROR_UNEXPECTED;
2534
+
2535
+ return (int) abm->funcs->get_target_backlight(abm);
2536
+}
2537
+
2538
+static struct pipe_ctx *get_pipe_from_link(const struct dc_link *link)
2539
+{
20802540 int i;
2081
- DC_LOGGER_INIT(link->ctx->logger);
2541
+ struct dc *dc = link->ctx->dc;
2542
+ struct pipe_ctx *pipe_ctx = NULL;
20822543
2083
- if ((dmcu == NULL) ||
2084
- (abm == NULL) ||
2085
- (abm->funcs->set_backlight_level == NULL))
2086
- return false;
2087
-
2088
- if (stream) {
2089
- if (stream->bl_pwm_level == EDP_BACKLIGHT_RAMP_DISABLE_LEVEL)
2090
- frame_ramp = 0;
2091
-
2092
- ((struct dc_stream_state *)stream)->bl_pwm_level = level;
2093
- }
2094
-
2095
- use_smooth_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
2096
-
2097
- DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", level, level);
2098
-
2099
- if (dc_is_embedded_signal(link->connector_signal)) {
2100
- if (stream != NULL) {
2101
- for (i = 0; i < MAX_PIPES; i++) {
2102
- if (core_dc->current_state->res_ctx.
2103
- pipe_ctx[i].stream
2104
- == stream)
2105
- /* DMCU -1 for all controller id values,
2106
- * therefore +1 here
2107
- */
2108
- controller_id =
2109
- core_dc->current_state->
2110
- res_ctx.pipe_ctx[i].stream_res.tg->inst +
2111
- 1;
2544
+ for (i = 0; i < MAX_PIPES; i++) {
2545
+ if (dc->current_state->res_ctx.pipe_ctx[i].stream) {
2546
+ if (dc->current_state->res_ctx.pipe_ctx[i].stream->link == link) {
2547
+ pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
2548
+ break;
21122549 }
21132550 }
2114
- abm->funcs->set_backlight_level(
2115
- abm,
2116
- level,
2117
- frame_ramp,
2118
- controller_id,
2119
- use_smooth_brightness);
21202551 }
21212552
2553
+ return pipe_ctx;
2554
+}
2555
+
2556
+bool dc_link_set_backlight_level(const struct dc_link *link,
2557
+ uint32_t backlight_pwm_u16_16,
2558
+ uint32_t frame_ramp)
2559
+{
2560
+ struct dc *dc = link->ctx->dc;
2561
+
2562
+ DC_LOGGER_INIT(link->ctx->logger);
2563
+ DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
2564
+ backlight_pwm_u16_16, backlight_pwm_u16_16);
2565
+
2566
+ if (dc_is_embedded_signal(link->connector_signal)) {
2567
+ struct pipe_ctx *pipe_ctx = get_pipe_from_link(link);
2568
+
2569
+ if (pipe_ctx) {
2570
+ /* Disable brightness ramping when the display is blanked
2571
+ * as it can hang the DMCU
2572
+ */
2573
+ if (pipe_ctx->plane_state == NULL)
2574
+ frame_ramp = 0;
2575
+ } else {
2576
+ return false;
2577
+ }
2578
+
2579
+ dc->hwss.set_backlight_level(
2580
+ pipe_ctx,
2581
+ backlight_pwm_u16_16,
2582
+ frame_ramp);
2583
+ }
21222584 return true;
21232585 }
21242586
2125
-bool dc_link_set_abm_disable(const struct dc_link *link)
2587
+bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool wait)
21262588 {
2127
- struct dc *core_dc = link->ctx->dc;
2128
- struct abm *abm = core_dc->res_pool->abm;
2589
+ struct dc *dc = link->ctx->dc;
2590
+ struct dmcu *dmcu = dc->res_pool->dmcu;
2591
+ struct dmub_psr *psr = dc->res_pool->psr;
21292592
2130
- if ((abm == NULL) || (abm->funcs->set_backlight_level == NULL))
2593
+ link->psr_settings.psr_allow_active = allow_active;
2594
+
2595
+ if (psr != NULL && link->psr_settings.psr_feature_enabled)
2596
+ psr->funcs->psr_enable(psr, allow_active, wait);
2597
+ else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_settings.psr_feature_enabled)
2598
+ dmcu->funcs->set_psr_enable(dmcu, allow_active, wait);
2599
+ else
21312600 return false;
21322601
2133
- abm->funcs->set_abm_immediate_disable(abm);
2602
+ return true;
2603
+}
2604
+
2605
+bool dc_link_get_psr_state(const struct dc_link *link, uint32_t *psr_state)
2606
+{
2607
+ struct dc *dc = link->ctx->dc;
2608
+ struct dmcu *dmcu = dc->res_pool->dmcu;
2609
+ struct dmub_psr *psr = dc->res_pool->psr;
2610
+
2611
+ if (psr != NULL && link->psr_settings.psr_feature_enabled)
2612
+ psr->funcs->psr_get_state(psr, psr_state);
2613
+ else if (dmcu != NULL && link->psr_settings.psr_feature_enabled)
2614
+ dmcu->funcs->get_psr_state(dmcu, psr_state);
21342615
21352616 return true;
21362617 }
21372618
2138
-bool dc_link_set_psr_enable(const struct dc_link *link, bool enable, bool wait)
2619
+static inline enum physical_phy_id
2620
+transmitter_to_phy_id(enum transmitter transmitter_value)
21392621 {
2140
- struct dc *core_dc = link->ctx->dc;
2141
- struct dmcu *dmcu = core_dc->res_pool->dmcu;
2622
+ switch (transmitter_value) {
2623
+ case TRANSMITTER_UNIPHY_A:
2624
+ return PHYLD_0;
2625
+ case TRANSMITTER_UNIPHY_B:
2626
+ return PHYLD_1;
2627
+ case TRANSMITTER_UNIPHY_C:
2628
+ return PHYLD_2;
2629
+ case TRANSMITTER_UNIPHY_D:
2630
+ return PHYLD_3;
2631
+ case TRANSMITTER_UNIPHY_E:
2632
+ return PHYLD_4;
2633
+ case TRANSMITTER_UNIPHY_F:
2634
+ return PHYLD_5;
2635
+ case TRANSMITTER_NUTMEG_CRT:
2636
+ return PHYLD_6;
2637
+ case TRANSMITTER_TRAVIS_CRT:
2638
+ return PHYLD_7;
2639
+ case TRANSMITTER_TRAVIS_LCD:
2640
+ return PHYLD_8;
2641
+ case TRANSMITTER_UNIPHY_G:
2642
+ return PHYLD_9;
2643
+ case TRANSMITTER_COUNT:
2644
+ return PHYLD_COUNT;
2645
+ case TRANSMITTER_UNKNOWN:
2646
+ return PHYLD_UNKNOWN;
2647
+ default:
2648
+ WARN_ONCE(1, "Unknown transmitter value %d\n",
2649
+ transmitter_value);
2650
+ return PHYLD_UNKNOWN;
2651
+ }
2652
+}
21422653
2143
- if (dmcu != NULL && link->psr_enabled)
2144
- dmcu->funcs->set_psr_enable(dmcu, enable, wait);
2654
+bool dc_link_setup_psr(struct dc_link *link,
2655
+ const struct dc_stream_state *stream, struct psr_config *psr_config,
2656
+ struct psr_context *psr_context)
2657
+{
2658
+ struct dc *dc;
2659
+ struct dmcu *dmcu;
2660
+ struct dmub_psr *psr;
2661
+ int i;
2662
+ /* updateSinkPsrDpcdConfig*/
2663
+ union dpcd_psr_configuration psr_configuration;
2664
+
2665
+ psr_context->controllerId = CONTROLLER_ID_UNDEFINED;
2666
+
2667
+ if (!link)
2668
+ return false;
2669
+
2670
+ dc = link->ctx->dc;
2671
+ dmcu = dc->res_pool->dmcu;
2672
+ psr = dc->res_pool->psr;
2673
+
2674
+ if (!dmcu && !psr)
2675
+ return false;
2676
+
2677
+
2678
+ memset(&psr_configuration, 0, sizeof(psr_configuration));
2679
+
2680
+ psr_configuration.bits.ENABLE = 1;
2681
+ psr_configuration.bits.CRC_VERIFICATION = 1;
2682
+ psr_configuration.bits.FRAME_CAPTURE_INDICATION =
2683
+ psr_config->psr_frame_capture_indication_req;
2684
+
2685
+ /* Check for PSR v2*/
2686
+ if (psr_config->psr_version == 0x2) {
2687
+ /* For PSR v2 selective update.
2688
+ * Indicates whether sink should start capturing
2689
+ * immediately following active scan line,
2690
+ * or starting with the 2nd active scan line.
2691
+ */
2692
+ psr_configuration.bits.LINE_CAPTURE_INDICATION = 0;
2693
+ /*For PSR v2, determines whether Sink should generate
2694
+ * IRQ_HPD when CRC mismatch is detected.
2695
+ */
2696
+ psr_configuration.bits.IRQ_HPD_WITH_CRC_ERROR = 1;
2697
+ }
2698
+
2699
+ dm_helpers_dp_write_dpcd(
2700
+ link->ctx,
2701
+ link,
2702
+ 368,
2703
+ &psr_configuration.raw,
2704
+ sizeof(psr_configuration.raw));
2705
+
2706
+ psr_context->channel = link->ddc->ddc_pin->hw_info.ddc_channel;
2707
+ psr_context->transmitterId = link->link_enc->transmitter;
2708
+ psr_context->engineId = link->link_enc->preferred_engine;
2709
+
2710
+ for (i = 0; i < MAX_PIPES; i++) {
2711
+ if (dc->current_state->res_ctx.pipe_ctx[i].stream
2712
+ == stream) {
2713
+ /* dmcu -1 for all controller id values,
2714
+ * therefore +1 here
2715
+ */
2716
+ psr_context->controllerId =
2717
+ dc->current_state->res_ctx.
2718
+ pipe_ctx[i].stream_res.tg->inst + 1;
2719
+ break;
2720
+ }
2721
+ }
2722
+
2723
+ /* Hardcoded for now. Can be Pcie or Uniphy (or Unknown)*/
2724
+ psr_context->phyType = PHY_TYPE_UNIPHY;
2725
+ /*PhyId is associated with the transmitter id*/
2726
+ psr_context->smuPhyId =
2727
+ transmitter_to_phy_id(link->link_enc->transmitter);
2728
+
2729
+ psr_context->crtcTimingVerticalTotal = stream->timing.v_total;
2730
+ psr_context->vsync_rate_hz = div64_u64(div64_u64((stream->
2731
+ timing.pix_clk_100hz * 100),
2732
+ stream->timing.v_total),
2733
+ stream->timing.h_total);
2734
+
2735
+ psr_context->psrSupportedDisplayConfig = true;
2736
+ psr_context->psrExitLinkTrainingRequired =
2737
+ psr_config->psr_exit_link_training_required;
2738
+ psr_context->sdpTransmitLineNumDeadline =
2739
+ psr_config->psr_sdp_transmit_line_num_deadline;
2740
+ psr_context->psrFrameCaptureIndicationReq =
2741
+ psr_config->psr_frame_capture_indication_req;
2742
+
2743
+ psr_context->skipPsrWaitForPllLock = 0; /* only = 1 in KV */
2744
+
2745
+ psr_context->numberOfControllers =
2746
+ link->dc->res_pool->timing_generator_count;
2747
+
2748
+ psr_context->rfb_update_auto_en = true;
2749
+
2750
+ /* 2 frames before enter PSR. */
2751
+ psr_context->timehyst_frames = 2;
2752
+ /* half a frame
2753
+ * (units in 100 lines, i.e. a value of 1 represents 100 lines)
2754
+ */
2755
+ psr_context->hyst_lines = stream->timing.v_total / 2 / 100;
2756
+ psr_context->aux_repeats = 10;
2757
+
2758
+ psr_context->psr_level.u32all = 0;
2759
+
2760
+#if defined(CONFIG_DRM_AMD_DC_DCN)
2761
+ /*skip power down the single pipe since it blocks the cstate*/
2762
+ if (ASICREV_IS_RAVEN(link->ctx->asic_id.hw_internal_rev))
2763
+ psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
2764
+#endif
2765
+
2766
+ /* SMU will perform additional powerdown sequence.
2767
+ * For unsupported ASICs, set psr_level flag to skip PSR
2768
+ * static screen notification to SMU.
2769
+ * (Always set for DAL2, did not check ASIC)
2770
+ */
2771
+ psr_context->allow_smu_optimizations = psr_config->allow_smu_optimizations;
2772
+
2773
+ /* Complete PSR entry before aborting to prevent intermittent
2774
+ * freezes on certain eDPs
2775
+ */
2776
+ psr_context->psr_level.bits.DISABLE_PSR_ENTRY_ABORT = 1;
2777
+
2778
+ /* Controls additional delay after remote frame capture before
2779
+ * continuing power down, default = 0
2780
+ */
2781
+ psr_context->frame_delay = 0;
2782
+
2783
+ if (psr)
2784
+ link->psr_settings.psr_feature_enabled = psr->funcs->psr_copy_settings(psr, link, psr_context);
2785
+ else
2786
+ link->psr_settings.psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, psr_context);
2787
+
2788
+ /* psr_enabled == 0 indicates setup_psr did not succeed, but this
2789
+ * should not happen since firmware should be running at this point
2790
+ */
2791
+ if (link->psr_settings.psr_feature_enabled == 0)
2792
+ ASSERT(0);
21452793
21462794 return true;
2795
+
21472796 }
21482797
21492798 const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
....@@ -2159,39 +2808,24 @@
21592808
21602809 static struct fixed31_32 get_pbn_per_slot(struct dc_stream_state *stream)
21612810 {
2162
- struct dc_link_settings *link_settings =
2163
- &stream->sink->link->cur_link_settings;
2164
- uint32_t link_rate_in_mbps =
2165
- link_settings->link_rate * LINK_RATE_REF_FREQ_IN_MHZ;
2166
- struct fixed31_32 mbps = dc_fixpt_from_int(
2167
- link_rate_in_mbps * link_settings->lane_count);
2811
+ struct fixed31_32 mbytes_per_sec;
2812
+ uint32_t link_rate_in_mbytes_per_sec = dc_link_bandwidth_kbps(stream->link,
2813
+ &stream->link->cur_link_settings);
2814
+ link_rate_in_mbytes_per_sec /= 8000; /* Kbits to MBytes */
21682815
2169
- return dc_fixpt_div_int(mbps, 54);
2170
-}
2816
+ mbytes_per_sec = dc_fixpt_from_int(link_rate_in_mbytes_per_sec);
21712817
2172
-static int get_color_depth(enum dc_color_depth color_depth)
2173
-{
2174
- switch (color_depth) {
2175
- case COLOR_DEPTH_666: return 6;
2176
- case COLOR_DEPTH_888: return 8;
2177
- case COLOR_DEPTH_101010: return 10;
2178
- case COLOR_DEPTH_121212: return 12;
2179
- case COLOR_DEPTH_141414: return 14;
2180
- case COLOR_DEPTH_161616: return 16;
2181
- default: return 0;
2182
- }
2818
+ return dc_fixpt_div_int(mbytes_per_sec, 54);
21832819 }
21842820
21852821 static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
21862822 {
2187
- uint32_t bpc;
21882823 uint64_t kbps;
21892824 struct fixed31_32 peak_kbps;
21902825 uint32_t numerator;
21912826 uint32_t denominator;
21922827
2193
- bpc = get_color_depth(pipe_ctx->stream_res.pix_clk_params.color_depth);
2194
- kbps = pipe_ctx->stream_res.pix_clk_params.requested_pix_clk * bpc * 3;
2828
+ kbps = dc_bandwidth_in_kbps_from_timing(&pipe_ctx->stream->timing);
21952829
21962830 /*
21972831 * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
....@@ -2264,10 +2898,10 @@
22642898 /* convert link_mst_stream_alloc_table to dm dp_mst_stream_alloc_table
22652899 * because stream_encoder is not exposed to dm
22662900 */
2267
-static enum dc_status allocate_mst_payload(struct pipe_ctx *pipe_ctx)
2901
+enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
22682902 {
22692903 struct dc_stream_state *stream = pipe_ctx->stream;
2270
- struct dc_link *link = stream->sink->link;
2904
+ struct dc_link *link = stream->link;
22712905 struct link_encoder *link_encoder = link->link_enc;
22722906 struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
22732907 struct dp_mst_stream_allocation_table proposed_table = {0};
....@@ -2275,6 +2909,7 @@
22752909 struct fixed31_32 pbn;
22762910 struct fixed31_32 pbn_per_slot;
22772911 uint8_t i;
2912
+ enum act_return_status ret;
22782913 DC_LOGGER_INIT(link->ctx->logger);
22792914
22802915 /* enable_link_dp_mst already check link->enabled_stream_count
....@@ -2322,21 +2957,23 @@
23222957 &link->mst_stream_alloc_table);
23232958
23242959 /* send down message */
2325
- dm_helpers_dp_mst_poll_for_allocation_change_trigger(
2960
+ ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
23262961 stream->ctx,
23272962 stream);
23282963
2329
- dm_helpers_dp_mst_send_payload_allocation(
2330
- stream->ctx,
2331
- stream,
2332
- true);
2964
+ if (ret != ACT_LINK_LOST) {
2965
+ dm_helpers_dp_mst_send_payload_allocation(
2966
+ stream->ctx,
2967
+ stream,
2968
+ true);
2969
+ }
23332970
23342971 /* slot X.Y for only current stream */
23352972 pbn_per_slot = get_pbn_per_slot(stream);
23362973 pbn = get_pbn_from_timing(pipe_ctx);
23372974 avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
23382975
2339
- stream_encoder->funcs->set_mst_bandwidth(
2976
+ stream_encoder->funcs->set_throttled_vcp_size(
23402977 stream_encoder,
23412978 avg_time_slots_per_mtp);
23422979
....@@ -2347,7 +2984,7 @@
23472984 static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
23482985 {
23492986 struct dc_stream_state *stream = pipe_ctx->stream;
2350
- struct dc_link *link = stream->sink->link;
2987
+ struct dc_link *link = stream->link;
23512988 struct link_encoder *link_encoder = link->link_enc;
23522989 struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
23532990 struct dp_mst_stream_allocation_table proposed_table = {0};
....@@ -2364,7 +3001,7 @@
23643001 */
23653002
23663003 /* slot X.Y */
2367
- stream_encoder->funcs->set_mst_bandwidth(
3004
+ stream_encoder->funcs->set_throttled_vcp_size(
23683005 stream_encoder,
23693006 avg_time_slots_per_mtp);
23703007
....@@ -2422,30 +3059,181 @@
24223059 return DC_OK;
24233060 }
24243061
3062
+enum dc_status dc_link_reallocate_mst_payload(struct dc_link *link)
3063
+{
3064
+ int i;
3065
+ struct pipe_ctx *pipe_ctx;
3066
+
3067
+ // Clear all of MST payload then reallocate
3068
+ for (i = 0; i < MAX_PIPES; i++) {
3069
+ pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
3070
+
3071
+ /* driver enable split pipe for external monitors
3072
+ * we have to check pipe_ctx is split pipe or not
3073
+ * If it's split pipe, driver using top pipe to
3074
+ * reaallocate.
3075
+ */
3076
+ if (!pipe_ctx || pipe_ctx->top_pipe)
3077
+ continue;
3078
+
3079
+ if (pipe_ctx->stream && pipe_ctx->stream->link == link &&
3080
+ pipe_ctx->stream->dpms_off == false &&
3081
+ pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
3082
+ deallocate_mst_payload(pipe_ctx);
3083
+ }
3084
+ }
3085
+
3086
+ for (i = 0; i < MAX_PIPES; i++) {
3087
+ pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
3088
+
3089
+ if (!pipe_ctx || pipe_ctx->top_pipe)
3090
+ continue;
3091
+
3092
+ if (pipe_ctx->stream && pipe_ctx->stream->link == link &&
3093
+ pipe_ctx->stream->dpms_off == false &&
3094
+ pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
3095
+ /* enable/disable PHY will clear connection between BE and FE
3096
+ * need to restore it.
3097
+ */
3098
+ link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
3099
+ pipe_ctx->stream_res.stream_enc->id, true);
3100
+ dc_link_allocate_mst_payload(pipe_ctx);
3101
+ }
3102
+ }
3103
+
3104
+ return DC_OK;
3105
+}
3106
+
3107
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
3108
+static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
3109
+{
3110
+ struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp;
3111
+ if (cp_psp && cp_psp->funcs.update_stream_config) {
3112
+ struct cp_psp_stream_config config;
3113
+
3114
+ memset(&config, 0, sizeof(config));
3115
+
3116
+ config.otg_inst = (uint8_t) pipe_ctx->stream_res.tg->inst;
3117
+ /*stream_enc_inst*/
3118
+ config.stream_enc_inst = (uint8_t) pipe_ctx->stream_res.stream_enc->stream_enc_inst;
3119
+ config.link_enc_inst = pipe_ctx->stream->link->link_enc_hw_inst;
3120
+ config.dpms_off = dpms_off;
3121
+ config.dm_stream_ctx = pipe_ctx->stream->dm_stream_context;
3122
+ config.mst_supported = (pipe_ctx->stream->signal ==
3123
+ SIGNAL_TYPE_DISPLAY_PORT_MST);
3124
+ cp_psp->funcs.update_stream_config(cp_psp->handle, &config);
3125
+ }
3126
+}
3127
+#endif
3128
+
24253129 void core_link_enable_stream(
24263130 struct dc_state *state,
24273131 struct pipe_ctx *pipe_ctx)
24283132 {
2429
- struct dc *core_dc = pipe_ctx->stream->ctx->dc;
3133
+ struct dc *dc = pipe_ctx->stream->ctx->dc;
3134
+ struct dc_stream_state *stream = pipe_ctx->stream;
24303135 enum dc_status status;
3136
+#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
3137
+ enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO;
3138
+#endif
24313139 DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
24323140
2433
- /* eDP lit up by bios already, no need to enable again. */
2434
- if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
2435
- core_dc->apply_edp_fast_boot_optimization) {
2436
- core_dc->apply_edp_fast_boot_optimization = false;
2437
- pipe_ctx->stream->dpms_off = false;
3141
+ if (!IS_DIAG_DC(dc->ctx->dce_environment) &&
3142
+ dc_is_virtual_signal(pipe_ctx->stream->signal))
24383143 return;
3144
+
3145
+ if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) {
3146
+ stream->link->link_enc->funcs->setup(
3147
+ stream->link->link_enc,
3148
+ pipe_ctx->stream->signal);
3149
+ pipe_ctx->stream_res.stream_enc->funcs->setup_stereo_sync(
3150
+ pipe_ctx->stream_res.stream_enc,
3151
+ pipe_ctx->stream_res.tg->inst,
3152
+ stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE);
24393153 }
24403154
2441
- if (pipe_ctx->stream->dpms_off)
2442
- return;
3155
+ if (dc_is_dp_signal(pipe_ctx->stream->signal))
3156
+ pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(
3157
+ pipe_ctx->stream_res.stream_enc,
3158
+ &stream->timing,
3159
+ stream->output_color_space,
3160
+ stream->use_vsc_sdp_for_colorimetry,
3161
+ stream->link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP);
24433162
2444
- status = enable_link(state, pipe_ctx);
3163
+ if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal))
3164
+ pipe_ctx->stream_res.stream_enc->funcs->hdmi_set_stream_attribute(
3165
+ pipe_ctx->stream_res.stream_enc,
3166
+ &stream->timing,
3167
+ stream->phy_pix_clk,
3168
+ pipe_ctx->stream_res.audio != NULL);
24453169
2446
- if (status != DC_OK) {
3170
+ pipe_ctx->stream->link->link_state_valid = true;
3171
+
3172
+#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
3173
+ if (pipe_ctx->stream_res.tg->funcs->set_out_mux)
3174
+ pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, otg_out_dest);
3175
+#endif
3176
+
3177
+ if (dc_is_dvi_signal(pipe_ctx->stream->signal))
3178
+ pipe_ctx->stream_res.stream_enc->funcs->dvi_set_stream_attribute(
3179
+ pipe_ctx->stream_res.stream_enc,
3180
+ &stream->timing,
3181
+ (pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ?
3182
+ true : false);
3183
+
3184
+ if (dc_is_lvds_signal(pipe_ctx->stream->signal))
3185
+ pipe_ctx->stream_res.stream_enc->funcs->lvds_set_stream_attribute(
3186
+ pipe_ctx->stream_res.stream_enc,
3187
+ &stream->timing);
3188
+
3189
+ if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
3190
+ bool apply_edp_fast_boot_optimization =
3191
+ pipe_ctx->stream->apply_edp_fast_boot_optimization;
3192
+
3193
+ pipe_ctx->stream->apply_edp_fast_boot_optimization = false;
3194
+
3195
+ resource_build_info_frame(pipe_ctx);
3196
+ dc->hwss.update_info_frame(pipe_ctx);
3197
+
3198
+ /* Do not touch link on seamless boot optimization. */
3199
+ if (pipe_ctx->stream->apply_seamless_boot_optimization) {
3200
+ pipe_ctx->stream->dpms_off = false;
3201
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
3202
+ update_psp_stream_config(pipe_ctx, false);
3203
+#endif
3204
+ return;
3205
+ }
3206
+
3207
+ /* eDP lit up by bios already, no need to enable again. */
3208
+ if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
3209
+ apply_edp_fast_boot_optimization) {
3210
+ pipe_ctx->stream->dpms_off = false;
3211
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
3212
+ update_psp_stream_config(pipe_ctx, false);
3213
+#endif
3214
+ return;
3215
+ }
3216
+
3217
+ if (pipe_ctx->stream->dpms_off)
3218
+ return;
3219
+
3220
+ /* Have to setup DSC before DIG FE and BE are connected (which happens before the
3221
+ * link training). This is to make sure the bandwidth sent to DIG BE won't be
3222
+ * bigger than what the link and/or DIG BE can handle. VBID[6]/CompressedStream_flag
3223
+ * will be automatically set at a later time when the video is enabled
3224
+ * (DP_VID_STREAM_EN = 1).
3225
+ */
3226
+ if (pipe_ctx->stream->timing.flags.DSC) {
3227
+ if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
3228
+ dc_is_virtual_signal(pipe_ctx->stream->signal))
3229
+ dp_set_dsc_enable(pipe_ctx, true);
3230
+ }
3231
+
3232
+ status = enable_link(state, pipe_ctx);
3233
+
3234
+ if (status != DC_OK) {
24473235 DC_LOG_WARNING("enabling link %u failed: %d\n",
2448
- pipe_ctx->stream->sink->link->link_index,
3236
+ pipe_ctx->stream->link->link_index,
24493237 status);
24503238
24513239 /* Abort stream enable *unless* the failure was due to
....@@ -2458,47 +3246,125 @@
24583246 BREAK_TO_DEBUGGER();
24593247 return;
24603248 }
3249
+ }
3250
+
3251
+ dc->hwss.enable_audio_stream(pipe_ctx);
3252
+
3253
+ /* turn off otg test pattern if enable */
3254
+ if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
3255
+ pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
3256
+ CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
3257
+ COLOR_DEPTH_UNDEFINED);
3258
+
3259
+ /* This second call is needed to reconfigure the DIG
3260
+ * as a workaround for the incorrect value being applied
3261
+ * from transmitter control.
3262
+ */
3263
+ if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
3264
+ stream->link->link_enc->funcs->setup(
3265
+ stream->link->link_enc,
3266
+ pipe_ctx->stream->signal);
3267
+
3268
+ dc->hwss.enable_stream(pipe_ctx);
3269
+
3270
+ /* Set DPS PPS SDP (AKA "info frames") */
3271
+ if (pipe_ctx->stream->timing.flags.DSC) {
3272
+ if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
3273
+ dc_is_virtual_signal(pipe_ctx->stream->signal))
3274
+ dp_set_dsc_pps_sdp(pipe_ctx, true);
3275
+ }
3276
+
3277
+ if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
3278
+ dc_link_allocate_mst_payload(pipe_ctx);
3279
+
3280
+ dc->hwss.unblank_stream(pipe_ctx,
3281
+ &pipe_ctx->stream->link->cur_link_settings);
3282
+
3283
+ if (stream->sink_patches.delay_ignore_msa > 0)
3284
+ msleep(stream->sink_patches.delay_ignore_msa);
3285
+
3286
+ if (dc_is_dp_signal(pipe_ctx->stream->signal))
3287
+ enable_stream_features(pipe_ctx);
3288
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
3289
+ update_psp_stream_config(pipe_ctx, false);
3290
+#endif
3291
+ } else { // if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
3292
+ if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
3293
+ dc_is_virtual_signal(pipe_ctx->stream->signal))
3294
+ dp_set_dsc_enable(pipe_ctx, true);
3295
+
24613296 }
24623297
2463
- core_dc->hwss.enable_audio_stream(pipe_ctx);
2464
-
2465
- /* turn off otg test pattern if enable */
2466
- if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
2467
- pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
2468
- CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
2469
- COLOR_DEPTH_UNDEFINED);
2470
-
2471
- core_dc->hwss.enable_stream(pipe_ctx);
2472
-
2473
- if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
2474
- allocate_mst_payload(pipe_ctx);
2475
-
2476
- core_dc->hwss.unblank_stream(pipe_ctx,
2477
- &pipe_ctx->stream->sink->link->cur_link_settings);
3298
+ if (pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
3299
+ core_link_set_avmute(pipe_ctx, false);
3300
+ }
24783301 }
24793302
2480
-void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
3303
+void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
24813304 {
2482
- struct dc *core_dc = pipe_ctx->stream->ctx->dc;
3305
+ struct dc *dc = pipe_ctx->stream->ctx->dc;
3306
+ struct dc_stream_state *stream = pipe_ctx->stream;
3307
+ struct dc_link *link = stream->sink->link;
24833308
2484
- core_dc->hwss.blank_stream(pipe_ctx);
3309
+ if (!IS_DIAG_DC(dc->ctx->dce_environment) &&
3310
+ dc_is_virtual_signal(pipe_ctx->stream->signal))
3311
+ return;
3312
+
3313
+ if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
3314
+ core_link_set_avmute(pipe_ctx, true);
3315
+ }
3316
+
3317
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
3318
+ update_psp_stream_config(pipe_ctx, true);
3319
+#endif
3320
+ dc->hwss.blank_stream(pipe_ctx);
24853321
24863322 if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
24873323 deallocate_mst_payload(pipe_ctx);
24883324
2489
- core_dc->hwss.disable_stream(pipe_ctx, option);
3325
+ if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
3326
+ struct ext_hdmi_settings settings = {0};
3327
+ enum engine_id eng_id = pipe_ctx->stream_res.stream_enc->id;
24903328
2491
- disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal);
3329
+ unsigned short masked_chip_caps = link->chip_caps &
3330
+ EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
3331
+ //Need to inform that sink is going to use legacy HDMI mode.
3332
+ dal_ddc_service_write_scdc_data(
3333
+ link->ddc,
3334
+ 165000,//vbios only handles 165Mhz.
3335
+ false);
3336
+ if (masked_chip_caps == EXT_DISPLAY_PATH_CAPS__HDMI20_TISN65DP159RSBT) {
3337
+ /* DP159, Retimer settings */
3338
+ if (get_ext_hdmi_settings(pipe_ctx, eng_id, &settings))
3339
+ write_i2c_retimer_setting(pipe_ctx,
3340
+ false, false, &settings);
3341
+ else
3342
+ write_i2c_default_retimer_setting(pipe_ctx,
3343
+ false, false);
3344
+ } else if (masked_chip_caps == EXT_DISPLAY_PATH_CAPS__HDMI20_PI3EQX1204) {
3345
+ /* PI3EQX1204, Redriver settings */
3346
+ write_i2c_redriver_setting(pipe_ctx, false);
3347
+ }
3348
+ }
3349
+
3350
+ disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal);
3351
+
3352
+ dc->hwss.disable_stream(pipe_ctx);
3353
+
3354
+ if (pipe_ctx->stream->timing.flags.DSC) {
3355
+ if (dc_is_dp_signal(pipe_ctx->stream->signal))
3356
+ dp_set_dsc_enable(pipe_ctx, false);
3357
+ }
24923358 }
24933359
24943360 void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
24953361 {
2496
- struct dc *core_dc = pipe_ctx->stream->ctx->dc;
3362
+ struct dc *dc = pipe_ctx->stream->ctx->dc;
24973363
2498
- if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A)
3364
+ if (!dc_is_hdmi_signal(pipe_ctx->stream->signal))
24993365 return;
25003366
2501
- core_dc->hwss.set_avmute(pipe_ctx, enable);
3367
+ dc->hwss.set_avmute(pipe_ctx, enable);
25023368 }
25033369
25043370 /**
....@@ -2550,3 +3416,246 @@
25503416 }
25513417 }
25523418
3419
+uint32_t dc_bandwidth_in_kbps_from_timing(
3420
+ const struct dc_crtc_timing *timing)
3421
+{
3422
+ uint32_t bits_per_channel = 0;
3423
+ uint32_t kbps;
3424
+ struct fixed31_32 link_bw_kbps;
3425
+
3426
+ if (timing->flags.DSC) {
3427
+ link_bw_kbps = dc_fixpt_from_int(timing->pix_clk_100hz);
3428
+ link_bw_kbps = dc_fixpt_div_int(link_bw_kbps, 160);
3429
+ link_bw_kbps = dc_fixpt_mul_int(link_bw_kbps, timing->dsc_cfg.bits_per_pixel);
3430
+ kbps = dc_fixpt_ceil(link_bw_kbps);
3431
+ return kbps;
3432
+ }
3433
+
3434
+ switch (timing->display_color_depth) {
3435
+ case COLOR_DEPTH_666:
3436
+ bits_per_channel = 6;
3437
+ break;
3438
+ case COLOR_DEPTH_888:
3439
+ bits_per_channel = 8;
3440
+ break;
3441
+ case COLOR_DEPTH_101010:
3442
+ bits_per_channel = 10;
3443
+ break;
3444
+ case COLOR_DEPTH_121212:
3445
+ bits_per_channel = 12;
3446
+ break;
3447
+ case COLOR_DEPTH_141414:
3448
+ bits_per_channel = 14;
3449
+ break;
3450
+ case COLOR_DEPTH_161616:
3451
+ bits_per_channel = 16;
3452
+ break;
3453
+ default:
3454
+ break;
3455
+ }
3456
+
3457
+ ASSERT(bits_per_channel != 0);
3458
+
3459
+ kbps = timing->pix_clk_100hz / 10;
3460
+ kbps *= bits_per_channel;
3461
+
3462
+ if (timing->flags.Y_ONLY != 1) {
3463
+ /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/
3464
+ kbps *= 3;
3465
+ if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
3466
+ kbps /= 2;
3467
+ else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
3468
+ kbps = kbps * 2 / 3;
3469
+ }
3470
+
3471
+ return kbps;
3472
+
3473
+}
3474
+
3475
+void dc_link_set_drive_settings(struct dc *dc,
3476
+ struct link_training_settings *lt_settings,
3477
+ const struct dc_link *link)
3478
+{
3479
+
3480
+ int i;
3481
+
3482
+ for (i = 0; i < dc->link_count; i++) {
3483
+ if (dc->links[i] == link)
3484
+ break;
3485
+ }
3486
+
3487
+ if (i >= dc->link_count)
3488
+ ASSERT_CRITICAL(false);
3489
+
3490
+ dc_link_dp_set_drive_settings(dc->links[i], lt_settings);
3491
+}
3492
+
3493
+void dc_link_perform_link_training(struct dc *dc,
3494
+ struct dc_link_settings *link_setting,
3495
+ bool skip_video_pattern)
3496
+{
3497
+ int i;
3498
+
3499
+ for (i = 0; i < dc->link_count; i++)
3500
+ dc_link_dp_perform_link_training(
3501
+ dc->links[i],
3502
+ link_setting,
3503
+ skip_video_pattern);
3504
+}
3505
+
3506
+void dc_link_set_preferred_link_settings(struct dc *dc,
3507
+ struct dc_link_settings *link_setting,
3508
+ struct dc_link *link)
3509
+{
3510
+ int i;
3511
+ struct pipe_ctx *pipe;
3512
+ struct dc_stream_state *link_stream;
3513
+ struct dc_link_settings store_settings = *link_setting;
3514
+
3515
+ link->preferred_link_setting = store_settings;
3516
+
3517
+ /* Retrain with preferred link settings only relevant for
3518
+ * DP signal type
3519
+ * Check for non-DP signal or if passive dongle present
3520
+ */
3521
+ if (!dc_is_dp_signal(link->connector_signal) ||
3522
+ link->dongle_max_pix_clk > 0)
3523
+ return;
3524
+
3525
+ for (i = 0; i < MAX_PIPES; i++) {
3526
+ pipe = &dc->current_state->res_ctx.pipe_ctx[i];
3527
+ if (pipe->stream && pipe->stream->link) {
3528
+ if (pipe->stream->link == link) {
3529
+ link_stream = pipe->stream;
3530
+ break;
3531
+ }
3532
+ }
3533
+ }
3534
+
3535
+ /* Stream not found */
3536
+ if (i == MAX_PIPES)
3537
+ return;
3538
+
3539
+ /* Cannot retrain link if backend is off */
3540
+ if (link_stream->dpms_off)
3541
+ return;
3542
+
3543
+ decide_link_settings(link_stream, &store_settings);
3544
+
3545
+ if ((store_settings.lane_count != LANE_COUNT_UNKNOWN) &&
3546
+ (store_settings.link_rate != LINK_RATE_UNKNOWN))
3547
+ dp_retrain_link_dp_test(link, &store_settings, false);
3548
+}
3549
+
3550
+void dc_link_set_preferred_training_settings(struct dc *dc,
3551
+ struct dc_link_settings *link_setting,
3552
+ struct dc_link_training_overrides *lt_overrides,
3553
+ struct dc_link *link,
3554
+ bool skip_immediate_retrain)
3555
+{
3556
+ if (lt_overrides != NULL)
3557
+ link->preferred_training_settings = *lt_overrides;
3558
+ else
3559
+ memset(&link->preferred_training_settings, 0, sizeof(link->preferred_training_settings));
3560
+
3561
+ if (link_setting != NULL) {
3562
+ link->preferred_link_setting = *link_setting;
3563
+ } else {
3564
+ link->preferred_link_setting.lane_count = LANE_COUNT_UNKNOWN;
3565
+ link->preferred_link_setting.link_rate = LINK_RATE_UNKNOWN;
3566
+ }
3567
+
3568
+ /* Retrain now, or wait until next stream update to apply */
3569
+ if (skip_immediate_retrain == false)
3570
+ dc_link_set_preferred_link_settings(dc, &link->preferred_link_setting, link);
3571
+}
3572
+
3573
+void dc_link_enable_hpd(const struct dc_link *link)
3574
+{
3575
+ dc_link_dp_enable_hpd(link);
3576
+}
3577
+
3578
+void dc_link_disable_hpd(const struct dc_link *link)
3579
+{
3580
+ dc_link_dp_disable_hpd(link);
3581
+}
3582
+
3583
+void dc_link_set_test_pattern(struct dc_link *link,
3584
+ enum dp_test_pattern test_pattern,
3585
+ enum dp_test_pattern_color_space test_pattern_color_space,
3586
+ const struct link_training_settings *p_link_settings,
3587
+ const unsigned char *p_custom_pattern,
3588
+ unsigned int cust_pattern_size)
3589
+{
3590
+ if (link != NULL)
3591
+ dc_link_dp_set_test_pattern(
3592
+ link,
3593
+ test_pattern,
3594
+ test_pattern_color_space,
3595
+ p_link_settings,
3596
+ p_custom_pattern,
3597
+ cust_pattern_size);
3598
+}
3599
+
3600
+uint32_t dc_link_bandwidth_kbps(
3601
+ const struct dc_link *link,
3602
+ const struct dc_link_settings *link_setting)
3603
+{
3604
+ uint32_t link_bw_kbps =
3605
+ link_setting->link_rate * LINK_RATE_REF_FREQ_IN_KHZ; /* bytes per sec */
3606
+
3607
+ link_bw_kbps *= 8; /* 8 bits per byte*/
3608
+ link_bw_kbps *= link_setting->lane_count;
3609
+
3610
+ if (dc_link_is_fec_supported(link) && !link->dc->debug.disable_fec) {
3611
+ /* Account for FEC overhead.
3612
+ * We have to do it based on caps,
3613
+ * and not based on FEC being set ready,
3614
+ * because FEC is set ready too late in
3615
+ * the process to correctly be picked up
3616
+ * by mode enumeration.
3617
+ *
3618
+ * There's enough zeros at the end of 'kbps'
3619
+ * that make the below operation 100% precise
3620
+ * for our purposes.
3621
+ * 'long long' makes it work even for HDMI 2.1
3622
+ * max bandwidth (and much, much bigger bandwidths
3623
+ * than that, actually).
3624
+ *
3625
+ * NOTE: Reducing link BW by 3% may not be precise
3626
+ * because it may be a stream BT that increases by 3%, and so
3627
+ * 1/1.03 = 0.970873 factor should have been used instead,
3628
+ * but the difference is minimal and is in a safe direction,
3629
+ * which all works well around potential ambiguity of DP 1.4a spec.
3630
+ */
3631
+ link_bw_kbps = mul_u64_u32_shr(BIT_ULL(32) * 970LL / 1000,
3632
+ link_bw_kbps, 32);
3633
+ }
3634
+
3635
+ return link_bw_kbps;
3636
+
3637
+}
3638
+
3639
+const struct dc_link_settings *dc_link_get_link_cap(
3640
+ const struct dc_link *link)
3641
+{
3642
+ if (link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN &&
3643
+ link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN)
3644
+ return &link->preferred_link_setting;
3645
+ return &link->verified_link_cap;
3646
+}
3647
+
3648
+void dc_link_overwrite_extended_receiver_cap(
3649
+ struct dc_link *link)
3650
+{
3651
+ dp_overwrite_extended_receiver_cap(link);
3652
+}
3653
+
3654
+bool dc_link_is_fec_supported(const struct dc_link *link)
3655
+{
3656
+ return (dc_is_dp_signal(link->connector_signal) &&
3657
+ link->link_enc->features.fec_supported &&
3658
+ link->dpcd_caps.fec_cap.bits.FEC_CAPABLE &&
3659
+ !IS_FPGA_MAXIMUS_DC(link->ctx->dce_environment));
3660
+}
3661
+