Lines Matching +full:d +full:- +full:link
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
6 #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__
49 struct dp_link_info *link) in dp_aux_link_power_up() argument
55 if (link->revision < 0x11) in dp_aux_link_power_up()
77 struct dp_link_info *link) in dp_aux_link_power_down() argument
82 if (link->revision < 0x11) in dp_aux_link_power_down()
99 static int dp_link_get_period(struct dp_link_private *link, int const addr) in dp_link_get_period() argument
106 if (drm_dp_dpcd_readb(link->aux, addr, &data) < 0) { in dp_link_get_period()
108 ret = -EINVAL; in dp_link_get_period()
112 /* Period - Bits 3:0 */ in dp_link_get_period()
116 ret = -EINVAL; in dp_link_get_period()
125 static int dp_link_parse_audio_channel_period(struct dp_link_private *link) in dp_link_parse_audio_channel_period() argument
128 struct dp_link_test_audio *req = &link->dp_link.test_audio; in dp_link_parse_audio_channel_period()
130 ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH1); in dp_link_parse_audio_channel_period()
131 if (ret == -EINVAL) in dp_link_parse_audio_channel_period()
134 req->test_audio_period_ch_1 = ret; in dp_link_parse_audio_channel_period()
135 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_1 = 0x%x\n", ret); in dp_link_parse_audio_channel_period()
137 ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH2); in dp_link_parse_audio_channel_period()
138 if (ret == -EINVAL) in dp_link_parse_audio_channel_period()
141 req->test_audio_period_ch_2 = ret; in dp_link_parse_audio_channel_period()
142 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_2 = 0x%x\n", ret); in dp_link_parse_audio_channel_period()
145 ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH3); in dp_link_parse_audio_channel_period()
146 if (ret == -EINVAL) in dp_link_parse_audio_channel_period()
149 req->test_audio_period_ch_3 = ret; in dp_link_parse_audio_channel_period()
150 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_3 = 0x%x\n", ret); in dp_link_parse_audio_channel_period()
152 ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH4); in dp_link_parse_audio_channel_period()
153 if (ret == -EINVAL) in dp_link_parse_audio_channel_period()
156 req->test_audio_period_ch_4 = ret; in dp_link_parse_audio_channel_period()
157 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_4 = 0x%x\n", ret); in dp_link_parse_audio_channel_period()
159 ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH5); in dp_link_parse_audio_channel_period()
160 if (ret == -EINVAL) in dp_link_parse_audio_channel_period()
163 req->test_audio_period_ch_5 = ret; in dp_link_parse_audio_channel_period()
164 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_5 = 0x%x\n", ret); in dp_link_parse_audio_channel_period()
166 ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH6); in dp_link_parse_audio_channel_period()
167 if (ret == -EINVAL) in dp_link_parse_audio_channel_period()
170 req->test_audio_period_ch_6 = ret; in dp_link_parse_audio_channel_period()
171 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_6 = 0x%x\n", ret); in dp_link_parse_audio_channel_period()
173 ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH7); in dp_link_parse_audio_channel_period()
174 if (ret == -EINVAL) in dp_link_parse_audio_channel_period()
177 req->test_audio_period_ch_7 = ret; in dp_link_parse_audio_channel_period()
178 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_7 = 0x%x\n", ret); in dp_link_parse_audio_channel_period()
180 ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH8); in dp_link_parse_audio_channel_period()
181 if (ret == -EINVAL) in dp_link_parse_audio_channel_period()
184 req->test_audio_period_ch_8 = ret; in dp_link_parse_audio_channel_period()
185 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_8 = 0x%x\n", ret); in dp_link_parse_audio_channel_period()
190 static int dp_link_parse_audio_pattern_type(struct dp_link_private *link) in dp_link_parse_audio_pattern_type() argument
197 rlen = drm_dp_dpcd_readb(link->aux, in dp_link_parse_audio_pattern_type()
200 DRM_ERROR("failed to read link audio mode. rlen=%zd\n", rlen); in dp_link_parse_audio_pattern_type()
204 /* Audio Pattern Type - Bits 7:0 */ in dp_link_parse_audio_pattern_type()
207 ret = -EINVAL; in dp_link_parse_audio_pattern_type()
211 link->dp_link.test_audio.test_audio_pattern_type = data; in dp_link_parse_audio_pattern_type()
212 drm_dbg_dp(link->drm_dev, "audio pattern type = 0x%x\n", data); in dp_link_parse_audio_pattern_type()
217 static int dp_link_parse_audio_mode(struct dp_link_private *link) in dp_link_parse_audio_mode() argument
227 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_AUDIO_MODE, &data); in dp_link_parse_audio_mode()
229 DRM_ERROR("failed to read link audio mode. rlen=%zd\n", rlen); in dp_link_parse_audio_mode()
233 /* Sampling Rate - Bits 3:0 */ in dp_link_parse_audio_mode()
238 ret = -EINVAL; in dp_link_parse_audio_mode()
242 /* Channel Count - Bits 7:4 */ in dp_link_parse_audio_mode()
247 ret = -EINVAL; in dp_link_parse_audio_mode()
251 link->dp_link.test_audio.test_audio_sampling_rate = sampling_rate; in dp_link_parse_audio_mode()
252 link->dp_link.test_audio.test_audio_channel_count = channel_count; in dp_link_parse_audio_mode()
253 drm_dbg_dp(link->drm_dev, in dp_link_parse_audio_mode()
260 static int dp_link_parse_audio_pattern_params(struct dp_link_private *link) in dp_link_parse_audio_pattern_params() argument
264 ret = dp_link_parse_audio_mode(link); in dp_link_parse_audio_pattern_params()
268 ret = dp_link_parse_audio_pattern_type(link); in dp_link_parse_audio_pattern_params()
272 ret = dp_link_parse_audio_channel_period(link); in dp_link_parse_audio_pattern_params()
292 * dp_link_is_bit_depth_valid() - validates the bit depth requested
310 static int dp_link_parse_timing_params1(struct dp_link_private *link, in dp_link_parse_timing_params1() argument
317 return -EINVAL; in dp_link_parse_timing_params1()
319 /* Read the requested video link pattern (Byte 0x221). */ in dp_link_parse_timing_params1()
320 rlen = drm_dp_dpcd_read(link->aux, addr, bp, len); in dp_link_parse_timing_params1()
323 return -EINVAL; in dp_link_parse_timing_params1()
331 static int dp_link_parse_timing_params2(struct dp_link_private *link, in dp_link_parse_timing_params2() argument
339 return -EINVAL; in dp_link_parse_timing_params2()
341 /* Read the requested video link pattern (Byte 0x221). */ in dp_link_parse_timing_params2()
342 rlen = drm_dp_dpcd_read(link->aux, addr, bp, len); in dp_link_parse_timing_params2()
345 return -EINVAL; in dp_link_parse_timing_params2()
354 static int dp_link_parse_timing_params3(struct dp_link_private *link, in dp_link_parse_timing_params3() argument
361 rlen = drm_dp_dpcd_read(link->aux, addr, &bp, len); in dp_link_parse_timing_params3()
364 return -EINVAL; in dp_link_parse_timing_params3()
372 * dp_link_parse_video_pattern_params() - parses video pattern parameters from DPCD
373 * @link: Display Port Driver data
375 * Returns 0 if it successfully parses the video link pattern and the link
378 static int dp_link_parse_video_pattern_params(struct dp_link_private *link) in dp_link_parse_video_pattern_params() argument
384 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_PATTERN, &bp); in dp_link_parse_video_pattern_params()
386 DRM_ERROR("failed to read link video pattern. rlen=%zd\n", in dp_link_parse_video_pattern_params()
392 DRM_ERROR("invalid link video pattern = 0x%x\n", bp); in dp_link_parse_video_pattern_params()
393 ret = -EINVAL; in dp_link_parse_video_pattern_params()
397 link->dp_link.test_video.test_video_pattern = bp; in dp_link_parse_video_pattern_params()
400 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_MISC0, &bp); in dp_link_parse_video_pattern_params()
402 DRM_ERROR("failed to read link bit depth. rlen=%zd\n", rlen); in dp_link_parse_video_pattern_params()
407 link->dp_link.test_video.test_dyn_range = in dp_link_parse_video_pattern_params()
413 DRM_ERROR("invalid link bit depth = 0x%x\n", bp); in dp_link_parse_video_pattern_params()
414 ret = -EINVAL; in dp_link_parse_video_pattern_params()
418 link->dp_link.test_video.test_bit_depth = bp; in dp_link_parse_video_pattern_params()
421 ret = dp_link_parse_timing_params1(link, DP_TEST_H_TOTAL_HI, 2, in dp_link_parse_video_pattern_params()
422 &link->dp_link.test_video.test_h_total); in dp_link_parse_video_pattern_params()
428 ret = dp_link_parse_timing_params1(link, DP_TEST_V_TOTAL_HI, 2, in dp_link_parse_video_pattern_params()
429 &link->dp_link.test_video.test_v_total); in dp_link_parse_video_pattern_params()
435 ret = dp_link_parse_timing_params1(link, DP_TEST_H_START_HI, 2, in dp_link_parse_video_pattern_params()
436 &link->dp_link.test_video.test_h_start); in dp_link_parse_video_pattern_params()
442 ret = dp_link_parse_timing_params1(link, DP_TEST_V_START_HI, 2, in dp_link_parse_video_pattern_params()
443 &link->dp_link.test_video.test_v_start); in dp_link_parse_video_pattern_params()
449 ret = dp_link_parse_timing_params2(link, DP_TEST_HSYNC_HI, 2, in dp_link_parse_video_pattern_params()
450 &link->dp_link.test_video.test_hsync_pol, in dp_link_parse_video_pattern_params()
451 &link->dp_link.test_video.test_hsync_width); in dp_link_parse_video_pattern_params()
457 ret = dp_link_parse_timing_params2(link, DP_TEST_VSYNC_HI, 2, in dp_link_parse_video_pattern_params()
458 &link->dp_link.test_video.test_vsync_pol, in dp_link_parse_video_pattern_params()
459 &link->dp_link.test_video.test_vsync_width); in dp_link_parse_video_pattern_params()
465 ret = dp_link_parse_timing_params1(link, DP_TEST_H_WIDTH_HI, 2, in dp_link_parse_video_pattern_params()
466 &link->dp_link.test_video.test_h_width); in dp_link_parse_video_pattern_params()
472 ret = dp_link_parse_timing_params1(link, DP_TEST_V_HEIGHT_HI, 2, in dp_link_parse_video_pattern_params()
473 &link->dp_link.test_video.test_v_height); in dp_link_parse_video_pattern_params()
479 ret = dp_link_parse_timing_params3(link, DP_TEST_MISC1, in dp_link_parse_video_pattern_params()
480 &link->dp_link.test_video.test_rr_d); in dp_link_parse_video_pattern_params()
481 link->dp_link.test_video.test_rr_d &= DP_TEST_REFRESH_DENOMINATOR; in dp_link_parse_video_pattern_params()
487 ret = dp_link_parse_timing_params3(link, DP_TEST_REFRESH_RATE_NUMERATOR, in dp_link_parse_video_pattern_params()
488 &link->dp_link.test_video.test_rr_n); in dp_link_parse_video_pattern_params()
494 drm_dbg_dp(link->drm_dev, in dp_link_parse_video_pattern_params()
495 "link video pattern = 0x%x\n" in dp_link_parse_video_pattern_params()
496 "link dynamic range = 0x%x\n" in dp_link_parse_video_pattern_params()
497 "link bit depth = 0x%x\n" in dp_link_parse_video_pattern_params()
498 "TEST_H_TOTAL = %d, TEST_V_TOTAL = %d\n" in dp_link_parse_video_pattern_params()
499 "TEST_H_START = %d, TEST_V_START = %d\n" in dp_link_parse_video_pattern_params()
500 "TEST_HSYNC_POL = %d\n" in dp_link_parse_video_pattern_params()
501 "TEST_HSYNC_WIDTH = %d\n" in dp_link_parse_video_pattern_params()
502 "TEST_VSYNC_POL = %d\n" in dp_link_parse_video_pattern_params()
503 "TEST_VSYNC_WIDTH = %d\n" in dp_link_parse_video_pattern_params()
504 "TEST_H_WIDTH = %d\n" in dp_link_parse_video_pattern_params()
505 "TEST_V_HEIGHT = %d\n" in dp_link_parse_video_pattern_params()
506 "TEST_REFRESH_DENOMINATOR = %d\n" in dp_link_parse_video_pattern_params()
507 "TEST_REFRESH_NUMERATOR = %d\n", in dp_link_parse_video_pattern_params()
508 link->dp_link.test_video.test_video_pattern, in dp_link_parse_video_pattern_params()
509 link->dp_link.test_video.test_dyn_range, in dp_link_parse_video_pattern_params()
510 link->dp_link.test_video.test_bit_depth, in dp_link_parse_video_pattern_params()
511 link->dp_link.test_video.test_h_total, in dp_link_parse_video_pattern_params()
512 link->dp_link.test_video.test_v_total, in dp_link_parse_video_pattern_params()
513 link->dp_link.test_video.test_h_start, in dp_link_parse_video_pattern_params()
514 link->dp_link.test_video.test_v_start, in dp_link_parse_video_pattern_params()
515 link->dp_link.test_video.test_hsync_pol, in dp_link_parse_video_pattern_params()
516 link->dp_link.test_video.test_hsync_width, in dp_link_parse_video_pattern_params()
517 link->dp_link.test_video.test_vsync_pol, in dp_link_parse_video_pattern_params()
518 link->dp_link.test_video.test_vsync_width, in dp_link_parse_video_pattern_params()
519 link->dp_link.test_video.test_h_width, in dp_link_parse_video_pattern_params()
520 link->dp_link.test_video.test_v_height, in dp_link_parse_video_pattern_params()
521 link->dp_link.test_video.test_rr_d, in dp_link_parse_video_pattern_params()
522 link->dp_link.test_video.test_rr_n); in dp_link_parse_video_pattern_params()
528 * dp_link_parse_link_training_params() - parses link training parameters from
530 * @link: Display Port Driver data
532 * Returns 0 if it successfully parses the link rate (Byte 0x219) and lane
535 static int dp_link_parse_link_training_params(struct dp_link_private *link) in dp_link_parse_link_training_params() argument
540 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_LINK_RATE, &bp); in dp_link_parse_link_training_params()
542 DRM_ERROR("failed to read link rate. rlen=%zd\n", rlen); in dp_link_parse_link_training_params()
547 DRM_ERROR("invalid link rate = 0x%x\n", bp); in dp_link_parse_link_training_params()
548 return -EINVAL; in dp_link_parse_link_training_params()
551 link->request.test_link_rate = bp; in dp_link_parse_link_training_params()
552 drm_dbg_dp(link->drm_dev, "link rate = 0x%x\n", in dp_link_parse_link_training_params()
553 link->request.test_link_rate); in dp_link_parse_link_training_params()
555 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_LANE_COUNT, &bp); in dp_link_parse_link_training_params()
564 return -EINVAL; in dp_link_parse_link_training_params()
567 link->request.test_lane_count = bp; in dp_link_parse_link_training_params()
568 drm_dbg_dp(link->drm_dev, "lane count = 0x%x\n", in dp_link_parse_link_training_params()
569 link->request.test_lane_count); in dp_link_parse_link_training_params()
574 * dp_link_parse_phy_test_params() - parses the phy link parameters
575 * @link: Display Port Driver data
577 * Parses the DPCD (Byte 0x248) for the DP PHY link pattern that is being
580 static int dp_link_parse_phy_test_params(struct dp_link_private *link) in dp_link_parse_phy_test_params() argument
585 rlen = drm_dp_dpcd_readb(link->aux, DP_PHY_TEST_PATTERN, in dp_link_parse_phy_test_params()
588 DRM_ERROR("failed to read phy link pattern. rlen=%zd\n", rlen); in dp_link_parse_phy_test_params()
592 link->dp_link.phy_params.phy_test_pattern_sel = data & 0x07; in dp_link_parse_phy_test_params()
594 drm_dbg_dp(link->drm_dev, "phy_test_pattern_sel = 0x%x\n", data); in dp_link_parse_phy_test_params()
606 return -EINVAL; in dp_link_parse_phy_test_params()
611 * dp_link_is_video_audio_test_requested() - checks for audio/video link request
612 * @link: link requested by the sink
614 * Returns true if the requested link is a permitted audio/video link.
616 static bool dp_link_is_video_audio_test_requested(u32 link) in dp_link_is_video_audio_test_requested() argument
622 return ((link & video_audio_test) && in dp_link_is_video_audio_test_requested()
623 !(link & ~video_audio_test)); in dp_link_is_video_audio_test_requested()
627 * dp_link_parse_request() - parses link request parameters from sink
628 * @link: Display Port Driver data
630 * Parses the DPCD to check if an automated link is requested (Byte 0x201),
631 * and what type of link automation is being requested (Byte 0x218).
633 static int dp_link_parse_request(struct dp_link_private *link) in dp_link_parse_request() argument
641 * whether an automated link has been requested by the sink. in dp_link_parse_request()
643 rlen = drm_dp_dpcd_readb(link->aux, in dp_link_parse_request()
650 drm_dbg_dp(link->drm_dev, "device service irq vector = 0x%x\n", data); in dp_link_parse_request()
653 drm_dbg_dp(link->drm_dev, "no test requested\n"); in dp_link_parse_request()
658 * Read the link request byte (Byte 0x218) to determine what type in dp_link_parse_request()
659 * of automated link has been requested by the sink. in dp_link_parse_request()
661 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_REQUEST, &data); in dp_link_parse_request()
668 drm_dbg_dp(link->drm_dev, "link 0x%x not supported\n", data); in dp_link_parse_request()
672 drm_dbg_dp(link->drm_dev, "Test:(0x%x) requested\n", data); in dp_link_parse_request()
673 link->request.test_requested = data; in dp_link_parse_request()
674 if (link->request.test_requested == DP_TEST_LINK_PHY_TEST_PATTERN) { in dp_link_parse_request()
675 ret = dp_link_parse_phy_test_params(link); in dp_link_parse_request()
678 ret = dp_link_parse_link_training_params(link); in dp_link_parse_request()
683 if (link->request.test_requested == DP_TEST_LINK_TRAINING) { in dp_link_parse_request()
684 ret = dp_link_parse_link_training_params(link); in dp_link_parse_request()
690 link->request.test_requested)) { in dp_link_parse_request()
691 ret = dp_link_parse_video_pattern_params(link); in dp_link_parse_request()
695 ret = dp_link_parse_audio_pattern_params(link); in dp_link_parse_request()
699 * Send a DP_TEST_ACK if all link parameters are valid, otherwise send in dp_link_parse_request()
703 link->dp_link.test_response = DP_TEST_NAK; in dp_link_parse_request()
705 if (link->request.test_requested != DP_TEST_LINK_EDID_READ) in dp_link_parse_request()
706 link->dp_link.test_response = DP_TEST_ACK; in dp_link_parse_request()
708 link->dp_link.test_response = in dp_link_parse_request()
715 static int dp_link_parse_sink_status_field(struct dp_link_private *link) in dp_link_parse_sink_status_field() argument
719 link->prev_sink_count = link->dp_link.sink_count; in dp_link_parse_sink_status_field()
720 len = drm_dp_read_sink_count(link->aux); in dp_link_parse_sink_status_field()
725 link->dp_link.sink_count = len; in dp_link_parse_sink_status_field()
727 len = drm_dp_dpcd_read_link_status(link->aux, in dp_link_parse_sink_status_field()
728 link->link_status); in dp_link_parse_sink_status_field()
730 DRM_ERROR("DP link status read failed\n"); in dp_link_parse_sink_status_field()
734 return dp_link_parse_request(link); in dp_link_parse_sink_status_field()
738 * dp_link_process_link_training_request() - processes new training requests
739 * @link: Display Port link data
741 * This function will handle new link training requests that are initiated by
742 * the sink. In particular, it will update the requested lane count and link
743 * rate, and then trigger the link retraining procedure.
745 * The function will return 0 if a link training request has been processed,
746 * otherwise it will return -EINVAL.
748 static int dp_link_process_link_training_request(struct dp_link_private *link) in dp_link_process_link_training_request() argument
750 if (link->request.test_requested != DP_TEST_LINK_TRAINING) in dp_link_process_link_training_request()
751 return -EINVAL; in dp_link_process_link_training_request()
753 drm_dbg_dp(link->drm_dev, in dp_link_process_link_training_request()
754 "Test:0x%x link rate = 0x%x, lane count = 0x%x\n", in dp_link_process_link_training_request()
756 link->request.test_link_rate, in dp_link_process_link_training_request()
757 link->request.test_lane_count); in dp_link_process_link_training_request()
759 link->dp_link.link_params.num_lanes = link->request.test_lane_count; in dp_link_process_link_training_request()
760 link->dp_link.link_params.rate = in dp_link_process_link_training_request()
761 drm_dp_bw_code_to_link_rate(link->request.test_link_rate); in dp_link_process_link_training_request()
768 struct dp_link_private *link = NULL; in dp_link_send_test_response() local
776 link = container_of(dp_link, struct dp_link_private, dp_link); in dp_link_send_test_response()
778 ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_RESPONSE, in dp_link_send_test_response()
779 dp_link->test_response); in dp_link_send_test_response()
787 struct dp_link_private *link = NULL; in dp_link_psm_config() local
792 return -EINVAL; in dp_link_psm_config()
795 link = container_of(dp_link, struct dp_link_private, dp_link); in dp_link_psm_config()
797 mutex_lock(&link->psm_mutex); in dp_link_psm_config()
799 ret = dp_aux_link_power_down(link->aux, link_info); in dp_link_psm_config()
801 ret = dp_aux_link_power_up(link->aux, link_info); in dp_link_psm_config()
807 mutex_unlock(&link->psm_mutex); in dp_link_psm_config()
813 struct dp_link_private *link = NULL; in dp_link_send_edid_checksum() local
821 link = container_of(dp_link, struct dp_link_private, dp_link); in dp_link_send_edid_checksum()
823 ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_EDID_CHECKSUM, in dp_link_send_edid_checksum()
828 static void dp_link_parse_vx_px(struct dp_link_private *link) in dp_link_parse_vx_px() argument
830 drm_dbg_dp(link->drm_dev, "vx: 0=%d, 1=%d, 2=%d, 3=%d\n", in dp_link_parse_vx_px()
831 drm_dp_get_adjust_request_voltage(link->link_status, 0), in dp_link_parse_vx_px()
832 drm_dp_get_adjust_request_voltage(link->link_status, 1), in dp_link_parse_vx_px()
833 drm_dp_get_adjust_request_voltage(link->link_status, 2), in dp_link_parse_vx_px()
834 drm_dp_get_adjust_request_voltage(link->link_status, 3)); in dp_link_parse_vx_px()
836 drm_dbg_dp(link->drm_dev, "px: 0=%d, 1=%d, 2=%d, 3=%d\n", in dp_link_parse_vx_px()
837 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 0), in dp_link_parse_vx_px()
838 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 1), in dp_link_parse_vx_px()
839 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 2), in dp_link_parse_vx_px()
840 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 3)); in dp_link_parse_vx_px()
843 * Update the voltage and pre-emphasis levels as per DPCD request in dp_link_parse_vx_px()
846 drm_dbg_dp(link->drm_dev, in dp_link_parse_vx_px()
848 link->dp_link.phy_params.v_level, in dp_link_parse_vx_px()
849 link->dp_link.phy_params.p_level); in dp_link_parse_vx_px()
850 link->dp_link.phy_params.v_level = in dp_link_parse_vx_px()
851 drm_dp_get_adjust_request_voltage(link->link_status, 0); in dp_link_parse_vx_px()
852 link->dp_link.phy_params.p_level = in dp_link_parse_vx_px()
853 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 0); in dp_link_parse_vx_px()
855 link->dp_link.phy_params.p_level >>= DP_TRAIN_PRE_EMPHASIS_SHIFT; in dp_link_parse_vx_px()
857 drm_dbg_dp(link->drm_dev, in dp_link_parse_vx_px()
859 link->dp_link.phy_params.v_level, in dp_link_parse_vx_px()
860 link->dp_link.phy_params.p_level); in dp_link_parse_vx_px()
864 * dp_link_process_phy_test_pattern_request() - process new phy link requests
865 * @link: Display Port Driver data
867 * This function will handle new phy link pattern requests that are initiated
868 * by the sink. The function will return 0 if a phy link pattern has been
869 * processed, otherwise it will return -EINVAL.
872 struct dp_link_private *link) in dp_link_process_phy_test_pattern_request() argument
874 if (!(link->request.test_requested & DP_TEST_LINK_PHY_TEST_PATTERN)) { in dp_link_process_phy_test_pattern_request()
875 drm_dbg_dp(link->drm_dev, "no phy test\n"); in dp_link_process_phy_test_pattern_request()
876 return -EINVAL; in dp_link_process_phy_test_pattern_request()
879 if (!is_link_rate_valid(link->request.test_link_rate) || in dp_link_process_phy_test_pattern_request()
880 !is_lane_count_valid(link->request.test_lane_count)) { in dp_link_process_phy_test_pattern_request()
881 DRM_ERROR("Invalid: link rate = 0x%x,lane count = 0x%x\n", in dp_link_process_phy_test_pattern_request()
882 link->request.test_link_rate, in dp_link_process_phy_test_pattern_request()
883 link->request.test_lane_count); in dp_link_process_phy_test_pattern_request()
884 return -EINVAL; in dp_link_process_phy_test_pattern_request()
887 drm_dbg_dp(link->drm_dev, in dp_link_process_phy_test_pattern_request()
889 link->dp_link.link_params.rate, in dp_link_process_phy_test_pattern_request()
890 link->dp_link.link_params.num_lanes); in dp_link_process_phy_test_pattern_request()
892 drm_dbg_dp(link->drm_dev, in dp_link_process_phy_test_pattern_request()
894 link->request.test_link_rate, in dp_link_process_phy_test_pattern_request()
895 link->request.test_lane_count); in dp_link_process_phy_test_pattern_request()
897 link->dp_link.link_params.num_lanes = link->request.test_lane_count; in dp_link_process_phy_test_pattern_request()
898 link->dp_link.link_params.rate = in dp_link_process_phy_test_pattern_request()
899 drm_dp_bw_code_to_link_rate(link->request.test_link_rate); in dp_link_process_phy_test_pattern_request()
901 dp_link_parse_vx_px(link); in dp_link_process_phy_test_pattern_request()
906 static bool dp_link_read_psr_error_status(struct dp_link_private *link) in dp_link_read_psr_error_status() argument
910 drm_dp_dpcd_read(link->aux, DP_PSR_ERROR_STATUS, &status, 1); in dp_link_read_psr_error_status()
913 DRM_ERROR("PSR LINK CRC ERROR\n"); in dp_link_read_psr_error_status()
924 static bool dp_link_psr_capability_changed(struct dp_link_private *link) in dp_link_psr_capability_changed() argument
928 drm_dp_dpcd_read(link->aux, DP_PSR_ESI, &status, 1); in dp_link_psr_capability_changed()
931 drm_dbg_dp(link->drm_dev, "PSR Capability Change\n"); in dp_link_psr_capability_changed()
940 return link_status[r - DP_LANE0_1_STATUS]; in get_link_status()
944 * dp_link_process_link_status_update() - processes link status updates
945 * @link: Display Port link module data
947 * This function will check for changes in the link status, e.g. clock
948 * recovery done on all lanes, and trigger link training if there is a
949 * failure/error on the link.
951 * The function will return 0 if the a link status update has been processed,
952 * otherwise it will return -EINVAL.
954 static int dp_link_process_link_status_update(struct dp_link_private *link) in dp_link_process_link_status_update() argument
956 bool channel_eq_done = drm_dp_channel_eq_ok(link->link_status, in dp_link_process_link_status_update()
957 link->dp_link.link_params.num_lanes); in dp_link_process_link_status_update()
959 bool clock_recovery_done = drm_dp_clock_recovery_ok(link->link_status, in dp_link_process_link_status_update()
960 link->dp_link.link_params.num_lanes); in dp_link_process_link_status_update()
962 drm_dbg_dp(link->drm_dev, in dp_link_process_link_status_update()
963 "channel_eq_done = %d, clock_recovery_done = %d\n", in dp_link_process_link_status_update()
967 return -EINVAL; in dp_link_process_link_status_update()
973 * dp_link_process_ds_port_status_change() - process port status changes
974 * @link: Display Port Driver data
981 * processed, otherwise it will return -EINVAL.
983 static int dp_link_process_ds_port_status_change(struct dp_link_private *link) in dp_link_process_ds_port_status_change() argument
985 if (get_link_status(link->link_status, DP_LANE_ALIGN_STATUS_UPDATED) & in dp_link_process_ds_port_status_change()
989 if (link->prev_sink_count == link->dp_link.sink_count) in dp_link_process_ds_port_status_change()
990 return -EINVAL; in dp_link_process_ds_port_status_change()
994 link->prev_sink_count = link->dp_link.sink_count; in dp_link_process_ds_port_status_change()
999 static bool dp_link_is_video_pattern_requested(struct dp_link_private *link) in dp_link_is_video_pattern_requested() argument
1001 return (link->request.test_requested & DP_TEST_LINK_VIDEO_PATTERN) in dp_link_is_video_pattern_requested()
1002 && !(link->request.test_requested & in dp_link_is_video_pattern_requested()
1006 static bool dp_link_is_audio_pattern_requested(struct dp_link_private *link) in dp_link_is_audio_pattern_requested() argument
1008 return (link->request.test_requested & DP_TEST_LINK_AUDIO_PATTERN); in dp_link_is_audio_pattern_requested()
1011 static void dp_link_reset_data(struct dp_link_private *link) in dp_link_reset_data() argument
1013 link->request = (const struct dp_link_request){ 0 }; in dp_link_reset_data()
1014 link->dp_link.test_video = (const struct dp_link_test_video){ 0 }; in dp_link_reset_data()
1015 link->dp_link.test_video.test_bit_depth = DP_TEST_BIT_DEPTH_UNKNOWN; in dp_link_reset_data()
1016 link->dp_link.test_audio = (const struct dp_link_test_audio){ 0 }; in dp_link_reset_data()
1017 link->dp_link.phy_params.phy_test_pattern_sel = 0; in dp_link_reset_data()
1018 link->dp_link.sink_request = 0; in dp_link_reset_data()
1019 link->dp_link.test_response = 0; in dp_link_reset_data()
1023 * dp_link_process_request() - handle HPD IRQ transition to HIGH
1024 * @dp_link: pointer to link module data
1028 * the start of a new link training request or sink status update.
1033 struct dp_link_private *link; in dp_link_process_request() local
1037 return -EINVAL; in dp_link_process_request()
1040 link = container_of(dp_link, struct dp_link_private, dp_link); in dp_link_process_request()
1042 dp_link_reset_data(link); in dp_link_process_request()
1044 ret = dp_link_parse_sink_status_field(link); in dp_link_process_request()
1048 if (link->request.test_requested == DP_TEST_LINK_EDID_READ) { in dp_link_process_request()
1049 dp_link->sink_request |= DP_TEST_LINK_EDID_READ; in dp_link_process_request()
1050 } else if (!dp_link_process_ds_port_status_change(link)) { in dp_link_process_request()
1051 dp_link->sink_request |= DS_PORT_STATUS_CHANGED; in dp_link_process_request()
1052 } else if (!dp_link_process_link_training_request(link)) { in dp_link_process_request()
1053 dp_link->sink_request |= DP_TEST_LINK_TRAINING; in dp_link_process_request()
1054 } else if (!dp_link_process_phy_test_pattern_request(link)) { in dp_link_process_request()
1055 dp_link->sink_request |= DP_TEST_LINK_PHY_TEST_PATTERN; in dp_link_process_request()
1056 } else if (dp_link_read_psr_error_status(link)) { in dp_link_process_request()
1058 } else if (dp_link_psr_capability_changed(link)) { in dp_link_process_request()
1059 drm_dbg_dp(link->drm_dev, "PSR Capability changed\n"); in dp_link_process_request()
1061 ret = dp_link_process_link_status_update(link); in dp_link_process_request()
1063 dp_link->sink_request |= DP_LINK_STATUS_UPDATED; in dp_link_process_request()
1065 if (dp_link_is_video_pattern_requested(link)) { in dp_link_process_request()
1067 dp_link->sink_request |= DP_TEST_LINK_VIDEO_PATTERN; in dp_link_process_request()
1069 if (dp_link_is_audio_pattern_requested(link)) { in dp_link_process_request()
1070 dp_link->sink_request |= DP_TEST_LINK_AUDIO_PATTERN; in dp_link_process_request()
1071 ret = -EINVAL; in dp_link_process_request()
1076 drm_dbg_dp(link->drm_dev, "sink request=%#x\n", in dp_link_process_request()
1077 dp_link->sink_request); in dp_link_process_request()
1084 struct dp_link_private *link; in dp_link_get_colorimetry_config() local
1088 return -EINVAL; in dp_link_get_colorimetry_config()
1091 link = container_of(dp_link, struct dp_link_private, dp_link); in dp_link_get_colorimetry_config()
1097 if (dp_link_is_video_pattern_requested(link)) { in dp_link_get_colorimetry_config()
1098 if (link->dp_link.test_video.test_dyn_range & in dp_link_get_colorimetry_config()
1111 struct dp_link_private *link; in dp_link_adjust_levels() local
1115 return -EINVAL; in dp_link_adjust_levels()
1118 link = container_of(dp_link, struct dp_link_private, dp_link); in dp_link_adjust_levels()
1121 for (i = 0; i < dp_link->link_params.num_lanes; i++) { in dp_link_adjust_levels()
1125 drm_dbg_dp(link->drm_dev, in dp_link_adjust_levels()
1126 "lane=%d req_vol_swing=%d req_pre_emphasis=%d\n", in dp_link_adjust_levels()
1134 dp_link->phy_params.v_level = v_max >> DP_TRAIN_VOLTAGE_SWING_SHIFT; in dp_link_adjust_levels()
1135 dp_link->phy_params.p_level = p_max >> DP_TRAIN_PRE_EMPHASIS_SHIFT; in dp_link_adjust_levels()
1138 * Adjust the voltage swing and pre-emphasis level combination to within in dp_link_adjust_levels()
1141 if (dp_link->phy_params.v_level > DP_TRAIN_LEVEL_MAX) { in dp_link_adjust_levels()
1142 drm_dbg_dp(link->drm_dev, in dp_link_adjust_levels()
1143 "Requested vSwingLevel=%d, change to %d\n", in dp_link_adjust_levels()
1144 dp_link->phy_params.v_level, in dp_link_adjust_levels()
1146 dp_link->phy_params.v_level = DP_TRAIN_LEVEL_MAX; in dp_link_adjust_levels()
1149 if (dp_link->phy_params.p_level > DP_TRAIN_LEVEL_MAX) { in dp_link_adjust_levels()
1150 drm_dbg_dp(link->drm_dev, in dp_link_adjust_levels()
1151 "Requested preEmphasisLevel=%d, change to %d\n", in dp_link_adjust_levels()
1152 dp_link->phy_params.p_level, in dp_link_adjust_levels()
1154 dp_link->phy_params.p_level = DP_TRAIN_LEVEL_MAX; in dp_link_adjust_levels()
1157 max_p_level = DP_TRAIN_LEVEL_MAX - dp_link->phy_params.v_level; in dp_link_adjust_levels()
1158 if (dp_link->phy_params.p_level > max_p_level) { in dp_link_adjust_levels()
1159 drm_dbg_dp(link->drm_dev, in dp_link_adjust_levels()
1160 "Requested preEmphasisLevel=%d, change to %d\n", in dp_link_adjust_levels()
1161 dp_link->phy_params.p_level, in dp_link_adjust_levels()
1163 dp_link->phy_params.p_level = max_p_level; in dp_link_adjust_levels()
1166 drm_dbg_dp(link->drm_dev, "adjusted: v_level=%d, p_level=%d\n", in dp_link_adjust_levels()
1167 dp_link->phy_params.v_level, dp_link->phy_params.p_level); in dp_link_adjust_levels()
1174 dp_link->phy_params.v_level = 0; in dp_link_reset_phy_params_vx_px()
1175 dp_link->phy_params.p_level = 0; in dp_link_reset_phy_params_vx_px()
1181 struct dp_link_private *link; in dp_link_get_test_bits_depth() local
1183 link = container_of(dp_link, struct dp_link_private, dp_link); in dp_link_get_test_bits_depth()
1201 drm_dbg_dp(link->drm_dev, "bpp=%d not supported, use bpc=8\n", in dp_link_get_test_bits_depth()
1214 struct dp_link_private *link; in dp_link_get() local
1219 return ERR_PTR(-EINVAL); in dp_link_get()
1222 link = devm_kzalloc(dev, sizeof(*link), GFP_KERNEL); in dp_link_get()
1223 if (!link) in dp_link_get()
1224 return ERR_PTR(-ENOMEM); in dp_link_get()
1226 link->aux = aux; in dp_link_get()
1228 mutex_init(&link->psm_mutex); in dp_link_get()
1229 dp_link = &link->dp_link; in dp_link_get()