Linux Audio

Check our new training course

Yocto / OpenEmbedded training

Feb 10-13, 2025
Register
Loading...
Note: File does not exist in v3.1.
  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
 21void 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. */
 31void 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
 75static 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
113static 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
175static 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
220static 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
306static 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
335static 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
353void 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
393update_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
402static 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
450static 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
491bool 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
523bool 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
550static 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
608static 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
642static 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
649static 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
658static 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}
710DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data);
711
712static 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}
742DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_type);
743
744static 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
753void 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}