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

Commit 47a5ac0a authored by Padmanabhan Komanduru's avatar Padmanabhan Komanduru
Browse files

msm: mdss: double check dynamic fps done interrupt



There can be a scenario where the DSI hardware finished the
dynamic fps operation and updated the DSI interrupt status
bit but the isr is not triggered. This is possible under
heavy system load where the interrupts are disabled by some
other thread on the CPU where MDSS IRQ is affined. Double
check the status of dynamic fps operation by reading back
the DSI interrupt status bit once the wait for interrupt times
out.

Change-Id: Iebe5ab3f6b43b4b3e61666a600488e8ce50f6995
Signed-off-by: default avatarPadmanabhan Komanduru <pkomandu@codeaurora.org>
parent 785534bd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1967,7 +1967,7 @@ static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata,
	}

	rc = mdss_dsi_en_wait4dynamic_done(ctrl_pdata);
	if (rc) {
	if (rc < 0) {
		pr_err("Unsuccessful dynamic fps change");
		goto dfps_timeout;
	}
+21 −4
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@
#define FIFO_STATUS	0x0C
#define LANE_STATUS	0xA8

#define MDSS_DSI_INT_CTRL	0x0110

struct mdss_dsi_ctrl_pdata *ctrl_list[DSI_CTRL_MAX];

struct mdss_hw mdss_dsi0_hw = {
@@ -2279,10 +2281,25 @@ int mdss_dsi_en_wait4dynamic_done(struct mdss_dsi_ctrl_pdata *ctrl)
		MIPI_OUTP((sctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL,
				(BIT(13) | BIT(8) | BIT(0)));

	if (!wait_for_completion_timeout(&ctrl->dynamic_comp,
			msecs_to_jiffies(VSYNC_PERIOD * 4))) {
	rc = wait_for_completion_timeout(&ctrl->dynamic_comp,
			msecs_to_jiffies(VSYNC_PERIOD * 4));
	if (rc == 0) {
		u32 reg_val, status;

		reg_val = MIPI_INP(ctrl->ctrl_base + MDSS_DSI_INT_CTRL);
		status = reg_val & DSI_INTR_DYNAMIC_REFRESH_DONE;
		if (status) {
			reg_val &= DSI_INTR_MASK_ALL;
			/* clear dfps DONE isr only */
			reg_val |= DSI_INTR_DYNAMIC_REFRESH_DONE;
			MIPI_OUTP(ctrl->ctrl_base + MDSS_DSI_INT_CTRL, reg_val);
			mdss_dsi_disable_irq(ctrl, DSI_DYNAMIC_TERM);
			pr_warn_ratelimited("%s: dfps done but irq not triggered\n",
				__func__);
		} else {
			pr_err("Dynamic interrupt timedout\n");
		rc = -EINVAL;
			rc = -ETIMEDOUT;
		}
	}

	data = MIPI_INP((ctrl->ctrl_base) + 0x0110);