diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h index f7c9758e032..b4e20e36985 100644 --- a/drivers/video/msm/mdp4.h +++ b/drivers/video/msm/mdp4.h @@ -554,11 +554,11 @@ void mdp4_overlay0_done_dsi_video(int cndx); void mdp4_overlay0_done_dsi_cmd(int cndx); void mdp4_primary_rdptr(void); void mdp4_dsi_cmd_overlay(struct msm_fb_data_type *mfd); -int mdp4_overlay_commit(struct fb_info *info, int mixer); -int mdp4_dsi_video_pipe_commit(void); -int mdp4_dsi_cmd_pipe_commit(void); -int mdp4_lcdc_pipe_commit(void); -int mdp4_dtv_pipe_commit(void); +int mdp4_dsi_video_pipe_commit(int cndx, int wait); +int mdp4_dsi_cmd_pipe_commit(int cndx, int wait); +int mdp4_lcdc_pipe_commit(int cndx, int wait); +int mdp4_dtv_pipe_commit(int cndx, int wait); +int mdp4_dsi_cmd_update_cnt(int cndx); void mdp4_dsi_rdptr_init(int cndx); void mdp4_dsi_vsync_init(int cndx); void mdp4_lcdc_vsync_init(int cndx); @@ -586,6 +586,7 @@ int mdp4_overlay_unset_mixer(int mixer); int mdp4_overlay_play_wait(struct fb_info *info, struct msmfb_overlay_data *req); int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req); +int mdp4_overlay_commit(struct fb_info *info, int mixer); struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(int ptype, int mixer); void mdp4_overlay_dma_commit(int mixer); void mdp4_overlay_vsync_commit(struct mdp4_overlay_pipe *pipe); diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c index a13f158298a..d1f72a9de94 100644 --- a/drivers/video/msm/mdp4_overlay.c +++ b/drivers/video/msm/mdp4_overlay.c @@ -3351,8 +3351,7 @@ int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req) if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) { /* cndx = 0 */ mdp4_dsi_cmd_pipe_queue(0, pipe); - } - if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) { + } else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) { /* cndx = 0 */ mdp4_dsi_video_pipe_queue(0, pipe); } else if (ctrl->panel_mode & MDP4_PANEL_LCDC) { @@ -3414,6 +3413,46 @@ end: return ret; } +int mdp4_overlay_commit(struct fb_info *info, int mixer) +{ + struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; + + if (mfd == NULL) + return -ENODEV; + + if (!mfd->panel_power_on) /* suspended */ + return -EINVAL; + + if (mixer >= MDP4_MIXER_MAX) + return -EPERM; + + mutex_lock(&mfd->dma->ov_mutex); + + mdp4_overlay_mdp_perf_upd(mfd, 1); + + if (mixer == MDP4_MIXER0) { + if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) { + /* cndx = 0 */ + mdp4_dsi_cmd_pipe_commit(0, 1); + } else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) { + /* cndx = 0 */ + mdp4_dsi_video_pipe_commit(0, 1); + } else if (ctrl->panel_mode & MDP4_PANEL_LCDC) { + /* cndx = 0 */ + mdp4_lcdc_pipe_commit(0, 1); + } + } else if (mixer == MDP4_MIXER1) { + if (ctrl->panel_mode & MDP4_PANEL_DTV) + mdp4_dtv_pipe_commit(0, 1); + } + + mdp4_overlay_mdp_perf_upd(mfd, 0); + + mutex_unlock(&mfd->dma->ov_mutex); + + return 0; +} + struct msm_iommu_ctx { char *name; int domain; diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c index dd0385657ff..838fd487cff 100644 --- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c +++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c @@ -320,7 +320,7 @@ void mdp4_dsi_cmd_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe) static void mdp4_dsi_cmd_blt_ov_update(struct mdp4_overlay_pipe *pipe); -int mdp4_dsi_cmd_pipe_commit(void) +int mdp4_dsi_cmd_pipe_commit(int cndx, int wait) { int i, undx; int mixer = 0; @@ -447,6 +447,12 @@ int mdp4_dsi_cmd_pipe_commit(void) mdp4_stat.overlay_commit[pipe->mixer_num]++; + if (wait) { + long long tick; + + mdp4_dsi_cmd_wait4vsync(0, &tick); + } + return cnt; } @@ -1088,7 +1094,7 @@ void mdp4_dsi_cmd_overlay(struct msm_fb_data_type *mfd) int cndx = 0; struct vsycn_ctrl *vctrl; struct mdp4_overlay_pipe *pipe; - long long xx; + long long tick; vctrl = &vsync_ctrl_db[cndx]; @@ -1110,12 +1116,10 @@ void mdp4_dsi_cmd_overlay(struct msm_fb_data_type *mfd) mdp4_overlay_mdp_perf_upd(mfd, 1); mutex_lock(&mfd->dma->ov_mutex); - mdp4_dsi_cmd_pipe_commit(); + mdp4_dsi_cmd_pipe_commit(0, 0); mutex_unlock(&mfd->dma->ov_mutex); - mdp4_dsi_cmd_wait4vsync(0, &xx); - vctrl->expire_tick = VSYNC_EXPIRE_TICK; - vctrl->clk_control = 1; + mdp4_dsi_cmd_wait4vsync(0, &tick); mdp4_overlay_mdp_perf_upd(mfd, 0); } diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c index 9f94271d7e4..3507d6fbc7d 100644 --- a/drivers/video/msm/mdp4_overlay_dsi_video.c +++ b/drivers/video/msm/mdp4_overlay_dsi_video.c @@ -147,7 +147,7 @@ static void mdp4_dsi_video_blt_ov_update(struct mdp4_overlay_pipe *pipe); static void mdp4_dsi_video_wait4dmap(int cndx); static void mdp4_dsi_video_wait4ov(int cndx); -int mdp4_dsi_video_pipe_commit(void) +int mdp4_dsi_video_pipe_commit(int cndx, int wait) { int i, undx; @@ -159,7 +159,7 @@ int mdp4_dsi_video_pipe_commit(void) unsigned long flags; int cnt = 0; - vctrl = &vsync_ctrl_db[0]; + vctrl = &vsync_ctrl_db[cndx]; mutex_lock(&vctrl->update_lock); undx = vctrl->update_ndx; @@ -253,6 +253,13 @@ int mdp4_dsi_video_pipe_commit(void) mdp4_stat.overlay_commit[pipe->mixer_num]++; + if (wait) { + if (pipe->ov_blt_addr) + mdp4_dsi_video_wait4ov(0); + else + mdp4_dsi_video_wait4dmap(0); + } + return cnt; } @@ -1055,7 +1062,7 @@ void mdp4_dsi_video_overlay(struct msm_fb_data_type *mfd) mdp4_overlay_mdp_perf_upd(mfd, 1); mutex_lock(&mfd->dma->ov_mutex); - mdp4_dsi_video_pipe_commit(); + mdp4_dsi_video_pipe_commit(0, 0); mutex_unlock(&mfd->dma->ov_mutex); if (pipe->ov_blt_addr) diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c index 1a68268f15b..d0347aaa6b2 100644 --- a/drivers/video/msm/mdp4_overlay_dtv.c +++ b/drivers/video/msm/mdp4_overlay_dtv.c @@ -164,7 +164,7 @@ void mdp4_dtv_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe) static void mdp4_dtv_blt_ov_update(struct mdp4_overlay_pipe *pipe); static void mdp4_dtv_wait4dmae(int cndx); -int mdp4_dtv_pipe_commit(void) +int mdp4_dtv_pipe_commit(int cndx, int wait) { int i, undx; @@ -176,7 +176,7 @@ int mdp4_dtv_pipe_commit(void) unsigned long flags; int cnt = 0; - vctrl = &vsync_ctrl_db[0]; + vctrl = &vsync_ctrl_db[cndx]; mutex_lock(&vctrl->update_lock); undx = vctrl->update_ndx; vp = &vctrl->vlist[undx]; @@ -235,6 +235,9 @@ int mdp4_dtv_pipe_commit(void) spin_unlock_irqrestore(&vctrl->spin_lock, flags); mdp4_stat.overlay_commit[pipe->mixer_num]++; + if (wait) + mdp4_dtv_wait4dmae(0); + return cnt; } @@ -563,10 +566,8 @@ int mdp4_dtv_off(struct platform_device *pdev) struct msm_fb_data_type *mfd; int ret = 0; int cndx = 0; - int undx; struct vsycn_ctrl *vctrl; struct mdp4_overlay_pipe *pipe; - struct vsync_update *vp; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); @@ -577,10 +578,6 @@ int mdp4_dtv_off(struct platform_device *pdev) while (vctrl->wait_vsync_cnt) msleep(20); /* >= 17 ms */ - undx = vctrl->update_ndx; - vp = &vctrl->vlist[undx]; - vp->update_cnt = 0; /* empty queue */ - pipe = vctrl->base_pipe; if (pipe != NULL) { mdp4_dtv_stop(mfd); @@ -1017,6 +1014,6 @@ void mdp4_dtv_overlay(struct msm_fb_data_type *mfd) } mutex_lock(&mfd->dma->ov_mutex); - mdp4_dtv_pipe_commit(); + mdp4_dtv_pipe_commit(0, 0); mutex_unlock(&mfd->dma->ov_mutex); } diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c index 065562f3154..27854f34541 100644 --- a/drivers/video/msm/mdp4_overlay_lcdc.c +++ b/drivers/video/msm/mdp4_overlay_lcdc.c @@ -152,7 +152,7 @@ static void mdp4_lcdc_blt_ov_update(struct mdp4_overlay_pipe *pipe); static void mdp4_lcdc_wait4dmap(int cndx); static void mdp4_lcdc_wait4ov(int cndx); -int mdp4_lcdc_pipe_commit(void) +int mdp4_lcdc_pipe_commit(int cndx, int wait) { int i, undx; @@ -164,7 +164,7 @@ int mdp4_lcdc_pipe_commit(void) unsigned long flags; int cnt = 0; - vctrl = &vsync_ctrl_db[0]; + vctrl = &vsync_ctrl_db[cndx]; mutex_lock(&vctrl->update_lock); undx = vctrl->update_ndx; @@ -257,6 +257,13 @@ int mdp4_lcdc_pipe_commit(void) mdp4_stat.overlay_commit[pipe->mixer_num]++; + if (wait) { + if (pipe->ov_blt_addr) + mdp4_lcdc_wait4ov(0); + else + mdp4_lcdc_wait4dmap(0); + } + return cnt; } @@ -921,7 +928,7 @@ void mdp4_lcdc_overlay(struct msm_fb_data_type *mfd) mdp4_overlay_mdp_perf_upd(mfd, 1); mutex_lock(&mfd->dma->ov_mutex); - mdp4_lcdc_pipe_commit(); + mdp4_lcdc_pipe_commit(0, 0); mutex_unlock(&mfd->dma->ov_mutex); if (pipe->ov_blt_addr) diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c index e476e3ec47b..a1ec42ef476 100644 --- a/drivers/video/msm/msm_fb.c +++ b/drivers/video/msm/msm_fb.c @@ -3006,6 +3006,20 @@ static int msmfb_overlay_play_wait(struct fb_info *info, unsigned long *argp) return ret; } +static int msmfb_overlay_commit(struct fb_info *info, unsigned long *argp) +{ + int ret, ndx; + + ret = copy_from_user(&ndx, argp, sizeof(ndx)); + if (ret) { + printk(KERN_ERR "%s:msmfb_overlay_unset ioctl failed \n", + __func__); + return ret; + } + + return mdp4_overlay_commit(info, ndx); +} + static int msmfb_overlay_play(struct fb_info *info, unsigned long *argp) { int ret; @@ -3485,6 +3499,11 @@ static int msm_fb_ioctl(struct fb_info *info, unsigned int cmd, ret = msmfb_overlay_unset(info, argp); up(&msm_fb_ioctl_ppp_sem); break; + case MSMFB_OVERLAY_COMMIT: + down(&msm_fb_ioctl_ppp_sem); + ret = msmfb_overlay_commit(info, argp); + up(&msm_fb_ioctl_ppp_sem); + break; case MSMFB_OVERLAY_PLAY: down(&msm_fb_ioctl_ppp_sem); ret = msmfb_overlay_play(info, argp); diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h index cca61859a5b..1305fe7d763 100644 --- a/include/linux/msm_mdp.h +++ b/include/linux/msm_mdp.h @@ -71,6 +71,8 @@ #define MSMFB_OVERLAY_VSYNC_CTRL _IOW(MSMFB_IOCTL_MAGIC, 160, unsigned int) #define MSMFB_VSYNC_CTRL _IOW(MSMFB_IOCTL_MAGIC, 161, unsigned int) #define MSMFB_BUFFER_SYNC _IOW(MSMFB_IOCTL_MAGIC, 162, struct mdp_buf_sync) +#define MSMFB_OVERLAY_COMMIT _IOW(MSMFB_IOCTL_MAGIC, 163, unsigned int) + #define FB_TYPE_3D_PANEL 0x10101010 #define MDP_IMGTYPE2_START 0x10000 #define MSMFB_DRIVER_VERSION 0xF9E8D701