msm: mdss: release mdp_busy flag at isr
Release mdp_busy flag a CMD_MDP_DONE isr while doing hs_clk_lane recovery to mitigate possibility of causing false mdp_busy time out whey system load is heavy. Also checking CMD_MDP_DONE isr status before declare mdp_busy timeout. CRs-Fixed: 823949 Change-Id: Ia5fe60c9799944b8867c262661c4cd97cffba1c7 Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>
This commit is contained in:
parent
ea354ea3e4
commit
67500148ea
2 changed files with 86 additions and 31 deletions
|
@ -153,6 +153,7 @@ enum dsi_pm_type {
|
|||
#define DSI_CMD_DST_FORMAT_RGB666 7
|
||||
#define DSI_CMD_DST_FORMAT_RGB888 8
|
||||
|
||||
#define DSI_INTR_DESJEW_MASK BIT(31)
|
||||
#define DSI_INTR_DYNAMIC_REFRESH_MASK BIT(29)
|
||||
#define DSI_INTR_DYNAMIC_REFRESH_DONE BIT(28)
|
||||
#define DSI_INTR_ERROR_MASK BIT(25)
|
||||
|
@ -168,6 +169,15 @@ enum dsi_pm_type {
|
|||
/* Update this if more interrupt masks are added in future chipsets */
|
||||
#define DSI_INTR_TOTAL_MASK 0x2222AA02
|
||||
|
||||
#define DSI_INTR_MASK_ALL \
|
||||
(DSI_INTR_DESJEW_MASK | \
|
||||
DSI_INTR_DYNAMIC_REFRESH_MASK | \
|
||||
DSI_INTR_ERROR_MASK | \
|
||||
DSI_INTR_BTA_DONE_MASK | \
|
||||
DSI_INTR_VIDEO_DONE_MASK | \
|
||||
DSI_INTR_CMD_MDP_DONE_MASK | \
|
||||
DSI_INTR_CMD_DMA_DONE_MASK)
|
||||
|
||||
#define DSI_CMD_TRIGGER_NONE 0x0 /* mdp trigger */
|
||||
#define DSI_CMD_TRIGGER_TE 0x02
|
||||
#define DSI_CMD_TRIGGER_SW 0x04
|
||||
|
|
|
@ -512,6 +512,9 @@ static void mdss_dsi_wait_clk_lane_to_stop(struct mdss_dsi_ctrl_pdata *ctrl)
|
|||
/* clear clk lane tx stop -- bit 20 */
|
||||
mdss_dsi_cfg_lane_ctrl(ctrl, BIT(20), 0);
|
||||
}
|
||||
|
||||
static void mdss_dsi_stop_hs_clk_lane(struct mdss_dsi_ctrl_pdata *ctrl);
|
||||
|
||||
/*
|
||||
* mdss_dsi_start_hs_clk_lane:
|
||||
* this function is work around solution for 8994 dsi clk lane
|
||||
|
@ -519,6 +522,10 @@ static void mdss_dsi_wait_clk_lane_to_stop(struct mdss_dsi_ctrl_pdata *ctrl)
|
|||
*/
|
||||
static void mdss_dsi_start_hs_clk_lane(struct mdss_dsi_ctrl_pdata *ctrl)
|
||||
{
|
||||
|
||||
/* make sure clk lane is stopped */
|
||||
mdss_dsi_stop_hs_clk_lane(ctrl);
|
||||
|
||||
mutex_lock(&ctrl->clk_lane_mutex);
|
||||
mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1);
|
||||
if (ctrl->clk_lane_cnt) {
|
||||
|
@ -541,21 +548,16 @@ static void mdss_dsi_start_hs_clk_lane(struct mdss_dsi_ctrl_pdata *ctrl)
|
|||
* this function is work around solution for 8994 dsi clk lane
|
||||
* may stuck at HS problem
|
||||
*/
|
||||
static void mdss_dsi_stop_hs_clk_lane(struct mdss_dsi_ctrl_pdata *ctrl,
|
||||
u32 term)
|
||||
static void mdss_dsi_stop_hs_clk_lane(struct mdss_dsi_ctrl_pdata *ctrl)
|
||||
{
|
||||
u32 fifo = 0;
|
||||
u32 lane = 0;
|
||||
unsigned long flags;
|
||||
|
||||
mutex_lock(&ctrl->clk_lane_mutex);
|
||||
mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1);
|
||||
if (ctrl->clk_lane_cnt != 1) {
|
||||
pr_err("%s: ndx=%d wait had been done, cnt=%d\n",
|
||||
__func__, ctrl->ndx, ctrl->clk_lane_cnt);
|
||||
if (ctrl->clk_lane_cnt == 0) /* stopped already */
|
||||
goto release;
|
||||
}
|
||||
|
||||
mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1);
|
||||
/* fifo */
|
||||
if (readl_poll_timeout(((ctrl->ctrl_base) + 0x000c),
|
||||
fifo,
|
||||
|
@ -574,7 +576,6 @@ static void mdss_dsi_stop_hs_clk_lane(struct mdss_dsi_ctrl_pdata *ctrl,
|
|||
pr_err("%s: datalane NOT stopped, lane=%x\n",
|
||||
__func__, lane);
|
||||
}
|
||||
|
||||
end:
|
||||
/* stop force clk lane hs */
|
||||
mdss_dsi_cfg_lane_ctrl(ctrl, BIT(28), 0);
|
||||
|
@ -582,14 +583,7 @@ end:
|
|||
mdss_dsi_wait_clk_lane_to_stop(ctrl);
|
||||
|
||||
ctrl->clk_lane_cnt = 0;
|
||||
|
||||
release:
|
||||
if (term == DSI_MDP_TERM) {
|
||||
spin_lock_irqsave(&ctrl->mdp_lock, flags);
|
||||
ctrl->mdp_busy = false;
|
||||
complete(&ctrl->mdp_comp);
|
||||
spin_unlock_irqrestore(&ctrl->mdp_lock, flags);
|
||||
}
|
||||
pr_debug("%s: ndx=%d, cnt=%d\n", __func__,
|
||||
ctrl->ndx, ctrl->clk_lane_cnt);
|
||||
|
||||
|
@ -623,10 +617,10 @@ static void mdss_dsi_cmd_stop_hs_clk_lane(struct mdss_dsi_ctrl_pdata *ctrl)
|
|||
mctrl = mdss_dsi_get_other_ctrl(ctrl);
|
||||
|
||||
if (mctrl)
|
||||
mdss_dsi_stop_hs_clk_lane(mctrl, DSI_CMD_TERM);
|
||||
mdss_dsi_stop_hs_clk_lane(mctrl);
|
||||
}
|
||||
|
||||
mdss_dsi_stop_hs_clk_lane(ctrl, DSI_CMD_TERM);
|
||||
mdss_dsi_stop_hs_clk_lane(ctrl);
|
||||
}
|
||||
|
||||
static void mdss_dsi_ctl_phy_reset(struct mdss_dsi_ctrl_pdata *ctrl)
|
||||
|
@ -1931,10 +1925,55 @@ void mdss_dsi_cmd_mdp_start(struct mdss_dsi_ctrl_pdata *ctrl)
|
|||
spin_unlock_irqrestore(&ctrl->mdp_lock, flag);
|
||||
}
|
||||
|
||||
static int mdss_dsi_mdp_busy_tout_check(struct mdss_dsi_ctrl_pdata *ctrl)
|
||||
{
|
||||
unsigned long flag;
|
||||
u32 isr;
|
||||
bool stop_hs_clk = false;
|
||||
int tout = 1;
|
||||
|
||||
/*
|
||||
* two possible scenario:
|
||||
* 1) DSI_INTR_CMD_MDP_DONE set but isr not fired
|
||||
* 2) DSI_INTR_CMD_MDP_DONE set and cleared (isr fired)
|
||||
* but event_thread not wakeup
|
||||
*/
|
||||
mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1);
|
||||
spin_lock_irqsave(&ctrl->mdp_lock, flag);
|
||||
|
||||
isr = MIPI_INP(ctrl->ctrl_base + 0x0110);
|
||||
if (isr & DSI_INTR_CMD_MDP_DONE) {
|
||||
WARN(1, "INTR_CMD_MDP_DONE set but isr not fired\n");
|
||||
isr &= DSI_INTR_MASK_ALL;
|
||||
isr |= DSI_INTR_CMD_MDP_DONE; /* clear this isr only */
|
||||
MIPI_OUTP(ctrl->ctrl_base + 0x0110, isr);
|
||||
mdss_dsi_disable_irq_nosync(ctrl, DSI_MDP_TERM);
|
||||
ctrl->mdp_busy = false;
|
||||
if (ctrl->cmd_clk_ln_recovery_en &&
|
||||
ctrl->panel_mode == DSI_CMD_MODE) {
|
||||
/* has hs_lane_recovery do the work */
|
||||
stop_hs_clk = true;
|
||||
}
|
||||
tout = 0; /* recovered */
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&ctrl->mdp_lock, flag);
|
||||
|
||||
if (stop_hs_clk)
|
||||
mdss_dsi_stop_hs_clk_lane(ctrl);
|
||||
|
||||
complete_all(&ctrl->mdp_comp);
|
||||
|
||||
mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0);
|
||||
|
||||
return tout;
|
||||
}
|
||||
|
||||
void mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl)
|
||||
{
|
||||
unsigned long flags;
|
||||
int need_wait = 0;
|
||||
int rc;
|
||||
|
||||
pr_debug("%s: start pid=%d\n",
|
||||
__func__, current->pid);
|
||||
|
@ -1949,11 +1988,18 @@ void mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl)
|
|||
/* wait until DMA finishes the current job */
|
||||
pr_debug("%s: pending pid=%d\n",
|
||||
__func__, current->pid);
|
||||
if (!wait_for_completion_timeout(&ctrl->mdp_comp,
|
||||
msecs_to_jiffies(DMA_TX_TIMEOUT))) {
|
||||
rc = wait_for_completion_timeout(&ctrl->mdp_comp,
|
||||
msecs_to_jiffies(DMA_TX_TIMEOUT));
|
||||
spin_lock_irqsave(&ctrl->mdp_lock, flags);
|
||||
if (!ctrl->mdp_busy)
|
||||
rc = 1;
|
||||
spin_unlock_irqrestore(&ctrl->mdp_lock, flags);
|
||||
if (!rc) {
|
||||
if (mdss_dsi_mdp_busy_tout_check(ctrl)) {
|
||||
pr_err("%s: timeout error\n", __func__);
|
||||
MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl", "dsi0_phy",
|
||||
"dsi1_ctrl", "dsi1_phy", "panic");
|
||||
MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl",
|
||||
"dsi0_phy", "dsi1_ctrl", "dsi1_phy", "panic");
|
||||
}
|
||||
}
|
||||
}
|
||||
pr_debug("%s: done pid=%d\n", __func__, current->pid);
|
||||
|
@ -2037,10 +2083,8 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
|
|||
/*
|
||||
* when partial update enabled, the roi of pinfo
|
||||
* is updated before mdp kickoff. Either width or
|
||||
* height of roi is 0, then it is false kickoff so
|
||||
* no mdp_busy flag set needed.
|
||||
* when partial update disabled, mdp_busy flag
|
||||
* alway set.
|
||||
* height of roi is non zero, then really kickoff
|
||||
* will followed.
|
||||
*/
|
||||
if (!roi || (roi->w != 0 || roi->h != 0)) {
|
||||
if (ctrl->cmd_clk_ln_recovery_en &&
|
||||
|
@ -2261,7 +2305,7 @@ static int dsi_event_thread(void *data)
|
|||
}
|
||||
|
||||
if (todo & DSI_EV_STOP_HS_CLK_LANE)
|
||||
mdss_dsi_stop_hs_clk_lane(ctrl, arg);
|
||||
mdss_dsi_stop_hs_clk_lane(ctrl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2469,12 +2513,13 @@ irqreturn_t mdss_dsi_isr(int irq, void *ptr)
|
|||
mdss_dsi_disable_irq_nosync(ctrl, DSI_MDP_TERM);
|
||||
if (ctrl->cmd_clk_ln_recovery_en &&
|
||||
ctrl->panel_mode == DSI_CMD_MODE) {
|
||||
/* stop force clk lane hs */
|
||||
mdss_dsi_cfg_lane_ctrl(ctrl, BIT(28), 0);
|
||||
dsi_send_events(ctrl, DSI_EV_STOP_HS_CLK_LANE,
|
||||
DSI_MDP_TERM);
|
||||
} else {
|
||||
ctrl->mdp_busy = false;
|
||||
complete(&ctrl->mdp_comp);
|
||||
}
|
||||
ctrl->mdp_busy = false;
|
||||
complete_all(&ctrl->mdp_comp);
|
||||
spin_unlock(&ctrl->mdp_lock);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue