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

Commit 42b00d91 authored by Veera Sundaram Sankaran's avatar Veera Sundaram Sankaran
Browse files

msm: mdss: clear irq if RD_PTR intr is detected before clk disable



Before disabling the RD_PTR ISR and turning off the clks, there is a
possibility that some other CPU might have received a READ_PTR ISR few
microseconds before and started to process it. By the time, the ISR
reaches the register read instructions, the clks might be disabled.
To avoid such cases, check for the intr status after disabling the ISR
and clear the irq before disabling the clks.

Change-Id: If9f0e2df22ec7ea26d62b08c9364c2047dda8c51
Signed-off-by: default avatarVeera Sundaram Sankaran <veeras@codeaurora.org>
parent ee630a97
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -565,6 +565,28 @@ void mdss_mdp_irq_disable(u32 intr_type, u32 intf_num)
	spin_unlock_irqrestore(&mdp_lock, irq_flags);
}

/*
 * This function is used to check and clear the status of
 * INTR and does not handle INTR2 and HIST_INTR
 */
void mdss_mdp_intr_check_and_clear(u32 intr_type, u32 intf_num)
{
	u32 status, irq;
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();

	irq = mdss_mdp_irq_mask(intr_type, intf_num);

	spin_lock(&mdp_lock);
	status = irq & readl_relaxed(mdata->mdp_base +
			MDSS_MDP_REG_INTR_STATUS);
	if (status) {
		pr_debug("clearing irq: intr_type:%d, intf_num:%d\n",
				intr_type, intf_num);
		writel_relaxed(irq, mdata->mdp_base + MDSS_MDP_REG_INTR_CLEAR);
	}
	spin_unlock(&mdp_lock);
}

void mdss_mdp_hist_irq_disable(u32 irq)
{
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+1 −0
Original line number Diff line number Diff line
@@ -981,6 +981,7 @@ void mdss_mdp_irq_clear(struct mdss_data_type *mdata,
		u32 intr_type, u32 intf_num);
int mdss_mdp_irq_enable(u32 intr_type, u32 intf_num);
void mdss_mdp_irq_disable(u32 intr_type, u32 intf_num);
void mdss_mdp_intr_check_and_clear(u32 intr_type, u32 intf_num);
int mdss_mdp_hist_irq_enable(u32 irq);
void mdss_mdp_hist_irq_disable(u32 irq);
void mdss_mdp_irq_disable_nosync(u32 intr_type, u32 intf_num);
+7 −0
Original line number Diff line number Diff line
@@ -1176,6 +1176,13 @@ static int mdss_mdp_setup_vsync(struct mdss_mdp_cmd_ctx *ctx,
			/* disable clocks and irq */
			mdss_mdp_irq_disable(MDSS_MDP_IRQ_PING_PONG_RD_PTR,
				ctx->pp_num);
			/*
			 * check the intr status and clear the irq before
			 * disabling the clocks
			 */
			mdss_mdp_intr_check_and_clear(
				MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num);

			mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
		}
	}