2 * Copyright 2012-15 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include "dm_services.h"
28 #include "dm_helpers.h"
30 #include "grph_object_id.h"
31 #include "gpio_service_interface.h"
32 #include "core_status.h"
33 #include "dc_link_dp.h"
34 #include "dc_link_ddc.h"
35 #include "link_hwss.h"
38 #include "link_encoder.h"
39 #include "hw_sequencer.h"
42 #include "fixed31_32.h"
43 #include "dpcd_defs.h"
46 #define DC_LOGGER_INIT(logger)
49 #define LINK_INFO(...) \
53 #define RETIMER_REDRIVER_INFO(...) \
54 DC_LOG_RETIMER_REDRIVER( \
56 /*******************************************************************************
58 ******************************************************************************/
61 LINK_RATE_REF_FREQ_IN_MHZ
= 27,
62 PEAK_FACTOR_X1000
= 1006,
64 * Some receivers fail to train on first try and are good
65 * on subsequent tries. 2 retries should be plenty. If we
66 * don't have a successful training then we don't expect to
69 LINK_TRAINING_MAX_VERIFY_RETRY
= 2
72 /*******************************************************************************
74 ******************************************************************************/
75 static void destruct(struct dc_link
*link
)
79 if (link
->hpd_gpio
!= NULL
) {
80 dal_gpio_close(link
->hpd_gpio
);
81 dal_gpio_destroy_irq(&link
->hpd_gpio
);
82 link
->hpd_gpio
= NULL
;
86 dal_ddc_service_destroy(&link
->ddc
);
89 link
->link_enc
->funcs
->destroy(&link
->link_enc
);
92 dc_sink_release(link
->local_sink
);
94 for (i
= 0; i
< link
->sink_count
; ++i
)
95 dc_sink_release(link
->remote_sinks
[i
]);
98 struct gpio
*get_hpd_gpio(struct dc_bios
*dcb
,
99 struct graphics_object_id link_id
,
100 struct gpio_service
*gpio_service
)
102 enum bp_result bp_result
;
103 struct graphics_object_hpd_info hpd_info
;
104 struct gpio_pin_info pin_info
;
106 if (dcb
->funcs
->get_hpd_info(dcb
, link_id
, &hpd_info
) != BP_RESULT_OK
)
109 bp_result
= dcb
->funcs
->get_gpio_pin_info(dcb
,
110 hpd_info
.hpd_int_gpio_uid
, &pin_info
);
112 if (bp_result
!= BP_RESULT_OK
) {
113 ASSERT(bp_result
== BP_RESULT_NORECORD
);
117 return dal_gpio_service_create_irq(
124 * Function: program_hpd_filter
127 * Programs HPD filter on associated HPD line
129 * @param [in] delay_on_connect_in_ms: Connect filter timeout
130 * @param [in] delay_on_disconnect_in_ms: Disconnect filter timeout
133 * true on success, false otherwise
135 static bool program_hpd_filter(
136 const struct dc_link
*link
)
142 int delay_on_connect_in_ms
= 0;
143 int delay_on_disconnect_in_ms
= 0;
145 if (link
->is_hpd_filter_disabled
)
147 /* Verify feature is supported */
148 switch (link
->connector_signal
) {
149 case SIGNAL_TYPE_DVI_SINGLE_LINK
:
150 case SIGNAL_TYPE_DVI_DUAL_LINK
:
151 case SIGNAL_TYPE_HDMI_TYPE_A
:
152 /* Program hpd filter */
153 delay_on_connect_in_ms
= 500;
154 delay_on_disconnect_in_ms
= 100;
156 case SIGNAL_TYPE_DISPLAY_PORT
:
157 case SIGNAL_TYPE_DISPLAY_PORT_MST
:
158 /* Program hpd filter to allow DP signal to settle */
159 /* 500: not able to detect MST <-> SST switch as HPD is low for
160 * only 100ms on DELL U2413
161 * 0: some passive dongle still show aux mode instead of i2c
162 * 20-50:not enough to hide bouncing HPD with passive dongle.
163 * also see intermittent i2c read issues.
165 delay_on_connect_in_ms
= 80;
166 delay_on_disconnect_in_ms
= 0;
168 case SIGNAL_TYPE_LVDS
:
169 case SIGNAL_TYPE_EDP
:
171 /* Don't program hpd filter */
175 /* Obtain HPD handle */
176 hpd
= get_hpd_gpio(link
->ctx
->dc_bios
, link
->link_id
, link
->ctx
->gpio_service
);
181 /* Setup HPD filtering */
182 if (dal_gpio_open(hpd
, GPIO_MODE_INTERRUPT
) == GPIO_RESULT_OK
) {
183 struct gpio_hpd_config config
;
185 config
.delay_on_connect
= delay_on_connect_in_ms
;
186 config
.delay_on_disconnect
= delay_on_disconnect_in_ms
;
188 dal_irq_setup_hpd_filter(hpd
, &config
);
194 ASSERT_CRITICAL(false);
197 /* Release HPD handle */
198 dal_gpio_destroy_irq(&hpd
);
204 * dc_link_detect_sink() - Determine if there is a sink connected
206 * @type: Returned connection type
207 * Does not detect downstream devices, such as MST sinks
208 * or display connected through active dongles
210 bool dc_link_detect_sink(struct dc_link
*link
, enum dc_connection_type
*type
)
212 uint32_t is_hpd_high
= 0;
213 struct gpio
*hpd_pin
;
215 if (link
->connector_signal
== SIGNAL_TYPE_LVDS
) {
216 *type
= dc_connection_single
;
220 if (link
->connector_signal
== SIGNAL_TYPE_EDP
)
221 link
->dc
->hwss
.edp_wait_for_hpd_ready(link
, true);
223 /* todo: may need to lock gpio access */
224 hpd_pin
= get_hpd_gpio(link
->ctx
->dc_bios
, link
->link_id
, link
->ctx
->gpio_service
);
226 goto hpd_gpio_failure
;
228 dal_gpio_open(hpd_pin
, GPIO_MODE_INTERRUPT
);
229 dal_gpio_get_value(hpd_pin
, &is_hpd_high
);
230 dal_gpio_close(hpd_pin
);
231 dal_gpio_destroy_irq(&hpd_pin
);
234 *type
= dc_connection_single
;
235 /* TODO: need to do the actual detection */
237 *type
= dc_connection_none
;
246 static enum ddc_transaction_type
get_ddc_transaction_type(
247 enum signal_type sink_signal
)
249 enum ddc_transaction_type transaction_type
= DDC_TRANSACTION_TYPE_NONE
;
251 switch (sink_signal
) {
252 case SIGNAL_TYPE_DVI_SINGLE_LINK
:
253 case SIGNAL_TYPE_DVI_DUAL_LINK
:
254 case SIGNAL_TYPE_HDMI_TYPE_A
:
255 case SIGNAL_TYPE_LVDS
:
256 case SIGNAL_TYPE_RGB
:
257 transaction_type
= DDC_TRANSACTION_TYPE_I2C
;
260 case SIGNAL_TYPE_DISPLAY_PORT
:
261 case SIGNAL_TYPE_EDP
:
262 transaction_type
= DDC_TRANSACTION_TYPE_I2C_OVER_AUX
;
265 case SIGNAL_TYPE_DISPLAY_PORT_MST
:
266 /* MST does not use I2COverAux, but there is the
267 * SPECIAL use case for "immediate dwnstrm device
268 * access" (EPR#370830). */
269 transaction_type
= DDC_TRANSACTION_TYPE_I2C_OVER_AUX
;
276 return transaction_type
;
279 static enum signal_type
get_basic_signal_type(
280 struct graphics_object_id encoder
,
281 struct graphics_object_id downstream
)
283 if (downstream
.type
== OBJECT_TYPE_CONNECTOR
) {
284 switch (downstream
.id
) {
285 case CONNECTOR_ID_SINGLE_LINK_DVII
:
286 switch (encoder
.id
) {
287 case ENCODER_ID_INTERNAL_DAC1
:
288 case ENCODER_ID_INTERNAL_KLDSCP_DAC1
:
289 case ENCODER_ID_INTERNAL_DAC2
:
290 case ENCODER_ID_INTERNAL_KLDSCP_DAC2
:
291 return SIGNAL_TYPE_RGB
;
293 return SIGNAL_TYPE_DVI_SINGLE_LINK
;
296 case CONNECTOR_ID_DUAL_LINK_DVII
:
298 switch (encoder
.id
) {
299 case ENCODER_ID_INTERNAL_DAC1
:
300 case ENCODER_ID_INTERNAL_KLDSCP_DAC1
:
301 case ENCODER_ID_INTERNAL_DAC2
:
302 case ENCODER_ID_INTERNAL_KLDSCP_DAC2
:
303 return SIGNAL_TYPE_RGB
;
305 return SIGNAL_TYPE_DVI_DUAL_LINK
;
309 case CONNECTOR_ID_SINGLE_LINK_DVID
:
310 return SIGNAL_TYPE_DVI_SINGLE_LINK
;
311 case CONNECTOR_ID_DUAL_LINK_DVID
:
312 return SIGNAL_TYPE_DVI_DUAL_LINK
;
313 case CONNECTOR_ID_VGA
:
314 return SIGNAL_TYPE_RGB
;
315 case CONNECTOR_ID_HDMI_TYPE_A
:
316 return SIGNAL_TYPE_HDMI_TYPE_A
;
317 case CONNECTOR_ID_LVDS
:
318 return SIGNAL_TYPE_LVDS
;
319 case CONNECTOR_ID_DISPLAY_PORT
:
320 return SIGNAL_TYPE_DISPLAY_PORT
;
321 case CONNECTOR_ID_EDP
:
322 return SIGNAL_TYPE_EDP
;
324 return SIGNAL_TYPE_NONE
;
326 } else if (downstream
.type
== OBJECT_TYPE_ENCODER
) {
327 switch (downstream
.id
) {
328 case ENCODER_ID_EXTERNAL_NUTMEG
:
329 case ENCODER_ID_EXTERNAL_TRAVIS
:
330 return SIGNAL_TYPE_DISPLAY_PORT
;
332 return SIGNAL_TYPE_NONE
;
336 return SIGNAL_TYPE_NONE
;
340 * dc_link_is_dp_sink_present() - Check if there is a native DP
341 * or passive DP-HDMI dongle connected
343 bool dc_link_is_dp_sink_present(struct dc_link
*link
)
345 enum gpio_result gpio_result
;
346 uint32_t clock_pin
= 0;
350 enum connector_id connector_id
=
351 dal_graphics_object_id_get_connector_id(link
->link_id
);
354 ((connector_id
== CONNECTOR_ID_DISPLAY_PORT
) ||
355 (connector_id
== CONNECTOR_ID_EDP
));
357 ddc
= dal_ddc_service_get_ddc_pin(link
->ddc
);
364 /* Open GPIO and set it to I2C mode */
365 /* Note: this GpioMode_Input will be converted
366 * to GpioConfigType_I2cAuxDualMode in GPIO component,
367 * which indicates we need additional delay */
369 if (GPIO_RESULT_OK
!= dal_ddc_open(
370 ddc
, GPIO_MODE_INPUT
, GPIO_DDC_CONFIG_TYPE_MODE_I2C
)) {
371 dal_gpio_destroy_ddc(&ddc
);
377 * Read GPIO: DP sink is present if both clock and data pins are zero
379 * [W/A] plug-unplug DP cable, sometimes customer board has
380 * one short pulse on clk_pin(1V, < 1ms). DP will be config to HDMI/DVI
381 * then monitor can't br light up. Add retry 3 times
382 * But in real passive dongle, it need additional 3ms to detect
385 gpio_result
= dal_gpio_get_value(ddc
->pin_clock
, &clock_pin
);
386 ASSERT(gpio_result
== GPIO_RESULT_OK
);
391 } while (retry
++ < 3);
393 present
= (gpio_result
== GPIO_RESULT_OK
) && !clock_pin
;
402 * Detect output sink type
404 static enum signal_type
link_detect_sink(
405 struct dc_link
*link
,
406 enum dc_detect_reason reason
)
408 enum signal_type result
= get_basic_signal_type(
409 link
->link_enc
->id
, link
->link_id
);
411 /* Internal digital encoder will detect only dongles
412 * that require digital signal */
414 /* Detection mechanism is different
415 * for different native connectors.
416 * LVDS connector supports only LVDS signal;
417 * PCIE is a bus slot, the actual connector needs to be detected first;
418 * eDP connector supports only eDP signal;
419 * HDMI should check straps for audio */
421 /* PCIE detects the actual connector on add-on board */
423 if (link
->link_id
.id
== CONNECTOR_ID_PCIE
) {
424 /* ZAZTODO implement PCIE add-on card detection */
427 switch (link
->link_id
.id
) {
428 case CONNECTOR_ID_HDMI_TYPE_A
: {
429 /* check audio support:
430 * if native HDMI is not supported, switch to DVI */
431 struct audio_support
*aud_support
= &link
->dc
->res_pool
->audio_support
;
433 if (!aud_support
->hdmi_audio_native
)
434 if (link
->link_id
.id
== CONNECTOR_ID_HDMI_TYPE_A
)
435 result
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
438 case CONNECTOR_ID_DISPLAY_PORT
: {
439 /* DP HPD short pulse. Passive DP dongle will not
442 if (reason
!= DETECT_REASON_HPDRX
) {
443 /* Check whether DP signal detected: if not -
444 * we assume signal is DVI; it could be corrected
445 * to HDMI after dongle detection
447 if (!dm_helpers_is_dp_sink_present(link
))
448 result
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
459 static enum signal_type
decide_signal_from_strap_and_dongle_type(
460 enum display_dongle_type dongle_type
,
461 struct audio_support
*audio_support
)
463 enum signal_type signal
= SIGNAL_TYPE_NONE
;
465 switch (dongle_type
) {
466 case DISPLAY_DONGLE_DP_HDMI_DONGLE
:
467 if (audio_support
->hdmi_audio_on_dongle
)
468 signal
= SIGNAL_TYPE_HDMI_TYPE_A
;
470 signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
472 case DISPLAY_DONGLE_DP_DVI_DONGLE
:
473 signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
475 case DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE
:
476 if (audio_support
->hdmi_audio_native
)
477 signal
= SIGNAL_TYPE_HDMI_TYPE_A
;
479 signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
482 signal
= SIGNAL_TYPE_NONE
;
489 static enum signal_type
dp_passive_dongle_detection(
490 struct ddc_service
*ddc
,
491 struct display_sink_capability
*sink_cap
,
492 struct audio_support
*audio_support
)
494 dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
496 return decide_signal_from_strap_and_dongle_type(
497 sink_cap
->dongle_type
,
501 static void link_disconnect_sink(struct dc_link
*link
)
503 if (link
->local_sink
) {
504 dc_sink_release(link
->local_sink
);
505 link
->local_sink
= NULL
;
508 link
->dpcd_sink_count
= 0;
511 static void link_disconnect_remap(struct dc_sink
*prev_sink
, struct dc_link
*link
)
513 dc_sink_release(link
->local_sink
);
514 link
->local_sink
= prev_sink
;
518 static bool detect_dp(
519 struct dc_link
*link
,
520 struct display_sink_capability
*sink_caps
,
521 bool *converter_disable_audio
,
522 struct audio_support
*audio_support
,
523 enum dc_detect_reason reason
)
526 sink_caps
->signal
= link_detect_sink(link
, reason
);
527 sink_caps
->transaction_type
=
528 get_ddc_transaction_type(sink_caps
->signal
);
530 if (sink_caps
->transaction_type
== DDC_TRANSACTION_TYPE_I2C_OVER_AUX
) {
531 sink_caps
->signal
= SIGNAL_TYPE_DISPLAY_PORT
;
532 if (!detect_dp_sink_caps(link
))
535 if (is_mst_supported(link
)) {
536 sink_caps
->signal
= SIGNAL_TYPE_DISPLAY_PORT_MST
;
537 link
->type
= dc_connection_mst_branch
;
539 dal_ddc_service_set_transaction_type(
541 sink_caps
->transaction_type
);
544 * This call will initiate MST topology discovery. Which
545 * will detect MST ports and add new DRM connector DRM
546 * framework. Then read EDID via remote i2c over aux. In
547 * the end, will notify DRM detect result and save EDID
548 * into DRM framework.
550 * .detect is called by .fill_modes.
551 * .fill_modes is called by user mode ioctl
552 * DRM_IOCTL_MODE_GETCONNECTOR.
554 * .get_modes is called by .fill_modes.
556 * call .get_modes, AMDGPU DM implementation will create
557 * new dc_sink and add to dc_link. For long HPD plug
558 * in/out, MST has its own handle.
560 * Therefore, just after dc_create, link->sink is not
561 * created for MST until user mode app calls
562 * DRM_IOCTL_MODE_GETCONNECTOR.
564 * Need check ->sink usages in case ->sink = NULL
565 * TODO: s3 resume check
567 if (reason
== DETECT_REASON_BOOT
)
570 dm_helpers_dp_update_branch_info(
574 if (!dm_helpers_dp_mst_start_top_mgr(
577 /* MST not supported */
578 link
->type
= dc_connection_single
;
579 sink_caps
->signal
= SIGNAL_TYPE_DISPLAY_PORT
;
583 if (link
->type
!= dc_connection_mst_branch
&&
584 is_dp_active_dongle(link
)) {
585 /* DP active dongles */
586 link
->type
= dc_connection_active_dongle
;
587 if (!link
->dpcd_caps
.sink_count
.bits
.SINK_COUNT
) {
589 * active dongle unplug processing for short irq
591 link_disconnect_sink(link
);
595 if (link
->dpcd_caps
.dongle_type
!= DISPLAY_DONGLE_DP_HDMI_CONVERTER
)
596 *converter_disable_audio
= true;
599 /* DP passive dongles */
600 sink_caps
->signal
= dp_passive_dongle_detection(link
->ddc
,
608 static bool is_same_edid(struct dc_edid
*old_edid
, struct dc_edid
*new_edid
)
610 if (old_edid
->length
!= new_edid
->length
)
613 if (new_edid
->length
== 0)
616 return (memcmp(old_edid
->raw_edid
, new_edid
->raw_edid
, new_edid
->length
) == 0);
620 * dc_link_detect() - Detect if a sink is attached to a given link
622 * link->local_sink is created or destroyed as needed.
624 * This does not create remote sinks but will trigger DM
625 * to start MST detection if a branch is detected.
627 bool dc_link_detect(struct dc_link
*link
, enum dc_detect_reason reason
)
629 struct dc_sink_init_data sink_init_data
= { 0 };
630 struct display_sink_capability sink_caps
= { 0 };
632 bool converter_disable_audio
= false;
633 struct audio_support
*aud_support
= &link
->dc
->res_pool
->audio_support
;
634 bool same_edid
= false;
635 enum dc_edid_status edid_status
;
636 struct dc_context
*dc_ctx
= link
->ctx
;
637 struct dc_sink
*sink
= NULL
;
638 struct dc_sink
*prev_sink
= NULL
;
639 struct dpcd_caps prev_dpcd_caps
;
640 bool same_dpcd
= true;
641 enum dc_connection_type new_connection_type
= dc_connection_none
;
642 DC_LOGGER_INIT(link
->ctx
->logger
);
643 if (link
->connector_signal
== SIGNAL_TYPE_VIRTUAL
)
646 if (false == dc_link_detect_sink(link
, &new_connection_type
)) {
651 if (link
->connector_signal
== SIGNAL_TYPE_EDP
&&
655 if (link
->connector_signal
== SIGNAL_TYPE_LVDS
&&
659 prev_sink
= link
->local_sink
;
660 if (prev_sink
!= NULL
) {
661 dc_sink_retain(prev_sink
);
662 memcpy(&prev_dpcd_caps
, &link
->dpcd_caps
, sizeof(struct dpcd_caps
));
664 link_disconnect_sink(link
);
666 if (new_connection_type
!= dc_connection_none
) {
667 link
->type
= new_connection_type
;
669 /* From Disconnected-to-Connected. */
670 switch (link
->connector_signal
) {
671 case SIGNAL_TYPE_HDMI_TYPE_A
: {
672 sink_caps
.transaction_type
= DDC_TRANSACTION_TYPE_I2C
;
673 if (aud_support
->hdmi_audio_native
)
674 sink_caps
.signal
= SIGNAL_TYPE_HDMI_TYPE_A
;
676 sink_caps
.signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
680 case SIGNAL_TYPE_DVI_SINGLE_LINK
: {
681 sink_caps
.transaction_type
= DDC_TRANSACTION_TYPE_I2C
;
682 sink_caps
.signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
686 case SIGNAL_TYPE_DVI_DUAL_LINK
: {
687 sink_caps
.transaction_type
= DDC_TRANSACTION_TYPE_I2C
;
688 sink_caps
.signal
= SIGNAL_TYPE_DVI_DUAL_LINK
;
692 case SIGNAL_TYPE_LVDS
: {
693 sink_caps
.transaction_type
= DDC_TRANSACTION_TYPE_I2C
;
694 sink_caps
.signal
= SIGNAL_TYPE_LVDS
;
698 case SIGNAL_TYPE_EDP
: {
699 detect_edp_sink_caps(link
);
700 sink_caps
.transaction_type
=
701 DDC_TRANSACTION_TYPE_I2C_OVER_AUX
;
702 sink_caps
.signal
= SIGNAL_TYPE_EDP
;
706 case SIGNAL_TYPE_DISPLAY_PORT
: {
710 &converter_disable_audio
,
711 aud_support
, reason
)) {
712 if (prev_sink
!= NULL
)
713 dc_sink_release(prev_sink
);
717 // Check if dpcp block is the same
718 if (prev_sink
!= NULL
) {
719 if (memcmp(&link
->dpcd_caps
, &prev_dpcd_caps
, sizeof(struct dpcd_caps
)))
722 /* Active dongle plug in without display or downstream unplug*/
723 if (link
->type
== dc_connection_active_dongle
724 && link
->dpcd_caps
.sink_count
.
725 bits
.SINK_COUNT
== 0) {
726 if (prev_sink
!= NULL
) {
727 /* Downstream unplug */
728 dc_sink_release(prev_sink
);
730 /* Empty dongle plug in */
731 for (i
= 0; i
< LINK_TRAINING_MAX_VERIFY_RETRY
; i
++) {
734 dp_verify_link_cap(link
,
735 &link
->reported_link_cap
,
745 if (link
->type
== dc_connection_mst_branch
) {
746 LINK_INFO("link=%d, mst branch is now Connected\n",
748 /* Need to setup mst link_cap struct here
749 * otherwise dc_link_detect() will leave mst link_cap
750 * empty which leads to allocate_mst_payload() has "0"
751 * pbn_per_slot value leading to exception on dc_fixpt_div()
753 link
->verified_link_cap
= link
->reported_link_cap
;
754 if (prev_sink
!= NULL
)
755 dc_sink_release(prev_sink
);
763 DC_ERROR("Invalid connector type! signal:%d\n",
764 link
->connector_signal
);
765 if (prev_sink
!= NULL
)
766 dc_sink_release(prev_sink
);
770 if (link
->dpcd_caps
.sink_count
.bits
.SINK_COUNT
)
771 link
->dpcd_sink_count
= link
->dpcd_caps
.sink_count
.
774 link
->dpcd_sink_count
= 1;
776 dal_ddc_service_set_transaction_type(
778 sink_caps
.transaction_type
);
780 link
->aux_mode
= dal_ddc_service_is_in_aux_transaction_mode(
783 sink_init_data
.link
= link
;
784 sink_init_data
.sink_signal
= sink_caps
.signal
;
786 sink
= dc_sink_create(&sink_init_data
);
788 DC_ERROR("Failed to create sink!\n");
789 if (prev_sink
!= NULL
)
790 dc_sink_release(prev_sink
);
794 sink
->link
->dongle_max_pix_clk
= sink_caps
.max_hdmi_pixel_clock
;
795 sink
->converter_disable_audio
= converter_disable_audio
;
797 link
->local_sink
= sink
;
799 edid_status
= dm_helpers_read_local_edid(
804 switch (edid_status
) {
805 case EDID_BAD_CHECKSUM
:
806 DC_LOG_ERROR("EDID checksum invalid.\n");
808 case EDID_NO_RESPONSE
:
809 DC_LOG_ERROR("No EDID read.\n");
812 * Abort detection for non-DP connectors if we have
815 * DP needs to report as connected if HDP is high
816 * even if we have no EDID in order to go to
819 if (dc_is_hdmi_signal(link
->connector_signal
) ||
820 dc_is_dvi_signal(link
->connector_signal
)) {
821 if (prev_sink
!= NULL
)
822 dc_sink_release(prev_sink
);
830 // Check if edid is the same
831 if ((prev_sink
!= NULL
) && ((edid_status
== EDID_THE_SAME
) || (edid_status
== EDID_OK
)))
832 same_edid
= is_same_edid(&prev_sink
->dc_edid
, &sink
->dc_edid
);
834 if (link
->connector_signal
== SIGNAL_TYPE_DISPLAY_PORT
&&
835 sink_caps
.transaction_type
== DDC_TRANSACTION_TYPE_I2C_OVER_AUX
&&
836 reason
!= DETECT_REASON_HPDRX
) {
838 * TODO debug why Dell 2413 doesn't like
842 /* deal with non-mst cases */
843 for (i
= 0; i
< LINK_TRAINING_MAX_VERIFY_RETRY
; i
++) {
846 dp_verify_link_cap(link
,
847 &link
->reported_link_cap
,
855 // If edid is the same, then discard new sink and revert back to original sink
857 link_disconnect_remap(prev_sink
, link
);
864 /* HDMI-DVI Dongle */
865 if (sink
->sink_signal
== SIGNAL_TYPE_HDMI_TYPE_A
&&
866 !sink
->edid_caps
.edid_hdmi
)
867 sink
->sink_signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
869 /* Connectivity log: detection */
870 for (i
= 0; i
< sink
->dc_edid
.length
/ EDID_BLOCK_SIZE
; i
++) {
871 CONN_DATA_DETECT(link
,
872 &sink
->dc_edid
.raw_edid
[i
* EDID_BLOCK_SIZE
],
874 "%s: [Block %d] ", sink
->edid_caps
.display_name
, i
);
877 DC_LOG_DETECTION_EDID_PARSER("%s: "
878 "manufacturer_id = %X, "
880 "serial_number = %X, "
881 "manufacture_week = %d, "
882 "manufacture_year = %d, "
883 "display_name = %s, "
884 "speaker_flag = %d, "
885 "audio_mode_count = %d\n",
887 sink
->edid_caps
.manufacturer_id
,
888 sink
->edid_caps
.product_id
,
889 sink
->edid_caps
.serial_number
,
890 sink
->edid_caps
.manufacture_week
,
891 sink
->edid_caps
.manufacture_year
,
892 sink
->edid_caps
.display_name
,
893 sink
->edid_caps
.speaker_flags
,
894 sink
->edid_caps
.audio_mode_count
);
896 for (i
= 0; i
< sink
->edid_caps
.audio_mode_count
; i
++) {
897 DC_LOG_DETECTION_EDID_PARSER("%s: mode number = %d, "
899 "channel_count = %d, "
901 "sample_size = %d\n",
904 sink
->edid_caps
.audio_modes
[i
].format_code
,
905 sink
->edid_caps
.audio_modes
[i
].channel_count
,
906 sink
->edid_caps
.audio_modes
[i
].sample_rate
,
907 sink
->edid_caps
.audio_modes
[i
].sample_size
);
911 /* From Connected-to-Disconnected. */
912 if (link
->type
== dc_connection_mst_branch
) {
913 LINK_INFO("link=%d, mst branch is now Disconnected\n",
916 dm_helpers_dp_mst_stop_top_mgr(link
->ctx
, link
);
918 link
->mst_stream_alloc_table
.stream_count
= 0;
919 memset(link
->mst_stream_alloc_table
.stream_allocations
, 0, sizeof(link
->mst_stream_alloc_table
.stream_allocations
));
922 link
->type
= dc_connection_none
;
923 sink_caps
.signal
= SIGNAL_TYPE_NONE
;
926 LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p dpcd same=%d edid same=%d\n",
927 link
->link_index
, sink
,
928 (sink_caps
.signal
== SIGNAL_TYPE_NONE
?
929 "Disconnected":"Connected"), prev_sink
,
930 same_dpcd
, same_edid
);
932 if (prev_sink
!= NULL
)
933 dc_sink_release(prev_sink
);
938 bool dc_link_get_hpd_state(struct dc_link
*dc_link
)
942 dal_gpio_lock_pin(dc_link
->hpd_gpio
);
943 dal_gpio_get_value(dc_link
->hpd_gpio
, &state
);
944 dal_gpio_unlock_pin(dc_link
->hpd_gpio
);
949 static enum hpd_source_id
get_hpd_line(
950 struct dc_link
*link
)
953 enum hpd_source_id hpd_id
= HPD_SOURCEID_UNKNOWN
;
955 hpd
= get_hpd_gpio(link
->ctx
->dc_bios
, link
->link_id
, link
->ctx
->gpio_service
);
958 switch (dal_irq_get_source(hpd
)) {
959 case DC_IRQ_SOURCE_HPD1
:
960 hpd_id
= HPD_SOURCEID1
;
962 case DC_IRQ_SOURCE_HPD2
:
963 hpd_id
= HPD_SOURCEID2
;
965 case DC_IRQ_SOURCE_HPD3
:
966 hpd_id
= HPD_SOURCEID3
;
968 case DC_IRQ_SOURCE_HPD4
:
969 hpd_id
= HPD_SOURCEID4
;
971 case DC_IRQ_SOURCE_HPD5
:
972 hpd_id
= HPD_SOURCEID5
;
974 case DC_IRQ_SOURCE_HPD6
:
975 hpd_id
= HPD_SOURCEID6
;
982 dal_gpio_destroy_irq(&hpd
);
988 static enum channel_id
get_ddc_line(struct dc_link
*link
)
991 enum channel_id channel
= CHANNEL_ID_UNKNOWN
;
993 ddc
= dal_ddc_service_get_ddc_pin(link
->ddc
);
996 switch (dal_ddc_get_line(ddc
)) {
997 case GPIO_DDC_LINE_DDC1
:
998 channel
= CHANNEL_ID_DDC1
;
1000 case GPIO_DDC_LINE_DDC2
:
1001 channel
= CHANNEL_ID_DDC2
;
1003 case GPIO_DDC_LINE_DDC3
:
1004 channel
= CHANNEL_ID_DDC3
;
1006 case GPIO_DDC_LINE_DDC4
:
1007 channel
= CHANNEL_ID_DDC4
;
1009 case GPIO_DDC_LINE_DDC5
:
1010 channel
= CHANNEL_ID_DDC5
;
1012 case GPIO_DDC_LINE_DDC6
:
1013 channel
= CHANNEL_ID_DDC6
;
1015 case GPIO_DDC_LINE_DDC_VGA
:
1016 channel
= CHANNEL_ID_DDC_VGA
;
1018 case GPIO_DDC_LINE_I2C_PAD
:
1019 channel
= CHANNEL_ID_I2C_PAD
;
1022 BREAK_TO_DEBUGGER();
1030 static enum transmitter
translate_encoder_to_transmitter(
1031 struct graphics_object_id encoder
)
1033 switch (encoder
.id
) {
1034 case ENCODER_ID_INTERNAL_UNIPHY
:
1035 switch (encoder
.enum_id
) {
1037 return TRANSMITTER_UNIPHY_A
;
1039 return TRANSMITTER_UNIPHY_B
;
1041 return TRANSMITTER_UNKNOWN
;
1044 case ENCODER_ID_INTERNAL_UNIPHY1
:
1045 switch (encoder
.enum_id
) {
1047 return TRANSMITTER_UNIPHY_C
;
1049 return TRANSMITTER_UNIPHY_D
;
1051 return TRANSMITTER_UNKNOWN
;
1054 case ENCODER_ID_INTERNAL_UNIPHY2
:
1055 switch (encoder
.enum_id
) {
1057 return TRANSMITTER_UNIPHY_E
;
1059 return TRANSMITTER_UNIPHY_F
;
1061 return TRANSMITTER_UNKNOWN
;
1064 case ENCODER_ID_INTERNAL_UNIPHY3
:
1065 switch (encoder
.enum_id
) {
1067 return TRANSMITTER_UNIPHY_G
;
1069 return TRANSMITTER_UNKNOWN
;
1072 case ENCODER_ID_EXTERNAL_NUTMEG
:
1073 switch (encoder
.enum_id
) {
1075 return TRANSMITTER_NUTMEG_CRT
;
1077 return TRANSMITTER_UNKNOWN
;
1080 case ENCODER_ID_EXTERNAL_TRAVIS
:
1081 switch (encoder
.enum_id
) {
1083 return TRANSMITTER_TRAVIS_CRT
;
1085 return TRANSMITTER_TRAVIS_LCD
;
1087 return TRANSMITTER_UNKNOWN
;
1091 return TRANSMITTER_UNKNOWN
;
1095 static bool construct(
1096 struct dc_link
*link
,
1097 const struct link_init_data
*init_params
)
1100 struct ddc_service_init_data ddc_service_init_data
= { { 0 } };
1101 struct dc_context
*dc_ctx
= init_params
->ctx
;
1102 struct encoder_init_data enc_init_data
= { 0 };
1103 struct integrated_info info
= {{{ 0 }}};
1104 struct dc_bios
*bios
= init_params
->dc
->ctx
->dc_bios
;
1105 const struct dc_vbios_funcs
*bp_funcs
= bios
->funcs
;
1106 DC_LOGGER_INIT(dc_ctx
->logger
);
1108 link
->irq_source_hpd
= DC_IRQ_SOURCE_INVALID
;
1109 link
->irq_source_hpd_rx
= DC_IRQ_SOURCE_INVALID
;
1111 link
->link_status
.dpcd_caps
= &link
->dpcd_caps
;
1113 link
->dc
= init_params
->dc
;
1115 link
->link_index
= init_params
->link_index
;
1117 link
->link_id
= bios
->funcs
->get_connector_id(bios
, init_params
->connector_index
);
1119 if (link
->link_id
.type
!= OBJECT_TYPE_CONNECTOR
) {
1120 dm_error("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
1121 __func__
, init_params
->connector_index
,
1122 link
->link_id
.type
, OBJECT_TYPE_CONNECTOR
);
1126 if (link
->dc
->res_pool
->funcs
->link_init
)
1127 link
->dc
->res_pool
->funcs
->link_init(link
);
1129 link
->hpd_gpio
= get_hpd_gpio(link
->ctx
->dc_bios
, link
->link_id
, link
->ctx
->gpio_service
);
1130 if (link
->hpd_gpio
!= NULL
) {
1131 dal_gpio_open(link
->hpd_gpio
, GPIO_MODE_INTERRUPT
);
1132 dal_gpio_unlock_pin(link
->hpd_gpio
);
1133 link
->irq_source_hpd
= dal_irq_get_source(link
->hpd_gpio
);
1136 switch (link
->link_id
.id
) {
1137 case CONNECTOR_ID_HDMI_TYPE_A
:
1138 link
->connector_signal
= SIGNAL_TYPE_HDMI_TYPE_A
;
1141 case CONNECTOR_ID_SINGLE_LINK_DVID
:
1142 case CONNECTOR_ID_SINGLE_LINK_DVII
:
1143 link
->connector_signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
1145 case CONNECTOR_ID_DUAL_LINK_DVID
:
1146 case CONNECTOR_ID_DUAL_LINK_DVII
:
1147 link
->connector_signal
= SIGNAL_TYPE_DVI_DUAL_LINK
;
1149 case CONNECTOR_ID_DISPLAY_PORT
:
1150 link
->connector_signal
= SIGNAL_TYPE_DISPLAY_PORT
;
1152 if (link
->hpd_gpio
!= NULL
)
1153 link
->irq_source_hpd_rx
=
1154 dal_irq_get_rx_source(link
->hpd_gpio
);
1157 case CONNECTOR_ID_EDP
:
1158 link
->connector_signal
= SIGNAL_TYPE_EDP
;
1160 if (link
->hpd_gpio
!= NULL
) {
1161 link
->irq_source_hpd
= DC_IRQ_SOURCE_INVALID
;
1162 link
->irq_source_hpd_rx
=
1163 dal_irq_get_rx_source(link
->hpd_gpio
);
1166 case CONNECTOR_ID_LVDS
:
1167 link
->connector_signal
= SIGNAL_TYPE_LVDS
;
1170 DC_LOG_WARNING("Unsupported Connector type:%d!\n", link
->link_id
.id
);
1176 /* TODO: #DAL3 Implement id to str function.*/
1177 LINK_INFO("Connector[%d] description:"
1179 init_params
->connector_index
,
1180 link
->connector_signal
);
1182 ddc_service_init_data
.ctx
= link
->ctx
;
1183 ddc_service_init_data
.id
= link
->link_id
;
1184 ddc_service_init_data
.link
= link
;
1185 link
->ddc
= dal_ddc_service_create(&ddc_service_init_data
);
1187 if (link
->ddc
== NULL
) {
1188 DC_ERROR("Failed to create ddc_service!\n");
1189 goto ddc_create_fail
;
1194 dal_ddc_service_get_ddc_pin(link
->ddc
));
1196 enc_init_data
.ctx
= dc_ctx
;
1197 bp_funcs
->get_src_obj(dc_ctx
->dc_bios
, link
->link_id
, 0, &enc_init_data
.encoder
);
1198 enc_init_data
.connector
= link
->link_id
;
1199 enc_init_data
.channel
= get_ddc_line(link
);
1200 enc_init_data
.hpd_source
= get_hpd_line(link
);
1202 link
->hpd_src
= enc_init_data
.hpd_source
;
1204 enc_init_data
.transmitter
=
1205 translate_encoder_to_transmitter(enc_init_data
.encoder
);
1206 link
->link_enc
= link
->dc
->res_pool
->funcs
->link_enc_create(
1209 if( link
->link_enc
== NULL
) {
1210 DC_ERROR("Failed to create link encoder!\n");
1211 goto link_enc_create_fail
;
1214 link
->link_enc_hw_inst
= link
->link_enc
->transmitter
;
1216 for (i
= 0; i
< 4; i
++) {
1218 bp_funcs
->get_device_tag(dc_ctx
->dc_bios
, link
->link_id
, i
, &link
->device_tag
)) {
1219 DC_ERROR("Failed to find device tag!\n");
1220 goto device_tag_fail
;
1223 /* Look for device tag that matches connector signal,
1224 * CRT for rgb, LCD for other supported signal tyes
1226 if (!bp_funcs
->is_device_id_supported(dc_ctx
->dc_bios
, link
->device_tag
.dev_id
))
1228 if (link
->device_tag
.dev_id
.device_type
== DEVICE_TYPE_CRT
1229 && link
->connector_signal
!= SIGNAL_TYPE_RGB
)
1231 if (link
->device_tag
.dev_id
.device_type
== DEVICE_TYPE_LCD
1232 && link
->connector_signal
== SIGNAL_TYPE_RGB
)
1237 if (bios
->integrated_info
)
1238 info
= *bios
->integrated_info
;
1240 /* Look for channel mapping corresponding to connector and device tag */
1241 for (i
= 0; i
< MAX_NUMBER_OF_EXT_DISPLAY_PATH
; i
++) {
1242 struct external_display_path
*path
=
1243 &info
.ext_disp_conn_info
.path
[i
];
1244 if (path
->device_connector_id
.enum_id
== link
->link_id
.enum_id
1245 && path
->device_connector_id
.id
== link
->link_id
.id
1246 && path
->device_connector_id
.type
== link
->link_id
.type
) {
1248 if (link
->device_tag
.acpi_device
!= 0
1249 && path
->device_acpi_enum
== link
->device_tag
.acpi_device
) {
1250 link
->ddi_channel_mapping
= path
->channel_mapping
;
1251 link
->chip_caps
= path
->caps
;
1252 } else if (path
->device_tag
==
1253 link
->device_tag
.dev_id
.raw_device_tag
) {
1254 link
->ddi_channel_mapping
= path
->channel_mapping
;
1255 link
->chip_caps
= path
->caps
;
1262 * TODO check if GPIO programmed correctly
1264 * If GPIO isn't programmed correctly HPD might not rise or drain
1265 * fast enough, leading to bounces.
1267 program_hpd_filter(link
);
1271 link
->link_enc
->funcs
->destroy(&link
->link_enc
);
1272 link_enc_create_fail
:
1273 dal_ddc_service_destroy(&link
->ddc
);
1277 if (link
->hpd_gpio
!= NULL
) {
1278 dal_gpio_destroy_irq(&link
->hpd_gpio
);
1279 link
->hpd_gpio
= NULL
;
1285 /*******************************************************************************
1287 ******************************************************************************/
1288 struct dc_link
*link_create(const struct link_init_data
*init_params
)
1290 struct dc_link
*link
=
1291 kzalloc(sizeof(*link
), GFP_KERNEL
);
1296 if (false == construct(link
, init_params
))
1297 goto construct_fail
;
1308 void link_destroy(struct dc_link
**link
)
1315 static void dpcd_configure_panel_mode(
1316 struct dc_link
*link
,
1317 enum dp_panel_mode panel_mode
)
1319 union dpcd_edp_config edp_config_set
;
1320 bool panel_mode_edp
= false;
1321 DC_LOGGER_INIT(link
->ctx
->logger
);
1323 memset(&edp_config_set
, '\0', sizeof(union dpcd_edp_config
));
1325 if (DP_PANEL_MODE_DEFAULT
!= panel_mode
) {
1327 switch (panel_mode
) {
1328 case DP_PANEL_MODE_EDP
:
1329 case DP_PANEL_MODE_SPECIAL
:
1330 panel_mode_edp
= true;
1337 /*set edp panel mode in receiver*/
1338 core_link_read_dpcd(
1340 DP_EDP_CONFIGURATION_SET
,
1341 &edp_config_set
.raw
,
1342 sizeof(edp_config_set
.raw
));
1344 if (edp_config_set
.bits
.PANEL_MODE_EDP
1345 != panel_mode_edp
) {
1346 enum ddc_result result
= DDC_RESULT_UNKNOWN
;
1348 edp_config_set
.bits
.PANEL_MODE_EDP
=
1350 result
= core_link_write_dpcd(
1352 DP_EDP_CONFIGURATION_SET
,
1353 &edp_config_set
.raw
,
1354 sizeof(edp_config_set
.raw
));
1356 ASSERT(result
== DDC_RESULT_SUCESSFULL
);
1359 DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d "
1360 "eDP panel mode enabled: %d \n",
1362 link
->dpcd_caps
.panel_mode_edp
,
1366 static void enable_stream_features(struct pipe_ctx
*pipe_ctx
)
1368 struct dc_stream_state
*stream
= pipe_ctx
->stream
;
1369 struct dc_link
*link
= stream
->link
;
1370 union down_spread_ctrl old_downspread
;
1371 union down_spread_ctrl new_downspread
;
1373 core_link_read_dpcd(link
, DP_DOWNSPREAD_CTRL
,
1374 &old_downspread
.raw
, sizeof(old_downspread
));
1376 new_downspread
.raw
= old_downspread
.raw
;
1378 new_downspread
.bits
.IGNORE_MSA_TIMING_PARAM
=
1379 (stream
->ignore_msa_timing_param
) ? 1 : 0;
1381 if (new_downspread
.raw
!= old_downspread
.raw
) {
1382 core_link_write_dpcd(link
, DP_DOWNSPREAD_CTRL
,
1383 &new_downspread
.raw
, sizeof(new_downspread
));
1387 static enum dc_status
enable_link_dp(
1388 struct dc_state
*state
,
1389 struct pipe_ctx
*pipe_ctx
)
1391 struct dc_stream_state
*stream
= pipe_ctx
->stream
;
1392 enum dc_status status
;
1393 bool skip_video_pattern
;
1394 struct dc_link
*link
= stream
->link
;
1395 struct dc_link_settings link_settings
= {0};
1396 enum dp_panel_mode panel_mode
;
1398 /* get link settings for video mode timing */
1399 decide_link_settings(stream
, &link_settings
);
1401 pipe_ctx
->stream_res
.pix_clk_params
.requested_sym_clk
=
1402 link_settings
.link_rate
* LINK_RATE_REF_FREQ_IN_KHZ
;
1403 state
->dccg
->funcs
->update_clocks(state
->dccg
, state
, false);
1407 pipe_ctx
->stream
->signal
,
1408 pipe_ctx
->clock_source
->id
,
1411 if (stream
->sink_patches
.dppowerup_delay
> 0) {
1412 int delay_dp_power_up_in_ms
= stream
->sink_patches
.dppowerup_delay
;
1414 msleep(delay_dp_power_up_in_ms
);
1417 panel_mode
= dp_get_panel_mode(link
);
1418 dpcd_configure_panel_mode(link
, panel_mode
);
1420 skip_video_pattern
= true;
1422 if (link_settings
.link_rate
== LINK_RATE_LOW
)
1423 skip_video_pattern
= false;
1425 if (perform_link_training_with_retries(
1429 LINK_TRAINING_ATTEMPTS
)) {
1430 link
->cur_link_settings
= link_settings
;
1434 status
= DC_FAIL_DP_LINK_TRAINING
;
1439 static enum dc_status
enable_link_edp(
1440 struct dc_state
*state
,
1441 struct pipe_ctx
*pipe_ctx
)
1443 enum dc_status status
;
1444 struct dc_stream_state
*stream
= pipe_ctx
->stream
;
1445 struct dc_link
*link
= stream
->link
;
1446 /*in case it is not on*/
1447 link
->dc
->hwss
.edp_power_control(link
, true);
1448 link
->dc
->hwss
.edp_wait_for_hpd_ready(link
, true);
1450 status
= enable_link_dp(state
, pipe_ctx
);
1456 static enum dc_status
enable_link_dp_mst(
1457 struct dc_state
*state
,
1458 struct pipe_ctx
*pipe_ctx
)
1460 struct dc_link
*link
= pipe_ctx
->stream
->link
;
1462 /* sink signal type after MST branch is MST. Multiple MST sinks
1463 * share one link. Link DP PHY is enable or training only once.
1465 if (link
->cur_link_settings
.lane_count
!= LANE_COUNT_UNKNOWN
)
1468 /* to make sure the pending down rep can be processed
1469 * before clear payload table
1471 dm_helpers_dp_mst_poll_pending_down_reply(link
->ctx
, link
);
1473 /* clear payload table */
1474 dm_helpers_dp_mst_clear_payload_allocation_table(link
->ctx
, link
);
1476 /* set the sink to MST mode before enabling the link */
1477 dp_enable_mst_on_sink(link
, true);
1479 return enable_link_dp(state
, pipe_ctx
);
1482 static bool get_ext_hdmi_settings(struct pipe_ctx
*pipe_ctx
,
1483 enum engine_id eng_id
,
1484 struct ext_hdmi_settings
*settings
)
1486 bool result
= false;
1488 struct integrated_info
*integrated_info
=
1489 pipe_ctx
->stream
->ctx
->dc_bios
->integrated_info
;
1491 if (integrated_info
== NULL
)
1495 * Get retimer settings from sbios for passing SI eye test for DCE11
1496 * The setting values are varied based on board revision and port id
1497 * Therefore the setting values of each ports is passed by sbios.
1500 // Check if current bios contains ext Hdmi settings
1501 if (integrated_info
->gpu_cap_info
& 0x20) {
1503 case ENGINE_ID_DIGA
:
1504 settings
->slv_addr
= integrated_info
->dp0_ext_hdmi_slv_addr
;
1505 settings
->reg_num
= integrated_info
->dp0_ext_hdmi_6g_reg_num
;
1506 settings
->reg_num_6g
= integrated_info
->dp0_ext_hdmi_6g_reg_num
;
1507 memmove(settings
->reg_settings
,
1508 integrated_info
->dp0_ext_hdmi_reg_settings
,
1509 sizeof(integrated_info
->dp0_ext_hdmi_reg_settings
));
1510 memmove(settings
->reg_settings_6g
,
1511 integrated_info
->dp0_ext_hdmi_6g_reg_settings
,
1512 sizeof(integrated_info
->dp0_ext_hdmi_6g_reg_settings
));
1515 case ENGINE_ID_DIGB
:
1516 settings
->slv_addr
= integrated_info
->dp1_ext_hdmi_slv_addr
;
1517 settings
->reg_num
= integrated_info
->dp1_ext_hdmi_6g_reg_num
;
1518 settings
->reg_num_6g
= integrated_info
->dp1_ext_hdmi_6g_reg_num
;
1519 memmove(settings
->reg_settings
,
1520 integrated_info
->dp1_ext_hdmi_reg_settings
,
1521 sizeof(integrated_info
->dp1_ext_hdmi_reg_settings
));
1522 memmove(settings
->reg_settings_6g
,
1523 integrated_info
->dp1_ext_hdmi_6g_reg_settings
,
1524 sizeof(integrated_info
->dp1_ext_hdmi_6g_reg_settings
));
1527 case ENGINE_ID_DIGC
:
1528 settings
->slv_addr
= integrated_info
->dp2_ext_hdmi_slv_addr
;
1529 settings
->reg_num
= integrated_info
->dp2_ext_hdmi_6g_reg_num
;
1530 settings
->reg_num_6g
= integrated_info
->dp2_ext_hdmi_6g_reg_num
;
1531 memmove(settings
->reg_settings
,
1532 integrated_info
->dp2_ext_hdmi_reg_settings
,
1533 sizeof(integrated_info
->dp2_ext_hdmi_reg_settings
));
1534 memmove(settings
->reg_settings_6g
,
1535 integrated_info
->dp2_ext_hdmi_6g_reg_settings
,
1536 sizeof(integrated_info
->dp2_ext_hdmi_6g_reg_settings
));
1539 case ENGINE_ID_DIGD
:
1540 settings
->slv_addr
= integrated_info
->dp3_ext_hdmi_slv_addr
;
1541 settings
->reg_num
= integrated_info
->dp3_ext_hdmi_6g_reg_num
;
1542 settings
->reg_num_6g
= integrated_info
->dp3_ext_hdmi_6g_reg_num
;
1543 memmove(settings
->reg_settings
,
1544 integrated_info
->dp3_ext_hdmi_reg_settings
,
1545 sizeof(integrated_info
->dp3_ext_hdmi_reg_settings
));
1546 memmove(settings
->reg_settings_6g
,
1547 integrated_info
->dp3_ext_hdmi_6g_reg_settings
,
1548 sizeof(integrated_info
->dp3_ext_hdmi_6g_reg_settings
));
1555 if (result
== true) {
1556 // Validate settings from bios integrated info table
1557 if (settings
->slv_addr
== 0)
1559 if (settings
->reg_num
> 9)
1561 if (settings
->reg_num_6g
> 3)
1564 for (i
= 0; i
< settings
->reg_num
; i
++) {
1565 if (settings
->reg_settings
[i
].i2c_reg_index
> 0x20)
1569 for (i
= 0; i
< settings
->reg_num_6g
; i
++) {
1570 if (settings
->reg_settings_6g
[i
].i2c_reg_index
> 0x20)
1579 static bool i2c_write(struct pipe_ctx
*pipe_ctx
,
1580 uint8_t address
, uint8_t *buffer
, uint32_t length
)
1582 struct i2c_command cmd
= {0};
1583 struct i2c_payload payload
= {0};
1585 memset(&payload
, 0, sizeof(payload
));
1586 memset(&cmd
, 0, sizeof(cmd
));
1588 cmd
.number_of_payloads
= 1;
1589 cmd
.engine
= I2C_COMMAND_ENGINE_DEFAULT
;
1590 cmd
.speed
= pipe_ctx
->stream
->ctx
->dc
->caps
.i2c_speed_in_khz
;
1592 payload
.address
= address
;
1593 payload
.data
= buffer
;
1594 payload
.length
= length
;
1595 payload
.write
= true;
1596 cmd
.payloads
= &payload
;
1598 if (dm_helpers_submit_i2c(pipe_ctx
->stream
->ctx
,
1599 pipe_ctx
->stream
->link
, &cmd
))
1605 static void write_i2c_retimer_setting(
1606 struct pipe_ctx
*pipe_ctx
,
1608 bool is_over_340mhz
,
1609 struct ext_hdmi_settings
*settings
)
1611 uint8_t slave_address
= (settings
->slv_addr
>> 1);
1613 const uint8_t apply_rx_tx_change
= 0x4;
1614 uint8_t offset
= 0xA;
1617 bool i2c_success
= false;
1618 DC_LOGGER_INIT(pipe_ctx
->stream
->ctx
->logger
);
1620 memset(&buffer
, 0, sizeof(buffer
));
1622 /* Start Ext-Hdmi programming*/
1624 for (i
= 0; i
< settings
->reg_num
; i
++) {
1625 /* Apply 3G settings */
1626 if (settings
->reg_settings
[i
].i2c_reg_index
<= 0x20) {
1628 buffer
[0] = settings
->reg_settings
[i
].i2c_reg_index
;
1629 buffer
[1] = settings
->reg_settings
[i
].i2c_reg_val
;
1630 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1631 buffer
, sizeof(buffer
));
1632 RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
1633 offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n",
1634 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1638 ASSERT(i2c_success
);
1640 /* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A
1641 * needs to be set to 1 on every 0xA-0xC write.
1643 if (settings
->reg_settings
[i
].i2c_reg_index
== 0xA ||
1644 settings
->reg_settings
[i
].i2c_reg_index
== 0xB ||
1645 settings
->reg_settings
[i
].i2c_reg_index
== 0xC) {
1647 /* Query current value from offset 0xA */
1648 if (settings
->reg_settings
[i
].i2c_reg_index
== 0xA)
1649 value
= settings
->reg_settings
[i
].i2c_reg_val
;
1652 dal_ddc_service_query_ddc_data(
1653 pipe_ctx
->stream
->link
->ddc
,
1654 slave_address
, &offset
, 1, &value
, 1);
1657 ASSERT(i2c_success
);
1661 /* Set APPLY_RX_TX_CHANGE bit to 1 */
1662 buffer
[1] = value
| apply_rx_tx_change
;
1663 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1664 buffer
, sizeof(buffer
));
1665 RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
1666 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1667 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1670 ASSERT(i2c_success
);
1675 /* Apply 3G settings */
1676 if (is_over_340mhz
) {
1677 for (i
= 0; i
< settings
->reg_num_6g
; i
++) {
1678 /* Apply 3G settings */
1679 if (settings
->reg_settings
[i
].i2c_reg_index
<= 0x20) {
1681 buffer
[0] = settings
->reg_settings_6g
[i
].i2c_reg_index
;
1682 buffer
[1] = settings
->reg_settings_6g
[i
].i2c_reg_val
;
1683 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1684 buffer
, sizeof(buffer
));
1685 RETIMER_REDRIVER_INFO("above 340Mhz: retimer write to slave_address = 0x%x,\
1686 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1687 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1691 ASSERT(i2c_success
);
1693 /* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A
1694 * needs to be set to 1 on every 0xA-0xC write.
1696 if (settings
->reg_settings_6g
[i
].i2c_reg_index
== 0xA ||
1697 settings
->reg_settings_6g
[i
].i2c_reg_index
== 0xB ||
1698 settings
->reg_settings_6g
[i
].i2c_reg_index
== 0xC) {
1700 /* Query current value from offset 0xA */
1701 if (settings
->reg_settings_6g
[i
].i2c_reg_index
== 0xA)
1702 value
= settings
->reg_settings_6g
[i
].i2c_reg_val
;
1705 dal_ddc_service_query_ddc_data(
1706 pipe_ctx
->stream
->link
->ddc
,
1707 slave_address
, &offset
, 1, &value
, 1);
1710 ASSERT(i2c_success
);
1714 /* Set APPLY_RX_TX_CHANGE bit to 1 */
1715 buffer
[1] = value
| apply_rx_tx_change
;
1716 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1717 buffer
, sizeof(buffer
));
1718 RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
1719 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1720 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1723 ASSERT(i2c_success
);
1730 /* Program additional settings if using 640x480 resolution */
1732 /* Write offset 0xFF to 0x01 */
1735 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1736 buffer
, sizeof(buffer
));
1737 RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
1738 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1739 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1742 ASSERT(i2c_success
);
1744 /* Write offset 0x00 to 0x23 */
1747 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1748 buffer
, sizeof(buffer
));
1749 RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
1750 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1751 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1754 ASSERT(i2c_success
);
1756 /* Write offset 0xff to 0x00 */
1759 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1760 buffer
, sizeof(buffer
));
1761 RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
1762 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1763 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1766 ASSERT(i2c_success
);
1771 static void write_i2c_default_retimer_setting(
1772 struct pipe_ctx
*pipe_ctx
,
1774 bool is_over_340mhz
)
1776 uint8_t slave_address
= (0xBA >> 1);
1778 bool i2c_success
= false;
1779 DC_LOGGER_INIT(pipe_ctx
->stream
->ctx
->logger
);
1781 memset(&buffer
, 0, sizeof(buffer
));
1783 /* Program Slave Address for tuning single integrity */
1784 /* Write offset 0x0A to 0x13 */
1787 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1788 buffer
, sizeof(buffer
));
1789 RETIMER_REDRIVER_INFO("retimer writes default setting to slave_address = 0x%x,\
1790 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1791 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1794 ASSERT(i2c_success
);
1796 /* Write offset 0x0A to 0x17 */
1799 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1800 buffer
, sizeof(buffer
));
1801 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
1802 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1803 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1806 ASSERT(i2c_success
);
1808 /* Write offset 0x0B to 0xDA or 0xD8 */
1810 buffer
[1] = is_over_340mhz
? 0xDA : 0xD8;
1811 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1812 buffer
, sizeof(buffer
));
1813 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
1814 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1815 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1818 ASSERT(i2c_success
);
1820 /* Write offset 0x0A to 0x17 */
1823 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1824 buffer
, sizeof(buffer
));
1825 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
1826 offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n",
1827 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1830 ASSERT(i2c_success
);
1832 /* Write offset 0x0C to 0x1D or 0x91 */
1834 buffer
[1] = is_over_340mhz
? 0x1D : 0x91;
1835 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1836 buffer
, sizeof(buffer
));
1837 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
1838 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1839 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1842 ASSERT(i2c_success
);
1844 /* Write offset 0x0A to 0x17 */
1847 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1848 buffer
, sizeof(buffer
));
1849 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
1850 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1851 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1854 ASSERT(i2c_success
);
1858 /* Program additional settings if using 640x480 resolution */
1860 /* Write offset 0xFF to 0x01 */
1863 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1864 buffer
, sizeof(buffer
));
1865 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
1866 offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
1867 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1870 ASSERT(i2c_success
);
1872 /* Write offset 0x00 to 0x23 */
1875 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1876 buffer
, sizeof(buffer
));
1877 RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
1878 offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n",
1879 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1882 ASSERT(i2c_success
);
1884 /* Write offset 0xff to 0x00 */
1887 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1888 buffer
, sizeof(buffer
));
1889 RETIMER_REDRIVER_INFO("retimer write default setting to slave_addr = 0x%x,\
1890 offset = 0x%x, reg_val= 0x%x, i2c_success = %d end here\n",
1891 slave_address
, buffer
[0], buffer
[1], i2c_success
?1:0);
1894 ASSERT(i2c_success
);
1898 static void write_i2c_redriver_setting(
1899 struct pipe_ctx
*pipe_ctx
,
1900 bool is_over_340mhz
)
1902 uint8_t slave_address
= (0xF0 >> 1);
1904 bool i2c_success
= false;
1905 DC_LOGGER_INIT(pipe_ctx
->stream
->ctx
->logger
);
1907 memset(&buffer
, 0, sizeof(buffer
));
1909 // Program Slave Address for tuning single integrity
1913 buffer
[6] = is_over_340mhz
? 0x4E : 0x4A;
1915 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1916 buffer
, sizeof(buffer
));
1917 RETIMER_REDRIVER_INFO("redriver write 0 to all 16 reg offset expect following:\n\
1918 \t slave_addr = 0x%x, offset[3] = 0x%x, offset[4] = 0x%x,\
1919 offset[5] = 0x%x,offset[6] is_over_340mhz = 0x%x,\
1920 i2c_success = %d\n",
1921 slave_address
, buffer
[3], buffer
[4], buffer
[5], buffer
[6], i2c_success
?1:0);
1925 ASSERT(i2c_success
);
1928 static void enable_link_hdmi(struct pipe_ctx
*pipe_ctx
)
1930 struct dc_stream_state
*stream
= pipe_ctx
->stream
;
1931 struct dc_link
*link
= stream
->link
;
1932 enum dc_color_depth display_color_depth
;
1933 enum engine_id eng_id
;
1934 struct ext_hdmi_settings settings
= {0};
1935 bool is_over_340mhz
= false;
1936 bool is_vga_mode
= (stream
->timing
.h_addressable
== 640)
1937 && (stream
->timing
.v_addressable
== 480);
1939 if (stream
->phy_pix_clk
== 0)
1940 stream
->phy_pix_clk
= stream
->timing
.pix_clk_100hz
/ 10;
1941 if (stream
->phy_pix_clk
> 340000)
1942 is_over_340mhz
= true;
1944 if (dc_is_hdmi_signal(pipe_ctx
->stream
->signal
)) {
1945 unsigned short masked_chip_caps
= pipe_ctx
->stream
->link
->chip_caps
&
1946 EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK
;
1947 if (masked_chip_caps
== EXT_DISPLAY_PATH_CAPS__HDMI20_TISN65DP159RSBT
) {
1948 /* DP159, Retimer settings */
1949 eng_id
= pipe_ctx
->stream_res
.stream_enc
->id
;
1951 if (get_ext_hdmi_settings(pipe_ctx
, eng_id
, &settings
)) {
1952 write_i2c_retimer_setting(pipe_ctx
,
1953 is_vga_mode
, is_over_340mhz
, &settings
);
1955 write_i2c_default_retimer_setting(pipe_ctx
,
1956 is_vga_mode
, is_over_340mhz
);
1958 } else if (masked_chip_caps
== EXT_DISPLAY_PATH_CAPS__HDMI20_PI3EQX1204
) {
1959 /* PI3EQX1204, Redriver settings */
1960 write_i2c_redriver_setting(pipe_ctx
, is_over_340mhz
);
1964 if (dc_is_hdmi_signal(pipe_ctx
->stream
->signal
))
1965 dal_ddc_service_write_scdc_data(
1967 stream
->phy_pix_clk
,
1968 stream
->timing
.flags
.LTE_340MCSC_SCRAMBLE
);
1970 memset(&stream
->link
->cur_link_settings
, 0,
1971 sizeof(struct dc_link_settings
));
1973 display_color_depth
= stream
->timing
.display_color_depth
;
1974 if (stream
->timing
.pixel_encoding
== PIXEL_ENCODING_YCBCR422
)
1975 display_color_depth
= COLOR_DEPTH_888
;
1977 link
->link_enc
->funcs
->enable_tmds_output(
1979 pipe_ctx
->clock_source
->id
,
1980 display_color_depth
,
1981 pipe_ctx
->stream
->signal
,
1982 stream
->phy_pix_clk
);
1984 if (pipe_ctx
->stream
->signal
== SIGNAL_TYPE_HDMI_TYPE_A
)
1985 dal_ddc_service_read_scdc_data(link
->ddc
);
1988 static void enable_link_lvds(struct pipe_ctx
*pipe_ctx
)
1990 struct dc_stream_state
*stream
= pipe_ctx
->stream
;
1991 struct dc_link
*link
= stream
->link
;
1993 if (stream
->phy_pix_clk
== 0)
1994 stream
->phy_pix_clk
= stream
->timing
.pix_clk_100hz
/ 10;
1996 memset(&stream
->link
->cur_link_settings
, 0,
1997 sizeof(struct dc_link_settings
));
1999 link
->link_enc
->funcs
->enable_lvds_output(
2001 pipe_ctx
->clock_source
->id
,
2002 stream
->phy_pix_clk
);
2006 /****************************enable_link***********************************/
2007 static enum dc_status
enable_link(
2008 struct dc_state
*state
,
2009 struct pipe_ctx
*pipe_ctx
)
2011 enum dc_status status
= DC_ERROR_UNEXPECTED
;
2012 switch (pipe_ctx
->stream
->signal
) {
2013 case SIGNAL_TYPE_DISPLAY_PORT
:
2014 status
= enable_link_dp(state
, pipe_ctx
);
2016 case SIGNAL_TYPE_EDP
:
2017 status
= enable_link_edp(state
, pipe_ctx
);
2019 case SIGNAL_TYPE_DISPLAY_PORT_MST
:
2020 status
= enable_link_dp_mst(state
, pipe_ctx
);
2023 case SIGNAL_TYPE_DVI_SINGLE_LINK
:
2024 case SIGNAL_TYPE_DVI_DUAL_LINK
:
2025 case SIGNAL_TYPE_HDMI_TYPE_A
:
2026 enable_link_hdmi(pipe_ctx
);
2029 case SIGNAL_TYPE_LVDS
:
2030 enable_link_lvds(pipe_ctx
);
2033 case SIGNAL_TYPE_VIRTUAL
:
2043 static void disable_link(struct dc_link
*link
, enum signal_type signal
)
2046 * TODO: implement call for dp_set_hw_test_pattern
2047 * it is needed for compliance testing
2050 /* here we need to specify that encoder output settings
2051 * need to be calculated as for the set mode,
2052 * it will lead to querying dynamic link capabilities
2053 * which should be done before enable output */
2055 if (dc_is_dp_signal(signal
)) {
2057 if (dc_is_dp_sst_signal(signal
))
2058 dp_disable_link_phy(link
, signal
);
2060 dp_disable_link_phy_mst(link
, signal
);
2062 link
->link_enc
->funcs
->disable_output(link
->link_enc
, signal
);
2065 static bool dp_active_dongle_validate_timing(
2066 const struct dc_crtc_timing
*timing
,
2067 const struct dpcd_caps
*dpcd_caps
)
2069 unsigned int required_pix_clk_100hz
= timing
->pix_clk_100hz
;
2070 const struct dc_dongle_caps
*dongle_caps
= &dpcd_caps
->dongle_caps
;
2072 switch (dpcd_caps
->dongle_type
) {
2073 case DISPLAY_DONGLE_DP_VGA_CONVERTER
:
2074 case DISPLAY_DONGLE_DP_DVI_CONVERTER
:
2075 case DISPLAY_DONGLE_DP_DVI_DONGLE
:
2076 if (timing
->pixel_encoding
== PIXEL_ENCODING_RGB
)
2084 if (dongle_caps
->dongle_type
!= DISPLAY_DONGLE_DP_HDMI_CONVERTER
||
2085 dongle_caps
->extendedCapValid
== false)
2088 /* Check Pixel Encoding */
2089 switch (timing
->pixel_encoding
) {
2090 case PIXEL_ENCODING_RGB
:
2091 case PIXEL_ENCODING_YCBCR444
:
2093 case PIXEL_ENCODING_YCBCR422
:
2094 if (!dongle_caps
->is_dp_hdmi_ycbcr422_pass_through
)
2097 case PIXEL_ENCODING_YCBCR420
:
2098 if (!dongle_caps
->is_dp_hdmi_ycbcr420_pass_through
)
2102 /* Invalid Pixel Encoding*/
2107 /* Check Color Depth and Pixel Clock */
2108 if (timing
->pixel_encoding
== PIXEL_ENCODING_YCBCR420
)
2109 required_pix_clk_100hz
/= 2;
2110 else if (timing
->pixel_encoding
== PIXEL_ENCODING_YCBCR422
)
2111 required_pix_clk_100hz
= required_pix_clk_100hz
* 2 / 3;
2113 switch (timing
->display_color_depth
) {
2114 case COLOR_DEPTH_666
:
2115 case COLOR_DEPTH_888
:
2116 /*888 and 666 should always be supported*/
2118 case COLOR_DEPTH_101010
:
2119 if (dongle_caps
->dp_hdmi_max_bpc
< 10)
2121 required_pix_clk_100hz
= required_pix_clk_100hz
* 10 / 8;
2123 case COLOR_DEPTH_121212
:
2124 if (dongle_caps
->dp_hdmi_max_bpc
< 12)
2126 required_pix_clk_100hz
= required_pix_clk_100hz
* 12 / 8;
2129 case COLOR_DEPTH_141414
:
2130 case COLOR_DEPTH_161616
:
2132 /* These color depths are currently not supported */
2136 if (required_pix_clk_100hz
> (dongle_caps
->dp_hdmi_max_pixel_clk
* 10))
2142 enum dc_status
dc_link_validate_mode_timing(
2143 const struct dc_stream_state
*stream
,
2144 struct dc_link
*link
,
2145 const struct dc_crtc_timing
*timing
)
2147 uint32_t max_pix_clk
= stream
->link
->dongle_max_pix_clk
* 10;
2148 struct dpcd_caps
*dpcd_caps
= &link
->dpcd_caps
;
2150 /* A hack to avoid failing any modes for EDID override feature on
2151 * topology change such as lower quality cable for DP or different dongle
2153 if (link
->remote_sinks
[0])
2156 /* Passive Dongle */
2157 if (0 != max_pix_clk
&& timing
->pix_clk_100hz
> max_pix_clk
)
2158 return DC_EXCEED_DONGLE_CAP
;
2161 if (!dp_active_dongle_validate_timing(timing
, dpcd_caps
))
2162 return DC_EXCEED_DONGLE_CAP
;
2164 switch (stream
->signal
) {
2165 case SIGNAL_TYPE_EDP
:
2166 case SIGNAL_TYPE_DISPLAY_PORT
:
2167 if (!dp_validate_mode_timing(
2170 return DC_NO_DP_LINK_BANDWIDTH
;
2180 int dc_link_get_backlight_level(const struct dc_link
*link
)
2182 struct abm
*abm
= link
->ctx
->dc
->res_pool
->abm
;
2184 if (abm
== NULL
|| abm
->funcs
->get_current_backlight
== NULL
)
2185 return DC_ERROR_UNEXPECTED
;
2187 return (int) abm
->funcs
->get_current_backlight(abm
);
2190 bool dc_link_set_backlight_level(const struct dc_link
*link
,
2191 uint32_t backlight_pwm_u16_16
,
2192 uint32_t frame_ramp
)
2194 struct dc
*core_dc
= link
->ctx
->dc
;
2195 struct abm
*abm
= core_dc
->res_pool
->abm
;
2196 struct dmcu
*dmcu
= core_dc
->res_pool
->dmcu
;
2197 unsigned int controller_id
= 0;
2198 bool use_smooth_brightness
= true;
2200 DC_LOGGER_INIT(link
->ctx
->logger
);
2202 if ((dmcu
== NULL
) ||
2204 (abm
->funcs
->set_backlight_level_pwm
== NULL
))
2207 use_smooth_brightness
= dmcu
->funcs
->is_dmcu_initialized(dmcu
);
2209 DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
2210 backlight_pwm_u16_16
, backlight_pwm_u16_16
);
2212 if (dc_is_embedded_signal(link
->connector_signal
)) {
2213 for (i
= 0; i
< MAX_PIPES
; i
++) {
2214 if (core_dc
->current_state
->res_ctx
.pipe_ctx
[i
].stream
) {
2215 if (core_dc
->current_state
->res_ctx
.
2216 pipe_ctx
[i
].stream
->link
2218 /* DMCU -1 for all controller id values,
2222 core_dc
->current_state
->
2223 res_ctx
.pipe_ctx
[i
].stream_res
.tg
->inst
+
2227 abm
->funcs
->set_backlight_level_pwm(
2229 backlight_pwm_u16_16
,
2232 use_smooth_brightness
);
2238 bool dc_link_set_abm_disable(const struct dc_link
*link
)
2240 struct dc
*core_dc
= link
->ctx
->dc
;
2241 struct abm
*abm
= core_dc
->res_pool
->abm
;
2243 if ((abm
== NULL
) || (abm
->funcs
->set_backlight_level_pwm
== NULL
))
2246 abm
->funcs
->set_abm_immediate_disable(abm
);
2251 bool dc_link_set_psr_enable(const struct dc_link
*link
, bool enable
, bool wait
)
2253 struct dc
*core_dc
= link
->ctx
->dc
;
2254 struct dmcu
*dmcu
= core_dc
->res_pool
->dmcu
;
2256 if ((dmcu
!= NULL
&& dmcu
->funcs
->is_dmcu_initialized(dmcu
)) && link
->psr_enabled
)
2257 dmcu
->funcs
->set_psr_enable(dmcu
, enable
, wait
);
2262 const struct dc_link_status
*dc_link_get_status(const struct dc_link
*link
)
2264 return &link
->link_status
;
2267 void core_link_resume(struct dc_link
*link
)
2269 if (link
->connector_signal
!= SIGNAL_TYPE_VIRTUAL
)
2270 program_hpd_filter(link
);
2273 static struct fixed31_32
get_pbn_per_slot(struct dc_stream_state
*stream
)
2275 struct dc_link_settings
*link_settings
=
2276 &stream
->link
->cur_link_settings
;
2277 uint32_t link_rate_in_mbps
=
2278 link_settings
->link_rate
* LINK_RATE_REF_FREQ_IN_MHZ
;
2279 struct fixed31_32 mbps
= dc_fixpt_from_int(
2280 link_rate_in_mbps
* link_settings
->lane_count
);
2282 return dc_fixpt_div_int(mbps
, 54);
2285 static int get_color_depth(enum dc_color_depth color_depth
)
2287 switch (color_depth
) {
2288 case COLOR_DEPTH_666
: return 6;
2289 case COLOR_DEPTH_888
: return 8;
2290 case COLOR_DEPTH_101010
: return 10;
2291 case COLOR_DEPTH_121212
: return 12;
2292 case COLOR_DEPTH_141414
: return 14;
2293 case COLOR_DEPTH_161616
: return 16;
2298 static struct fixed31_32
get_pbn_from_timing(struct pipe_ctx
*pipe_ctx
)
2302 struct fixed31_32 peak_kbps
;
2304 uint32_t denominator
;
2306 bpc
= get_color_depth(pipe_ctx
->stream_res
.pix_clk_params
.color_depth
);
2307 kbps
= pipe_ctx
->stream_res
.pix_clk_params
.requested_pix_clk_100hz
/ 10 * bpc
* 3;
2310 * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
2311 * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on
2312 * common multiplier to render an integer PBN for all link rate/lane
2313 * counts combinations
2315 * peak_kbps *= (1006/1000)
2316 * peak_kbps *= (64/54)
2317 * peak_kbps *= 8 convert to bytes
2320 numerator
= 64 * PEAK_FACTOR_X1000
;
2321 denominator
= 54 * 8 * 1000 * 1000;
2323 peak_kbps
= dc_fixpt_from_fraction(kbps
, denominator
);
2328 static void update_mst_stream_alloc_table(
2329 struct dc_link
*link
,
2330 struct stream_encoder
*stream_enc
,
2331 const struct dp_mst_stream_allocation_table
*proposed_table
)
2333 struct link_mst_stream_allocation work_table
[MAX_CONTROLLER_NUM
] = {
2335 struct link_mst_stream_allocation
*dc_alloc
;
2340 /* if DRM proposed_table has more than one new payload */
2341 ASSERT(proposed_table
->stream_count
-
2342 link
->mst_stream_alloc_table
.stream_count
< 2);
2344 /* copy proposed_table to link, add stream encoder */
2345 for (i
= 0; i
< proposed_table
->stream_count
; i
++) {
2347 for (j
= 0; j
< link
->mst_stream_alloc_table
.stream_count
; j
++) {
2349 &link
->mst_stream_alloc_table
.stream_allocations
[j
];
2351 if (dc_alloc
->vcp_id
==
2352 proposed_table
->stream_allocations
[i
].vcp_id
) {
2354 work_table
[i
] = *dc_alloc
;
2355 break; /* exit j loop */
2360 if (j
== link
->mst_stream_alloc_table
.stream_count
) {
2361 work_table
[i
].vcp_id
=
2362 proposed_table
->stream_allocations
[i
].vcp_id
;
2363 work_table
[i
].slot_count
=
2364 proposed_table
->stream_allocations
[i
].slot_count
;
2365 work_table
[i
].stream_enc
= stream_enc
;
2369 /* update link->mst_stream_alloc_table with work_table */
2370 link
->mst_stream_alloc_table
.stream_count
=
2371 proposed_table
->stream_count
;
2372 for (i
= 0; i
< MAX_CONTROLLER_NUM
; i
++)
2373 link
->mst_stream_alloc_table
.stream_allocations
[i
] =
2377 /* convert link_mst_stream_alloc_table to dm dp_mst_stream_alloc_table
2378 * because stream_encoder is not exposed to dm
2380 static enum dc_status
allocate_mst_payload(struct pipe_ctx
*pipe_ctx
)
2382 struct dc_stream_state
*stream
= pipe_ctx
->stream
;
2383 struct dc_link
*link
= stream
->link
;
2384 struct link_encoder
*link_encoder
= link
->link_enc
;
2385 struct stream_encoder
*stream_encoder
= pipe_ctx
->stream_res
.stream_enc
;
2386 struct dp_mst_stream_allocation_table proposed_table
= {0};
2387 struct fixed31_32 avg_time_slots_per_mtp
;
2388 struct fixed31_32 pbn
;
2389 struct fixed31_32 pbn_per_slot
;
2391 DC_LOGGER_INIT(link
->ctx
->logger
);
2393 /* enable_link_dp_mst already check link->enabled_stream_count
2394 * and stream is in link->stream[]. This is called during set mode,
2395 * stream_enc is available.
2398 /* get calculate VC payload for stream: stream_alloc */
2399 if (dm_helpers_dp_mst_write_payload_allocation_table(
2404 update_mst_stream_alloc_table(
2405 link
, pipe_ctx
->stream_res
.stream_enc
, &proposed_table
);
2408 DC_LOG_WARNING("Failed to update"
2409 "MST allocation table for"
2411 pipe_ctx
->pipe_idx
);
2414 "stream_count: %d: \n ",
2416 link
->mst_stream_alloc_table
.stream_count
);
2418 for (i
= 0; i
< MAX_CONTROLLER_NUM
; i
++) {
2419 DC_LOG_MST("stream_enc[%d]: %p "
2420 "stream[%d].vcp_id: %d "
2421 "stream[%d].slot_count: %d\n",
2423 (void *) link
->mst_stream_alloc_table
.stream_allocations
[i
].stream_enc
,
2425 link
->mst_stream_alloc_table
.stream_allocations
[i
].vcp_id
,
2427 link
->mst_stream_alloc_table
.stream_allocations
[i
].slot_count
);
2430 ASSERT(proposed_table
.stream_count
> 0);
2432 /* program DP source TX for payload */
2433 link_encoder
->funcs
->update_mst_stream_allocation_table(
2435 &link
->mst_stream_alloc_table
);
2437 /* send down message */
2438 dm_helpers_dp_mst_poll_for_allocation_change_trigger(
2442 dm_helpers_dp_mst_send_payload_allocation(
2447 /* slot X.Y for only current stream */
2448 pbn_per_slot
= get_pbn_per_slot(stream
);
2449 pbn
= get_pbn_from_timing(pipe_ctx
);
2450 avg_time_slots_per_mtp
= dc_fixpt_div(pbn
, pbn_per_slot
);
2452 stream_encoder
->funcs
->set_mst_bandwidth(
2454 avg_time_slots_per_mtp
);
2460 static enum dc_status
deallocate_mst_payload(struct pipe_ctx
*pipe_ctx
)
2462 struct dc_stream_state
*stream
= pipe_ctx
->stream
;
2463 struct dc_link
*link
= stream
->link
;
2464 struct link_encoder
*link_encoder
= link
->link_enc
;
2465 struct stream_encoder
*stream_encoder
= pipe_ctx
->stream_res
.stream_enc
;
2466 struct dp_mst_stream_allocation_table proposed_table
= {0};
2467 struct fixed31_32 avg_time_slots_per_mtp
= dc_fixpt_from_int(0);
2469 bool mst_mode
= (link
->type
== dc_connection_mst_branch
);
2470 DC_LOGGER_INIT(link
->ctx
->logger
);
2472 /* deallocate_mst_payload is called before disable link. When mode or
2473 * disable/enable monitor, new stream is created which is not in link
2474 * stream[] yet. For this, payload is not allocated yet, so de-alloc
2475 * should not done. For new mode set, map_resources will get engine
2476 * for new stream, so stream_enc->id should be validated until here.
2480 stream_encoder
->funcs
->set_mst_bandwidth(
2482 avg_time_slots_per_mtp
);
2484 /* TODO: which component is responsible for remove payload table? */
2486 if (dm_helpers_dp_mst_write_payload_allocation_table(
2492 update_mst_stream_alloc_table(
2493 link
, pipe_ctx
->stream_res
.stream_enc
, &proposed_table
);
2496 DC_LOG_WARNING("Failed to update"
2497 "MST allocation table for"
2499 pipe_ctx
->pipe_idx
);
2504 "stream_count: %d: ",
2506 link
->mst_stream_alloc_table
.stream_count
);
2508 for (i
= 0; i
< MAX_CONTROLLER_NUM
; i
++) {
2509 DC_LOG_MST("stream_enc[%d]: %p "
2510 "stream[%d].vcp_id: %d "
2511 "stream[%d].slot_count: %d\n",
2513 (void *) link
->mst_stream_alloc_table
.stream_allocations
[i
].stream_enc
,
2515 link
->mst_stream_alloc_table
.stream_allocations
[i
].vcp_id
,
2517 link
->mst_stream_alloc_table
.stream_allocations
[i
].slot_count
);
2520 link_encoder
->funcs
->update_mst_stream_allocation_table(
2522 &link
->mst_stream_alloc_table
);
2525 dm_helpers_dp_mst_poll_for_allocation_change_trigger(
2529 dm_helpers_dp_mst_send_payload_allocation(
2538 void core_link_enable_stream(
2539 struct dc_state
*state
,
2540 struct pipe_ctx
*pipe_ctx
)
2542 struct dc
*core_dc
= pipe_ctx
->stream
->ctx
->dc
;
2543 struct dc_stream_state
*stream
= pipe_ctx
->stream
;
2544 enum dc_status status
;
2545 DC_LOGGER_INIT(pipe_ctx
->stream
->ctx
->logger
);
2547 if (pipe_ctx
->stream
->signal
!= SIGNAL_TYPE_VIRTUAL
) {
2548 stream
->link
->link_enc
->funcs
->setup(
2549 stream
->link
->link_enc
,
2550 pipe_ctx
->stream
->signal
);
2551 pipe_ctx
->stream_res
.stream_enc
->funcs
->setup_stereo_sync(
2552 pipe_ctx
->stream_res
.stream_enc
,
2553 pipe_ctx
->stream_res
.tg
->inst
,
2554 stream
->timing
.timing_3d_format
!= TIMING_3D_FORMAT_NONE
);
2557 if (dc_is_dp_signal(pipe_ctx
->stream
->signal
))
2558 pipe_ctx
->stream_res
.stream_enc
->funcs
->dp_set_stream_attribute(
2559 pipe_ctx
->stream_res
.stream_enc
,
2561 stream
->output_color_space
);
2563 if (dc_is_hdmi_signal(pipe_ctx
->stream
->signal
))
2564 pipe_ctx
->stream_res
.stream_enc
->funcs
->hdmi_set_stream_attribute(
2565 pipe_ctx
->stream_res
.stream_enc
,
2567 stream
->phy_pix_clk
,
2568 pipe_ctx
->stream_res
.audio
!= NULL
);
2570 if (dc_is_dvi_signal(pipe_ctx
->stream
->signal
))
2571 pipe_ctx
->stream_res
.stream_enc
->funcs
->dvi_set_stream_attribute(
2572 pipe_ctx
->stream_res
.stream_enc
,
2574 (pipe_ctx
->stream
->signal
== SIGNAL_TYPE_DVI_DUAL_LINK
) ?
2577 if (dc_is_lvds_signal(pipe_ctx
->stream
->signal
))
2578 pipe_ctx
->stream_res
.stream_enc
->funcs
->lvds_set_stream_attribute(
2579 pipe_ctx
->stream_res
.stream_enc
,
2582 if (!IS_FPGA_MAXIMUS_DC(core_dc
->ctx
->dce_environment
)) {
2583 bool apply_edp_fast_boot_optimization
=
2584 pipe_ctx
->stream
->apply_edp_fast_boot_optimization
;
2586 pipe_ctx
->stream
->apply_edp_fast_boot_optimization
= false;
2588 resource_build_info_frame(pipe_ctx
);
2589 core_dc
->hwss
.update_info_frame(pipe_ctx
);
2591 /* Do not touch link on seamless boot optimization. */
2592 if (pipe_ctx
->stream
->apply_seamless_boot_optimization
) {
2593 pipe_ctx
->stream
->dpms_off
= false;
2597 /* eDP lit up by bios already, no need to enable again. */
2598 if (pipe_ctx
->stream
->signal
== SIGNAL_TYPE_EDP
&&
2599 apply_edp_fast_boot_optimization
) {
2600 pipe_ctx
->stream
->dpms_off
= false;
2604 if (pipe_ctx
->stream
->dpms_off
)
2607 status
= enable_link(state
, pipe_ctx
);
2609 if (status
!= DC_OK
) {
2610 DC_LOG_WARNING("enabling link %u failed: %d\n",
2611 pipe_ctx
->stream
->link
->link_index
,
2614 /* Abort stream enable *unless* the failure was due to
2615 * DP link training - some DP monitors will recover and
2616 * show the stream anyway. But MST displays can't proceed
2617 * without link training.
2619 if (status
!= DC_FAIL_DP_LINK_TRAINING
||
2620 pipe_ctx
->stream
->signal
== SIGNAL_TYPE_DISPLAY_PORT_MST
) {
2621 BREAK_TO_DEBUGGER();
2626 stream
->link
->link_status
.link_active
= true;
2628 core_dc
->hwss
.enable_audio_stream(pipe_ctx
);
2630 /* turn off otg test pattern if enable */
2631 if (pipe_ctx
->stream_res
.tg
->funcs
->set_test_pattern
)
2632 pipe_ctx
->stream_res
.tg
->funcs
->set_test_pattern(pipe_ctx
->stream_res
.tg
,
2633 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE
,
2634 COLOR_DEPTH_UNDEFINED
);
2636 core_dc
->hwss
.enable_stream(pipe_ctx
);
2638 if (pipe_ctx
->stream
->signal
== SIGNAL_TYPE_DISPLAY_PORT_MST
)
2639 allocate_mst_payload(pipe_ctx
);
2641 core_dc
->hwss
.unblank_stream(pipe_ctx
,
2642 &pipe_ctx
->stream
->link
->cur_link_settings
);
2644 if (dc_is_dp_signal(pipe_ctx
->stream
->signal
))
2645 enable_stream_features(pipe_ctx
);
2650 void core_link_disable_stream(struct pipe_ctx
*pipe_ctx
, int option
)
2652 struct dc
*core_dc
= pipe_ctx
->stream
->ctx
->dc
;
2654 core_dc
->hwss
.blank_stream(pipe_ctx
);
2656 if (pipe_ctx
->stream
->signal
== SIGNAL_TYPE_DISPLAY_PORT_MST
)
2657 deallocate_mst_payload(pipe_ctx
);
2659 core_dc
->hwss
.disable_stream(pipe_ctx
, option
);
2661 disable_link(pipe_ctx
->stream
->link
, pipe_ctx
->stream
->signal
);
2663 pipe_ctx
->stream
->link
->link_status
.link_active
= false;
2666 void core_link_set_avmute(struct pipe_ctx
*pipe_ctx
, bool enable
)
2668 struct dc
*core_dc
= pipe_ctx
->stream
->ctx
->dc
;
2670 if (pipe_ctx
->stream
->signal
!= SIGNAL_TYPE_HDMI_TYPE_A
)
2673 core_dc
->hwss
.set_avmute(pipe_ctx
, enable
);
2677 *****************************************************************************
2678 * Function: dc_link_enable_hpd_filter
2681 * If enable is true, programs HPD filter on associated HPD line using
2682 * delay_on_disconnect/delay_on_connect values dependent on
2683 * link->connector_signal
2685 * If enable is false, programs HPD filter on associated HPD line with no
2686 * delays on connect or disconnect
2688 * @param [in] link: pointer to the dc link
2689 * @param [in] enable: boolean specifying whether to enable hbd
2690 *****************************************************************************
2692 void dc_link_enable_hpd_filter(struct dc_link
*link
, bool enable
)
2697 link
->is_hpd_filter_disabled
= false;
2698 program_hpd_filter(link
);
2700 link
->is_hpd_filter_disabled
= true;
2701 /* Obtain HPD handle */
2702 hpd
= get_hpd_gpio(link
->ctx
->dc_bios
, link
->link_id
, link
->ctx
->gpio_service
);
2707 /* Setup HPD filtering */
2708 if (dal_gpio_open(hpd
, GPIO_MODE_INTERRUPT
) == GPIO_RESULT_OK
) {
2709 struct gpio_hpd_config config
;
2711 config
.delay_on_connect
= 0;
2712 config
.delay_on_disconnect
= 0;
2714 dal_irq_setup_hpd_filter(hpd
, &config
);
2716 dal_gpio_close(hpd
);
2718 ASSERT_CRITICAL(false);
2720 /* Release HPD handle */
2721 dal_gpio_destroy_irq(&hpd
);