summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_host.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c
index fca1d37b40bb..88f6b9040651 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_host.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_host.c
@@ -1488,11 +1488,15 @@ 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;
+ struct mdss_panel_info *pinfo;
- if (ctrl->panel_mode == DSI_CMD_MODE)
+ /* for dsi 2.1 and above dma scheduling is used */
+ if ((!ctrl) || (ctrl->panel_mode == DSI_CMD_MODE) ||
+ (ctrl->shared_data->hw_rev > MDSS_DSI_HW_REV_200))
return ret;
+ pinfo = &ctrl->panel_data.panel_info;
+
if (ctrl->ctrl_state & CTRL_STATE_MDP_ACTIVE) {
mdss_dsi_wait4video_done(ctrl);
v_total = mdss_panel_get_vtotal(pinfo);
@@ -1512,12 +1516,39 @@ static int mdss_dsi_wait4video_eng_busy(struct mdss_dsi_ctrl_pdata *ctrl)
return ret;
}
+static void mdss_dsi_schedule_dma_cmd(struct mdss_dsi_ctrl_pdata *ctrl)
+{
+ u32 v_blank, val = 0x0;
+ struct mdss_panel_info *pinfo;
+
+ /* for dsi 2.0 and below dma scheduling is not supported */
+ if ((!ctrl) || (ctrl->panel_mode == DSI_CMD_MODE) ||
+ (ctrl->shared_data->hw_rev < MDSS_DSI_HW_REV_201))
+ return;
+
+ pinfo = &ctrl->panel_data.panel_info;
+ v_blank = pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width;
+
+ /* DMA_SCHEDULE_CTRL */
+ val = MIPI_INP(ctrl->ctrl_io.base + 0x100);
+ val = val | (1 << 28); /* DMA_SCHEDULE_EN */
+ MIPI_OUTP(ctrl->ctrl_io.base + 0x100, val);
+ val |= (pinfo->yres + v_blank);
+ MIPI_OUTP(ctrl->ctrl_io.base + 0x100, val); /* DMA_SCHEDULE_LINE */
+ wmb();
+
+ pr_debug("%s schedule at line %x", __func__, val);
+ MDSS_XLOG(ctrl->ndx, val);
+}
+
static void mdss_dsi_wait4active_region(struct mdss_dsi_ctrl_pdata *ctrl)
{
int in_blanking = 0;
int retry_count = 0;
- if (ctrl->panel_mode != DSI_VIDEO_MODE)
+ /* for dsi 2.1 and above dma scheduling is used */
+ if ((!ctrl) || (ctrl->panel_mode != DSI_VIDEO_MODE) ||
+ (ctrl->shared_data->hw_rev > MDSS_DSI_HW_REV_200))
return;
while (retry_count != MAX_BTA_WAIT_RETRY) {
@@ -2204,6 +2235,10 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
MIPI_OUTP((ctrl->ctrl_base) + 0x04c, len);
wmb();
+ /* schedule dma cmds at start of blanking region */
+ mdss_dsi_schedule_dma_cmd(ctrl);
+
+ /* DSI_CMD_MODE_DMA_SW_TRIGGER */
MIPI_OUTP((ctrl->ctrl_base) + 0x090, 0x01);
wmb();
MDSS_XLOG(ctrl->dma_addr, len);