mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
msm: msm_fb: wait for VSYNC instead of DMA_P for commit completion.
In the current implementation, we are waiting for DMA_P interrupt in commit call to signal completion. This can cause 2 commits happening in the same vsync period due to which IOMMU page faults can happen when vsync comes while second commit is programming resgisters. To avoid this, wait for DMA_P is replaced by wait for VSYNC. Change-Id: I68d4d4b4e7a574f86faecd5b4812e1f5852f4209 Signed-off-by: Vishnuvardhan Prodduturi <vproddut@codeaurora.org>
This commit is contained in:
parent
3c4ccf282e
commit
77e93ca69c
1 changed files with 18 additions and 9 deletions
|
@ -66,6 +66,7 @@ static struct vsycn_ctrl {
|
|||
struct vsync_update vlist[2];
|
||||
int vsync_irq_enabled;
|
||||
ktime_t vsync_time;
|
||||
wait_queue_head_t wait_queue_internal;
|
||||
wait_queue_head_t wait_queue;
|
||||
} vsync_ctrl_db[MAX_CONTROLLER];
|
||||
|
||||
|
@ -266,10 +267,6 @@ int mdp4_dsi_video_pipe_commit(int cndx, int wait)
|
|||
/* kickoff overlay engine */
|
||||
mdp4_stat.kickoff_ov0++;
|
||||
outpdw(MDP_BASE + 0x0004, 0);
|
||||
} else {
|
||||
/* schedule second phase update at dmap */
|
||||
INIT_COMPLETION(vctrl->dmap_comp);
|
||||
vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
|
||||
}
|
||||
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
|
||||
|
||||
|
@ -279,7 +276,7 @@ int mdp4_dsi_video_pipe_commit(int cndx, int wait)
|
|||
if (pipe->ov_blt_addr)
|
||||
mdp4_dsi_video_wait4ov(0);
|
||||
else
|
||||
mdp4_dsi_video_wait4dmap(0);
|
||||
mdp4_dsi_video_wait4vsync(0);
|
||||
}
|
||||
|
||||
return cnt;
|
||||
|
@ -329,8 +326,9 @@ void mdp4_dsi_video_vsync_ctrl(struct fb_info *info, int enable)
|
|||
void mdp4_dsi_video_wait4vsync(int cndx)
|
||||
{
|
||||
struct vsycn_ctrl *vctrl;
|
||||
struct mdp4_overlay_pipe *pipe;
|
||||
int ret;
|
||||
ktime_t timestamp;
|
||||
unsigned long flags;
|
||||
|
||||
if (cndx >= MAX_CONTROLLER) {
|
||||
pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
|
||||
|
@ -338,14 +336,16 @@ void mdp4_dsi_video_wait4vsync(int cndx)
|
|||
}
|
||||
|
||||
vctrl = &vsync_ctrl_db[cndx];
|
||||
pipe = vctrl->base_pipe;
|
||||
|
||||
if (atomic_read(&vctrl->suspend) > 0)
|
||||
return;
|
||||
spin_lock_irqsave(&vctrl->spin_lock, flags);
|
||||
timestamp = vctrl->vsync_time;
|
||||
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
|
||||
|
||||
mdp4_video_vsync_irq_ctrl(cndx, 1);
|
||||
|
||||
ret = wait_event_interruptible_timeout(vctrl->wait_queue, 1,
|
||||
ret = wait_event_timeout(vctrl->wait_queue_internal,
|
||||
!ktime_equal(timestamp, vctrl->vsync_time),
|
||||
msecs_to_jiffies(VSYNC_PERIOD * 8));
|
||||
|
||||
if (ret <= 0)
|
||||
|
@ -417,10 +417,14 @@ ssize_t mdp4_dsi_video_show_event(struct device *dev,
|
|||
ssize_t ret = 0;
|
||||
u64 vsync_tick;
|
||||
ktime_t timestamp;
|
||||
unsigned long flags;
|
||||
|
||||
cndx = 0;
|
||||
vctrl = &vsync_ctrl_db[0];
|
||||
|
||||
spin_lock_irqsave(&vctrl->spin_lock, flags);
|
||||
timestamp = vctrl->vsync_time;
|
||||
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
|
||||
|
||||
ret = wait_event_interruptible(vctrl->wait_queue,
|
||||
!ktime_equal(timestamp, vctrl->vsync_time) &&
|
||||
|
@ -428,7 +432,10 @@ ssize_t mdp4_dsi_video_show_event(struct device *dev,
|
|||
if (ret == -ERESTARTSYS)
|
||||
return ret;
|
||||
|
||||
spin_lock_irqsave(&vctrl->spin_lock, flags);
|
||||
vsync_tick = ktime_to_ns(vctrl->vsync_time);
|
||||
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
|
||||
|
||||
ret = scnprintf(buf, PAGE_SIZE, "VSYNC=%llu", vsync_tick);
|
||||
buf[strlen(buf) + 1] = '\0';
|
||||
return ret;
|
||||
|
@ -456,6 +463,7 @@ void mdp4_dsi_vsync_init(int cndx)
|
|||
init_completion(&vctrl->ov_comp);
|
||||
atomic_set(&vctrl->suspend, 1);
|
||||
spin_lock_init(&vctrl->spin_lock);
|
||||
init_waitqueue_head(&vctrl->wait_queue_internal);
|
||||
init_waitqueue_head(&vctrl->wait_queue);
|
||||
}
|
||||
|
||||
|
@ -977,6 +985,7 @@ void mdp4_primary_vsync_dsi_video(void)
|
|||
|
||||
spin_lock(&vctrl->spin_lock);
|
||||
vctrl->vsync_time = ktime_get();
|
||||
wake_up_all(&vctrl->wait_queue_internal);
|
||||
wake_up_interruptible_all(&vctrl->wait_queue);
|
||||
spin_unlock(&vctrl->spin_lock);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue