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

Commit f05f952b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge changes I9550aa97,Ib1f12423 into msm-4.14

* changes:
  drm/msm/dsi-staging: simulate esd trigger on display panel
  drm/msm/dsi-staging: turn off DSI ctrl status interrupts during ESD
parents eea0e323 6ffd46b1
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -3298,6 +3298,25 @@ u32 dsi_ctrl_collect_misr(struct dsi_ctrl *dsi_ctrl)
	return misr;
}

void dsi_ctrl_mask_error_status_interrupts(struct dsi_ctrl *dsi_ctrl)
{
	if (!dsi_ctrl || !dsi_ctrl->hw.ops.error_intr_ctrl
			|| !dsi_ctrl->hw.ops.clear_error_status) {
		pr_err("Invalid params\n");
		return;
	}

	/*
	 * Mask DSI error status interrupts and clear error status
	 * register
	 */
	mutex_lock(&dsi_ctrl->ctrl_lock);
	dsi_ctrl->hw.ops.error_intr_ctrl(&dsi_ctrl->hw, false);
	dsi_ctrl->hw.ops.clear_error_status(&dsi_ctrl->hw,
					DSI_ERROR_INTERRUPT_COUNT);
	mutex_unlock(&dsi_ctrl->ctrl_lock);
}

/**
 * dsi_ctrl_irq_update() - Put a irq vote to process DSI error
 *				interrupts at any time.
+7 −0
Original line number Diff line number Diff line
@@ -710,6 +710,13 @@ int dsi_message_validate_tx_mode(struct dsi_ctrl *dsi_ctrl, u32 cmd_len,
 */
void dsi_ctrl_isr_configure(struct dsi_ctrl *dsi_ctrl, bool enable);

/**
 * dsi_ctrl_mask_error_status_interrupts() - API to mask dsi ctrl error status
 *                                           interrupts
 * @dsi_ctrl:              DSI controller handle.
 */
void dsi_ctrl_mask_error_status_interrupts(struct dsi_ctrl *dsi_ctrl);

/**
 * dsi_ctrl_irq_update() - Put a irq vote to process DSI error
 *				interrupts at any time.
+112 −17
Original line number Diff line number Diff line
@@ -51,6 +51,40 @@ static const struct of_device_id dsi_display_dt_match[] = {

static struct dsi_display *main_display;

static void dsi_display_mask_ctrl_error_interrupts(struct dsi_display *display)
{
	int i;
	struct dsi_display_ctrl *ctrl;

	if (!display)
		return;

	for (i = 0; (i < display->ctrl_count) &&
			(i < MAX_DSI_CTRLS_PER_DISPLAY); i++) {
		ctrl = &display->ctrl[i];
		if (!ctrl)
			continue;
		dsi_ctrl_mask_error_status_interrupts(ctrl->ctrl);
	}
}

static void dsi_display_ctrl_irq_update(struct dsi_display *display, bool en)
{
	int i;
	struct dsi_display_ctrl *ctrl;

	if (!display)
		return;

	for (i = 0; (i < display->ctrl_count) &&
			(i < MAX_DSI_CTRLS_PER_DISPLAY); i++) {
		ctrl = &display->ctrl[i];
		if (!ctrl)
			continue;
		dsi_ctrl_irq_update(ctrl->ctrl, en);
	}
}

void dsi_rect_intersect(const struct dsi_rect *r1,
		const struct dsi_rect *r2,
		struct dsi_rect *result)
@@ -496,6 +530,11 @@ static int dsi_display_status_reg_read(struct dsi_display *display)
		}
	}
exit:
	if (rc <= 0) {
		dsi_display_ctrl_irq_update(display, false);
		dsi_display_mask_ctrl_error_interrupts(display);
	}

	dsi_display_cmd_engine_disable(display);
done:
	return rc;
@@ -867,6 +906,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,
@@ -943,6 +1038,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;
@@ -970,6 +1070,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,
@@ -2485,23 +2597,6 @@ static void dsi_display_ctrl_isr_configure(struct dsi_display *display, bool en)
	}
}

static void dsi_display_ctrl_irq_update(struct dsi_display *display, bool en)
{
	int i;
	struct dsi_display_ctrl *ctrl;

	if (!display)
		return;

	for (i = 0; (i < display->ctrl_count) &&
			(i < MAX_DSI_CTRLS_PER_DISPLAY); i++) {
		ctrl = &display->ctrl[i];
		if (!ctrl)
			continue;
		dsi_ctrl_irq_update(ctrl->ctrl, en);
	}
}

int dsi_pre_clkoff_cb(void *priv,
			   enum dsi_clk_type clk,
			   enum dsi_clk_state new_state)
+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;
+24 −0
Original line number Diff line number Diff line
@@ -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;
Loading