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