1 // SPDX-License-Identifier: MIT
3 * Copyright (C) 2013-2019 NVIDIA Corporation
4 * Copyright (C) 2015 Rob Clark
7 #include <drm/drm_crtc.h>
8 #include <drm/drm_dp_helper.h>
9 #include <drm/drm_print.h>
13 static const u8 drm_dp_edp_revisions
[] = { 0x11, 0x12, 0x13, 0x14 };
15 static void drm_dp_link_caps_reset(struct drm_dp_link_caps
*caps
)
17 caps
->enhanced_framing
= false;
18 caps
->tps3_supported
= false;
19 caps
->fast_training
= false;
20 caps
->channel_coding
= false;
21 caps
->alternate_scrambler_reset
= false;
24 void drm_dp_link_caps_copy(struct drm_dp_link_caps
*dest
,
25 const struct drm_dp_link_caps
*src
)
27 dest
->enhanced_framing
= src
->enhanced_framing
;
28 dest
->tps3_supported
= src
->tps3_supported
;
29 dest
->fast_training
= src
->fast_training
;
30 dest
->channel_coding
= src
->channel_coding
;
31 dest
->alternate_scrambler_reset
= src
->alternate_scrambler_reset
;
34 static void drm_dp_link_reset(struct drm_dp_link
*link
)
45 drm_dp_link_caps_reset(&link
->caps
);
46 link
->aux_rd_interval
.cr
= 0;
47 link
->aux_rd_interval
.ce
= 0;
53 for (i
= 0; i
< DP_MAX_SUPPORTED_RATES
; i
++)
60 * drm_dp_link_add_rate() - add a rate to the list of supported rates
61 * @link: the link to add the rate to
62 * @rate: the rate to add
64 * Add a link rate to the list of supported link rates.
67 * 0 on success or one of the following negative error codes on failure:
68 * - ENOSPC if the maximum number of supported rates has been reached
69 * - EEXISTS if the link already supports this rate
72 * drm_dp_link_remove_rate()
74 int drm_dp_link_add_rate(struct drm_dp_link
*link
, unsigned long rate
)
76 unsigned int i
, pivot
;
78 if (link
->num_rates
== DP_MAX_SUPPORTED_RATES
)
81 for (pivot
= 0; pivot
< link
->num_rates
; pivot
++)
82 if (rate
<= link
->rates
[pivot
])
85 if (pivot
!= link
->num_rates
&& rate
== link
->rates
[pivot
])
88 for (i
= link
->num_rates
; i
> pivot
; i
--)
89 link
->rates
[i
] = link
->rates
[i
- 1];
91 link
->rates
[pivot
] = rate
;
98 * drm_dp_link_remove_rate() - remove a rate from the list of supported rates
99 * @link: the link from which to remove the rate
100 * @rate: the rate to remove
102 * Removes a link rate from the list of supported link rates.
105 * 0 on success or one of the following negative error codes on failure:
106 * - EINVAL if the specified rate is not among the supported rates
109 * drm_dp_link_add_rate()
111 int drm_dp_link_remove_rate(struct drm_dp_link
*link
, unsigned long rate
)
115 for (i
= 0; i
< link
->num_rates
; i
++)
116 if (rate
== link
->rates
[i
])
119 if (i
== link
->num_rates
)
124 while (i
< link
->num_rates
) {
125 link
->rates
[i
] = link
->rates
[i
+ 1];
133 * drm_dp_link_update_rates() - normalize the supported link rates array
134 * @link: the link for which to normalize the supported link rates
136 * Users should call this function after they've manually modified the array
137 * of supported link rates. This function removes any stale entries, compacts
138 * the array and updates the supported link rate count. Note that calling the
139 * drm_dp_link_remove_rate() function already does this janitorial work.
142 * drm_dp_link_add_rate(), drm_dp_link_remove_rate()
144 void drm_dp_link_update_rates(struct drm_dp_link
*link
)
146 unsigned int i
, count
= 0;
148 for (i
= 0; i
< link
->num_rates
; i
++) {
149 if (link
->rates
[i
] != 0)
150 link
->rates
[count
++] = link
->rates
[i
];
153 for (i
= count
; i
< link
->num_rates
; i
++)
156 link
->num_rates
= count
;
160 * drm_dp_link_probe() - probe a DisplayPort link for capabilities
161 * @aux: DisplayPort AUX channel
162 * @link: pointer to structure in which to return link capabilities
164 * The structure filled in by this function can usually be passed directly
165 * into drm_dp_link_power_up() and drm_dp_link_configure() to power up and
166 * configure the link based on the link's capabilities.
168 * Returns 0 on success or a negative error code on failure.
170 int drm_dp_link_probe(struct drm_dp_aux
*aux
, struct drm_dp_link
*link
)
172 u8 dpcd
[DP_RECEIVER_CAP_SIZE
], value
;
173 unsigned int rd_interval
;
176 drm_dp_link_reset(link
);
178 err
= drm_dp_dpcd_read(aux
, DP_DPCD_REV
, dpcd
, sizeof(dpcd
));
182 link
->revision
= dpcd
[DP_DPCD_REV
];
183 link
->max_rate
= drm_dp_max_link_rate(dpcd
);
184 link
->max_lanes
= drm_dp_max_lane_count(dpcd
);
186 link
->caps
.enhanced_framing
= drm_dp_enhanced_frame_cap(dpcd
);
187 link
->caps
.tps3_supported
= drm_dp_tps3_supported(dpcd
);
188 link
->caps
.fast_training
= drm_dp_fast_training_cap(dpcd
);
189 link
->caps
.channel_coding
= drm_dp_channel_coding_supported(dpcd
);
191 if (drm_dp_alternate_scrambler_reset_cap(dpcd
)) {
192 link
->caps
.alternate_scrambler_reset
= true;
194 err
= drm_dp_dpcd_readb(aux
, DP_EDP_DPCD_REV
, &value
);
198 if (value
>= ARRAY_SIZE(drm_dp_edp_revisions
))
199 DRM_ERROR("unsupported eDP version: %02x\n", value
);
201 link
->edp
= drm_dp_edp_revisions
[value
];
205 * The DPCD stores the AUX read interval in units of 4 ms. There are
208 * 1) if the TRAINING_AUX_RD_INTERVAL field is 0, the clock recovery
209 * and channel equalization should use 100 us or 400 us AUX read
210 * intervals, respectively
212 * 2) for DP v1.4 and above, clock recovery should always use 100 us
215 rd_interval
= dpcd
[DP_TRAINING_AUX_RD_INTERVAL
] &
216 DP_TRAINING_AUX_RD_MASK
;
218 if (rd_interval
> 4) {
219 DRM_DEBUG_KMS("AUX interval %u out of range (max. 4)\n",
224 rd_interval
*= 4 * USEC_PER_MSEC
;
226 if (rd_interval
== 0 || link
->revision
>= DP_DPCD_REV_14
)
227 link
->aux_rd_interval
.cr
= 100;
229 if (rd_interval
== 0)
230 link
->aux_rd_interval
.ce
= 400;
232 link
->rate
= link
->max_rate
;
233 link
->lanes
= link
->max_lanes
;
235 /* Parse SUPPORTED_LINK_RATES from eDP 1.4 */
236 if (link
->edp
>= 0x14) {
237 u8 supported_rates
[DP_MAX_SUPPORTED_RATES
* 2];
241 err
= drm_dp_dpcd_read(aux
, DP_SUPPORTED_LINK_RATES
,
243 sizeof(supported_rates
));
247 for (i
= 0; i
< DP_MAX_SUPPORTED_RATES
; i
++) {
248 rate
= supported_rates
[i
* 2 + 1] << 8 |
249 supported_rates
[i
* 2 + 0];
251 drm_dp_link_add_rate(link
, rate
* 200);
259 * drm_dp_link_power_up() - power up a DisplayPort link
260 * @aux: DisplayPort AUX channel
261 * @link: pointer to a structure containing the link configuration
263 * Returns 0 on success or a negative error code on failure.
265 int drm_dp_link_power_up(struct drm_dp_aux
*aux
, struct drm_dp_link
*link
)
270 /* DP_SET_POWER register is only available on DPCD v1.1 and later */
271 if (link
->revision
< 0x11)
274 err
= drm_dp_dpcd_readb(aux
, DP_SET_POWER
, &value
);
278 value
&= ~DP_SET_POWER_MASK
;
279 value
|= DP_SET_POWER_D0
;
281 err
= drm_dp_dpcd_writeb(aux
, DP_SET_POWER
, value
);
286 * According to the DP 1.1 specification, a "Sink Device must exit the
287 * power saving state within 1 ms" (Section 2.5.3.1, Table 5-52, "Sink
288 * Control Field" (register 0x600).
290 usleep_range(1000, 2000);
296 * drm_dp_link_power_down() - power down a DisplayPort link
297 * @aux: DisplayPort AUX channel
298 * @link: pointer to a structure containing the link configuration
300 * Returns 0 on success or a negative error code on failure.
302 int drm_dp_link_power_down(struct drm_dp_aux
*aux
, struct drm_dp_link
*link
)
307 /* DP_SET_POWER register is only available on DPCD v1.1 and later */
308 if (link
->revision
< 0x11)
311 err
= drm_dp_dpcd_readb(aux
, DP_SET_POWER
, &value
);
315 value
&= ~DP_SET_POWER_MASK
;
316 value
|= DP_SET_POWER_D3
;
318 err
= drm_dp_dpcd_writeb(aux
, DP_SET_POWER
, value
);
326 * drm_dp_link_configure() - configure a DisplayPort link
327 * @aux: DisplayPort AUX channel
328 * @link: pointer to a structure containing the link configuration
330 * Returns 0 on success or a negative error code on failure.
332 int drm_dp_link_configure(struct drm_dp_aux
*aux
, struct drm_dp_link
*link
)
337 if (link
->ops
&& link
->ops
->configure
) {
338 err
= link
->ops
->configure(link
);
340 DRM_ERROR("failed to configure DP link: %d\n", err
);
345 values
[0] = drm_dp_link_rate_to_bw_code(link
->rate
);
346 values
[1] = link
->lanes
;
348 if (link
->caps
.enhanced_framing
)
349 values
[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN
;
351 err
= drm_dp_dpcd_write(aux
, DP_LINK_BW_SET
, values
, sizeof(values
));
355 if (link
->caps
.channel_coding
)
356 value
= DP_SET_ANSI_8B10B
;
360 err
= drm_dp_dpcd_writeb(aux
, DP_MAIN_LINK_CHANNEL_CODING_SET
, value
);
364 if (link
->caps
.alternate_scrambler_reset
) {
365 err
= drm_dp_dpcd_writeb(aux
, DP_EDP_CONFIGURATION_SET
,
366 DP_ALTERNATE_SCRAMBLER_RESET_ENABLE
);
375 * drm_dp_link_choose() - choose the lowest possible configuration for a mode
376 * @link: DRM DP link object
377 * @mode: DRM display mode
378 * @info: DRM display information
380 * According to the eDP specification, a source should select a configuration
381 * with the lowest number of lanes and the lowest possible link rate that can
382 * match the bitrate requirements of a video mode. However it must ensure not
383 * to exceed the capabilities of the sink.
385 * Returns: 0 on success or a negative error code on failure.
387 int drm_dp_link_choose(struct drm_dp_link
*link
,
388 const struct drm_display_mode
*mode
,
389 const struct drm_display_info
*info
)
391 /* available link symbol clock rates */
392 static const unsigned int rates
[3] = { 162000, 270000, 540000 };
393 /* available number of lanes */
394 static const unsigned int lanes
[3] = { 1, 2, 4 };
395 unsigned long requirement
, capacity
;
396 unsigned int rate
= link
->max_rate
;
399 /* bandwidth requirement */
400 requirement
= mode
->clock
* info
->bpc
* 3;
402 for (i
= 0; i
< ARRAY_SIZE(lanes
) && lanes
[i
] <= link
->max_lanes
; i
++) {
403 for (j
= 0; j
< ARRAY_SIZE(rates
) && rates
[j
] <= rate
; j
++) {
405 * Capacity for this combination of lanes and rate,
406 * factoring in the ANSI 8B/10B encoding.
408 * Link rates in the DRM DP helpers are really link
409 * symbol frequencies, so a tenth of the actual rate
412 capacity
= lanes
[i
] * (rates
[j
] * 10) * 8 / 10;
414 if (capacity
>= requirement
) {
415 DRM_DEBUG_KMS("using %u lanes at %u kHz (%lu/%lu kbps)\n",
416 lanes
[i
], rates
[j
], requirement
,
418 link
->lanes
= lanes
[i
];
419 link
->rate
= rates
[j
];
431 * These functions contain common logic and helpers to implement DisplayPort
436 * drm_dp_link_train_init() - initialize DisplayPort link training state
437 * @train: DisplayPort link training state
439 void drm_dp_link_train_init(struct drm_dp_link_train
*train
)
441 struct drm_dp_link_train_set
*request
= &train
->request
;
442 struct drm_dp_link_train_set
*adjust
= &train
->adjust
;
445 for (i
= 0; i
< 4; i
++) {
446 request
->voltage_swing
[i
] = 0;
447 adjust
->voltage_swing
[i
] = 0;
449 request
->pre_emphasis
[i
] = 0;
450 adjust
->pre_emphasis
[i
] = 0;
452 request
->post_cursor
[i
] = 0;
453 adjust
->post_cursor
[i
] = 0;
456 train
->pattern
= DP_TRAINING_PATTERN_DISABLE
;
457 train
->clock_recovered
= false;
458 train
->channel_equalized
= false;
461 static bool drm_dp_link_train_valid(const struct drm_dp_link_train
*train
)
463 return train
->clock_recovered
&& train
->channel_equalized
;
466 static int drm_dp_link_apply_training(struct drm_dp_link
*link
)
468 struct drm_dp_link_train_set
*request
= &link
->train
.request
;
469 unsigned int lanes
= link
->lanes
, *vs
, *pe
, *pc
, i
;
470 struct drm_dp_aux
*aux
= link
->aux
;
471 u8 values
[4], pattern
= 0;
474 err
= link
->ops
->apply_training(link
);
476 DRM_ERROR("failed to apply link training: %d\n", err
);
480 vs
= request
->voltage_swing
;
481 pe
= request
->pre_emphasis
;
482 pc
= request
->post_cursor
;
484 /* write currently selected voltage-swing and pre-emphasis levels */
485 for (i
= 0; i
< lanes
; i
++)
486 values
[i
] = DP_TRAIN_VOLTAGE_SWING_LEVEL(vs
[i
]) |
487 DP_TRAIN_PRE_EMPHASIS_LEVEL(pe
[i
]);
489 err
= drm_dp_dpcd_write(aux
, DP_TRAINING_LANE0_SET
, values
, lanes
);
491 DRM_ERROR("failed to set training parameters: %d\n", err
);
495 /* write currently selected post-cursor level (if supported) */
496 if (link
->revision
>= 0x12 && link
->rate
== 540000) {
497 values
[0] = values
[1] = 0;
499 for (i
= 0; i
< lanes
; i
++)
500 values
[i
/ 2] |= DP_LANE_POST_CURSOR(i
, pc
[i
]);
502 err
= drm_dp_dpcd_write(aux
, DP_TRAINING_LANE0_1_SET2
, values
,
503 DIV_ROUND_UP(lanes
, 2));
505 DRM_ERROR("failed to set post-cursor: %d\n", err
);
510 /* write link pattern */
511 if (link
->train
.pattern
!= DP_TRAINING_PATTERN_DISABLE
)
512 pattern
|= DP_LINK_SCRAMBLING_DISABLE
;
514 pattern
|= link
->train
.pattern
;
516 err
= drm_dp_dpcd_writeb(aux
, DP_TRAINING_PATTERN_SET
, pattern
);
518 DRM_ERROR("failed to set training pattern: %d\n", err
);
525 static void drm_dp_link_train_wait(struct drm_dp_link
*link
)
527 unsigned long min
= 0;
529 switch (link
->train
.pattern
) {
530 case DP_TRAINING_PATTERN_1
:
531 min
= link
->aux_rd_interval
.cr
;
534 case DP_TRAINING_PATTERN_2
:
535 case DP_TRAINING_PATTERN_3
:
536 min
= link
->aux_rd_interval
.ce
;
544 usleep_range(min
, 2 * min
);
547 static void drm_dp_link_get_adjustments(struct drm_dp_link
*link
,
548 u8 status
[DP_LINK_STATUS_SIZE
])
550 struct drm_dp_link_train_set
*adjust
= &link
->train
.adjust
;
553 for (i
= 0; i
< link
->lanes
; i
++) {
554 adjust
->voltage_swing
[i
] =
555 drm_dp_get_adjust_request_voltage(status
, i
) >>
556 DP_TRAIN_VOLTAGE_SWING_SHIFT
;
558 adjust
->pre_emphasis
[i
] =
559 drm_dp_get_adjust_request_pre_emphasis(status
, i
) >>
560 DP_TRAIN_PRE_EMPHASIS_SHIFT
;
562 adjust
->post_cursor
[i
] =
563 drm_dp_get_adjust_request_post_cursor(status
, i
);
567 static void drm_dp_link_train_adjust(struct drm_dp_link_train
*train
)
569 struct drm_dp_link_train_set
*request
= &train
->request
;
570 struct drm_dp_link_train_set
*adjust
= &train
->adjust
;
573 for (i
= 0; i
< 4; i
++)
574 if (request
->voltage_swing
[i
] != adjust
->voltage_swing
[i
])
575 request
->voltage_swing
[i
] = adjust
->voltage_swing
[i
];
577 for (i
= 0; i
< 4; i
++)
578 if (request
->pre_emphasis
[i
] != adjust
->pre_emphasis
[i
])
579 request
->pre_emphasis
[i
] = adjust
->pre_emphasis
[i
];
581 for (i
= 0; i
< 4; i
++)
582 if (request
->post_cursor
[i
] != adjust
->post_cursor
[i
])
583 request
->post_cursor
[i
] = adjust
->post_cursor
[i
];
586 static int drm_dp_link_recover_clock(struct drm_dp_link
*link
)
588 u8 status
[DP_LINK_STATUS_SIZE
];
591 err
= drm_dp_link_apply_training(link
);
595 drm_dp_link_train_wait(link
);
597 err
= drm_dp_dpcd_read_link_status(link
->aux
, status
);
599 DRM_ERROR("failed to read link status: %d\n", err
);
603 if (!drm_dp_clock_recovery_ok(status
, link
->lanes
))
604 drm_dp_link_get_adjustments(link
, status
);
606 link
->train
.clock_recovered
= true;
611 static int drm_dp_link_clock_recovery(struct drm_dp_link
*link
)
616 /* start clock recovery using training pattern 1 */
617 link
->train
.pattern
= DP_TRAINING_PATTERN_1
;
619 for (repeat
= 1; repeat
< 5; repeat
++) {
620 err
= drm_dp_link_recover_clock(link
);
622 DRM_ERROR("failed to recover clock: %d\n", err
);
626 if (link
->train
.clock_recovered
)
629 drm_dp_link_train_adjust(&link
->train
);
635 static int drm_dp_link_equalize_channel(struct drm_dp_link
*link
)
637 struct drm_dp_aux
*aux
= link
->aux
;
638 u8 status
[DP_LINK_STATUS_SIZE
];
641 err
= drm_dp_link_apply_training(link
);
645 drm_dp_link_train_wait(link
);
647 err
= drm_dp_dpcd_read_link_status(aux
, status
);
649 DRM_ERROR("failed to read link status: %d\n", err
);
653 if (!drm_dp_clock_recovery_ok(status
, link
->lanes
)) {
654 DRM_ERROR("clock recovery lost while equalizing channel\n");
655 link
->train
.clock_recovered
= false;
659 if (!drm_dp_channel_eq_ok(status
, link
->lanes
))
660 drm_dp_link_get_adjustments(link
, status
);
662 link
->train
.channel_equalized
= true;
667 static int drm_dp_link_channel_equalization(struct drm_dp_link
*link
)
672 /* start channel equalization using pattern 2 or 3 */
673 if (link
->caps
.tps3_supported
)
674 link
->train
.pattern
= DP_TRAINING_PATTERN_3
;
676 link
->train
.pattern
= DP_TRAINING_PATTERN_2
;
678 for (repeat
= 1; repeat
< 5; repeat
++) {
679 err
= drm_dp_link_equalize_channel(link
);
681 DRM_ERROR("failed to equalize channel: %d\n", err
);
685 if (link
->train
.channel_equalized
)
688 drm_dp_link_train_adjust(&link
->train
);
694 static int drm_dp_link_downgrade(struct drm_dp_link
*link
)
696 switch (link
->rate
) {
712 static void drm_dp_link_train_disable(struct drm_dp_link
*link
)
716 link
->train
.pattern
= DP_TRAINING_PATTERN_DISABLE
;
718 err
= drm_dp_link_apply_training(link
);
720 DRM_ERROR("failed to disable link training: %d\n", err
);
723 static int drm_dp_link_train_full(struct drm_dp_link
*link
)
728 DRM_DEBUG_KMS("full-training link: %u lane%s at %u MHz\n",
729 link
->lanes
, (link
->lanes
> 1) ? "s" : "",
732 err
= drm_dp_link_configure(link
->aux
, link
);
734 DRM_ERROR("failed to configure DP link: %d\n", err
);
738 err
= drm_dp_link_clock_recovery(link
);
740 DRM_ERROR("clock recovery failed: %d\n", err
);
744 if (!link
->train
.clock_recovered
) {
745 DRM_ERROR("clock recovery failed, downgrading link\n");
747 err
= drm_dp_link_downgrade(link
);
754 DRM_DEBUG_KMS("clock recovery succeeded\n");
756 err
= drm_dp_link_channel_equalization(link
);
758 DRM_ERROR("channel equalization failed: %d\n", err
);
762 if (!link
->train
.channel_equalized
) {
763 DRM_ERROR("channel equalization failed, downgrading link\n");
765 err
= drm_dp_link_downgrade(link
);
772 DRM_DEBUG_KMS("channel equalization succeeded\n");
775 drm_dp_link_train_disable(link
);
779 static int drm_dp_link_train_fast(struct drm_dp_link
*link
)
781 u8 status
[DP_LINK_STATUS_SIZE
];
784 DRM_DEBUG_KMS("fast-training link: %u lane%s at %u MHz\n",
785 link
->lanes
, (link
->lanes
> 1) ? "s" : "",
788 err
= drm_dp_link_configure(link
->aux
, link
);
790 DRM_ERROR("failed to configure DP link: %d\n", err
);
794 /* transmit training pattern 1 for 500 microseconds */
795 link
->train
.pattern
= DP_TRAINING_PATTERN_1
;
797 err
= drm_dp_link_apply_training(link
);
801 usleep_range(500, 1000);
803 /* transmit training pattern 2 or 3 for 500 microseconds */
804 if (link
->caps
.tps3_supported
)
805 link
->train
.pattern
= DP_TRAINING_PATTERN_3
;
807 link
->train
.pattern
= DP_TRAINING_PATTERN_2
;
809 err
= drm_dp_link_apply_training(link
);
813 usleep_range(500, 1000);
815 err
= drm_dp_dpcd_read_link_status(link
->aux
, status
);
817 DRM_ERROR("failed to read link status: %d\n", err
);
821 if (!drm_dp_clock_recovery_ok(status
, link
->lanes
)) {
822 DRM_ERROR("clock recovery failed\n");
826 if (!drm_dp_channel_eq_ok(status
, link
->lanes
)) {
827 DRM_ERROR("channel equalization failed\n");
832 drm_dp_link_train_disable(link
);
837 * drm_dp_link_train() - perform DisplayPort link training
838 * @link: a DP link object
840 * Uses the context stored in the DP link object to perform link training. It
841 * is expected that drivers will call drm_dp_link_probe() to obtain the link
842 * capabilities before performing link training.
844 * If the sink supports fast link training (no AUX CH handshake) and valid
845 * training settings are available, this function will try to perform fast
846 * link training and fall back to full link training on failure.
848 * Returns: 0 on success or a negative error code on failure.
850 int drm_dp_link_train(struct drm_dp_link
*link
)
854 drm_dp_link_train_init(&link
->train
);
856 if (link
->caps
.fast_training
) {
857 if (drm_dp_link_train_valid(&link
->train
)) {
858 err
= drm_dp_link_train_fast(link
);
860 DRM_ERROR("fast link training failed: %d\n",
865 DRM_DEBUG_KMS("training parameters not available\n");
868 DRM_DEBUG_KMS("fast link training not supported\n");
871 err
= drm_dp_link_train_full(link
);
873 DRM_ERROR("full link training failed: %d\n", err
);