drm/amd/display: Decrease messaging about DP alt mode state to debug
[linux-2.6-block.git] / drivers / gpu / drm / amd / display / dc / core / dc_link.c
CommitLineData
4562236b
HW
1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
841d0023
SR
26#include <linux/slab.h>
27
4562236b 28#include "dm_services.h"
cdca3f21 29#include "atomfirmware.h"
4562236b
HW
30#include "dm_helpers.h"
31#include "dc.h"
4562236b
HW
32#include "grph_object_id.h"
33#include "gpio_service_interface.h"
34#include "core_status.h"
35#include "dc_link_dp.h"
d144b40a 36#include "link/link_dp_dpia.h"
a98cdd8c 37#include "link/link_ddc.h"
4562236b 38#include "link_hwss.h"
4370f72e 39#include "link.h"
7f93c1de 40#include "opp.h"
fb3466a4 41
4562236b
HW
42#include "link_encoder.h"
43#include "hw_sequencer.h"
44#include "resource.h"
6728b30c 45#include "abm.h"
4562236b 46#include "fixed31_32.h"
eaca91ee 47#include "dpcd_defs.h"
3548f073 48#include "dmcu.h"
dc88b4a6 49#include "hw/clk_mgr.h"
9dac88d8 50#include "dce/dmub_psr.h"
cdca3f21 51#include "dmub/dmub_srv.h"
d4caa72e 52#include "inc/hw/panel_cntl.h"
ede4f6da 53#include "inc/link_enc_cfg.h"
a28d0bac 54#include "link/link_dpcd.h"
5fed53c7 55#include "link/link_dp_trace.h"
4370f72e 56#include "link/link_hpd.h"
630168a9 57#include "link/link_dp_training.h"
94dfeaa4 58#include "link/link_dp_phy.h"
d5a43956 59#include "link/link_dp_capability.h"
4562236b 60
18b4f1a0
MS
61#include "dc/dcn30/dcn30_vpg.h"
62
5d4b05dd
BL
63#define DC_LOGGER_INIT(logger)
64
4562236b 65#define LINK_INFO(...) \
1296423b 66 DC_LOG_HW_HOTPLUG( \
4562236b
HW
67 __VA_ARGS__)
68
2f14bc89
CL
69#define RETIMER_REDRIVER_INFO(...) \
70 DC_LOG_RETIMER_REDRIVER( \
71 __VA_ARGS__)
4562236b
HW
72
73/*******************************************************************************
74 * Private functions
75 ******************************************************************************/
d9e32672 76static void dc_link_destruct(struct dc_link *link)
4562236b
HW
77{
78 int i;
79
621514aa 80 if (link->hpd_gpio) {
ac627caf
CH
81 dal_gpio_destroy_irq(&link->hpd_gpio);
82 link->hpd_gpio = NULL;
83 }
84
d0778ebf 85 if (link->ddc)
a98cdd8c 86 link_destroy_ddc_service(&link->ddc);
4562236b 87
d4caa72e
AK
88 if (link->panel_cntl)
89 link->panel_cntl->funcs->destroy(&link->panel_cntl);
9da3d050 90
e1f4328f 91 if (link->link_enc) {
f42ef862
JK
92 /* Update link encoder resource tracking variables. These are used for
93 * the dynamic assignment of link encoders to streams. Virtual links
94 * are not assigned encoder resources on creation.
e1f4328f 95 */
f42ef862
JK
96 if (link->link_id.id != CONNECTOR_ID_VIRTUAL) {
97 link->dc->res_pool->link_encoders[link->eng_id - ENGINE_ID_DIGA] = NULL;
98 link->dc->res_pool->dig_link_enc_count--;
99 }
4562236b 100 link->link_enc->funcs->destroy(&link->link_enc);
e1f4328f 101 }
4562236b 102
d0778ebf
HW
103 if (link->local_sink)
104 dc_sink_release(link->local_sink);
4562236b 105
d0778ebf
HW
106 for (i = 0; i < link->sink_count; ++i)
107 dc_sink_release(link->remote_sinks[i]);
4562236b
HW
108}
109
cf3a2627
JL
110bool dc_link_wait_for_t12(struct dc_link *link)
111{
112 if (link->connector_signal == SIGNAL_TYPE_EDP && link->dc->hwss.edp_wait_for_T12) {
113 link->dc->hwss.edp_wait_for_T12(link);
114
115 return true;
116 }
117
118 return false;
119}
120
2119aa17
DF
121/**
122 * dc_link_detect_sink() - Determine if there is a sink connected
123 *
ac492ec9 124 * @link: pointer to the dc link
2119aa17
DF
125 * @type: Returned connection type
126 * Does not detect downstream devices, such as MST sinks
127 * or display connected through active dongles
128 */
fbbdadf2 129bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type)
4562236b
HW
130{
131 uint32_t is_hpd_high = 0;
4562236b 132
11c3ee48
AD
133 if (link->connector_signal == SIGNAL_TYPE_LVDS) {
134 *type = dc_connection_single;
135 return true;
136 }
137
abe882a3
AK
138 if (link->connector_signal == SIGNAL_TYPE_EDP) {
139 /*in case it is not on*/
a8201902
LM
140 if (!link->dc->config.edp_no_power_sequencing)
141 link->dc->hwss.edp_power_control(link, true);
0a6414e7 142 link->dc->hwss.edp_wait_for_hpd_ready(link, true);
abe882a3 143 }
0a6414e7 144
99732e52
JK
145 /* Link may not have physical HPD pin. */
146 if (link->ep_type != DISPLAY_ENDPOINT_PHY) {
fc0b067d 147 if (link->is_hpd_pending || !dc_link_dpia_query_hpd_status(link))
99732e52 148 *type = dc_connection_none;
6ef86fa8
MS
149 else
150 *type = dc_connection_single;
99732e52
JK
151
152 return true;
153 }
154
4370f72e 155 if (!query_hpd_status(link, &is_hpd_high))
4562236b
HW
156 goto hpd_gpio_failure;
157
4562236b
HW
158 if (is_hpd_high) {
159 *type = dc_connection_single;
160 /* TODO: need to do the actual detection */
161 } else {
162 *type = dc_connection_none;
163 }
164
165 return true;
166
167hpd_gpio_failure:
168 return false;
169}
170
621514aa 171static enum ddc_transaction_type get_ddc_transaction_type(enum signal_type sink_signal)
4562236b
HW
172{
173 enum ddc_transaction_type transaction_type = DDC_TRANSACTION_TYPE_NONE;
174
175 switch (sink_signal) {
176 case SIGNAL_TYPE_DVI_SINGLE_LINK:
177 case SIGNAL_TYPE_DVI_DUAL_LINK:
178 case SIGNAL_TYPE_HDMI_TYPE_A:
179 case SIGNAL_TYPE_LVDS:
180 case SIGNAL_TYPE_RGB:
181 transaction_type = DDC_TRANSACTION_TYPE_I2C;
182 break;
183
184 case SIGNAL_TYPE_DISPLAY_PORT:
185 case SIGNAL_TYPE_EDP:
186 transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
187 break;
188
189 case SIGNAL_TYPE_DISPLAY_PORT_MST:
190 /* MST does not use I2COverAux, but there is the
191 * SPECIAL use case for "immediate dwnstrm device
21764099
MW
192 * access" (EPR#370830).
193 */
4562236b
HW
194 transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
195 break;
196
197 default:
198 break;
199 }
200
201 return transaction_type;
202}
203
621514aa
MW
204static enum signal_type get_basic_signal_type(struct graphics_object_id encoder,
205 struct graphics_object_id downstream)
4562236b
HW
206{
207 if (downstream.type == OBJECT_TYPE_CONNECTOR) {
208 switch (downstream.id) {
209 case CONNECTOR_ID_SINGLE_LINK_DVII:
210 switch (encoder.id) {
211 case ENCODER_ID_INTERNAL_DAC1:
212 case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
213 case ENCODER_ID_INTERNAL_DAC2:
214 case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
215 return SIGNAL_TYPE_RGB;
216 default:
217 return SIGNAL_TYPE_DVI_SINGLE_LINK;
218 }
219 break;
220 case CONNECTOR_ID_DUAL_LINK_DVII:
221 {
222 switch (encoder.id) {
223 case ENCODER_ID_INTERNAL_DAC1:
224 case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
225 case ENCODER_ID_INTERNAL_DAC2:
226 case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
227 return SIGNAL_TYPE_RGB;
228 default:
229 return SIGNAL_TYPE_DVI_DUAL_LINK;
230 }
231 }
232 break;
233 case CONNECTOR_ID_SINGLE_LINK_DVID:
234 return SIGNAL_TYPE_DVI_SINGLE_LINK;
235 case CONNECTOR_ID_DUAL_LINK_DVID:
236 return SIGNAL_TYPE_DVI_DUAL_LINK;
237 case CONNECTOR_ID_VGA:
238 return SIGNAL_TYPE_RGB;
239 case CONNECTOR_ID_HDMI_TYPE_A:
240 return SIGNAL_TYPE_HDMI_TYPE_A;
241 case CONNECTOR_ID_LVDS:
242 return SIGNAL_TYPE_LVDS;
243 case CONNECTOR_ID_DISPLAY_PORT:
8cb3c169 244 case CONNECTOR_ID_USBC:
4562236b
HW
245 return SIGNAL_TYPE_DISPLAY_PORT;
246 case CONNECTOR_ID_EDP:
247 return SIGNAL_TYPE_EDP;
248 default:
249 return SIGNAL_TYPE_NONE;
250 }
251 } else if (downstream.type == OBJECT_TYPE_ENCODER) {
252 switch (downstream.id) {
253 case ENCODER_ID_EXTERNAL_NUTMEG:
254 case ENCODER_ID_EXTERNAL_TRAVIS:
255 return SIGNAL_TYPE_DISPLAY_PORT;
256 default:
257 return SIGNAL_TYPE_NONE;
258 }
259 }
260
261 return SIGNAL_TYPE_NONE;
262}
263
ac492ec9 264/*
2119aa17
DF
265 * dc_link_is_dp_sink_present() - Check if there is a native DP
266 * or passive DP-HDMI dongle connected
4562236b 267 */
aac5db82 268bool dc_link_is_dp_sink_present(struct dc_link *link)
4562236b
HW
269{
270 enum gpio_result gpio_result;
271 uint32_t clock_pin = 0;
bd4905a9 272 uint8_t retry = 0;
4562236b
HW
273 struct ddc *ddc;
274
275 enum connector_id connector_id =
276 dal_graphics_object_id_get_connector_id(link->link_id);
277
278 bool present =
279 ((connector_id == CONNECTOR_ID_DISPLAY_PORT) ||
8cb3c169
ST
280 (connector_id == CONNECTOR_ID_EDP) ||
281 (connector_id == CONNECTOR_ID_USBC));
4562236b 282
a98cdd8c 283 ddc = get_ddc_pin(link->ddc);
4562236b
HW
284
285 if (!ddc) {
286 BREAK_TO_DEBUGGER();
287 return present;
288 }
289
290 /* Open GPIO and set it to I2C mode */
291 /* Note: this GpioMode_Input will be converted
292 * to GpioConfigType_I2cAuxDualMode in GPIO component,
21764099
MW
293 * which indicates we need additional delay
294 */
4562236b 295
621514aa
MW
296 if (dal_ddc_open(ddc, GPIO_MODE_INPUT,
297 GPIO_DDC_CONFIG_TYPE_MODE_I2C) != GPIO_RESULT_OK) {
8fb3a636 298 dal_ddc_close(ddc);
4562236b
HW
299
300 return present;
301 }
302
bd4905a9
PH
303 /*
304 * Read GPIO: DP sink is present if both clock and data pins are zero
305 *
306 * [W/A] plug-unplug DP cable, sometimes customer board has
307 * one short pulse on clk_pin(1V, < 1ms). DP will be config to HDMI/DVI
308 * then monitor can't br light up. Add retry 3 times
309 * But in real passive dongle, it need additional 3ms to detect
310 */
311 do {
312 gpio_result = dal_gpio_get_value(ddc->pin_clock, &clock_pin);
313 ASSERT(gpio_result == GPIO_RESULT_OK);
314 if (clock_pin)
315 udelay(1000);
316 else
317 break;
318 } while (retry++ < 3);
4562236b 319
4dfb0bad 320 present = (gpio_result == GPIO_RESULT_OK) && !clock_pin;
4562236b
HW
321
322 dal_ddc_close(ddc);
323
324 return present;
325}
326
327/*
328 * @brief
329 * Detect output sink type
330 */
621514aa
MW
331static enum signal_type link_detect_sink(struct dc_link *link,
332 enum dc_detect_reason reason)
4562236b 333{
99732e52
JK
334 enum signal_type result;
335 struct graphics_object_id enc_id;
336
337 if (link->is_dig_mapping_flexible)
338 enc_id = (struct graphics_object_id){.id = ENCODER_ID_UNKNOWN};
339 else
340 enc_id = link->link_enc->id;
341 result = get_basic_signal_type(enc_id, link->link_id);
342
343 /* Use basic signal type for link without physical connector. */
344 if (link->ep_type != DISPLAY_ENDPOINT_PHY)
345 return result;
4562236b
HW
346
347 /* Internal digital encoder will detect only dongles
21764099
MW
348 * that require digital signal
349 */
4562236b
HW
350
351 /* Detection mechanism is different
352 * for different native connectors.
353 * LVDS connector supports only LVDS signal;
354 * PCIE is a bus slot, the actual connector needs to be detected first;
355 * eDP connector supports only eDP signal;
21764099
MW
356 * HDMI should check straps for audio
357 */
4562236b
HW
358
359 /* PCIE detects the actual connector on add-on board */
50dc581a 360 if (link->link_id.id == CONNECTOR_ID_PCIE) {
4562236b 361 /* ZAZTODO implement PCIE add-on card detection */
50dc581a 362 }
4562236b
HW
363
364 switch (link->link_id.id) {
365 case CONNECTOR_ID_HDMI_TYPE_A: {
366 /* check audio support:
21764099
MW
367 * if native HDMI is not supported, switch to DVI
368 */
621514aa
MW
369 struct audio_support *aud_support =
370 &link->dc->res_pool->audio_support;
4562236b
HW
371
372 if (!aud_support->hdmi_audio_native)
373 if (link->link_id.id == CONNECTOR_ID_HDMI_TYPE_A)
374 result = SIGNAL_TYPE_DVI_SINGLE_LINK;
375 }
376 break;
8cb3c169
ST
377 case CONNECTOR_ID_DISPLAY_PORT:
378 case CONNECTOR_ID_USBC: {
8f38b66c
HW
379 /* DP HPD short pulse. Passive DP dongle will not
380 * have short pulse
381 */
382 if (reason != DETECT_REASON_HPDRX) {
383 /* Check whether DP signal detected: if not -
384 * we assume signal is DVI; it could be corrected
385 * to HDMI after dongle detection
386 */
aac5db82 387 if (!dm_helpers_is_dp_sink_present(link))
8f38b66c
HW
388 result = SIGNAL_TYPE_DVI_SINGLE_LINK;
389 }
4562236b
HW
390 }
391 break;
392 default:
393 break;
394 }
395
396 return result;
397}
398
621514aa
MW
399static enum signal_type decide_signal_from_strap_and_dongle_type(enum display_dongle_type dongle_type,
400 struct audio_support *audio_support)
4562236b
HW
401{
402 enum signal_type signal = SIGNAL_TYPE_NONE;
403
404 switch (dongle_type) {
405 case DISPLAY_DONGLE_DP_HDMI_DONGLE:
406 if (audio_support->hdmi_audio_on_dongle)
621514aa 407 signal = SIGNAL_TYPE_HDMI_TYPE_A;
4562236b
HW
408 else
409 signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
410 break;
411 case DISPLAY_DONGLE_DP_DVI_DONGLE:
412 signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
413 break;
414 case DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE:
415 if (audio_support->hdmi_audio_native)
416 signal = SIGNAL_TYPE_HDMI_TYPE_A;
417 else
418 signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
419 break;
420 default:
421 signal = SIGNAL_TYPE_NONE;
422 break;
423 }
424
425 return signal;
426}
427
a98cdd8c
WL
428static bool i2c_read(
429 struct ddc_service *ddc,
430 uint32_t address,
431 uint8_t *buffer,
432 uint32_t len)
433{
434 uint8_t offs_data = 0;
435 struct i2c_payload payloads[2] = {
436 {
437 .write = true,
438 .address = address,
439 .length = 1,
440 .data = &offs_data },
441 {
442 .write = false,
443 .address = address,
444 .length = len,
445 .data = buffer } };
446
447 struct i2c_command command = {
448 .payloads = payloads,
449 .number_of_payloads = 2,
450 .engine = DDC_I2C_COMMAND_ENGINE,
451 .speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
452
453 return dm_helpers_submit_i2c(
454 ddc->ctx,
455 ddc->link,
456 &command);
457}
458
459enum {
460 DP_SINK_CAP_SIZE =
461 DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV + 1
462};
463
464static void query_dp_dual_mode_adaptor(
465 struct ddc_service *ddc,
466 struct display_sink_capability *sink_cap)
467{
468 uint8_t i;
469 bool is_valid_hdmi_signature;
470 enum display_dongle_type *dongle = &sink_cap->dongle_type;
471 uint8_t type2_dongle_buf[DP_ADAPTOR_TYPE2_SIZE];
472 bool is_type2_dongle = false;
473 int retry_count = 2;
474 struct dp_hdmi_dongle_signature_data *dongle_signature;
475
476 /* Assume we have no valid DP passive dongle connected */
477 *dongle = DISPLAY_DONGLE_NONE;
478 sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK;
479
480 /* Read DP-HDMI dongle I2c (no response interpreted as DP-DVI dongle)*/
481 if (!i2c_read(
482 ddc,
483 DP_HDMI_DONGLE_ADDRESS,
484 type2_dongle_buf,
485 sizeof(type2_dongle_buf))) {
486 /* Passive HDMI dongles can sometimes fail here without retrying*/
487 while (retry_count > 0) {
488 if (i2c_read(ddc,
489 DP_HDMI_DONGLE_ADDRESS,
490 type2_dongle_buf,
491 sizeof(type2_dongle_buf)))
492 break;
493 retry_count--;
494 }
495 if (retry_count == 0) {
496 *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
497 sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
498
499 CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf),
500 "DP-DVI passive dongle %dMhz: ",
501 DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
502 return;
503 }
504 }
505
506 /* Check if Type 2 dongle.*/
507 if (type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_ID] == DP_ADAPTOR_TYPE2_ID)
508 is_type2_dongle = true;
509
510 dongle_signature =
511 (struct dp_hdmi_dongle_signature_data *)type2_dongle_buf;
512
513 is_valid_hdmi_signature = true;
514
515 /* Check EOT */
516 if (dongle_signature->eot != DP_HDMI_DONGLE_SIGNATURE_EOT) {
517 is_valid_hdmi_signature = false;
518 }
519
520 /* Check signature */
521 for (i = 0; i < sizeof(dongle_signature->id); ++i) {
522 /* If its not the right signature,
523 * skip mismatch in subversion byte.*/
524 if (dongle_signature->id[i] !=
525 dp_hdmi_dongle_signature_str[i] && i != 3) {
526
527 if (is_type2_dongle) {
528 is_valid_hdmi_signature = false;
529 break;
530 }
531
532 }
533 }
534
535 if (is_type2_dongle) {
536 uint32_t max_tmds_clk =
537 type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK];
538
539 max_tmds_clk = max_tmds_clk * 2 + max_tmds_clk / 2;
540
541 if (0 == max_tmds_clk ||
542 max_tmds_clk < DP_ADAPTOR_TYPE2_MIN_TMDS_CLK ||
543 max_tmds_clk > DP_ADAPTOR_TYPE2_MAX_TMDS_CLK) {
544 *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
545
546 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
547 sizeof(type2_dongle_buf),
548 "DP-DVI passive dongle %dMhz: ",
549 DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
550 } else {
551 if (is_valid_hdmi_signature == true) {
552 *dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
553
554 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
555 sizeof(type2_dongle_buf),
556 "Type 2 DP-HDMI passive dongle %dMhz: ",
557 max_tmds_clk);
558 } else {
559 *dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
560
561 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
562 sizeof(type2_dongle_buf),
563 "Type 2 DP-HDMI passive dongle (no signature) %dMhz: ",
564 max_tmds_clk);
565
566 }
567
568 /* Multiply by 1000 to convert to kHz. */
569 sink_cap->max_hdmi_pixel_clock =
570 max_tmds_clk * 1000;
571 }
572 sink_cap->is_dongle_type_one = false;
573
574 } else {
575 if (is_valid_hdmi_signature == true) {
576 *dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
577
578 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
579 sizeof(type2_dongle_buf),
580 "Type 1 DP-HDMI passive dongle %dMhz: ",
581 sink_cap->max_hdmi_pixel_clock / 1000);
582 } else {
583 *dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
584
585 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
586 sizeof(type2_dongle_buf),
587 "Type 1 DP-HDMI passive dongle (no signature) %dMhz: ",
588 sink_cap->max_hdmi_pixel_clock / 1000);
589 }
590 sink_cap->is_dongle_type_one = true;
591 }
592
593 return;
594}
595
621514aa
MW
596static enum signal_type dp_passive_dongle_detection(struct ddc_service *ddc,
597 struct display_sink_capability *sink_cap,
598 struct audio_support *audio_support)
4562236b 599{
a98cdd8c 600 query_dp_dual_mode_adaptor(ddc, sink_cap);
621514aa
MW
601
602 return decide_signal_from_strap_and_dongle_type(sink_cap->dongle_type,
603 audio_support);
4562236b
HW
604}
605
d0778ebf 606static void link_disconnect_sink(struct dc_link *link)
4562236b 607{
d0778ebf
HW
608 if (link->local_sink) {
609 dc_sink_release(link->local_sink);
610 link->local_sink = NULL;
4562236b
HW
611 }
612
613 link->dpcd_sink_count = 0;
1e9653a4 614 //link->dpcd_caps.dpcd_rev.raw = 0;
4562236b
HW
615}
616
eb815442
ST
617static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *link)
618{
619 dc_sink_release(link->local_sink);
620 link->local_sink = prev_sink;
621}
622
fe8db3bc 623#if defined(CONFIG_DRM_AMD_DC_HDCP)
0023b7ee 624bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal)
5f869379
BL
625{
626 bool ret = false;
627
0023b7ee 628 switch (signal) {
5f869379
BL
629 case SIGNAL_TYPE_DISPLAY_PORT:
630 case SIGNAL_TYPE_DISPLAY_PORT_MST:
631 ret = link->hdcp_caps.bcaps.bits.HDCP_CAPABLE;
632 break;
633 case SIGNAL_TYPE_DVI_SINGLE_LINK:
634 case SIGNAL_TYPE_DVI_DUAL_LINK:
635 case SIGNAL_TYPE_HDMI_TYPE_A:
636 /* HDMI doesn't tell us its HDCP(1.4) capability, so assume to always be capable,
637 * we can poll for bksv but some displays have an issue with this. Since its so rare
638 * for a display to not be 1.4 capable, this assumtion is ok
639 */
640 ret = true;
641 break;
642 default:
643 break;
644 }
645 return ret;
646}
647
0023b7ee 648bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal)
5f869379
BL
649{
650 bool ret = false;
651
0023b7ee 652 switch (signal) {
5f869379
BL
653 case SIGNAL_TYPE_DISPLAY_PORT:
654 case SIGNAL_TYPE_DISPLAY_PORT_MST:
655 ret = (link->hdcp_caps.bcaps.bits.HDCP_CAPABLE &&
656 link->hdcp_caps.rx_caps.fields.byte0.hdcp_capable &&
657 (link->hdcp_caps.rx_caps.fields.version == 0x2)) ? 1 : 0;
658 break;
659 case SIGNAL_TYPE_DVI_SINGLE_LINK:
660 case SIGNAL_TYPE_DVI_DUAL_LINK:
661 case SIGNAL_TYPE_HDMI_TYPE_A:
662 ret = (link->hdcp_caps.rx_caps.fields.version == 0x4) ? 1:0;
663 break;
664 default:
665 break;
666 }
667
668 return ret;
669}
670
fe8db3bc
BL
671static void query_hdcp_capability(enum signal_type signal, struct dc_link *link)
672{
673 struct hdcp_protection_message msg22;
674 struct hdcp_protection_message msg14;
675
676 memset(&msg22, 0, sizeof(struct hdcp_protection_message));
677 memset(&msg14, 0, sizeof(struct hdcp_protection_message));
678 memset(link->hdcp_caps.rx_caps.raw, 0,
679 sizeof(link->hdcp_caps.rx_caps.raw));
680
681 if ((link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
682 link->ddc->transaction_type ==
683 DDC_TRANSACTION_TYPE_I2C_OVER_AUX) ||
684 link->connector_signal == SIGNAL_TYPE_EDP) {
685 msg22.data = link->hdcp_caps.rx_caps.raw;
686 msg22.length = sizeof(link->hdcp_caps.rx_caps.raw);
687 msg22.msg_id = HDCP_MESSAGE_ID_RX_CAPS;
688 } else {
689 msg22.data = &link->hdcp_caps.rx_caps.fields.version;
690 msg22.length = sizeof(link->hdcp_caps.rx_caps.fields.version);
691 msg22.msg_id = HDCP_MESSAGE_ID_HDCP2VERSION;
692 }
693 msg22.version = HDCP_VERSION_22;
694 msg22.link = HDCP_LINK_PRIMARY;
695 msg22.max_retries = 5;
696 dc_process_hdcp_msg(signal, link, &msg22);
697
698 if (signal == SIGNAL_TYPE_DISPLAY_PORT || signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
fe8db3bc
BL
699 msg14.data = &link->hdcp_caps.bcaps.raw;
700 msg14.length = sizeof(link->hdcp_caps.bcaps.raw);
701 msg14.msg_id = HDCP_MESSAGE_ID_READ_BCAPS;
702 msg14.version = HDCP_VERSION_14;
703 msg14.link = HDCP_LINK_PRIMARY;
704 msg14.max_retries = 5;
705
4202ef47 706 dc_process_hdcp_msg(signal, link, &msg14);
fe8db3bc
BL
707 }
708
709}
710#endif
711
7f7652ee 712static void read_current_link_settings_on_detect(struct dc_link *link)
5b7c0d8d 713{
c78abac9 714 union lane_count_set lane_count_set = {0};
5b7c0d8d
AK
715 uint8_t link_bw_set;
716 uint8_t link_rate_set;
abe882a3
AK
717 uint32_t read_dpcd_retry_cnt = 10;
718 enum dc_status status = DC_ERROR_UNEXPECTED;
719 int i;
c78abac9 720 union max_down_spread max_down_spread = {0};
5b7c0d8d
AK
721
722 // Read DPCD 00101h to find out the number of lanes currently set
abe882a3 723 for (i = 0; i < read_dpcd_retry_cnt; i++) {
621514aa
MW
724 status = core_link_read_dpcd(link,
725 DP_LANE_COUNT_SET,
726 &lane_count_set.raw,
727 sizeof(lane_count_set));
abe882a3
AK
728 /* First DPCD read after VDD ON can fail if the particular board
729 * does not have HPD pin wired correctly. So if DPCD read fails,
730 * which it should never happen, retry a few times. Target worst
731 * case scenario of 80 ms.
732 */
733 if (status == DC_OK) {
621514aa
MW
734 link->cur_link_settings.lane_count =
735 lane_count_set.bits.LANE_COUNT_SET;
abe882a3
AK
736 break;
737 }
738
3e10f319 739 msleep(8);
abe882a3
AK
740 }
741
5b7c0d8d
AK
742 // Read DPCD 00100h to find if standard link rates are set
743 core_link_read_dpcd(link, DP_LINK_BW_SET,
621514aa 744 &link_bw_set, sizeof(link_bw_set));
5b7c0d8d
AK
745
746 if (link_bw_set == 0) {
7f7652ee
ML
747 if (link->connector_signal == SIGNAL_TYPE_EDP) {
748 /* If standard link rates are not being used,
749 * Read DPCD 00115h to find the edp link rate set used
750 */
751 core_link_read_dpcd(link, DP_LINK_RATE_SET,
621514aa 752 &link_rate_set, sizeof(link_rate_set));
7f7652ee
ML
753
754 // edp_supported_link_rates_count = 0 for DP
755 if (link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
756 link->cur_link_settings.link_rate =
621514aa 757 link->dpcd_caps.edp_supported_link_rates[link_rate_set];
7f7652ee
ML
758 link->cur_link_settings.link_rate_set = link_rate_set;
759 link->cur_link_settings.use_link_rate_set = true;
760 }
761 } else {
762 // Link Rate not found. Seamless boot may not work.
763 ASSERT(false);
5b7c0d8d
AK
764 }
765 } else {
766 link->cur_link_settings.link_rate = link_bw_set;
767 link->cur_link_settings.use_link_rate_set = false;
768 }
701c75ce
DL
769 // Read DPCD 00003h to find the max down spread.
770 core_link_read_dpcd(link, DP_MAX_DOWNSPREAD,
621514aa 771 &max_down_spread.raw, sizeof(max_down_spread));
701c75ce
DL
772 link->cur_link_settings.link_spread =
773 max_down_spread.bits.MAX_DOWN_SPREAD ?
774 LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
5b7c0d8d
AK
775}
776
5b2b2416
MW
777static bool detect_dp(struct dc_link *link,
778 struct display_sink_capability *sink_caps,
5b2b2416 779 enum dc_detect_reason reason)
4562236b 780{
8a58e25b 781 struct audio_support *audio_support = &link->dc->res_pool->audio_support;
5b2b2416 782
8f38b66c 783 sink_caps->signal = link_detect_sink(link, reason);
4562236b
HW
784 sink_caps->transaction_type =
785 get_ddc_transaction_type(sink_caps->signal);
786
787 if (sink_caps->transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
788 sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
cdb39798
YS
789 if (!detect_dp_sink_caps(link))
790 return false;
4562236b 791
c282d951 792 if (is_dp_branch_device(link))
36c9137b
DZ
793 /* DP SST branch */
794 link->type = dc_connection_sst_branch;
4562236b
HW
795 } else {
796 /* DP passive dongles */
d0778ebf 797 sink_caps->signal = dp_passive_dongle_detection(link->ddc,
5b2b2416
MW
798 sink_caps,
799 audio_support);
efbde23a 800 link->dpcd_caps.dongle_type = sink_caps->dongle_type;
4a897de1 801 link->dpcd_caps.is_dongle_type_one = sink_caps->is_dongle_type_one;
1e9653a4 802 link->dpcd_caps.dpcd_rev.raw = 0;
4562236b 803 }
cdb39798
YS
804
805 return true;
4562236b
HW
806}
807
eb815442
ST
808static bool is_same_edid(struct dc_edid *old_edid, struct dc_edid *new_edid)
809{
810 if (old_edid->length != new_edid->length)
811 return false;
812
813 if (new_edid->length == 0)
814 return false;
815
ded3491b
MW
816 return (memcmp(old_edid->raw_edid,
817 new_edid->raw_edid, new_edid->length) == 0);
eb815442
ST
818}
819
8ccf0e20 820static bool wait_for_entering_dp_alt_mode(struct dc_link *link)
b5b1f455 821{
b5b1f455
EY
822 /**
823 * something is terribly wrong if time out is > 200ms. (5Hz)
824 * 500 microseconds * 400 tries us 200 ms
825 **/
826 unsigned int sleep_time_in_microseconds = 500;
827 unsigned int tries_allowed = 400;
828 bool is_in_alt_mode;
829 unsigned long long enter_timestamp;
830 unsigned long long finish_timestamp;
831 unsigned long long time_taken_in_ns;
832 int tries_taken;
833
834 DC_LOGGER_INIT(link->ctx->logger);
835
ded3491b 836 if (!link->link_enc->funcs->is_in_alt_mode)
b5b1f455
EY
837 return true;
838
839 is_in_alt_mode = link->link_enc->funcs->is_in_alt_mode(link->link_enc);
bd314901 840 DC_LOG_DC("DP Alt mode state on HPD: %d\n", is_in_alt_mode);
b5b1f455
EY
841
842 if (is_in_alt_mode)
843 return true;
844
845 enter_timestamp = dm_get_timestamp(link->ctx);
846
847 for (tries_taken = 0; tries_taken < tries_allowed; tries_taken++) {
848 udelay(sleep_time_in_microseconds);
849 /* ask the link if alt mode is enabled, if so return ok */
850 if (link->link_enc->funcs->is_in_alt_mode(link->link_enc)) {
b5b1f455 851 finish_timestamp = dm_get_timestamp(link->ctx);
ded3491b
MW
852 time_taken_in_ns =
853 dm_get_elapse_time_in_ns(link->ctx,
854 finish_timestamp,
855 enter_timestamp);
b5b1f455 856 DC_LOG_WARNING("Alt mode entered finished after %llu ms\n",
b859c579 857 div_u64(time_taken_in_ns, 1000000));
b5b1f455
EY
858 return true;
859 }
b5b1f455
EY
860 }
861 finish_timestamp = dm_get_timestamp(link->ctx);
862 time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp,
863 enter_timestamp);
864 DC_LOG_WARNING("Alt mode has timed out after %llu ms\n",
ded3491b 865 div_u64(time_taken_in_ns, 1000000));
b5b1f455
EY
866 return false;
867}
868
c282d951
WL
869static void apply_dpia_mst_dsc_always_on_wa(struct dc_link *link)
870{
c282d951
WL
871 /* Apply work around for tunneled MST on certain USB4 docks. Always use DSC if dock
872 * reports DSC support.
873 */
874 if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
875 link->type == dc_connection_mst_branch &&
876 link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
31d64b82 877 link->dpcd_caps.branch_hw_revision == DP_BRANCH_HW_REV_20 &&
c282d951
WL
878 link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT &&
879 !link->dc->debug.dpia_debug.bits.disable_mst_dsc_work_around)
880 link->wa_flags.dpia_mst_dsc_always_on = true;
c282d951
WL
881}
882
883static void revert_dpia_mst_dsc_always_on_wa(struct dc_link *link)
884{
885 /* Disable work around which keeps DSC on for tunneled MST on certain USB4 docks. */
886 if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
887 link->wa_flags.dpia_mst_dsc_always_on = false;
888}
889
890static bool discover_dp_mst_topology(struct dc_link *link, enum dc_detect_reason reason)
891{
892 DC_LOGGER_INIT(link->ctx->logger);
893
894 LINK_INFO("link=%d, mst branch is now Connected\n",
895 link->link_index);
896
c282d951 897 link->type = dc_connection_mst_branch;
d3d42110
JX
898 apply_dpia_mst_dsc_always_on_wa(link);
899
c282d951
WL
900 dm_helpers_dp_update_branch_info(link->ctx, link);
901 if (dm_helpers_dp_mst_start_top_mgr(link->ctx,
b6500759 902 link, (reason == DETECT_REASON_BOOT || reason == DETECT_REASON_RESUMEFROMS3S4))) {
c282d951
WL
903 link_disconnect_sink(link);
904 } else {
905 link->type = dc_connection_sst_branch;
906 }
907
908 return link->type == dc_connection_mst_branch;
909}
910
aec4706b 911bool reset_cur_dp_mst_topology(struct dc_link *link)
c282d951
WL
912{
913 DC_LOGGER_INIT(link->ctx->logger);
914
915 LINK_INFO("link=%d, mst branch is now Disconnected\n",
916 link->link_index);
917
918 revert_dpia_mst_dsc_always_on_wa(link);
cc67aae1 919 return dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
c282d951
WL
920}
921
922static bool should_prepare_phy_clocks_for_link_verification(const struct dc *dc,
923 enum dc_detect_reason reason)
924{
925 int i;
926 bool can_apply_seamless_boot = false;
927
928 for (i = 0; i < dc->current_state->stream_count; i++) {
929 if (dc->current_state->streams[i]->apply_seamless_boot_optimization) {
930 can_apply_seamless_boot = true;
931 break;
932 }
933 }
934
935 return !can_apply_seamless_boot && reason != DETECT_REASON_BOOT;
936}
937
938static void prepare_phy_clocks_for_destructive_link_verification(const struct dc *dc)
939{
c282d951 940 dc_z10_restore(dc);
c282d951
WL
941 clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
942}
943
944static void restore_phy_clocks_for_destructive_link_verification(const struct dc *dc)
945{
946 clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
947}
948
949static void set_all_streams_dpms_off_for_link(struct dc_link *link)
950{
951 int i;
952 struct pipe_ctx *pipe_ctx;
953 struct dc_stream_update stream_update;
954 bool dpms_off = true;
2426d71c 955 struct link_resource link_res = {0};
c282d951
WL
956
957 memset(&stream_update, 0, sizeof(stream_update));
958 stream_update.dpms_off = &dpms_off;
959
960 for (i = 0; i < MAX_PIPES; i++) {
961 pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
962 if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
963 pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
964 stream_update.stream = pipe_ctx->stream;
965 dc_commit_updates_for_stream(link->ctx->dc, NULL, 0,
966 pipe_ctx->stream, &stream_update,
967 link->ctx->dc->current_state);
968 }
969 }
2426d71c
WL
970
971 /* link can be also enabled by vbios. In this case it is not recorded
972 * in pipe_ctx. Disable link phy here to make sure it is completely off
973 */
974 dp_disable_link_phy(link, &link_res, link->connector_signal);
c282d951
WL
975}
976
977static void verify_link_capability_destructive(struct dc_link *link,
978 struct dc_sink *sink,
979 enum dc_detect_reason reason)
980{
c282d951
WL
981 bool should_prepare_phy_clocks =
982 should_prepare_phy_clocks_for_link_verification(link->dc, reason);
983
984 if (should_prepare_phy_clocks)
985 prepare_phy_clocks_for_destructive_link_verification(link->dc);
986
c282d951
WL
987 if (dc_is_dp_signal(link->local_sink->sink_signal)) {
988 struct dc_link_settings known_limit_link_setting =
989 dp_get_max_link_cap(link);
c282d951 990 set_all_streams_dpms_off_for_link(link);
c282d951 991 dp_verify_link_cap_with_retries(
2426d71c 992 link, &known_limit_link_setting,
c282d951
WL
993 LINK_TRAINING_MAX_VERIFY_RETRY);
994 } else {
995 ASSERT(0);
996 }
997
998 if (should_prepare_phy_clocks)
999 restore_phy_clocks_for_destructive_link_verification(link->dc);
1000}
1001
1002static void verify_link_capability_non_destructive(struct dc_link *link)
1003{
1004 if (dc_is_dp_signal(link->local_sink->sink_signal)) {
1005 if (dc_is_embedded_signal(link->local_sink->sink_signal) ||
1006 link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
1007 /* TODO - should we check link encoder's max link caps here?
1008 * How do we know which link encoder to check from?
1009 */
1010 link->verified_link_cap = link->reported_link_cap;
1011 else
1012 link->verified_link_cap = dp_get_max_link_cap(link);
1013 }
1014}
1015
1016static bool should_verify_link_capability_destructively(struct dc_link *link,
1017 enum dc_detect_reason reason)
1018{
1019 bool destrictive = false;
1020 struct dc_link_settings max_link_cap;
1021 bool is_link_enc_unavailable = link->link_enc &&
1022 link->dc->res_pool->funcs->link_encs_assign &&
1023 !link_enc_cfg_is_link_enc_avail(
1024 link->ctx->dc,
1025 link->link_enc->preferred_engine,
1026 link);
1027
1028 if (dc_is_dp_signal(link->local_sink->sink_signal)) {
1029 max_link_cap = dp_get_max_link_cap(link);
1030 destrictive = true;
1031
1032 if (link->dc->debug.skip_detection_link_training ||
1033 dc_is_embedded_signal(link->local_sink->sink_signal) ||
1034 link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
1035 destrictive = false;
d5a43956 1036 } else if (link_dp_get_encoding_format(&max_link_cap) ==
c282d951
WL
1037 DP_8b_10b_ENCODING) {
1038 if (link->dpcd_caps.is_mst_capable ||
1039 is_link_enc_unavailable) {
1040 destrictive = false;
1041 }
1042 }
a572f705 1043 }
c282d951
WL
1044
1045 return destrictive;
1046}
1047
1048static void verify_link_capability(struct dc_link *link, struct dc_sink *sink,
1049 enum dc_detect_reason reason)
1050{
1051 if (should_verify_link_capability_destructively(link, reason))
1052 verify_link_capability_destructive(link, sink, reason);
1053 else
1054 verify_link_capability_non_destructive(link);
1055}
1056
1057
1058/**
1059 * detect_link_and_local_sink() - Detect if a sink is attached to a given link
2119aa17
DF
1060 *
1061 * link->local_sink is created or destroyed as needed.
1062 *
c282d951 1063 * This does not create remote sinks.
2119aa17 1064 */
c282d951 1065static bool detect_link_and_local_sink(struct dc_link *link,
dd80ad9b 1066 enum dc_detect_reason reason)
4562236b 1067{
4562236b
HW
1068 struct dc_sink_init_data sink_init_data = { 0 };
1069 struct display_sink_capability sink_caps = { 0 };
7335d956 1070 uint32_t i;
4562236b
HW
1071 bool converter_disable_audio = false;
1072 struct audio_support *aud_support = &link->dc->res_pool->audio_support;
eb815442 1073 bool same_edid = false;
4562236b
HW
1074 enum dc_edid_status edid_status;
1075 struct dc_context *dc_ctx = link->ctx;
a8201902 1076 struct dc *dc = dc_ctx->dc;
533ed6c7 1077 struct dc_sink *sink = NULL;
eb815442
ST
1078 struct dc_sink *prev_sink = NULL;
1079 struct dpcd_caps prev_dpcd_caps;
4562236b 1080 enum dc_connection_type new_connection_type = dc_connection_none;
c797ede0 1081 const uint32_t post_oui_delay = 30; // 30ms
9ae1b27f 1082
5d4b05dd 1083 DC_LOGGER_INIT(link->ctx->logger);
248cbed6
EB
1084
1085 if (dc_is_virtual_signal(link->connector_signal))
4562236b
HW
1086 return false;
1087
5ab991ba
YLC
1088 if (((link->connector_signal == SIGNAL_TYPE_LVDS ||
1089 link->connector_signal == SIGNAL_TYPE_EDP) &&
1090 (!link->dc->config.allow_edp_hotplug_detection)) &&
1091 link->local_sink) {
96577cf8 1092 // need to re-write OUI and brightness in resume case
83a3766b
RM
1093 if (link->connector_signal == SIGNAL_TYPE_EDP &&
1094 (link->dpcd_sink_ext_caps.bits.oled == 1)) {
96577cf8 1095 dpcd_set_source_specific_data(link);
c797ede0 1096 msleep(post_oui_delay);
ded3491b
MW
1097 dc_link_set_default_brightness_aux(link);
1098 //TODO: use cached
96577cf8
HW
1099 }
1100
abe882a3 1101 return true;
96577cf8 1102 }
abe882a3 1103
ded3491b 1104 if (!dc_link_detect_sink(link, &new_connection_type)) {
4562236b
HW
1105 BREAK_TO_DEBUGGER();
1106 return false;
1107 }
1108
eb815442 1109 prev_sink = link->local_sink;
ded3491b 1110 if (prev_sink) {
eb815442
ST
1111 dc_sink_retain(prev_sink);
1112 memcpy(&prev_dpcd_caps, &link->dpcd_caps, sizeof(struct dpcd_caps));
1113 }
dcf298c3 1114
ded3491b 1115 link_disconnect_sink(link);
4562236b 1116 if (new_connection_type != dc_connection_none) {
d0778ebf 1117 link->type = new_connection_type;
eed928dc 1118 link->link_state_valid = false;
4562236b
HW
1119
1120 /* From Disconnected-to-Connected. */
d0778ebf 1121 switch (link->connector_signal) {
4562236b
HW
1122 case SIGNAL_TYPE_HDMI_TYPE_A: {
1123 sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
1124 if (aud_support->hdmi_audio_native)
1125 sink_caps.signal = SIGNAL_TYPE_HDMI_TYPE_A;
1126 else
1127 sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
1128 break;
1129 }
1130
1131 case SIGNAL_TYPE_DVI_SINGLE_LINK: {
1132 sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
1133 sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
1134 break;
1135 }
1136
1137 case SIGNAL_TYPE_DVI_DUAL_LINK: {
1138 sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
1139 sink_caps.signal = SIGNAL_TYPE_DVI_DUAL_LINK;
1140 break;
1141 }
1142
11c3ee48
AD
1143 case SIGNAL_TYPE_LVDS: {
1144 sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
1145 sink_caps.signal = SIGNAL_TYPE_LVDS;
1146 break;
1147 }
1148
4562236b 1149 case SIGNAL_TYPE_EDP: {
96577cf8
HW
1150 read_current_link_settings_on_detect(link);
1151
4654a2f7 1152 detect_edp_sink_caps(link);
5d593d68 1153 read_current_link_settings_on_detect(link);
a8201902
LM
1154
1155 /* Disable power sequence on MIPI panel + converter
1156 */
1157 if (dc->config.enable_mipi_converter_optimization &&
1158 dc_ctx->dce_version == DCN_VERSION_3_01 &&
1159 link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_0022B9 &&
1160 memcmp(&link->dpcd_caps.branch_dev_name, DP_SINK_BRANCH_DEV_NAME_7580,
06f2f777 1161 sizeof(link->dpcd_caps.branch_dev_name)) == 0) {
a8201902
LM
1162 dc->config.edp_no_power_sequencing = true;
1163
06f2f777
SJK
1164 if (!link->dpcd_caps.set_power_state_capable_edp)
1165 link->wa_flags.dp_keep_receiver_powered = true;
1166 }
1167
7f7652ee 1168 sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
4562236b
HW
1169 sink_caps.signal = SIGNAL_TYPE_EDP;
1170 break;
1171 }
1172
1173 case SIGNAL_TYPE_DISPLAY_PORT: {
b5b1f455 1174 /* wa HPD high coming too early*/
99732e52
JK
1175 if (link->ep_type == DISPLAY_ENDPOINT_PHY &&
1176 link->link_enc->features.flags.bits.DP_IS_USB_C == 1) {
b5b1f455 1177 /* if alt mode times out, return false */
8ccf0e20 1178 if (!wait_for_entering_dp_alt_mode(link))
b5b1f455 1179 return false;
b5b1f455
EY
1180 }
1181
8a58e25b 1182 if (!detect_dp(link, &sink_caps, reason)) {
ded3491b 1183 if (prev_sink)
eb815442 1184 dc_sink_release(prev_sink);
cdb39798 1185 return false;
eb815442 1186 }
4562236b 1187
36c9137b
DZ
1188 /* Active SST downstream branch device unplug*/
1189 if (link->type == dc_connection_sst_branch &&
ded3491b
MW
1190 link->dpcd_caps.sink_count.bits.SINK_COUNT == 0) {
1191 if (prev_sink)
80adaebd 1192 /* Downstream unplug */
eb815442 1193 dc_sink_release(prev_sink);
4562236b 1194 return true;
eb815442 1195 }
4562236b 1196
8a58e25b
WL
1197 /* disable audio for non DP to HDMI active sst converter */
1198 if (link->type == dc_connection_sst_branch &&
1199 is_dp_active_dongle(link) &&
1200 (link->dpcd_caps.dongle_type !=
1201 DISPLAY_DONGLE_DP_HDMI_CONVERTER))
1202 converter_disable_audio = true;
4562236b
HW
1203 break;
1204 }
1205
1206 default:
1207 DC_ERROR("Invalid connector type! signal:%d\n",
ded3491b
MW
1208 link->connector_signal);
1209 if (prev_sink)
eb815442 1210 dc_sink_release(prev_sink);
4562236b
HW
1211 return false;
1212 } /* switch() */
1213
1214 if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
ded3491b
MW
1215 link->dpcd_sink_count =
1216 link->dpcd_caps.sink_count.bits.SINK_COUNT;
2a0b4d85
MT
1217 else
1218 link->dpcd_sink_count = 1;
4562236b 1219
a98cdd8c 1220 set_ddc_transaction_type(link->ddc,
ded3491b 1221 sink_caps.transaction_type);
4562236b 1222
ded3491b 1223 link->aux_mode =
a98cdd8c 1224 link_is_in_aux_transaction_mode(link->ddc);
7c7f5b15 1225
d0778ebf 1226 sink_init_data.link = link;
4562236b 1227 sink_init_data.sink_signal = sink_caps.signal;
4562236b 1228
7d58e721
MT
1229 sink = dc_sink_create(&sink_init_data);
1230 if (!sink) {
1231 DC_ERROR("Failed to create sink!\n");
ded3491b 1232 if (prev_sink)
eb815442 1233 dc_sink_release(prev_sink);
7d58e721
MT
1234 return false;
1235 }
4562236b 1236
ceb3dbb4 1237 sink->link->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock;
dcf298c3 1238 sink->converter_disable_audio = converter_disable_audio;
7d58e721 1239
dcd5fb82 1240 /* dc_sink_create returns a new reference */
dcf298c3 1241 link->local_sink = sink;
4562236b 1242
ded3491b
MW
1243 edid_status = dm_helpers_read_local_edid(link->ctx,
1244 link, sink);
4562236b
HW
1245
1246 switch (edid_status) {
1247 case EDID_BAD_CHECKSUM:
1296423b 1248 DC_LOG_ERROR("EDID checksum invalid.\n");
4562236b 1249 break;
906fbba2
DZ
1250 case EDID_PARTIAL_VALID:
1251 DC_LOG_ERROR("Partial EDID valid, abandon invalid blocks.\n");
1252 break;
4562236b 1253 case EDID_NO_RESPONSE:
1296423b 1254 DC_LOG_ERROR("No EDID read.\n");
01dc285d
HW
1255 /*
1256 * Abort detection for non-DP connectors if we have
1257 * no EDID
1258 *
1259 * DP needs to report as connected if HDP is high
1260 * even if we have no EDID in order to go to
1261 * fail-safe mode
1262 */
16196776 1263 if (dc_is_hdmi_signal(link->connector_signal) ||
219097df 1264 dc_is_dvi_signal(link->connector_signal)) {
ded3491b 1265 if (prev_sink)
219097df
S
1266 dc_sink_release(prev_sink);
1267
01dc285d 1268 return false;
219097df 1269 }
10a9accd
I
1270
1271 if (link->type == dc_connection_sst_branch &&
1272 link->dpcd_caps.dongle_type ==
1273 DISPLAY_DONGLE_DP_VGA_CONVERTER &&
1274 reason == DETECT_REASON_HPDRX) {
1275 /* Abort detection for DP-VGA adapters when EDID
1276 * can't be read and detection reason is VGA-side
1277 * hotplug
1278 */
1279 if (prev_sink)
1280 dc_sink_release(prev_sink);
1281 link_disconnect_sink(link);
1282
1283 return true;
1284 }
1285
910e834d 1286 break;
4562236b
HW
1287 default:
1288 break;
1289 }
1290
eb815442 1291 // Check if edid is the same
ded3491b
MW
1292 if ((prev_sink) &&
1293 (edid_status == EDID_THE_SAME || edid_status == EDID_OK))
1294 same_edid = is_same_edid(&prev_sink->dc_edid,
1295 &sink->dc_edid);
eb815442 1296
5fbdb1f3 1297 if (sink->edid_caps.panel_patch.skip_scdc_overwrite)
a760fc1b
ML
1298 link->ctx->dc->debug.hdmi20_disable = true;
1299
0301ccba 1300 if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
ded3491b
MW
1301 sink_caps.transaction_type ==
1302 DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
0301ccba 1303 /*
1304 * TODO debug why Dell 2413 doesn't like
1305 * two link trainings
1306 */
fe8db3bc
BL
1307#if defined(CONFIG_DRM_AMD_DC_HDCP)
1308 query_hdcp_capability(sink->sink_signal, link);
1309#endif
0301ccba 1310 } else {
1311 // If edid is the same, then discard new sink and revert back to original sink
1312 if (same_edid) {
1313 link_disconnect_remap(prev_sink, link);
1314 sink = prev_sink;
1315 prev_sink = NULL;
0301ccba 1316 }
fe8db3bc
BL
1317#if defined(CONFIG_DRM_AMD_DC_HDCP)
1318 query_hdcp_capability(sink->sink_signal, link);
1319#endif
eb815442 1320 }
4562236b 1321
0301ccba 1322 /* HDMI-DVI Dongle */
1323 if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
ded3491b 1324 !sink->edid_caps.edid_hdmi)
0301ccba 1325 sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
1326
5fed53c7
LHM
1327 if (link->local_sink && dc_is_dp_signal(sink_caps.signal))
1328 dp_trace_init(link);
1329
4562236b 1330 /* Connectivity log: detection */
a634913e 1331 for (i = 0; i < sink->dc_edid.length / DC_EDID_BLOCK_SIZE; i++) {
4562236b 1332 CONN_DATA_DETECT(link,
ded3491b
MW
1333 &sink->dc_edid.raw_edid[i * DC_EDID_BLOCK_SIZE],
1334 DC_EDID_BLOCK_SIZE,
1335 "%s: [Block %d] ", sink->edid_caps.display_name, i);
4562236b
HW
1336 }
1337
1296423b 1338 DC_LOG_DETECTION_EDID_PARSER("%s: "
4562236b
HW
1339 "manufacturer_id = %X, "
1340 "product_id = %X, "
1341 "serial_number = %X, "
1342 "manufacture_week = %d, "
1343 "manufacture_year = %d, "
1344 "display_name = %s, "
1345 "speaker_flag = %d, "
1346 "audio_mode_count = %d\n",
1347 __func__,
b73a22d3
HW
1348 sink->edid_caps.manufacturer_id,
1349 sink->edid_caps.product_id,
1350 sink->edid_caps.serial_number,
1351 sink->edid_caps.manufacture_week,
1352 sink->edid_caps.manufacture_year,
1353 sink->edid_caps.display_name,
1354 sink->edid_caps.speaker_flags,
1355 sink->edid_caps.audio_mode_count);
1356
1357 for (i = 0; i < sink->edid_caps.audio_mode_count; i++) {
1296423b 1358 DC_LOG_DETECTION_EDID_PARSER("%s: mode number = %d, "
4562236b
HW
1359 "format_code = %d, "
1360 "channel_count = %d, "
1361 "sample_rate = %d, "
1362 "sample_size = %d\n",
1363 __func__,
1364 i,
b73a22d3
HW
1365 sink->edid_caps.audio_modes[i].format_code,
1366 sink->edid_caps.audio_modes[i].channel_count,
1367 sink->edid_caps.audio_modes[i].sample_rate,
1368 sink->edid_caps.audio_modes[i].sample_size);
4562236b 1369 }
c17a34e0
IC
1370
1371 if (link->connector_signal == SIGNAL_TYPE_EDP) {
1178ac68
IC
1372 /* Init dc_panel_config by HW config */
1373 if (dc_ctx->dc->res_pool->funcs->get_panel_config_defaults)
1374 dc_ctx->dc->res_pool->funcs->get_panel_config_defaults(&link->panel_config);
1375 /* Pickup base DM settings */
eccff6cd 1376 dm_helpers_init_panel_settings(dc_ctx, &link->panel_config, sink);
c17a34e0
IC
1377 // Override dc_panel_config if system has specific settings
1378 dm_helpers_override_panel_settings(dc_ctx, &link->panel_config);
1379 }
1380
4562236b
HW
1381 } else {
1382 /* From Connected-to-Disconnected. */
dcf298c3
WL
1383 link->type = dc_connection_none;
1384 sink_caps.signal = SIGNAL_TYPE_NONE;
233d87a5
ST
1385 /* When we unplug a passive DP-HDMI dongle connection, dongle_max_pix_clk
1386 * is not cleared. If we emulate a DP signal on this connection, it thinks
1387 * the dongle is still there and limits the number of modes we can emulate.
1388 * Clear dongle_max_pix_clk on disconnect to fix this
1389 */
1390 link->dongle_max_pix_clk = 0;
4a3ad932 1391
c595fb05 1392 dc_link_clear_dprx_states(link);
5fed53c7 1393 dp_trace_reset(link);
4562236b
HW
1394 }
1395
8a58e25b 1396 LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p edid same=%d\n",
ded3491b
MW
1397 link->link_index, sink,
1398 (sink_caps.signal ==
1399 SIGNAL_TYPE_NONE ? "Disconnected" : "Connected"),
8a58e25b 1400 prev_sink, same_edid);
eb815442 1401
ded3491b 1402 if (prev_sink)
eb815442 1403 dc_sink_release(prev_sink);
4562236b
HW
1404
1405 return true;
9ae1b27f
JG
1406}
1407
1408bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
1409{
c282d951 1410 bool is_local_sink_detect_success;
87e298d6 1411 bool is_delegated_to_mst_top_mgr = false;
c282d951 1412 enum dc_connection_type pre_link_type = link->type;
47c02af7 1413
c282d951 1414 is_local_sink_detect_success = detect_link_and_local_sink(link, reason);
9ae1b27f 1415
c282d951
WL
1416 if (is_local_sink_detect_success && link->local_sink)
1417 verify_link_capability(link, link->local_sink, reason);
9ae1b27f 1418
c282d951
WL
1419 if (is_local_sink_detect_success && link->local_sink &&
1420 dc_is_dp_signal(link->local_sink->sink_signal) &&
1421 link->dpcd_caps.is_mst_capable)
87e298d6 1422 is_delegated_to_mst_top_mgr = discover_dp_mst_topology(link, reason);
9ae1b27f 1423
c282d951
WL
1424 if (is_local_sink_detect_success &&
1425 pre_link_type == dc_connection_mst_branch &&
1426 link->type != dc_connection_mst_branch)
87e298d6 1427 is_delegated_to_mst_top_mgr = reset_cur_dp_mst_topology(link);
9ae1b27f 1428
87e298d6 1429 return is_local_sink_detect_success && !is_delegated_to_mst_top_mgr;
4562236b
HW
1430}
1431
d0778ebf 1432static enum channel_id get_ddc_line(struct dc_link *link)
4562236b
HW
1433{
1434 struct ddc *ddc;
f69e98a9
ST
1435 enum channel_id channel;
1436
1437 channel = CHANNEL_ID_UNKNOWN;
4562236b 1438
a98cdd8c 1439 ddc = get_ddc_pin(link->ddc);
4562236b
HW
1440
1441 if (ddc) {
1442 switch (dal_ddc_get_line(ddc)) {
1443 case GPIO_DDC_LINE_DDC1:
1444 channel = CHANNEL_ID_DDC1;
1445 break;
1446 case GPIO_DDC_LINE_DDC2:
1447 channel = CHANNEL_ID_DDC2;
1448 break;
1449 case GPIO_DDC_LINE_DDC3:
1450 channel = CHANNEL_ID_DDC3;
1451 break;
1452 case GPIO_DDC_LINE_DDC4:
1453 channel = CHANNEL_ID_DDC4;
1454 break;
1455 case GPIO_DDC_LINE_DDC5:
1456 channel = CHANNEL_ID_DDC5;
1457 break;
1458 case GPIO_DDC_LINE_DDC6:
1459 channel = CHANNEL_ID_DDC6;
1460 break;
1461 case GPIO_DDC_LINE_DDC_VGA:
1462 channel = CHANNEL_ID_DDC_VGA;
1463 break;
1464 case GPIO_DDC_LINE_I2C_PAD:
1465 channel = CHANNEL_ID_I2C_PAD;
1466 break;
1467 default:
1468 BREAK_TO_DEBUGGER();
1469 break;
1470 }
1471 }
1472
1473 return channel;
1474}
1475
9ec420d8 1476static enum transmitter translate_encoder_to_transmitter(struct graphics_object_id encoder)
4562236b
HW
1477{
1478 switch (encoder.id) {
1479 case ENCODER_ID_INTERNAL_UNIPHY:
1480 switch (encoder.enum_id) {
1481 case ENUM_ID_1:
1482 return TRANSMITTER_UNIPHY_A;
1483 case ENUM_ID_2:
1484 return TRANSMITTER_UNIPHY_B;
1485 default:
1486 return TRANSMITTER_UNKNOWN;
1487 }
1488 break;
1489 case ENCODER_ID_INTERNAL_UNIPHY1:
1490 switch (encoder.enum_id) {
1491 case ENUM_ID_1:
1492 return TRANSMITTER_UNIPHY_C;
1493 case ENUM_ID_2:
1494 return TRANSMITTER_UNIPHY_D;
1495 default:
1496 return TRANSMITTER_UNKNOWN;
1497 }
1498 break;
1499 case ENCODER_ID_INTERNAL_UNIPHY2:
1500 switch (encoder.enum_id) {
1501 case ENUM_ID_1:
1502 return TRANSMITTER_UNIPHY_E;
1503 case ENUM_ID_2:
1504 return TRANSMITTER_UNIPHY_F;
1505 default:
1506 return TRANSMITTER_UNKNOWN;
1507 }
1508 break;
1509 case ENCODER_ID_INTERNAL_UNIPHY3:
1510 switch (encoder.enum_id) {
1511 case ENUM_ID_1:
1512 return TRANSMITTER_UNIPHY_G;
1513 default:
1514 return TRANSMITTER_UNKNOWN;
1515 }
1516 break;
1517 case ENCODER_ID_EXTERNAL_NUTMEG:
1518 switch (encoder.enum_id) {
1519 case ENUM_ID_1:
1520 return TRANSMITTER_NUTMEG_CRT;
1521 default:
1522 return TRANSMITTER_UNKNOWN;
1523 }
1524 break;
1525 case ENCODER_ID_EXTERNAL_TRAVIS:
1526 switch (encoder.enum_id) {
1527 case ENUM_ID_1:
1528 return TRANSMITTER_TRAVIS_CRT;
1529 case ENUM_ID_2:
1530 return TRANSMITTER_TRAVIS_LCD;
1531 default:
1532 return TRANSMITTER_UNKNOWN;
1533 }
1534 break;
1535 default:
1536 return TRANSMITTER_UNKNOWN;
1537 }
1538}
1539
9fa0fb77
MS
1540static bool dc_link_construct_legacy(struct dc_link *link,
1541 const struct link_init_data *init_params)
4562236b
HW
1542{
1543 uint8_t i;
6bad8e4a 1544 struct ddc_service_init_data ddc_service_init_data = { 0 };
4562236b
HW
1545 struct dc_context *dc_ctx = init_params->ctx;
1546 struct encoder_init_data enc_init_data = { 0 };
d4caa72e 1547 struct panel_cntl_init_data panel_cntl_init_data = { 0 };
3a00c042 1548 struct integrated_info *info;
4562236b
HW
1549 struct dc_bios *bios = init_params->dc->ctx->dc_bios;
1550 const struct dc_vbios_funcs *bp_funcs = bios->funcs;
c85ef99a 1551 struct bp_disp_connector_caps_info disp_connect_caps_info = { 0 };
9ec420d8 1552
5d4b05dd 1553 DC_LOGGER_INIT(dc_ctx->logger);
4562236b 1554
b4423a3d 1555 info = kzalloc(sizeof(*info), GFP_KERNEL);
3a00c042
LJ
1556 if (!info)
1557 goto create_fail;
1558
d0778ebf
HW
1559 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
1560 link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID;
4562236b
HW
1561
1562 link->link_status.dpcd_caps = &link->dpcd_caps;
1563
1564 link->dc = init_params->dc;
1565 link->ctx = dc_ctx;
d0778ebf 1566 link->link_index = init_params->link_index;
4562236b 1567
9ec420d8
MW
1568 memset(&link->preferred_training_settings, 0,
1569 sizeof(struct dc_link_training_overrides));
1570 memset(&link->preferred_link_setting, 0,
1571 sizeof(struct dc_link_settings));
e0a6440a 1572
9ec420d8
MW
1573 link->link_id =
1574 bios->funcs->get_connector_id(bios, init_params->connector_index);
fb7b11e1 1575
f42ef862
JK
1576 link->ep_type = DISPLAY_ENDPOINT_PHY;
1577
64ff0882 1578 DC_LOG_DC("BIOS object table - link_id: %d", link->link_id.id);
c85ef99a
YS
1579
1580 if (bios->funcs->get_disp_connector_caps_info) {
1581 bios->funcs->get_disp_connector_caps_info(bios, link->link_id, &disp_connect_caps_info);
1582 link->is_internal_display = disp_connect_caps_info.INTERNAL_DISPLAY;
64ff0882 1583 DC_LOG_DC("BIOS object table - is_internal_display: %d", link->is_internal_display);
c85ef99a
YS
1584 }
1585
4562236b 1586 if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
acbf7faa 1587 dm_output_to_console("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
9ec420d8
MW
1588 __func__, init_params->connector_index,
1589 link->link_id.type, OBJECT_TYPE_CONNECTOR);
4562236b
HW
1590 goto create_fail;
1591 }
1592
66b198ff
DL
1593 if (link->dc->res_pool->funcs->link_init)
1594 link->dc->res_pool->funcs->link_init(link);
1595
4370f72e 1596 link->hpd_gpio = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id,
9ec420d8 1597 link->ctx->gpio_service);
64ff0882 1598
9ec420d8 1599 if (link->hpd_gpio) {
04612213
HW
1600 dal_gpio_open(link->hpd_gpio, GPIO_MODE_INTERRUPT);
1601 dal_gpio_unlock_pin(link->hpd_gpio);
ac627caf 1602 link->irq_source_hpd = dal_irq_get_source(link->hpd_gpio);
64ff0882
GS
1603
1604 DC_LOG_DC("BIOS object table - hpd_gpio id: %d", link->hpd_gpio->id);
1605 DC_LOG_DC("BIOS object table - hpd_gpio en: %d", link->hpd_gpio->en);
04612213 1606 }
4562236b
HW
1607
1608 switch (link->link_id.id) {
1609 case CONNECTOR_ID_HDMI_TYPE_A:
d0778ebf 1610 link->connector_signal = SIGNAL_TYPE_HDMI_TYPE_A;
4562236b
HW
1611
1612 break;
1613 case CONNECTOR_ID_SINGLE_LINK_DVID:
1614 case CONNECTOR_ID_SINGLE_LINK_DVII:
d0778ebf 1615 link->connector_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
4562236b
HW
1616 break;
1617 case CONNECTOR_ID_DUAL_LINK_DVID:
1618 case CONNECTOR_ID_DUAL_LINK_DVII:
d0778ebf 1619 link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
4562236b
HW
1620 break;
1621 case CONNECTOR_ID_DISPLAY_PORT:
8cb3c169 1622 case CONNECTOR_ID_USBC:
9ec420d8 1623 link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
4562236b 1624
9ec420d8 1625 if (link->hpd_gpio)
d0778ebf 1626 link->irq_source_hpd_rx =
ac627caf 1627 dal_irq_get_rx_source(link->hpd_gpio);
4562236b
HW
1628
1629 break;
1630 case CONNECTOR_ID_EDP:
d0778ebf 1631 link->connector_signal = SIGNAL_TYPE_EDP;
4562236b 1632
9ec420d8 1633 if (link->hpd_gpio) {
5ab991ba
YLC
1634 if (!link->dc->config.allow_edp_hotplug_detection)
1635 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
ab144f0b
DL
1636
1637 switch (link->dc->config.allow_edp_hotplug_detection) {
1638 case 1: // only the 1st eDP handles hotplug
1639 if (link->link_index == 0)
1640 link->irq_source_hpd_rx =
1641 dal_irq_get_rx_source(link->hpd_gpio);
1642 else
1643 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
1644 break;
1645 case 2: // only the 2nd eDP handles hotplug
1646 if (link->link_index == 1)
1647 link->irq_source_hpd_rx =
1648 dal_irq_get_rx_source(link->hpd_gpio);
1649 else
1650 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
1651 break;
1652 default:
1653 break;
1654 }
4562236b 1655 }
904fb6e0 1656
4562236b 1657 break;
11c3ee48
AD
1658 case CONNECTOR_ID_LVDS:
1659 link->connector_signal = SIGNAL_TYPE_LVDS;
1660 break;
4562236b 1661 default:
9ec420d8
MW
1662 DC_LOG_WARNING("Unsupported Connector type:%d!\n",
1663 link->link_id.id);
4562236b
HW
1664 goto create_fail;
1665 }
1666
4562236b
HW
1667 /* TODO: #DAL3 Implement id to str function.*/
1668 LINK_INFO("Connector[%d] description:"
9ec420d8
MW
1669 "signal %d\n",
1670 init_params->connector_index,
1671 link->connector_signal);
4562236b
HW
1672
1673 ddc_service_init_data.ctx = link->ctx;
1674 ddc_service_init_data.id = link->link_id;
1675 ddc_service_init_data.link = link;
a98cdd8c 1676 link->ddc = link_create_ddc_service(&ddc_service_init_data);
4562236b 1677
9ec420d8 1678 if (!link->ddc) {
4562236b
HW
1679 DC_ERROR("Failed to create ddc_service!\n");
1680 goto ddc_create_fail;
1681 }
1682
44a09e3d
NK
1683 if (!link->ddc->ddc_pin) {
1684 DC_ERROR("Failed to get I2C info for connector!\n");
1685 goto ddc_create_fail;
1686 }
1687
d0778ebf 1688 link->ddc_hw_inst =
a98cdd8c 1689 dal_ddc_get_line(get_ddc_pin(link->ddc));
4562236b 1690
904fb6e0 1691
d4caa72e 1692 if (link->dc->res_pool->funcs->panel_cntl_create &&
904fb6e0
AK
1693 (link->link_id.id == CONNECTOR_ID_EDP ||
1694 link->link_id.id == CONNECTOR_ID_LVDS)) {
d4caa72e 1695 panel_cntl_init_data.ctx = dc_ctx;
3306ace5
JW
1696 panel_cntl_init_data.inst =
1697 panel_cntl_init_data.ctx->dc_edp_id_count;
d4caa72e
AK
1698 link->panel_cntl =
1699 link->dc->res_pool->funcs->panel_cntl_create(
1700 &panel_cntl_init_data);
3306ace5 1701 panel_cntl_init_data.ctx->dc_edp_id_count++;
d4caa72e
AK
1702
1703 if (link->panel_cntl == NULL) {
1704 DC_ERROR("Failed to create link panel_cntl!\n");
1705 goto panel_cntl_create_fail;
904fb6e0
AK
1706 }
1707 }
1708
4562236b 1709 enc_init_data.ctx = dc_ctx;
9ec420d8
MW
1710 bp_funcs->get_src_obj(dc_ctx->dc_bios, link->link_id, 0,
1711 &enc_init_data.encoder);
4562236b
HW
1712 enc_init_data.connector = link->link_id;
1713 enc_init_data.channel = get_ddc_line(link);
1714 enc_init_data.hpd_source = get_hpd_line(link);
7a096334 1715
d0778ebf 1716 link->hpd_src = enc_init_data.hpd_source;
7a096334 1717
4562236b 1718 enc_init_data.transmitter =
9ec420d8
MW
1719 translate_encoder_to_transmitter(enc_init_data.encoder);
1720 link->link_enc =
e216431b 1721 link->dc->res_pool->funcs->link_enc_create(dc_ctx, &enc_init_data);
4562236b 1722
9ec420d8 1723 if (!link->link_enc) {
4562236b
HW
1724 DC_ERROR("Failed to create link encoder!\n");
1725 goto link_enc_create_fail;
1726 }
1727
d3abc78f 1728 DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C);
f01ee019 1729 DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE);
d3abc78f 1730
e1f4328f
JK
1731 /* Update link encoder tracking variables. These are used for the dynamic
1732 * assignment of link encoders to streams.
1733 */
f42ef862
JK
1734 link->eng_id = link->link_enc->preferred_engine;
1735 link->dc->res_pool->link_encoders[link->eng_id - ENGINE_ID_DIGA] = link->link_enc;
e1f4328f
JK
1736 link->dc->res_pool->dig_link_enc_count++;
1737
d0778ebf 1738 link->link_enc_hw_inst = link->link_enc->transmitter;
4562236b
HW
1739
1740 for (i = 0; i < 4; i++) {
9ec420d8
MW
1741 if (bp_funcs->get_device_tag(dc_ctx->dc_bios,
1742 link->link_id, i,
1743 &link->device_tag) != BP_RESULT_OK) {
4562236b
HW
1744 DC_ERROR("Failed to find device tag!\n");
1745 goto device_tag_fail;
1746 }
1747
1748 /* Look for device tag that matches connector signal,
1749 * CRT for rgb, LCD for other supported signal tyes
1750 */
9ec420d8
MW
1751 if (!bp_funcs->is_device_id_supported(dc_ctx->dc_bios,
1752 link->device_tag.dev_id))
4562236b 1753 continue;
9ec420d8
MW
1754 if (link->device_tag.dev_id.device_type == DEVICE_TYPE_CRT &&
1755 link->connector_signal != SIGNAL_TYPE_RGB)
4562236b 1756 continue;
9ec420d8
MW
1757 if (link->device_tag.dev_id.device_type == DEVICE_TYPE_LCD &&
1758 link->connector_signal == SIGNAL_TYPE_RGB)
4562236b 1759 continue;
64ff0882
GS
1760
1761 DC_LOG_DC("BIOS object table - device_tag.acpi_device: %d", link->device_tag.acpi_device);
1762 DC_LOG_DC("BIOS object table - device_tag.dev_id.device_type: %d", link->device_tag.dev_id.device_type);
1763 DC_LOG_DC("BIOS object table - device_tag.dev_id.enum_id: %d", link->device_tag.dev_id.enum_id);
4562236b
HW
1764 break;
1765 }
1766
1767 if (bios->integrated_info)
b4423a3d 1768 memcpy(info, bios->integrated_info, sizeof(*info));
4562236b
HW
1769
1770 /* Look for channel mapping corresponding to connector and device tag */
1771 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; i++) {
1772 struct external_display_path *path =
3a00c042 1773 &info->ext_disp_conn_info.path[i];
1e8635ea 1774
9ec420d8
MW
1775 if (path->device_connector_id.enum_id == link->link_id.enum_id &&
1776 path->device_connector_id.id == link->link_id.id &&
1777 path->device_connector_id.type == link->link_id.type) {
1778 if (link->device_tag.acpi_device != 0 &&
1779 path->device_acpi_enum == link->device_tag.acpi_device) {
1e8635ea
ZF
1780 link->ddi_channel_mapping = path->channel_mapping;
1781 link->chip_caps = path->caps;
64ff0882
GS
1782 DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X", link->ddi_channel_mapping.raw);
1783 DC_LOG_DC("BIOS object table - chip_caps: %d", link->chip_caps);
1e8635ea 1784 } else if (path->device_tag ==
9ec420d8 1785 link->device_tag.dev_id.raw_device_tag) {
1e8635ea
ZF
1786 link->ddi_channel_mapping = path->channel_mapping;
1787 link->chip_caps = path->caps;
64ff0882
GS
1788 DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X", link->ddi_channel_mapping.raw);
1789 DC_LOG_DC("BIOS object table - chip_caps: %d", link->chip_caps);
1e8635ea 1790 }
54fe00be
GS
1791
1792 if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) {
1793 link->bios_forced_drive_settings.VOLTAGE_SWING =
1794 (info->ext_disp_conn_info.fixdpvoltageswing & 0x3);
1795 link->bios_forced_drive_settings.PRE_EMPHASIS =
1796 ((info->ext_disp_conn_info.fixdpvoltageswing >> 2) & 0x3);
1797 }
1798
4562236b
HW
1799 break;
1800 }
1801 }
1802
09821499
IK
1803 if (bios->funcs->get_atom_dc_golden_table)
1804 bios->funcs->get_atom_dc_golden_table(bios);
1805
4562236b
HW
1806 /*
1807 * TODO check if GPIO programmed correctly
1808 *
1809 * If GPIO isn't programmed correctly HPD might not rise or drain
1810 * fast enough, leading to bounces.
1811 */
b0c4e977 1812 program_hpd_filter(link);
4562236b 1813
6651875a 1814 link->psr_settings.psr_vtotal_control_support = false;
1cfbbdde 1815 link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
d1ebfdd8 1816
a4905435 1817 DC_LOG_DC("BIOS object table - %s finished successfully.\n", __func__);
616cf23b 1818 kfree(info);
4562236b
HW
1819 return true;
1820device_tag_fail:
1821 link->link_enc->funcs->destroy(&link->link_enc);
1822link_enc_create_fail:
d4caa72e
AK
1823 if (link->panel_cntl != NULL)
1824 link->panel_cntl->funcs->destroy(&link->panel_cntl);
1825panel_cntl_create_fail:
a98cdd8c 1826 link_destroy_ddc_service(&link->ddc);
4562236b
HW
1827ddc_create_fail:
1828create_fail:
1829
9ec420d8 1830 if (link->hpd_gpio) {
ac627caf
CH
1831 dal_gpio_destroy_irq(&link->hpd_gpio);
1832 link->hpd_gpio = NULL;
4562236b
HW
1833 }
1834
a4905435 1835 DC_LOG_DC("BIOS object table - %s failed.\n", __func__);
3a00c042
LJ
1836 kfree(info);
1837
4562236b
HW
1838 return false;
1839}
1840
9fa0fb77
MS
1841static bool dc_link_construct_dpia(struct dc_link *link,
1842 const struct link_init_data *init_params)
1843{
6bad8e4a 1844 struct ddc_service_init_data ddc_service_init_data = { 0 };
9fa0fb77
MS
1845 struct dc_context *dc_ctx = init_params->ctx;
1846
1847 DC_LOGGER_INIT(dc_ctx->logger);
1848
40fadb4c
MS
1849 /* Initialized irq source for hpd and hpd rx */
1850 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
1851 link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID;
9fa0fb77
MS
1852 link->link_status.dpcd_caps = &link->dpcd_caps;
1853
1854 link->dc = init_params->dc;
1855 link->ctx = dc_ctx;
1856 link->link_index = init_params->link_index;
1857
1858 memset(&link->preferred_training_settings, 0,
1859 sizeof(struct dc_link_training_overrides));
1860 memset(&link->preferred_link_setting, 0,
1861 sizeof(struct dc_link_settings));
1862
1863 /* Dummy Init for linkid */
1864 link->link_id.type = OBJECT_TYPE_CONNECTOR;
1865 link->link_id.id = CONNECTOR_ID_DISPLAY_PORT;
99447622 1866 link->link_id.enum_id = ENUM_ID_1 + init_params->connector_index;
9fa0fb77
MS
1867 link->is_internal_display = false;
1868 link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
1869 LINK_INFO("Connector[%d] description:signal %d\n",
1870 init_params->connector_index,
1871 link->connector_signal);
1872
698d0a6f 1873 link->ep_type = DISPLAY_ENDPOINT_USB4_DPIA;
99447622 1874 link->is_dig_mapping_flexible = true;
698d0a6f 1875
9fa0fb77
MS
1876 /* TODO: Initialize link : funcs->link_init */
1877
1878 ddc_service_init_data.ctx = link->ctx;
1879 ddc_service_init_data.id = link->link_id;
1880 ddc_service_init_data.link = link;
1881 /* Set indicator for dpia link so that ddc won't be created */
1882 ddc_service_init_data.is_dpia_link = true;
1883
a98cdd8c 1884 link->ddc = link_create_ddc_service(&ddc_service_init_data);
9fa0fb77
MS
1885 if (!link->ddc) {
1886 DC_ERROR("Failed to create ddc_service!\n");
1887 goto ddc_create_fail;
1888 }
1889
1890 /* Set dpia port index : 0 to number of dpia ports */
1891 link->ddc_hw_inst = init_params->connector_index;
1892
1893 /* TODO: Create link encoder */
1894
1895 link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
1896
4b169ca3
JK
1897 /* Some docks seem to NAK I2C writes to segment pointer with mot=0. */
1898 link->wa_flags.dp_mot_reset_segment = true;
1899
9fa0fb77
MS
1900 return true;
1901
1902ddc_create_fail:
1903 return false;
1904}
1905
1906static bool dc_link_construct(struct dc_link *link,
1907 const struct link_init_data *init_params)
1908{
1909 /* Handle dpia case */
1910 if (init_params->is_dpia_link)
1911 return dc_link_construct_dpia(link, init_params);
1912 else
1913 return dc_link_construct_legacy(link, init_params);
1914}
4562236b
HW
1915/*******************************************************************************
1916 * Public functions
1917 ******************************************************************************/
d0778ebf 1918struct dc_link *link_create(const struct link_init_data *init_params)
4562236b 1919{
d0778ebf 1920 struct dc_link *link =
2004f45e 1921 kzalloc(sizeof(*link), GFP_KERNEL);
4562236b
HW
1922
1923 if (NULL == link)
1924 goto alloc_fail;
1925
d9e32672 1926 if (false == dc_link_construct(link, init_params))
4562236b
HW
1927 goto construct_fail;
1928
1929 return link;
1930
1931construct_fail:
2004f45e 1932 kfree(link);
4562236b
HW
1933
1934alloc_fail:
1935 return NULL;
1936}
1937
d0778ebf 1938void link_destroy(struct dc_link **link)
4562236b 1939{
d9e32672 1940 dc_link_destruct(*link);
2004f45e 1941 kfree(*link);
4562236b
HW
1942 *link = NULL;
1943}
1944
4562236b
HW
1945static void enable_stream_features(struct pipe_ctx *pipe_ctx)
1946{
0971c40e 1947 struct dc_stream_state *stream = pipe_ctx->stream;
4562236b 1948
6016cd9d
BG
1949 if (pipe_ctx->stream->signal != SIGNAL_TYPE_DISPLAY_PORT_MST) {
1950 struct dc_link *link = stream->link;
1951 union down_spread_ctrl old_downspread;
1952 union down_spread_ctrl new_downspread;
1953
0726ed30
YZ
1954 memset(&old_downspread, 0, sizeof(old_downspread));
1955
6016cd9d
BG
1956 core_link_read_dpcd(link, DP_DOWNSPREAD_CTRL,
1957 &old_downspread.raw, sizeof(old_downspread));
4562236b 1958
6016cd9d 1959 new_downspread.raw = old_downspread.raw;
87943159 1960
6016cd9d
BG
1961 new_downspread.bits.IGNORE_MSA_TIMING_PARAM =
1962 (stream->ignore_msa_timing_param) ? 1 : 0;
4562236b 1963
6016cd9d
BG
1964 if (new_downspread.raw != old_downspread.raw) {
1965 core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
1966 &new_downspread.raw, sizeof(new_downspread));
1967 }
1968
1969 } else {
1970 dm_helpers_mst_enable_stream_features(stream);
87943159 1971 }
4562236b
HW
1972}
1973
9100c359
MW
1974static enum dc_status enable_link_dp(struct dc_state *state,
1975 struct pipe_ctx *pipe_ctx)
4562236b 1976{
0971c40e 1977 struct dc_stream_state *stream = pipe_ctx->stream;
4562236b
HW
1978 enum dc_status status;
1979 bool skip_video_pattern;
ceb3dbb4 1980 struct dc_link *link = stream->link;
017860c9
WL
1981 const struct dc_link_settings *link_settings =
1982 &pipe_ctx->link_config.dp_link_settings;
e0a6440a 1983 bool fec_enable;
5ec43eda
ML
1984 int i;
1985 bool apply_seamless_boot_optimization = false;
96577cf8 1986 uint32_t bl_oled_enable_delay = 50; // in ms
eccff6cd 1987 uint32_t post_oui_delay = 30; // 30ms
82253671
JK
1988 /* Reduce link bandwidth between failed link training attempts. */
1989 bool do_fallback = false;
5ec43eda
ML
1990
1991 // check for seamless boot
1992 for (i = 0; i < state->stream_count; i++) {
1993 if (state->streams[i]->apply_seamless_boot_optimization) {
1994 apply_seamless_boot_optimization = true;
1995 break;
1996 }
1997 }
4562236b 1998
edfb2693
JK
1999 /* Train with fallback when enabling DPIA link. Conventional links are
2000 * trained with fallback during sink detection.
2001 */
2002 if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
2003 do_fallback = true;
2004
05692bb0
WL
2005 /*
2006 * Temporary w/a to get DP2.0 link rates to work with SST.
2007 * TODO DP2.0 - Workaround: Remove w/a if and when the issue is resolved.
2008 */
d5a43956 2009 if (link_dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING &&
05692bb0
WL
2010 pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
2011 link->dc->debug.set_mst_en_for_sst) {
f01ee019
FZ
2012 dp_enable_mst_on_sink(link, true);
2013 }
f01ee019 2014
5b7c0d8d 2015 if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
5b7c0d8d 2016 /*in case it is not on*/
a8201902
LM
2017 if (!link->dc->config.edp_no_power_sequencing)
2018 link->dc->hwss.edp_power_control(link, true);
5b7c0d8d 2019 link->dc->hwss.edp_wait_for_hpd_ready(link, true);
15ae3b28
AK
2020 }
2021
d5a43956 2022 if (link_dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
f01ee019
FZ
2023 /* TODO - DP2.0 HW: calculate 32 symbol clock for HPO encoder */
2024 } else {
2025 pipe_ctx->stream_res.pix_clk_params.requested_sym_clk =
017860c9 2026 link_settings->link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
f01ee019
FZ
2027 if (state->clk_mgr && !apply_seamless_boot_optimization)
2028 state->clk_mgr->funcs->update_clocks(state->clk_mgr,
2029 state, false);
2030 }
4562236b 2031
96577cf8
HW
2032 // during mode switch we do DP_SET_POWER off then on, and OUI is lost
2033 dpcd_set_source_specific_data(link);
eccff6cd
IC
2034 if (link->dpcd_sink_ext_caps.raw != 0) {
2035 post_oui_delay += link->panel_config.pps.extra_post_OUI_ms;
c797ede0 2036 msleep(post_oui_delay);
eccff6cd 2037 }
96577cf8 2038
4a3ad932 2039 // similarly, mode switch can cause loss of cable ID
c595fb05 2040 dpcd_write_cable_id_to_dprx(link);
4a3ad932 2041
4562236b
HW
2042 skip_video_pattern = true;
2043
017860c9 2044 if (link_settings->link_rate == LINK_RATE_LOW)
9100c359
MW
2045 skip_video_pattern = false;
2046
017860c9 2047 if (perform_link_training_with_retries(link_settings,
9100c359
MW
2048 skip_video_pattern,
2049 LINK_TRAINING_ATTEMPTS,
2050 pipe_ctx,
82253671
JK
2051 pipe_ctx->stream->signal,
2052 do_fallback)) {
4562236b 2053 status = DC_OK;
9100c359 2054 } else {
c0ba5ec7 2055 status = DC_FAIL_DP_LINK_TRAINING;
9100c359 2056 }
4562236b 2057
9100c359 2058 if (link->preferred_training_settings.fec_enable)
008a4016
NC
2059 fec_enable = *link->preferred_training_settings.fec_enable;
2060 else
2061 fec_enable = true;
2062
d5a43956 2063 if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING)
f01ee019 2064 dp_set_fec_enable(link, fec_enable);
96577cf8
HW
2065
2066 // during mode set we do DP_SET_POWER off then on, aux writes are lost
2067 if (link->dpcd_sink_ext_caps.bits.oled == 1 ||
2068 link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1 ||
2069 link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1) {
2070 dc_link_set_default_brightness_aux(link); // TODO: use cached if known
2071 if (link->dpcd_sink_ext_caps.bits.oled == 1)
2072 msleep(bl_oled_enable_delay);
2073 dc_link_backlight_enable_aux(link, true);
2074 }
2075
4562236b
HW
2076 return status;
2077}
2078
904623ee
YS
2079static enum dc_status enable_link_edp(
2080 struct dc_state *state,
2081 struct pipe_ctx *pipe_ctx)
2082{
17048d89 2083 return enable_link_dp(state, pipe_ctx);
904623ee
YS
2084}
2085
ab8db3e1
AG
2086static enum dc_status enable_link_dp_mst(
2087 struct dc_state *state,
2088 struct pipe_ctx *pipe_ctx)
4562236b 2089{
ceb3dbb4 2090 struct dc_link *link = pipe_ctx->stream->link;
4562236b
HW
2091
2092 /* sink signal type after MST branch is MST. Multiple MST sinks
2093 * share one link. Link DP PHY is enable or training only once.
2094 */
07920450 2095 if (link->link_status.link_active)
4562236b
HW
2096 return DC_OK;
2097
9cc032b2
MT
2098 /* clear payload table */
2099 dm_helpers_dp_mst_clear_payload_allocation_table(link->ctx, link);
2100
22051b63 2101 /* to make sure the pending down rep can be processed
9cc032b2 2102 * before enabling the link
22051b63
MT
2103 */
2104 dm_helpers_dp_mst_poll_pending_down_reply(link->ctx, link);
2105
07c84c7a
DW
2106 /* set the sink to MST mode before enabling the link */
2107 dp_enable_mst_on_sink(link, true);
2108
ab8db3e1 2109 return enable_link_dp(state, pipe_ctx);
4562236b
HW
2110}
2111
ebd1e719
LHM
2112void dc_link_blank_all_dp_displays(struct dc *dc)
2113{
2114 unsigned int i;
2115 uint8_t dpcd_power_state = '\0';
2116 enum dc_status status = DC_ERROR_UNEXPECTED;
2117
2118 for (i = 0; i < dc->link_count; i++) {
2119 if ((dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) ||
2120 (dc->links[i]->priv == NULL) || (dc->links[i]->local_sink == NULL))
2121 continue;
2122
2123 /* DP 2.0 spec requires that we read LTTPR caps first */
2124 dp_retrieve_lttpr_cap(dc->links[i]);
2125 /* if any of the displays are lit up turn them off */
2126 status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
2127 &dpcd_power_state, sizeof(dpcd_power_state));
2128
2129 if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0)
2130 dc_link_blank_dp_stream(dc->links[i], true);
2131 }
2132
2133}
2134
2d017189
DM
2135void dc_link_blank_all_edp_displays(struct dc *dc)
2136{
2137 unsigned int i;
2138 uint8_t dpcd_power_state = '\0';
2139 enum dc_status status = DC_ERROR_UNEXPECTED;
2140
2141 for (i = 0; i < dc->link_count; i++) {
2142 if ((dc->links[i]->connector_signal != SIGNAL_TYPE_EDP) ||
2143 (!dc->links[i]->edp_sink_present))
2144 continue;
2145
2146 /* if any of the displays are lit up turn them off */
2147 status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
2148 &dpcd_power_state, sizeof(dpcd_power_state));
2149
2150 if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0)
2151 dc_link_blank_dp_stream(dc->links[i], true);
2152 }
2153}
2154
ebd1e719
LHM
2155void dc_link_blank_dp_stream(struct dc_link *link, bool hw_init)
2156{
2157 unsigned int j;
2158 struct dc *dc = link->ctx->dc;
2159 enum signal_type signal = link->connector_signal;
2160
2161 if ((signal == SIGNAL_TYPE_EDP) ||
2162 (signal == SIGNAL_TYPE_DISPLAY_PORT)) {
2163 if (link->ep_type == DISPLAY_ENDPOINT_PHY &&
2164 link->link_enc->funcs->get_dig_frontend &&
2165 link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
2166 unsigned int fe = link->link_enc->funcs->get_dig_frontend(link->link_enc);
2167
2168 if (fe != ENGINE_ID_UNKNOWN)
2169 for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
2170 if (fe == dc->res_pool->stream_enc[j]->id) {
2171 dc->res_pool->stream_enc[j]->funcs->dp_blank(link,
2172 dc->res_pool->stream_enc[j]);
2173 break;
2174 }
2175 }
2176 }
2177
2178 if ((!link->wa_flags.dp_keep_receiver_powered) || hw_init)
94dfeaa4 2179 dc_link_dp_receiver_power_ctrl(link, false);
ebd1e719
LHM
2180 }
2181}
2182
1e8635ea
ZF
2183static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx,
2184 enum engine_id eng_id,
2185 struct ext_hdmi_settings *settings)
2186{
2187 bool result = false;
2188 int i = 0;
2189 struct integrated_info *integrated_info =
2190 pipe_ctx->stream->ctx->dc_bios->integrated_info;
2191
2192 if (integrated_info == NULL)
2193 return false;
2194
2195 /*
2196 * Get retimer settings from sbios for passing SI eye test for DCE11
2197 * The setting values are varied based on board revision and port id
2198 * Therefore the setting values of each ports is passed by sbios.
2199 */
2200
2201 // Check if current bios contains ext Hdmi settings
2202 if (integrated_info->gpu_cap_info & 0x20) {
2203 switch (eng_id) {
2204 case ENGINE_ID_DIGA:
2205 settings->slv_addr = integrated_info->dp0_ext_hdmi_slv_addr;
2206 settings->reg_num = integrated_info->dp0_ext_hdmi_6g_reg_num;
2207 settings->reg_num_6g = integrated_info->dp0_ext_hdmi_6g_reg_num;
2208 memmove(settings->reg_settings,
2209 integrated_info->dp0_ext_hdmi_reg_settings,
2210 sizeof(integrated_info->dp0_ext_hdmi_reg_settings));
2211 memmove(settings->reg_settings_6g,
2212 integrated_info->dp0_ext_hdmi_6g_reg_settings,
2213 sizeof(integrated_info->dp0_ext_hdmi_6g_reg_settings));
2214 result = true;
2215 break;
2216 case ENGINE_ID_DIGB:
2217 settings->slv_addr = integrated_info->dp1_ext_hdmi_slv_addr;
2218 settings->reg_num = integrated_info->dp1_ext_hdmi_6g_reg_num;
2219 settings->reg_num_6g = integrated_info->dp1_ext_hdmi_6g_reg_num;
2220 memmove(settings->reg_settings,
2221 integrated_info->dp1_ext_hdmi_reg_settings,
2222 sizeof(integrated_info->dp1_ext_hdmi_reg_settings));
2223 memmove(settings->reg_settings_6g,
2224 integrated_info->dp1_ext_hdmi_6g_reg_settings,
2225 sizeof(integrated_info->dp1_ext_hdmi_6g_reg_settings));
2226 result = true;
2227 break;
2228 case ENGINE_ID_DIGC:
2229 settings->slv_addr = integrated_info->dp2_ext_hdmi_slv_addr;
2230 settings->reg_num = integrated_info->dp2_ext_hdmi_6g_reg_num;
2231 settings->reg_num_6g = integrated_info->dp2_ext_hdmi_6g_reg_num;
2232 memmove(settings->reg_settings,
2233 integrated_info->dp2_ext_hdmi_reg_settings,
2234 sizeof(integrated_info->dp2_ext_hdmi_reg_settings));
2235 memmove(settings->reg_settings_6g,
2236 integrated_info->dp2_ext_hdmi_6g_reg_settings,
2237 sizeof(integrated_info->dp2_ext_hdmi_6g_reg_settings));
2238 result = true;
2239 break;
4e527c01
AJ
2240 case ENGINE_ID_DIGD:
2241 settings->slv_addr = integrated_info->dp3_ext_hdmi_slv_addr;
2242 settings->reg_num = integrated_info->dp3_ext_hdmi_6g_reg_num;
2243 settings->reg_num_6g = integrated_info->dp3_ext_hdmi_6g_reg_num;
2244 memmove(settings->reg_settings,
2245 integrated_info->dp3_ext_hdmi_reg_settings,
2246 sizeof(integrated_info->dp3_ext_hdmi_reg_settings));
2247 memmove(settings->reg_settings_6g,
2248 integrated_info->dp3_ext_hdmi_6g_reg_settings,
2249 sizeof(integrated_info->dp3_ext_hdmi_6g_reg_settings));
2250 result = true;
2251 break;
1e8635ea
ZF
2252 default:
2253 break;
2254 }
2255
2256 if (result == true) {
2257 // Validate settings from bios integrated info table
2258 if (settings->slv_addr == 0)
2259 return false;
2260 if (settings->reg_num > 9)
2261 return false;
2262 if (settings->reg_num_6g > 3)
2263 return false;
2264
2265 for (i = 0; i < settings->reg_num; i++) {
2266 if (settings->reg_settings[i].i2c_reg_index > 0x20)
2267 return false;
2268 }
2269
2270 for (i = 0; i < settings->reg_num_6g; i++) {
2271 if (settings->reg_settings_6g[i].i2c_reg_index > 0x20)
2272 return false;
2273 }
2274 }
2275 }
2276
2277 return result;
2278}
2279
2280static bool i2c_write(struct pipe_ctx *pipe_ctx,
2281 uint8_t address, uint8_t *buffer, uint32_t length)
2282{
2283 struct i2c_command cmd = {0};
2284 struct i2c_payload payload = {0};
2285
2286 memset(&payload, 0, sizeof(payload));
2287 memset(&cmd, 0, sizeof(cmd));
2288
2289 cmd.number_of_payloads = 1;
2290 cmd.engine = I2C_COMMAND_ENGINE_DEFAULT;
2291 cmd.speed = pipe_ctx->stream->ctx->dc->caps.i2c_speed_in_khz;
2292
2293 payload.address = address;
2294 payload.data = buffer;
2295 payload.length = length;
2296 payload.write = true;
2297 cmd.payloads = &payload;
2298
c85e6e54 2299 if (dm_helpers_submit_i2c(pipe_ctx->stream->ctx,
ceb3dbb4 2300 pipe_ctx->stream->link, &cmd))
1e8635ea
ZF
2301 return true;
2302
2303 return false;
2304}
2305
2306static void write_i2c_retimer_setting(
2307 struct pipe_ctx *pipe_ctx,
2308 bool is_vga_mode,
2309 bool is_over_340mhz,
2310 struct ext_hdmi_settings *settings)
2311{
2312 uint8_t slave_address = (settings->slv_addr >> 1);
2313 uint8_t buffer[2];
2314 const uint8_t apply_rx_tx_change = 0x4;
2315 uint8_t offset = 0xA;
2316 uint8_t value = 0;
2317 int i = 0;
2318 bool i2c_success = false;
2f14bc89 2319 DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
1e8635ea
ZF
2320
2321 memset(&buffer, 0, sizeof(buffer));
2322
2323 /* Start Ext-Hdmi programming*/
2324
2325 for (i = 0; i < settings->reg_num; i++) {
2326 /* Apply 3G settings */
2327 if (settings->reg_settings[i].i2c_reg_index <= 0x20) {
2328
2329 buffer[0] = settings->reg_settings[i].i2c_reg_index;
2330 buffer[1] = settings->reg_settings[i].i2c_reg_val;
2331 i2c_success = i2c_write(pipe_ctx, slave_address,
2332 buffer, sizeof(buffer));
2f14bc89
CL
2333 RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
2334 offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n",
2335 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea
ZF
2336
2337 if (!i2c_success)
a0e40018 2338 goto i2c_write_fail;
1e8635ea
ZF
2339
2340 /* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A
2341 * needs to be set to 1 on every 0xA-0xC write.
2342 */
2343 if (settings->reg_settings[i].i2c_reg_index == 0xA ||
2344 settings->reg_settings[i].i2c_reg_index == 0xB ||
2345 settings->reg_settings[i].i2c_reg_index == 0xC) {
2346
2347 /* Query current value from offset 0xA */
2348 if (settings->reg_settings[i].i2c_reg_index == 0xA)
2349 value = settings->reg_settings[i].i2c_reg_val;
2350 else {
2351 i2c_success =
a98cdd8c 2352 link_query_ddc_data(
ceb3dbb4 2353 pipe_ctx->stream->link->ddc,
1e8635ea
ZF
2354 slave_address, &offset, 1, &value, 1);
2355 if (!i2c_success)
a0e40018 2356 goto i2c_write_fail;
1e8635ea
ZF
2357 }
2358
2359 buffer[0] = offset;
2360 /* Set APPLY_RX_TX_CHANGE bit to 1 */
2361 buffer[1] = value | apply_rx_tx_change;
2362 i2c_success = i2c_write(pipe_ctx, slave_address,
2363 buffer, sizeof(buffer));
2f14bc89
CL
2364 RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
2365 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2366 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2367 if (!i2c_success)
a0e40018 2368 goto i2c_write_fail;
1e8635ea
ZF
2369 }
2370 }
2371 }
2372
2373 /* Apply 3G settings */
2374 if (is_over_340mhz) {
2375 for (i = 0; i < settings->reg_num_6g; i++) {
2376 /* Apply 3G settings */
2377 if (settings->reg_settings[i].i2c_reg_index <= 0x20) {
2378
2379 buffer[0] = settings->reg_settings_6g[i].i2c_reg_index;
2380 buffer[1] = settings->reg_settings_6g[i].i2c_reg_val;
2381 i2c_success = i2c_write(pipe_ctx, slave_address,
2382 buffer, sizeof(buffer));
2f14bc89
CL
2383 RETIMER_REDRIVER_INFO("above 340Mhz: retimer write to slave_address = 0x%x,\
2384 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2385 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea
ZF
2386
2387 if (!i2c_success)
a0e40018 2388 goto i2c_write_fail;
1e8635ea
ZF
2389
2390 /* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A
2391 * needs to be set to 1 on every 0xA-0xC write.
2392 */
2393 if (settings->reg_settings_6g[i].i2c_reg_index == 0xA ||
2394 settings->reg_settings_6g[i].i2c_reg_index == 0xB ||
2395 settings->reg_settings_6g[i].i2c_reg_index == 0xC) {
2396
2397 /* Query current value from offset 0xA */
2398 if (settings->reg_settings_6g[i].i2c_reg_index == 0xA)
2399 value = settings->reg_settings_6g[i].i2c_reg_val;
2400 else {
2401 i2c_success =
a98cdd8c 2402 link_query_ddc_data(
ceb3dbb4 2403 pipe_ctx->stream->link->ddc,
1e8635ea
ZF
2404 slave_address, &offset, 1, &value, 1);
2405 if (!i2c_success)
a0e40018 2406 goto i2c_write_fail;
1e8635ea
ZF
2407 }
2408
2409 buffer[0] = offset;
2410 /* Set APPLY_RX_TX_CHANGE bit to 1 */
2411 buffer[1] = value | apply_rx_tx_change;
2412 i2c_success = i2c_write(pipe_ctx, slave_address,
2413 buffer, sizeof(buffer));
2f14bc89
CL
2414 RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
2415 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2416 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2417 if (!i2c_success)
a0e40018 2418 goto i2c_write_fail;
1e8635ea
ZF
2419 }
2420 }
2421 }
2422 }
2423
2424 if (is_vga_mode) {
2425 /* Program additional settings if using 640x480 resolution */
2426
2427 /* Write offset 0xFF to 0x01 */
2428 buffer[0] = 0xff;
2429 buffer[1] = 0x01;
2430 i2c_success = i2c_write(pipe_ctx, slave_address,
2431 buffer, sizeof(buffer));
2f14bc89
CL
2432 RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
2433 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2434 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2435 if (!i2c_success)
a0e40018 2436 goto i2c_write_fail;
1e8635ea
ZF
2437
2438 /* Write offset 0x00 to 0x23 */
2439 buffer[0] = 0x00;
2440 buffer[1] = 0x23;
2441 i2c_success = i2c_write(pipe_ctx, slave_address,
2442 buffer, sizeof(buffer));
2f14bc89 2443 RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
c2af2a42 2444 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2f14bc89 2445 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2446 if (!i2c_success)
a0e40018 2447 goto i2c_write_fail;
1e8635ea
ZF
2448
2449 /* Write offset 0xff to 0x00 */
2450 buffer[0] = 0xff;
2451 buffer[1] = 0x00;
2452 i2c_success = i2c_write(pipe_ctx, slave_address,
2453 buffer, sizeof(buffer));
2f14bc89 2454 RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
c2af2a42 2455 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2f14bc89 2456 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2457 if (!i2c_success)
a0e40018 2458 goto i2c_write_fail;
1e8635ea
ZF
2459
2460 }
a0e40018
RS
2461
2462 return;
2463
2464i2c_write_fail:
2465 DC_LOG_DEBUG("Set retimer failed");
1e8635ea
ZF
2466}
2467
2468static void write_i2c_default_retimer_setting(
2469 struct pipe_ctx *pipe_ctx,
2470 bool is_vga_mode,
2471 bool is_over_340mhz)
2472{
2473 uint8_t slave_address = (0xBA >> 1);
2474 uint8_t buffer[2];
2475 bool i2c_success = false;
2f14bc89 2476 DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
1e8635ea
ZF
2477
2478 memset(&buffer, 0, sizeof(buffer));
2479
2480 /* Program Slave Address for tuning single integrity */
2481 /* Write offset 0x0A to 0x13 */
2482 buffer[0] = 0x0A;
2483 buffer[1] = 0x13;
2484 i2c_success = i2c_write(pipe_ctx, slave_address,
2485 buffer, sizeof(buffer));
2f14bc89
CL
2486 RETIMER_REDRIVER_INFO("retimer writes default setting to slave_address = 0x%x,\
2487 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2488 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2489 if (!i2c_success)
a0e40018 2490 goto i2c_write_fail;
1e8635ea
ZF
2491
2492 /* Write offset 0x0A to 0x17 */
2493 buffer[0] = 0x0A;
2494 buffer[1] = 0x17;
2495 i2c_success = i2c_write(pipe_ctx, slave_address,
2496 buffer, sizeof(buffer));
2f14bc89
CL
2497 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2498 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2499 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2500 if (!i2c_success)
a0e40018 2501 goto i2c_write_fail;
1e8635ea
ZF
2502
2503 /* Write offset 0x0B to 0xDA or 0xD8 */
2504 buffer[0] = 0x0B;
2505 buffer[1] = is_over_340mhz ? 0xDA : 0xD8;
2506 i2c_success = i2c_write(pipe_ctx, slave_address,
2507 buffer, sizeof(buffer));
2f14bc89
CL
2508 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2509 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2510 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2511 if (!i2c_success)
a0e40018 2512 goto i2c_write_fail;
1e8635ea
ZF
2513
2514 /* Write offset 0x0A to 0x17 */
2515 buffer[0] = 0x0A;
2516 buffer[1] = 0x17;
2517 i2c_success = i2c_write(pipe_ctx, slave_address,
2518 buffer, sizeof(buffer));
2f14bc89
CL
2519 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2520 offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n",
2521 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2522 if (!i2c_success)
a0e40018 2523 goto i2c_write_fail;
1e8635ea
ZF
2524
2525 /* Write offset 0x0C to 0x1D or 0x91 */
2526 buffer[0] = 0x0C;
2527 buffer[1] = is_over_340mhz ? 0x1D : 0x91;
2528 i2c_success = i2c_write(pipe_ctx, slave_address,
2529 buffer, sizeof(buffer));
2f14bc89
CL
2530 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2531 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2532 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2533 if (!i2c_success)
a0e40018 2534 goto i2c_write_fail;
1e8635ea
ZF
2535
2536 /* Write offset 0x0A to 0x17 */
2537 buffer[0] = 0x0A;
2538 buffer[1] = 0x17;
2539 i2c_success = i2c_write(pipe_ctx, slave_address,
2540 buffer, sizeof(buffer));
2f14bc89
CL
2541 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2542 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2543 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2544 if (!i2c_success)
a0e40018 2545 goto i2c_write_fail;
1e8635ea
ZF
2546
2547
2548 if (is_vga_mode) {
2549 /* Program additional settings if using 640x480 resolution */
2550
2551 /* Write offset 0xFF to 0x01 */
2552 buffer[0] = 0xff;
2553 buffer[1] = 0x01;
2554 i2c_success = i2c_write(pipe_ctx, slave_address,
2555 buffer, sizeof(buffer));
2f14bc89
CL
2556 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2557 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
2558 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2559 if (!i2c_success)
a0e40018 2560 goto i2c_write_fail;
1e8635ea
ZF
2561
2562 /* Write offset 0x00 to 0x23 */
2563 buffer[0] = 0x00;
2564 buffer[1] = 0x23;
2565 i2c_success = i2c_write(pipe_ctx, slave_address,
2566 buffer, sizeof(buffer));
2f14bc89
CL
2567 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
2568 offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n",
2569 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2570 if (!i2c_success)
a0e40018 2571 goto i2c_write_fail;
1e8635ea
ZF
2572
2573 /* Write offset 0xff to 0x00 */
2574 buffer[0] = 0xff;
2575 buffer[1] = 0x00;
2576 i2c_success = i2c_write(pipe_ctx, slave_address,
2577 buffer, sizeof(buffer));
2f14bc89
CL
2578 RETIMER_REDRIVER_INFO("retimer write default setting to slave_addr = 0x%x,\
2579 offset = 0x%x, reg_val= 0x%x, i2c_success = %d end here\n",
2580 slave_address, buffer[0], buffer[1], i2c_success?1:0);
1e8635ea 2581 if (!i2c_success)
a0e40018 2582 goto i2c_write_fail;
1e8635ea 2583 }
a0e40018
RS
2584
2585 return;
2586
2587i2c_write_fail:
2588 DC_LOG_DEBUG("Set default retimer failed");
1e8635ea
ZF
2589}
2590
2591static void write_i2c_redriver_setting(
2592 struct pipe_ctx *pipe_ctx,
2593 bool is_over_340mhz)
2594{
2595 uint8_t slave_address = (0xF0 >> 1);
2596 uint8_t buffer[16];
2597 bool i2c_success = false;
2f14bc89 2598 DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
1e8635ea
ZF
2599
2600 memset(&buffer, 0, sizeof(buffer));
2601
2602 // Program Slave Address for tuning single integrity
2603 buffer[3] = 0x4E;
2604 buffer[4] = 0x4E;
2605 buffer[5] = 0x4E;
2606 buffer[6] = is_over_340mhz ? 0x4E : 0x4A;
2607
2608 i2c_success = i2c_write(pipe_ctx, slave_address,
2609 buffer, sizeof(buffer));
2f14bc89
CL
2610 RETIMER_REDRIVER_INFO("redriver write 0 to all 16 reg offset expect following:\n\
2611 \t slave_addr = 0x%x, offset[3] = 0x%x, offset[4] = 0x%x,\
2612 offset[5] = 0x%x,offset[6] is_over_340mhz = 0x%x,\
2613 i2c_success = %d\n",
2614 slave_address, buffer[3], buffer[4], buffer[5], buffer[6], i2c_success?1:0);
1e8635ea
ZF
2615
2616 if (!i2c_success)
a0e40018 2617 DC_LOG_DEBUG("Set redriver failed");
1e8635ea
ZF
2618}
2619
ef30f441
WL
2620static void disable_link(struct dc_link *link, const struct link_resource *link_res,
2621 enum signal_type signal)
61f14c5b
LL
2622{
2623 /*
2624 * TODO: implement call for dp_set_hw_test_pattern
2625 * it is needed for compliance testing
2626 */
2627
2628 /* Here we need to specify that encoder output settings
2629 * need to be calculated as for the set mode,
2630 * it will lead to querying dynamic link capabilities
2631 * which should be done before enable output
2632 */
2633
2634 if (dc_is_dp_signal(signal)) {
2635 /* SST DP, eDP */
f01ee019 2636 struct dc_link_settings link_settings = link->cur_link_settings;
61f14c5b 2637 if (dc_is_dp_sst_signal(signal))
ef30f441 2638 dp_disable_link_phy(link, link_res, signal);
61f14c5b 2639 else
ef30f441 2640 dp_disable_link_phy_mst(link, link_res, signal);
61f14c5b
LL
2641
2642 if (dc_is_dp_sst_signal(signal) ||
2643 link->mst_stream_alloc_table.stream_count == 0) {
d5a43956 2644 if (link_dp_get_encoding_format(&link_settings) == DP_8b_10b_ENCODING) {
f01ee019 2645 dp_set_fec_enable(link, false);
ef30f441 2646 dp_set_fec_ready(link, link_res, false);
f01ee019 2647 }
61f14c5b 2648 }
9c75891f
WL
2649 } else if (signal != SIGNAL_TYPE_VIRTUAL) {
2650 link->dc->hwss.disable_link_output(link, link_res, signal);
61f14c5b
LL
2651 }
2652
2653 if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
2654 /* MST disable link only when no stream use the link */
2655 if (link->mst_stream_alloc_table.stream_count <= 0)
2656 link->link_status.link_active = false;
2657 } else {
2658 link->link_status.link_active = false;
2659 }
2660}
2661
4562236b
HW
2662static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
2663{
0971c40e 2664 struct dc_stream_state *stream = pipe_ctx->stream;
ceb3dbb4 2665 struct dc_link *link = stream->link;
cc4d99b8 2666 enum dc_color_depth display_color_depth;
1e8635ea
ZF
2667 enum engine_id eng_id;
2668 struct ext_hdmi_settings settings = {0};
2669 bool is_over_340mhz = false;
2670 bool is_vga_mode = (stream->timing.h_addressable == 640)
2671 && (stream->timing.v_addressable == 480);
9c75891f 2672 struct dc *dc = pipe_ctx->stream->ctx->dc;
1e8635ea 2673
321f65a6 2674 if (stream->phy_pix_clk == 0)
380604e2 2675 stream->phy_pix_clk = stream->timing.pix_clk_100hz / 10;
1e8635ea
ZF
2676 if (stream->phy_pix_clk > 340000)
2677 is_over_340mhz = true;
2678
2679 if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
ceb3dbb4 2680 unsigned short masked_chip_caps = pipe_ctx->stream->link->chip_caps &
3e5e2215 2681 EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
cc57306f 2682 if (masked_chip_caps == EXT_DISPLAY_PATH_CAPS__HDMI20_TISN65DP159RSBT) {
1e8635ea
ZF
2683 /* DP159, Retimer settings */
2684 eng_id = pipe_ctx->stream_res.stream_enc->id;
2685
2686 if (get_ext_hdmi_settings(pipe_ctx, eng_id, &settings)) {
2687 write_i2c_retimer_setting(pipe_ctx,
2688 is_vga_mode, is_over_340mhz, &settings);
2689 } else {
2690 write_i2c_default_retimer_setting(pipe_ctx,
2691 is_vga_mode, is_over_340mhz);
2692 }
cc57306f 2693 } else if (masked_chip_caps == EXT_DISPLAY_PATH_CAPS__HDMI20_PI3EQX1204) {
1e8635ea
ZF
2694 /* PI3EQX1204, Redriver settings */
2695 write_i2c_redriver_setting(pipe_ctx, is_over_340mhz);
2696 }
2697 }
4562236b
HW
2698
2699 if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
a98cdd8c 2700 write_scdc_data(
ceb3dbb4 2701 stream->link->ddc,
4562236b 2702 stream->phy_pix_clk,
4fa086b9 2703 stream->timing.flags.LTE_340MCSC_SCRAMBLE);
4562236b 2704
ceb3dbb4 2705 memset(&stream->link->cur_link_settings, 0,
4562236b
HW
2706 sizeof(struct dc_link_settings));
2707
4fa086b9
LSL
2708 display_color_depth = stream->timing.display_color_depth;
2709 if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422)
cc4d99b8
CL
2710 display_color_depth = COLOR_DEPTH_888;
2711
9c75891f
WL
2712 dc->hwss.enable_tmds_link_output(
2713 link,
2714 &pipe_ctx->link_res,
2715 pipe_ctx->stream->signal,
4562236b 2716 pipe_ctx->clock_source->id,
cc4d99b8 2717 display_color_depth,
4562236b
HW
2718 stream->phy_pix_clk);
2719
3a9aeadb 2720 if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
a98cdd8c 2721 read_scdc_data(link->ddc);
4562236b
HW
2722}
2723
11c3ee48
AD
2724static void enable_link_lvds(struct pipe_ctx *pipe_ctx)
2725{
2726 struct dc_stream_state *stream = pipe_ctx->stream;
ceb3dbb4 2727 struct dc_link *link = stream->link;
9c75891f 2728 struct dc *dc = stream->ctx->dc;
11c3ee48
AD
2729
2730 if (stream->phy_pix_clk == 0)
380604e2 2731 stream->phy_pix_clk = stream->timing.pix_clk_100hz / 10;
11c3ee48 2732
ceb3dbb4 2733 memset(&stream->link->cur_link_settings, 0,
11c3ee48 2734 sizeof(struct dc_link_settings));
9c75891f
WL
2735 dc->hwss.enable_lvds_link_output(
2736 link,
2737 &pipe_ctx->link_res,
11c3ee48
AD
2738 pipe_ctx->clock_source->id,
2739 stream->phy_pix_clk);
2740
2741}
2742
90bb21cb
MA
2743bool dc_power_alpm_dpcd_enable(struct dc_link *link, bool enable)
2744{
2745 bool ret = false;
2746 union dpcd_alpm_configuration alpm_config;
2747
2748 if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) {
2749 memset(&alpm_config, 0, sizeof(alpm_config));
2750
2751 alpm_config.bits.ENABLE = (enable ? true : false);
2752 ret = dm_helpers_dp_write_dpcd(link->ctx, link,
2753 DP_RECEIVER_ALPM_CONFIG, &alpm_config.raw,
2754 sizeof(alpm_config.raw));
2755 }
2756 return ret;
2757}
2758
4562236b 2759/****************************enable_link***********************************/
ab8db3e1
AG
2760static enum dc_status enable_link(
2761 struct dc_state *state,
2762 struct pipe_ctx *pipe_ctx)
4562236b
HW
2763{
2764 enum dc_status status = DC_ERROR_UNEXPECTED;
61f14c5b
LL
2765 struct dc_stream_state *stream = pipe_ctx->stream;
2766 struct dc_link *link = stream->link;
2767
2768 /* There's some scenarios where driver is unloaded with display
2769 * still enabled. When driver is reloaded, it may cause a display
2770 * to not light up if there is a mismatch between old and new
2771 * link settings. Need to call disable first before enabling at
2772 * new link settings.
2773 */
2774 if (link->link_status.link_active) {
ef30f441 2775 disable_link(link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
61f14c5b
LL
2776 }
2777
4562236b
HW
2778 switch (pipe_ctx->stream->signal) {
2779 case SIGNAL_TYPE_DISPLAY_PORT:
ab8db3e1 2780 status = enable_link_dp(state, pipe_ctx);
4562236b 2781 break;
904623ee
YS
2782 case SIGNAL_TYPE_EDP:
2783 status = enable_link_edp(state, pipe_ctx);
2784 break;
4562236b 2785 case SIGNAL_TYPE_DISPLAY_PORT_MST:
ab8db3e1 2786 status = enable_link_dp_mst(state, pipe_ctx);
4562236b
HW
2787 msleep(200);
2788 break;
2789 case SIGNAL_TYPE_DVI_SINGLE_LINK:
2790 case SIGNAL_TYPE_DVI_DUAL_LINK:
2791 case SIGNAL_TYPE_HDMI_TYPE_A:
2792 enable_link_hdmi(pipe_ctx);
2793 status = DC_OK;
2794 break;
11c3ee48
AD
2795 case SIGNAL_TYPE_LVDS:
2796 enable_link_lvds(pipe_ctx);
2797 status = DC_OK;
2798 break;
4562236b
HW
2799 case SIGNAL_TYPE_VIRTUAL:
2800 status = DC_OK;
2801 break;
2802 default:
2803 break;
2804 }
2805
293b9160
AK
2806 if (status == DC_OK)
2807 pipe_ctx->stream->link->link_status.link_active = true;
2808
4562236b
HW
2809 return status;
2810}
2811
162f8078
ML
2812static uint32_t get_timing_pixel_clock_100hz(const struct dc_crtc_timing *timing)
2813{
2814
2815 uint32_t pxl_clk = timing->pix_clk_100hz;
2816
2817 if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
2818 pxl_clk /= 2;
2819 else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
2820 pxl_clk = pxl_clk * 2 / 3;
2821
2822 if (timing->display_color_depth == COLOR_DEPTH_101010)
2823 pxl_clk = pxl_clk * 10 / 8;
2824 else if (timing->display_color_depth == COLOR_DEPTH_121212)
2825 pxl_clk = pxl_clk * 12 / 8;
2826
2827 return pxl_clk;
2828}
2829
73da927b 2830static bool dp_active_dongle_validate_timing(
6bffebc9 2831 const struct dc_crtc_timing *timing,
f110892e 2832 const struct dpcd_caps *dpcd_caps)
6bffebc9 2833{
f110892e
HW
2834 const struct dc_dongle_caps *dongle_caps = &dpcd_caps->dongle_caps;
2835
2836 switch (dpcd_caps->dongle_type) {
2837 case DISPLAY_DONGLE_DP_VGA_CONVERTER:
2838 case DISPLAY_DONGLE_DP_DVI_CONVERTER:
2839 case DISPLAY_DONGLE_DP_DVI_DONGLE:
2840 if (timing->pixel_encoding == PIXEL_ENCODING_RGB)
2841 return true;
2842 else
2843 return false;
2844 default:
2845 break;
2846 }
6bffebc9 2847
f01ee019
FZ
2848 if (dpcd_caps->dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER &&
2849 dongle_caps->extendedCapValid == true) {
d9eb8fea
WL
2850 /* Check Pixel Encoding */
2851 switch (timing->pixel_encoding) {
2852 case PIXEL_ENCODING_RGB:
2853 case PIXEL_ENCODING_YCBCR444:
2854 break;
2855 case PIXEL_ENCODING_YCBCR422:
2856 if (!dongle_caps->is_dp_hdmi_ycbcr422_pass_through)
2857 return false;
2858 break;
2859 case PIXEL_ENCODING_YCBCR420:
2860 if (!dongle_caps->is_dp_hdmi_ycbcr420_pass_through)
2861 return false;
2862 break;
2863 default:
2864 /* Invalid Pixel Encoding*/
6bffebc9 2865 return false;
d9eb8fea 2866 }
6bffebc9 2867
d9eb8fea
WL
2868 switch (timing->display_color_depth) {
2869 case COLOR_DEPTH_666:
2870 case COLOR_DEPTH_888:
2871 /*888 and 666 should always be supported*/
2872 break;
2873 case COLOR_DEPTH_101010:
2874 if (dongle_caps->dp_hdmi_max_bpc < 10)
2875 return false;
2876 break;
2877 case COLOR_DEPTH_121212:
2878 if (dongle_caps->dp_hdmi_max_bpc < 12)
2879 return false;
2880 break;
2881 case COLOR_DEPTH_141414:
2882 case COLOR_DEPTH_161616:
2883 default:
2884 /* These color depths are currently not supported */
6bffebc9 2885 return false;
d9eb8fea 2886 }
6bffebc9 2887
91dcfe5f
DV
2888 /* Check 3D format */
2889 switch (timing->timing_3d_format) {
2890 case TIMING_3D_FORMAT_NONE:
2891 case TIMING_3D_FORMAT_FRAME_ALTERNATE:
2892 /*Only frame alternate 3D is supported on active dongle*/
2893 break;
2894 default:
2895 /*other 3D formats are not supported due to bad infoframe translation */
2896 return false;
2897 }
2898
c022375a 2899#if defined(CONFIG_DRM_AMD_DC_DCN)
d9eb8fea
WL
2900 if (dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps > 0) { // DP to HDMI FRL converter
2901 struct dc_crtc_timing outputTiming = *timing;
c022375a 2902
d9eb8fea
WL
2903 if (timing->flags.DSC && !timing->dsc_cfg.is_frl)
2904 /* DP input has DSC, HDMI FRL output doesn't have DSC, remove DSC from output timing */
2905 outputTiming.flags.DSC = 0;
2906 if (dc_bandwidth_in_kbps_from_timing(&outputTiming) > dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps)
2907 return false;
2908 } else { // DP to HDMI TMDS converter
2909 if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10))
2910 return false;
2911 }
2912#else
c022375a
FZ
2913 if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10))
2914 return false;
c022375a 2915#endif
f01ee019
FZ
2916 }
2917
928adbf6
WL
2918 if (dpcd_caps->channel_coding_cap.bits.DP_128b_132b_SUPPORTED == 0 &&
2919 dpcd_caps->dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT == 0 &&
2920 dongle_caps->dfp_cap_ext.supported) {
f01ee019
FZ
2921
2922 if (dongle_caps->dfp_cap_ext.max_pixel_rate_in_mps < (timing->pix_clk_100hz / 10000))
2923 return false;
2924
2925 if (dongle_caps->dfp_cap_ext.max_video_h_active_width < timing->h_addressable)
2926 return false;
2927
2928 if (dongle_caps->dfp_cap_ext.max_video_v_active_height < timing->v_addressable)
2929 return false;
2930
2931 if (timing->pixel_encoding == PIXEL_ENCODING_RGB) {
2932 if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
2933 return false;
2934 if (timing->display_color_depth == COLOR_DEPTH_666 &&
2935 !dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_6bpc)
2936 return false;
2937 else if (timing->display_color_depth == COLOR_DEPTH_888 &&
2938 !dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_8bpc)
2939 return false;
2940 else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
2941 !dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_10bpc)
2942 return false;
2943 else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
2944 !dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_12bpc)
2945 return false;
2946 else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
2947 !dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_16bpc)
2948 return false;
2949 } else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR444) {
2950 if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
2951 return false;
2952 if (timing->display_color_depth == COLOR_DEPTH_888 &&
2953 !dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_8bpc)
2954 return false;
2955 else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
2956 !dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_10bpc)
2957 return false;
2958 else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
2959 !dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_12bpc)
2960 return false;
2961 else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
2962 !dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_16bpc)
2963 return false;
2964 } else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
2965 if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
2966 return false;
2967 if (timing->display_color_depth == COLOR_DEPTH_888 &&
2968 !dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_8bpc)
2969 return false;
2970 else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
2971 !dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_10bpc)
2972 return false;
2973 else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
2974 !dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_12bpc)
2975 return false;
2976 else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
2977 !dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_16bpc)
2978 return false;
2979 } else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
2980 if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
2981 return false;
2982 if (timing->display_color_depth == COLOR_DEPTH_888 &&
2983 !dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_8bpc)
2984 return false;
2985 else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
2986 !dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_10bpc)
2987 return false;
2988 else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
2989 !dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_12bpc)
2990 return false;
2991 else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
2992 !dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_16bpc)
2993 return false;
2994 }
2995 }
f01ee019 2996
6bffebc9
EY
2997 return true;
2998}
2999
4562236b 3000enum dc_status dc_link_validate_mode_timing(
0971c40e 3001 const struct dc_stream_state *stream,
d0778ebf 3002 struct dc_link *link,
4562236b
HW
3003 const struct dc_crtc_timing *timing)
3004{
380604e2 3005 uint32_t max_pix_clk = stream->link->dongle_max_pix_clk * 10;
f110892e 3006 struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
4562236b
HW
3007
3008 /* A hack to avoid failing any modes for EDID override feature on
3009 * topology change such as lower quality cable for DP or different dongle
3010 */
95d620ad 3011 if (link->remote_sinks[0] && link->remote_sinks[0]->sink_signal == SIGNAL_TYPE_VIRTUAL)
4562236b
HW
3012 return DC_OK;
3013
6bffebc9 3014 /* Passive Dongle */
162f8078 3015 if (max_pix_clk != 0 && get_timing_pixel_clock_100hz(timing) > max_pix_clk)
6bffebc9
EY
3016 return DC_EXCEED_DONGLE_CAP;
3017
3018 /* Active Dongle*/
f110892e 3019 if (!dp_active_dongle_validate_timing(timing, dpcd_caps))
6bffebc9 3020 return DC_EXCEED_DONGLE_CAP;
4562236b
HW
3021
3022 switch (stream->signal) {
3023 case SIGNAL_TYPE_EDP:
3024 case SIGNAL_TYPE_DISPLAY_PORT:
3025 if (!dp_validate_mode_timing(
3026 link,
3027 timing))
3028 return DC_NO_DP_LINK_BANDWIDTH;
3029 break;
3030
3031 default:
3032 break;
3033 }
3034
3035 return DC_OK;
3036}
3037
4dc0b814
YS
3038static struct abm *get_abm_from_stream_res(const struct dc_link *link)
3039{
3040 int i;
823e4bd6 3041 struct dc *dc = NULL;
4dc0b814
YS
3042 struct abm *abm = NULL;
3043
823e4bd6
KW
3044 if (!link || !link->ctx)
3045 return NULL;
3046
3047 dc = link->ctx->dc;
3048
4dc0b814
YS
3049 for (i = 0; i < MAX_PIPES; i++) {
3050 struct pipe_ctx pipe_ctx = dc->current_state->res_ctx.pipe_ctx[i];
3051 struct dc_stream_state *stream = pipe_ctx.stream;
3052
3053 if (stream && stream->link == link) {
3054 abm = pipe_ctx.stream_res.abm;
3055 break;
3056 }
3057 }
3058 return abm;
3059}
3060
620a0d27
DF
3061int dc_link_get_backlight_level(const struct dc_link *link)
3062{
4dc0b814 3063 struct abm *abm = get_abm_from_stream_res(link);
9e0d55ae
HW
3064 struct panel_cntl *panel_cntl = link->panel_cntl;
3065 struct dc *dc = link->ctx->dc;
3066 struct dmcu *dmcu = dc->res_pool->dmcu;
3067 bool fw_set_brightness = true;
3068
3069 if (dmcu)
3070 fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
3071
3072 if (!fw_set_brightness && panel_cntl->funcs->get_current_backlight)
3073 return panel_cntl->funcs->get_current_backlight(panel_cntl);
3074 else if (abm != NULL && abm->funcs->get_current_backlight != NULL)
3075 return (int) abm->funcs->get_current_backlight(abm);
3076 else
620a0d27 3077 return DC_ERROR_UNEXPECTED;
620a0d27 3078}
4562236b 3079
fefe92fe
AK
3080int dc_link_get_target_backlight_pwm(const struct dc_link *link)
3081{
4dc0b814 3082 struct abm *abm = get_abm_from_stream_res(link);
fefe92fe
AK
3083
3084 if (abm == NULL || abm->funcs->get_target_backlight == NULL)
3085 return DC_ERROR_UNEXPECTED;
3086
3087 return (int) abm->funcs->get_target_backlight(abm);
3088}
3089
3ba01817
YS
3090static struct pipe_ctx *get_pipe_from_link(const struct dc_link *link)
3091{
3092 int i;
3093 struct dc *dc = link->ctx->dc;
3094 struct pipe_ctx *pipe_ctx = NULL;
3095
3096 for (i = 0; i < MAX_PIPES; i++) {
3097 if (dc->current_state->res_ctx.pipe_ctx[i].stream) {
3098 if (dc->current_state->res_ctx.pipe_ctx[i].stream->link == link) {
3099 pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
3100 break;
3101 }
3102 }
3103 }
3104
3105 return pipe_ctx;
3106}
3107
262485a5
AK
3108bool dc_link_set_backlight_level(const struct dc_link *link,
3109 uint32_t backlight_pwm_u16_16,
923fe495 3110 uint32_t frame_ramp)
4562236b 3111{
2b77dcc5 3112 struct dc *dc = link->ctx->dc;
23bfb331 3113
4b0e95d1 3114 DC_LOGGER_INIT(link->ctx->logger);
262485a5
AK
3115 DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
3116 backlight_pwm_u16_16, backlight_pwm_u16_16);
4562236b 3117
d0778ebf 3118 if (dc_is_embedded_signal(link->connector_signal)) {
3ba01817 3119 struct pipe_ctx *pipe_ctx = get_pipe_from_link(link);
4b0e95d1 3120
3ba01817
YS
3121 if (pipe_ctx) {
3122 /* Disable brightness ramping when the display is blanked
3123 * as it can hang the DMCU
3124 */
3125 if (pipe_ctx->plane_state == NULL)
3126 frame_ramp = 0;
3127 } else {
3ba01817
YS
3128 return false;
3129 }
4b0e95d1
YS
3130
3131 dc->hwss.set_backlight_level(
3132 pipe_ctx,
262485a5 3133 backlight_pwm_u16_16,
4b0e95d1 3134 frame_ramp);
4562236b 3135 }
4562236b
HW
3136 return true;
3137}
3138
e5dfcd27
RC
3139bool dc_link_set_psr_allow_active(struct dc_link *link, const bool *allow_active,
3140 bool wait, bool force_static, const unsigned int *power_opts)
4562236b 3141{
2b77dcc5
AK
3142 struct dc *dc = link->ctx->dc;
3143 struct dmcu *dmcu = dc->res_pool->dmcu;
4c1a1335 3144 struct dmub_psr *psr = dc->res_pool->psr;
f56c837a 3145 unsigned int panel_inst;
3548f073 3146
1d496907
KK
3147 if (psr == NULL && force_static)
3148 return false;
3149
f56c837a
ML
3150 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
3151 return false;
3152
7aeb2e47 3153 if ((allow_active != NULL) && (*allow_active == true) && (link->type == dc_connection_none)) {
1b5c30bf
ME
3154 // Don't enter PSR if panel is not connected
3155 return false;
3156 }
3157
e5dfcd27
RC
3158 /* Set power optimization flag */
3159 if (power_opts && link->psr_settings.psr_power_opt != *power_opts) {
3160 link->psr_settings.psr_power_opt = *power_opts;
3161
3162 if (psr != NULL && link->psr_settings.psr_feature_enabled && psr->funcs->psr_set_power_opt)
f0d0c391 3163 psr->funcs->psr_set_power_opt(psr, link->psr_settings.psr_power_opt, panel_inst);
e5dfcd27
RC
3164 }
3165
aa4be416
EK
3166 if (psr != NULL && link->psr_settings.psr_feature_enabled &&
3167 force_static && psr->funcs->psr_force_static)
3168 psr->funcs->psr_force_static(psr, panel_inst);
3169
e5dfcd27
RC
3170 /* Enable or Disable PSR */
3171 if (allow_active && link->psr_settings.psr_allow_active != *allow_active) {
3172 link->psr_settings.psr_allow_active = *allow_active;
3173
e5dfcd27
RC
3174 if (!link->psr_settings.psr_allow_active)
3175 dc_z10_restore(dc);
4074bc3f 3176
e5dfcd27 3177 if (psr != NULL && link->psr_settings.psr_feature_enabled) {
e5dfcd27
RC
3178 psr->funcs->psr_enable(psr, link->psr_settings.psr_allow_active, wait, panel_inst);
3179 } else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) &&
3180 link->psr_settings.psr_feature_enabled)
3181 dmcu->funcs->set_psr_enable(dmcu, link->psr_settings.psr_allow_active, wait);
3182 else
3183 return false;
3184 }
4562236b 3185
4562236b
HW
3186 return true;
3187}
3188
1d496907 3189bool dc_link_get_psr_state(const struct dc_link *link, enum dc_psr_state *state)
e0d08a40 3190{
2b77dcc5
AK
3191 struct dc *dc = link->ctx->dc;
3192 struct dmcu *dmcu = dc->res_pool->dmcu;
4c1a1335 3193 struct dmub_psr *psr = dc->res_pool->psr;
f56c837a
ML
3194 unsigned int panel_inst;
3195
3196 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
3197 return false;
e0d08a40 3198
d1ebfdd8 3199 if (psr != NULL && link->psr_settings.psr_feature_enabled)
f56c837a 3200 psr->funcs->psr_get_state(psr, state, panel_inst);
d1ebfdd8 3201 else if (dmcu != NULL && link->psr_settings.psr_feature_enabled)
1d496907 3202 dmcu->funcs->get_psr_state(dmcu, state);
e0d08a40
RL
3203
3204 return true;
3205}
3206
5ab5e4e6
NC
3207static inline enum physical_phy_id
3208transmitter_to_phy_id(enum transmitter transmitter_value)
3209{
3210 switch (transmitter_value) {
3211 case TRANSMITTER_UNIPHY_A:
3212 return PHYLD_0;
3213 case TRANSMITTER_UNIPHY_B:
3214 return PHYLD_1;
3215 case TRANSMITTER_UNIPHY_C:
3216 return PHYLD_2;
3217 case TRANSMITTER_UNIPHY_D:
3218 return PHYLD_3;
3219 case TRANSMITTER_UNIPHY_E:
3220 return PHYLD_4;
3221 case TRANSMITTER_UNIPHY_F:
3222 return PHYLD_5;
3223 case TRANSMITTER_NUTMEG_CRT:
3224 return PHYLD_6;
3225 case TRANSMITTER_TRAVIS_CRT:
3226 return PHYLD_7;
3227 case TRANSMITTER_TRAVIS_LCD:
3228 return PHYLD_8;
3229 case TRANSMITTER_UNIPHY_G:
3230 return PHYLD_9;
3231 case TRANSMITTER_COUNT:
3232 return PHYLD_COUNT;
3233 case TRANSMITTER_UNKNOWN:
3234 return PHYLD_UNKNOWN;
3235 default:
3236 WARN_ONCE(1, "Unknown transmitter value %d\n",
3237 transmitter_value);
3238 return PHYLD_UNKNOWN;
3239 }
3240}
3241
e0d08a40
RL
3242bool dc_link_setup_psr(struct dc_link *link,
3243 const struct dc_stream_state *stream, struct psr_config *psr_config,
3244 struct psr_context *psr_context)
3245{
2b77dcc5 3246 struct dc *dc;
e0d08a40 3247 struct dmcu *dmcu;
4c1a1335 3248 struct dmub_psr *psr;
e0d08a40 3249 int i;
f56c837a 3250 unsigned int panel_inst;
e0d08a40
RL
3251 /* updateSinkPsrDpcdConfig*/
3252 union dpcd_psr_configuration psr_configuration;
6651875a 3253 union dpcd_sink_active_vtotal_control_mode vtotal_control = {0};
e0d08a40
RL
3254
3255 psr_context->controllerId = CONTROLLER_ID_UNDEFINED;
3256
3257 if (!link)
3258 return false;
3259
2b77dcc5
AK
3260 dc = link->ctx->dc;
3261 dmcu = dc->res_pool->dmcu;
4c1a1335 3262 psr = dc->res_pool->psr;
e0d08a40 3263
4c1a1335 3264 if (!dmcu && !psr)
e0d08a40
RL
3265 return false;
3266
f56c837a
ML
3267 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
3268 return false;
3269
e0d08a40
RL
3270
3271 memset(&psr_configuration, 0, sizeof(psr_configuration));
3272
3273 psr_configuration.bits.ENABLE = 1;
3274 psr_configuration.bits.CRC_VERIFICATION = 1;
3275 psr_configuration.bits.FRAME_CAPTURE_INDICATION =
3276 psr_config->psr_frame_capture_indication_req;
3277
3278 /* Check for PSR v2*/
6d1044a0 3279 if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) {
e0d08a40
RL
3280 /* For PSR v2 selective update.
3281 * Indicates whether sink should start capturing
3282 * immediately following active scan line,
3283 * or starting with the 2nd active scan line.
3284 */
3285 psr_configuration.bits.LINE_CAPTURE_INDICATION = 0;
3286 /*For PSR v2, determines whether Sink should generate
3287 * IRQ_HPD when CRC mismatch is detected.
3288 */
3289 psr_configuration.bits.IRQ_HPD_WITH_CRC_ERROR = 1;
6d1044a0
DZ
3290 /* For PSR v2, set the bit when the Source device will
3291 * be enabling PSR2 operation.
3292 */
3293 psr_configuration.bits.ENABLE_PSR2 = 1;
3294 /* For PSR v2, the Sink device must be able to receive
3295 * SU region updates early in the frame time.
3296 */
3297 psr_configuration.bits.EARLY_TRANSPORT_ENABLE = 1;
e0d08a40
RL
3298 }
3299
3300 dm_helpers_dp_write_dpcd(
3301 link->ctx,
3302 link,
3303 368,
3304 &psr_configuration.raw,
3305 sizeof(psr_configuration.raw));
3306
6d1044a0 3307 if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) {
90bb21cb 3308 dc_power_alpm_dpcd_enable(link, true);
a35806b3
DZ
3309 psr_context->su_granularity_required =
3310 psr_config->su_granularity_required;
3311 psr_context->su_y_granularity =
3312 psr_config->su_y_granularity;
32c453f1
DZ
3313 psr_context->line_time_in_us =
3314 psr_config->line_time_in_us;
6651875a
DZ
3315
3316 if (link->psr_settings.psr_vtotal_control_support) {
3317 psr_context->rate_control_caps = psr_config->rate_control_caps;
3318 vtotal_control.bits.ENABLE = true;
3319 core_link_write_dpcd(link, DP_SINK_PSR_ACTIVE_VTOTAL_CONTROL_MODE,
3320 &vtotal_control.raw, sizeof(vtotal_control.raw));
3321 }
6d1044a0
DZ
3322 }
3323
e0d08a40
RL
3324 psr_context->channel = link->ddc->ddc_pin->hw_info.ddc_channel;
3325 psr_context->transmitterId = link->link_enc->transmitter;
3326 psr_context->engineId = link->link_enc->preferred_engine;
3327
3328 for (i = 0; i < MAX_PIPES; i++) {
2b77dcc5 3329 if (dc->current_state->res_ctx.pipe_ctx[i].stream
e0d08a40
RL
3330 == stream) {
3331 /* dmcu -1 for all controller id values,
3332 * therefore +1 here
3333 */
3334 psr_context->controllerId =
2b77dcc5 3335 dc->current_state->res_ctx.
e0d08a40
RL
3336 pipe_ctx[i].stream_res.tg->inst + 1;
3337 break;
3338 }
3339 }
3340
3341 /* Hardcoded for now. Can be Pcie or Uniphy (or Unknown)*/
3342 psr_context->phyType = PHY_TYPE_UNIPHY;
3343 /*PhyId is associated with the transmitter id*/
5ab5e4e6
NC
3344 psr_context->smuPhyId =
3345 transmitter_to_phy_id(link->link_enc->transmitter);
e0d08a40
RL
3346
3347 psr_context->crtcTimingVerticalTotal = stream->timing.v_total;
5b5abe95 3348 psr_context->vsync_rate_hz = div64_u64(div64_u64((stream->
e0d08a40
RL
3349 timing.pix_clk_100hz * 100),
3350 stream->timing.v_total),
3351 stream->timing.h_total);
3352
3353 psr_context->psrSupportedDisplayConfig = true;
3354 psr_context->psrExitLinkTrainingRequired =
3355 psr_config->psr_exit_link_training_required;
3356 psr_context->sdpTransmitLineNumDeadline =
3357 psr_config->psr_sdp_transmit_line_num_deadline;
3358 psr_context->psrFrameCaptureIndicationReq =
3359 psr_config->psr_frame_capture_indication_req;
3360
3361 psr_context->skipPsrWaitForPllLock = 0; /* only = 1 in KV */
3362
3363 psr_context->numberOfControllers =
3364 link->dc->res_pool->timing_generator_count;
3365
3366 psr_context->rfb_update_auto_en = true;
3367
3368 /* 2 frames before enter PSR. */
3369 psr_context->timehyst_frames = 2;
3370 /* half a frame
3371 * (units in 100 lines, i.e. a value of 1 represents 100 lines)
3372 */
3373 psr_context->hyst_lines = stream->timing.v_total / 2 / 100;
3374 psr_context->aux_repeats = 10;
3375
3376 psr_context->psr_level.u32all = 0;
3377
e0d08a40 3378 /*skip power down the single pipe since it blocks the cstate*/
8fe44c08 3379#if defined(CONFIG_DRM_AMD_DC_DCN)
cbaf919f 3380 if (link->ctx->asic_id.chip_family >= FAMILY_RV) {
501867d0
QZ
3381 switch(link->ctx->asic_id.chip_family) {
3382 case FAMILY_YELLOW_CARP:
3383 case AMDGPU_FAMILY_GC_10_3_6:
08ebadfc 3384 case AMDGPU_FAMILY_GC_11_0_1:
00812bfc 3385 if (dc->debug.disable_z10 || dc->debug.psr_skip_crtc_disable)
8cab4ef0 3386 psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
501867d0
QZ
3387 break;
3388 default:
3389 psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
3390 break;
3391 }
cbaf919f
NK
3392 }
3393#else
2ff3cf82 3394 if (link->ctx->asic_id.chip_family >= FAMILY_RV)
e0d08a40 3395 psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
cbaf919f 3396#endif
e0d08a40
RL
3397
3398 /* SMU will perform additional powerdown sequence.
3399 * For unsupported ASICs, set psr_level flag to skip PSR
3400 * static screen notification to SMU.
3401 * (Always set for DAL2, did not check ASIC)
3402 */
3403 psr_context->allow_smu_optimizations = psr_config->allow_smu_optimizations;
175f0971 3404 psr_context->allow_multi_disp_optimizations = psr_config->allow_multi_disp_optimizations;
e0d08a40
RL
3405
3406 /* Complete PSR entry before aborting to prevent intermittent
3407 * freezes on certain eDPs
3408 */
3409 psr_context->psr_level.bits.DISABLE_PSR_ENTRY_ABORT = 1;
3410
c7eac19e
DZ
3411 /* enable ALPM */
3412 psr_context->psr_level.bits.DISABLE_ALPM = 0;
3413 psr_context->psr_level.bits.ALPM_DEFAULT_PD_MODE = 1;
3414
e0d08a40
RL
3415 /* Controls additional delay after remote frame capture before
3416 * continuing power down, default = 0
3417 */
3418 psr_context->frame_delay = 0;
3419
99c04671 3420 if (psr) {
f56c837a
ML
3421 link->psr_settings.psr_feature_enabled = psr->funcs->psr_copy_settings(psr,
3422 link, psr_context, panel_inst);
99c04671
EK
3423 link->psr_settings.psr_power_opt = 0;
3424 link->psr_settings.psr_allow_active = 0;
3425 }
4c1a1335 3426 else
d1ebfdd8 3427 link->psr_settings.psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, psr_context);
e0d08a40
RL
3428
3429 /* psr_enabled == 0 indicates setup_psr did not succeed, but this
3430 * should not happen since firmware should be running at this point
3431 */
d1ebfdd8 3432 if (link->psr_settings.psr_feature_enabled == 0)
e0d08a40
RL
3433 ASSERT(0);
3434
3435 return true;
3436
3437}
3438
b8e0b3d6
WW
3439void dc_link_get_psr_residency(const struct dc_link *link, uint32_t *residency)
3440{
3441 struct dc *dc = link->ctx->dc;
3442 struct dmub_psr *psr = dc->res_pool->psr;
74b4afad
ML
3443 unsigned int panel_inst;
3444
3445 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
3446 return;
b8e0b3d6 3447
74b4afad 3448 /* PSR residency measurements only supported on DMCUB */
b8e0b3d6 3449 if (psr != NULL && link->psr_settings.psr_feature_enabled)
74b4afad 3450 psr->funcs->psr_get_residency(psr, residency, panel_inst);
b8e0b3d6
WW
3451 else
3452 *residency = 0;
3453}
3454
6651875a
DZ
3455bool dc_link_set_sink_vtotal_in_psr_active(const struct dc_link *link, uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su)
3456{
3457 struct dc *dc = link->ctx->dc;
3458 struct dmub_psr *psr = dc->res_pool->psr;
3459
3460 if (psr == NULL || !link->psr_settings.psr_feature_enabled || !link->psr_settings.psr_vtotal_control_support)
3461 return false;
3462
3463 psr->funcs->psr_set_sink_vtotal_in_psr_active(psr, psr_vtotal_idle, psr_vtotal_su);
3464
3465 return true;
3466}
3467
d0778ebf 3468const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
4562236b 3469{
4562236b
HW
3470 return &link->link_status;
3471}
3472
d0778ebf 3473void core_link_resume(struct dc_link *link)
4562236b 3474{
d0778ebf 3475 if (link->connector_signal != SIGNAL_TYPE_VIRTUAL)
b0c4e977 3476 program_hpd_filter(link);
4562236b
HW
3477}
3478
0971c40e 3479static struct fixed31_32 get_pbn_per_slot(struct dc_stream_state *stream)
4562236b 3480{
332c1191 3481 struct fixed31_32 mbytes_per_sec;
fe798de5
CP
3482 uint32_t link_rate_in_mbytes_per_sec = dc_link_bandwidth_kbps(stream->link,
3483 &stream->link->cur_link_settings);
332c1191
NC
3484 link_rate_in_mbytes_per_sec /= 8000; /* Kbits to MBytes */
3485
3486 mbytes_per_sec = dc_fixpt_from_int(link_rate_in_mbytes_per_sec);
3487
3488 return dc_fixpt_div_int(mbytes_per_sec, 54);
4562236b
HW
3489}
3490
786b4061 3491static struct fixed31_32 get_pbn_from_bw_in_kbps(uint64_t kbps)
4562236b 3492{
4562236b 3493 struct fixed31_32 peak_kbps;
8532467c
ML
3494 uint32_t numerator = 0;
3495 uint32_t denominator = 1;
4562236b 3496
4562236b
HW
3497 /*
3498 * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
3499 * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on
3500 * common multiplier to render an integer PBN for all link rate/lane
3501 * counts combinations
3502 * calculate
3503 * peak_kbps *= (1006/1000)
3504 * peak_kbps *= (64/54)
3505 * peak_kbps *= 8 convert to bytes
3506 */
3507
3508 numerator = 64 * PEAK_FACTOR_X1000;
3509 denominator = 54 * 8 * 1000 * 1000;
3510 kbps *= numerator;
eb0e5154 3511 peak_kbps = dc_fixpt_from_fraction(kbps, denominator);
4562236b
HW
3512
3513 return peak_kbps;
3514}
3515
786b4061
WL
3516static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
3517{
3518 uint64_t kbps;
3519
3520 kbps = dc_bandwidth_in_kbps_from_timing(&pipe_ctx->stream->timing);
3521 return get_pbn_from_bw_in_kbps(kbps);
3522}
3523
4562236b 3524static void update_mst_stream_alloc_table(
d0778ebf 3525 struct dc_link *link,
4562236b 3526 struct stream_encoder *stream_enc,
d740e0bf 3527 struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
8c5e9bbb 3528 const struct dc_dp_mst_stream_allocation_table *proposed_table)
4562236b 3529{
c78abac9 3530 struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
4562236b
HW
3531 struct link_mst_stream_allocation *dc_alloc;
3532
3533 int i;
3534 int j;
3535
3536 /* if DRM proposed_table has more than one new payload */
3537 ASSERT(proposed_table->stream_count -
3538 link->mst_stream_alloc_table.stream_count < 2);
3539
d0778ebf 3540 /* copy proposed_table to link, add stream encoder */
4562236b
HW
3541 for (i = 0; i < proposed_table->stream_count; i++) {
3542
3543 for (j = 0; j < link->mst_stream_alloc_table.stream_count; j++) {
3544 dc_alloc =
3545 &link->mst_stream_alloc_table.stream_allocations[j];
3546
3547 if (dc_alloc->vcp_id ==
3548 proposed_table->stream_allocations[i].vcp_id) {
3549
3550 work_table[i] = *dc_alloc;
786b4061 3551 work_table[i].slot_count = proposed_table->stream_allocations[i].slot_count;
4562236b
HW
3552 break; /* exit j loop */
3553 }
3554 }
3555
3556 /* new vcp_id */
3557 if (j == link->mst_stream_alloc_table.stream_count) {
3558 work_table[i].vcp_id =
3559 proposed_table->stream_allocations[i].vcp_id;
3560 work_table[i].slot_count =
3561 proposed_table->stream_allocations[i].slot_count;
3562 work_table[i].stream_enc = stream_enc;
d740e0bf 3563 work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc;
4562236b
HW
3564 }
3565 }
3566
3567 /* update link->mst_stream_alloc_table with work_table */
3568 link->mst_stream_alloc_table.stream_count =
3569 proposed_table->stream_count;
3570 for (i = 0; i < MAX_CONTROLLER_NUM; i++)
3571 link->mst_stream_alloc_table.stream_allocations[i] =
3572 work_table[i];
3573}
d9eb8fea 3574
cc67aae1
WL
3575static void remove_stream_from_alloc_table(
3576 struct dc_link *link,
3577 struct stream_encoder *dio_stream_enc,
3578 struct hpo_dp_stream_encoder *hpo_dp_stream_enc)
3579{
3580 int i = 0;
3581 struct link_mst_stream_allocation_table *table =
3582 &link->mst_stream_alloc_table;
3583
3584 if (hpo_dp_stream_enc) {
3585 for (; i < table->stream_count; i++)
3586 if (hpo_dp_stream_enc == table->stream_allocations[i].hpo_dp_stream_enc)
3587 break;
3588 } else {
3589 for (; i < table->stream_count; i++)
3590 if (dio_stream_enc == table->stream_allocations[i].stream_enc)
3591 break;
3592 }
3593
3594 if (i < table->stream_count) {
3595 i++;
3596 for (; i < table->stream_count; i++)
3597 table->stream_allocations[i-1] = table->stream_allocations[i];
3598 memset(&table->stream_allocations[table->stream_count-1], 0,
3599 sizeof(struct link_mst_stream_allocation));
3600 table->stream_count--;
3601 }
3602}
3603
356af2f3
GS
3604static void dc_log_vcp_x_y(const struct dc_link *link, struct fixed31_32 avg_time_slots_per_mtp)
3605{
3606 const uint32_t VCP_Y_PRECISION = 1000;
3607 uint64_t vcp_x, vcp_y;
3608
3609 // Add 0.5*(1/VCP_Y_PRECISION) to round up to decimal precision
3610 avg_time_slots_per_mtp = dc_fixpt_add(
3611 avg_time_slots_per_mtp, dc_fixpt_from_fraction(1, 2 * VCP_Y_PRECISION));
3612
3613 vcp_x = dc_fixpt_floor(avg_time_slots_per_mtp);
3614 vcp_y = dc_fixpt_floor(
3615 dc_fixpt_mul_int(
3616 dc_fixpt_sub_int(avg_time_slots_per_mtp, dc_fixpt_floor(avg_time_slots_per_mtp)),
3617 VCP_Y_PRECISION));
3618
3619 if (link->type == dc_connection_mst_branch)
3620 DC_LOG_DP2("MST Update Payload: set_throttled_vcp_size slot X.Y for MST stream "
3621 "X: %lld Y: %lld/%d", vcp_x, vcp_y, VCP_Y_PRECISION);
3622 else
3623 DC_LOG_DP2("SST Update Payload: set_throttled_vcp_size slot X.Y for SST stream "
3624 "X: %lld Y: %lld/%d", vcp_x, vcp_y, VCP_Y_PRECISION);
3625}
3626
f01ee019
FZ
3627/*
3628 * Payload allocation/deallocation for SST introduced in DP2.0
3629 */
240e6d25
IB
3630static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx,
3631 bool allocate)
f01ee019
FZ
3632{
3633 struct dc_stream_state *stream = pipe_ctx->stream;
3634 struct dc_link *link = stream->link;
f01ee019
FZ
3635 struct link_mst_stream_allocation_table proposed_table = {0};
3636 struct fixed31_32 avg_time_slots_per_mtp;
5279e091 3637 const struct dc_link_settings empty_link_settings = {0};
9d8033d6 3638 const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
f01ee019
FZ
3639 DC_LOGGER_INIT(link->ctx->logger);
3640
3641 /* slot X.Y for SST payload deallocate */
3642 if (!allocate) {
3643 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
3644
356af2f3 3645 dc_log_vcp_x_y(link, avg_time_slots_per_mtp);
f01ee019 3646
9d8033d6
WL
3647 if (link_hwss->ext.set_throttled_vcp_size)
3648 link_hwss->ext.set_throttled_vcp_size(pipe_ctx,
3649 avg_time_slots_per_mtp);
3650 if (link_hwss->ext.set_hblank_min_symbol_width)
3651 link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
5279e091
WL
3652 &empty_link_settings,
3653 avg_time_slots_per_mtp);
f01ee019
FZ
3654 }
3655
3656 /* calculate VC payload and update branch with new payload allocation table*/
3657 if (!dpcd_write_128b_132b_sst_payload_allocation_table(
3658 stream,
3659 link,
3660 &proposed_table,
3661 allocate)) {
3662 DC_LOG_ERROR("SST Update Payload: Failed to update "
3663 "allocation table for "
3664 "pipe idx: %d\n",
3665 pipe_ctx->pipe_idx);
e5309d7f 3666 return DC_FAIL_DP_PAYLOAD_ALLOCATION;
f01ee019
FZ
3667 }
3668
a5b79943 3669 proposed_table.stream_allocations[0].hpo_dp_stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
f01ee019
FZ
3670
3671 ASSERT(proposed_table.stream_count == 1);
3672
3673 //TODO - DP2.0 Logging: Instead of hpo_dp_stream_enc pointer, log instance id
3674 DC_LOG_DP2("SST Update Payload: hpo_dp_stream_enc: %p "
3675 "vcp_id: %d "
3676 "slot_count: %d\n",
3677 (void *) proposed_table.stream_allocations[0].hpo_dp_stream_enc,
3678 proposed_table.stream_allocations[0].vcp_id,
3679 proposed_table.stream_allocations[0].slot_count);
3680
3681 /* program DP source TX for payload */
a5b79943 3682 link_hwss->ext.update_stream_allocation_table(link, &pipe_ctx->link_res,
f01ee019
FZ
3683 &proposed_table);
3684
3685 /* poll for ACT handled */
3686 if (!dpcd_poll_for_allocation_change_trigger(link)) {
3687 // Failures will result in blackscreen and errors logged
3688 BREAK_TO_DEBUGGER();
3689 }
3690
3691 /* slot X.Y for SST payload allocate */
d5a43956 3692 if (allocate && link_dp_get_encoding_format(&link->cur_link_settings) ==
c371b0d1 3693 DP_128b_132b_ENCODING) {
f01ee019
FZ
3694 avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(stream, link);
3695
356af2f3 3696 dc_log_vcp_x_y(link, avg_time_slots_per_mtp);
f01ee019 3697
9d8033d6
WL
3698 if (link_hwss->ext.set_throttled_vcp_size)
3699 link_hwss->ext.set_throttled_vcp_size(pipe_ctx,
3700 avg_time_slots_per_mtp);
3701 if (link_hwss->ext.set_hblank_min_symbol_width)
3702 link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
5279e091
WL
3703 &link->cur_link_settings,
3704 avg_time_slots_per_mtp);
f01ee019
FZ
3705 }
3706
3707 /* Always return DC_OK.
3708 * If part of sequence fails, log failure(s) and show blackscreen
3709 */
3710 return DC_OK;
3711}
4562236b
HW
3712
3713/* convert link_mst_stream_alloc_table to dm dp_mst_stream_alloc_table
3714 * because stream_encoder is not exposed to dm
3715 */
48af9b91 3716enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
4562236b 3717{
0971c40e 3718 struct dc_stream_state *stream = pipe_ctx->stream;
ceb3dbb4 3719 struct dc_link *link = stream->link;
8c5e9bbb 3720 struct dc_dp_mst_stream_allocation_table proposed_table = {0};
4562236b
HW
3721 struct fixed31_32 avg_time_slots_per_mtp;
3722 struct fixed31_32 pbn;
3723 struct fixed31_32 pbn_per_slot;
2fcb2697 3724 int i;
48af9b91 3725 enum act_return_status ret;
9d8033d6 3726 const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
5d4b05dd 3727 DC_LOGGER_INIT(link->ctx->logger);
4562236b
HW
3728
3729 /* enable_link_dp_mst already check link->enabled_stream_count
3730 * and stream is in link->stream[]. This is called during set mode,
3731 * stream_enc is available.
3732 */
3733
3734 /* get calculate VC payload for stream: stream_alloc */
3735 if (dm_helpers_dp_mst_write_payload_allocation_table(
3736 stream->ctx,
4fa086b9 3737 stream,
4562236b 3738 &proposed_table,
d9eb8fea 3739 true))
4562236b 3740 update_mst_stream_alloc_table(
d740e0bf
FZ
3741 link,
3742 pipe_ctx->stream_res.stream_enc,
3743 pipe_ctx->stream_res.hpo_dp_stream_enc,
3744 &proposed_table);
4562236b 3745 else
1296423b 3746 DC_LOG_WARNING("Failed to update"
4562236b
HW
3747 "MST allocation table for"
3748 "pipe idx:%d\n",
3749 pipe_ctx->pipe_idx);
3750
1296423b 3751 DC_LOG_MST("%s "
4562236b
HW
3752 "stream_count: %d: \n ",
3753 __func__,
3754 link->mst_stream_alloc_table.stream_count);
3755
3756 for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
3032deb5 3757 DC_LOG_MST("stream_enc[%d]: %p "
d740e0bf 3758 "stream[%d].hpo_dp_stream_enc: %p "
4562236b
HW
3759 "stream[%d].vcp_id: %d "
3760 "stream[%d].slot_count: %d\n",
3761 i,
3032deb5 3762 (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
4562236b 3763 i,
d740e0bf
FZ
3764 (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
3765 i,
4562236b
HW
3766 link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
3767 i,
3768 link->mst_stream_alloc_table.stream_allocations[i].slot_count);
3769 }
3770
3771 ASSERT(proposed_table.stream_count > 0);
3772
3773 /* program DP source TX for payload */
a5b79943 3774 if (link_hwss->ext.update_stream_allocation_table == NULL ||
d5a43956 3775 link_dp_get_encoding_format(&link->cur_link_settings) == DP_UNKNOWN_ENCODING) {
d740e0bf
FZ
3776 DC_LOG_ERROR("Failure: unknown encoding format\n");
3777 return DC_ERROR_UNEXPECTED;
3778 }
4562236b 3779
a5b79943
WL
3780 link_hwss->ext.update_stream_allocation_table(link,
3781 &pipe_ctx->link_res,
3782 &link->mst_stream_alloc_table);
3783
4562236b 3784 /* send down message */
48af9b91 3785 ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
4562236b 3786 stream->ctx,
4fa086b9 3787 stream);
4562236b 3788
48af9b91
AL
3789 if (ret != ACT_LINK_LOST) {
3790 dm_helpers_dp_mst_send_payload_allocation(
3791 stream->ctx,
3792 stream,
3793 true);
3794 }
4562236b
HW
3795
3796 /* slot X.Y for only current stream */
3797 pbn_per_slot = get_pbn_per_slot(stream);
7dd4f4df
AT
3798 if (pbn_per_slot.value == 0) {
3799 DC_LOG_ERROR("Failure: pbn_per_slot==0 not allowed. Cannot continue, returning DC_UNSUPPORTED_VALUE.\n");
3800 return DC_UNSUPPORTED_VALUE;
3801 }
4562236b 3802 pbn = get_pbn_from_timing(pipe_ctx);
eb0e5154 3803 avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
4562236b 3804
5279e091
WL
3805 dc_log_vcp_x_y(link, avg_time_slots_per_mtp);
3806
9d8033d6
WL
3807 if (link_hwss->ext.set_throttled_vcp_size)
3808 link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
3809 if (link_hwss->ext.set_hblank_min_symbol_width)
3810 link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
5279e091 3811 &link->cur_link_settings,
d740e0bf 3812 avg_time_slots_per_mtp);
d740e0bf
FZ
3813
3814 return DC_OK;
3815
3816}
3817
d740e0bf
FZ
3818enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
3819{
3820 struct dc_stream_state *stream = pipe_ctx->stream;
3821 struct dc_link *link = stream->link;
3822 struct fixed31_32 avg_time_slots_per_mtp;
3823 struct fixed31_32 pbn;
3824 struct fixed31_32 pbn_per_slot;
8c5e9bbb 3825 struct dc_dp_mst_stream_allocation_table proposed_table = {0};
d740e0bf 3826 uint8_t i;
9d8033d6 3827 const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
d740e0bf
FZ
3828 DC_LOGGER_INIT(link->ctx->logger);
3829
3830 /* decrease throttled vcp size */
3831 pbn_per_slot = get_pbn_per_slot(stream);
3832 pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
3833 avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
3834
9d8033d6
WL
3835 if (link_hwss->ext.set_throttled_vcp_size)
3836 link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
3837 if (link_hwss->ext.set_hblank_min_symbol_width)
3838 link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
5279e091 3839 &link->cur_link_settings,
d740e0bf
FZ
3840 avg_time_slots_per_mtp);
3841
3842 /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
3843 dm_helpers_dp_mst_send_payload_allocation(
3844 stream->ctx,
3845 stream,
3846 true);
3847
3848 /* notify immediate branch device table update */
3849 if (dm_helpers_dp_mst_write_payload_allocation_table(
3850 stream->ctx,
3851 stream,
3852 &proposed_table,
3853 true)) {
3854 /* update mst stream allocation table software state */
3855 update_mst_stream_alloc_table(
3856 link,
3857 pipe_ctx->stream_res.stream_enc,
3858 pipe_ctx->stream_res.hpo_dp_stream_enc,
3859 &proposed_table);
3860 } else {
3861 DC_LOG_WARNING("Failed to update"
3862 "MST allocation table for"
3863 "pipe idx:%d\n",
3864 pipe_ctx->pipe_idx);
3865 }
3866
3867 DC_LOG_MST("%s "
3868 "stream_count: %d: \n ",
3869 __func__,
3870 link->mst_stream_alloc_table.stream_count);
3871
3872 for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
3873 DC_LOG_MST("stream_enc[%d]: %p "
f18368b6 3874 "stream[%d].hpo_dp_stream_enc: %p "
d740e0bf
FZ
3875 "stream[%d].vcp_id: %d "
3876 "stream[%d].slot_count: %d\n",
3877 i,
3878 (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
3879 i,
f18368b6
WL
3880 (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
3881 i,
d740e0bf
FZ
3882 link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
3883 i,
3884 link->mst_stream_alloc_table.stream_allocations[i].slot_count);
3885 }
3886
3887 ASSERT(proposed_table.stream_count > 0);
3888
3889 /* update mst stream allocation table hardware state */
a5b79943 3890 if (link_hwss->ext.update_stream_allocation_table == NULL ||
d5a43956 3891 link_dp_get_encoding_format(&link->cur_link_settings) == DP_UNKNOWN_ENCODING) {
a5b79943
WL
3892 DC_LOG_ERROR("Failure: unknown encoding format\n");
3893 return DC_ERROR_UNEXPECTED;
3894 }
3895
3896 link_hwss->ext.update_stream_allocation_table(link, &pipe_ctx->link_res,
d740e0bf
FZ
3897 &link->mst_stream_alloc_table);
3898
3899 /* poll for immediate branch device ACT handled */
0b58162e 3900 dm_helpers_dp_mst_poll_for_allocation_change_trigger(
d740e0bf
FZ
3901 stream->ctx,
3902 stream);
4562236b
HW
3903
3904 return DC_OK;
d740e0bf
FZ
3905}
3906
3907enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
3908{
3909 struct dc_stream_state *stream = pipe_ctx->stream;
3910 struct dc_link *link = stream->link;
3911 struct fixed31_32 avg_time_slots_per_mtp;
3912 struct fixed31_32 pbn;
3913 struct fixed31_32 pbn_per_slot;
8c5e9bbb 3914 struct dc_dp_mst_stream_allocation_table proposed_table = {0};
d740e0bf
FZ
3915 uint8_t i;
3916 enum act_return_status ret;
9d8033d6 3917 const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
d740e0bf
FZ
3918 DC_LOGGER_INIT(link->ctx->logger);
3919
3920 /* notify immediate branch device table update */
3921 if (dm_helpers_dp_mst_write_payload_allocation_table(
3922 stream->ctx,
3923 stream,
3924 &proposed_table,
3925 true)) {
3926 /* update mst stream allocation table software state */
3927 update_mst_stream_alloc_table(
3928 link,
3929 pipe_ctx->stream_res.stream_enc,
3930 pipe_ctx->stream_res.hpo_dp_stream_enc,
3931 &proposed_table);
3932 }
3933
3934 DC_LOG_MST("%s "
3935 "stream_count: %d: \n ",
3936 __func__,
3937 link->mst_stream_alloc_table.stream_count);
3938
3939 for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
3940 DC_LOG_MST("stream_enc[%d]: %p "
f18368b6 3941 "stream[%d].hpo_dp_stream_enc: %p "
d740e0bf
FZ
3942 "stream[%d].vcp_id: %d "
3943 "stream[%d].slot_count: %d\n",
3944 i,
3945 (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
3946 i,
f18368b6
WL
3947 (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
3948 i,
d740e0bf
FZ
3949 link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
3950 i,
3951 link->mst_stream_alloc_table.stream_allocations[i].slot_count);
3952 }
3953
3954 ASSERT(proposed_table.stream_count > 0);
4562236b 3955
d740e0bf 3956 /* update mst stream allocation table hardware state */
990cad0e 3957 if (link_hwss->ext.update_stream_allocation_table == NULL ||
d5a43956 3958 link_dp_get_encoding_format(&link->cur_link_settings) == DP_UNKNOWN_ENCODING) {
990cad0e
WL
3959 DC_LOG_ERROR("Failure: unknown encoding format\n");
3960 return DC_ERROR_UNEXPECTED;
3961 }
3962
3963 link_hwss->ext.update_stream_allocation_table(link, &pipe_ctx->link_res,
d740e0bf
FZ
3964 &link->mst_stream_alloc_table);
3965
3966 /* poll for immediate branch device ACT handled */
3967 ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
3968 stream->ctx,
3969 stream);
3970
3971 if (ret != ACT_LINK_LOST) {
3972 /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
3973 dm_helpers_dp_mst_send_payload_allocation(
3974 stream->ctx,
3975 stream,
3976 true);
3977 }
3978
3979 /* increase throttled vcp size */
3980 pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
3981 pbn_per_slot = get_pbn_per_slot(stream);
3982 avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
3983
9d8033d6
WL
3984 if (link_hwss->ext.set_throttled_vcp_size)
3985 link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
3986 if (link_hwss->ext.set_hblank_min_symbol_width)
3987 link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
5279e091 3988 &link->cur_link_settings,
d740e0bf
FZ
3989 avg_time_slots_per_mtp);
3990
3991 return DC_OK;
4562236b
HW
3992}
3993
3994static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
3995{
0971c40e 3996 struct dc_stream_state *stream = pipe_ctx->stream;
ceb3dbb4 3997 struct dc_link *link = stream->link;
8c5e9bbb 3998 struct dc_dp_mst_stream_allocation_table proposed_table = {0};
eb0e5154 3999 struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
2fcb2697 4000 int i;
d0778ebf 4001 bool mst_mode = (link->type == dc_connection_mst_branch);
9d8033d6 4002 const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
5279e091 4003 const struct dc_link_settings empty_link_settings = {0};
5d4b05dd 4004 DC_LOGGER_INIT(link->ctx->logger);
4562236b
HW
4005
4006 /* deallocate_mst_payload is called before disable link. When mode or
4007 * disable/enable monitor, new stream is created which is not in link
4008 * stream[] yet. For this, payload is not allocated yet, so de-alloc
4009 * should not done. For new mode set, map_resources will get engine
4010 * for new stream, so stream_enc->id should be validated until here.
4011 */
4012
4013 /* slot X.Y */
9d8033d6
WL
4014 if (link_hwss->ext.set_throttled_vcp_size)
4015 link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
4016 if (link_hwss->ext.set_hblank_min_symbol_width)
4017 link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
5279e091 4018 &empty_link_settings,
d740e0bf 4019 avg_time_slots_per_mtp);
4562236b 4020
4562236b 4021 if (mst_mode) {
cc67aae1
WL
4022 /* when link is in mst mode, reply on mst manager to remove
4023 * payload
4024 */
4562236b
HW
4025 if (dm_helpers_dp_mst_write_payload_allocation_table(
4026 stream->ctx,
4fa086b9 4027 stream,
4562236b 4028 &proposed_table,
cc67aae1 4029 false))
4562236b 4030
d740e0bf 4031 update_mst_stream_alloc_table(
cc67aae1
WL
4032 link,
4033 pipe_ctx->stream_res.stream_enc,
4034 pipe_ctx->stream_res.hpo_dp_stream_enc,
4035 &proposed_table);
4036 else
4037 DC_LOG_WARNING("Failed to update"
4038 "MST allocation table for"
4039 "pipe idx:%d\n",
4040 pipe_ctx->pipe_idx);
4041 } else {
4042 /* when link is no longer in mst mode (mst hub unplugged),
4043 * remove payload with default dc logic
4044 */
4045 remove_stream_from_alloc_table(link, pipe_ctx->stream_res.stream_enc,
4046 pipe_ctx->stream_res.hpo_dp_stream_enc);
4562236b
HW
4047 }
4048
1296423b 4049 DC_LOG_MST("%s"
4562236b
HW
4050 "stream_count: %d: ",
4051 __func__,
4052 link->mst_stream_alloc_table.stream_count);
4053
4054 for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
d740e0bf
FZ
4055 DC_LOG_MST("stream_enc[%d]: %p "
4056 "stream[%d].hpo_dp_stream_enc: %p "
4057 "stream[%d].vcp_id: %d "
4058 "stream[%d].slot_count: %d\n",
4059 i,
4060 (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
4061 i,
4062 (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
4063 i,
4064 link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
4065 i,
4066 link->mst_stream_alloc_table.stream_allocations[i].slot_count);
4562236b
HW
4067 }
4068
a5b79943
WL
4069 /* update mst stream allocation table hardware state */
4070 if (link_hwss->ext.update_stream_allocation_table == NULL ||
d5a43956 4071 link_dp_get_encoding_format(&link->cur_link_settings) == DP_UNKNOWN_ENCODING) {
9ff28ab4 4072 DC_LOG_DEBUG("Unknown encoding format\n");
d740e0bf
FZ
4073 return DC_ERROR_UNEXPECTED;
4074 }
4562236b 4075
a5b79943
WL
4076 link_hwss->ext.update_stream_allocation_table(link, &pipe_ctx->link_res,
4077 &link->mst_stream_alloc_table);
4078
4562236b
HW
4079 if (mst_mode) {
4080 dm_helpers_dp_mst_poll_for_allocation_change_trigger(
4081 stream->ctx,
4fa086b9 4082 stream);
4562236b
HW
4083
4084 dm_helpers_dp_mst_send_payload_allocation(
4085 stream->ctx,
4fa086b9 4086 stream,
4562236b
HW
4087 false);
4088 }
4089
4090 return DC_OK;
4091}
ffdaeb1f 4092
ffdaeb1f 4093
d462fcf5
BL
4094#if defined(CONFIG_DRM_AMD_DC_HDCP)
4095static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
4096{
4097 struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp;
64d283cb 4098 struct link_encoder *link_enc = NULL;
580013b2
WL
4099 struct cp_psp_stream_config config = {0};
4100 enum dp_panel_mode panel_mode =
4101 dp_get_panel_mode(pipe_ctx->stream->link);
64d283cb 4102
580013b2
WL
4103 if (cp_psp == NULL || cp_psp->funcs.update_stream_config == NULL)
4104 return;
d462fcf5 4105
66d58bf7 4106 link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
580013b2
WL
4107 ASSERT(link_enc);
4108 if (link_enc == NULL)
4109 return;
cfd3f70e 4110
580013b2
WL
4111 /* otg instance */
4112 config.otg_inst = (uint8_t) pipe_ctx->stream_res.tg->inst;
ffd89aa9 4113
580013b2
WL
4114 /* dig front end */
4115 config.dig_fe = (uint8_t) pipe_ctx->stream_res.stream_enc->stream_enc_inst;
ffd89aa9 4116
580013b2
WL
4117 /* stream encoder index */
4118 config.stream_enc_idx = pipe_ctx->stream_res.stream_enc->id - ENGINE_ID_DIGA;
d5a43956 4119 if (link_is_dp_128b_132b_signal(pipe_ctx))
580013b2
WL
4120 config.stream_enc_idx =
4121 pipe_ctx->stream_res.hpo_dp_stream_enc->id - ENGINE_ID_HPO_DP_0;
ffd89aa9 4122
580013b2
WL
4123 /* dig back end */
4124 config.dig_be = pipe_ctx->stream->link->link_enc_hw_inst;
4125
4126 /* link encoder index */
4127 config.link_enc_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
d5a43956 4128 if (link_is_dp_128b_132b_signal(pipe_ctx))
580013b2 4129 config.link_enc_idx = pipe_ctx->link_res.hpo_dp_link_enc->inst;
d9eb8fea 4130
84ebd73e
MG
4131 /* dio output index is dpia index for DPIA endpoint & dcio index by default */
4132 if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
4133 config.dio_output_idx = pipe_ctx->stream->link->link_id.enum_id - ENUM_ID_1;
4134 else
4135 config.dio_output_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
4136
580013b2
WL
4137
4138 /* phy index */
4139 config.phy_idx = resource_transmitter_to_phy_idx(
4140 pipe_ctx->stream->link->dc, link_enc->transmitter);
4141 if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
4142 /* USB4 DPIA doesn't use PHY in our soc, initialize it to 0 */
4143 config.phy_idx = 0;
4144
4145 /* stream properties */
4146 config.assr_enabled = (panel_mode == DP_PANEL_MODE_EDP) ? 1 : 0;
4147 config.mst_enabled = (pipe_ctx->stream->signal ==
4148 SIGNAL_TYPE_DISPLAY_PORT_MST) ? 1 : 0;
d5a43956 4149 config.dp2_enabled = link_is_dp_128b_132b_signal(pipe_ctx) ? 1 : 0;
580013b2
WL
4150 config.usb4_enabled = (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) ?
4151 1 : 0;
4152 config.dpms_off = dpms_off;
4153
4154 /* dm stream context */
4155 config.dm_stream_ctx = pipe_ctx->stream->dm_stream_context;
4156
4157 cp_psp->funcs.update_stream_config(cp_psp->handle, &config);
d462fcf5
BL
4158}
4159#endif
4562236b 4160
f01ee019
FZ
4161static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pipe_ctx *pipe_ctx)
4162{
4163 struct dc *dc = pipe_ctx->stream->ctx->dc;
4164 struct dc_stream_state *stream = pipe_ctx->stream;
4165 struct link_mst_stream_allocation_table proposed_table = {0};
4166 struct fixed31_32 avg_time_slots_per_mtp;
4167 uint8_t req_slot_count = 0;
4168 uint8_t vc_id = 1; /// VC ID always 1 for SST
017860c9 4169 struct dc_link_settings link_settings = pipe_ctx->link_config.dp_link_settings;
9d8033d6 4170 const struct link_hwss *link_hwss = get_link_hwss(stream->link, &pipe_ctx->link_res);
f01ee019
FZ
4171 DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
4172
f01ee019
FZ
4173 stream->link->cur_link_settings = link_settings;
4174
e8702d0b
WL
4175 if (link_hwss->ext.enable_dp_link_output)
4176 link_hwss->ext.enable_dp_link_output(stream->link, &pipe_ctx->link_res,
4177 stream->signal, pipe_ctx->clock_source->id,
4178 &link_settings);
f01ee019
FZ
4179
4180#ifdef DIAGS_BUILD
4181 /* Workaround for FPGA HPO capture DP link data:
4182 * HPO capture will set link to active mode
4183 * This workaround is required to get a capture from start of frame
4184 */
4185 if (!dc->debug.fpga_hpo_capture_en) {
4186 struct encoder_set_dp_phy_pattern_param params = {0};
4187 params.dp_phy_pattern = DP_TEST_PATTERN_VIDEO_MODE;
4188
4189 /* Set link active */
4190 stream->link->hpo_dp_link_enc->funcs->set_link_test_pattern(
4191 stream->link->hpo_dp_link_enc,
4192 &params);
4193 }
4194#endif
4195
4196 /* Enable DP_STREAM_ENC */
4197 dc->hwss.enable_stream(pipe_ctx);
4198
4199 /* Set DPS PPS SDP (AKA "info frames") */
4200 if (pipe_ctx->stream->timing.flags.DSC) {
253a5591 4201 dp_set_dsc_pps_sdp(pipe_ctx, true, true);
f01ee019
FZ
4202 }
4203
4204 /* Allocate Payload */
4205 if ((stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) && (state->stream_count > 1)) {
4206 // MST case
4207 uint8_t i;
4208
4209 proposed_table.stream_count = state->stream_count;
4210 for (i = 0; i < state->stream_count; i++) {
4211 avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(state->streams[i], state->streams[i]->link);
4212 req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp);
4213 proposed_table.stream_allocations[i].slot_count = req_slot_count;
4214 proposed_table.stream_allocations[i].vcp_id = i+1;
4215 /* NOTE: This makes assumption that pipe_ctx index is same as stream index */
4216 proposed_table.stream_allocations[i].hpo_dp_stream_enc = state->res_ctx.pipe_ctx[i].stream_res.hpo_dp_stream_enc;
4217 }
4218 } else {
4219 // SST case
4220 avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(stream, stream->link);
4221 req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp);
4222 proposed_table.stream_count = 1; /// Always 1 stream for SST
4223 proposed_table.stream_allocations[0].slot_count = req_slot_count;
4224 proposed_table.stream_allocations[0].vcp_id = vc_id;
4225 proposed_table.stream_allocations[0].hpo_dp_stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
4226 }
4227
a5b79943
WL
4228 link_hwss->ext.update_stream_allocation_table(stream->link,
4229 &pipe_ctx->link_res,
f01ee019
FZ
4230 &proposed_table);
4231
9d8033d6
WL
4232 if (link_hwss->ext.set_throttled_vcp_size)
4233 link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
f01ee019
FZ
4234
4235 dc->hwss.unblank_stream(pipe_ctx, &stream->link->cur_link_settings);
14e2739c 4236 dc->hwss.enable_audio_stream(pipe_ctx);
f01ee019 4237}
f01ee019 4238
ab8db3e1
AG
4239void core_link_enable_stream(
4240 struct dc_state *state,
4241 struct pipe_ctx *pipe_ctx)
4562236b 4242{
2b77dcc5 4243 struct dc *dc = pipe_ctx->stream->ctx->dc;
1e7e86c4 4244 struct dc_stream_state *stream = pipe_ctx->stream;
3550d622 4245 struct dc_link *link = stream->sink->link;
4cac1e6d 4246 enum dc_status status;
64d283cb 4247 struct link_encoder *link_enc;
c06f670f 4248 enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO;
18b4f1a0 4249 struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
eff5e115 4250 const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
b0d88890 4251
d5a43956 4252 if (link_is_dp_128b_132b_signal(pipe_ctx))
b0d88890 4253 vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg;
d9eb8fea 4254
5d4b05dd 4255 DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
4cac1e6d 4256
fa39f936
HW
4257 if (pipe_ctx->stream->sink) {
4258 if (pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
4259 pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
4260 DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x\n", __func__,
4261 pipe_ctx->stream->sink->edid_caps.display_name,
4262 pipe_ctx->stream->signal);
4263 }
4264 }
4265
39063de9 4266 if (!IS_DIAG_DC(dc->ctx->dce_environment) &&
ef5a7d26
WL
4267 dc_is_virtual_signal(pipe_ctx->stream->signal))
4268 return;
4269
66d58bf7 4270 link_enc = link_enc_cfg_get_link_enc(link);
64d283cb
JK
4271 ASSERT(link_enc);
4272
f01ee019 4273 if (!dc_is_virtual_signal(pipe_ctx->stream->signal)
d5a43956 4274 && !link_is_dp_128b_132b_signal(pipe_ctx)) {
64d283cb
JK
4275 if (link_enc)
4276 link_enc->funcs->setup(
4277 link_enc,
4278 pipe_ctx->stream->signal);
1e7e86c4
ST
4279 }
4280
eed928dc
CL
4281 pipe_ctx->stream->link->link_state_valid = true;
4282
eff5e115 4283 if (pipe_ctx->stream_res.tg->funcs->set_out_mux) {
d5a43956 4284 if (link_is_dp_128b_132b_signal(pipe_ctx))
eff5e115
WL
4285 otg_out_dest = OUT_MUX_HPO_DP;
4286 else
4287 otg_out_dest = OUT_MUX_DIO;
c06f670f 4288 pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, otg_out_dest);
eff5e115 4289 }
be547111 4290
eff5e115 4291 link_hwss->setup_stream_attribute(pipe_ctx);
11c3ee48 4292
2b77dcc5 4293 if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
d2d7885f
AK
4294 bool apply_edp_fast_boot_optimization =
4295 pipe_ctx->stream->apply_edp_fast_boot_optimization;
4296
4297 pipe_ctx->stream->apply_edp_fast_boot_optimization = false;
4298
18b4f1a0
MS
4299 // Enable VPG before building infoframe
4300 if (vpg && vpg->funcs->vpg_poweron)
4301 vpg->funcs->vpg_poweron(vpg);
18b4f1a0 4302
aa9c4abe 4303 resource_build_info_frame(pipe_ctx);
2b77dcc5 4304 dc->hwss.update_info_frame(pipe_ctx);
aa9c4abe 4305
3550d622
LHM
4306 if (dc_is_dp_signal(pipe_ctx->stream->signal))
4307 dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
4308
d2d7885f
AK
4309 /* Do not touch link on seamless boot optimization. */
4310 if (pipe_ctx->stream->apply_seamless_boot_optimization) {
4311 pipe_ctx->stream->dpms_off = false;
e664609e
AW
4312
4313 /* Still enable stream features & audio on seamless boot for DP external displays */
4314 if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT) {
4315 enable_stream_features(pipe_ctx);
14e2739c 4316 dc->hwss.enable_audio_stream(pipe_ctx);
e664609e
AW
4317 }
4318
d462fcf5
BL
4319#if defined(CONFIG_DRM_AMD_DC_HDCP)
4320 update_psp_stream_config(pipe_ctx, false);
4321#endif
d2d7885f
AK
4322 return;
4323 }
4324
aa9c4abe
NC
4325 /* eDP lit up by bios already, no need to enable again. */
4326 if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
8cf9575d 4327 apply_edp_fast_boot_optimization &&
8acd9754 4328 !pipe_ctx->stream->timing.flags.DSC &&
4329 !pipe_ctx->next_odm_pipe) {
aa9c4abe 4330 pipe_ctx->stream->dpms_off = false;
d462fcf5
BL
4331#if defined(CONFIG_DRM_AMD_DC_HDCP)
4332 update_psp_stream_config(pipe_ctx, false);
4333#endif
aa9c4abe
NC
4334 return;
4335 }
4cac1e6d 4336
aa9c4abe
NC
4337 if (pipe_ctx->stream->dpms_off)
4338 return;
f0362823 4339
c7783a6e
NI
4340 /* Have to setup DSC before DIG FE and BE are connected (which happens before the
4341 * link training). This is to make sure the bandwidth sent to DIG BE won't be
4342 * bigger than what the link and/or DIG BE can handle. VBID[6]/CompressedStream_flag
4343 * will be automatically set at a later time when the video is enabled
4344 * (DP_VID_STREAM_EN = 1).
4345 */
4346 if (pipe_ctx->stream->timing.flags.DSC) {
4347 if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
4348 dc_is_virtual_signal(pipe_ctx->stream->signal))
4349 dp_set_dsc_enable(pipe_ctx, true);
4350
4351 }
4352
aa9c4abe 4353 status = enable_link(state, pipe_ctx);
c0ba5ec7 4354
aa9c4abe 4355 if (status != DC_OK) {
1296423b 4356 DC_LOG_WARNING("enabling link %u failed: %d\n",
ceb3dbb4 4357 pipe_ctx->stream->link->link_index,
c0ba5ec7
KC
4358 status);
4359
4360 /* Abort stream enable *unless* the failure was due to
4361 * DP link training - some DP monitors will recover and
00f713c6
EY
4362 * show the stream anyway. But MST displays can't proceed
4363 * without link training.
c0ba5ec7 4364 */
00f713c6
EY
4365 if (status != DC_FAIL_DP_LINK_TRAINING ||
4366 pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
bca5bea4 4367 if (false == stream->link->link_status.link_active)
ef30f441
WL
4368 disable_link(stream->link, &pipe_ctx->link_res,
4369 pipe_ctx->stream->signal);
c0ba5ec7
KC
4370 BREAK_TO_DEBUGGER();
4371 return;
4372 }
aa9c4abe 4373 }
4562236b 4374
aa9c4abe
NC
4375 /* turn off otg test pattern if enable */
4376 if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
4377 pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
4378 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
4379 COLOR_DEPTH_UNDEFINED);
71021265 4380
be547111
BL
4381 /* This second call is needed to reconfigure the DIG
4382 * as a workaround for the incorrect value being applied
4383 * from transmitter control.
4384 */
f01ee019 4385 if (!(dc_is_virtual_signal(pipe_ctx->stream->signal) ||
d5a43956 4386 link_is_dp_128b_132b_signal(pipe_ctx)))
64d283cb
JK
4387 if (link_enc)
4388 link_enc->funcs->setup(
4389 link_enc,
4390 pipe_ctx->stream->signal);
be547111 4391
2b77dcc5 4392 dc->hwss.enable_stream(pipe_ctx);
4562236b 4393
1a9e3d45 4394 /* Set DPS PPS SDP (AKA "info frames") */
606b3551
DL
4395 if (pipe_ctx->stream->timing.flags.DSC) {
4396 if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
8cf9575d
MH
4397 dc_is_virtual_signal(pipe_ctx->stream->signal)) {
4398 dp_set_dsc_on_rx(pipe_ctx, true);
253a5591 4399 dp_set_dsc_pps_sdp(pipe_ctx, true, true);
8cf9575d 4400 }
97bda032 4401 }
1a9e3d45
NC
4402
4403 if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
48af9b91 4404 dc_link_allocate_mst_payload(pipe_ctx);
f01ee019 4405 else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
d5a43956 4406 link_is_dp_128b_132b_signal(pipe_ctx))
f01ee019 4407 dc_link_update_sst_payload(pipe_ctx, true);
1a9e3d45 4408
2b77dcc5 4409 dc->hwss.unblank_stream(pipe_ctx,
ceb3dbb4 4410 &pipe_ctx->stream->link->cur_link_settings);
aa9c4abe 4411
e2c9529f
JC
4412 if (stream->sink_patches.delay_ignore_msa > 0)
4413 msleep(stream->sink_patches.delay_ignore_msa);
dc326f61 4414
14fee4ca
JA
4415 if (dc_is_dp_signal(pipe_ctx->stream->signal))
4416 enable_stream_features(pipe_ctx);
d462fcf5
BL
4417#if defined(CONFIG_DRM_AMD_DC_HDCP)
4418 update_psp_stream_config(pipe_ctx, false);
4419#endif
c0794a3b
RC
4420
4421 dc->hwss.enable_audio_stream(pipe_ctx);
4422
2b77dcc5 4423 } else { // if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
d5a43956 4424 if (link_is_dp_128b_132b_signal(pipe_ctx))
f01ee019 4425 fpga_dp_hpo_enable_link_and_stream(state, pipe_ctx);
97bda032
HW
4426 if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
4427 dc_is_virtual_signal(pipe_ctx->stream->signal))
2f752e91 4428 dp_set_dsc_enable(pipe_ctx, true);
97bda032 4429 }
4cf7c427 4430
98dd398a 4431 if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
4cf7c427
JX
4432 core_link_set_avmute(pipe_ctx, false);
4433 }
4562236b
HW
4434}
4435
57430404 4436void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
4562236b 4437{
2b77dcc5 4438 struct dc *dc = pipe_ctx->stream->ctx->dc;
ab0cb022 4439 struct dc_stream_state *stream = pipe_ctx->stream;
052fa7e8 4440 struct dc_link *link = stream->sink->link;
18b4f1a0 4441 struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
b0d88890 4442
d5a43956 4443 if (link_is_dp_128b_132b_signal(pipe_ctx))
b0d88890 4444 vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg;
4562236b 4445
fa39f936
HW
4446 DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
4447
4448 if (pipe_ctx->stream->sink) {
4449 if (pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
4450 pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
4451 DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x\n", __func__,
4452 pipe_ctx->stream->sink->edid_caps.display_name,
4453 pipe_ctx->stream->signal);
4454 }
4455 }
4456
39063de9 4457 if (!IS_DIAG_DC(dc->ctx->dce_environment) &&
ef5a7d26
WL
4458 dc_is_virtual_signal(pipe_ctx->stream->signal))
4459 return;
4460
74d021b5
BS
4461 if (!pipe_ctx->stream->sink->edid_caps.panel_patch.skip_avmute) {
4462 if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
4463 core_link_set_avmute(pipe_ctx, true);
4cf7c427
JX
4464 }
4465
c0794a3b
RC
4466 dc->hwss.disable_audio_stream(pipe_ctx);
4467
d462fcf5
BL
4468#if defined(CONFIG_DRM_AMD_DC_HDCP)
4469 update_psp_stream_config(pipe_ctx, true);
4470#endif
b61f0562 4471 dc->hwss.blank_stream(pipe_ctx);
d462fcf5 4472
4562236b
HW
4473 if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
4474 deallocate_mst_payload(pipe_ctx);
f01ee019 4475 else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
d5a43956 4476 link_is_dp_128b_132b_signal(pipe_ctx))
f01ee019 4477 dc_link_update_sst_payload(pipe_ctx, false);
4562236b 4478
052fa7e8
CL
4479 if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
4480 struct ext_hdmi_settings settings = {0};
4481 enum engine_id eng_id = pipe_ctx->stream_res.stream_enc->id;
ab0cb022 4482
052fa7e8
CL
4483 unsigned short masked_chip_caps = link->chip_caps &
4484 EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
4485 //Need to inform that sink is going to use legacy HDMI mode.
a98cdd8c 4486 write_scdc_data(
052fa7e8
CL
4487 link->ddc,
4488 165000,//vbios only handles 165Mhz.
4489 false);
4490 if (masked_chip_caps == EXT_DISPLAY_PATH_CAPS__HDMI20_TISN65DP159RSBT) {
4491 /* DP159, Retimer settings */
4492 if (get_ext_hdmi_settings(pipe_ctx, eng_id, &settings))
4493 write_i2c_retimer_setting(pipe_ctx,
4494 false, false, &settings);
4495 else
4496 write_i2c_default_retimer_setting(pipe_ctx,
4497 false, false);
4498 } else if (masked_chip_caps == EXT_DISPLAY_PATH_CAPS__HDMI20_PI3EQX1204) {
4499 /* PI3EQX1204, Redriver settings */
4500 write_i2c_redriver_setting(pipe_ctx, false);
4501 }
4502 }
4562236b 4503
f01ee019 4504 if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
d5a43956 4505 !link_is_dp_128b_132b_signal(pipe_ctx)) {
f01ee019
FZ
4506
4507 /* In DP1.x SST mode, our encoder will go to TPS1
4508 * when link is on but stream is off.
4509 * Disabling link before stream will avoid exposing TPS1 pattern
4510 * during the disable sequence as it will confuse some receivers
4511 * state machine.
4512 * In DP2 or MST mode, our encoder will stay video active
4513 */
ef30f441 4514 disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
f01ee019
FZ
4515 dc->hwss.disable_stream(pipe_ctx);
4516 } else {
4517 dc->hwss.disable_stream(pipe_ctx);
ef30f441 4518 disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
f01ee019 4519 }
eec3303d 4520
606b3551
DL
4521 if (pipe_ctx->stream->timing.flags.DSC) {
4522 if (dc_is_dp_signal(pipe_ctx->stream->signal))
4523 dp_set_dsc_enable(pipe_ctx, false);
97bda032 4524 }
d5a43956 4525 if (link_is_dp_128b_132b_signal(pipe_ctx)) {
f01ee019
FZ
4526 if (pipe_ctx->stream_res.tg->funcs->set_out_mux)
4527 pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, OUT_MUX_DIO);
4528 }
18b4f1a0 4529
18b4f1a0
MS
4530 if (vpg && vpg->funcs->vpg_powerdown)
4531 vpg->funcs->vpg_powerdown(vpg);
4562236b
HW
4532}
4533
15e17335
CL
4534void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
4535{
2b77dcc5 4536 struct dc *dc = pipe_ctx->stream->ctx->dc;
15e17335 4537
a280a71f 4538 if (!dc_is_hdmi_signal(pipe_ctx->stream->signal))
15e17335
CL
4539 return;
4540
2b77dcc5 4541 dc->hwss.set_avmute(pipe_ctx, enable);
15e17335
CL
4542}
4543
fe798de5
CP
4544void dc_link_set_drive_settings(struct dc *dc,
4545 struct link_training_settings *lt_settings,
4546 const struct dc_link *link)
4547{
4548
4549 int i;
f6a3795d 4550 struct link_resource link_res;
fe798de5 4551
f6a3795d
WL
4552 for (i = 0; i < dc->link_count; i++)
4553 if (dc->links[i] == link)
4554 break;
fe798de5 4555
f6a3795d 4556 if (i >= dc->link_count)
fe798de5 4557 ASSERT_CRITICAL(false);
f6a3795d
WL
4558
4559 dc_link_get_cur_link_res(link, &link_res);
4560 dc_link_dp_set_drive_settings(dc->links[i], &link_res, lt_settings);
fe798de5
CP
4561}
4562
fe798de5
CP
4563void dc_link_set_preferred_link_settings(struct dc *dc,
4564 struct dc_link_settings *link_setting,
4565 struct dc_link *link)
4566{
4567 int i;
4568 struct pipe_ctx *pipe;
4569 struct dc_stream_state *link_stream;
4570 struct dc_link_settings store_settings = *link_setting;
4571
4572 link->preferred_link_setting = store_settings;
4573
4574 /* Retrain with preferred link settings only relevant for
4575 * DP signal type
08900ab7 4576 * Check for non-DP signal or if passive dongle present
fe798de5 4577 */
08900ab7
ST
4578 if (!dc_is_dp_signal(link->connector_signal) ||
4579 link->dongle_max_pix_clk > 0)
fe798de5
CP
4580 return;
4581
4582 for (i = 0; i < MAX_PIPES; i++) {
4583 pipe = &dc->current_state->res_ctx.pipe_ctx[i];
4584 if (pipe->stream && pipe->stream->link) {
252f3d95
HW
4585 if (pipe->stream->link == link) {
4586 link_stream = pipe->stream;
fe798de5 4587 break;
252f3d95 4588 }
fe798de5
CP
4589 }
4590 }
4591
4592 /* Stream not found */
4593 if (i == MAX_PIPES)
4594 return;
4595
fe798de5
CP
4596 /* Cannot retrain link if backend is off */
4597 if (link_stream->dpms_off)
4598 return;
4599
d5a43956 4600 if (link_decide_link_settings(link_stream, &store_settings))
fe798de5
CP
4601 dp_retrain_link_dp_test(link, &store_settings, false);
4602}
4603
e0a6440a
DG
4604void dc_link_set_preferred_training_settings(struct dc *dc,
4605 struct dc_link_settings *link_setting,
4606 struct dc_link_training_overrides *lt_overrides,
4607 struct dc_link *link,
4608 bool skip_immediate_retrain)
4609{
4610 if (lt_overrides != NULL)
4611 link->preferred_training_settings = *lt_overrides;
4612 else
4613 memset(&link->preferred_training_settings, 0, sizeof(link->preferred_training_settings));
4614
4615 if (link_setting != NULL) {
4616 link->preferred_link_setting = *link_setting;
4617 } else {
4618 link->preferred_link_setting.lane_count = LANE_COUNT_UNKNOWN;
4619 link->preferred_link_setting.link_rate = LINK_RATE_UNKNOWN;
4620 }
4621
ea192af5
MS
4622 if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
4623 link->type == dc_connection_mst_branch)
4624 dm_helpers_dp_mst_update_branch_bandwidth(dc->ctx, link);
4625
e0a6440a
DG
4626 /* Retrain now, or wait until next stream update to apply */
4627 if (skip_immediate_retrain == false)
4628 dc_link_set_preferred_link_settings(dc, &link->preferred_link_setting, link);
4629}
4630
fe798de5
CP
4631void dc_link_set_test_pattern(struct dc_link *link,
4632 enum dp_test_pattern test_pattern,
2057b7e1 4633 enum dp_test_pattern_color_space test_pattern_color_space,
fe798de5
CP
4634 const struct link_training_settings *p_link_settings,
4635 const unsigned char *p_custom_pattern,
4636 unsigned int cust_pattern_size)
4637{
4638 if (link != NULL)
4639 dc_link_dp_set_test_pattern(
4640 link,
4641 test_pattern,
2057b7e1 4642 test_pattern_color_space,
fe798de5
CP
4643 p_link_settings,
4644 p_custom_pattern,
4645 cust_pattern_size);
4646}
4647
4648uint32_t dc_link_bandwidth_kbps(
4649 const struct dc_link *link,
4650 const struct dc_link_settings *link_setting)
4651{
f01ee019
FZ
4652 uint32_t total_data_bw_efficiency_x10000 = 0;
4653 uint32_t link_rate_per_lane_kbps = 0;
4654
d5a43956 4655 switch (link_dp_get_encoding_format(link_setting)) {
f01ee019
FZ
4656 case DP_8b_10b_ENCODING:
4657 /* For 8b/10b encoding:
4658 * link rate is defined in the unit of LINK_RATE_REF_FREQ_IN_KHZ per DP byte per lane.
4659 * data bandwidth efficiency is 80% with additional 3% overhead if FEC is supported.
4660 */
4661 link_rate_per_lane_kbps = link_setting->link_rate * LINK_RATE_REF_FREQ_IN_KHZ * BITS_PER_DP_BYTE;
4662 total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_8b_10b_x10000;
4663 if (dc_link_should_enable_fec(link)) {
4664 total_data_bw_efficiency_x10000 /= 100;
4665 total_data_bw_efficiency_x10000 *= DATA_EFFICIENCY_8b_10b_FEC_EFFICIENCY_x100;
4666 }
4667 break;
4668 case DP_128b_132b_ENCODING:
4669 /* For 128b/132b encoding:
4670 * link rate is defined in the unit of 10mbps per lane.
4671 * total data bandwidth efficiency is always 96.71%.
4672 */
4673 link_rate_per_lane_kbps = link_setting->link_rate * 10000;
4674 total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_128b_132b_x10000;
4675 break;
4676 default:
4677 break;
4678 }
4679
4680 /* overall effective link bandwidth = link rate per lane * lane count * total data bandwidth efficiency */
4681 return link_rate_per_lane_kbps * link_setting->lane_count / 10000 * total_data_bw_efficiency_x10000;
fe798de5
CP
4682}
4683
91a9ead0
MM
4684uint32_t dc_bandwidth_in_kbps_from_timing(
4685 const struct dc_crtc_timing *timing)
4686{
4687 uint32_t bits_per_channel = 0;
4688 uint32_t kbps;
4689
4690#if defined(CONFIG_DRM_AMD_DC_DCN)
4691 if (timing->flags.DSC)
4692 return dc_dsc_stream_bandwidth_in_kbps(timing,
4693 timing->dsc_cfg.bits_per_pixel,
4694 timing->dsc_cfg.num_slices_h,
4695 timing->dsc_cfg.is_dp);
433e5dec 4696#endif /* CONFIG_DRM_AMD_DC_DCN */
91a9ead0
MM
4697
4698 switch (timing->display_color_depth) {
4699 case COLOR_DEPTH_666:
4700 bits_per_channel = 6;
4701 break;
4702 case COLOR_DEPTH_888:
4703 bits_per_channel = 8;
4704 break;
4705 case COLOR_DEPTH_101010:
4706 bits_per_channel = 10;
4707 break;
4708 case COLOR_DEPTH_121212:
4709 bits_per_channel = 12;
4710 break;
4711 case COLOR_DEPTH_141414:
4712 bits_per_channel = 14;
4713 break;
4714 case COLOR_DEPTH_161616:
4715 bits_per_channel = 16;
4716 break;
4717 default:
4718 ASSERT(bits_per_channel != 0);
4719 bits_per_channel = 8;
4720 break;
4721 }
4722
4723 kbps = timing->pix_clk_100hz / 10;
4724 kbps *= bits_per_channel;
4725
4726 if (timing->flags.Y_ONLY != 1) {
4727 /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/
4728 kbps *= 3;
4729 if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
4730 kbps /= 2;
4731 else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
4732 kbps = kbps * 2 / 3;
4733 }
4734
4735 return kbps;
4736
4737}
ef30f441 4738
f6a3795d
WL
4739void dc_link_get_cur_link_res(const struct dc_link *link,
4740 struct link_resource *link_res)
ef30f441
WL
4741{
4742 int i;
4743 struct pipe_ctx *pipe = NULL;
f6a3795d
WL
4744
4745 memset(link_res, 0, sizeof(*link_res));
ef30f441
WL
4746
4747 for (i = 0; i < MAX_PIPES; i++) {
4748 pipe = &link->dc->current_state->res_ctx.pipe_ctx[i];
4749 if (pipe->stream && pipe->stream->link && pipe->top_pipe == NULL) {
4750 if (pipe->stream->link == link) {
f6a3795d 4751 *link_res = pipe->link_res;
ef30f441
WL
4752 break;
4753 }
4754 }
4755 }
4756
ef30f441 4757}
4c3adc0b
WL
4758
4759/**
4760 * dc_get_cur_link_res_map() - take a snapshot of current link resource allocation state
4761 * @dc: pointer to dc of the dm calling this
4762 * @map: a dc link resource snapshot defined internally to dc.
4763 *
4764 * DM needs to capture a snapshot of current link resource allocation mapping
4765 * and store it in its persistent storage.
4766 *
4767 * Some of the link resource is using first come first serve policy.
4768 * The allocation mapping depends on original hotplug order. This information
4769 * is lost after driver is loaded next time. The snapshot is used in order to
4770 * restore link resource to its previous state so user will get consistent
4771 * link capability allocation across reboot.
4772 *
4773 * Return: none (void function)
4774 *
4775 */
4776void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map)
4777{
4c3adc0b 4778 struct dc_link *link;
9506b8d9 4779 uint32_t i;
4c3adc0b
WL
4780 uint32_t hpo_dp_recycle_map = 0;
4781
4782 *map = 0;
4783
4784 if (dc->caps.dp_hpo) {
4785 for (i = 0; i < dc->caps.max_links; i++) {
4786 link = dc->links[i];
4787 if (link->link_status.link_active &&
d5a43956
WL
4788 link_dp_get_encoding_format(&link->reported_link_cap) == DP_128b_132b_ENCODING &&
4789 link_dp_get_encoding_format(&link->cur_link_settings) != DP_128b_132b_ENCODING)
4c3adc0b
WL
4790 /* hpo dp link encoder is considered as recycled, when RX reports 128b/132b encoding capability
4791 * but current link doesn't use it.
4792 */
4793 hpo_dp_recycle_map |= (1 << i);
4794 }
4795 *map |= (hpo_dp_recycle_map << LINK_RES_HPO_DP_REC_MAP__SHIFT);
4796 }
4c3adc0b
WL
4797}
4798
4799/**
4800 * dc_restore_link_res_map() - restore link resource allocation state from a snapshot
4801 * @dc: pointer to dc of the dm calling this
4802 * @map: a dc link resource snapshot defined internally to dc.
4803 *
4804 * DM needs to call this function after initial link detection on boot and
4805 * before first commit streams to restore link resource allocation state
4806 * from previous boot session.
4807 *
4808 * Some of the link resource is using first come first serve policy.
4809 * The allocation mapping depends on original hotplug order. This information
4810 * is lost after driver is loaded next time. The snapshot is used in order to
4811 * restore link resource to its previous state so user will get consistent
4812 * link capability allocation across reboot.
4813 *
4814 * Return: none (void function)
4815 *
4816 */
4817void dc_restore_link_res_map(const struct dc *dc, uint32_t *map)
4818{
4c3adc0b 4819 struct dc_link *link;
9506b8d9 4820 uint32_t i;
4c3adc0b
WL
4821 unsigned int available_hpo_dp_count;
4822 uint32_t hpo_dp_recycle_map = (*map & LINK_RES_HPO_DP_REC_MAP__MASK)
4823 >> LINK_RES_HPO_DP_REC_MAP__SHIFT;
4824
4825 if (dc->caps.dp_hpo) {
4826 available_hpo_dp_count = dc->res_pool->hpo_dp_link_enc_count;
4827 /* remove excess 128b/132b encoding support for not recycled links */
4828 for (i = 0; i < dc->caps.max_links; i++) {
4829 if ((hpo_dp_recycle_map & (1 << i)) == 0) {
4830 link = dc->links[i];
4831 if (link->type != dc_connection_none &&
d5a43956 4832 link_dp_get_encoding_format(&link->verified_link_cap) == DP_128b_132b_ENCODING) {
4c3adc0b
WL
4833 if (available_hpo_dp_count > 0)
4834 available_hpo_dp_count--;
4835 else
4836 /* remove 128b/132b encoding capability by limiting verified link rate to HBR3 */
4837 link->verified_link_cap.link_rate = LINK_RATE_HIGH3;
4838 }
4839 }
4840 }
4841 /* remove excess 128b/132b encoding support for recycled links */
4842 for (i = 0; i < dc->caps.max_links; i++) {
4843 if ((hpo_dp_recycle_map & (1 << i)) != 0) {
4844 link = dc->links[i];
4845 if (link->type != dc_connection_none &&
d5a43956 4846 link_dp_get_encoding_format(&link->verified_link_cap) == DP_128b_132b_ENCODING) {
4c3adc0b
WL
4847 if (available_hpo_dp_count > 0)
4848 available_hpo_dp_count--;
4849 else
4850 /* remove 128b/132b encoding capability by limiting verified link rate to HBR3 */
4851 link->verified_link_cap.link_rate = LINK_RATE_HIGH3;
4852 }
4853 }
4854 }
4855 }
4c3adc0b 4856}