/* * mdp4_dsi_video_pipe_queue: * called from thread context */ void mdp4_dsi_video_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe) { struct vsycn_ctrl *vctrl; struct vsync_update *vp; struct mdp4_overlay_pipe *pp; int undx; if (cndx >= MAX_CONTROLLER) { pr_err("%s: out or range: cndx=%d\n", __func__, cndx); return; } /* start timing generator & mmu if they are not started yet */ mdp4_overlay_dsi_video_start(); vctrl = &vsync_ctrl_db[cndx]; if (atomic_read(&vctrl->suspend) > 0) return; mutex_lock(&vctrl->update_lock); undx = vctrl->update_ndx; vp = &vctrl->vlist[undx]; pp = &vp->plist[pipe->pipe_ndx - 1]; /* ndx start form 1 */ pr_debug("%s: vndx=%d pipe=%x ndx=%d num=%d pid=%d\n", __func__, undx, (int)pipe, pipe->pipe_ndx, pipe->pipe_num, current->pid); *pp = *pipe; /* clone it */ vp->update_cnt++; mutex_unlock(&vctrl->update_lock); mdp4_stat.overlay_play[pipe->mixer_num]++; }
void mdp4_dsi_video_wait4vsync(int cndx, long long *vtime) { 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) { *vtime = -1; return; } /* start timing generator & mmu if they are not started yet */ mdp4_overlay_dsi_video_start(); 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_stat.wait4vsync0++; *vtime = ktime_to_ns(vctrl->vsync_time); }
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; if (enable) { #ifdef CONFIG_MACH_LGE /* */ if (!dsi_video_enabled) mdp4_overlay_dsi_video_start(); #endif vsync_irq_enable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM); } else { vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM); } if (vctrl->vsync_irq_enabled && atomic_read(&vctrl->suspend) == 0) atomic_set(&vctrl->vsync_resume, 1); }
void mdp4_dsi_video_overlay(struct msm_fb_data_type *mfd) { struct fb_info *fbi = mfd->fbi; uint8 *buf; unsigned int buf_offset; int bpp; struct mdp4_overlay_pipe *pipe; if (!mfd->panel_power_on) return; /* no need to power on cmd block since it's dsi video mode */ bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf_offset = calc_fb_offset(mfd, fbi, bpp); mutex_lock(&mfd->dma->ov_mutex); pipe = dsi_pipe; if (mfd->display_iova) pipe->srcp0_addr = mfd->display_iova + buf_offset; else pipe->srcp0_addr = (uint32)(buf + buf_offset); mdp4_overlay_rgb_setup(pipe); mdp4_overlay_reg_flush(pipe, 0); mdp4_mixer_stage_up(pipe); mdp4_overlay_dsi_video_start(); mdp4_overlay_dsi_video_vsync_push(mfd, pipe); mdp4_iommu_unmap(pipe); mutex_unlock(&mfd->dma->ov_mutex); }
void mdp4_dsi_video_overlay(struct msm_fb_data_type *mfd) { struct fb_info *fbi = mfd->fbi; uint8 *buf; unsigned int buf_offset; int bpp; struct mdp4_overlay_pipe *pipe; if (!mfd->panel_power_on) return; /* no need to power on cmd block since it's dsi video mode */ bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf_offset = calc_fb_offset(mfd, fbi, bpp); mutex_lock(&mfd->dma->ov_mutex); pipe = dsi_pipe; if (mfd->map_buffer) { pipe->srcp0_addr = (unsigned int)mfd->map_buffer->iova[0] + \ buf_offset; pr_debug("start 0x%lx srcp0_addr 0x%x\n", mfd-> map_buffer->iova[0], pipe->srcp0_addr); } else { pipe->srcp0_addr = (uint32)(buf + buf_offset); } #ifdef CONFIG_LGE_HIDDEN_RESET if (on_hidden_reset) pipe->srcp0_addr = (unsigned int)lge_get_hreset_fb_phys_addr(); #endif mdp4_overlay_rgb_setup(pipe); mdp4_mixer_stage_up(pipe); mdp4_overlay_reg_flush(pipe, 0); mdp4_overlay_dsi_video_start(); mdp4_overlay_dsi_video_vsync_push(mfd, pipe); mdp4_iommu_unmap(pipe); mutex_unlock(&mfd->dma->ov_mutex); }
int mipi_lgit_lcd_on(struct platform_device *pdev) { struct msm_fb_data_type *mfd; int rc = 0; int cnt = 0; mfd = platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; #ifdef LGIT_IEF_SWITCH if(local_mfd0 == NULL) local_mfd0 = mfd; #endif printk(KERN_INFO "%s is started ...\n", __func__); //LGE_UPDATE_S [email protected] : adding change mipi mode to write register setting of LCD IC MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000);//HS mode cnt = mipi_dsi_cmds_tx(mfd, &lgit_tx_buf, mipi_lgit_pdata->power_on_set_1, mipi_lgit_pdata->power_on_set_size_1); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000);//LP mode if (cnt < 0) return cnt; //LGE_UPDATE_E [email protected] : adding change mipi mode to write register setting of LCD IC mipi_dsi_op_mode_config(DSI_VIDEO_MODE); mdp4_overlay_dsi_video_start(); mdelay(10); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000);//HS mode cnt = mipi_dsi_cmds_tx(mfd, &lgit_tx_buf, mipi_lgit_pdata->power_on_set_2, mipi_lgit_pdata->power_on_set_size_2); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000);//LP mode if (cnt < 0) return cnt; rc = gpio_request(DSV_ONBST,"DSV_ONBST_en"); if (rc) { printk(KERN_INFO "%s: DSV_ONBST Request Fail \n", __func__); } else { rc = gpio_direction_output(DSV_ONBST, 1); // OUTPUT if (rc) { printk(KERN_INFO "%s: DSV_ONBST Direction Set Fail \n", __func__); } else { gpio_set_value(DSV_ONBST, 1); } gpio_free(DSV_ONBST); } mdelay(20); //LGE_UPDATE_S [email protected] : adding change mipi mode to write register setting of LCD IC MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000);//HS mode cnt = mipi_dsi_cmds_tx(mfd, &lgit_tx_buf, mipi_lgit_pdata->power_on_set_3, mipi_lgit_pdata->power_on_set_size_3); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000);//LP mode //LGE_UPDATE_E [email protected] : adding change mipi mode to write register setting of LCD IC printk(KERN_INFO "%s is ended... \n", __func__); return cnt; }
int mdp4_dsi_video_pipe_commit(int cndx, int wait) { static uint32 frameDropCnt = 0; // QC_1206 int lmCfg; // QC_1204 int i, undx; int mixer = 0; struct vsycn_ctrl *vctrl; struct vsync_update *vp; struct mdp4_overlay_pipe *pipe; struct mdp4_overlay_pipe *real_pipe; unsigned long flags; int cnt = 0; vctrl = &vsync_ctrl_db[cndx]; mutex_lock(&vctrl->update_lock); undx = vctrl->update_ndx; vp = &vctrl->vlist[undx]; pipe = vctrl->base_pipe; mixer = pipe->mixer_num; if (vp->update_cnt == 0) { mutex_unlock(&vctrl->update_lock); return cnt; } vctrl->update_ndx++; vctrl->update_ndx &= 0x01; vp->update_cnt = 0; /* reset */ if (vctrl->blt_free) { vctrl->blt_free--; // if (vctrl->blt_free == 0) // mdp4_free_writeback_buf(vctrl->mfd, mixer); } 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) { frameDropCnt++; // QC_1206 spin_unlock_irqrestore(&vctrl->spin_lock, flags); pr_err("%s: Error, frame dropped %d %d\n", __func__, vctrl->ov_koff, vctrl->ov_done); if (frameDropCnt >= 2) { // QC_1206 mdp4_dump_regs(); // QC_1205 lmCfg = inpdw(MDP_BASE + 0x10100); // QC_1204 pr_err("*** %s: lmCfg=%x, frameDropCnt=%d\n", __func__, lmCfg, frameDropCnt); // QC_1204 // retry ov0 pr_err("*** %s: Retrying OV0\n", __func__); // QC_1204 INIT_COMPLETION(vctrl->ov_comp); // QC_1204 vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM); // QC_1204 mb(); // QC_1204 outpdw(MDP_BASE + 0x0004, 0); // QC_1204 } return 0; } else { frameDropCnt = 0; // QC_1206 } spin_unlock_irqrestore(&vctrl->spin_lock, flags); mdp4_overlay_mdp_perf_upd(vctrl->mfd, 1); if (vctrl->blt_change) { pipe = vctrl->base_pipe; spin_lock_irqsave(&vctrl->spin_lock, flags); INIT_COMPLETION(vctrl->dmap_comp); INIT_COMPLETION(vctrl->ov_comp); vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM); spin_unlock_irqrestore(&vctrl->spin_lock, flags); mdp4_dsi_video_wait4dmap(0); if (pipe->ov_blt_addr) mdp4_dsi_video_wait4ov(0); } pipe = vp->plist; for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) { if (pipe->pipe_used) { cnt++; real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx); if (real_pipe && real_pipe->pipe_used) { /* 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); /* start timing generator & mmu if they are not started yet */ mdp4_overlay_dsi_video_start(); pipe = vctrl->base_pipe; spin_lock_irqsave(&vctrl->spin_lock, flags); if (pipe->ov_blt_addr) { mdp4_dsi_video_blt_ov_update(pipe); pipe->ov_cnt++; INIT_COMPLETION(vctrl->ov_comp); vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM); mb(); vctrl->ov_koff++; pr_err("*** %s: vctrl->ov_koff++=%d\n", __func__, vctrl->ov_koff); // QC_1204 lmCfg = inpdw(MDP_BASE + 0x10100); // QC_1204 pr_err("*** %s: lmCfg=%x\n", __func__, lmCfg); // QC_1204 /* 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); 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; }
int mdp4_dsi_video_pipe_commit(int cndx, int wait) { int i, undx; int mixer = 0; struct vsycn_ctrl *vctrl; struct vsync_update *vp; struct mdp4_overlay_pipe *pipe; struct mdp4_overlay_pipe *real_pipe; unsigned long flags; int cnt = 0; #ifdef MDP_ODD_RESOLUTION_CTRL int current_pipe_ndx = 0; #endif vctrl = &vsync_ctrl_db[cndx]; mutex_lock(&vctrl->update_lock); undx = vctrl->update_ndx; vp = &vctrl->vlist[undx]; pipe = vctrl->base_pipe; if (pipe == NULL) { pr_err("%s: NO base pipe\n", __func__); mutex_unlock(&vctrl->update_lock); return 0; } mixer = pipe->mixer_num; mdp_update_pm(vctrl->mfd, vctrl->vsync_time); /* * allow stage_commit without pipes queued * (vp->update_cnt == 0) to unstage pipes after * overlay_unset */ vctrl->update_ndx++; vctrl->update_ndx &= 0x01; vp->update_cnt = 0; /* reset */ if (vctrl->blt_free) { vctrl->blt_free--; if (vctrl->blt_free == 0) mdp4_free_writeback_buf(vctrl->mfd, mixer); } mutex_unlock(&vctrl->update_lock); spin_lock_irqsave(&vctrl->spin_lock, flags); if (vctrl->ov_koff != vctrl->ov_done) { spin_unlock_irqrestore(&vctrl->spin_lock, flags); pr_err("%s: Error, frame dropped %d %d\n", __func__, vctrl->ov_koff, vctrl->ov_done); return 0; } spin_unlock_irqrestore(&vctrl->spin_lock, flags); pipe = vp->plist; for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) { if (pipe->pipe_used) { 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 */ mdp4_overlay_vsync_commit(pipe); if (pipe->frame_format != MDP4_FRAME_FORMAT_LINEAR) { spin_lock_irqsave(&vctrl->spin_lock, flags); INIT_COMPLETION(vctrl->dmap_comp); vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM); spin_unlock_irqrestore(&vctrl->spin_lock, flags); } } } } mdp4_mixer_stage_commit(mixer); /* 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) { mdp4_dsi_video_blt_ov_update(pipe); pipe->ov_cnt++; INIT_COMPLETION(vctrl->ov_comp); vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM); mb(); vctrl->ov_koff++; /* 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); 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); } #ifdef MDP_ODD_RESOLUTION_CTRL current_pipe_ndx = pipe->pipe_ndx; for (i = current_pipe_ndx ; i >= 0; i--, pipe--) { pipe->check_odd_res = 0; } #endif return cnt; }
int mdp4_dsi_video_pipe_commit(int cndx, int wait) { int i, undx; int mixer = 0; struct vsycn_ctrl *vctrl; struct vsync_update *vp; struct mdp4_overlay_pipe *pipe; struct mdp4_overlay_pipe *real_pipe; unsigned long flags; int cnt = 0; vctrl = &vsync_ctrl_db[cndx]; mutex_lock(&vctrl->update_lock); undx = vctrl->update_ndx; vp = &vctrl->vlist[undx]; pipe = vctrl->base_pipe; mixer = pipe->mixer_num; mdp_update_pm(vctrl->mfd, vctrl->vsync_time); if (vp->update_cnt == 0) { mutex_unlock(&vctrl->update_lock); return cnt; } vctrl->update_ndx++; vctrl->update_ndx &= 0x01; vp->update_cnt = 0; /* reset */ if (vctrl->blt_free) { vctrl->blt_free--; if (vctrl->blt_free == 0) mdp4_free_writeback_buf(vctrl->mfd, mixer); } 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) { spin_unlock_irqrestore(&vctrl->spin_lock, flags); pr_err("%s: Error, frame dropped %d %d\n", __func__, vctrl->ov_koff, vctrl->ov_done); return 0; } spin_unlock_irqrestore(&vctrl->spin_lock, flags); #ifndef CONFIG_ARCH_MSM8X60 mdp4_overlay_mdp_perf_upd(vctrl->mfd, 1); if (vctrl->blt_change) { pipe = vctrl->base_pipe; spin_lock_irqsave(&vctrl->spin_lock, flags); INIT_COMPLETION(vctrl->dmap_comp); INIT_COMPLETION(vctrl->ov_comp); vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM); spin_unlock_irqrestore(&vctrl->spin_lock, flags); mdp4_dsi_video_wait4dmap(0); if (pipe->ov_blt_addr) mdp4_dsi_video_wait4ov(0); } #endif pipe = vp->plist; for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) { if (pipe->pipe_used) { cnt++; real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx); if (real_pipe && real_pipe->pipe_used) { /* pipe not unset */ mdp4_overlay_vsync_commit(pipe); if (pipe->frame_format != MDP4_FRAME_FORMAT_LINEAR) { spin_lock_irqsave(&vctrl->spin_lock, flags); INIT_COMPLETION(vctrl->dmap_comp); vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM); spin_unlock_irqrestore(&vctrl->spin_lock, flags); } } /* 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); /* start timing generator & mmu if they are not started yet */ mdp4_overlay_dsi_video_start(); pipe = vctrl->base_pipe; spin_lock_irqsave(&vctrl->spin_lock, flags); if (pipe->ov_blt_addr) { mdp4_dsi_video_blt_ov_update(pipe); pipe->ov_cnt++; INIT_COMPLETION(vctrl->ov_comp); vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM); mb(); vctrl->ov_koff++; /* 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); mdp4_stat.overlay_commit[pipe->mixer_num]++; if (wait) { if (pipe->ov_blt_addr) mdp4_dsi_video_wait4ov(cndx); else mdp4_dsi_video_wait4dmap(cndx); } return cnt; }
int mdp4_dsi_video_on(struct platform_device *pdev) { int dsi_width; int dsi_height; int dsi_bpp; int dsi_border_clr; int dsi_underflow_clr; int dsi_hsync_skew; int hsync_period; int hsync_ctrl; int vsync_period; int display_hctl; int display_v_start; int display_v_end; int active_hctl; int active_h_start; int active_h_end; int active_v_start; int active_v_end; int ctrl_polarity; int h_back_porch; int h_front_porch; int v_back_porch; int v_front_porch; int hsync_pulse_width; int vsync_pulse_width; int hsync_polarity; int vsync_polarity; int data_en_polarity; int hsync_start_x; int hsync_end_x; uint8 *buf; unsigned int buf_offset; int bpp, ptype; struct fb_info *fbi; struct fb_var_screeninfo *var; struct msm_fb_data_type *mfd; struct mdp4_overlay_pipe *pipe; int ret = 0; int cndx = 0; struct vsycn_ctrl *vctrl; struct msm_panel_info *pinfo; vctrl = &vsync_ctrl_db[cndx]; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); pinfo = &mfd->panel_info; if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; mutex_lock(&mfd->dma->ov_mutex); vctrl->mfd = mfd; vctrl->dev = mfd->fbi->dev; vctrl->blt_ctrl = pinfo->lcd.blt_ctrl; vctrl->vsync_irq_enabled = 0; vsync_irq_cnt = 0; /* mdp clock on */ mdp_clk_ctrl(1); fbi = mfd->fbi; var = &fbi->var; bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf_offset = calc_fb_offset(mfd, fbi, bpp); if (vctrl->base_pipe == NULL) { ptype = mdp4_overlay_format2type(mfd->fb_imgType); if (ptype < 0) printk(KERN_INFO "%s: format2type failed\n", __func__); pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0); if (pipe == NULL) { printk(KERN_INFO "%s: pipe_alloc failed\n", __func__); mutex_unlock(&mfd->dma->ov_mutex); return -EBUSY; } pipe->pipe_used++; pipe->mixer_stage = MDP4_MIXER_STAGE_BASE; pipe->mixer_num = MDP4_MIXER0; pipe->src_format = mfd->fb_imgType; mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_DSI_VIDEO); ret = mdp4_overlay_format2pipe(pipe); if (ret < 0) printk(KERN_INFO "%s: format2type failed\n", __func__); pipe->ov_blt_addr = 0; pipe->dma_blt_addr = 0; vctrl->base_pipe = pipe; /* keep it */ mdp4_init_writeback_buf(mfd, MDP4_MIXER0); } else { pipe = vctrl->base_pipe; } atomic_set(&vctrl->suspend, 0); pipe->src_height = fbi->var.yres; pipe->src_width = fbi->var.xres; pipe->src_h = fbi->var.yres; pipe->src_w = fbi->var.xres; pipe->src_y = 0; pipe->src_x = 0; pipe->dst_h = fbi->var.yres; pipe->dst_w = fbi->var.xres; pipe->srcp0_ystride = fbi->fix.line_length; pipe->bpp = bpp; if (mfd->display_iova) pipe->srcp0_addr = mfd->display_iova + buf_offset; else pipe->srcp0_addr = (uint32)(buf + buf_offset); pipe->dst_h = fbi->var.yres; pipe->dst_w = fbi->var.xres; mdp4_overlay_solidfill_init(pipe); mdp4_overlay_mdp_pipe_req(pipe, mfd); mdp4_calc_blt_mdp_bw(mfd, pipe); mdp4_overlay_dmap_xy(pipe); /* dma_p */ mdp4_overlay_dmap_cfg(mfd, 1); mdp4_overlay_rgb_setup(pipe); mdp4_overlayproc_cfg(pipe); mdp4_overlay_reg_flush(pipe, 1); mdp4_mixer_stage_up(pipe, 0); mdp4_mixer_stage_commit(pipe->mixer_num); /* * DSI timing setting */ h_back_porch = var->left_margin; h_front_porch = var->right_margin; v_back_porch = var->upper_margin; v_front_porch = var->lower_margin; hsync_pulse_width = var->hsync_len; vsync_pulse_width = var->vsync_len; dsi_border_clr = mfd->panel_info.lcdc.border_clr; dsi_underflow_clr = mfd->panel_info.lcdc.underflow_clr; dsi_hsync_skew = mfd->panel_info.lcdc.hsync_skew; dsi_width = mfd->panel_info.xres + mfd->panel_info.lcdc.xres_pad; dsi_height = mfd->panel_info.yres + mfd->panel_info.lcdc.yres_pad; dsi_bpp = mfd->panel_info.bpp; hsync_period = hsync_pulse_width + h_back_porch + dsi_width + h_front_porch; hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; hsync_start_x = h_back_porch + hsync_pulse_width; hsync_end_x = hsync_period - h_front_porch - 1; display_hctl = (hsync_end_x << 16) | hsync_start_x; vsync_period = (vsync_pulse_width + v_back_porch + dsi_height + v_front_porch); display_v_start = ((vsync_pulse_width + v_back_porch) * hsync_period) + dsi_hsync_skew; display_v_end = ((vsync_period - v_front_porch) * hsync_period) + dsi_hsync_skew - 1; if (dsi_width != var->xres) { active_h_start = hsync_start_x + first_pixel_start_x; active_h_end = active_h_start + var->xres - 1; active_hctl = ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start; } else { active_hctl = 0; } if (dsi_height != var->yres) { active_v_start = display_v_start + first_pixel_start_y * hsync_period; active_v_end = active_v_start + (var->yres) * hsync_period - 1; active_v_start |= ACTIVE_START_Y_EN; } else { active_v_start = 0; active_v_end = 0; } dsi_underflow_clr |= 0x80000000; /* enable recovery */ hsync_polarity = 0; vsync_polarity = 0; data_en_polarity = 0; ctrl_polarity = (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x4, hsync_ctrl); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x8, vsync_period * hsync_period); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0xc, vsync_pulse_width * hsync_period); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x10, display_hctl); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x14, display_v_start); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x18, display_v_end); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x1c, active_hctl); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x20, active_v_start); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x24, active_v_end); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x28, dsi_border_clr); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x2c, dsi_underflow_clr); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x30, dsi_hsync_skew); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x38, ctrl_polarity); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); mdp_histogram_ctrl_all(TRUE); mdp4_overlay_dsi_video_start(); mutex_unlock(&mfd->dma->ov_mutex); return ret; }
int mipi_lgit_lcd_on(struct platform_device *pdev) { int cnt = 0; bool cabc_off_state = 1; struct msm_fb_data_type *mfd; if (check_stable_lcd_on) mipi_stable_lcd_on(pdev); mfd = platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; #if defined(CONFIG_LGIT_COLOR_ENGINE_SWITCH) if(local_mfd0 == NULL) local_mfd0 = mfd; #endif pr_info("%s:+ wuxga \n", __func__); // //MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000); //HS mode cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set_1, mipi_lgit_pdata->power_on_set_size_1); if (cnt < 0) return cnt; #if defined(CONFIG_LGE_BACKLIGHT_CABC) cabc_off_state = lgit_lcd_cabc_state(); if (cabc_off_state == 1) { if ((mipi_lgit_pdata->power_on_set_3_noCABC != NULL) && (mipi_lgit_pdata->power_on_set_size_3_noCABC > 0)) { cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set_3_noCABC, mipi_lgit_pdata->power_on_set_size_3_noCABC); if (cnt < 0) return cnt; pr_info("%s: CABC OFF\n", __func__); } } else { if ((mipi_lgit_pdata->power_on_set_3 != NULL) && (mipi_lgit_pdata->power_on_set_size_3 > 0)) { cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set_3, mipi_lgit_pdata->power_on_set_size_3); if (cnt < 0) return cnt; pr_info("%s: CABC ON\n", __func__); } } #endif cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set_2, mipi_lgit_pdata->power_on_set_size_2); if (cnt < 0) return cnt; mipi_dsi_op_mode_config(DSI_VIDEO_MODE); mdp4_overlay_dsi_video_start(); mdelay(120); // pr_info("%s:- wuxga \n", __func__); return cnt; }
int mdp4_dsi_video_pipe_commit(int cndx, int wait, u32 *release_busy) { int i, undx; int mixer = 0; struct vsycn_ctrl *vctrl; struct vsync_update *vp; struct mdp4_overlay_pipe *pipe; struct mdp4_overlay_pipe *real_pipe; unsigned long flags; int cnt = 0; vctrl = &vsync_ctrl_db[cndx]; mutex_lock(&vctrl->update_lock); undx = vctrl->update_ndx; vp = &vctrl->vlist[undx]; pipe = vctrl->base_pipe; if (pipe == NULL) { pr_err("%s: NO base pipe\n", __func__); mutex_unlock(&vctrl->update_lock); return 0; } mixer = pipe->mixer_num; mdp_update_pm(vctrl->mfd, vctrl->vsync_time); /* * allow stage_commit without pipes queued * (vp->update_cnt == 0) to unstage pipes after * overlay_unset */ vctrl->update_ndx++; vctrl->update_ndx &= 0x01; vp->update_cnt = 0; /* reset */ if (vctrl->blt_free) { vctrl->blt_free--; if (vctrl->blt_free == 0) mdp4_free_writeback_buf(vctrl->mfd, mixer); } 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) { spin_unlock_irqrestore(&vctrl->spin_lock, flags); pr_err("%s: Error, frame dropped %d %d\n", __func__, vctrl->ov_koff, vctrl->ov_done); return 0; } spin_unlock_irqrestore(&vctrl->spin_lock, flags); pipe = vp->plist; for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) { if (pipe->pipe_used) { cnt++; real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx); if (real_pipe && real_pipe->pipe_used) { /* 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); /* start timing generator & mmu if they are not started yet */ mdp4_overlay_dsi_video_start(); pipe = vctrl->base_pipe; spin_lock_irqsave(&vctrl->spin_lock, flags); if (pipe->ov_blt_addr) { mdp4_dsi_video_blt_ov_update(pipe); pipe->ov_cnt++; INIT_COMPLETION(vctrl->ov_comp); vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM); mb(); vctrl->ov_koff++; /* kickoff overlay engine */ mdp4_stat.kickoff_ov0++; outpdw(MDP_BASE + 0x0004, 0); } spin_unlock_irqrestore(&vctrl->spin_lock, flags); mdp4_stat.overlay_commit[pipe->mixer_num]++; if (wait) { if (release_busy) { msm_fb_release_busy(vctrl->mfd); *release_busy = false; mutex_unlock(&vctrl->mfd->dma->ov_mutex); } if (pipe->ov_blt_addr) mdp4_dsi_video_wait4ov(0); else mdp4_dsi_video_wait4vsync(0); } return cnt; }
int mipi_lgit_lcd_on(struct platform_device *pdev) { struct msm_fb_data_type *mfd; int rc = 0; int cnt = 0; mfd = platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; #ifdef LGIT_IEF_SWITCH if(local_mfd0 == NULL) local_mfd0 = mfd; #endif printk(KERN_INFO "%s: mipi lgit lcd on started \n", __func__); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000); cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, // mipi_lgit_pdata->power_on_set_1, faux123_power_on_set_1, mipi_lgit_pdata->power_on_set_size_1); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000); if (cnt < 0) return cnt; mipi_dsi_op_mode_config(DSI_VIDEO_MODE); mdp4_overlay_dsi_video_start(); mdelay(10); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000);//HS mode cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set_2, mipi_lgit_pdata->power_on_set_size_2); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000);//LP mode if (cnt < 0) return cnt; rc = gpio_request(DSV_ONBST,"DSV_ONBST_en"); if (rc) { printk(KERN_INFO "%s: DSV_ONBST Request Fail \n", __func__); } else { rc = gpio_direction_output(DSV_ONBST, 1); if (rc) { printk(KERN_INFO "%s: DSV_ONBST Direction Set Fail \n" , __func__); } else { gpio_set_value(DSV_ONBST, 1); } gpio_free(DSV_ONBST); } mdelay(20); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000); cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set_3, mipi_lgit_pdata->power_on_set_size_3); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000); printk(KERN_INFO "%s: mipi lgit lcd on ended \n", __func__); return cnt; }
int mipi_lgit_lcd_on(struct platform_device *pdev) { int cnt = 0; bool cabc_off_state = 1; struct msm_fb_data_type *mfd; if (check_stable_lcd_on) mipi_stable_lcd_on(pdev); mfd = platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; #if defined(CONFIG_LGIT_COLOR_ENGINE_SWITCH) if(local_mfd0 == NULL) local_mfd0 = mfd; #endif printk(KERN_INFO "[LCD][DEBUG] %s is started \n", __func__); //LGE_UPDATE_S [email protected] : adding change mipi mode to write register setting of LCD IC //MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000); //HS mode cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set_1, mipi_lgit_pdata->power_on_set_size_1); if (cnt < 0) return cnt; #if defined(CONFIG_LGE_BACKLIGHT_CABC) cabc_off_state = lgit_lcd_cabc_state(); if (cabc_off_state == 1) { if ((mipi_lgit_pdata->power_on_set_3_noCABC != NULL) && (mipi_lgit_pdata->power_on_set_size_3_noCABC > 0)) { cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set_3_noCABC, mipi_lgit_pdata->power_on_set_size_3_noCABC); if (cnt < 0) return cnt; printk(KERN_INFO "[LCD][DEBUG] %s : CABC OFF\n", __func__); } } else { if ((mipi_lgit_pdata->power_on_set_3 != NULL) && (mipi_lgit_pdata->power_on_set_size_3 > 0)) { cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set_3, mipi_lgit_pdata->power_on_set_size_3); if (cnt < 0) return cnt; printk(KERN_INFO "[LCD][DEBUG] %s : CABC ON\n", __func__); } } #endif cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set_2, mipi_lgit_pdata->power_on_set_size_2); if (cnt < 0) return cnt; mipi_dsi_op_mode_config(DSI_VIDEO_MODE); mdp4_overlay_dsi_video_start(); mdelay(120); //LGE_UPDATE_E [email protected] : adding change mipi mode to write register setting of LCD IC printk(KERN_INFO "[LCD][DEBUG] %s is ended \n", __func__); return cnt; }
int mipi_lgit_lcd_on(struct platform_device *pdev) { struct msm_fb_data_type *mfd; int cnt = 0; pr_info("%s started\n", __func__); mfd = platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; #ifdef LGIT_IEF_SWITCH if(local_mfd0 == NULL) local_mfd0 = mfd; #endif MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000); cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set_1, mipi_lgit_pdata->power_on_set_size_1); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000); if (cnt < 0) { pr_err("%s: failed to transmit power_on_set_1 cmds\n", __func__); return cnt; } mipi_dsi_op_mode_config(DSI_VIDEO_MODE); mdp4_overlay_dsi_video_start(); mdelay(10); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000);//HS mode cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set_2, mipi_lgit_pdata->power_on_set_size_2); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000);//LP mode if (cnt < 0) { pr_err("%s: failed to transmit power_on_set_2 cmds\n", __func__); return cnt; } cnt = lgit_external_dsv_onoff(1); if (cnt < 0) { pr_err("%s: failed to turn on external dsv\n", __func__); return cnt; } MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000); cnt = mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set_3, mipi_lgit_pdata->power_on_set_size_3); MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000); if (cnt < 0) { pr_err("%s: failed to transmit power_on_set_3 cmds\n", __func__); return cnt; } pr_info("%s finished\n", __func__); return cnt; }
int mipi_lgit_lcd_on(struct platform_device *pdev) { struct msm_fb_data_type *mfd; #if defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_WVGA_INVERSE_PT_PANEL) static int gpio43 = PM8921_GPIO_PM_TO_SYS(43); #elif defined(CONFIG_FB_MSM_MIPI_LGIT_LH470WX1_VIDEO_HD_PT) static int gpio20 = PM8921_GPIO_PM_TO_SYS(20); #endif /* CONFIG_FB_MSM_MIPI_LGIT_VIDEO_WVGA_INVERSE_PT_PANEL */ mfd = platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; #ifdef LGIT_IEF_SWITCH if(local_mfd0 == NULL) local_mfd0 = mfd; #endif /* LGE_CHANGE_S, [email protected], Change the Power On Sequence of LCD, 2012.03.28*/ #if defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_WVGA_INVERSE_PT_PANEL) gpio_direction_output(gpio43, 0); mdelay(12); gpio_direction_output(gpio43, 1); #endif /* CONFIG_FB_MSM_MIPI_LGIT_VIDEO_WVGA_INVERSE_PT_PANEL */ /* LGE_CHANGE_E, [email protected], Change the Power On Sequence of LCD, 2012.03.28*/ #if defined(CONFIG_FB_MSM_MIPI_LGIT_LH470WX1_VIDEO_HD_PT) /*LG display 4.7" HD for FX1 */ if(system_state==SYSTEM_BOOTING){ mipi_dsi_op_mode_config(DSI_VIDEO_MODE); mdp4_overlay_dsi_video_start(); } else { mdelay(5); gpio_set_value(gpio20, 1); mdelay(5); if(lgit_change_panel) mipi_dsi_cmds_tx(&lgit_tx_buf, lgit_power_on_set1, ARRAY_SIZE(lgit_power_on_set1)); else mipi_dsi_cmds_tx(&lgit_tx_buf, lgit_power_on_set1_change, ARRAY_SIZE(lgit_power_on_set1_change)); mipi_set_tx_power_mode(0); mipi_dsi_op_mode_config(DSI_VIDEO_MODE); mdp4_overlay_dsi_video_start(); mdelay(10); mipi_dsi_cmds_tx(&lgit_tx_buf, lgit_power_on_set2, ARRAY_SIZE(lgit_power_on_set2)); gpio_tlmm_config(GPIO_CFG(GPIO_LCD_DSV_EN, 0, GPIO_CFG_OUTPUT , GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE); gpio_set_value(GPIO_LCD_DSV_EN,1); mdelay(5); mipi_dsi_cmds_tx(&lgit_tx_buf, lgit_power_on_set3, ARRAY_SIZE(lgit_power_on_set3)); } #elif defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_HD_PT) printk(KERN_INFO "%s: mipi lgit lcd on started \n", __func__); mipi_dsi_cmds_tx(&lgit_tx_buf, lgit_power_on_set, ARRAY_SIZE(lgit_power_on_set)); #else mipi_dsi_cmds_tx(&lgit_tx_buf, mipi_lgit_pdata->power_on_set, mipi_lgit_pdata->power_on_set_size); #endif return 0; }