msm_fb: display: Add MSMFB_OVERLAY_COMMIT ioctl.

MSMFB_OVERLAY_COMMIT ioctl is used to display on external.
This is used instead of the default PAN mechanism to avoid delays in that path.
This ioctl for external also waits for DMAE thus fixing tearing.

Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>
Signed-off-by: Arun Kumar K.R <akumarkr@codeaurora.org>
This commit is contained in:
Saurabh Shah
2012-09-27 12:47:10 -07:00
committed by Iliyan Malchev
parent d4e24fdbb1
commit 736cf9db3b
8 changed files with 104 additions and 28 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -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