--- 836c18a27bcbb141834142d8ef349ce93f61a922 +++ be241950481568b272594a73c1b7e7242dd11873 @@ -204,6 +204,8 @@ int mdp4_dsi_video_pipe_commit(int cndx, } mutex_unlock(&vctrl->update_lock); + /* free previous committed iommu back to pool */ + mdp4_overlay_iommu_unmap_freelist(mixer); spin_lock_irqsave(&vctrl->spin_lock, flags); if (vctrl->ov_koff != vctrl->ov_done) { @@ -233,13 +235,16 @@ int mdp4_dsi_video_pipe_commit(int cndx, cnt++; real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx); if (real_pipe && real_pipe->pipe_used) { - /* - * commit pipes which are in pending queue - * and not be unset yet - */ + /* pipe not unset */ mdp4_overlay_vsync_commit(pipe); } - } + /* free previous iommu to freelist + * which will be freed at next + * pipe_commit + */ + mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0); + pipe->pipe_used = 0; /* clear */ + } } mdp4_mixer_stage_commit(mixer); @@ -247,35 +252,6 @@ int mdp4_dsi_video_pipe_commit(int cndx, /* start timing generator & mmu if they are not started yet */ mdp4_overlay_dsi_video_start(); - /* - * there has possibility that pipe commit come very close to next vsync - * this may cause two consecutive pie_commits happen within same vsync - * period which casue iommu page fault when previous iommu buffer - * freed. Set ION_IOMMU_UNMAP_DELAYED flag at ion_map_iommu() to - * add delay unmap iommu buffer to fix this problem. - * Also ion_unmap_iommu() may take as long as 9 ms to free an ion buffer. - * therefore mdp4_overlay_iommu_unmap_freelist(mixer) should be called - * ater stage_commit() to ensure pipe_commit (up to stage_commit) - * is completed within vsync period. - */ - - /* free previous committed iommu back to pool */ - mdp4_overlay_iommu_unmap_freelist(mixer); - - pipe = vp->plist; - for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) { - if (pipe->pipe_used) { - - - /* free previous iommu to freelist - * which will be freed at next - * pipe_commit - */ - mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0); - pipe->pipe_used = 0; /* clear */ - } - } - pipe = vctrl->base_pipe; spin_lock_irqsave(&vctrl->spin_lock, flags); if (pipe->ov_blt_addr) { @@ -301,7 +277,7 @@ int mdp4_dsi_video_pipe_commit(int cndx, if (pipe->ov_blt_addr) mdp4_dsi_video_wait4ov(0); else - mdp4_dsi_video_wait4vsync(0); + mdp4_dsi_video_wait4dmap(0); } #ifdef MDP_ODD_RESOLUTION_CTRL current_pipe_ndx = pipe->pipe_ndx; @@ -475,9 +451,6 @@ ssize_t mdp4_dsi_video_show_event(struct ssize_t ret = 0; unsigned long flags; u64 vsync_tick; - ktime_t ctime; - u32 ctick, ptick; - int diff; cndx = 0; vctrl = &vsync_ctrl_db[0]; @@ -486,29 +459,6 @@ ssize_t mdp4_dsi_video_show_event(struct if (atomic_read(&vctrl->suspend) > 0 || atomic_read(&vctrl->vsync_resume) == 0) return 0; - /* - * show_event thread keep spinning on vctrl->vsync_comp - * race condition on x.done if multiple thread blocked - * at wait_for_completion(&vctrl->vsync_comp) - * - * if show_event thread waked up first then it will come back - * and call INIT_COMPLETION(vctrl->vsync_comp) which set x.done = 0 - * then second thread wakeed up which set x.done = 0x7ffffffd - * after that wait_for_completion will never wait. - * To avoid this, force show_event thread to sleep 5 ms here - * since it has full vsycn period (16.6 ms) to wait - */ - ctime = ktime_get(); - ctick = (u32)ktime_to_us(ctime); - ptick = (u32)ktime_to_us(vctrl->vsync_time); - ptick += 5000; /* 5ms */ - diff = ptick - ctick; - if (diff > 0) { - if (diff > 1000) /* 1 ms */ - diff = 1000; - usleep(diff); - } - spin_lock_irqsave(&vctrl->spin_lock, flags); if (vctrl->wait_vsync_cnt == 0) @@ -813,7 +763,6 @@ int mdp4_dsi_video_off(struct platform_d mdp4_dsi_video_wait4vsync(cndx); complete_all(&vctrl->vsync_comp); - vctrl->wait_vsync_cnt = 0; if (pipe == NULL) return -EINVAL; @@ -1034,11 +983,13 @@ void mdp4_primary_vsync_dsi_video(void) vctrl = &vsync_ctrl_db[cndx]; pr_debug("%s: cpu=%d\n", __func__, smp_processor_id()); - spin_lock(&vctrl->spin_lock); + spin_lock(&vctrl->spin_lock); + vctrl->vsync_time = ktime_get(); - vctrl->vsync_time = ktime_get(); - complete_all(&vctrl->vsync_comp); - vctrl->wait_vsync_cnt = 0; + if (vctrl->wait_vsync_cnt) { + complete_all(&vctrl->vsync_comp); + vctrl->wait_vsync_cnt = 0; + } spin_unlock(&vctrl->spin_lock); } @@ -1251,7 +1202,7 @@ void mdp4_dsi_video_overlay(struct msm_f if (pipe->ov_blt_addr) mdp4_dsi_video_wait4ov(cndx); else - mdp4_dsi_video_wait4vsync(cndx); + mdp4_dsi_video_wait4dmap(cndx); } mdp4_overlay_mdp_perf_upd(mfd, 0);