xref: /linux/drivers/gpu/drm/i915/display/intel_dp_test.c (revision 570f7e331f5febb30f1384817463c7e42b65ca7d)
1 // SPDX-License-Identifier: MIT
2 /* Copyright © 2024 Intel Corporation */
3 
4 #include <linux/debugfs.h>
5 
6 #include <drm/display/drm_dp.h>
7 #include <drm/display/drm_dp_helper.h>
8 #include <drm/drm_edid.h>
9 #include <drm/drm_print.h>
10 #include <drm/drm_probe_helper.h>
11 
12 #include "intel_ddi.h"
13 #include "intel_de.h"
14 #include "intel_display_regs.h"
15 #include "intel_display_types.h"
16 #include "intel_dp.h"
17 #include "intel_dp_link_caps.h"
18 #include "intel_dp_link_training.h"
19 #include "intel_dp_mst.h"
20 #include "intel_dp_test.h"
21 
22 void intel_dp_test_reset(struct intel_dp *intel_dp)
23 {
24 	/*
25 	 * Clearing compliance test variables to allow capturing
26 	 * of values for next automated test request.
27 	 */
28 	memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance));
29 }
30 
31 static bool set_filter_for_lane_count(struct intel_connector *connector,
32 				      struct intel_dp_link_caps *link_caps,
33 				      int lane_count,
34 				      struct link_config_limits *limits)
35 {
36 	struct intel_dp_link_config link_config;
37 	struct intel_dp_link_caps_order order =
38 		intel_dp_link_caps_connector_compute_order(connector);
39 	struct intel_dp_link_caps_filter new_filter = INTEL_DP_LINK_CAPS_FILTER_NONE;
40 	struct intel_dp_link_caps_iter iter;
41 	bool found = false;
42 
43 	intel_dp_link_caps_iter_start(&iter, link_caps, order, limits->link_config_filter);
44 	for_each_dp_link_config(&iter, &link_config) {
45 		if (link_config.lane_count != lane_count)
46 			continue;
47 
48 		intel_dp_link_caps_filter_add(link_caps, &new_filter, &link_config);
49 		found = true;
50 	}
51 	intel_dp_link_caps_iter_end(&iter);
52 
53 	if (!found)
54 		return false;
55 
56 	limits->link_config_filter = new_filter;
57 
58 	return true;
59 }
60 
61 static bool set_filter_for_link_config(struct intel_connector *connector,
62 				       struct intel_dp_link_caps *link_caps,
63 				       const struct intel_dp_link_config *link_params,
64 				       struct link_config_limits *limits)
65 {
66 	struct intel_dp_link_caps_filter new_filter = INTEL_DP_LINK_CAPS_FILTER_NONE;
67 
68 	if (!intel_dp_link_caps_filter_add(link_caps, &new_filter, link_params))
69 		return false;
70 
71 	limits->link_config_filter = new_filter;
72 
73 	return true;
74 }
75 
76 static bool set_filter_for_link_params(struct intel_connector *connector,
77 				       int link_rate, int lane_count,
78 				       struct link_config_limits *limits)
79 {
80 	struct intel_dp *intel_dp = intel_attached_dp(connector);
81 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
82 	struct intel_dp_link_caps *link_caps = intel_dp->link.caps;
83 	struct intel_display *display = to_intel_display(intel_dp);
84 	struct intel_dp_link_config requested_config;
85 
86 	requested_config.rate = link_rate;
87 	requested_config.lane_count = lane_count;
88 
89 	if (set_filter_for_link_config(connector, link_caps, &requested_config, limits))
90 		return true;
91 
92 	/*
93 	 * Preserve the legacy behavior: if the requested (rate, lane_count)
94 	 * combination is not an allowed config, fall back to all configs
95 	 * matching the requested lane count.
96 	 *
97 	 * TODO: Recheck whether this behavior is actually correct.
98 	 */
99 	if (set_filter_for_lane_count(connector, link_caps, lane_count, limits))
100 		return true;
101 
102 	drm_dbg_kms(display->drm,
103 		    "[ENCODER:%d:%s] Invalid autotest link config parameters: %dx%d\n",
104 		    encoder->base.base.id, encoder->base.name,
105 		    requested_config.lane_count,
106 		    requested_config.rate);
107 
108 	return false;
109 }
110 
111 /* Adjust link config limits based on compliance test requests. */
112 bool intel_dp_test_compute_config(struct intel_connector *connector,
113 				  struct intel_crtc_state *pipe_config,
114 				  struct link_config_limits *limits)
115 {
116 	struct intel_dp *intel_dp = intel_attached_dp(connector);
117 	struct intel_display *display = to_intel_display(intel_dp);
118 
119 	/* For DP Compliance we override the computed bpp for the pipe */
120 	if (intel_dp->compliance.test_data.bpc != 0) {
121 		int bpp = 3 * intel_dp->compliance.test_data.bpc;
122 
123 		limits->pipe.min_bpp = bpp;
124 		limits->pipe.max_bpp = bpp;
125 		pipe_config->dither_force_disable = bpp == 6 * 3;
126 
127 		drm_dbg_kms(display->drm, "Setting pipe_bpp to %d\n", bpp);
128 	}
129 
130 	/* Use values requested by Compliance Test Request */
131 	if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) {
132 		if (!set_filter_for_link_params(connector,
133 						intel_dp->compliance.test_link_rate,
134 						intel_dp->compliance.test_lane_count,
135 						limits))
136 			return false;
137 	}
138 
139 	return true;
140 }
141 
142 /* Compliance test status bits  */
143 #define INTEL_DP_RESOLUTION_PREFERRED	1
144 #define INTEL_DP_RESOLUTION_STANDARD	2
145 #define INTEL_DP_RESOLUTION_FAILSAFE	3
146 
147 static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp)
148 {
149 	struct intel_display *display = to_intel_display(intel_dp);
150 	int status = 0;
151 	int test_link_rate;
152 	u8 test_lane_count, test_link_bw;
153 	/* (DP CTS 1.2)
154 	 * 4.3.1.11
155 	 */
156 	/* Read the TEST_LANE_COUNT and TEST_LINK_RTAE fields (DP CTS 3.1.4) */
157 	status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LANE_COUNT,
158 				   &test_lane_count);
159 
160 	if (status <= 0) {
161 		drm_dbg_kms(display->drm, "Lane count read failed\n");
162 		return DP_TEST_NAK;
163 	}
164 	test_lane_count &= DP_MAX_LANE_COUNT_MASK;
165 
166 	status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE,
167 				   &test_link_bw);
168 	if (status <= 0) {
169 		drm_dbg_kms(display->drm, "Link Rate read failed\n");
170 		return DP_TEST_NAK;
171 	}
172 	test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw);
173 
174 	/* Validate the requested link rate and lane count */
175 	if (!intel_dp_link_params_valid(intel_dp, test_link_rate,
176 					test_lane_count))
177 		return DP_TEST_NAK;
178 
179 	intel_dp->compliance.test_lane_count = test_lane_count;
180 	intel_dp->compliance.test_link_rate = test_link_rate;
181 
182 	return DP_TEST_ACK;
183 }
184 
185 static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp)
186 {
187 	struct intel_display *display = to_intel_display(intel_dp);
188 	u8 test_pattern;
189 	u8 test_misc;
190 	__be16 h_width, v_height;
191 	int status = 0;
192 
193 	/* Read the TEST_PATTERN (DP CTS 3.1.5) */
194 	status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_PATTERN,
195 				   &test_pattern);
196 	if (status <= 0) {
197 		drm_dbg_kms(display->drm, "Test pattern read failed\n");
198 		return DP_TEST_NAK;
199 	}
200 	if (test_pattern != DP_COLOR_RAMP)
201 		return DP_TEST_NAK;
202 
203 	status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_H_WIDTH_HI,
204 				  &h_width, 2);
205 	if (status <= 0) {
206 		drm_dbg_kms(display->drm, "H Width read failed\n");
207 		return DP_TEST_NAK;
208 	}
209 
210 	status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_V_HEIGHT_HI,
211 				  &v_height, 2);
212 	if (status <= 0) {
213 		drm_dbg_kms(display->drm, "V Height read failed\n");
214 		return DP_TEST_NAK;
215 	}
216 
217 	status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_MISC0,
218 				   &test_misc);
219 	if (status <= 0) {
220 		drm_dbg_kms(display->drm, "TEST MISC read failed\n");
221 		return DP_TEST_NAK;
222 	}
223 	if ((test_misc & DP_TEST_COLOR_FORMAT_MASK) != DP_COLOR_FORMAT_RGB)
224 		return DP_TEST_NAK;
225 	if (test_misc & DP_TEST_DYNAMIC_RANGE_CEA)
226 		return DP_TEST_NAK;
227 	switch (test_misc & DP_TEST_BIT_DEPTH_MASK) {
228 	case DP_TEST_BIT_DEPTH_6:
229 		intel_dp->compliance.test_data.bpc = 6;
230 		break;
231 	case DP_TEST_BIT_DEPTH_8:
232 		intel_dp->compliance.test_data.bpc = 8;
233 		break;
234 	default:
235 		return DP_TEST_NAK;
236 	}
237 
238 	intel_dp->compliance.test_data.video_pattern = test_pattern;
239 	intel_dp->compliance.test_data.hdisplay = be16_to_cpu(h_width);
240 	intel_dp->compliance.test_data.vdisplay = be16_to_cpu(v_height);
241 	/* Set test active flag here so userspace doesn't interrupt things */
242 	intel_dp->compliance.test_active = true;
243 
244 	return DP_TEST_ACK;
245 }
246 
247 static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
248 {
249 	struct intel_display *display = to_intel_display(intel_dp);
250 	u8 test_result = DP_TEST_ACK;
251 	struct intel_connector *intel_connector = intel_dp->attached_connector;
252 	struct drm_connector *connector = &intel_connector->base;
253 
254 	if (!intel_connector->detect_edid || connector->edid_corrupt ||
255 	    intel_dp->aux.i2c_defer_count > 6) {
256 		/* Check EDID read for NACKs, DEFERs and corruption
257 		 * (DP CTS 1.2 Core r1.1)
258 		 *    4.2.2.4 : Failed EDID read, I2C_NAK
259 		 *    4.2.2.5 : Failed EDID read, I2C_DEFER
260 		 *    4.2.2.6 : EDID corruption detected
261 		 * Use failsafe mode for all cases
262 		 */
263 		if (intel_dp->aux.i2c_nack_count > 0 ||
264 		    intel_dp->aux.i2c_defer_count > 0)
265 			drm_dbg_kms(display->drm,
266 				    "EDID read had %d NACKs, %d DEFERs\n",
267 				    intel_dp->aux.i2c_nack_count,
268 				    intel_dp->aux.i2c_defer_count);
269 		intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE;
270 	} else {
271 		/* FIXME: Get rid of drm_edid_raw() */
272 		const struct edid *block = drm_edid_raw(intel_connector->detect_edid);
273 
274 		/* We have to write the checksum of the last block read */
275 		block += block->extensions;
276 
277 		if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM,
278 				       block->checksum) <= 0)
279 			drm_dbg_kms(display->drm,
280 				    "Failed to write EDID checksum\n");
281 
282 		test_result = DP_TEST_ACK | DP_TEST_EDID_CHECKSUM_WRITE;
283 		intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_PREFERRED;
284 	}
285 
286 	/* Set test active flag here so userspace doesn't interrupt things */
287 	intel_dp->compliance.test_active = true;
288 
289 	return test_result;
290 }
291 
292 static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
293 					const struct intel_crtc_state *crtc_state)
294 {
295 	struct intel_display *display = to_intel_display(intel_dp);
296 	struct drm_dp_phy_test_params *data =
297 			&intel_dp->compliance.test_data.phytest;
298 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
299 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
300 	enum pipe pipe = crtc->pipe;
301 	u32 pattern_val;
302 
303 	switch (data->phy_pattern) {
304 	case DP_LINK_QUAL_PATTERN_DISABLE:
305 		drm_dbg_kms(display->drm, "Disable Phy Test Pattern\n");
306 		intel_de_write(display, DDI_DP_COMP_CTL(pipe), 0x0);
307 		if (DISPLAY_VER(display) >= 10)
308 			intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state),
309 				     DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK,
310 				     DP_TP_CTL_LINK_TRAIN_NORMAL);
311 		break;
312 	case DP_LINK_QUAL_PATTERN_D10_2:
313 		drm_dbg_kms(display->drm, "Set D10.2 Phy Test Pattern\n");
314 		intel_de_write(display, DDI_DP_COMP_CTL(pipe),
315 			       DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2);
316 		break;
317 	case DP_LINK_QUAL_PATTERN_ERROR_RATE:
318 		drm_dbg_kms(display->drm,
319 			    "Set Error Count Phy Test Pattern\n");
320 		intel_de_write(display, DDI_DP_COMP_CTL(pipe),
321 			       DDI_DP_COMP_CTL_ENABLE |
322 			       DDI_DP_COMP_CTL_SCRAMBLED_0);
323 		break;
324 	case DP_LINK_QUAL_PATTERN_PRBS7:
325 		drm_dbg_kms(display->drm, "Set PRBS7 Phy Test Pattern\n");
326 		intel_de_write(display, DDI_DP_COMP_CTL(pipe),
327 			       DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7);
328 		break;
329 	case DP_LINK_QUAL_PATTERN_80BIT_CUSTOM:
330 		/*
331 		 * FIXME: Ideally pattern should come from DPCD 0x250. As
332 		 * current firmware of DPR-100 could not set it, so hardcoding
333 		 * now for compliance test.
334 		 */
335 		drm_dbg_kms(display->drm,
336 			    "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n");
337 		pattern_val = 0x3e0f83e0;
338 		intel_de_write(display, DDI_DP_COMP_PAT(pipe, 0), pattern_val);
339 		pattern_val = 0x0f83e0f8;
340 		intel_de_write(display, DDI_DP_COMP_PAT(pipe, 1), pattern_val);
341 		pattern_val = 0x0000f83e;
342 		intel_de_write(display, DDI_DP_COMP_PAT(pipe, 2), pattern_val);
343 		intel_de_write(display, DDI_DP_COMP_CTL(pipe),
344 			       DDI_DP_COMP_CTL_ENABLE |
345 			       DDI_DP_COMP_CTL_CUSTOM80);
346 		break;
347 	case DP_LINK_QUAL_PATTERN_CP2520_PAT_1:
348 		/*
349 		 * FIXME: Ideally pattern should come from DPCD 0x24A. As
350 		 * current firmware of DPR-100 could not set it, so hardcoding
351 		 * now for compliance test.
352 		 */
353 		drm_dbg_kms(display->drm,
354 			    "Set HBR2 compliance Phy Test Pattern\n");
355 		pattern_val = 0xFB;
356 		intel_de_write(display, DDI_DP_COMP_CTL(pipe),
357 			       DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 |
358 			       pattern_val);
359 		break;
360 	case DP_LINK_QUAL_PATTERN_CP2520_PAT_3:
361 		if (DISPLAY_VER(display) < 10)  {
362 			drm_warn(display->drm,
363 				 "Platform does not support TPS4\n");
364 			break;
365 		}
366 		drm_dbg_kms(display->drm,
367 			    "Set TPS4 compliance Phy Test Pattern\n");
368 		intel_de_write(display, DDI_DP_COMP_CTL(pipe), 0x0);
369 		intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state),
370 			     DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK,
371 			     DP_TP_CTL_TRAIN_PAT4_SEL_TP4A | DP_TP_CTL_LINK_TRAIN_PAT4);
372 		break;
373 	default:
374 		drm_warn(display->drm, "Invalid Phy Test Pattern\n");
375 	}
376 }
377 
378 static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
379 					 const struct intel_crtc_state *crtc_state)
380 {
381 	struct intel_display *display = to_intel_display(intel_dp);
382 	struct drm_dp_phy_test_params *data =
383 		&intel_dp->compliance.test_data.phytest;
384 	u8 link_status[DP_LINK_STATUS_SIZE];
385 
386 	if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX,
387 					     link_status) < 0) {
388 		drm_dbg_kms(display->drm, "failed to get link status\n");
389 		return;
390 	}
391 
392 	/* retrieve vswing & pre-emphasis setting */
393 	intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX,
394 				  link_status);
395 
396 	intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX);
397 
398 	intel_dp_phy_pattern_update(intel_dp, crtc_state);
399 
400 	drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
401 			  intel_dp->train_set, crtc_state->lane_count);
402 
403 	drm_dp_set_phy_test_pattern(&intel_dp->aux, data,
404 				    intel_dp->dpcd[DP_DPCD_REV]);
405 }
406 
407 static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp)
408 {
409 	struct intel_display *display = to_intel_display(intel_dp);
410 	struct drm_dp_phy_test_params *data =
411 		&intel_dp->compliance.test_data.phytest;
412 
413 	if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) {
414 		drm_dbg_kms(display->drm,
415 			    "DP Phy Test pattern AUX read failure\n");
416 		return DP_TEST_NAK;
417 	}
418 
419 	/* Set test active flag here so userspace doesn't interrupt things */
420 	intel_dp->compliance.test_active = true;
421 
422 	return DP_TEST_ACK;
423 }
424 
425 void intel_dp_test_request(struct intel_dp *intel_dp)
426 {
427 	struct intel_display *display = to_intel_display(intel_dp);
428 	u8 response = DP_TEST_NAK;
429 	u8 request = 0;
430 	int status;
431 
432 	status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_REQUEST, &request);
433 	if (status <= 0) {
434 		drm_dbg_kms(display->drm,
435 			    "Could not read test request from sink\n");
436 		goto update_status;
437 	}
438 
439 	switch (request) {
440 	case DP_TEST_LINK_TRAINING:
441 		drm_dbg_kms(display->drm, "LINK_TRAINING test requested\n");
442 		response = intel_dp_autotest_link_training(intel_dp);
443 		break;
444 	case DP_TEST_LINK_VIDEO_PATTERN:
445 		drm_dbg_kms(display->drm, "TEST_PATTERN test requested\n");
446 		response = intel_dp_autotest_video_pattern(intel_dp);
447 		break;
448 	case DP_TEST_LINK_EDID_READ:
449 		drm_dbg_kms(display->drm, "EDID test requested\n");
450 		response = intel_dp_autotest_edid(intel_dp);
451 		break;
452 	case DP_TEST_LINK_PHY_TEST_PATTERN:
453 		drm_dbg_kms(display->drm, "PHY_PATTERN test requested\n");
454 		response = intel_dp_autotest_phy_pattern(intel_dp);
455 		break;
456 	default:
457 		drm_dbg_kms(display->drm, "Invalid test request '%02x'\n",
458 			    request);
459 		break;
460 	}
461 
462 	if (response & DP_TEST_ACK)
463 		intel_dp->compliance.test_type = request;
464 
465 update_status:
466 	status = drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_RESPONSE, response);
467 	if (status <= 0)
468 		drm_dbg_kms(display->drm,
469 			    "Could not write test response to sink\n");
470 }
471 
472 /* phy test */
473 
474 static int intel_dp_prep_phy_test(struct intel_dp *intel_dp,
475 				  struct drm_modeset_acquire_ctx *ctx,
476 				  u8 *pipe_mask)
477 {
478 	struct intel_display *display = to_intel_display(intel_dp);
479 	struct drm_connector_list_iter conn_iter;
480 	struct intel_connector *connector;
481 	int ret = 0;
482 
483 	*pipe_mask = 0;
484 
485 	drm_connector_list_iter_begin(display->drm, &conn_iter);
486 	for_each_intel_connector_iter(connector, &conn_iter) {
487 		struct drm_connector_state *conn_state =
488 			connector->base.state;
489 		struct intel_crtc_state *crtc_state;
490 		struct intel_crtc *crtc;
491 
492 		if (!intel_dp_has_connector(intel_dp, conn_state))
493 			continue;
494 
495 		crtc = to_intel_crtc(conn_state->crtc);
496 		if (!crtc)
497 			continue;
498 
499 		ret = drm_modeset_lock(&crtc->base.mutex, ctx);
500 		if (ret)
501 			break;
502 
503 		crtc_state = to_intel_crtc_state(crtc->base.state);
504 
505 		drm_WARN_ON(display->drm,
506 			    !intel_crtc_has_dp_encoder(crtc_state));
507 
508 		if (!crtc_state->hw.active)
509 			continue;
510 
511 		if (conn_state->commit &&
512 		    !try_wait_for_completion(&conn_state->commit->hw_done))
513 			continue;
514 
515 		*pipe_mask |= BIT(crtc->pipe);
516 	}
517 	drm_connector_list_iter_end(&conn_iter);
518 
519 	return ret;
520 }
521 
522 static int intel_dp_do_phy_test(struct intel_encoder *encoder,
523 				struct drm_modeset_acquire_ctx *ctx)
524 {
525 	struct intel_display *display = to_intel_display(encoder);
526 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
527 	struct intel_crtc *crtc;
528 	u8 pipe_mask;
529 	int ret;
530 
531 	ret = drm_modeset_lock(&display->drm->mode_config.connection_mutex,
532 			       ctx);
533 	if (ret)
534 		return ret;
535 
536 	ret = intel_dp_prep_phy_test(intel_dp, ctx, &pipe_mask);
537 	if (ret)
538 		return ret;
539 
540 	if (pipe_mask == 0)
541 		return 0;
542 
543 	drm_dbg_kms(display->drm, "[ENCODER:%d:%s] PHY test\n",
544 		    encoder->base.base.id, encoder->base.name);
545 
546 	for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) {
547 		const struct intel_crtc_state *crtc_state =
548 			to_intel_crtc_state(crtc->base.state);
549 
550 		/* test on the MST master transcoder */
551 		if (DISPLAY_VER(display) >= 12 &&
552 		    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
553 		    !intel_dp_mst_is_master_trans(crtc_state))
554 			continue;
555 
556 		intel_dp_process_phy_request(intel_dp, crtc_state);
557 		break;
558 	}
559 
560 	return 0;
561 }
562 
563 bool intel_dp_test_phy(struct intel_dp *intel_dp)
564 {
565 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
566 	struct intel_encoder *encoder = &dig_port->base;
567 	struct drm_modeset_acquire_ctx ctx;
568 	int ret;
569 
570 	if (!intel_dp->compliance.test_active ||
571 	    intel_dp->compliance.test_type != DP_TEST_LINK_PHY_TEST_PATTERN)
572 		return false;
573 
574 	drm_modeset_acquire_init(&ctx, 0);
575 
576 	for (;;) {
577 		ret = intel_dp_do_phy_test(encoder, &ctx);
578 
579 		if (ret == -EDEADLK) {
580 			drm_modeset_backoff(&ctx);
581 			continue;
582 		}
583 
584 		break;
585 	}
586 
587 	drm_modeset_drop_locks(&ctx);
588 	drm_modeset_acquire_fini(&ctx);
589 	drm_WARN(encoder->base.dev, ret,
590 		 "Acquiring modeset locks failed with %i\n", ret);
591 
592 	return true;
593 }
594 
595 bool intel_dp_test_short_pulse(struct intel_dp *intel_dp)
596 {
597 	struct intel_display *display = to_intel_display(intel_dp);
598 	bool reprobe_needed = false;
599 
600 	switch (intel_dp->compliance.test_type) {
601 	case DP_TEST_LINK_TRAINING:
602 		drm_dbg_kms(display->drm,
603 			    "Link Training Compliance Test requested\n");
604 		/* Send a Hotplug Uevent to userspace to start modeset */
605 		drm_kms_helper_hotplug_event(display->drm);
606 		break;
607 	case DP_TEST_LINK_PHY_TEST_PATTERN:
608 		drm_dbg_kms(display->drm,
609 			    "PHY test pattern Compliance Test requested\n");
610 		/*
611 		 * Schedule long hpd to do the test
612 		 *
613 		 * FIXME get rid of the ad-hoc phy test modeset code
614 		 * and properly incorporate it into the normal modeset.
615 		 */
616 		reprobe_needed = true;
617 	}
618 
619 	return reprobe_needed;
620 }
621 
622 static ssize_t i915_displayport_test_active_write(struct file *file,
623 						  const char __user *ubuf,
624 						  size_t len, loff_t *offp)
625 {
626 	struct seq_file *m = file->private_data;
627 	struct intel_display *display = m->private;
628 	char *input_buffer;
629 	int status = 0;
630 	struct drm_connector *connector;
631 	struct drm_connector_list_iter conn_iter;
632 	struct intel_dp *intel_dp;
633 	int val = 0;
634 
635 	if (len == 0)
636 		return 0;
637 
638 	input_buffer = memdup_user_nul(ubuf, len);
639 	if (IS_ERR(input_buffer))
640 		return PTR_ERR(input_buffer);
641 
642 	drm_dbg_kms(display->drm, "Copied %d bytes from user\n", (unsigned int)len);
643 
644 	drm_connector_list_iter_begin(display->drm, &conn_iter);
645 	drm_for_each_connector_iter(connector, &conn_iter) {
646 		struct intel_encoder *encoder;
647 
648 		if (connector->connector_type !=
649 		    DRM_MODE_CONNECTOR_DisplayPort)
650 			continue;
651 
652 		encoder = to_intel_encoder(connector->encoder);
653 		if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
654 			continue;
655 
656 		if (encoder && connector->status == connector_status_connected) {
657 			intel_dp = enc_to_intel_dp(encoder);
658 			status = kstrtoint(input_buffer, 10, &val);
659 			if (status < 0)
660 				break;
661 			drm_dbg_kms(display->drm, "Got %d for test active\n", val);
662 			/* To prevent erroneous activation of the compliance
663 			 * testing code, only accept an actual value of 1 here
664 			 */
665 			if (val == 1)
666 				intel_dp->compliance.test_active = true;
667 			else
668 				intel_dp->compliance.test_active = false;
669 		}
670 	}
671 	drm_connector_list_iter_end(&conn_iter);
672 	kfree(input_buffer);
673 	if (status < 0)
674 		return status;
675 
676 	*offp += len;
677 	return len;
678 }
679 
680 static int i915_displayport_test_active_show(struct seq_file *m, void *data)
681 {
682 	struct intel_display *display = m->private;
683 	struct drm_connector *connector;
684 	struct drm_connector_list_iter conn_iter;
685 	struct intel_dp *intel_dp;
686 
687 	drm_connector_list_iter_begin(display->drm, &conn_iter);
688 	drm_for_each_connector_iter(connector, &conn_iter) {
689 		struct intel_encoder *encoder;
690 
691 		if (connector->connector_type !=
692 		    DRM_MODE_CONNECTOR_DisplayPort)
693 			continue;
694 
695 		encoder = to_intel_encoder(connector->encoder);
696 		if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
697 			continue;
698 
699 		if (encoder && connector->status == connector_status_connected) {
700 			intel_dp = enc_to_intel_dp(encoder);
701 			if (intel_dp->compliance.test_active)
702 				seq_puts(m, "1");
703 			else
704 				seq_puts(m, "0");
705 		} else {
706 			seq_puts(m, "0");
707 		}
708 	}
709 	drm_connector_list_iter_end(&conn_iter);
710 
711 	return 0;
712 }
713 
714 static int i915_displayport_test_active_open(struct inode *inode,
715 					     struct file *file)
716 {
717 	return single_open(file, i915_displayport_test_active_show,
718 			   inode->i_private);
719 }
720 
721 static const struct file_operations i915_displayport_test_active_fops = {
722 	.owner = THIS_MODULE,
723 	.open = i915_displayport_test_active_open,
724 	.read = seq_read,
725 	.llseek = seq_lseek,
726 	.release = single_release,
727 	.write = i915_displayport_test_active_write
728 };
729 
730 static int i915_displayport_test_data_show(struct seq_file *m, void *data)
731 {
732 	struct intel_display *display = m->private;
733 	struct drm_connector *connector;
734 	struct drm_connector_list_iter conn_iter;
735 	struct intel_dp *intel_dp;
736 
737 	drm_connector_list_iter_begin(display->drm, &conn_iter);
738 	drm_for_each_connector_iter(connector, &conn_iter) {
739 		struct intel_encoder *encoder;
740 
741 		if (connector->connector_type !=
742 		    DRM_MODE_CONNECTOR_DisplayPort)
743 			continue;
744 
745 		encoder = to_intel_encoder(connector->encoder);
746 		if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
747 			continue;
748 
749 		if (encoder && connector->status == connector_status_connected) {
750 			intel_dp = enc_to_intel_dp(encoder);
751 			if (intel_dp->compliance.test_type ==
752 			    DP_TEST_LINK_EDID_READ)
753 				seq_printf(m, "%lx",
754 					   intel_dp->compliance.test_data.edid);
755 			else if (intel_dp->compliance.test_type ==
756 				 DP_TEST_LINK_VIDEO_PATTERN) {
757 				seq_printf(m, "hdisplay: %d\n",
758 					   intel_dp->compliance.test_data.hdisplay);
759 				seq_printf(m, "vdisplay: %d\n",
760 					   intel_dp->compliance.test_data.vdisplay);
761 				seq_printf(m, "bpc: %u\n",
762 					   intel_dp->compliance.test_data.bpc);
763 			} else if (intel_dp->compliance.test_type ==
764 				   DP_TEST_LINK_PHY_TEST_PATTERN) {
765 				seq_printf(m, "pattern: %d\n",
766 					   intel_dp->compliance.test_data.phytest.phy_pattern);
767 				seq_printf(m, "Number of lanes: %d\n",
768 					   intel_dp->compliance.test_data.phytest.num_lanes);
769 				seq_printf(m, "Link Rate: %d\n",
770 					   intel_dp->compliance.test_data.phytest.link_rate);
771 				seq_printf(m, "level: %02x\n",
772 					   intel_dp->train_set[0]);
773 			}
774 		} else {
775 			seq_puts(m, "0");
776 		}
777 	}
778 	drm_connector_list_iter_end(&conn_iter);
779 
780 	return 0;
781 }
782 DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data);
783 
784 static int i915_displayport_test_type_show(struct seq_file *m, void *data)
785 {
786 	struct intel_display *display = m->private;
787 	struct drm_connector *connector;
788 	struct drm_connector_list_iter conn_iter;
789 	struct intel_dp *intel_dp;
790 
791 	drm_connector_list_iter_begin(display->drm, &conn_iter);
792 	drm_for_each_connector_iter(connector, &conn_iter) {
793 		struct intel_encoder *encoder;
794 
795 		if (connector->connector_type !=
796 		    DRM_MODE_CONNECTOR_DisplayPort)
797 			continue;
798 
799 		encoder = to_intel_encoder(connector->encoder);
800 		if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
801 			continue;
802 
803 		if (encoder && connector->status == connector_status_connected) {
804 			intel_dp = enc_to_intel_dp(encoder);
805 			seq_printf(m, "%02lx\n", intel_dp->compliance.test_type);
806 		} else {
807 			seq_puts(m, "0");
808 		}
809 	}
810 	drm_connector_list_iter_end(&conn_iter);
811 
812 	return 0;
813 }
814 DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_type);
815 
816 static const struct {
817 	const char *name;
818 	const struct file_operations *fops;
819 } intel_display_debugfs_files[] = {
820 	{"i915_dp_test_data", &i915_displayport_test_data_fops},
821 	{"i915_dp_test_type", &i915_displayport_test_type_fops},
822 	{"i915_dp_test_active", &i915_displayport_test_active_fops},
823 };
824 
825 void intel_dp_test_debugfs_register(struct intel_display *display)
826 {
827 	int i;
828 
829 	for (i = 0; i < ARRAY_SIZE(intel_display_debugfs_files); i++) {
830 		debugfs_create_file(intel_display_debugfs_files[i].name,
831 				    0644,
832 				    display->drm->debugfs_root,
833 				    display,
834 				    intel_display_debugfs_files[i].fops);
835 	}
836 }
837