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