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