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

Commit feac9726 authored by Shashank Babu Chinta Venkata's avatar Shashank Babu Chinta Venkata
Browse files

drm/msm/dsi-staging: simulate esd trigger on display panel



Add capability to trigger an on demand esd from debugfs.
When esd is requested, it will pull reset gpio low causing
display panel to go into inactive state and next ESD status
check will attempt to do a full display recovery.

For example, the debugfs node for ESD trigger will be
available at /<debugfs-root>/<active display>/esd_trigger

Format for triggering an ESD:
"echo 1 > /d/dsi_nt35597_truly_dsc_cmd_display/esd_trigger"

CRs-Fixed: 2180708
Change-Id: I9550aa97ceb5c85d2566b285443a9323ac13fc75
Signed-off-by: default avatarShashank Babu Chinta Venkata <sbchin@codeaurora.org>
parent e2538419
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
@@ -904,6 +904,62 @@ static ssize_t debugfs_misr_setup(struct file *file,
	return rc;
}

static ssize_t debugfs_esd_trigger_check(struct file *file,
				  const char __user *user_buf,
				  size_t user_len,
				  loff_t *ppos)
{
	struct dsi_display *display = file->private_data;
	char *buf;
	int rc = 0;
	u32 esd_trigger;

	if (!display)
		return -ENODEV;

	if (*ppos)
		return 0;

	if (user_len > sizeof(u32))
		return -EINVAL;

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

	if (copy_from_user(buf, user_buf, user_len)) {
		rc = -EINVAL;
		goto error;
	}

	buf[user_len] = '\0'; /* terminate the string */

	if (kstrtouint(buf, 10, &esd_trigger)) {
		rc = -EINVAL;
		goto error;
	}

	if (esd_trigger != 1) {
		rc = -EINVAL;
		goto error;
	}

	display->esd_trigger = esd_trigger;

	if (display->esd_trigger) {
		rc = dsi_panel_trigger_esd_attack(display->panel);
		if (rc) {
			pr_err("Failed to trigger ESD attack\n");
			return rc;
		}
	}

	rc = user_len;
error:
	kfree(buf);
	return rc;
}

static ssize_t debugfs_misr_read(struct file *file,
				 char __user *user_buf,
				 size_t user_len,
@@ -980,6 +1036,11 @@ static const struct file_operations misr_data_fops = {
	.write = debugfs_misr_setup,
};

static const struct file_operations esd_trigger_fops = {
	.open = simple_open,
	.write = debugfs_esd_trigger_check,
};

static int dsi_display_debugfs_init(struct dsi_display *display)
{
	int rc = 0;
@@ -1007,6 +1068,18 @@ static int dsi_display_debugfs_init(struct dsi_display *display)
		goto error_remove_dir;
	}

	dump_file = debugfs_create_file("esd_trigger",
					0644,
					dir,
					display,
					&esd_trigger_fops);
	if (IS_ERR_OR_NULL(dump_file)) {
		rc = PTR_ERR(dump_file);
		pr_err("[%s] debugfs for esd trigger file failed, rc=%d\n",
		       display->name, rc);
		goto error_remove_dir;
	}

	misr_data = debugfs_create_file("misr_data",
					0600,
					dir,
+2 −0
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@ struct dsi_display_clk_info {
 * @root:             Debugfs root directory
 * @misr_enable       Frame MISR enable/disable
 * @misr_frame_count  Number of frames to accumulate the MISR value
 * @esd_trigger       field indicating ESD trigger through debugfs
 */
struct dsi_display {
	struct platform_device *pdev;
@@ -218,6 +219,7 @@ struct dsi_display {

	bool misr_enable;
	u32 misr_frame_count;
	u32 esd_trigger;
	/* multiple dsi error handlers */
	struct workqueue_struct *err_workq;
	struct work_struct fifo_underflow_work;
+25 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -321,6 +321,30 @@ static int dsi_panel_gpio_release(struct dsi_panel *panel)
	return rc;
}

int dsi_panel_trigger_esd_attack(struct dsi_panel *panel)
{
	struct dsi_panel_reset_config *r_config;

	if (!panel) {
		pr_err("Invalid panel param\n");
		return -EINVAL;
	}

	r_config = &panel->reset_config;
	if (!r_config) {
		pr_err("Invalid panel reset configuration\n");
		return -EINVAL;
	}

	if (gpio_is_valid(r_config->reset_gpio)) {
		gpio_set_value(r_config->reset_gpio, 0);
		pr_info("GPIO pulled low to simulate ESD\n");
		return 0;
	}
	pr_err("failed to pull down gpio\n");
	return -EINVAL;
}

static int dsi_panel_reset(struct dsi_panel *panel)
{
	int rc = 0;
+3 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -206,6 +206,8 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
				struct device_node *of_node,
				int topology_override);

int dsi_panel_trigger_esd_attack(struct dsi_panel *panel);

void dsi_panel_put(struct dsi_panel *panel);

int dsi_panel_drv_init(struct dsi_panel *panel, struct mipi_dsi_host *host);