summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshish Garg <ashigarg@codeaurora.org>2017-10-16 16:18:26 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2017-10-31 10:32:59 -0700
commit0d030ecce2fbe85ae841101be1ad2008d7c2f31c (patch)
tree4d38a3743b3b25678de4ff4b9b5d1c4596d49a08
parent9c23726ad4dfc95009710805647555503635ba2d (diff)
msm: mdss: add support for dma scheduling for dsi v2.1
Dsi controller v2.1 and above supports scheduling of dma commands. Schedule dsi cmds at the starting of blanking region to avoid sending of commands in active region resulting in dsi overflow errors. Change-Id: I658b7d7008eb9071148820c0ea949ae9ba593ed9 Signed-off-by: Ashish Garg <ashigarg@codeaurora.org>
-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);