diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2015-07-02 19:41:31 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2015-07-02 19:41:30 -0700 |
commit | 981d47a1a61d9d461367b9792195770fa907013c (patch) | |
tree | a829a3e2e115b8ced37fbf3c266e8c9a0c8295c9 | |
parent | 9b803d0e4a10e1be55ac6ac98bf9ee3ed8a7eabc (diff) | |
parent | b1f427219d917ec7c017e95c86fd1bdd24d77b54 (diff) | |
download | qcom-981d47a1a61d9d461367b9792195770fa907013c.tar.gz |
Merge "msm: mdss: release mdp_busy flag at isr"
-rw-r--r-- | drivers/video/msm/mdss/mdss_dsi.h | 10 | ||||
-rw-r--r-- | drivers/video/msm/mdss/mdss_dsi_host.c | 97 |
2 files changed, 78 insertions, 29 deletions
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h index 0768e4def31..b31b3b1ae41 100644 --- a/drivers/video/msm/mdss/mdss_dsi.h +++ b/drivers/video/msm/mdss/mdss_dsi.h @@ -151,6 +151,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) @@ -166,6 +167,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 diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c index 1c78963893e..1bd6e72f7c9 100644 --- a/drivers/video/msm/mdss/mdss_dsi_host.c +++ b/drivers/video/msm/mdss/mdss_dsi_host.c @@ -509,6 +509,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 @@ -516,6 +519,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) { @@ -538,21 +545,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, @@ -571,7 +573,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); @@ -579,18 +580,11 @@ end: mdss_dsi_wait_clk_lane_to_stop(ctrl); ctrl->clk_lane_cnt = 0; - + mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0); release: - if (term == DSI_MDP_TERM) { - spin_lock_irqsave(&ctrl->mdp_lock, flags); - ctrl->mdp_busy = false; - complete_all(&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); - mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0); mutex_unlock(&ctrl->clk_lane_mutex); } @@ -620,10 +614,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, u32 event) @@ -1865,6 +1859,50 @@ 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; +} + int mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl) { unsigned long flags; @@ -1889,9 +1927,11 @@ int mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl) rc = 1; spin_unlock_irqrestore(&ctrl->mdp_lock, flags); if (!rc) { - pr_err("%s: timeout error\n", __func__); - MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0", "dsi1", + if (mdss_dsi_mdp_busy_tout_check(ctrl)) { + pr_err("%s: timeout error\n", __func__); + MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0", "dsi1", "edp", "hdmi", "panic"); + } } } @@ -1983,10 +2023,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->hw_rev == MDSS_DSI_HW_REV_103_1 && @@ -2191,7 +2229,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); if (todo & DSI_EV_LP_RX_TIMEOUT) { mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1); @@ -2374,12 +2412,13 @@ irqreturn_t mdss_dsi_isr(int irq, void *ptr) mdss_dsi_disable_irq_nosync(ctrl, DSI_MDP_TERM); if (ctrl->hw_rev == MDSS_DSI_HW_REV_103_1 && 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_all(&ctrl->mdp_comp); } + ctrl->mdp_busy = false; + complete_all(&ctrl->mdp_comp); spin_unlock(&ctrl->mdp_lock); } |