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