Commit de3ee254 authored by Abhinav Kumar's avatar Abhinav Kumar Committed by Rob Clark
Browse files

drm/msm/dp: add debugfs nodes for video pattern tests



Add the debugfs nodes needed for the video pattern
compliance tests to MSM DP driver.

Changes in v2: rebase on top of latest patchset of dependency

Signed-off-by: default avatarAbhinav Kumar <abhinavk@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
parent f913454a
Loading
Loading
Loading
Loading
+184 −0
Original line number Diff line number Diff line
@@ -203,17 +203,174 @@ static ssize_t dp_debug_read_info(struct file *file, char __user *user_buff,
	return -EINVAL;
}

static int dp_test_data_show(struct seq_file *m, void *data)
{
	struct drm_device *dev;
	struct dp_debug_private *debug;
	struct drm_connector *connector;
	struct drm_connector_list_iter conn_iter;
	u32 bpc;

	debug = m->private;
	dev = debug->drm_dev;
	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter) {

		if (connector->connector_type !=
			DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		if (connector->status == connector_status_connected) {
			bpc = debug->link->test_video.test_bit_depth;
			seq_printf(m, "hdisplay: %d\n",
					debug->link->test_video.test_h_width);
			seq_printf(m, "vdisplay: %d\n",
					debug->link->test_video.test_v_height);
					seq_printf(m, "bpc: %u\n",
					dp_link_bit_depth_to_bpc(bpc));
		} else
			seq_puts(m, "0");
	}

	drm_connector_list_iter_end(&conn_iter);

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(dp_test_data);

static int dp_test_type_show(struct seq_file *m, void *data)
{
	struct dp_debug_private *debug = m->private;
	struct drm_device *dev = debug->drm_dev;
	struct drm_connector *connector;
	struct drm_connector_list_iter conn_iter;

	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter) {

		if (connector->connector_type !=
			DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		if (connector->status == connector_status_connected)
			seq_printf(m, "%02x", DP_TEST_LINK_VIDEO_PATTERN);
		else
			seq_puts(m, "0");
	}
	drm_connector_list_iter_end(&conn_iter);

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(dp_test_type);

static ssize_t dp_test_active_write(struct file *file,
		const char __user *ubuf,
		size_t len, loff_t *offp)
{
	char *input_buffer;
	int status = 0;
	struct dp_debug_private *debug;
	struct drm_device *dev;
	struct drm_connector *connector;
	struct drm_connector_list_iter conn_iter;
	int val = 0;

	debug = ((struct seq_file *)file->private_data)->private;
	dev = debug->drm_dev;

	if (len == 0)
		return 0;

	input_buffer = memdup_user_nul(ubuf, len);
	if (IS_ERR(input_buffer))
		return PTR_ERR(input_buffer);

	DRM_DEBUG_DRIVER("Copied %d bytes from user\n", (unsigned int)len);

	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter) {
		if (connector->connector_type !=
			DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		if (connector->status == connector_status_connected) {
			status = kstrtoint(input_buffer, 10, &val);
			if (status < 0)
				break;
			DRM_DEBUG_DRIVER("Got %d for test active\n", val);
			/* To prevent erroneous activation of the compliance
			 * testing code, only accept an actual value of 1 here
			 */
			if (val == 1)
				debug->panel->video_test = true;
			else
				debug->panel->video_test = false;
		}
	}
	drm_connector_list_iter_end(&conn_iter);
	kfree(input_buffer);
	if (status < 0)
		return status;

	*offp += len;
	return len;
}

static int dp_test_active_show(struct seq_file *m, void *data)
{
	struct dp_debug_private *debug = m->private;
	struct drm_device *dev = debug->drm_dev;
	struct drm_connector *connector;
	struct drm_connector_list_iter conn_iter;

	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter) {
		if (connector->connector_type !=
			DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		if (connector->status == connector_status_connected) {
			if (debug->panel->video_test)
				seq_puts(m, "1");
			else
				seq_puts(m, "0");
		} else
			seq_puts(m, "0");
	}
	drm_connector_list_iter_end(&conn_iter);

	return 0;
}

static int dp_test_active_open(struct inode *inode,
		struct file *file)
{
	return single_open(file, dp_test_active_show,
			inode->i_private);
}

static const struct file_operations dp_debug_fops = {
	.open = simple_open,
	.read = dp_debug_read_info,
};

static const struct file_operations test_active_fops = {
	.owner = THIS_MODULE,
	.open = dp_test_active_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
	.write = dp_test_active_write
};

static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor)
{
	int rc = 0;
	struct dp_debug_private *debug = container_of(dp_debug,
			struct dp_debug_private, dp_debug);
	struct dentry *file;
	struct dentry *test_active;
	struct dentry *test_data, *test_type;

	file = debugfs_create_file("dp_debug", 0444, minor->debugfs_root,
			debug, &dp_debug_fops);
@@ -223,6 +380,33 @@ static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor)
				  DEBUG_NAME, rc);
	}

	test_active = debugfs_create_file("msm_dp_test_active", 0444,
			minor->debugfs_root,
			debug, &test_active_fops);
	if (IS_ERR_OR_NULL(test_active)) {
		rc = PTR_ERR(test_active);
		DRM_ERROR("[%s] debugfs test_active failed, rc=%d\n",
				  DEBUG_NAME, rc);
	}

	test_data = debugfs_create_file("msm_dp_test_data", 0444,
			minor->debugfs_root,
			debug, &dp_test_data_fops);
	if (IS_ERR_OR_NULL(test_data)) {
		rc = PTR_ERR(test_data);
		DRM_ERROR("[%s] debugfs test_data failed, rc=%d\n",
				  DEBUG_NAME, rc);
	}

	test_type = debugfs_create_file("msm_dp_test_type", 0444,
			minor->debugfs_root,
			debug, &dp_test_type_fops);
	if (IS_ERR_OR_NULL(test_type)) {
		rc = PTR_ERR(test_type);
		DRM_ERROR("[%s] debugfs test_type failed, rc=%d\n",
				  DEBUG_NAME, rc);
	}

	debug->root = minor->debugfs_root;

	return rc;
+23 −0
Original line number Diff line number Diff line
@@ -112,6 +112,29 @@ static inline u32 dp_link_bit_depth_to_bpp(u32 tbd)
	}
}

/**
 * dp_test_bit_depth_to_bpc() - convert test bit depth to bpc
 * @tbd: test bit depth
 *
 * Returns the bits per comp (bpc) to be used corresponding to the
 * bit depth value. This function assumes that bit depth has
 * already been validated.
 */
static inline u32 dp_link_bit_depth_to_bpc(u32 tbd)
{
	switch (tbd) {
	case DP_TEST_BIT_DEPTH_6:
		return 6;
	case DP_TEST_BIT_DEPTH_8:
		return 8;
	case DP_TEST_BIT_DEPTH_10:
		return 10;
	case DP_TEST_BIT_DEPTH_UNKNOWN:
	default:
		return 0;
	}
}

u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp);
int dp_link_process_request(struct dp_link *dp_link);
int dp_link_get_colorimetry_config(struct dp_link *dp_link);