void mdp4_dsi_video_wait4vsync(int cndx) { struct vsycn_ctrl *vctrl; struct mdp4_overlay_pipe *pipe; int ret; if (cndx >= MAX_CONTROLLER) { pr_err("%s: out or range: cndx=%d\n", __func__, cndx); return; } vctrl = &vsync_ctrl_db[cndx]; pipe = vctrl->base_pipe; if (atomic_read(&vctrl->suspend) > 0) return; mdp4_video_vsync_irq_ctrl(cndx, 1); ret = wait_event_interruptible_timeout(vctrl->wait_queue, 1, msecs_to_jiffies(VSYNC_PERIOD * 8)); if (ret <= 0) pr_err("%s timeout ret=%d", __func__, ret); mdp4_video_vsync_irq_ctrl(cndx, 0); mdp4_stat.wait4vsync0++; }
void mdp4_dsi_video_wait4vsync(int cndx) { struct vsycn_ctrl *vctrl; int ret; ktime_t timestamp; unsigned long flags; if (cndx >= MAX_CONTROLLER) { pr_err("%s: out or range: cndx=%d\n", __func__, cndx); return; } vctrl = &vsync_ctrl_db[cndx]; 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_timeout(vctrl->wait_queue_internal, !ktime_equal(timestamp, vctrl->vsync_time), msecs_to_jiffies(VSYNC_PERIOD * 8)); if (ret <= 0) pr_err("%s timeout ret=%d", __func__, ret); mdp4_video_vsync_irq_ctrl(cndx, 0); mdp4_stat.wait4vsync0++; }
void mdp4_dsi_video_wait4vsync(int cndx) { struct vsycn_ctrl *vctrl; struct mdp4_overlay_pipe *pipe; unsigned long flags; if (cndx >= MAX_CONTROLLER) { pr_err("%s: out or range: cndx=%d\n", __func__, cndx); return; } vctrl = &vsync_ctrl_db[cndx]; pipe = vctrl->base_pipe; if (atomic_read(&vctrl->suspend) > 0) return; mdp4_video_vsync_irq_ctrl(cndx, 1); spin_lock_irqsave(&vctrl->spin_lock, flags); if (vctrl->wait_vsync_cnt == 0) INIT_COMPLETION(vctrl->vsync_comp); vctrl->wait_vsync_cnt++; spin_unlock_irqrestore(&vctrl->spin_lock, flags); wait_for_completion(&vctrl->vsync_comp); mdp4_video_vsync_irq_ctrl(cndx, 0); mdp4_stat.wait4vsync0++; }
void mdp4_dsi_video_wait4vsync(int cndx) { struct vsycn_ctrl *vctrl; struct mdp4_overlay_pipe *pipe; unsigned long flags; int ret; if (cndx >= MAX_CONTROLLER) { pr_err("%s: out or range: cndx=%d\n", __func__, cndx); return; } vctrl = &vsync_ctrl_db[cndx]; pipe = vctrl->base_pipe; if (atomic_read(&vctrl->suspend) > 0) return; mdp4_video_vsync_irq_ctrl(cndx, 1); spin_lock_irqsave(&vctrl->spin_lock, flags); if (vctrl->wait_vsync_cnt == 0) INIT_COMPLETION(vctrl->vsync_comp); vctrl->wait_vsync_cnt++; spin_unlock_irqrestore(&vctrl->spin_lock, flags); /* double the timeout in vsync time stamp generation */ ret = wait_for_completion_interruptible_timeout(&vctrl->vsync_comp, msecs_to_jiffies(VSYNC_PERIOD * 8)); if (ret <= 0) pr_err("%s timeout ret=%d", __func__, ret); mdp4_video_vsync_irq_ctrl(cndx, 0); mdp4_stat.wait4vsync0++; }
void mdp4_dsi_video_wait4vsync(int cndx) { struct vsycn_ctrl *vctrl; struct mdp4_overlay_pipe *pipe; int ret; unsigned int data; if (cndx >= MAX_CONTROLLER) { pr_err("%s: out or range: cndx=%d\n", __func__, cndx); return; } vctrl = &vsync_ctrl_db[cndx]; pipe = vctrl->base_pipe; data = inpdw(MDP_BASE + DSI_VIDEO_BASE); data &= 0x01; if (data == 0 || !dsi_video_enabled) /* timing generator disabled */ return; mdp4_video_vsync_irq_ctrl(cndx, 1); ret = wait_event_interruptible_timeout(vctrl->wait_queue, 1, msecs_to_jiffies(VSYNC_PERIOD * 8)); if (ret <= 0) pr_err("%s timeout ret=%d", __func__, ret); mdp4_video_vsync_irq_ctrl(cndx, 0); mdp4_stat.wait4vsync0++; }
void mdp4_dsi_video_wait4vsync(int cndx) { struct vsycn_ctrl *vctrl; struct mdp4_overlay_pipe *pipe; unsigned long flags; unsigned long result; if (cndx >= MAX_CONTROLLER) { pr_err("%s: out or range: cndx=%d\n", __func__, cndx); return; } vctrl = &vsync_ctrl_db[cndx]; pipe = vctrl->base_pipe; if (atomic_read(&vctrl->suspend) > 0) return; mdp4_video_vsync_irq_ctrl(cndx, 1); spin_lock_irqsave(&vctrl->spin_lock, flags); if (vctrl->wait_vsync_cnt == 0) INIT_COMPLETION(vctrl->vsync_comp); vctrl->wait_vsync_cnt++; spin_unlock_irqrestore(&vctrl->spin_lock, flags); result = wait_for_completion_timeout(&vctrl->vsync_comp, msecs_to_jiffies(100)); if (!result) { printk(KERN_INFO "[DEBUG]%s. There's no interrupt!!\n", __func__); complete_all(&vctrl->vsync_comp); } mdp4_video_vsync_irq_ctrl(cndx, 0); mdp4_stat.wait4vsync0++; }
void mdp4_dsi_video_wait4vsync(int cndx) { struct vsycn_ctrl *vctrl; struct mdp4_overlay_pipe *pipe; unsigned long flags; if (cndx >= MAX_CONTROLLER) { pr_err("%s: out or range: cndx=%d\n", __func__, cndx); return; } vctrl = &vsync_ctrl_db[cndx]; pipe = vctrl->base_pipe; if (atomic_read(&vctrl->suspend) > 0) return; mdp4_video_vsync_irq_ctrl(cndx, 1); spin_lock_irqsave(&vctrl->spin_lock, flags); if (vctrl->wait_vsync_cnt == 0) INIT_COMPLETION(vctrl->vsync_comp); vctrl->wait_vsync_cnt++; spin_unlock_irqrestore(&vctrl->spin_lock, flags); /* OPPO 3013-04-18 Gousj modify for black screen when phone call come*/ /* wait_for_completion(&vctrl->vsync_comp) * have no timeout */ if (!wait_for_completion_timeout( &vctrl->vsync_comp, msecs_to_jiffies(100))) pr_err("%s %d TIMEOUT_\n", __func__, __LINE__); /* OPPO 3013-04-18 Gousj modify for black screen when phone call come*/ mdp4_video_vsync_irq_ctrl(cndx, 0); mdp4_stat.wait4vsync0++; }
void mdp4_dsi_video_vsync_ctrl(struct fb_info *info, int enable) { struct vsycn_ctrl *vctrl; int cndx = 0; vctrl = &vsync_ctrl_db[cndx]; if (vctrl->vsync_irq_enabled == enable) return; pr_debug("%s: vsync enable=%d\n", __func__, enable); vctrl->vsync_irq_enabled = enable; mdp4_video_vsync_irq_ctrl(cndx, enable); }
void mdp4_dsi_video_vsync_ctrl(struct fb_info *info, int enable) { struct vsycn_ctrl *vctrl; int cndx = 0; vctrl = &vsync_ctrl_db[cndx]; if (vctrl->vsync_irq_enabled == enable) return; pr_debug("%s: vsync enable=%d\n", __func__, enable); vctrl->vsync_irq_enabled = enable; mdp4_video_vsync_irq_ctrl(cndx, enable); if (vctrl->vsync_irq_enabled && atomic_read(&vctrl->suspend) == 0) atomic_set(&vctrl->vsync_resume, 1); }
int mdp4_dsi_video_off(struct platform_device *pdev) { int ret = 0; int cndx = 0; struct msm_fb_data_type *mfd; struct vsycn_ctrl *vctrl; struct mdp4_overlay_pipe *pipe; struct vsync_update *vp; unsigned long flags; int mixer = 0; int undx, need_wait = 0; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); mutex_lock(&mfd->dma->ov_mutex); vctrl = &vsync_ctrl_db[cndx]; pipe = vctrl->base_pipe; mdp4_dsi_video_wait4vsync(cndx); if (pipe == NULL) return -EINVAL; if (pipe->ov_blt_addr) { spin_lock_irqsave(&vctrl->spin_lock, flags); if (vctrl->ov_koff != vctrl->ov_done) need_wait = 1; spin_unlock_irqrestore(&vctrl->spin_lock, flags); if (need_wait) mdp4_dsi_video_wait4ov(0); } mdp_histogram_ctrl_all(FALSE); dsi_video_enabled = 0; undx = vctrl->update_ndx; vp = &vctrl->vlist[undx]; if (vp->update_cnt) { /* * pipe's iommu will be freed at next overlay play * and iommu_drop statistic will be increased by one */ pr_warn("%s: update_cnt=%d\n", __func__, vp->update_cnt); mdp4_dsi_video_pipe_clean(vp); } if (pipe) { /* sanity check, free pipes besides base layer */ mixer = pipe->mixer_num; mdp4_overlay_unset_mixer(mixer); if (mfd->ref_cnt == 0) { /* adb stop */ if (pipe->pipe_type == OVERLAY_TYPE_BF) mdp4_overlay_borderfill_stage_down(pipe); /* base pipe may change after borderfill_stage_down */ pipe = vctrl->base_pipe; mdp4_mixer_stage_down(pipe, 1); mdp4_overlay_pipe_free(pipe, 1); vctrl->base_pipe = NULL; } else { /* system suspending */ mdp4_mixer_stage_down(vctrl->base_pipe, 1); mdp4_overlay_iommu_pipe_free( vctrl->base_pipe->pipe_ndx, 1); } } mdp4_dsi_video_tg_off(vctrl); atomic_set(&vctrl->suspend, 1); if (vctrl->vsync_irq_enabled) { vctrl->vsync_irq_enabled = 0; mdp4_video_vsync_irq_ctrl(cndx, 0); } /* * clean up ion freelist * there need two stage to empty ion free list * therefore need call unmap freelist twice */ mdp4_overlay_iommu_unmap_freelist(mixer); mdp4_overlay_iommu_unmap_freelist(mixer); /* mdp clock off */ mdp_clk_ctrl(0); mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); mutex_unlock(&mfd->dma->ov_mutex); return ret; }
int mdp4_dsi_video_off(struct platform_device *pdev) { int ret = 0; int cndx = 0; struct msm_fb_data_type *mfd; struct vsycn_ctrl *vctrl; struct mdp4_overlay_pipe *pipe; struct vsync_update *vp; unsigned long flags; int mixer = 0; int undx, need_wait = 0; #if defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_HD_PT) \ || defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_FHD_INVERSE_PT) \ || defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_FHD_INVERSE_PT_PANEL) \ || defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_WUXGA_PT) \ || defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_WUXGA_INVERSE_PT) int retry_cnt = 0; #endif printk(KERN_INFO "%s is started.. \n", __func__); #if defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_HD_PT) \ || defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_FHD_INVERSE_PT) \ || defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_FHD_INVERSE_PT_PANEL) \ || defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_WUXGA_PT) \ || defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_WUXGA_INVERSE_PT) do { ret = mipi_lgit_lcd_off(pdev); if (ret < 0) { panel_next_off(pdev); msleep(2); panel_next_on(pdev); msleep(5); retry_cnt++; } else { // if upper routine is successed, need to initialize ret variable. ret = 0; break; } } while(retry_cnt < 10); printk(KERN_INFO "%s : mipi_lgit_lcd_off retry_cnt = %d\n", __func__, retry_cnt); #endif mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); mutex_lock(&mfd->dma->ov_mutex); vctrl = &vsync_ctrl_db[cndx]; pipe = vctrl->base_pipe; mdp4_dsi_video_wait4vsync(cndx); if (pipe->ov_blt_addr) { spin_lock_irqsave(&vctrl->spin_lock, flags); if (vctrl->ov_koff != vctrl->ov_done) need_wait = 1; spin_unlock_irqrestore(&vctrl->spin_lock, flags); if (need_wait) mdp4_dsi_video_wait4ov(0); } mdp_histogram_ctrl_all(FALSE); dsi_video_enabled = 0; undx = vctrl->update_ndx; vp = &vctrl->vlist[undx]; if (vp->update_cnt) { /* * pipe's iommu will be freed at next overlay play * and iommu_drop statistic will be increased by one */ pr_warn("%s: update_cnt=%d\n", __func__, vp->update_cnt); mdp4_dsi_video_pipe_clean(vp); } if (pipe) { /* sanity check, free pipes besides base layer */ mixer = pipe->mixer_num; mdp4_overlay_unset_mixer(mixer); if (mfd->ref_cnt == 0) { /* adb stop */ if (pipe->pipe_type == OVERLAY_TYPE_BF) mdp4_overlay_borderfill_stage_down(pipe); /* base pipe may change after borderfill_stage_down */ pipe = vctrl->base_pipe; mdp4_mixer_stage_down(pipe, 1); mdp4_overlay_pipe_free(pipe, 1); vctrl->base_pipe = NULL; } else { /* system suspending */ mdp4_mixer_stage_down(vctrl->base_pipe, 1); mdp4_overlay_iommu_pipe_free( vctrl->base_pipe->pipe_ndx, 1); } } mdp4_dsi_video_tg_off(vctrl); atomic_set(&vctrl->suspend, 1); if (vctrl->vsync_irq_enabled) { vctrl->vsync_irq_enabled = 0; mdp4_video_vsync_irq_ctrl(cndx, 0); } /* * clean up ion freelist * there need two stage to empty ion free list * therefore need call unmap freelist twice */ mdp4_overlay_iommu_unmap_freelist(mixer); mdp4_overlay_iommu_unmap_freelist(mixer); /* mdp clock off */ mdp_clk_ctrl(0); mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); printk(KERN_INFO "%s is ended.. \n", __func__); mutex_unlock(&mfd->dma->ov_mutex); return ret; }