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"
27 #include "dm_helpers.h"
29 #include "grph_object_id.h"
30 #include "gpio_service_interface.h"
31 #include "core_status.h"
32 #include "dc_link_dp.h"
33 #include "dc_link_ddc.h"
34 #include "link_hwss.h"
36 #include "link_encoder.h"
37 #include "hw_sequencer.h"
40 #include "fixed31_32.h"
41 #include "dpcd_defs.h"
44 #include "dce/dce_11_0_d.h"
45 #include "dce/dce_11_0_enum.h"
46 #include "dce/dce_11_0_sh_mask.h"
48 #define LINK_INFO(...) \
49 dm_logger_write(dc_ctx->logger, LOG_HW_HOTPLUG, \
52 /*******************************************************************************
54 ******************************************************************************/
57 LINK_RATE_REF_FREQ_IN_MHZ
= 27,
58 PEAK_FACTOR_X1000
= 1006
61 /*******************************************************************************
63 ******************************************************************************/
64 static void destruct(struct dc_link
*link
)
69 dal_ddc_service_destroy(&link
->ddc
);
72 link
->link_enc
->funcs
->destroy(&link
->link_enc
);
75 dc_sink_release(link
->local_sink
);
77 for (i
= 0; i
< link
->sink_count
; ++i
)
78 dc_sink_release(link
->remote_sinks
[i
]);
81 static struct gpio
*get_hpd_gpio(const struct dc_link
*link
)
83 enum bp_result bp_result
;
84 struct dc_bios
*dcb
= link
->ctx
->dc_bios
;
85 struct graphics_object_hpd_info hpd_info
;
86 struct gpio_pin_info pin_info
;
88 if (dcb
->funcs
->get_hpd_info(dcb
, link
->link_id
, &hpd_info
) != BP_RESULT_OK
)
91 bp_result
= dcb
->funcs
->get_gpio_pin_info(dcb
,
92 hpd_info
.hpd_int_gpio_uid
, &pin_info
);
94 if (bp_result
!= BP_RESULT_OK
) {
95 ASSERT(bp_result
== BP_RESULT_NORECORD
);
99 return dal_gpio_service_create_irq(
100 link
->ctx
->gpio_service
,
106 * Function: program_hpd_filter
109 * Programs HPD filter on associated HPD line
111 * @param [in] delay_on_connect_in_ms: Connect filter timeout
112 * @param [in] delay_on_disconnect_in_ms: Disconnect filter timeout
115 * true on success, false otherwise
117 static bool program_hpd_filter(
118 const struct dc_link
*link
)
124 int delay_on_connect_in_ms
= 0;
125 int delay_on_disconnect_in_ms
= 0;
127 /* Verify feature is supported */
128 switch (link
->connector_signal
) {
129 case SIGNAL_TYPE_DVI_SINGLE_LINK
:
130 case SIGNAL_TYPE_DVI_DUAL_LINK
:
131 case SIGNAL_TYPE_HDMI_TYPE_A
:
132 /* Program hpd filter */
133 delay_on_connect_in_ms
= 500;
134 delay_on_disconnect_in_ms
= 100;
136 case SIGNAL_TYPE_DISPLAY_PORT
:
137 case SIGNAL_TYPE_DISPLAY_PORT_MST
:
138 /* Program hpd filter to allow DP signal to settle */
139 /* 500: not able to detect MST <-> SST switch as HPD is low for
140 * only 100ms on DELL U2413
141 * 0: some passive dongle still show aux mode instead of i2c
142 * 20-50:not enough to hide bouncing HPD with passive dongle.
143 * also see intermittent i2c read issues.
145 delay_on_connect_in_ms
= 80;
146 delay_on_disconnect_in_ms
= 0;
148 case SIGNAL_TYPE_LVDS
:
149 case SIGNAL_TYPE_EDP
:
151 /* Don't program hpd filter */
155 /* Obtain HPD handle */
156 hpd
= get_hpd_gpio(link
);
161 /* Setup HPD filtering */
162 if (dal_gpio_open(hpd
, GPIO_MODE_INTERRUPT
) == GPIO_RESULT_OK
) {
163 struct gpio_hpd_config config
;
165 config
.delay_on_connect
= delay_on_connect_in_ms
;
166 config
.delay_on_disconnect
= delay_on_disconnect_in_ms
;
168 dal_irq_setup_hpd_filter(hpd
, &config
);
174 ASSERT_CRITICAL(false);
177 /* Release HPD handle */
178 dal_gpio_destroy_irq(&hpd
);
183 static bool detect_sink(struct dc_link
*link
, enum dc_connection_type
*type
)
185 uint32_t is_hpd_high
= 0;
186 struct gpio
*hpd_pin
;
188 /* todo: may need to lock gpio access */
189 hpd_pin
= get_hpd_gpio(link
);
191 goto hpd_gpio_failure
;
193 dal_gpio_open(hpd_pin
, GPIO_MODE_INTERRUPT
);
194 dal_gpio_get_value(hpd_pin
, &is_hpd_high
);
195 dal_gpio_close(hpd_pin
);
196 dal_gpio_destroy_irq(&hpd_pin
);
199 *type
= dc_connection_single
;
200 /* TODO: need to do the actual detection */
202 *type
= dc_connection_none
;
211 enum ddc_transaction_type
get_ddc_transaction_type(
212 enum signal_type sink_signal
)
214 enum ddc_transaction_type transaction_type
= DDC_TRANSACTION_TYPE_NONE
;
216 switch (sink_signal
) {
217 case SIGNAL_TYPE_DVI_SINGLE_LINK
:
218 case SIGNAL_TYPE_DVI_DUAL_LINK
:
219 case SIGNAL_TYPE_HDMI_TYPE_A
:
220 case SIGNAL_TYPE_LVDS
:
221 case SIGNAL_TYPE_RGB
:
222 transaction_type
= DDC_TRANSACTION_TYPE_I2C
;
225 case SIGNAL_TYPE_DISPLAY_PORT
:
226 case SIGNAL_TYPE_EDP
:
227 transaction_type
= DDC_TRANSACTION_TYPE_I2C_OVER_AUX
;
230 case SIGNAL_TYPE_DISPLAY_PORT_MST
:
231 /* MST does not use I2COverAux, but there is the
232 * SPECIAL use case for "immediate dwnstrm device
233 * access" (EPR#370830). */
234 transaction_type
= DDC_TRANSACTION_TYPE_I2C_OVER_AUX
;
241 return transaction_type
;
244 static enum signal_type
get_basic_signal_type(
245 struct graphics_object_id encoder
,
246 struct graphics_object_id downstream
)
248 if (downstream
.type
== OBJECT_TYPE_CONNECTOR
) {
249 switch (downstream
.id
) {
250 case CONNECTOR_ID_SINGLE_LINK_DVII
:
251 switch (encoder
.id
) {
252 case ENCODER_ID_INTERNAL_DAC1
:
253 case ENCODER_ID_INTERNAL_KLDSCP_DAC1
:
254 case ENCODER_ID_INTERNAL_DAC2
:
255 case ENCODER_ID_INTERNAL_KLDSCP_DAC2
:
256 return SIGNAL_TYPE_RGB
;
258 return SIGNAL_TYPE_DVI_SINGLE_LINK
;
261 case CONNECTOR_ID_DUAL_LINK_DVII
:
263 switch (encoder
.id
) {
264 case ENCODER_ID_INTERNAL_DAC1
:
265 case ENCODER_ID_INTERNAL_KLDSCP_DAC1
:
266 case ENCODER_ID_INTERNAL_DAC2
:
267 case ENCODER_ID_INTERNAL_KLDSCP_DAC2
:
268 return SIGNAL_TYPE_RGB
;
270 return SIGNAL_TYPE_DVI_DUAL_LINK
;
274 case CONNECTOR_ID_SINGLE_LINK_DVID
:
275 return SIGNAL_TYPE_DVI_SINGLE_LINK
;
276 case CONNECTOR_ID_DUAL_LINK_DVID
:
277 return SIGNAL_TYPE_DVI_DUAL_LINK
;
278 case CONNECTOR_ID_VGA
:
279 return SIGNAL_TYPE_RGB
;
280 case CONNECTOR_ID_HDMI_TYPE_A
:
281 return SIGNAL_TYPE_HDMI_TYPE_A
;
282 case CONNECTOR_ID_LVDS
:
283 return SIGNAL_TYPE_LVDS
;
284 case CONNECTOR_ID_DISPLAY_PORT
:
285 return SIGNAL_TYPE_DISPLAY_PORT
;
286 case CONNECTOR_ID_EDP
:
287 return SIGNAL_TYPE_EDP
;
289 return SIGNAL_TYPE_NONE
;
291 } else if (downstream
.type
== OBJECT_TYPE_ENCODER
) {
292 switch (downstream
.id
) {
293 case ENCODER_ID_EXTERNAL_NUTMEG
:
294 case ENCODER_ID_EXTERNAL_TRAVIS
:
295 return SIGNAL_TYPE_DISPLAY_PORT
;
297 return SIGNAL_TYPE_NONE
;
301 return SIGNAL_TYPE_NONE
;
306 * Check whether there is a dongle on DP connector
308 static bool is_dp_sink_present(struct dc_link
*link
)
310 enum gpio_result gpio_result
;
311 uint32_t clock_pin
= 0;
315 enum connector_id connector_id
=
316 dal_graphics_object_id_get_connector_id(link
->link_id
);
319 ((connector_id
== CONNECTOR_ID_DISPLAY_PORT
) ||
320 (connector_id
== CONNECTOR_ID_EDP
));
322 ddc
= dal_ddc_service_get_ddc_pin(link
->ddc
);
329 /* Open GPIO and set it to I2C mode */
330 /* Note: this GpioMode_Input will be converted
331 * to GpioConfigType_I2cAuxDualMode in GPIO component,
332 * which indicates we need additional delay */
334 if (GPIO_RESULT_OK
!= dal_ddc_open(
335 ddc
, GPIO_MODE_INPUT
, GPIO_DDC_CONFIG_TYPE_MODE_I2C
)) {
336 dal_gpio_destroy_ddc(&ddc
);
341 /* Read GPIO: DP sink is present if both clock and data pins are zero */
342 /* [anaumov] in DAL2, there was no check for GPIO failure */
344 gpio_result
= dal_gpio_get_value(ddc
->pin_clock
, &clock_pin
);
345 ASSERT(gpio_result
== GPIO_RESULT_OK
);
347 present
= (gpio_result
== GPIO_RESULT_OK
) && !clock_pin
;
356 * Detect output sink type
358 static enum signal_type
link_detect_sink(
359 struct dc_link
*link
,
360 enum dc_detect_reason reason
)
362 enum signal_type result
= get_basic_signal_type(
363 link
->link_enc
->id
, link
->link_id
);
365 /* Internal digital encoder will detect only dongles
366 * that require digital signal */
368 /* Detection mechanism is different
369 * for different native connectors.
370 * LVDS connector supports only LVDS signal;
371 * PCIE is a bus slot, the actual connector needs to be detected first;
372 * eDP connector supports only eDP signal;
373 * HDMI should check straps for audio */
375 /* PCIE detects the actual connector on add-on board */
377 if (link
->link_id
.id
== CONNECTOR_ID_PCIE
) {
378 /* ZAZTODO implement PCIE add-on card detection */
381 switch (link
->link_id
.id
) {
382 case CONNECTOR_ID_HDMI_TYPE_A
: {
383 /* check audio support:
384 * if native HDMI is not supported, switch to DVI */
385 struct audio_support
*aud_support
= &link
->dc
->res_pool
->audio_support
;
387 if (!aud_support
->hdmi_audio_native
)
388 if (link
->link_id
.id
== CONNECTOR_ID_HDMI_TYPE_A
)
389 result
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
392 case CONNECTOR_ID_DISPLAY_PORT
: {
393 /* DP HPD short pulse. Passive DP dongle will not
396 if (reason
!= DETECT_REASON_HPDRX
) {
397 /* Check whether DP signal detected: if not -
398 * we assume signal is DVI; it could be corrected
399 * to HDMI after dongle detection
401 if (!is_dp_sink_present(link
))
402 result
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
413 static enum signal_type
decide_signal_from_strap_and_dongle_type(
414 enum display_dongle_type dongle_type
,
415 struct audio_support
*audio_support
)
417 enum signal_type signal
= SIGNAL_TYPE_NONE
;
419 switch (dongle_type
) {
420 case DISPLAY_DONGLE_DP_HDMI_DONGLE
:
421 if (audio_support
->hdmi_audio_on_dongle
)
422 signal
= SIGNAL_TYPE_HDMI_TYPE_A
;
424 signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
426 case DISPLAY_DONGLE_DP_DVI_DONGLE
:
427 signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
429 case DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE
:
430 if (audio_support
->hdmi_audio_native
)
431 signal
= SIGNAL_TYPE_HDMI_TYPE_A
;
433 signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
436 signal
= SIGNAL_TYPE_NONE
;
443 static enum signal_type
dp_passive_dongle_detection(
444 struct ddc_service
*ddc
,
445 struct display_sink_capability
*sink_cap
,
446 struct audio_support
*audio_support
)
448 dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
450 return decide_signal_from_strap_and_dongle_type(
451 sink_cap
->dongle_type
,
455 static void link_disconnect_sink(struct dc_link
*link
)
457 if (link
->local_sink
) {
458 dc_sink_release(link
->local_sink
);
459 link
->local_sink
= NULL
;
462 link
->dpcd_sink_count
= 0;
465 static void detect_dp(
466 struct dc_link
*link
,
467 struct display_sink_capability
*sink_caps
,
468 bool *converter_disable_audio
,
469 struct audio_support
*audio_support
,
470 enum dc_detect_reason reason
)
473 sink_caps
->signal
= link_detect_sink(link
, reason
);
474 sink_caps
->transaction_type
=
475 get_ddc_transaction_type(sink_caps
->signal
);
477 if (sink_caps
->transaction_type
== DDC_TRANSACTION_TYPE_I2C_OVER_AUX
) {
478 sink_caps
->signal
= SIGNAL_TYPE_DISPLAY_PORT
;
479 detect_dp_sink_caps(link
);
481 /* DP active dongles */
482 if (is_dp_active_dongle(link
)) {
483 link
->type
= dc_connection_active_dongle
;
484 if (!link
->dpcd_caps
.sink_count
.bits
.SINK_COUNT
) {
486 * active dongle unplug processing for short irq
488 link_disconnect_sink(link
);
492 if (link
->dpcd_caps
.dongle_type
!=
493 DISPLAY_DONGLE_DP_HDMI_CONVERTER
) {
494 *converter_disable_audio
= true;
497 if (is_mst_supported(link
)) {
498 sink_caps
->signal
= SIGNAL_TYPE_DISPLAY_PORT_MST
;
501 * This call will initiate MST topology discovery. Which
502 * will detect MST ports and add new DRM connector DRM
503 * framework. Then read EDID via remote i2c over aux. In
504 * the end, will notify DRM detect result and save EDID
505 * into DRM framework.
507 * .detect is called by .fill_modes.
508 * .fill_modes is called by user mode ioctl
509 * DRM_IOCTL_MODE_GETCONNECTOR.
511 * .get_modes is called by .fill_modes.
513 * call .get_modes, AMDGPU DM implementation will create
514 * new dc_sink and add to dc_link. For long HPD plug
515 * in/out, MST has its own handle.
517 * Therefore, just after dc_create, link->sink is not
518 * created for MST until user mode app calls
519 * DRM_IOCTL_MODE_GETCONNECTOR.
521 * Need check ->sink usages in case ->sink = NULL
522 * TODO: s3 resume check
524 if (reason
== DETECT_REASON_BOOT
)
527 if (dm_helpers_dp_mst_start_top_mgr(
530 link
->type
= dc_connection_mst_branch
;
532 /* MST not supported */
533 sink_caps
->signal
= SIGNAL_TYPE_DISPLAY_PORT
;
537 /* DP passive dongles */
538 sink_caps
->signal
= dp_passive_dongle_detection(link
->ddc
,
544 bool dc_link_detect(struct dc_link
*link
, enum dc_detect_reason reason
)
546 struct dc_sink_init_data sink_init_data
= { 0 };
547 struct display_sink_capability sink_caps
= { 0 };
549 bool converter_disable_audio
= false;
550 struct audio_support
*aud_support
= &link
->dc
->res_pool
->audio_support
;
551 enum dc_edid_status edid_status
;
552 struct dc_context
*dc_ctx
= link
->ctx
;
553 struct dc_sink
*sink
= NULL
;
554 enum dc_connection_type new_connection_type
= dc_connection_none
;
556 if (link
->connector_signal
== SIGNAL_TYPE_VIRTUAL
)
559 if (false == detect_sink(link
, &new_connection_type
)) {
564 if (link
->connector_signal
== SIGNAL_TYPE_EDP
&&
568 link_disconnect_sink(link
);
570 if (new_connection_type
!= dc_connection_none
) {
571 link
->type
= new_connection_type
;
573 /* From Disconnected-to-Connected. */
574 switch (link
->connector_signal
) {
575 case SIGNAL_TYPE_HDMI_TYPE_A
: {
576 sink_caps
.transaction_type
= DDC_TRANSACTION_TYPE_I2C
;
577 if (aud_support
->hdmi_audio_native
)
578 sink_caps
.signal
= SIGNAL_TYPE_HDMI_TYPE_A
;
580 sink_caps
.signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
584 case SIGNAL_TYPE_DVI_SINGLE_LINK
: {
585 sink_caps
.transaction_type
= DDC_TRANSACTION_TYPE_I2C
;
586 sink_caps
.signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
590 case SIGNAL_TYPE_DVI_DUAL_LINK
: {
591 sink_caps
.transaction_type
= DDC_TRANSACTION_TYPE_I2C
;
592 sink_caps
.signal
= SIGNAL_TYPE_DVI_DUAL_LINK
;
596 case SIGNAL_TYPE_EDP
: {
597 detect_edp_sink_caps(link
);
598 sink_caps
.transaction_type
=
599 DDC_TRANSACTION_TYPE_I2C_OVER_AUX
;
600 sink_caps
.signal
= SIGNAL_TYPE_EDP
;
604 case SIGNAL_TYPE_DISPLAY_PORT
: {
608 &converter_disable_audio
,
609 aud_support
, reason
);
611 /* Active dongle downstream unplug */
612 if (link
->type
== dc_connection_active_dongle
613 && link
->dpcd_caps
.sink_count
.
614 bits
.SINK_COUNT
== 0)
617 if (link
->type
== dc_connection_mst_branch
) {
618 LINK_INFO("link=%d, mst branch is now Connected\n",
620 /* Need to setup mst link_cap struct here
621 * otherwise dc_link_detect() will leave mst link_cap
622 * empty which leads to allocate_mst_payload() has "0"
623 * pbn_per_slot value leading to exception on dal_fixed31_32_div()
625 link
->verified_link_cap
= link
->reported_link_cap
;
633 DC_ERROR("Invalid connector type! signal:%d\n",
634 link
->connector_signal
);
638 if (link
->dpcd_caps
.sink_count
.bits
.SINK_COUNT
)
639 link
->dpcd_sink_count
= link
->dpcd_caps
.sink_count
.
642 link
->dpcd_sink_count
= 1;
644 dal_ddc_service_set_transaction_type(
646 sink_caps
.transaction_type
);
648 link
->aux_mode
= dal_ddc_service_is_in_aux_transaction_mode(
651 sink_init_data
.link
= link
;
652 sink_init_data
.sink_signal
= sink_caps
.signal
;
654 sink
= dc_sink_create(&sink_init_data
);
656 DC_ERROR("Failed to create sink!\n");
660 sink
->dongle_max_pix_clk
= sink_caps
.max_hdmi_pixel_clock
;
661 sink
->converter_disable_audio
= converter_disable_audio
;
663 link
->local_sink
= sink
;
665 edid_status
= dm_helpers_read_local_edid(
670 switch (edid_status
) {
671 case EDID_BAD_CHECKSUM
:
672 dm_logger_write(link
->ctx
->logger
, LOG_ERROR
,
673 "EDID checksum invalid.\n");
675 case EDID_NO_RESPONSE
:
676 dm_logger_write(link
->ctx
->logger
, LOG_ERROR
,
684 if (link
->connector_signal
== SIGNAL_TYPE_DISPLAY_PORT
&&
685 sink_caps
.transaction_type
==
686 DDC_TRANSACTION_TYPE_I2C_OVER_AUX
) {
688 * TODO debug why Dell 2413 doesn't like
692 /* deal with non-mst cases */
693 dp_hbr_verify_link_cap(link
, &link
->reported_link_cap
);
696 /* HDMI-DVI Dongle */
697 if (sink
->sink_signal
== SIGNAL_TYPE_HDMI_TYPE_A
&&
698 !sink
->edid_caps
.edid_hdmi
)
699 sink
->sink_signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
701 /* Connectivity log: detection */
702 for (i
= 0; i
< sink
->dc_edid
.length
/ EDID_BLOCK_SIZE
; i
++) {
703 CONN_DATA_DETECT(link
,
704 &sink
->dc_edid
.raw_edid
[i
* EDID_BLOCK_SIZE
],
706 "%s: [Block %d] ", sink
->edid_caps
.display_name
, i
);
709 dm_logger_write(link
->ctx
->logger
, LOG_DETECTION_EDID_PARSER
,
711 "manufacturer_id = %X, "
713 "serial_number = %X, "
714 "manufacture_week = %d, "
715 "manufacture_year = %d, "
716 "display_name = %s, "
717 "speaker_flag = %d, "
718 "audio_mode_count = %d\n",
720 sink
->edid_caps
.manufacturer_id
,
721 sink
->edid_caps
.product_id
,
722 sink
->edid_caps
.serial_number
,
723 sink
->edid_caps
.manufacture_week
,
724 sink
->edid_caps
.manufacture_year
,
725 sink
->edid_caps
.display_name
,
726 sink
->edid_caps
.speaker_flags
,
727 sink
->edid_caps
.audio_mode_count
);
729 for (i
= 0; i
< sink
->edid_caps
.audio_mode_count
; i
++) {
730 dm_logger_write(link
->ctx
->logger
, LOG_DETECTION_EDID_PARSER
,
731 "%s: mode number = %d, "
733 "channel_count = %d, "
735 "sample_size = %d\n",
738 sink
->edid_caps
.audio_modes
[i
].format_code
,
739 sink
->edid_caps
.audio_modes
[i
].channel_count
,
740 sink
->edid_caps
.audio_modes
[i
].sample_rate
,
741 sink
->edid_caps
.audio_modes
[i
].sample_size
);
745 /* From Connected-to-Disconnected. */
746 if (link
->type
== dc_connection_mst_branch
) {
747 LINK_INFO("link=%d, mst branch is now Disconnected\n",
749 dm_helpers_dp_mst_stop_top_mgr(link
->ctx
, link
);
751 link
->mst_stream_alloc_table
.stream_count
= 0;
752 memset(link
->mst_stream_alloc_table
.stream_allocations
, 0, sizeof(link
->mst_stream_alloc_table
.stream_allocations
));
755 link
->type
= dc_connection_none
;
756 sink_caps
.signal
= SIGNAL_TYPE_NONE
;
759 LINK_INFO("link=%d, dc_sink_in=%p is now %s\n",
760 link
->link_index
, sink
,
761 (sink_caps
.signal
== SIGNAL_TYPE_NONE
?
762 "Disconnected":"Connected"));
767 static enum hpd_source_id
get_hpd_line(
768 struct dc_link
*link
)
771 enum hpd_source_id hpd_id
= HPD_SOURCEID_UNKNOWN
;
773 hpd
= get_hpd_gpio(link
);
776 switch (dal_irq_get_source(hpd
)) {
777 case DC_IRQ_SOURCE_HPD1
:
778 hpd_id
= HPD_SOURCEID1
;
780 case DC_IRQ_SOURCE_HPD2
:
781 hpd_id
= HPD_SOURCEID2
;
783 case DC_IRQ_SOURCE_HPD3
:
784 hpd_id
= HPD_SOURCEID3
;
786 case DC_IRQ_SOURCE_HPD4
:
787 hpd_id
= HPD_SOURCEID4
;
789 case DC_IRQ_SOURCE_HPD5
:
790 hpd_id
= HPD_SOURCEID5
;
792 case DC_IRQ_SOURCE_HPD6
:
793 hpd_id
= HPD_SOURCEID6
;
800 dal_gpio_destroy_irq(&hpd
);
806 static enum channel_id
get_ddc_line(struct dc_link
*link
)
809 enum channel_id channel
= CHANNEL_ID_UNKNOWN
;
811 ddc
= dal_ddc_service_get_ddc_pin(link
->ddc
);
814 switch (dal_ddc_get_line(ddc
)) {
815 case GPIO_DDC_LINE_DDC1
:
816 channel
= CHANNEL_ID_DDC1
;
818 case GPIO_DDC_LINE_DDC2
:
819 channel
= CHANNEL_ID_DDC2
;
821 case GPIO_DDC_LINE_DDC3
:
822 channel
= CHANNEL_ID_DDC3
;
824 case GPIO_DDC_LINE_DDC4
:
825 channel
= CHANNEL_ID_DDC4
;
827 case GPIO_DDC_LINE_DDC5
:
828 channel
= CHANNEL_ID_DDC5
;
830 case GPIO_DDC_LINE_DDC6
:
831 channel
= CHANNEL_ID_DDC6
;
833 case GPIO_DDC_LINE_DDC_VGA
:
834 channel
= CHANNEL_ID_DDC_VGA
;
836 case GPIO_DDC_LINE_I2C_PAD
:
837 channel
= CHANNEL_ID_I2C_PAD
;
848 static enum transmitter
translate_encoder_to_transmitter(
849 struct graphics_object_id encoder
)
851 switch (encoder
.id
) {
852 case ENCODER_ID_INTERNAL_UNIPHY
:
853 switch (encoder
.enum_id
) {
855 return TRANSMITTER_UNIPHY_A
;
857 return TRANSMITTER_UNIPHY_B
;
859 return TRANSMITTER_UNKNOWN
;
862 case ENCODER_ID_INTERNAL_UNIPHY1
:
863 switch (encoder
.enum_id
) {
865 return TRANSMITTER_UNIPHY_C
;
867 return TRANSMITTER_UNIPHY_D
;
869 return TRANSMITTER_UNKNOWN
;
872 case ENCODER_ID_INTERNAL_UNIPHY2
:
873 switch (encoder
.enum_id
) {
875 return TRANSMITTER_UNIPHY_E
;
877 return TRANSMITTER_UNIPHY_F
;
879 return TRANSMITTER_UNKNOWN
;
882 case ENCODER_ID_INTERNAL_UNIPHY3
:
883 switch (encoder
.enum_id
) {
885 return TRANSMITTER_UNIPHY_G
;
887 return TRANSMITTER_UNKNOWN
;
890 case ENCODER_ID_EXTERNAL_NUTMEG
:
891 switch (encoder
.enum_id
) {
893 return TRANSMITTER_NUTMEG_CRT
;
895 return TRANSMITTER_UNKNOWN
;
898 case ENCODER_ID_EXTERNAL_TRAVIS
:
899 switch (encoder
.enum_id
) {
901 return TRANSMITTER_TRAVIS_CRT
;
903 return TRANSMITTER_TRAVIS_LCD
;
905 return TRANSMITTER_UNKNOWN
;
909 return TRANSMITTER_UNKNOWN
;
913 static bool construct(
914 struct dc_link
*link
,
915 const struct link_init_data
*init_params
)
918 struct gpio
*hpd_gpio
= NULL
;
919 struct ddc_service_init_data ddc_service_init_data
= { { 0 } };
920 struct dc_context
*dc_ctx
= init_params
->ctx
;
921 struct encoder_init_data enc_init_data
= { 0 };
922 struct integrated_info info
= {{{ 0 }}};
923 struct dc_bios
*bios
= init_params
->dc
->ctx
->dc_bios
;
924 const struct dc_vbios_funcs
*bp_funcs
= bios
->funcs
;
926 link
->irq_source_hpd
= DC_IRQ_SOURCE_INVALID
;
927 link
->irq_source_hpd_rx
= DC_IRQ_SOURCE_INVALID
;
929 link
->link_status
.dpcd_caps
= &link
->dpcd_caps
;
931 link
->dc
= init_params
->dc
;
933 link
->link_index
= init_params
->link_index
;
935 link
->link_id
= bios
->funcs
->get_connector_id(bios
, init_params
->connector_index
);
937 if (link
->link_id
.type
!= OBJECT_TYPE_CONNECTOR
) {
938 dm_error("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d!\n",
939 __func__
, init_params
->connector_index
);
943 hpd_gpio
= get_hpd_gpio(link
);
945 if (hpd_gpio
!= NULL
)
946 link
->irq_source_hpd
= dal_irq_get_source(hpd_gpio
);
948 switch (link
->link_id
.id
) {
949 case CONNECTOR_ID_HDMI_TYPE_A
:
950 link
->connector_signal
= SIGNAL_TYPE_HDMI_TYPE_A
;
953 case CONNECTOR_ID_SINGLE_LINK_DVID
:
954 case CONNECTOR_ID_SINGLE_LINK_DVII
:
955 link
->connector_signal
= SIGNAL_TYPE_DVI_SINGLE_LINK
;
957 case CONNECTOR_ID_DUAL_LINK_DVID
:
958 case CONNECTOR_ID_DUAL_LINK_DVII
:
959 link
->connector_signal
= SIGNAL_TYPE_DVI_DUAL_LINK
;
961 case CONNECTOR_ID_DISPLAY_PORT
:
962 link
->connector_signal
= SIGNAL_TYPE_DISPLAY_PORT
;
964 if (hpd_gpio
!= NULL
)
965 link
->irq_source_hpd_rx
=
966 dal_irq_get_rx_source(hpd_gpio
);
969 case CONNECTOR_ID_EDP
:
970 link
->connector_signal
= SIGNAL_TYPE_EDP
;
972 if (hpd_gpio
!= NULL
) {
973 link
->irq_source_hpd
= DC_IRQ_SOURCE_INVALID
;
974 link
->irq_source_hpd_rx
=
975 dal_irq_get_rx_source(hpd_gpio
);
979 dm_logger_write(dc_ctx
->logger
, LOG_WARNING
,
980 "Unsupported Connector type:%d!\n", link
->link_id
.id
);
984 if (hpd_gpio
!= NULL
) {
985 dal_gpio_destroy_irq(&hpd_gpio
);
989 /* TODO: #DAL3 Implement id to str function.*/
990 LINK_INFO("Connector[%d] description:"
992 init_params
->connector_index
,
993 link
->connector_signal
);
995 ddc_service_init_data
.ctx
= link
->ctx
;
996 ddc_service_init_data
.id
= link
->link_id
;
997 ddc_service_init_data
.link
= link
;
998 link
->ddc
= dal_ddc_service_create(&ddc_service_init_data
);
1000 if (link
->ddc
== NULL
) {
1001 DC_ERROR("Failed to create ddc_service!\n");
1002 goto ddc_create_fail
;
1007 dal_ddc_service_get_ddc_pin(link
->ddc
));
1009 enc_init_data
.ctx
= dc_ctx
;
1010 bp_funcs
->get_src_obj(dc_ctx
->dc_bios
, link
->link_id
, 0, &enc_init_data
.encoder
);
1011 enc_init_data
.connector
= link
->link_id
;
1012 enc_init_data
.channel
= get_ddc_line(link
);
1013 enc_init_data
.hpd_source
= get_hpd_line(link
);
1015 link
->hpd_src
= enc_init_data
.hpd_source
;
1017 enc_init_data
.transmitter
=
1018 translate_encoder_to_transmitter(enc_init_data
.encoder
);
1019 link
->link_enc
= link
->dc
->res_pool
->funcs
->link_enc_create(
1022 if( link
->link_enc
== NULL
) {
1023 DC_ERROR("Failed to create link encoder!\n");
1024 goto link_enc_create_fail
;
1027 link
->link_enc_hw_inst
= link
->link_enc
->transmitter
;
1029 for (i
= 0; i
< 4; i
++) {
1031 bp_funcs
->get_device_tag(dc_ctx
->dc_bios
, link
->link_id
, i
, &link
->device_tag
)) {
1032 DC_ERROR("Failed to find device tag!\n");
1033 goto device_tag_fail
;
1036 /* Look for device tag that matches connector signal,
1037 * CRT for rgb, LCD for other supported signal tyes
1039 if (!bp_funcs
->is_device_id_supported(dc_ctx
->dc_bios
, link
->device_tag
.dev_id
))
1041 if (link
->device_tag
.dev_id
.device_type
== DEVICE_TYPE_CRT
1042 && link
->connector_signal
!= SIGNAL_TYPE_RGB
)
1044 if (link
->device_tag
.dev_id
.device_type
== DEVICE_TYPE_LCD
1045 && link
->connector_signal
== SIGNAL_TYPE_RGB
)
1050 if (bios
->integrated_info
)
1051 info
= *bios
->integrated_info
;
1053 /* Look for channel mapping corresponding to connector and device tag */
1054 for (i
= 0; i
< MAX_NUMBER_OF_EXT_DISPLAY_PATH
; i
++) {
1055 struct external_display_path
*path
=
1056 &info
.ext_disp_conn_info
.path
[i
];
1057 if (path
->device_connector_id
.enum_id
== link
->link_id
.enum_id
1058 && path
->device_connector_id
.id
== link
->link_id
.id
1059 && path
->device_connector_id
.type
== link
->link_id
.type
) {
1061 if (link
->device_tag
.acpi_device
!= 0
1062 && path
->device_acpi_enum
== link
->device_tag
.acpi_device
) {
1063 link
->ddi_channel_mapping
= path
->channel_mapping
;
1064 link
->chip_caps
= path
->caps
;
1065 } else if (path
->device_tag
==
1066 link
->device_tag
.dev_id
.raw_device_tag
) {
1067 link
->ddi_channel_mapping
= path
->channel_mapping
;
1068 link
->chip_caps
= path
->caps
;
1075 * TODO check if GPIO programmed correctly
1077 * If GPIO isn't programmed correctly HPD might not rise or drain
1078 * fast enough, leading to bounces.
1080 program_hpd_filter(link
);
1084 link
->link_enc
->funcs
->destroy(&link
->link_enc
);
1085 link_enc_create_fail
:
1086 dal_ddc_service_destroy(&link
->ddc
);
1090 if (hpd_gpio
!= NULL
) {
1091 dal_gpio_destroy_irq(&hpd_gpio
);
1097 /*******************************************************************************
1099 ******************************************************************************/
1100 struct dc_link
*link_create(const struct link_init_data
*init_params
)
1102 struct dc_link
*link
=
1103 kzalloc(sizeof(*link
), GFP_KERNEL
);
1108 if (false == construct(link
, init_params
))
1109 goto construct_fail
;
1120 void link_destroy(struct dc_link
**link
)
1127 static void dpcd_configure_panel_mode(
1128 struct dc_link
*link
,
1129 enum dp_panel_mode panel_mode
)
1131 union dpcd_edp_config edp_config_set
;
1132 bool panel_mode_edp
= false;
1134 memset(&edp_config_set
, '\0', sizeof(union dpcd_edp_config
));
1136 if (DP_PANEL_MODE_DEFAULT
!= panel_mode
) {
1138 switch (panel_mode
) {
1139 case DP_PANEL_MODE_EDP
:
1140 case DP_PANEL_MODE_SPECIAL
:
1141 panel_mode_edp
= true;
1148 /*set edp panel mode in receiver*/
1149 core_link_read_dpcd(
1151 DP_EDP_CONFIGURATION_SET
,
1152 &edp_config_set
.raw
,
1153 sizeof(edp_config_set
.raw
));
1155 if (edp_config_set
.bits
.PANEL_MODE_EDP
1156 != panel_mode_edp
) {
1157 enum ddc_result result
= DDC_RESULT_UNKNOWN
;
1159 edp_config_set
.bits
.PANEL_MODE_EDP
=
1161 result
= core_link_write_dpcd(
1163 DP_EDP_CONFIGURATION_SET
,
1164 &edp_config_set
.raw
,
1165 sizeof(edp_config_set
.raw
));
1167 ASSERT(result
== DDC_RESULT_SUCESSFULL
);
1170 dm_logger_write(link
->ctx
->logger
, LOG_DETECTION_DP_CAPS
,
1171 "Link: %d eDP panel mode supported: %d "
1172 "eDP panel mode enabled: %d \n",
1174 link
->dpcd_caps
.panel_mode_edp
,
1178 static void enable_stream_features(struct pipe_ctx
*pipe_ctx
)
1180 struct dc_stream_state
*stream
= pipe_ctx
->stream
;
1181 struct dc_link
*link
= stream
->sink
->link
;
1182 union down_spread_ctrl downspread
;
1184 core_link_read_dpcd(link
, DP_DOWNSPREAD_CTRL
,
1185 &downspread
.raw
, sizeof(downspread
));
1187 downspread
.bits
.IGNORE_MSA_TIMING_PARAM
=
1188 (stream
->ignore_msa_timing_param
) ? 1 : 0;
1190 core_link_write_dpcd(link
, DP_DOWNSPREAD_CTRL
,
1191 &downspread
.raw
, sizeof(downspread
));
1194 static enum dc_status
enable_link_dp(
1195 struct dc_state
*state
,
1196 struct pipe_ctx
*pipe_ctx
)
1198 struct dc_stream_state
*stream
= pipe_ctx
->stream
;
1199 enum dc_status status
;
1200 bool skip_video_pattern
;
1201 struct dc_link
*link
= stream
->sink
->link
;
1202 struct dc_link_settings link_settings
= {0};
1203 enum dp_panel_mode panel_mode
;
1204 enum dc_link_rate max_link_rate
= LINK_RATE_HIGH2
;
1206 /* get link settings for video mode timing */
1207 decide_link_settings(stream
, &link_settings
);
1209 /* raise clock state for HBR3 if required. Confirmed with HW DCE/DPCS
1210 * logic for HBR3 still needs Nominal (0.8V) on VDDC rail
1212 if (link
->link_enc
->features
.flags
.bits
.IS_HBR3_CAPABLE
)
1213 max_link_rate
= LINK_RATE_HIGH3
;
1215 if (link_settings
.link_rate
== max_link_rate
) {
1216 if (state
->dis_clk
->funcs
->set_min_clocks_state
) {
1217 if (state
->dis_clk
->cur_min_clks_state
< DM_PP_CLOCKS_STATE_NOMINAL
)
1218 state
->dis_clk
->funcs
->set_min_clocks_state(
1219 state
->dis_clk
, DM_PP_CLOCKS_STATE_NOMINAL
);
1221 uint32_t dp_phyclk_in_khz
;
1222 const struct clocks_value clocks_value
=
1223 state
->dis_clk
->cur_clocks_value
;
1225 /* 27mhz = 27000000hz= 27000khz */
1226 dp_phyclk_in_khz
= link_settings
.link_rate
* 27000;
1228 if (((clocks_value
.max_non_dp_phyclk_in_khz
!= 0) &&
1229 (dp_phyclk_in_khz
> clocks_value
.max_non_dp_phyclk_in_khz
)) ||
1230 (dp_phyclk_in_khz
> clocks_value
.max_dp_phyclk_in_khz
)) {
1231 state
->dis_clk
->funcs
->apply_clock_voltage_request(
1233 DM_PP_CLOCK_TYPE_DISPLAYPHYCLK
,
1243 pipe_ctx
->stream
->signal
,
1244 pipe_ctx
->clock_source
->id
,
1247 panel_mode
= dp_get_panel_mode(link
);
1248 dpcd_configure_panel_mode(link
, panel_mode
);
1250 skip_video_pattern
= true;
1252 if (link_settings
.link_rate
== LINK_RATE_LOW
)
1253 skip_video_pattern
= false;
1255 if (perform_link_training_with_retries(
1259 LINK_TRAINING_ATTEMPTS
)) {
1260 link
->cur_link_settings
= link_settings
;
1264 status
= DC_FAIL_DP_LINK_TRAINING
;
1266 enable_stream_features(pipe_ctx
);
1271 static enum dc_status
enable_link_dp_mst(
1272 struct dc_state
*state
,
1273 struct pipe_ctx
*pipe_ctx
)
1275 struct dc_link
*link
= pipe_ctx
->stream
->sink
->link
;
1277 /* sink signal type after MST branch is MST. Multiple MST sinks
1278 * share one link. Link DP PHY is enable or training only once.
1280 if (link
->cur_link_settings
.lane_count
!= LANE_COUNT_UNKNOWN
)
1283 /* set the sink to MST mode before enabling the link */
1284 dp_enable_mst_on_sink(link
, true);
1286 return enable_link_dp(state
, pipe_ctx
);
1289 static bool get_ext_hdmi_settings(struct pipe_ctx
*pipe_ctx
,
1290 enum engine_id eng_id
,
1291 struct ext_hdmi_settings
*settings
)
1293 bool result
= false;
1295 struct integrated_info
*integrated_info
=
1296 pipe_ctx
->stream
->ctx
->dc_bios
->integrated_info
;
1298 if (integrated_info
== NULL
)
1302 * Get retimer settings from sbios for passing SI eye test for DCE11
1303 * The setting values are varied based on board revision and port id
1304 * Therefore the setting values of each ports is passed by sbios.
1307 // Check if current bios contains ext Hdmi settings
1308 if (integrated_info
->gpu_cap_info
& 0x20) {
1310 case ENGINE_ID_DIGA
:
1311 settings
->slv_addr
= integrated_info
->dp0_ext_hdmi_slv_addr
;
1312 settings
->reg_num
= integrated_info
->dp0_ext_hdmi_6g_reg_num
;
1313 settings
->reg_num_6g
= integrated_info
->dp0_ext_hdmi_6g_reg_num
;
1314 memmove(settings
->reg_settings
,
1315 integrated_info
->dp0_ext_hdmi_reg_settings
,
1316 sizeof(integrated_info
->dp0_ext_hdmi_reg_settings
));
1317 memmove(settings
->reg_settings_6g
,
1318 integrated_info
->dp0_ext_hdmi_6g_reg_settings
,
1319 sizeof(integrated_info
->dp0_ext_hdmi_6g_reg_settings
));
1322 case ENGINE_ID_DIGB
:
1323 settings
->slv_addr
= integrated_info
->dp1_ext_hdmi_slv_addr
;
1324 settings
->reg_num
= integrated_info
->dp1_ext_hdmi_6g_reg_num
;
1325 settings
->reg_num_6g
= integrated_info
->dp1_ext_hdmi_6g_reg_num
;
1326 memmove(settings
->reg_settings
,
1327 integrated_info
->dp1_ext_hdmi_reg_settings
,
1328 sizeof(integrated_info
->dp1_ext_hdmi_reg_settings
));
1329 memmove(settings
->reg_settings_6g
,
1330 integrated_info
->dp1_ext_hdmi_6g_reg_settings
,
1331 sizeof(integrated_info
->dp1_ext_hdmi_6g_reg_settings
));
1334 case ENGINE_ID_DIGC
:
1335 settings
->slv_addr
= integrated_info
->dp2_ext_hdmi_slv_addr
;
1336 settings
->reg_num
= integrated_info
->dp2_ext_hdmi_6g_reg_num
;
1337 settings
->reg_num_6g
= integrated_info
->dp2_ext_hdmi_6g_reg_num
;
1338 memmove(settings
->reg_settings
,
1339 integrated_info
->dp2_ext_hdmi_reg_settings
,
1340 sizeof(integrated_info
->dp2_ext_hdmi_reg_settings
));
1341 memmove(settings
->reg_settings_6g
,
1342 integrated_info
->dp2_ext_hdmi_6g_reg_settings
,
1343 sizeof(integrated_info
->dp2_ext_hdmi_6g_reg_settings
));
1351 if (result
== true) {
1352 // Validate settings from bios integrated info table
1353 if (settings
->slv_addr
== 0)
1355 if (settings
->reg_num
> 9)
1357 if (settings
->reg_num_6g
> 3)
1360 for (i
= 0; i
< settings
->reg_num
; i
++) {
1361 if (settings
->reg_settings
[i
].i2c_reg_index
> 0x20)
1365 for (i
= 0; i
< settings
->reg_num_6g
; i
++) {
1366 if (settings
->reg_settings_6g
[i
].i2c_reg_index
> 0x20)
1375 static bool i2c_write(struct pipe_ctx
*pipe_ctx
,
1376 uint8_t address
, uint8_t *buffer
, uint32_t length
)
1378 struct i2c_command cmd
= {0};
1379 struct i2c_payload payload
= {0};
1381 memset(&payload
, 0, sizeof(payload
));
1382 memset(&cmd
, 0, sizeof(cmd
));
1384 cmd
.number_of_payloads
= 1;
1385 cmd
.engine
= I2C_COMMAND_ENGINE_DEFAULT
;
1386 cmd
.speed
= pipe_ctx
->stream
->ctx
->dc
->caps
.i2c_speed_in_khz
;
1388 payload
.address
= address
;
1389 payload
.data
= buffer
;
1390 payload
.length
= length
;
1391 payload
.write
= true;
1392 cmd
.payloads
= &payload
;
1394 if (dc_submit_i2c(pipe_ctx
->stream
->ctx
->dc
,
1395 pipe_ctx
->stream
->sink
->link
->link_index
, &cmd
))
1401 static void write_i2c_retimer_setting(
1402 struct pipe_ctx
*pipe_ctx
,
1404 bool is_over_340mhz
,
1405 struct ext_hdmi_settings
*settings
)
1407 uint8_t slave_address
= (settings
->slv_addr
>> 1);
1409 const uint8_t apply_rx_tx_change
= 0x4;
1410 uint8_t offset
= 0xA;
1413 bool i2c_success
= false;
1415 memset(&buffer
, 0, sizeof(buffer
));
1417 /* Start Ext-Hdmi programming*/
1419 for (i
= 0; i
< settings
->reg_num
; i
++) {
1420 /* Apply 3G settings */
1421 if (settings
->reg_settings
[i
].i2c_reg_index
<= 0x20) {
1423 buffer
[0] = settings
->reg_settings
[i
].i2c_reg_index
;
1424 buffer
[1] = settings
->reg_settings
[i
].i2c_reg_val
;
1425 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1426 buffer
, sizeof(buffer
));
1430 ASSERT(i2c_success
);
1432 /* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A
1433 * needs to be set to 1 on every 0xA-0xC write.
1435 if (settings
->reg_settings
[i
].i2c_reg_index
== 0xA ||
1436 settings
->reg_settings
[i
].i2c_reg_index
== 0xB ||
1437 settings
->reg_settings
[i
].i2c_reg_index
== 0xC) {
1439 /* Query current value from offset 0xA */
1440 if (settings
->reg_settings
[i
].i2c_reg_index
== 0xA)
1441 value
= settings
->reg_settings
[i
].i2c_reg_val
;
1444 dal_ddc_service_query_ddc_data(
1445 pipe_ctx
->stream
->sink
->link
->ddc
,
1446 slave_address
, &offset
, 1, &value
, 1);
1449 ASSERT(i2c_success
);
1453 /* Set APPLY_RX_TX_CHANGE bit to 1 */
1454 buffer
[1] = value
| apply_rx_tx_change
;
1455 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1456 buffer
, sizeof(buffer
));
1459 ASSERT(i2c_success
);
1464 /* Apply 3G settings */
1465 if (is_over_340mhz
) {
1466 for (i
= 0; i
< settings
->reg_num_6g
; i
++) {
1467 /* Apply 3G settings */
1468 if (settings
->reg_settings
[i
].i2c_reg_index
<= 0x20) {
1470 buffer
[0] = settings
->reg_settings_6g
[i
].i2c_reg_index
;
1471 buffer
[1] = settings
->reg_settings_6g
[i
].i2c_reg_val
;
1472 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1473 buffer
, sizeof(buffer
));
1477 ASSERT(i2c_success
);
1479 /* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A
1480 * needs to be set to 1 on every 0xA-0xC write.
1482 if (settings
->reg_settings_6g
[i
].i2c_reg_index
== 0xA ||
1483 settings
->reg_settings_6g
[i
].i2c_reg_index
== 0xB ||
1484 settings
->reg_settings_6g
[i
].i2c_reg_index
== 0xC) {
1486 /* Query current value from offset 0xA */
1487 if (settings
->reg_settings_6g
[i
].i2c_reg_index
== 0xA)
1488 value
= settings
->reg_settings_6g
[i
].i2c_reg_val
;
1491 dal_ddc_service_query_ddc_data(
1492 pipe_ctx
->stream
->sink
->link
->ddc
,
1493 slave_address
, &offset
, 1, &value
, 1);
1496 ASSERT(i2c_success
);
1500 /* Set APPLY_RX_TX_CHANGE bit to 1 */
1501 buffer
[1] = value
| apply_rx_tx_change
;
1502 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1503 buffer
, sizeof(buffer
));
1506 ASSERT(i2c_success
);
1513 /* Program additional settings if using 640x480 resolution */
1515 /* Write offset 0xFF to 0x01 */
1518 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1519 buffer
, sizeof(buffer
));
1522 ASSERT(i2c_success
);
1524 /* Write offset 0x00 to 0x23 */
1527 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1528 buffer
, sizeof(buffer
));
1531 ASSERT(i2c_success
);
1533 /* Write offset 0xff to 0x00 */
1536 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1537 buffer
, sizeof(buffer
));
1540 ASSERT(i2c_success
);
1545 static void write_i2c_default_retimer_setting(
1546 struct pipe_ctx
*pipe_ctx
,
1548 bool is_over_340mhz
)
1550 uint8_t slave_address
= (0xBA >> 1);
1552 bool i2c_success
= false;
1554 memset(&buffer
, 0, sizeof(buffer
));
1556 /* Program Slave Address for tuning single integrity */
1557 /* Write offset 0x0A to 0x13 */
1560 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1561 buffer
, sizeof(buffer
));
1564 ASSERT(i2c_success
);
1566 /* Write offset 0x0A to 0x17 */
1569 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1570 buffer
, sizeof(buffer
));
1573 ASSERT(i2c_success
);
1575 /* Write offset 0x0B to 0xDA or 0xD8 */
1577 buffer
[1] = is_over_340mhz
? 0xDA : 0xD8;
1578 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1579 buffer
, sizeof(buffer
));
1582 ASSERT(i2c_success
);
1584 /* Write offset 0x0A to 0x17 */
1587 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1588 buffer
, sizeof(buffer
));
1591 ASSERT(i2c_success
);
1593 /* Write offset 0x0C to 0x1D or 0x91 */
1595 buffer
[1] = is_over_340mhz
? 0x1D : 0x91;
1596 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1597 buffer
, sizeof(buffer
));
1600 ASSERT(i2c_success
);
1602 /* Write offset 0x0A to 0x17 */
1605 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1606 buffer
, sizeof(buffer
));
1609 ASSERT(i2c_success
);
1613 /* Program additional settings if using 640x480 resolution */
1615 /* Write offset 0xFF to 0x01 */
1618 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1619 buffer
, sizeof(buffer
));
1622 ASSERT(i2c_success
);
1624 /* Write offset 0x00 to 0x23 */
1627 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1628 buffer
, sizeof(buffer
));
1631 ASSERT(i2c_success
);
1633 /* Write offset 0xff to 0x00 */
1636 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1637 buffer
, sizeof(buffer
));
1640 ASSERT(i2c_success
);
1644 static void write_i2c_redriver_setting(
1645 struct pipe_ctx
*pipe_ctx
,
1646 bool is_over_340mhz
)
1648 uint8_t slave_address
= (0xF0 >> 1);
1650 bool i2c_success
= false;
1652 memset(&buffer
, 0, sizeof(buffer
));
1654 // Program Slave Address for tuning single integrity
1658 buffer
[6] = is_over_340mhz
? 0x4E : 0x4A;
1660 i2c_success
= i2c_write(pipe_ctx
, slave_address
,
1661 buffer
, sizeof(buffer
));
1665 ASSERT(i2c_success
);
1668 static void enable_link_hdmi(struct pipe_ctx
*pipe_ctx
)
1670 struct dc_stream_state
*stream
= pipe_ctx
->stream
;
1671 struct dc_link
*link
= stream
->sink
->link
;
1672 enum dc_color_depth display_color_depth
;
1673 enum engine_id eng_id
;
1674 struct ext_hdmi_settings settings
= {0};
1675 bool is_over_340mhz
= false;
1676 bool is_vga_mode
= (stream
->timing
.h_addressable
== 640)
1677 && (stream
->timing
.v_addressable
== 480);
1679 if (stream
->phy_pix_clk
> 340000)
1680 is_over_340mhz
= true;
1682 if (dc_is_hdmi_signal(pipe_ctx
->stream
->signal
)) {
1683 if ((pipe_ctx
->stream
->sink
->link
->chip_caps
>> 2) == 0x2) {
1684 /* DP159, Retimer settings */
1685 eng_id
= pipe_ctx
->stream_res
.stream_enc
->id
;
1687 if (get_ext_hdmi_settings(pipe_ctx
, eng_id
, &settings
)) {
1688 write_i2c_retimer_setting(pipe_ctx
,
1689 is_vga_mode
, is_over_340mhz
, &settings
);
1691 write_i2c_default_retimer_setting(pipe_ctx
,
1692 is_vga_mode
, is_over_340mhz
);
1694 } else if ((pipe_ctx
->stream
->sink
->link
->chip_caps
>> 2) == 0x1) {
1695 /* PI3EQX1204, Redriver settings */
1696 write_i2c_redriver_setting(pipe_ctx
, is_over_340mhz
);
1700 if (dc_is_hdmi_signal(pipe_ctx
->stream
->signal
))
1701 dal_ddc_service_write_scdc_data(
1702 stream
->sink
->link
->ddc
,
1703 stream
->phy_pix_clk
,
1704 stream
->timing
.flags
.LTE_340MCSC_SCRAMBLE
);
1706 memset(&stream
->sink
->link
->cur_link_settings
, 0,
1707 sizeof(struct dc_link_settings
));
1709 display_color_depth
= stream
->timing
.display_color_depth
;
1710 if (stream
->timing
.pixel_encoding
== PIXEL_ENCODING_YCBCR422
)
1711 display_color_depth
= COLOR_DEPTH_888
;
1713 link
->link_enc
->funcs
->enable_tmds_output(
1715 pipe_ctx
->clock_source
->id
,
1716 display_color_depth
,
1717 pipe_ctx
->stream
->signal
== SIGNAL_TYPE_HDMI_TYPE_A
,
1718 pipe_ctx
->stream
->signal
== SIGNAL_TYPE_DVI_DUAL_LINK
,
1719 stream
->phy_pix_clk
);
1721 if (pipe_ctx
->stream
->signal
== SIGNAL_TYPE_HDMI_TYPE_A
)
1722 dal_ddc_service_read_scdc_data(link
->ddc
);
1725 /****************************enable_link***********************************/
1726 static enum dc_status
enable_link(
1727 struct dc_state
*state
,
1728 struct pipe_ctx
*pipe_ctx
)
1730 enum dc_status status
= DC_ERROR_UNEXPECTED
;
1731 switch (pipe_ctx
->stream
->signal
) {
1732 case SIGNAL_TYPE_DISPLAY_PORT
:
1733 case SIGNAL_TYPE_EDP
:
1734 status
= enable_link_dp(state
, pipe_ctx
);
1736 case SIGNAL_TYPE_DISPLAY_PORT_MST
:
1737 status
= enable_link_dp_mst(state
, pipe_ctx
);
1740 case SIGNAL_TYPE_DVI_SINGLE_LINK
:
1741 case SIGNAL_TYPE_DVI_DUAL_LINK
:
1742 case SIGNAL_TYPE_HDMI_TYPE_A
:
1743 enable_link_hdmi(pipe_ctx
);
1746 case SIGNAL_TYPE_VIRTUAL
:
1753 if (pipe_ctx
->stream_res
.audio
&& status
== DC_OK
) {
1754 /* notify audio driver for audio modes of monitor */
1755 pipe_ctx
->stream_res
.audio
->funcs
->az_enable(pipe_ctx
->stream_res
.audio
);
1758 /* TODO: audio should be per stream rather than per link */
1759 pipe_ctx
->stream_res
.stream_enc
->funcs
->audio_mute_control(
1760 pipe_ctx
->stream_res
.stream_enc
, false);
1766 static void disable_link(struct dc_link
*link
, enum signal_type signal
)
1769 * TODO: implement call for dp_set_hw_test_pattern
1770 * it is needed for compliance testing
1773 /* here we need to specify that encoder output settings
1774 * need to be calculated as for the set mode,
1775 * it will lead to querying dynamic link capabilities
1776 * which should be done before enable output */
1778 if (dc_is_dp_signal(signal
)) {
1780 if (dc_is_dp_sst_signal(signal
))
1781 dp_disable_link_phy(link
, signal
);
1783 dp_disable_link_phy_mst(link
, signal
);
1785 link
->link_enc
->funcs
->disable_output(link
->link_enc
, signal
);
1788 enum dc_status
dc_link_validate_mode_timing(
1789 const struct dc_stream_state
*stream
,
1790 struct dc_link
*link
,
1791 const struct dc_crtc_timing
*timing
)
1793 uint32_t max_pix_clk
= stream
->sink
->dongle_max_pix_clk
;
1795 /* A hack to avoid failing any modes for EDID override feature on
1796 * topology change such as lower quality cable for DP or different dongle
1798 if (link
->remote_sinks
[0])
1801 if (0 != max_pix_clk
&& timing
->pix_clk_khz
> max_pix_clk
)
1802 return DC_EXCEED_DONGLE_MAX_CLK
;
1804 switch (stream
->signal
) {
1805 case SIGNAL_TYPE_EDP
:
1806 case SIGNAL_TYPE_DISPLAY_PORT
:
1807 if (!dp_validate_mode_timing(
1810 return DC_NO_DP_LINK_BANDWIDTH
;
1821 bool dc_link_set_backlight_level(const struct dc_link
*link
, uint32_t level
,
1822 uint32_t frame_ramp
, const struct dc_stream_state
*stream
)
1824 struct dc
*core_dc
= link
->ctx
->dc
;
1825 struct abm
*abm
= core_dc
->res_pool
->abm
;
1826 unsigned int controller_id
= 0;
1829 if ((abm
== NULL
) || (abm
->funcs
->set_backlight_level
== NULL
))
1832 dm_logger_write(link
->ctx
->logger
, LOG_BACKLIGHT
,
1833 "New Backlight level: %d (0x%X)\n", level
, level
);
1835 if (dc_is_embedded_signal(link
->connector_signal
)) {
1836 if (stream
!= NULL
) {
1837 for (i
= 0; i
< MAX_PIPES
; i
++) {
1838 if (core_dc
->current_state
->res_ctx
.
1841 /* DMCU -1 for all controller id values,
1845 core_dc
->current_state
->
1846 res_ctx
.pipe_ctx
[i
].stream_res
.tg
->inst
+
1850 abm
->funcs
->set_backlight_level(
1861 bool dc_link_set_abm_disable(const struct dc_link
*link
)
1863 struct dc
*core_dc
= link
->ctx
->dc
;
1864 struct abm
*abm
= core_dc
->res_pool
->abm
;
1866 if ((abm
== NULL
) || (abm
->funcs
->set_backlight_level
== NULL
))
1869 abm
->funcs
->set_abm_immediate_disable(abm
);
1875 bool dc_link_set_psr_enable(const struct dc_link
*link
, bool enable
, bool wait
)
1877 struct dc
*core_dc
= link
->ctx
->dc
;
1878 struct dmcu
*dmcu
= core_dc
->res_pool
->dmcu
;
1880 if (dmcu
!= NULL
&& link
->psr_enabled
)
1881 dmcu
->funcs
->set_psr_enable(dmcu
, enable
, wait
);
1886 bool dc_link_get_psr_state(const struct dc_link
*link
, uint32_t *psr_state
)
1888 struct dc
*core_dc
= link
->ctx
->dc
;
1889 struct dmcu
*dmcu
= core_dc
->res_pool
->dmcu
;
1891 if (dmcu
!= NULL
&& link
->psr_enabled
)
1892 dmcu
->funcs
->get_psr_state(dmcu
, psr_state
);
1897 bool dc_link_setup_psr(struct dc_link
*link
,
1898 const struct dc_stream_state
*stream
, struct psr_config
*psr_config
,
1899 struct psr_context
*psr_context
)
1901 struct dc
*core_dc
= link
->ctx
->dc
;
1902 struct dmcu
*dmcu
= core_dc
->res_pool
->dmcu
;
1905 psr_context
->controllerId
= CONTROLLER_ID_UNDEFINED
;
1909 /* updateSinkPsrDpcdConfig*/
1910 union dpcd_psr_configuration psr_configuration
;
1912 memset(&psr_configuration
, 0, sizeof(psr_configuration
));
1914 psr_configuration
.bits
.ENABLE
= 1;
1915 psr_configuration
.bits
.CRC_VERIFICATION
= 1;
1916 psr_configuration
.bits
.FRAME_CAPTURE_INDICATION
=
1917 psr_config
->psr_frame_capture_indication_req
;
1919 /* Check for PSR v2*/
1920 if (psr_config
->psr_version
== 0x2) {
1921 /* For PSR v2 selective update.
1922 * Indicates whether sink should start capturing
1923 * immediately following active scan line,
1924 * or starting with the 2nd active scan line.
1926 psr_configuration
.bits
.LINE_CAPTURE_INDICATION
= 0;
1927 /*For PSR v2, determines whether Sink should generate
1928 * IRQ_HPD when CRC mismatch is detected.
1930 psr_configuration
.bits
.IRQ_HPD_WITH_CRC_ERROR
= 1;
1933 dm_helpers_dp_write_dpcd(
1937 &psr_configuration
.raw
,
1938 sizeof(psr_configuration
.raw
));
1940 psr_context
->channel
= link
->ddc
->ddc_pin
->hw_info
.ddc_channel
;
1941 psr_context
->transmitterId
= link
->link_enc
->transmitter
;
1942 psr_context
->engineId
= link
->link_enc
->preferred_engine
;
1944 for (i
= 0; i
< MAX_PIPES
; i
++) {
1945 if (core_dc
->current_state
->res_ctx
.pipe_ctx
[i
].stream
1947 /* dmcu -1 for all controller id values,
1950 psr_context
->controllerId
=
1951 core_dc
->current_state
->res_ctx
.
1952 pipe_ctx
[i
].stream_res
.tg
->inst
+ 1;
1957 /* Hardcoded for now. Can be Pcie or Uniphy (or Unknown)*/
1958 psr_context
->phyType
= PHY_TYPE_UNIPHY
;
1959 /*PhyId is associated with the transmitter id*/
1960 psr_context
->smuPhyId
= link
->link_enc
->transmitter
;
1962 psr_context
->crtcTimingVerticalTotal
= stream
->timing
.v_total
;
1963 psr_context
->vsyncRateHz
= div64_u64(div64_u64((stream
->
1964 timing
.pix_clk_khz
* 1000),
1965 stream
->timing
.v_total
),
1966 stream
->timing
.h_total
);
1968 psr_context
->psrSupportedDisplayConfig
= true;
1969 psr_context
->psrExitLinkTrainingRequired
=
1970 psr_config
->psr_exit_link_training_required
;
1971 psr_context
->sdpTransmitLineNumDeadline
=
1972 psr_config
->psr_sdp_transmit_line_num_deadline
;
1973 psr_context
->psrFrameCaptureIndicationReq
=
1974 psr_config
->psr_frame_capture_indication_req
;
1976 psr_context
->skipPsrWaitForPllLock
= 0; /* only = 1 in KV */
1978 psr_context
->numberOfControllers
=
1979 link
->dc
->res_pool
->res_cap
->num_timing_generator
;
1981 psr_context
->rfb_update_auto_en
= true;
1983 /* 2 frames before enter PSR. */
1984 psr_context
->timehyst_frames
= 2;
1986 * (units in 100 lines, i.e. a value of 1 represents 100 lines)
1988 psr_context
->hyst_lines
= stream
->timing
.v_total
/ 2 / 100;
1989 psr_context
->aux_repeats
= 10;
1991 psr_context
->psr_level
.u32all
= 0;
1993 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
1994 /*skip power down the single pipe since it blocks the cstate*/
1995 if (ASIC_REV_IS_RAVEN(link
->ctx
->asic_id
.hw_internal_rev
))
1996 psr_context
->psr_level
.bits
.SKIP_CRTC_DISABLE
= true;
1999 /* SMU will perform additional powerdown sequence.
2000 * For unsupported ASICs, set psr_level flag to skip PSR
2001 * static screen notification to SMU.
2002 * (Always set for DAL2, did not check ASIC)
2004 psr_context
->psr_level
.bits
.SKIP_SMU_NOTIFICATION
= 1;
2006 /* Complete PSR entry before aborting to prevent intermittent
2007 * freezes on certain eDPs
2009 psr_context
->psr_level
.bits
.DISABLE_PSR_ENTRY_ABORT
= 1;
2011 /* Controls additional delay after remote frame capture before
2012 * continuing power down, default = 0
2014 psr_context
->frame_delay
= 0;
2016 link
->psr_enabled
= true;
2017 dmcu
->funcs
->setup_psr(dmcu
, link
, psr_context
);
2024 const struct dc_link_status
*dc_link_get_status(const struct dc_link
*link
)
2026 return &link
->link_status
;
2029 void core_link_resume(struct dc_link
*link
)
2031 if (link
->connector_signal
!= SIGNAL_TYPE_VIRTUAL
)
2032 program_hpd_filter(link
);
2035 static struct fixed31_32
get_pbn_per_slot(struct dc_stream_state
*stream
)
2037 struct dc_link_settings
*link_settings
=
2038 &stream
->sink
->link
->cur_link_settings
;
2039 uint32_t link_rate_in_mbps
=
2040 link_settings
->link_rate
* LINK_RATE_REF_FREQ_IN_MHZ
;
2041 struct fixed31_32 mbps
= dal_fixed31_32_from_int(
2042 link_rate_in_mbps
* link_settings
->lane_count
);
2044 return dal_fixed31_32_div_int(mbps
, 54);
2047 static int get_color_depth(enum dc_color_depth color_depth
)
2049 switch (color_depth
) {
2050 case COLOR_DEPTH_666
: return 6;
2051 case COLOR_DEPTH_888
: return 8;
2052 case COLOR_DEPTH_101010
: return 10;
2053 case COLOR_DEPTH_121212
: return 12;
2054 case COLOR_DEPTH_141414
: return 14;
2055 case COLOR_DEPTH_161616
: return 16;
2060 static struct fixed31_32
get_pbn_from_timing(struct pipe_ctx
*pipe_ctx
)
2064 struct fixed31_32 peak_kbps
;
2066 uint32_t denominator
;
2068 bpc
= get_color_depth(pipe_ctx
->stream_res
.pix_clk_params
.color_depth
);
2069 kbps
= pipe_ctx
->stream_res
.pix_clk_params
.requested_pix_clk
* bpc
* 3;
2072 * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
2073 * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on
2074 * common multiplier to render an integer PBN for all link rate/lane
2075 * counts combinations
2077 * peak_kbps *= (1006/1000)
2078 * peak_kbps *= (64/54)
2079 * peak_kbps *= 8 convert to bytes
2082 numerator
= 64 * PEAK_FACTOR_X1000
;
2083 denominator
= 54 * 8 * 1000 * 1000;
2085 peak_kbps
= dal_fixed31_32_from_fraction(kbps
, denominator
);
2090 static void update_mst_stream_alloc_table(
2091 struct dc_link
*link
,
2092 struct stream_encoder
*stream_enc
,
2093 const struct dp_mst_stream_allocation_table
*proposed_table
)
2095 struct link_mst_stream_allocation work_table
[MAX_CONTROLLER_NUM
] = {
2097 struct link_mst_stream_allocation
*dc_alloc
;
2102 /* if DRM proposed_table has more than one new payload */
2103 ASSERT(proposed_table
->stream_count
-
2104 link
->mst_stream_alloc_table
.stream_count
< 2);
2106 /* copy proposed_table to link, add stream encoder */
2107 for (i
= 0; i
< proposed_table
->stream_count
; i
++) {
2109 for (j
= 0; j
< link
->mst_stream_alloc_table
.stream_count
; j
++) {
2111 &link
->mst_stream_alloc_table
.stream_allocations
[j
];
2113 if (dc_alloc
->vcp_id
==
2114 proposed_table
->stream_allocations
[i
].vcp_id
) {
2116 work_table
[i
] = *dc_alloc
;
2117 break; /* exit j loop */
2122 if (j
== link
->mst_stream_alloc_table
.stream_count
) {
2123 work_table
[i
].vcp_id
=
2124 proposed_table
->stream_allocations
[i
].vcp_id
;
2125 work_table
[i
].slot_count
=
2126 proposed_table
->stream_allocations
[i
].slot_count
;
2127 work_table
[i
].stream_enc
= stream_enc
;
2131 /* update link->mst_stream_alloc_table with work_table */
2132 link
->mst_stream_alloc_table
.stream_count
=
2133 proposed_table
->stream_count
;
2134 for (i
= 0; i
< MAX_CONTROLLER_NUM
; i
++)
2135 link
->mst_stream_alloc_table
.stream_allocations
[i
] =
2139 /* convert link_mst_stream_alloc_table to dm dp_mst_stream_alloc_table
2140 * because stream_encoder is not exposed to dm
2142 static enum dc_status
allocate_mst_payload(struct pipe_ctx
*pipe_ctx
)
2144 struct dc_stream_state
*stream
= pipe_ctx
->stream
;
2145 struct dc_link
*link
= stream
->sink
->link
;
2146 struct link_encoder
*link_encoder
= link
->link_enc
;
2147 struct stream_encoder
*stream_encoder
= pipe_ctx
->stream_res
.stream_enc
;
2148 struct dp_mst_stream_allocation_table proposed_table
= {0};
2149 struct fixed31_32 avg_time_slots_per_mtp
;
2150 struct fixed31_32 pbn
;
2151 struct fixed31_32 pbn_per_slot
;
2154 /* enable_link_dp_mst already check link->enabled_stream_count
2155 * and stream is in link->stream[]. This is called during set mode,
2156 * stream_enc is available.
2159 /* get calculate VC payload for stream: stream_alloc */
2160 if (dm_helpers_dp_mst_write_payload_allocation_table(
2165 update_mst_stream_alloc_table(
2166 link
, pipe_ctx
->stream_res
.stream_enc
, &proposed_table
);
2169 dm_logger_write(link
->ctx
->logger
, LOG_WARNING
,
2171 "MST allocation table for"
2173 pipe_ctx
->pipe_idx
);
2175 dm_logger_write(link
->ctx
->logger
, LOG_MST
,
2177 "stream_count: %d: \n ",
2179 link
->mst_stream_alloc_table
.stream_count
);
2181 for (i
= 0; i
< MAX_CONTROLLER_NUM
; i
++) {
2182 dm_logger_write(link
->ctx
->logger
, LOG_MST
,
2183 "stream_enc[%d]: 0x%x "
2184 "stream[%d].vcp_id: %d "
2185 "stream[%d].slot_count: %d\n",
2187 link
->mst_stream_alloc_table
.stream_allocations
[i
].stream_enc
,
2189 link
->mst_stream_alloc_table
.stream_allocations
[i
].vcp_id
,
2191 link
->mst_stream_alloc_table
.stream_allocations
[i
].slot_count
);
2194 ASSERT(proposed_table
.stream_count
> 0);
2196 /* program DP source TX for payload */
2197 link_encoder
->funcs
->update_mst_stream_allocation_table(
2199 &link
->mst_stream_alloc_table
);
2201 /* send down message */
2202 dm_helpers_dp_mst_poll_for_allocation_change_trigger(
2206 dm_helpers_dp_mst_send_payload_allocation(
2211 /* slot X.Y for only current stream */
2212 pbn_per_slot
= get_pbn_per_slot(stream
);
2213 pbn
= get_pbn_from_timing(pipe_ctx
);
2214 avg_time_slots_per_mtp
= dal_fixed31_32_div(pbn
, pbn_per_slot
);
2216 stream_encoder
->funcs
->set_mst_bandwidth(
2218 avg_time_slots_per_mtp
);
2224 static enum dc_status
deallocate_mst_payload(struct pipe_ctx
*pipe_ctx
)
2226 struct dc_stream_state
*stream
= pipe_ctx
->stream
;
2227 struct dc_link
*link
= stream
->sink
->link
;
2228 struct link_encoder
*link_encoder
= link
->link_enc
;
2229 struct stream_encoder
*stream_encoder
= pipe_ctx
->stream_res
.stream_enc
;
2230 struct dp_mst_stream_allocation_table proposed_table
= {0};
2231 struct fixed31_32 avg_time_slots_per_mtp
= dal_fixed31_32_from_int(0);
2233 bool mst_mode
= (link
->type
== dc_connection_mst_branch
);
2235 /* deallocate_mst_payload is called before disable link. When mode or
2236 * disable/enable monitor, new stream is created which is not in link
2237 * stream[] yet. For this, payload is not allocated yet, so de-alloc
2238 * should not done. For new mode set, map_resources will get engine
2239 * for new stream, so stream_enc->id should be validated until here.
2243 stream_encoder
->funcs
->set_mst_bandwidth(
2245 avg_time_slots_per_mtp
);
2247 /* TODO: which component is responsible for remove payload table? */
2249 if (dm_helpers_dp_mst_write_payload_allocation_table(
2255 update_mst_stream_alloc_table(
2256 link
, pipe_ctx
->stream_res
.stream_enc
, &proposed_table
);
2259 dm_logger_write(link
->ctx
->logger
, LOG_WARNING
,
2261 "MST allocation table for"
2263 pipe_ctx
->pipe_idx
);
2267 dm_logger_write(link
->ctx
->logger
, LOG_MST
,
2269 "stream_count: %d: ",
2271 link
->mst_stream_alloc_table
.stream_count
);
2273 for (i
= 0; i
< MAX_CONTROLLER_NUM
; i
++) {
2274 dm_logger_write(link
->ctx
->logger
, LOG_MST
,
2275 "stream_enc[%d]: 0x%x "
2276 "stream[%d].vcp_id: %d "
2277 "stream[%d].slot_count: %d\n",
2279 link
->mst_stream_alloc_table
.stream_allocations
[i
].stream_enc
,
2281 link
->mst_stream_alloc_table
.stream_allocations
[i
].vcp_id
,
2283 link
->mst_stream_alloc_table
.stream_allocations
[i
].slot_count
);
2286 link_encoder
->funcs
->update_mst_stream_allocation_table(
2288 &link
->mst_stream_alloc_table
);
2291 dm_helpers_dp_mst_poll_for_allocation_change_trigger(
2295 dm_helpers_dp_mst_send_payload_allocation(
2304 void core_link_enable_stream(
2305 struct dc_state
*state
,
2306 struct pipe_ctx
*pipe_ctx
)
2308 struct dc
*core_dc
= pipe_ctx
->stream
->ctx
->dc
;
2310 enum dc_status status
= enable_link(state
, pipe_ctx
);
2312 if (status
!= DC_OK
) {
2313 dm_logger_write(pipe_ctx
->stream
->ctx
->logger
,
2314 LOG_WARNING
, "enabling link %u failed: %d\n",
2315 pipe_ctx
->stream
->sink
->link
->link_index
,
2318 /* Abort stream enable *unless* the failure was due to
2319 * DP link training - some DP monitors will recover and
2320 * show the stream anyway.
2322 if (status
!= DC_FAIL_DP_LINK_TRAINING
) {
2323 BREAK_TO_DEBUGGER();
2328 /* turn off otg test pattern if enable */
2329 pipe_ctx
->stream_res
.tg
->funcs
->set_test_pattern(pipe_ctx
->stream_res
.tg
,
2330 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE
,
2331 COLOR_DEPTH_UNDEFINED
);
2333 core_dc
->hwss
.enable_stream(pipe_ctx
);
2335 if (pipe_ctx
->stream
->signal
== SIGNAL_TYPE_DISPLAY_PORT_MST
)
2336 allocate_mst_payload(pipe_ctx
);
2339 void core_link_disable_stream(struct pipe_ctx
*pipe_ctx
)
2341 struct dc
*core_dc
= pipe_ctx
->stream
->ctx
->dc
;
2343 if (pipe_ctx
->stream
->signal
== SIGNAL_TYPE_DISPLAY_PORT_MST
)
2344 deallocate_mst_payload(pipe_ctx
);
2346 core_dc
->hwss
.disable_stream(pipe_ctx
);
2348 disable_link(pipe_ctx
->stream
->sink
->link
, pipe_ctx
->stream
->signal
);
2351 void core_link_set_avmute(struct pipe_ctx
*pipe_ctx
, bool enable
)
2353 struct dc
*core_dc
= pipe_ctx
->stream
->ctx
->dc
;
2355 if (pipe_ctx
->stream
->signal
!= SIGNAL_TYPE_HDMI_TYPE_A
)
2358 core_dc
->hwss
.set_avmute(pipe_ctx
, enable
);