xref: /openbmc/linux/drivers/gpu/drm/msm/dp/dp_link.c (revision 85250a24)
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 	return 0;
969 }
970 
971 /**
972  * dp_link_process_ds_port_status_change() - process port status changes
973  * @link: Display Port Driver data
974  *
975  * This function will handle downstream port updates that are initiated by
976  * the sink. If the downstream port status has changed, the EDID is read via
977  * AUX.
978  *
979  * The function will return 0 if a downstream port update has been
980  * processed, otherwise it will return -EINVAL.
981  */
982 static int dp_link_process_ds_port_status_change(struct dp_link_private *link)
983 {
984 	if (get_link_status(link->link_status, DP_LANE_ALIGN_STATUS_UPDATED) &
985 					DP_DOWNSTREAM_PORT_STATUS_CHANGED)
986 		goto reset;
987 
988 	if (link->prev_sink_count == link->dp_link.sink_count)
989 		return -EINVAL;
990 
991 reset:
992 	/* reset prev_sink_count */
993 	link->prev_sink_count = link->dp_link.sink_count;
994 
995 	return 0;
996 }
997 
998 static bool dp_link_is_video_pattern_requested(struct dp_link_private *link)
999 {
1000 	return (link->request.test_requested & DP_TEST_LINK_VIDEO_PATTERN)
1001 		&& !(link->request.test_requested &
1002 		DP_TEST_LINK_AUDIO_DISABLED_VIDEO);
1003 }
1004 
1005 static bool dp_link_is_audio_pattern_requested(struct dp_link_private *link)
1006 {
1007 	return (link->request.test_requested & DP_TEST_LINK_AUDIO_PATTERN);
1008 }
1009 
1010 static void dp_link_reset_data(struct dp_link_private *link)
1011 {
1012 	link->request = (const struct dp_link_request){ 0 };
1013 	link->dp_link.test_video = (const struct dp_link_test_video){ 0 };
1014 	link->dp_link.test_video.test_bit_depth = DP_TEST_BIT_DEPTH_UNKNOWN;
1015 	link->dp_link.test_audio = (const struct dp_link_test_audio){ 0 };
1016 	link->dp_link.phy_params.phy_test_pattern_sel = 0;
1017 	link->dp_link.sink_request = 0;
1018 	link->dp_link.test_response = 0;
1019 }
1020 
1021 /**
1022  * dp_link_process_request() - handle HPD IRQ transition to HIGH
1023  * @dp_link: pointer to link module data
1024  *
1025  * This function will handle the HPD IRQ state transitions from LOW to HIGH
1026  * (including cases when there are back to back HPD IRQ HIGH) indicating
1027  * the start of a new link training request or sink status update.
1028  */
1029 int dp_link_process_request(struct dp_link *dp_link)
1030 {
1031 	int ret = 0;
1032 	struct dp_link_private *link;
1033 
1034 	if (!dp_link) {
1035 		DRM_ERROR("invalid input\n");
1036 		return -EINVAL;
1037 	}
1038 
1039 	link = container_of(dp_link, struct dp_link_private, dp_link);
1040 
1041 	dp_link_reset_data(link);
1042 
1043 	ret = dp_link_parse_sink_status_field(link);
1044 	if (ret)
1045 		return ret;
1046 
1047 	if (link->request.test_requested == DP_TEST_LINK_EDID_READ) {
1048 		dp_link->sink_request |= DP_TEST_LINK_EDID_READ;
1049 	} else if (!dp_link_process_ds_port_status_change(link)) {
1050 		dp_link->sink_request |= DS_PORT_STATUS_CHANGED;
1051 	} else if (!dp_link_process_link_training_request(link)) {
1052 		dp_link->sink_request |= DP_TEST_LINK_TRAINING;
1053 	} else if (!dp_link_process_phy_test_pattern_request(link)) {
1054 		dp_link->sink_request |= DP_TEST_LINK_PHY_TEST_PATTERN;
1055 	} else {
1056 		ret = dp_link_process_link_status_update(link);
1057 		if (!ret) {
1058 			dp_link->sink_request |= DP_LINK_STATUS_UPDATED;
1059 		} else {
1060 			if (dp_link_is_video_pattern_requested(link)) {
1061 				ret = 0;
1062 				dp_link->sink_request |= DP_TEST_LINK_VIDEO_PATTERN;
1063 			}
1064 			if (dp_link_is_audio_pattern_requested(link)) {
1065 				dp_link->sink_request |= DP_TEST_LINK_AUDIO_PATTERN;
1066 				ret = -EINVAL;
1067 			}
1068 		}
1069 	}
1070 
1071 	drm_dbg_dp(link->drm_dev, "sink request=%#x",
1072 				dp_link->sink_request);
1073 	return ret;
1074 }
1075 
1076 int dp_link_get_colorimetry_config(struct dp_link *dp_link)
1077 {
1078 	u32 cc;
1079 	struct dp_link_private *link;
1080 
1081 	if (!dp_link) {
1082 		DRM_ERROR("invalid input\n");
1083 		return -EINVAL;
1084 	}
1085 
1086 	link = container_of(dp_link, struct dp_link_private, dp_link);
1087 
1088 	/*
1089 	 * Unless a video pattern CTS test is ongoing, use RGB_VESA
1090 	 * Only RGB_VESA and RGB_CEA supported for now
1091 	 */
1092 	if (dp_link_is_video_pattern_requested(link))
1093 		cc = link->dp_link.test_video.test_dyn_range;
1094 	else
1095 		cc = DP_TEST_DYNAMIC_RANGE_VESA;
1096 
1097 	return cc;
1098 }
1099 
1100 int dp_link_adjust_levels(struct dp_link *dp_link, u8 *link_status)
1101 {
1102 	int i;
1103 	int v_max = 0, p_max = 0;
1104 	struct dp_link_private *link;
1105 
1106 	if (!dp_link) {
1107 		DRM_ERROR("invalid input\n");
1108 		return -EINVAL;
1109 	}
1110 
1111 	link = container_of(dp_link, struct dp_link_private, dp_link);
1112 
1113 	/* use the max level across lanes */
1114 	for (i = 0; i < dp_link->link_params.num_lanes; i++) {
1115 		u8 data_v = drm_dp_get_adjust_request_voltage(link_status, i);
1116 		u8 data_p = drm_dp_get_adjust_request_pre_emphasis(link_status,
1117 									 i);
1118 		drm_dbg_dp(link->drm_dev,
1119 				"lane=%d req_vol_swing=%d req_pre_emphasis=%d\n",
1120 				i, data_v, data_p);
1121 		if (v_max < data_v)
1122 			v_max = data_v;
1123 		if (p_max < data_p)
1124 			p_max = data_p;
1125 	}
1126 
1127 	dp_link->phy_params.v_level = v_max >> DP_TRAIN_VOLTAGE_SWING_SHIFT;
1128 	dp_link->phy_params.p_level = p_max >> DP_TRAIN_PRE_EMPHASIS_SHIFT;
1129 
1130 	/**
1131 	 * Adjust the voltage swing and pre-emphasis level combination to within
1132 	 * the allowable range.
1133 	 */
1134 	if (dp_link->phy_params.v_level > DP_TRAIN_VOLTAGE_SWING_MAX) {
1135 		drm_dbg_dp(link->drm_dev,
1136 			"Requested vSwingLevel=%d, change to %d\n",
1137 			dp_link->phy_params.v_level,
1138 			DP_TRAIN_VOLTAGE_SWING_MAX);
1139 		dp_link->phy_params.v_level = DP_TRAIN_VOLTAGE_SWING_MAX;
1140 	}
1141 
1142 	if (dp_link->phy_params.p_level > DP_TRAIN_PRE_EMPHASIS_MAX) {
1143 		drm_dbg_dp(link->drm_dev,
1144 			"Requested preEmphasisLevel=%d, change to %d\n",
1145 			dp_link->phy_params.p_level,
1146 			DP_TRAIN_PRE_EMPHASIS_MAX);
1147 		dp_link->phy_params.p_level = DP_TRAIN_PRE_EMPHASIS_MAX;
1148 	}
1149 
1150 	if ((dp_link->phy_params.p_level > DP_TRAIN_PRE_EMPHASIS_LVL_1)
1151 		&& (dp_link->phy_params.v_level ==
1152 			DP_TRAIN_VOLTAGE_SWING_LVL_2)) {
1153 		drm_dbg_dp(link->drm_dev,
1154 			"Requested preEmphasisLevel=%d, change to %d\n",
1155 			dp_link->phy_params.p_level,
1156 			DP_TRAIN_PRE_EMPHASIS_LVL_1);
1157 		dp_link->phy_params.p_level = DP_TRAIN_PRE_EMPHASIS_LVL_1;
1158 	}
1159 
1160 	drm_dbg_dp(link->drm_dev, "adjusted: v_level=%d, p_level=%d\n",
1161 		dp_link->phy_params.v_level, dp_link->phy_params.p_level);
1162 
1163 	return 0;
1164 }
1165 
1166 void dp_link_reset_phy_params_vx_px(struct dp_link *dp_link)
1167 {
1168 	dp_link->phy_params.v_level = 0;
1169 	dp_link->phy_params.p_level = 0;
1170 }
1171 
1172 u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp)
1173 {
1174 	u32 tbd;
1175 
1176 	/*
1177 	 * Few simplistic rules and assumptions made here:
1178 	 *    1. Test bit depth is bit depth per color component
1179 	 *    2. Assume 3 color components
1180 	 */
1181 	switch (bpp) {
1182 	case 18:
1183 		tbd = DP_TEST_BIT_DEPTH_6;
1184 		break;
1185 	case 24:
1186 		tbd = DP_TEST_BIT_DEPTH_8;
1187 		break;
1188 	case 30:
1189 		tbd = DP_TEST_BIT_DEPTH_10;
1190 		break;
1191 	default:
1192 		tbd = DP_TEST_BIT_DEPTH_UNKNOWN;
1193 		break;
1194 	}
1195 
1196 	if (tbd != DP_TEST_BIT_DEPTH_UNKNOWN)
1197 		tbd = (tbd >> DP_TEST_BIT_DEPTH_SHIFT);
1198 
1199 	return tbd;
1200 }
1201 
1202 struct dp_link *dp_link_get(struct device *dev, struct drm_dp_aux *aux)
1203 {
1204 	struct dp_link_private *link;
1205 	struct dp_link *dp_link;
1206 
1207 	if (!dev || !aux) {
1208 		DRM_ERROR("invalid input\n");
1209 		return ERR_PTR(-EINVAL);
1210 	}
1211 
1212 	link = devm_kzalloc(dev, sizeof(*link), GFP_KERNEL);
1213 	if (!link)
1214 		return ERR_PTR(-ENOMEM);
1215 
1216 	link->dev   = dev;
1217 	link->aux   = aux;
1218 
1219 	mutex_init(&link->psm_mutex);
1220 	dp_link = &link->dp_link;
1221 
1222 	return dp_link;
1223 }
1224