Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 87222e74 authored by Padmanabhan Komanduru's avatar Padmanabhan Komanduru
Browse files

drm/msm/dp: add debugfs support for restricting maximum link rate



Add debugfs support to restrict the maximum link rate supported by
Display Port driver. This is needed for certain cases of DP Link CTS
where the sink supports maximum link rate of 5.4 GHz. Any link rate
which is published more than 5.4 GHz in DPCD is expected by the source
to be treated as error and fallback to fail-safe of 1.62 GHz.

Change-Id: Ief14586b45fb832c2fd00a6372ddf57b3ace5864
Signed-off-by: default avatarPadmanabhan Komanduru <pkomandu@codeaurora.org>
parent 5b93813a
Loading
Loading
Loading
Loading
+80 −0
Original line number Diff line number Diff line
@@ -107,6 +107,40 @@ static ssize_t dp_debug_write_edid_modes(struct file *file,
	return len;
}

static ssize_t dp_debug_bw_code_write(struct file *file,
		const char __user *user_buff, size_t count, loff_t *ppos)
{
	struct dp_debug_private *debug = file->private_data;
	char buf[SZ_8];
	size_t len = 0;
	u32 max_bw_code = 0;

	if (!debug)
		return -ENODEV;

	if (*ppos)
		return 0;

	/* Leave room for termination char */
	len = min_t(size_t, count, SZ_8 - 1);
	if (copy_from_user(buf, user_buff, len))
		return 0;

	buf[len] = '\0';

	if (kstrtoint(buf, 10, &max_bw_code) != 0)
		return 0;

	if (!is_link_rate_valid(max_bw_code)) {
		pr_err("Unsupported bw code %d\n", max_bw_code);
		return len;
	}
	debug->panel->max_bw_code = max_bw_code;
	pr_debug("max_bw_code: %d\n", max_bw_code);

	return len;
}

static ssize_t dp_debug_read_connected(struct file *file,
		char __user *user_buff, size_t count, loff_t *ppos)
{
@@ -349,6 +383,36 @@ static ssize_t dp_debug_read_info(struct file *file, char __user *user_buff,
	return -EINVAL;
}

static ssize_t dp_debug_bw_code_read(struct file *file,
	char __user *user_buff, size_t count, loff_t *ppos)
{
	struct dp_debug_private *debug = file->private_data;
	char *buf;
	u32 len = 0;

	if (!debug)
		return -ENODEV;

	if (*ppos)
		return 0;

	buf = kzalloc(SZ_4K, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	len += snprintf(buf + len, (SZ_4K - len),
			"max_bw_code = %d\n", debug->panel->max_bw_code);

	if (copy_to_user(user_buff, buf, len)) {
		kfree(buf);
		return -EFAULT;
	}

	*ppos += len;
	kfree(buf);
	return len;
}

static const struct file_operations dp_debug_fops = {
	.open = simple_open,
	.read = dp_debug_read_info,
@@ -370,6 +434,12 @@ static const struct file_operations connected_fops = {
	.read = dp_debug_read_connected,
};

static const struct file_operations bw_code_fops = {
	.open = simple_open,
	.read = dp_debug_bw_code_read,
	.write = dp_debug_bw_code_write,
};

static int dp_debug_init(struct dp_debug *dp_debug)
{
	int rc = 0;
@@ -377,6 +447,7 @@ static int dp_debug_init(struct dp_debug *dp_debug)
		struct dp_debug_private, dp_debug);
	struct dentry *dir, *file, *edid_modes;
	struct dentry *hpd, *connected;
	struct dentry *max_bw_code;
	struct dentry *root = debug->root;

	dir = debugfs_create_dir(DEBUG_NAME, NULL);
@@ -423,6 +494,15 @@ static int dp_debug_init(struct dp_debug *dp_debug)
		goto error_remove_dir;
	}

	max_bw_code = debugfs_create_file("max_bw_code", 0644, dir,
			debug, &bw_code_fops);
	if (IS_ERR_OR_NULL(max_bw_code)) {
		rc = PTR_ERR(max_bw_code);
		pr_err("[%s] debugfs max_bw_code failed, rc=%d\n",
		       DEBUG_NAME, rc);
		goto error_remove_dir;
	}

	root = dir;
	return rc;
error_remove_dir:
+4 −1
Original line number Diff line number Diff line
@@ -182,7 +182,9 @@ static int dp_panel_read_sink_caps(struct dp_panel *dp_panel,
	rc = dp_panel_read_dpcd(dp_panel);
	if (rc || !is_link_rate_valid(drm_dp_link_rate_to_bw_code(
		dp_panel->link_info.rate)) || !is_lane_count_valid(
		dp_panel->link_info.num_lanes)) {
		dp_panel->link_info.num_lanes) ||
		((drm_dp_link_rate_to_bw_code(dp_panel->link_info.rate)) >
		dp_panel->max_bw_code)) {
		pr_err("panel dpcd read failed/incorrect, set default params\n");
		dp_panel_set_default_link_params(dp_panel);
	}
@@ -501,6 +503,7 @@ struct dp_panel *dp_panel_get(struct dp_panel_in *in)

	dp_panel = &panel->dp_panel;
	panel->aux_cfg_update_done = false;
	dp_panel->max_bw_code = DP_LINK_BW_8_1;

	dp_panel->sde_edid_register = dp_panel_edid_register;
	dp_panel->sde_edid_deregister = dp_panel_edid_deregister;
+3 −0
Original line number Diff line number Diff line
@@ -71,6 +71,9 @@ struct dp_panel {
	u32 vic;
	u32 max_pclk_khz;

	/* debug */
	u32 max_bw_code;

	int (*sde_edid_register)(struct dp_panel *dp_panel);
	void (*sde_edid_deregister)(struct dp_panel *dp_panel);
	int (*init_info)(struct dp_panel *dp_panel);