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

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

drm/msm/dsi-staging: handle spurious error interrupts



DSI controller can trigger spurious error interrupts
during ESD attack scenarios. Add a check for such spurious
interrupts during error handling.

Change-Id: Iab86e34a7d94991de5c2ad1c62404f1dee1c81b6
Signed-off-by: default avatarShashank Babu Chinta Venkata <sbchin@codeaurora.org>
parent 045b32a6
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -2166,6 +2166,35 @@ int dsi_ctrl_phy_reset_config(struct dsi_ctrl *dsi_ctrl, bool enable)
	return 0;
}

static bool dsi_ctrl_check_for_spurious_error_interrupts(
					struct dsi_ctrl *dsi_ctrl)
{
	const unsigned long intr_check_interval = msecs_to_jiffies(1000);
	const unsigned int interrupt_threshold = 15;
	unsigned long jiffies_now = jiffies;

	if (!dsi_ctrl) {
		pr_err("Invalid DSI controller structure\n");
		return false;
	}

	if (dsi_ctrl->jiffies_start == 0)
		dsi_ctrl->jiffies_start = jiffies;

	dsi_ctrl->error_interrupt_count++;

	if ((jiffies_now - dsi_ctrl->jiffies_start) < intr_check_interval) {
		if (dsi_ctrl->error_interrupt_count > interrupt_threshold) {
			pr_warn("Detected spurious interrupts on dsi ctrl\n");
			return true;
		}
	} else {
		dsi_ctrl->jiffies_start = jiffies;
		dsi_ctrl->error_interrupt_count = 1;
	}
	return false;
}

static void dsi_ctrl_handle_error_status(struct dsi_ctrl *dsi_ctrl,
				unsigned long int error)
{
@@ -2237,6 +2266,19 @@ static void dsi_ctrl_handle_error_status(struct dsi_ctrl *dsi_ctrl,
	if (error & 0xF)
		pr_err("ack error: 0x%lx\n", error);

	/*
	 * DSI Phy can go into bad state during ESD influence. This can
	 * manifest as various types of spurious error interrupts on
	 * DSI controller. This check will allow us to handle afore mentioned
	 * case and prevent us from re enabling interrupts until a full ESD
	 * recovery is completed.
	 */
	if (dsi_ctrl_check_for_spurious_error_interrupts(dsi_ctrl) &&
				dsi_ctrl->esd_check_underway) {
		dsi_ctrl->hw.ops.soft_reset(&dsi_ctrl->hw);
		return;
	}

	/* enable back DSI interrupts */
	if (dsi_ctrl->hw.ops.error_intr_ctrl)
		dsi_ctrl->hw.ops.error_intr_ctrl(&dsi_ctrl->hw, true);
+4 −0
Original line number Diff line number Diff line
@@ -259,6 +259,10 @@ struct dsi_ctrl {
	bool misr_enable;
	u32 misr_cache;

	/* Check for spurious interrupts */
	unsigned long jiffies_start;
	unsigned int error_interrupt_count;

	bool phy_isolation_enabled;
	bool null_insertion_enabled;
	bool modeupdated;