diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c index 04ce8d6c11d2..734d3bee8fd0 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_host.c +++ b/drivers/video/fbdev/msm/mdss_dsi_host.c @@ -1425,6 +1425,35 @@ void mdss_dsi_ctrl_setup(struct mdss_dsi_ctrl_pdata *ctrl) mdss_dsi_op_mode_config(pdata->panel_info.mipi.mode, pdata); } +static int mdss_dsi_wait4video_eng_busy(struct mdss_dsi_ctrl_pdata *ctrl) +{ + int ret = 0; + u32 v_total = 0, v_blank = 0, sleep_ms = 0, fps = 0; + struct mdss_panel_info *pinfo = &ctrl->panel_data.panel_info; + + if (ctrl->panel_mode == DSI_CMD_MODE) + return ret; + + if (ctrl->ctrl_state & CTRL_STATE_MDP_ACTIVE) { + mdss_dsi_wait4video_done(ctrl); + v_total = mdss_panel_get_vtotal(pinfo); + v_blank = pinfo->lcdc.v_back_porch + pinfo->lcdc.v_front_porch + + pinfo->lcdc.v_pulse_width; + if (pinfo->dynamic_fps && pinfo->current_fps) + fps = pinfo->current_fps; + else + fps = pinfo->mipi.frame_rate; + + sleep_ms = CEIL((v_blank * 1000), (v_total * fps)) + 1; + /* delay sleep_ms to skip BLLP */ + if (sleep_ms) + udelay(sleep_ms * 1000); + ret = 1; + } + + return ret; +} + /** * mdss_dsi_bta_status_check() - Check dsi panel status through bta check * @ctrl_pdata: pointer to the dsi controller structure @@ -1465,6 +1494,7 @@ int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata) reinit_completion(&ctrl_pdata->bta_comp); mdss_dsi_enable_irq(ctrl_pdata, DSI_BTA_TERM); spin_unlock_irqrestore(&ctrl_pdata->mdp_lock, flag); + mdss_dsi_wait4video_eng_busy(ctrl_pdata); /* mask out overflow errors */ if (ignore_underflow) mdss_dsi_set_reg(ctrl_pdata, 0x10c, 0x0f0000, 0x0f0000); @@ -2350,15 +2380,20 @@ void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl) /* DSI_INTL_CTRL */ data = MIPI_INP((ctrl->ctrl_base) + 0x0110); data &= DSI_INTR_TOTAL_MASK; - data |= DSI_INTR_VIDEO_DONE_MASK; - MIPI_OUTP((ctrl->ctrl_base) + 0x0110, data); + /* clear previous VIDEO_DONE interrupt */ + MIPI_OUTP((ctrl->ctrl_base) + 0x0110, (data | DSI_INTR_VIDEO_DONE)); + wmb(); /* ensure interrupt is cleared */ spin_lock_irqsave(&ctrl->mdp_lock, flag); reinit_completion(&ctrl->video_comp); mdss_dsi_enable_irq(ctrl, DSI_VIDEO_TERM); spin_unlock_irqrestore(&ctrl->mdp_lock, flag); + data |= DSI_INTR_VIDEO_DONE_MASK; + MIPI_OUTP((ctrl->ctrl_base) + 0x0110, data); + wmb(); /* ensure interrupt is enabled */ + wait_for_completion_timeout(&ctrl->video_comp, msecs_to_jiffies(VSYNC_PERIOD * 4)); @@ -2368,35 +2403,6 @@ void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl) MIPI_OUTP((ctrl->ctrl_base) + 0x0110, data); } -static int mdss_dsi_wait4video_eng_busy(struct mdss_dsi_ctrl_pdata *ctrl) -{ - int ret = 0; - u32 v_total = 0, v_blank = 0, sleep_ms = 0, fps = 0; - struct mdss_panel_info *pinfo = &ctrl->panel_data.panel_info; - - if (ctrl->panel_mode == DSI_CMD_MODE) - return ret; - - if (ctrl->ctrl_state & CTRL_STATE_MDP_ACTIVE) { - mdss_dsi_wait4video_done(ctrl); - v_total = mdss_panel_get_vtotal(pinfo); - v_blank = pinfo->lcdc.v_back_porch + pinfo->lcdc.v_front_porch + - pinfo->lcdc.v_pulse_width; - if (pinfo->dynamic_fps && pinfo->current_fps) - fps = pinfo->current_fps; - else - fps = pinfo->mipi.frame_rate; - - sleep_ms = CEIL((v_blank * 1000), (v_total * fps)) + 1; - /* delay sleep_ms to skip BLLP */ - if (sleep_ms) - udelay(sleep_ms * 1000); - ret = 1; - } - - return ret; -} - void mdss_dsi_cmd_mdp_start(struct mdss_dsi_ctrl_pdata *ctrl) { unsigned long flag;