xref: /openbmc/linux/drivers/gpu/drm/msm/dp/dp_link.c (revision 6726d552)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
4  */
5 
6 #define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
7 
8 #include <drm/drm_print.h>
9 
10 #include "dp_link.h"
11 #include "dp_panel.h"
12 
13 #define DP_TEST_REQUEST_MASK		0x7F
14 
15 enum audio_sample_rate {
16 	AUDIO_SAMPLE_RATE_32_KHZ	= 0x00,
17 	AUDIO_SAMPLE_RATE_44_1_KHZ	= 0x01,
18 	AUDIO_SAMPLE_RATE_48_KHZ	= 0x02,
19 	AUDIO_SAMPLE_RATE_88_2_KHZ	= 0x03,
20 	AUDIO_SAMPLE_RATE_96_KHZ	= 0x04,
21 	AUDIO_SAMPLE_RATE_176_4_KHZ	= 0x05,
22 	AUDIO_SAMPLE_RATE_192_KHZ	= 0x06,
23 };
24 
25 enum audio_pattern_type {
26 	AUDIO_TEST_PATTERN_OPERATOR_DEFINED	= 0x00,
27 	AUDIO_TEST_PATTERN_SAWTOOTH		= 0x01,
28 };
29 
30 struct dp_link_request {
31 	u32 test_requested;
32 	u32 test_link_rate;
33 	u32 test_lane_count;
34 };
35 
36 struct dp_link_private {
37 	u32 prev_sink_count;
38 	struct device *dev;
39 	struct drm_device *drm_dev;
40 	struct drm_dp_aux *aux;
41 	struct dp_link dp_link;
42 
43 	struct dp_link_request request;
44 	struct mutex psm_mutex;
45 	u8 link_status[DP_LINK_STATUS_SIZE];
46 };
47 
48 static int dp_aux_link_power_up(struct drm_dp_aux *aux,
49 					struct dp_link_info *link)
50 {
51 	u8 value;
52 	int err;
53 
54 	if (link->revision < 0x11)
55 		return 0;
56 
57 	err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
58 	if (err < 0)
59 		return err;
60 
61 	value &= ~DP_SET_POWER_MASK;
62 	value |= DP_SET_POWER_D0;
63 
64 	err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
65 	if (err < 0)
66 		return err;
67 
68 	usleep_range(1000, 2000);
69 
70 	return 0;
71 }
72 
73 static int dp_aux_link_power_down(struct drm_dp_aux *aux,
74 					struct dp_link_info *link)
75 {
76 	u8 value;
77 	int err;
78 
79 	if (link->revision < 0x11)
80 		return 0;
81 
82 	err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
83 	if (err < 0)
84 		return err;
85 
86 	value &= ~DP_SET_POWER_MASK;
87 	value |= DP_SET_POWER_D3;
88 
89 	err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
90 	if (err < 0)
91 		return err;
92 
93 	return 0;
94 }
95 
96 static int dp_link_get_period(struct dp_link_private *link, int const addr)
97 {
98 	int ret = 0;
99 	u8 data;
100 	u32 const max_audio_period = 0xA;
101 
102 	/* TEST_AUDIO_PERIOD_CH_XX */
103 	if (drm_dp_dpcd_readb(link->aux, addr, &data) < 0) {
104 		DRM_ERROR("failed to read test_audio_period (0x%x)\n", addr);
105 		ret = -EINVAL;
106 		goto exit;
107 	}
108 
109 	/* Period - Bits 3:0 */
110 	data = data & 0xF;
111 	if ((int)data > max_audio_period) {
112 		DRM_ERROR("invalid test_audio_period_ch_1 = 0x%x\n", data);
113 		ret = -EINVAL;
114 		goto exit;
115 	}
116 
117 	ret = data;
118 exit:
119 	return ret;
120 }
121 
122 static int dp_link_parse_audio_channel_period(struct dp_link_private *link)
123 {
124 	int ret = 0;
125 	struct dp_link_test_audio *req = &link->dp_link.test_audio;
126 
127 	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH1);
128 	if (ret == -EINVAL)
129 		goto exit;
130 
131 	req->test_audio_period_ch_1 = ret;
132 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_1 = 0x%x\n", ret);
133 
134 	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH2);
135 	if (ret == -EINVAL)
136 		goto exit;
137 
138 	req->test_audio_period_ch_2 = ret;
139 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_2 = 0x%x\n", ret);
140 
141 	/* TEST_AUDIO_PERIOD_CH_3 (Byte 0x275) */
142 	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH3);
143 	if (ret == -EINVAL)
144 		goto exit;
145 
146 	req->test_audio_period_ch_3 = ret;
147 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_3 = 0x%x\n", ret);
148 
149 	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH4);
150 	if (ret == -EINVAL)
151 		goto exit;
152 
153 	req->test_audio_period_ch_4 = ret;
154 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_4 = 0x%x\n", ret);
155 
156 	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH5);
157 	if (ret == -EINVAL)
158 		goto exit;
159 
160 	req->test_audio_period_ch_5 = ret;
161 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_5 = 0x%x\n", ret);
162 
163 	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH6);
164 	if (ret == -EINVAL)
165 		goto exit;
166 
167 	req->test_audio_period_ch_6 = ret;
168 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_6 = 0x%x\n", ret);
169 
170 	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH7);
171 	if (ret == -EINVAL)
172 		goto exit;
173 
174 	req->test_audio_period_ch_7 = ret;
175 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_7 = 0x%x\n", ret);
176 
177 	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH8);
178 	if (ret == -EINVAL)
179 		goto exit;
180 
181 	req->test_audio_period_ch_8 = ret;
182 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_8 = 0x%x\n", ret);
183 exit:
184 	return ret;
185 }
186 
187 static int dp_link_parse_audio_pattern_type(struct dp_link_private *link)
188 {
189 	int ret = 0;
190 	u8 data;
191 	ssize_t rlen;
192 	int const max_audio_pattern_type = 0x1;
193 
194 	rlen = drm_dp_dpcd_readb(link->aux,
195 				DP_TEST_AUDIO_PATTERN_TYPE, &data);
196 	if (rlen < 0) {
197 		DRM_ERROR("failed to read link audio mode. rlen=%zd\n", rlen);
198 		return rlen;
199 	}
200 
201 	/* Audio Pattern Type - Bits 7:0 */
202 	if ((int)data > max_audio_pattern_type) {
203 		DRM_ERROR("invalid audio pattern type = 0x%x\n", data);
204 		ret = -EINVAL;
205 		goto exit;
206 	}
207 
208 	link->dp_link.test_audio.test_audio_pattern_type = data;
209 	drm_dbg_dp(link->drm_dev, "audio pattern type = 0x%x\n", data);
210 exit:
211 	return ret;
212 }
213 
214 static int dp_link_parse_audio_mode(struct dp_link_private *link)
215 {
216 	int ret = 0;
217 	u8 data;
218 	ssize_t rlen;
219 	int const max_audio_sampling_rate = 0x6;
220 	int const max_audio_channel_count = 0x8;
221 	int sampling_rate = 0x0;
222 	int channel_count = 0x0;
223 
224 	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_AUDIO_MODE, &data);
225 	if (rlen < 0) {
226 		DRM_ERROR("failed to read link audio mode. rlen=%zd\n", rlen);
227 		return rlen;
228 	}
229 
230 	/* Sampling Rate - Bits 3:0 */
231 	sampling_rate = data & 0xF;
232 	if (sampling_rate > max_audio_sampling_rate) {
233 		DRM_ERROR("sampling rate (0x%x) greater than max (0x%x)\n",
234 				sampling_rate, max_audio_sampling_rate);
235 		ret = -EINVAL;
236 		goto exit;
237 	}
238 
239 	/* Channel Count - Bits 7:4 */
240 	channel_count = ((data & 0xF0) >> 4) + 1;
241 	if (channel_count > max_audio_channel_count) {
242 		DRM_ERROR("channel_count (0x%x) greater than max (0x%x)\n",
243 				channel_count, max_audio_channel_count);
244 		ret = -EINVAL;
245 		goto exit;
246 	}
247 
248 	link->dp_link.test_audio.test_audio_sampling_rate = sampling_rate;
249 	link->dp_link.test_audio.test_audio_channel_count = channel_count;
250 	drm_dbg_dp(link->drm_dev,
251 			"sampling_rate = 0x%x, channel_count = 0x%x\n",
252 			sampling_rate, channel_count);
253 exit:
254 	return ret;
255 }
256 
257 static int dp_link_parse_audio_pattern_params(struct dp_link_private *link)
258 {
259 	int ret = 0;
260 
261 	ret = dp_link_parse_audio_mode(link);
262 	if (ret)
263 		goto exit;
264 
265 	ret = dp_link_parse_audio_pattern_type(link);
266 	if (ret)
267 		goto exit;
268 
269 	ret = dp_link_parse_audio_channel_period(link);
270 
271 exit:
272 	return ret;
273 }
274 
275 static bool dp_link_is_video_pattern_valid(u32 pattern)
276 {
277 	switch (pattern) {
278 	case DP_NO_TEST_PATTERN:
279 	case DP_COLOR_RAMP:
280 	case DP_BLACK_AND_WHITE_VERTICAL_LINES:
281 	case DP_COLOR_SQUARE:
282 		return true;
283 	default:
284 		return false;
285 	}
286 }
287 
288 /**
289  * dp_link_is_bit_depth_valid() - validates the bit depth requested
290  * @tbd: bit depth requested by the sink
291  *
292  * Returns true if the requested bit depth is supported.
293  */
294 static bool dp_link_is_bit_depth_valid(u32 tbd)
295 {
296 	/* DP_TEST_VIDEO_PATTERN_NONE is treated as invalid */
297 	switch (tbd) {
298 	case DP_TEST_BIT_DEPTH_6:
299 	case DP_TEST_BIT_DEPTH_8:
300 	case DP_TEST_BIT_DEPTH_10:
301 		return true;
302 	default:
303 		return false;
304 	}
305 }
306 
307 static int dp_link_parse_timing_params1(struct dp_link_private *link,
308 					int addr, int len, u32 *val)
309 {
310 	u8 bp[2];
311 	int rlen;
312 
313 	if (len != 2)
314 		return -EINVAL;
315 
316 	/* Read the requested video link pattern (Byte 0x221). */
317 	rlen = drm_dp_dpcd_read(link->aux, addr, bp, len);
318 	if (rlen < len) {
319 		DRM_ERROR("failed to read 0x%x\n", addr);
320 		return -EINVAL;
321 	}
322 
323 	*val = bp[1] | (bp[0] << 8);
324 
325 	return 0;
326 }
327 
328 static int dp_link_parse_timing_params2(struct dp_link_private *link,
329 					int addr, int len,
330 					u32 *val1, u32 *val2)
331 {
332 	u8 bp[2];
333 	int rlen;
334 
335 	if (len != 2)
336 		return -EINVAL;
337 
338 	/* Read the requested video link pattern (Byte 0x221). */
339 	rlen = drm_dp_dpcd_read(link->aux, addr, bp, len);
340 	if (rlen < len) {
341 		DRM_ERROR("failed to read 0x%x\n", addr);
342 		return -EINVAL;
343 	}
344 
345 	*val1 = (bp[0] & BIT(7)) >> 7;
346 	*val2 = bp[1] | ((bp[0] & 0x7F) << 8);
347 
348 	return 0;
349 }
350 
351 static int dp_link_parse_timing_params3(struct dp_link_private *link,
352 					int addr, u32 *val)
353 {
354 	u8 bp;
355 	u32 len = 1;
356 	int rlen;
357 
358 	rlen = drm_dp_dpcd_read(link->aux, addr, &bp, len);
359 	if (rlen < 1) {
360 		DRM_ERROR("failed to read 0x%x\n", addr);
361 		return -EINVAL;
362 	}
363 	*val = bp;
364 
365 	return 0;
366 }
367 
368 /**
369  * dp_link_parse_video_pattern_params() - parses video pattern parameters from DPCD
370  * @link: Display Port Driver data
371  *
372  * Returns 0 if it successfully parses the video link pattern and the link
373  * bit depth requested by the sink and, and if the values parsed are valid.
374  */
375 static int dp_link_parse_video_pattern_params(struct dp_link_private *link)
376 {
377 	int ret = 0;
378 	ssize_t rlen;
379 	u8 bp;
380 
381 	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_PATTERN, &bp);
382 	if (rlen < 0) {
383 		DRM_ERROR("failed to read link video pattern. rlen=%zd\n",
384 			rlen);
385 		return rlen;
386 	}
387 
388 	if (!dp_link_is_video_pattern_valid(bp)) {
389 		DRM_ERROR("invalid link video pattern = 0x%x\n", bp);
390 		ret = -EINVAL;
391 		return ret;
392 	}
393 
394 	link->dp_link.test_video.test_video_pattern = bp;
395 
396 	/* Read the requested color bit depth and dynamic range (Byte 0x232) */
397 	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_MISC0, &bp);
398 	if (rlen < 0) {
399 		DRM_ERROR("failed to read link bit depth. rlen=%zd\n", rlen);
400 		return rlen;
401 	}
402 
403 	/* Dynamic Range */
404 	link->dp_link.test_video.test_dyn_range =
405 			(bp & DP_TEST_DYNAMIC_RANGE_CEA);
406 
407 	/* Color bit depth */
408 	bp &= DP_TEST_BIT_DEPTH_MASK;
409 	if (!dp_link_is_bit_depth_valid(bp)) {
410 		DRM_ERROR("invalid link bit depth = 0x%x\n", bp);
411 		ret = -EINVAL;
412 		return ret;
413 	}
414 
415 	link->dp_link.test_video.test_bit_depth = bp;
416 
417 	/* resolution timing params */
418 	ret = dp_link_parse_timing_params1(link, DP_TEST_H_TOTAL_HI, 2,
419 			&link->dp_link.test_video.test_h_total);
420 	if (ret) {
421 		DRM_ERROR("failed to parse test_htotal(DP_TEST_H_TOTAL_HI)\n");
422 		return ret;
423 	}
424 
425 	ret = dp_link_parse_timing_params1(link, DP_TEST_V_TOTAL_HI, 2,
426 			&link->dp_link.test_video.test_v_total);
427 	if (ret) {
428 		DRM_ERROR("failed to parse test_v_total(DP_TEST_V_TOTAL_HI)\n");
429 		return ret;
430 	}
431 
432 	ret = dp_link_parse_timing_params1(link, DP_TEST_H_START_HI, 2,
433 			&link->dp_link.test_video.test_h_start);
434 	if (ret) {
435 		DRM_ERROR("failed to parse test_h_start(DP_TEST_H_START_HI)\n");
436 		return ret;
437 	}
438 
439 	ret = dp_link_parse_timing_params1(link, DP_TEST_V_START_HI, 2,
440 			&link->dp_link.test_video.test_v_start);
441 	if (ret) {
442 		DRM_ERROR("failed to parse test_v_start(DP_TEST_V_START_HI)\n");
443 		return ret;
444 	}
445 
446 	ret = dp_link_parse_timing_params2(link, DP_TEST_HSYNC_HI, 2,
447 			&link->dp_link.test_video.test_hsync_pol,
448 			&link->dp_link.test_video.test_hsync_width);
449 	if (ret) {
450 		DRM_ERROR("failed to parse (DP_TEST_HSYNC_HI)\n");
451 		return ret;
452 	}
453 
454 	ret = dp_link_parse_timing_params2(link, DP_TEST_VSYNC_HI, 2,
455 			&link->dp_link.test_video.test_vsync_pol,
456 			&link->dp_link.test_video.test_vsync_width);
457 	if (ret) {
458 		DRM_ERROR("failed to parse (DP_TEST_VSYNC_HI)\n");
459 		return ret;
460 	}
461 
462 	ret = dp_link_parse_timing_params1(link, DP_TEST_H_WIDTH_HI, 2,
463 			&link->dp_link.test_video.test_h_width);
464 	if (ret) {
465 		DRM_ERROR("failed to parse test_h_width(DP_TEST_H_WIDTH_HI)\n");
466 		return ret;
467 	}
468 
469 	ret = dp_link_parse_timing_params1(link, DP_TEST_V_HEIGHT_HI, 2,
470 			&link->dp_link.test_video.test_v_height);
471 	if (ret) {
472 		DRM_ERROR("failed to parse test_v_height\n");
473 		return ret;
474 	}
475 
476 	ret = dp_link_parse_timing_params3(link, DP_TEST_MISC1,
477 		&link->dp_link.test_video.test_rr_d);
478 	link->dp_link.test_video.test_rr_d &= DP_TEST_REFRESH_DENOMINATOR;
479 	if (ret) {
480 		DRM_ERROR("failed to parse test_rr_d (DP_TEST_MISC1)\n");
481 		return ret;
482 	}
483 
484 	ret = dp_link_parse_timing_params3(link, DP_TEST_REFRESH_RATE_NUMERATOR,
485 		&link->dp_link.test_video.test_rr_n);
486 	if (ret) {
487 		DRM_ERROR("failed to parse test_rr_n\n");
488 		return ret;
489 	}
490 
491 	drm_dbg_dp(link->drm_dev,
492 		"link video pattern = 0x%x\n"
493 		"link dynamic range = 0x%x\n"
494 		"link bit depth = 0x%x\n"
495 		"TEST_H_TOTAL = %d, TEST_V_TOTAL = %d\n"
496 		"TEST_H_START = %d, TEST_V_START = %d\n"
497 		"TEST_HSYNC_POL = %d\n"
498 		"TEST_HSYNC_WIDTH = %d\n"
499 		"TEST_VSYNC_POL = %d\n"
500 		"TEST_VSYNC_WIDTH = %d\n"
501 		"TEST_H_WIDTH = %d\n"
502 		"TEST_V_HEIGHT = %d\n"
503 		"TEST_REFRESH_DENOMINATOR = %d\n"
504 		 "TEST_REFRESH_NUMERATOR = %d\n",
505 		link->dp_link.test_video.test_video_pattern,
506 		link->dp_link.test_video.test_dyn_range,
507 		link->dp_link.test_video.test_bit_depth,
508 		link->dp_link.test_video.test_h_total,
509 		link->dp_link.test_video.test_v_total,
510 		link->dp_link.test_video.test_h_start,
511 		link->dp_link.test_video.test_v_start,
512 		link->dp_link.test_video.test_hsync_pol,
513 		link->dp_link.test_video.test_hsync_width,
514 		link->dp_link.test_video.test_vsync_pol,
515 		link->dp_link.test_video.test_vsync_width,
516 		link->dp_link.test_video.test_h_width,
517 		link->dp_link.test_video.test_v_height,
518 		link->dp_link.test_video.test_rr_d,
519 		link->dp_link.test_video.test_rr_n);
520 
521 	return ret;
522 }
523 
524 /**
525  * dp_link_parse_link_training_params() - parses link training parameters from
526  * DPCD
527  * @link: Display Port Driver data
528  *
529  * Returns 0 if it successfully parses the link rate (Byte 0x219) and lane
530  * count (Byte 0x220), and if these values parse are valid.
531  */
532 static int dp_link_parse_link_training_params(struct dp_link_private *link)
533 {
534 	u8 bp;
535 	ssize_t rlen;
536 
537 	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_LINK_RATE,	&bp);
538 	if (rlen < 0) {
539 		DRM_ERROR("failed to read link rate. rlen=%zd\n", rlen);
540 		return rlen;
541 	}
542 
543 	if (!is_link_rate_valid(bp)) {
544 		DRM_ERROR("invalid link rate = 0x%x\n", bp);
545 		return -EINVAL;
546 	}
547 
548 	link->request.test_link_rate = bp;
549 	drm_dbg_dp(link->drm_dev, "link rate = 0x%x\n",
550 				link->request.test_link_rate);
551 
552 	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_LANE_COUNT, &bp);
553 	if (rlen < 0) {
554 		DRM_ERROR("failed to read lane count. rlen=%zd\n", rlen);
555 		return rlen;
556 	}
557 	bp &= DP_MAX_LANE_COUNT_MASK;
558 
559 	if (!is_lane_count_valid(bp)) {
560 		DRM_ERROR("invalid lane count = 0x%x\n", bp);
561 		return -EINVAL;
562 	}
563 
564 	link->request.test_lane_count = bp;
565 	drm_dbg_dp(link->drm_dev, "lane count = 0x%x\n",
566 				link->request.test_lane_count);
567 	return 0;
568 }
569 
570 /**
571  * dp_link_parse_phy_test_params() - parses the phy link parameters
572  * @link: Display Port Driver data
573  *
574  * Parses the DPCD (Byte 0x248) for the DP PHY link pattern that is being
575  * requested.
576  */
577 static int dp_link_parse_phy_test_params(struct dp_link_private *link)
578 {
579 	u8 data;
580 	ssize_t rlen;
581 
582 	rlen = drm_dp_dpcd_readb(link->aux, DP_PHY_TEST_PATTERN,
583 					&data);
584 	if (rlen < 0) {
585 		DRM_ERROR("failed to read phy link pattern. rlen=%zd\n", rlen);
586 		return rlen;
587 	}
588 
589 	link->dp_link.phy_params.phy_test_pattern_sel = data & 0x07;
590 
591 	drm_dbg_dp(link->drm_dev, "phy_test_pattern_sel = 0x%x\n", data);
592 
593 	switch (data) {
594 	case DP_PHY_TEST_PATTERN_SEL_MASK:
595 	case DP_PHY_TEST_PATTERN_NONE:
596 	case DP_PHY_TEST_PATTERN_D10_2:
597 	case DP_PHY_TEST_PATTERN_ERROR_COUNT:
598 	case DP_PHY_TEST_PATTERN_PRBS7:
599 	case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
600 	case DP_PHY_TEST_PATTERN_CP2520:
601 		return 0;
602 	default:
603 		return -EINVAL;
604 	}
605 }
606 
607 /**
608  * dp_link_is_video_audio_test_requested() - checks for audio/video link request
609  * @link: link requested by the sink
610  *
611  * Returns true if the requested link is a permitted audio/video link.
612  */
613 static bool dp_link_is_video_audio_test_requested(u32 link)
614 {
615 	u8 video_audio_test = (DP_TEST_LINK_VIDEO_PATTERN |
616 				DP_TEST_LINK_AUDIO_PATTERN |
617 				DP_TEST_LINK_AUDIO_DISABLED_VIDEO);
618 
619 	return ((link & video_audio_test) &&
620 		!(link & ~video_audio_test));
621 }
622 
623 /**
624  * dp_link_parse_request() - parses link request parameters from sink
625  * @link: Display Port Driver data
626  *
627  * Parses the DPCD to check if an automated link is requested (Byte 0x201),
628  * and what type of link automation is being requested (Byte 0x218).
629  */
630 static int dp_link_parse_request(struct dp_link_private *link)
631 {
632 	int ret = 0;
633 	u8 data;
634 	ssize_t rlen;
635 
636 	/**
637 	 * Read the device service IRQ vector (Byte 0x201) to determine
638 	 * whether an automated link has been requested by the sink.
639 	 */
640 	rlen = drm_dp_dpcd_readb(link->aux,
641 				DP_DEVICE_SERVICE_IRQ_VECTOR, &data);
642 	if (rlen < 0) {
643 		DRM_ERROR("aux read failed. rlen=%zd\n", rlen);
644 		return rlen;
645 	}
646 
647 	drm_dbg_dp(link->drm_dev, "device service irq vector = 0x%x\n", data);
648 
649 	if (!(data & DP_AUTOMATED_TEST_REQUEST)) {
650 		drm_dbg_dp(link->drm_dev, "no test requested\n");
651 		return 0;
652 	}
653 
654 	/**
655 	 * Read the link request byte (Byte 0x218) to determine what type
656 	 * of automated link has been requested by the sink.
657 	 */
658 	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_REQUEST, &data);
659 	if (rlen < 0) {
660 		DRM_ERROR("aux read failed. rlen=%zd\n", rlen);
661 		return rlen;
662 	}
663 
664 	if (!data || (data == DP_TEST_LINK_FAUX_PATTERN)) {
665 		drm_dbg_dp(link->drm_dev, "link 0x%x not supported\n", data);
666 		goto end;
667 	}
668 
669 	drm_dbg_dp(link->drm_dev, "Test:(0x%x) requested\n", data);
670 	link->request.test_requested = data;
671 	if (link->request.test_requested == DP_TEST_LINK_PHY_TEST_PATTERN) {
672 		ret = dp_link_parse_phy_test_params(link);
673 		if (ret)
674 			goto end;
675 		ret = dp_link_parse_link_training_params(link);
676 		if (ret)
677 			goto end;
678 	}
679 
680 	if (link->request.test_requested == DP_TEST_LINK_TRAINING) {
681 		ret = dp_link_parse_link_training_params(link);
682 		if (ret)
683 			goto end;
684 	}
685 
686 	if (dp_link_is_video_audio_test_requested(
687 			link->request.test_requested)) {
688 		ret = dp_link_parse_video_pattern_params(link);
689 		if (ret)
690 			goto end;
691 
692 		ret = dp_link_parse_audio_pattern_params(link);
693 	}
694 end:
695 	/*
696 	 * Send a DP_TEST_ACK if all link parameters are valid, otherwise send
697 	 * a DP_TEST_NAK.
698 	 */
699 	if (ret) {
700 		link->dp_link.test_response = DP_TEST_NAK;
701 	} else {
702 		if (link->request.test_requested != DP_TEST_LINK_EDID_READ)
703 			link->dp_link.test_response = DP_TEST_ACK;
704 		else
705 			link->dp_link.test_response =
706 				DP_TEST_EDID_CHECKSUM_WRITE;
707 	}
708 
709 	return ret;
710 }
711 
712 /**
713  * dp_link_parse_sink_count() - parses the sink count
714  * @dp_link: pointer to link module data
715  *
716  * Parses the DPCD to check if there is an update to the sink count
717  * (Byte 0x200), and whether all the sink devices connected have Content
718  * Protection enabled.
719  */
720 static int dp_link_parse_sink_count(struct dp_link *dp_link)
721 {
722 	ssize_t rlen;
723 	bool cp_ready;
724 
725 	struct dp_link_private *link = container_of(dp_link,
726 			struct dp_link_private, dp_link);
727 
728 	rlen = drm_dp_dpcd_readb(link->aux, DP_SINK_COUNT,
729 				 &link->dp_link.sink_count);
730 	if (rlen < 0) {
731 		DRM_ERROR("sink count read failed. rlen=%zd\n", rlen);
732 		return rlen;
733 	}
734 
735 	cp_ready = link->dp_link.sink_count & DP_SINK_CP_READY;
736 
737 	link->dp_link.sink_count =
738 		DP_GET_SINK_COUNT(link->dp_link.sink_count);
739 
740 	drm_dbg_dp(link->drm_dev, "sink_count = 0x%x, cp_ready = 0x%x\n",
741 				link->dp_link.sink_count, cp_ready);
742 	return 0;
743 }
744 
745 static int dp_link_parse_sink_status_field(struct dp_link_private *link)
746 {
747 	int len = 0;
748 
749 	link->prev_sink_count = link->dp_link.sink_count;
750 	len = dp_link_parse_sink_count(&link->dp_link);
751 	if (len < 0) {
752 		DRM_ERROR("DP parse sink count failed\n");
753 		return len;
754 	}
755 
756 	len = drm_dp_dpcd_read_link_status(link->aux,
757 		link->link_status);
758 	if (len < DP_LINK_STATUS_SIZE) {
759 		DRM_ERROR("DP link status read failed\n");
760 		return len;
761 	}
762 
763 	return dp_link_parse_request(link);
764 }
765 
766 /**
767  * dp_link_process_link_training_request() - processes new training requests
768  * @link: Display Port link data
769  *
770  * This function will handle new link training requests that are initiated by
771  * the sink. In particular, it will update the requested lane count and link
772  * rate, and then trigger the link retraining procedure.
773  *
774  * The function will return 0 if a link training request has been processed,
775  * otherwise it will return -EINVAL.
776  */
777 static int dp_link_process_link_training_request(struct dp_link_private *link)
778 {
779 	if (link->request.test_requested != DP_TEST_LINK_TRAINING)
780 		return -EINVAL;
781 
782 	drm_dbg_dp(link->drm_dev,
783 			"Test:0x%x link rate = 0x%x, lane count = 0x%x\n",
784 			DP_TEST_LINK_TRAINING,
785 			link->request.test_link_rate,
786 			link->request.test_lane_count);
787 
788 	link->dp_link.link_params.num_lanes = link->request.test_lane_count;
789 	link->dp_link.link_params.rate =
790 		drm_dp_bw_code_to_link_rate(link->request.test_link_rate);
791 
792 	return 0;
793 }
794 
795 bool dp_link_send_test_response(struct dp_link *dp_link)
796 {
797 	struct dp_link_private *link = NULL;
798 	int ret = 0;
799 
800 	if (!dp_link) {
801 		DRM_ERROR("invalid input\n");
802 		return false;
803 	}
804 
805 	link = container_of(dp_link, struct dp_link_private, dp_link);
806 
807 	ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_RESPONSE,
808 			dp_link->test_response);
809 
810 	return ret == 1;
811 }
812 
813 int dp_link_psm_config(struct dp_link *dp_link,
814 			      struct dp_link_info *link_info, bool enable)
815 {
816 	struct dp_link_private *link = NULL;
817 	int ret = 0;
818 
819 	if (!dp_link) {
820 		DRM_ERROR("invalid params\n");
821 		return -EINVAL;
822 	}
823 
824 	link = container_of(dp_link, struct dp_link_private, dp_link);
825 
826 	mutex_lock(&link->psm_mutex);
827 	if (enable)
828 		ret = dp_aux_link_power_down(link->aux, link_info);
829 	else
830 		ret = dp_aux_link_power_up(link->aux, link_info);
831 
832 	if (ret)
833 		DRM_ERROR("Failed to %s low power mode\n", enable ?
834 							"enter" : "exit");
835 	else
836 		dp_link->psm_enabled = enable;
837 
838 	mutex_unlock(&link->psm_mutex);
839 	return ret;
840 }
841 
842 bool dp_link_send_edid_checksum(struct dp_link *dp_link, u8 checksum)
843 {
844 	struct dp_link_private *link = NULL;
845 	int ret = 0;
846 
847 	if (!dp_link) {
848 		DRM_ERROR("invalid input\n");
849 		return false;
850 	}
851 
852 	link = container_of(dp_link, struct dp_link_private, dp_link);
853 
854 	ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_EDID_CHECKSUM,
855 						checksum);
856 	return ret == 1;
857 }
858 
859 static void dp_link_parse_vx_px(struct dp_link_private *link)
860 {
861 	drm_dbg_dp(link->drm_dev, "vx: 0=%d, 1=%d, 2=%d, 3=%d\n",
862 		drm_dp_get_adjust_request_voltage(link->link_status, 0),
863 		drm_dp_get_adjust_request_voltage(link->link_status, 1),
864 		drm_dp_get_adjust_request_voltage(link->link_status, 2),
865 		drm_dp_get_adjust_request_voltage(link->link_status, 3));
866 
867 	drm_dbg_dp(link->drm_dev, "px: 0=%d, 1=%d, 2=%d, 3=%d\n",
868 		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 0),
869 		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 1),
870 		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 2),
871 		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 3));
872 
873 	/**
874 	 * Update the voltage and pre-emphasis levels as per DPCD request
875 	 * vector.
876 	 */
877 	drm_dbg_dp(link->drm_dev,
878 			 "Current: v_level = 0x%x, p_level = 0x%x\n",
879 			link->dp_link.phy_params.v_level,
880 			link->dp_link.phy_params.p_level);
881 	link->dp_link.phy_params.v_level =
882 		drm_dp_get_adjust_request_voltage(link->link_status, 0);
883 	link->dp_link.phy_params.p_level =
884 		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 0);
885 
886 	link->dp_link.phy_params.p_level >>= DP_TRAIN_PRE_EMPHASIS_SHIFT;
887 
888 	drm_dbg_dp(link->drm_dev,
889 			"Requested: v_level = 0x%x, p_level = 0x%x\n",
890 			link->dp_link.phy_params.v_level,
891 			link->dp_link.phy_params.p_level);
892 }
893 
894 /**
895  * dp_link_process_phy_test_pattern_request() - process new phy link requests
896  * @link: Display Port Driver data
897  *
898  * This function will handle new phy link pattern requests that are initiated
899  * by the sink. The function will return 0 if a phy link pattern has been
900  * processed, otherwise it will return -EINVAL.
901  */
902 static int dp_link_process_phy_test_pattern_request(
903 		struct dp_link_private *link)
904 {
905 	if (!(link->request.test_requested & DP_TEST_LINK_PHY_TEST_PATTERN)) {
906 		drm_dbg_dp(link->drm_dev, "no phy test\n");
907 		return -EINVAL;
908 	}
909 
910 	if (!is_link_rate_valid(link->request.test_link_rate) ||
911 		!is_lane_count_valid(link->request.test_lane_count)) {
912 		DRM_ERROR("Invalid: link rate = 0x%x,lane count = 0x%x\n",
913 				link->request.test_link_rate,
914 				link->request.test_lane_count);
915 		return -EINVAL;
916 	}
917 
918 	drm_dbg_dp(link->drm_dev,
919 			"Current: rate = 0x%x, lane count = 0x%x\n",
920 			link->dp_link.link_params.rate,
921 			link->dp_link.link_params.num_lanes);
922 
923 	drm_dbg_dp(link->drm_dev,
924 			"Requested: rate = 0x%x, lane count = 0x%x\n",
925 			link->request.test_link_rate,
926 			link->request.test_lane_count);
927 
928 	link->dp_link.link_params.num_lanes = link->request.test_lane_count;
929 	link->dp_link.link_params.rate =
930 		drm_dp_bw_code_to_link_rate(link->request.test_link_rate);
931 
932 	dp_link_parse_vx_px(link);
933 
934 	return 0;
935 }
936 
937 static u8 get_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
938 {
939 	return link_status[r - DP_LANE0_1_STATUS];
940 }
941 
942 /**
943  * dp_link_process_link_status_update() - processes link status updates
944  * @link: Display Port link module data
945  *
946  * This function will check for changes in the link status, e.g. clock
947  * recovery done on all lanes, and trigger link training if there is a
948  * failure/error on the link.
949  *
950  * The function will return 0 if the a link status update has been processed,
951  * otherwise it will return -EINVAL.
952  */
953 static int dp_link_process_link_status_update(struct dp_link_private *link)
954 {
955 	bool channel_eq_done = drm_dp_channel_eq_ok(link->link_status,
956 			link->dp_link.link_params.num_lanes);
957 
958 	bool clock_recovery_done = drm_dp_clock_recovery_ok(link->link_status,
959 			link->dp_link.link_params.num_lanes);
960 
961 	drm_dbg_dp(link->drm_dev,
962 		       "channel_eq_done = %d, clock_recovery_done = %d\n",
963                         channel_eq_done, clock_recovery_done);
964 
965 	if (channel_eq_done && clock_recovery_done)
966 		return -EINVAL;
967 
968 
969        return 0;
970 }
971 
972 /**
973  * dp_link_process_ds_port_status_change() - process port status changes
974  * @link: Display Port Driver data
975  *
976  * This function will handle downstream port updates that are initiated by
977  * the sink. If the downstream port status has changed, the EDID is read via
978  * AUX.
979  *
980  * The function will return 0 if a downstream port update has been
981  * processed, otherwise it will return -EINVAL.
982  */
983 static int dp_link_process_ds_port_status_change(struct dp_link_private *link)
984 {
985 	if (get_link_status(link->link_status, DP_LANE_ALIGN_STATUS_UPDATED) &
986 					DP_DOWNSTREAM_PORT_STATUS_CHANGED)
987 		goto reset;
988 
989 	if (link->prev_sink_count == link->dp_link.sink_count)
990 		return -EINVAL;
991 
992 reset:
993 	/* reset prev_sink_count */
994 	link->prev_sink_count = link->dp_link.sink_count;
995 
996 	return 0;
997 }
998 
999 static bool dp_link_is_video_pattern_requested(struct dp_link_private *link)
1000 {
1001 	return (link->request.test_requested & DP_TEST_LINK_VIDEO_PATTERN)
1002 		&& !(link->request.test_requested &
1003 		DP_TEST_LINK_AUDIO_DISABLED_VIDEO);
1004 }
1005 
1006 static bool dp_link_is_audio_pattern_requested(struct dp_link_private *link)
1007 {
1008 	return (link->request.test_requested & DP_TEST_LINK_AUDIO_PATTERN);
1009 }
1010 
1011 static void dp_link_reset_data(struct dp_link_private *link)
1012 {
1013 	link->request = (const struct dp_link_request){ 0 };
1014 	link->dp_link.test_video = (const struct dp_link_test_video){ 0 };
1015 	link->dp_link.test_video.test_bit_depth = DP_TEST_BIT_DEPTH_UNKNOWN;
1016 	link->dp_link.test_audio = (const struct dp_link_test_audio){ 0 };
1017 	link->dp_link.phy_params.phy_test_pattern_sel = 0;
1018 	link->dp_link.sink_request = 0;
1019 	link->dp_link.test_response = 0;
1020 }
1021 
1022 /**
1023  * dp_link_process_request() - handle HPD IRQ transition to HIGH
1024  * @dp_link: pointer to link module data
1025  *
1026  * This function will handle the HPD IRQ state transitions from LOW to HIGH
1027  * (including cases when there are back to back HPD IRQ HIGH) indicating
1028  * the start of a new link training request or sink status update.
1029  */
1030 int dp_link_process_request(struct dp_link *dp_link)
1031 {
1032 	int ret = 0;
1033 	struct dp_link_private *link;
1034 
1035 	if (!dp_link) {
1036 		DRM_ERROR("invalid input\n");
1037 		return -EINVAL;
1038 	}
1039 
1040 	link = container_of(dp_link, struct dp_link_private, dp_link);
1041 
1042 	dp_link_reset_data(link);
1043 
1044 	ret = dp_link_parse_sink_status_field(link);
1045 	if (ret)
1046 		return ret;
1047 
1048 	if (link->request.test_requested == DP_TEST_LINK_EDID_READ) {
1049 		dp_link->sink_request |= DP_TEST_LINK_EDID_READ;
1050 	} else if (!dp_link_process_ds_port_status_change(link)) {
1051 		dp_link->sink_request |= DS_PORT_STATUS_CHANGED;
1052 	} else if (!dp_link_process_link_training_request(link)) {
1053 		dp_link->sink_request |= DP_TEST_LINK_TRAINING;
1054 	} else if (!dp_link_process_phy_test_pattern_request(link)) {
1055 		dp_link->sink_request |= DP_TEST_LINK_PHY_TEST_PATTERN;
1056 	} else {
1057 		ret = dp_link_process_link_status_update(link);
1058 		if (!ret) {
1059 			dp_link->sink_request |= DP_LINK_STATUS_UPDATED;
1060 		} else {
1061 			if (dp_link_is_video_pattern_requested(link)) {
1062 				ret = 0;
1063 				dp_link->sink_request |= DP_TEST_LINK_VIDEO_PATTERN;
1064 			}
1065 			if (dp_link_is_audio_pattern_requested(link)) {
1066 				dp_link->sink_request |= DP_TEST_LINK_AUDIO_PATTERN;
1067 				ret = -EINVAL;
1068 			}
1069 		}
1070 	}
1071 
1072 	drm_dbg_dp(link->drm_dev, "sink request=%#x",
1073 				dp_link->sink_request);
1074 	return ret;
1075 }
1076 
1077 int dp_link_get_colorimetry_config(struct dp_link *dp_link)
1078 {
1079 	u32 cc;
1080 	struct dp_link_private *link;
1081 
1082 	if (!dp_link) {
1083 		DRM_ERROR("invalid input\n");
1084 		return -EINVAL;
1085 	}
1086 
1087 	link = container_of(dp_link, struct dp_link_private, dp_link);
1088 
1089 	/*
1090 	 * Unless a video pattern CTS test is ongoing, use RGB_VESA
1091 	 * Only RGB_VESA and RGB_CEA supported for now
1092 	 */
1093 	if (dp_link_is_video_pattern_requested(link))
1094 		cc = link->dp_link.test_video.test_dyn_range;
1095 	else
1096 		cc = DP_TEST_DYNAMIC_RANGE_VESA;
1097 
1098 	return cc;
1099 }
1100 
1101 int dp_link_adjust_levels(struct dp_link *dp_link, u8 *link_status)
1102 {
1103 	int i;
1104 	int v_max = 0, p_max = 0;
1105 	struct dp_link_private *link;
1106 
1107 	if (!dp_link) {
1108 		DRM_ERROR("invalid input\n");
1109 		return -EINVAL;
1110 	}
1111 
1112 	link = container_of(dp_link, struct dp_link_private, dp_link);
1113 
1114 	/* use the max level across lanes */
1115 	for (i = 0; i < dp_link->link_params.num_lanes; i++) {
1116 		u8 data_v = drm_dp_get_adjust_request_voltage(link_status, i);
1117 		u8 data_p = drm_dp_get_adjust_request_pre_emphasis(link_status,
1118 									 i);
1119 		drm_dbg_dp(link->drm_dev,
1120 				"lane=%d req_vol_swing=%d req_pre_emphasis=%d\n",
1121 				i, data_v, data_p);
1122 		if (v_max < data_v)
1123 			v_max = data_v;
1124 		if (p_max < data_p)
1125 			p_max = data_p;
1126 	}
1127 
1128 	dp_link->phy_params.v_level = v_max >> DP_TRAIN_VOLTAGE_SWING_SHIFT;
1129 	dp_link->phy_params.p_level = p_max >> DP_TRAIN_PRE_EMPHASIS_SHIFT;
1130 
1131 	/**
1132 	 * Adjust the voltage swing and pre-emphasis level combination to within
1133 	 * the allowable range.
1134 	 */
1135 	if (dp_link->phy_params.v_level > DP_TRAIN_VOLTAGE_SWING_MAX) {
1136 		drm_dbg_dp(link->drm_dev,
1137 			"Requested vSwingLevel=%d, change to %d\n",
1138 			dp_link->phy_params.v_level,
1139 			DP_TRAIN_VOLTAGE_SWING_MAX);
1140 		dp_link->phy_params.v_level = DP_TRAIN_VOLTAGE_SWING_MAX;
1141 	}
1142 
1143 	if (dp_link->phy_params.p_level > DP_TRAIN_PRE_EMPHASIS_MAX) {
1144 		drm_dbg_dp(link->drm_dev,
1145 			"Requested preEmphasisLevel=%d, change to %d\n",
1146 			dp_link->phy_params.p_level,
1147 			DP_TRAIN_PRE_EMPHASIS_MAX);
1148 		dp_link->phy_params.p_level = DP_TRAIN_PRE_EMPHASIS_MAX;
1149 	}
1150 
1151 	if ((dp_link->phy_params.p_level > DP_TRAIN_PRE_EMPHASIS_LVL_1)
1152 		&& (dp_link->phy_params.v_level ==
1153 			DP_TRAIN_VOLTAGE_SWING_LVL_2)) {
1154 		drm_dbg_dp(link->drm_dev,
1155 			"Requested preEmphasisLevel=%d, change to %d\n",
1156 			dp_link->phy_params.p_level,
1157 			DP_TRAIN_PRE_EMPHASIS_LVL_1);
1158 		dp_link->phy_params.p_level = DP_TRAIN_PRE_EMPHASIS_LVL_1;
1159 	}
1160 
1161 	drm_dbg_dp(link->drm_dev, "adjusted: v_level=%d, p_level=%d\n",
1162 		dp_link->phy_params.v_level, dp_link->phy_params.p_level);
1163 
1164 	return 0;
1165 }
1166 
1167 void dp_link_reset_phy_params_vx_px(struct dp_link *dp_link)
1168 {
1169 	dp_link->phy_params.v_level = 0;
1170 	dp_link->phy_params.p_level = 0;
1171 }
1172 
1173 u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp)
1174 {
1175 	u32 tbd;
1176 
1177 	/*
1178 	 * Few simplistic rules and assumptions made here:
1179 	 *    1. Test bit depth is bit depth per color component
1180 	 *    2. Assume 3 color components
1181 	 */
1182 	switch (bpp) {
1183 	case 18:
1184 		tbd = DP_TEST_BIT_DEPTH_6;
1185 		break;
1186 	case 24:
1187 		tbd = DP_TEST_BIT_DEPTH_8;
1188 		break;
1189 	case 30:
1190 		tbd = DP_TEST_BIT_DEPTH_10;
1191 		break;
1192 	default:
1193 		tbd = DP_TEST_BIT_DEPTH_UNKNOWN;
1194 		break;
1195 	}
1196 
1197 	if (tbd != DP_TEST_BIT_DEPTH_UNKNOWN)
1198 		tbd = (tbd >> DP_TEST_BIT_DEPTH_SHIFT);
1199 
1200 	return tbd;
1201 }
1202 
1203 struct dp_link *dp_link_get(struct device *dev, struct drm_dp_aux *aux)
1204 {
1205 	struct dp_link_private *link;
1206 	struct dp_link *dp_link;
1207 
1208 	if (!dev || !aux) {
1209 		DRM_ERROR("invalid input\n");
1210 		return ERR_PTR(-EINVAL);
1211 	}
1212 
1213 	link = devm_kzalloc(dev, sizeof(*link), GFP_KERNEL);
1214 	if (!link)
1215 		return ERR_PTR(-ENOMEM);
1216 
1217 	link->dev   = dev;
1218 	link->aux   = aux;
1219 
1220 	mutex_init(&link->psm_mutex);
1221 	dp_link = &link->dp_link;
1222 
1223 	return dp_link;
1224 }
1225