void mdp4_mddi_overlay(struct msm_fb_data_type *mfd) { mutex_lock(&mfd->dma->ov_mutex); #ifdef MDP4_NONBLOCKING if (mfd && mfd->panel_power_on) { #else if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) { #endif mdp4_overlay_update_lcd(mfd); #ifdef MDP4_MDDI_DMA_SWITCH if (mdp4_overlay_pipe_staged(mddi_pipe->mixer_num) <= 1) { mdp4_dma_s_update_lcd(mfd, mddi_pipe); mdp4_mddi_dma_s_kickoff(mfd, mddi_pipe); } else #endif mdp4_mddi_overlay_kickoff(mfd, mddi_pipe); mdp4_stat.kickoff_mddi++; /* signal if pan function is waiting for the update completion */ if (mfd->pan_waiting) { mfd->pan_waiting = FALSE; complete(&mfd->pan_comp); } } mutex_unlock(&mfd->dma->ov_mutex); }
void mdp4_mddi_overlay_kickoff(struct msm_fb_data_type *mfd, struct mdp4_overlay_pipe *pipe) { #ifdef MDP4_NONBLOCKING unsigned long flag; if (pipe == mddi_pipe) { if (mdp4_overlay_pipe_staged(pipe->mixer_num) > 1) { if (time_before(jiffies, (mddi_last_kick + mddi_kick_interval/2))) { mdp4_stat.kickoff_mddi_skip++; return; } } } spin_lock_irqsave(&mdp_spin_lock, flag); if (mfd->dma->busy == TRUE) { INIT_COMPLETION(pipe->comp); pending_pipe = pipe; } spin_unlock_irqrestore(&mdp_spin_lock, flag); if (pending_pipe != NULL) { wait_for_completion_killable(&pipe->comp); pending_pipe = NULL; } down(&mfd->sem); mdp_enable_irq(MDP_OVERLAY0_TERM); mfd->dma->busy = TRUE; mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd); if (pipe != mddi_pipe) { int intv; intv = jiffies - mddi_last_kick; mddi_kick_interval += intv; mddi_kick_interval /= 2; mddi_last_kick = jiffies; } up(&mfd->sem); #else down(&mfd->sem); mdp_enable_irq(MDP_OVERLAY0_TERM); mfd->dma->busy = TRUE; INIT_COMPLETION(pipe->comp); pending_pipe = pipe; mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd); up(&mfd->sem); wait_for_completion_killable(&pipe->comp); mdp_disable_irq(MDP_OVERLAY0_TERM); #endif }
void mdp4_mddi_overlay(struct msm_fb_data_type *mfd) { mutex_lock(&mfd->dma->ov_mutex); if (mfd && mfd->panel_power_on) { #ifndef CONFIG_SHLCDC_BOARD mdp4_mddi_dma_busy_wait(mfd); #endif /*CONFIG_SHLCDC_BOARD*/ mdp4_overlay_update_lcd(mfd); if (mdp_hw_revision < MDP4_REVISION_V2_1) { /* dmas dmap switch */ #ifdef CONFIG_SHLCDC_BOARD if ((mdp4_overlay_pipe_staged(mddi_pipe->mixer_num) <= 1) && ( mddi_pipe->src_h == mddi_pipe->dst_h ) && ( mddi_pipe->src_w == mddi_pipe->dst_w )) { #else if (mdp4_overlay_mixer_play(mddi_pipe->mixer_num) == 0) { #endif /* CONFIG_SHLCDC_BOARD */ mdp4_dma_s_update_lcd(mfd, mddi_pipe); mdp4_mddi_dma_s_kickoff(mfd, mddi_pipe); } else mdp4_mddi_kickoff_ui(mfd, mddi_pipe); } else /* no dams dmap switch */ mdp4_mddi_kickoff_ui(mfd, mddi_pipe); mdp4_stat.kickoff_mddi++; /* signal if pan function is waiting for the update completion */ if (mfd->pan_waiting) { mfd->pan_waiting = FALSE; complete(&mfd->pan_comp); } } mdp4_overlay_resource_release(); mutex_unlock(&mfd->dma->ov_mutex); } int mdp4_mddi_overlay_cursor(struct fb_info *info, struct fb_cursor *cursor) { struct msm_fb_data_type *mfd = info->par; mutex_lock(&mfd->dma->ov_mutex); if (mfd && mfd->panel_power_on) { #ifndef CONFIG_SHLCDC_BOARD mdp4_mddi_dma_busy_wait(mfd); #endif /* CONFIG_SHLCDC_BOARD */ mdp_hw_cursor_update(info, cursor); } mutex_unlock(&mfd->dma->ov_mutex); return 0; }
void mdp4_mddi_overlay_kickoff(struct msm_fb_data_type *mfd, struct mdp4_overlay_pipe *pipe) { #ifdef MDP4_NONBLOCKING unsigned long flag; /* use dma_p(overlay) pipe ,change bpp into 16 */ #ifdef CONFIG_FB_MSM_BPP_SWITCH if(16 != mfd->panel_info.bpp) { mdp4_switch_bpp_config(mfd,16); } #endif if (pipe == mddi_pipe) { /* base layer */ if (mdp4_overlay_pipe_staged(pipe->mixer_num) > 1) { if (time_before(jiffies, (mddi_last_kick + mddi_kick_interval/2))) { mdp4_stat.kickoff_mddi_skip++; return; /* let other pipe to kickoff */ } } } spin_lock_irqsave(&mdp_spin_lock, flag); if (mfd->dma->busy == TRUE) { INIT_COMPLETION(pipe->comp); pending_pipe = pipe; } spin_unlock_irqrestore(&mdp_spin_lock, flag); if (pending_pipe != NULL) { /* wait until DMA finishes the current job */ #ifdef CONFIG_HUAWEI_KERNEL wait_for_completion_interruptible_timeout(&pipe->comp, 1 * HZ); #else wait_for_completion_killable(&pipe->comp); #endif pending_pipe = NULL; } down(&mfd->sem); mdp_enable_irq(MDP_OVERLAY0_TERM); mfd->dma->busy = TRUE; /* start OVERLAY pipe */ mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd); if (pipe != mddi_pipe) { /* non base layer */ int intv; if (mddi_last_kick == 0) intv = 0; else intv = jiffies - mddi_last_kick; mddi_kick_interval += intv; mddi_kick_interval /= 2; /* average */ mddi_last_kick = jiffies; } up(&mfd->sem); #else down(&mfd->sem); mdp_enable_irq(MDP_OVERLAY0_TERM); mfd->dma->busy = TRUE; INIT_COMPLETION(pipe->comp); pending_pipe = pipe; /* start OVERLAY pipe */ mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd); up(&mfd->sem); /* wait until DMA finishes the current job */ #ifdef CONFIG_HUAWEI_KERNEL wait_for_completion_interruptible_timeout(&pipe->comp, 1 * HZ); #else wait_for_completion_killable(&pipe->comp); #endif mdp_disable_irq(MDP_OVERLAY0_TERM); #endif }
void mdp4_mddi_overlay_kickoff(struct msm_fb_data_type *mfd, struct mdp4_overlay_pipe *pipe) { #ifdef MDP4_NONBLOCKING unsigned long flag; if (pipe == mddi_pipe) { /* base layer */ if (mdp4_overlay_pipe_staged(pipe->mixer_num) > 1) { if (time_before(jiffies, (mddi_last_kick + mddi_kick_interval/2))) { mdp4_stat.kickoff_mddi_skip++; return; /* let other pipe to kickoff */ } } } spin_lock_irqsave(&mdp_spin_lock, flag); if (mfd->dma->busy == TRUE) { INIT_COMPLETION(pipe->comp); pending_pipe = pipe; } spin_unlock_irqrestore(&mdp_spin_lock, flag); if (pending_pipe != NULL) { /* wait until DMA finishes the current job */ wait_for_completion_killable(&pipe->comp); pending_pipe = NULL; } down(&mfd->sem); mdp_enable_irq(MDP_OVERLAY0_TERM); mfd->dma->busy = TRUE; /* start OVERLAY pipe */ mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd); if (pipe != mddi_pipe) { /* non base layer */ int intv; if (mddi_last_kick == 0) intv = 0; else intv = jiffies - mddi_last_kick; mddi_kick_interval += intv; mddi_kick_interval /= 2; /* average */ mddi_last_kick = jiffies; } up(&mfd->sem); #else down(&mfd->sem); mdp_enable_irq(MDP_OVERLAY0_TERM); mfd->dma->busy = TRUE; INIT_COMPLETION(pipe->comp); pending_pipe = pipe; /* start OVERLAY pipe */ mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd); up(&mfd->sem); /* wait until DMA finishes the current job */ wait_for_completion_killable(&pipe->comp); mdp_disable_irq(MDP_OVERLAY0_TERM); #endif }