Lines Matching refs:link
34 static void drm_dp_link_reset(struct drm_dp_link *link)
38 if (!link)
41 link->revision = 0;
42 link->max_rate = 0;
43 link->max_lanes = 0;
45 drm_dp_link_caps_reset(&link->caps);
46 link->aux_rd_interval.cr = 0;
47 link->aux_rd_interval.ce = 0;
48 link->edp = 0;
50 link->rate = 0;
51 link->lanes = 0;
54 link->rates[i] = 0;
56 link->num_rates = 0;
61 * @link: the link to add the rate to
64 * Add a link rate to the list of supported link rates.
69 * - EEXISTS if the link already supports this rate
74 int drm_dp_link_add_rate(struct drm_dp_link *link, unsigned long rate)
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;
92 link->num_rates++;
99 * @link: the link from which to remove the rate
102 * Removes a link rate from the list of supported link rates.
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)
122 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
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
144 void drm_dp_link_update_rates(struct drm_dp_link *link)
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++)
154 link->rates[i] = 0;
156 link->num_rates = count;
160 * drm_dp_link_probe() - probe a DisplayPort link for capabilities
162 * @link: pointer to structure in which to return link capabilities
166 * configure the link based on the link's capabilities.
170 int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
176 drm_dp_link_reset(link);
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);
192 link->caps.alternate_scrambler_reset = true;
201 link->edp = drm_dp_edp_revisions[value];
226 if (rd_interval == 0 || link->revision >= DP_DPCD_REV_14)
227 link->aux_rd_interval.cr = 100;
230 link->aux_rd_interval.ce = 400;
232 link->rate = link->max_rate;
233 link->lanes = link->max_lanes;
236 if (link->edp >= 0x14) {
251 drm_dp_link_add_rate(link, rate * 200);
259 * drm_dp_link_power_up() - power up a DisplayPort link
261 * @link: pointer to a structure containing the link configuration
265 int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link)
271 if (link->revision < 0x11)
296 * drm_dp_link_power_down() - power down a DisplayPort link
298 * @link: pointer to a structure containing the link configuration
302 int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link)
308 if (link->revision < 0x11)
326 * drm_dp_link_configure() - configure a DisplayPort link
328 * @link: pointer to a structure containing the link configuration
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)
355 if (link->caps.channel_coding)
364 if (link->caps.alternate_scrambler_reset) {
376 * @link: DRM DP link object
381 * with the lowest number of lanes and the lowest possible link rate that can
387 int drm_dp_link_choose(struct drm_dp_link *link,
391 /* available link symbol clock rates */
396 unsigned int rate = link->max_rate;
402 for (i = 0; i < ARRAY_SIZE(lanes) && lanes[i] <= link->max_lanes; i++) {
408 * Link rates in the DRM DP helpers are really link
410 * of the link.
418 link->lanes = lanes[i];
419 link->rate = rates[j];
432 * link training.
436 * drm_dp_link_train_init() - initialize DisplayPort link training state
437 * @train: DisplayPort link training state
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;
474 err = link->ops->apply_training(link);
476 DRM_ERROR("failed to apply link training: %d\n", err);
496 if (link->revision >= 0x12 && link->rate == 540000) {
510 /* write link pattern */
511 if (link->train.pattern != DP_TRAINING_PATTERN_DISABLE)
514 pattern |= link->train.pattern;
525 static void drm_dp_link_train_wait(struct drm_dp_link *link)
529 switch (link->train.pattern) {
531 min = link->aux_rd_interval.cr;
536 min = link->aux_rd_interval.ce;
547 static void drm_dp_link_get_adjustments(struct drm_dp_link *link,
550 struct drm_dp_link_train_set *adjust = &link->train.adjust;
553 for (i = 0; i < link->lanes; i++) {
586 static int drm_dp_link_recover_clock(struct drm_dp_link *link)
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)
617 link->train.pattern = DP_TRAINING_PATTERN_1;
620 err = drm_dp_link_recover_clock(link);
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;
641 err = drm_dp_link_apply_training(link);
645 drm_dp_link_train_wait(link);
649 DRM_ERROR("failed to read link status: %d\n", err);
653 if (!drm_dp_clock_recovery_ok(status, link->lanes)) {
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)
673 if (link->caps.tps3_supported)
674 link->train.pattern = DP_TRAINING_PATTERN_3;
676 link->train.pattern = DP_TRAINING_PATTERN_2;
679 err = drm_dp_link_equalize_channel(link);
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) {
701 link->rate = 162000;
705 link->rate = 270000;
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" : "",
730 link->rate / 100);
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);
744 if (!link->train.clock_recovered) {
745 DRM_ERROR("clock recovery failed, downgrading link\n");
747 err = drm_dp_link_downgrade(link);
756 err = drm_dp_link_channel_equalization(link);
762 if (!link->train.channel_equalized) {
763 DRM_ERROR("channel equalization failed, downgrading link\n");
765 err = drm_dp_link_downgrade(link);
775 drm_dp_link_train_disable(link);
779 static int drm_dp_link_train_fast(struct drm_dp_link *link)
784 DRM_DEBUG_KMS("fast-training link: %u lane%s at %u MHz\n",
785 link->lanes, (link->lanes > 1) ? "s" : "",
786 link->rate / 100);
788 err = drm_dp_link_configure(link->aux, link);
790 DRM_ERROR("failed to configure DP link: %d\n", err);
795 link->train.pattern = DP_TRAINING_PATTERN_1;
797 err = drm_dp_link_apply_training(link);
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);
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)) {
826 if (!drm_dp_channel_eq_ok(status, link->lanes)) {
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
846 * link training and fall back to full link training 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",
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);