summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2015-07-02 19:41:31 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2015-07-02 19:41:30 -0700
commit981d47a1a61d9d461367b9792195770fa907013c (patch)
treea829a3e2e115b8ced37fbf3c266e8c9a0c8295c9
parent9b803d0e4a10e1be55ac6ac98bf9ee3ed8a7eabc (diff)
parentb1f427219d917ec7c017e95c86fd1bdd24d77b54 (diff)
downloadqcom-981d47a1a61d9d461367b9792195770fa907013c.tar.gz
Merge "msm: mdss: release mdp_busy flag at isr"
-rw-r--r--drivers/video/msm/mdss/mdss_dsi.h10
-rw-r--r--drivers/video/msm/mdss/mdss_dsi_host.c97
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);
}