static void mdp_dma_s_update_lcd(struct msm_fb_data_type *mfd) { MDPIBUF *iBuf = &mfd->ibuf; int mddi_dest = FALSE; uint32 outBpp = iBuf->bpp; uint32 dma_s_cfg_reg; uint8 *src; struct msm_fb_panel_data *pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data; dma_s_cfg_reg = DMA_PACK_TIGHT | DMA_PACK_ALIGN_LSB | DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS; if (mfd->fb_imgType == MDP_BGR_565) dma_s_cfg_reg |= DMA_PACK_PATTERN_BGR; else dma_s_cfg_reg |= DMA_PACK_PATTERN_RGB; if (outBpp == 4) dma_s_cfg_reg |= DMA_IBUF_C3ALPHA_EN; if (outBpp == 2) dma_s_cfg_reg |= DMA_IBUF_FORMAT_RGB565; if (mfd->panel_info.pdest != DISPLAY_2) { printk(KERN_ERR "error: non-secondary type through dma_s!\n"); return; } if (mfd->panel_info.type == MDDI_PANEL) { dma_s_cfg_reg |= DMA_OUT_SEL_MDDI; mddi_dest = TRUE; } else { dma_s_cfg_reg |= DMA_AHBM_LCD_SEL_SECONDARY; outp32(MDP_EBI2_LCD1, mfd->data_port_phys); } dma_s_cfg_reg |= DMA_DITHER_EN; src = (uint8 *) iBuf->buf; src += (iBuf->dma_x + iBuf->dma_y * iBuf->ibuf_width) * outBpp; //starting input address //MDP cmd block enable mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); MDP_OUTP(MDP_BASE + 0xa0004, (iBuf->dma_h << 16 | iBuf->dma_w)); //PIXELSIZE MDP_OUTP(MDP_BASE + 0xa0008, src); //ibuf address MDP_OUTP(MDP_BASE + 0xa000c, iBuf->ibuf_width * outBpp); //ystride if (mfd->panel_info.bpp == 18) { dma_s_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */ DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; } else { dma_s_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */ DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; } if (mddi_dest) { MDP_OUTP(MDP_BASE + 0xa0010, (iBuf->dma_y << 16) | iBuf->dma_x); MDP_OUTP(MDP_BASE + 0x00090, 1); MDP_OUTP(MDP_BASE + 0x00094, (MDDI_VDO_PACKET_DESC << 16) | mfd->panel_info.mddi.vdopkt); } else { // setting LCDC write window pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w, iBuf->dma_h); } MDP_OUTP(MDP_BASE + 0xa0000, dma_s_cfg_reg); // MDP cmd block disable mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); mdp_pipe_kickoff(MDP_DMA_S_TERM, mfd); }
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; 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 mdp_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; uint32 dma2_cfg_reg; int bpp; struct fb_info *fbi; struct fb_var_screeninfo *var; struct msm_fb_data_type *mfd; int ret; uint32_t mask, curr; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; fbi = mfd->fbi; var = &fbi->var; vsync_cntrl.dev = mfd->fbi->dev; atomic_set(&vsync_cntrl.suspend, 0); bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf += calc_fb_offset(mfd, fbi, bpp); dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_OUT_SEL_DSI_VIDEO; if (mfd->fb_imgType == MDP_BGR_565) dma2_cfg_reg |= DMA_PACK_PATTERN_BGR; else if (mfd->fb_imgType == MDP_RGBA_8888) dma2_cfg_reg |= DMA_PACK_PATTERN_BGR; else dma2_cfg_reg |= DMA_PACK_PATTERN_RGB; if (bpp == 2) dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565; else if (bpp == 3) dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB888; else dma2_cfg_reg |= DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888; switch (mfd->panel_info.bpp) { case 24: dma2_cfg_reg |= DMA_DSTC0G_8BITS | DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS; break; case 18: dma2_cfg_reg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; break; case 16: dma2_cfg_reg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; break; default: printk(KERN_ERR "mdp lcdc can't support format %d bpp!\n", mfd->panel_info.bpp); return -ENODEV; } /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); /* starting address */ MDP_OUTP(MDP_BASE + DMA_P_BASE + 0x8, (uint32) buf); /* active window width and height */ MDP_OUTP(MDP_BASE + DMA_P_BASE + 0x4, ((fbi->var.yres) << 16) | (fbi->var.xres)); /* buffer ystride */ MDP_OUTP(MDP_BASE + DMA_P_BASE + 0xc, fbi->fix.line_length); /* x/y coordinate = always 0 for lcdc */ MDP_OUTP(MDP_BASE + DMA_P_BASE + 0x10, 0); /* dma config */ curr = inpdw(MDP_BASE + DMA_P_BASE); mask = 0x0FFFFFFF; dma2_cfg_reg = (dma2_cfg_reg & mask) | (curr & ~mask); MDP_OUTP(MDP_BASE + DMA_P_BASE, dma2_cfg_reg); /* * 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; dsi_height = mfd->panel_info.yres; dsi_bpp = mfd->panel_info.bpp; hsync_period = h_back_porch + dsi_width + h_front_porch + 1; hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; hsync_start_x = h_back_porch; hsync_end_x = dsi_width + h_back_porch - 1; display_hctl = (hsync_end_x << 16) | hsync_start_x; vsync_period = (v_back_porch + dsi_height + v_front_porch + 1) * hsync_period; display_v_start = v_back_porch * hsync_period + dsi_hsync_skew; display_v_end = (dsi_height + v_back_porch) * hsync_period; 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; 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; 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); if (!(mfd->cont_splash_done)) { mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); mipi_dsi_controller_cfg(0); } MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x4, hsync_ctrl); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x8, vsync_period); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0xc, vsync_pulse_width); 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); ret = panel_next_on(pdev); if (ret == 0) { /* enable DSI block */ MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1); /*Turning on DMA_P block*/ mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE); } /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); return ret; }
int mdp4_dtv_on(struct platform_device *pdev) { int dtv_width; int dtv_height; int dtv_bpp; int dtv_border_clr; int dtv_underflow_clr; int dtv_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; int bpp, ptype; uint32 format; struct fb_info *fbi; struct fb_var_screeninfo *var; struct msm_fb_data_type *mfd; struct mdp4_overlay_pipe *pipe; int ret; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; fbi = mfd->fbi; var = &fbi->var; bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf += fbi->var.xoffset * bpp + fbi->var.yoffset * fbi->fix.line_length; if (bpp == 2) format = MDP_RGB_565; else if (bpp == 3) format = MDP_RGB_888; else format = MDP_ARGB_8888; if (dtv_pipe == NULL) { ptype = mdp4_overlay_format2type(format); if (ptype < 0) printk(KERN_INFO "%s: format2type failed\n", __func__); pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER1, 0); if (pipe == NULL) { printk(KERN_INFO "%s: pipe_alloc failed\n", __func__); return -EBUSY; } pipe->pipe_used++; pipe->mixer_stage = MDP4_MIXER_STAGE_BASE; pipe->mixer_num = MDP4_MIXER1; pipe->src_format = format; mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_DTV); ret = mdp4_overlay_format2pipe(pipe); if (ret < 0) printk(KERN_INFO "%s: format2type failed\n", __func__); dtv_pipe = pipe; /* keep it */ } else { pipe = dtv_pipe; } /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); 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->srcp0_addr = (uint32) buf; pipe->srcp0_ystride = fbi->fix.line_length; mdp4_overlay_dmae_xy(pipe); /* dma_e */ mdp4_overlay_dmae_cfg(mfd, 0); mdp4_overlay_rgb_setup(pipe); mdp4_mixer_stage_up(pipe); mdp4_overlayproc_cfg(pipe); /* * DTV 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; dtv_border_clr = mfd->panel_info.lcdc.border_clr; dtv_underflow_clr = mfd->panel_info.lcdc.underflow_clr; dtv_hsync_skew = mfd->panel_info.lcdc.hsync_skew; pr_info("%s: <ID=%d %dx%d (%d,%d,%d), (%d,%d,%d) %dMHz>\n", __func__, var->reserved[3], var->xres, var->yres, var->right_margin, var->hsync_len, var->left_margin, var->lower_margin, var->vsync_len, var->upper_margin, var->pixclock/1000/1000); dtv_width = var->xres; dtv_height = var->yres; dtv_bpp = mfd->panel_info.bpp; hsync_period = hsync_pulse_width + h_back_porch + dtv_width + h_front_porch; hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; hsync_start_x = hsync_pulse_width + h_back_porch; 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 + dtv_height + v_front_porch) * hsync_period; display_v_start = (vsync_pulse_width + v_back_porch) * hsync_period + dtv_hsync_skew; display_v_end = vsync_period - (v_front_porch * hsync_period) + dtv_hsync_skew - 1; if (dtv_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 (dtv_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; } dtv_underflow_clr |= 0x80000000; /* enable recovery */ hsync_polarity = fbi->var.yres >= 720 ? 0 : 1; vsync_polarity = fbi->var.yres >= 720 ? 0 : 1; data_en_polarity = 0; ctrl_polarity = (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); MDP_OUTP(MDP_BASE + DTV_BASE + 0x4, hsync_ctrl); MDP_OUTP(MDP_BASE + DTV_BASE + 0x8, vsync_period); MDP_OUTP(MDP_BASE + DTV_BASE + 0xc, vsync_pulse_width * hsync_period); MDP_OUTP(MDP_BASE + DTV_BASE + 0x18, display_hctl); MDP_OUTP(MDP_BASE + DTV_BASE + 0x1c, display_v_start); MDP_OUTP(MDP_BASE + DTV_BASE + 0x20, display_v_end); MDP_OUTP(MDP_BASE + DTV_BASE + 0x40, dtv_border_clr); MDP_OUTP(MDP_BASE + DTV_BASE + 0x44, dtv_underflow_clr); MDP_OUTP(MDP_BASE + DTV_BASE + 0x48, dtv_hsync_skew); MDP_OUTP(MDP_BASE + DTV_BASE + 0x50, ctrl_polarity); MDP_OUTP(MDP_BASE + DTV_BASE + 0x2c, active_hctl); MDP_OUTP(MDP_BASE + DTV_BASE + 0x30, active_v_start); MDP_OUTP(MDP_BASE + DTV_BASE + 0x38, active_v_end); /* Test pattern 8 x 8 pixel */ /* MDP_OUTP(MDP_BASE + DTV_BASE + 0x4C, 0x80000808); */ ret = panel_next_on(pdev); if (ret == 0) { /* enable DTV block */ MDP_OUTP(MDP_BASE + DTV_BASE, 1); mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_ON, FALSE); dev_info(&pdev->dev, "mdp4_overlay_dtv: on"); } else { dev_warn(&pdev->dev, "mdp4_overlay_dtv: panel_next_on failed"); } /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); return ret; }
int mdp_lcdc_on(struct platform_device *pdev) { int lcdc_width; int lcdc_height; int lcdc_bpp; int lcdc_border_clr; int lcdc_underflow_clr; int lcdc_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; int bpp; uint32 dma2_cfg_reg; struct fb_info *fbi; struct fb_var_screeninfo *var; struct msm_fb_data_type *mfd; uint32 dma_base; uint32 timer_base = LCDC_BASE; uint32 block = MDP_DMA2_BLOCK; int ret; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; fbi = mfd->fbi; var = &fbi->var; /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf += fbi->var.xoffset * bpp + fbi->var.yoffset * fbi->fix.line_length; dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_DITHER_EN | DMA_OUT_SEL_LCDC; if (mfd->fb_imgType == MDP_BGR_565) dma2_cfg_reg |= DMA_PACK_PATTERN_BGR; else if (mfd->fb_imgType == MDP_RGBA_8888) dma2_cfg_reg |= DMA_PACK_PATTERN_BGR; else dma2_cfg_reg |= DMA_PACK_PATTERN_RGB; if (bpp == 2) dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565; else if (bpp == 3) dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB888; else dma2_cfg_reg |= DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888; switch (mfd->panel_info.bpp) { case 24: dma2_cfg_reg |= DMA_DSTC0G_8BITS | DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS; break; case 18: dma2_cfg_reg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; break; case 16: dma2_cfg_reg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; break; default: printk(KERN_ERR "mdp lcdc can't support format %d bpp!\n", mfd->panel_info.bpp); return -ENODEV; } /* DMA register config */ dma_base = DMA_P_BASE; #ifdef CONFIG_FB_MSM_MDP40 if (mfd->panel.type == HDMI_PANEL) dma_base = DMA_E_BASE; #endif /* starting address */ MDP_OUTP(MDP_BASE + dma_base + 0x8, (uint32) buf); /* active window width and height */ MDP_OUTP(MDP_BASE + dma_base + 0x4, ((fbi->var.yres) << 16) | (fbi->var.xres)); /* buffer ystride */ MDP_OUTP(MDP_BASE + dma_base + 0xc, fbi->fix.line_length); /* x/y coordinate = always 0 for lcdc */ MDP_OUTP(MDP_BASE + dma_base + 0x10, 0); /* dma config */ MDP_OUTP(MDP_BASE + dma_base, dma2_cfg_reg); /* * LCDC 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; lcdc_border_clr = mfd->panel_info.lcdc.border_clr; lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr; lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew; lcdc_width = mfd->panel_info.xres; lcdc_height = mfd->panel_info.yres; lcdc_bpp = mfd->panel_info.bpp; hsync_period = hsync_pulse_width + h_back_porch + lcdc_width + h_front_porch; hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; hsync_start_x = hsync_pulse_width + h_back_porch; 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 + lcdc_height + v_front_porch) * hsync_period; display_v_start = (vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew; display_v_end = vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1; if (lcdc_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 (lcdc_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; } #ifdef CONFIG_FB_MSM_MDP40 if (mfd->panel.type == HDMI_PANEL) { block = MDP_DMA_E_BLOCK; timer_base = DTV_BASE; hsync_polarity = 0; vsync_polarity = 0; } else { hsync_polarity = 1; vsync_polarity = 1; } lcdc_underflow_clr |= 0x80000000; /* enable recovery */ #else hsync_polarity = 1; vsync_polarity = 0; #endif data_en_polarity = 0; ctrl_polarity = (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); MDP_OUTP(MDP_BASE + timer_base + 0x4, hsync_ctrl); MDP_OUTP(MDP_BASE + timer_base + 0x8, vsync_period); MDP_OUTP(MDP_BASE + timer_base + 0xc, vsync_pulse_width * hsync_period); if (timer_base == LCDC_BASE) { MDP_OUTP(MDP_BASE + timer_base + 0x10, display_hctl); MDP_OUTP(MDP_BASE + timer_base + 0x14, display_v_start); MDP_OUTP(MDP_BASE + timer_base + 0x18, display_v_end); MDP_OUTP(MDP_BASE + timer_base + 0x28, lcdc_border_clr); MDP_OUTP(MDP_BASE + timer_base + 0x2c, lcdc_underflow_clr); MDP_OUTP(MDP_BASE + timer_base + 0x30, lcdc_hsync_skew); MDP_OUTP(MDP_BASE + timer_base + 0x38, ctrl_polarity); MDP_OUTP(MDP_BASE + timer_base + 0x1c, active_hctl); MDP_OUTP(MDP_BASE + timer_base + 0x20, active_v_start); MDP_OUTP(MDP_BASE + timer_base + 0x24, active_v_end); } else { MDP_OUTP(MDP_BASE + timer_base + 0x18, display_hctl); MDP_OUTP(MDP_BASE + timer_base + 0x1c, display_v_start); MDP_OUTP(MDP_BASE + timer_base + 0x20, display_v_end); MDP_OUTP(MDP_BASE + timer_base + 0x40, lcdc_border_clr); MDP_OUTP(MDP_BASE + timer_base + 0x44, lcdc_underflow_clr); MDP_OUTP(MDP_BASE + timer_base + 0x48, lcdc_hsync_skew); MDP_OUTP(MDP_BASE + timer_base + 0x50, ctrl_polarity); MDP_OUTP(MDP_BASE + timer_base + 0x2c, active_hctl); MDP_OUTP(MDP_BASE + timer_base + 0x30, active_v_start); MDP_OUTP(MDP_BASE + timer_base + 0x38, active_v_end); } ret = panel_next_on(pdev); if (ret == 0) { /* enable LCDC block */ MDP_OUTP(MDP_BASE + timer_base, 1); mdp_pipe_ctrl(block, MDP_BLOCK_POWER_ON, FALSE); } /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); return ret; }
static void mdp_dma2_update_lcd(struct msm_fb_data_type *mfd) { MDPIBUF *iBuf = &mfd->ibuf; int mddi_dest = FALSE; uint32 outBpp = iBuf->bpp; uint32 dma2_cfg_reg; uint8 *src; uint32 mddi_ld_param; uint16 mddi_vdo_packet_reg; struct msm_fb_panel_data *pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data; uint32 ystride = mfd->fbi->fix.line_length; uint32 mddi_pkt_desc; #ifdef CONFIG_HUAWEI_KERNEL lcd_align_type lcd_align = LCD_PANEL_ALIGN_LSB; lcd_align = lcd_align_probe(); if (lcd_align == LCD_PANEL_ALIGN_MSB) { dma2_cfg_reg = DMA_PACK_TIGHT | DMA_PACK_ALIGN_MSB | DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS; } else { dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS; } #else dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS; #endif #ifdef CONFIG_FB_MSM_MDP22 dma2_cfg_reg |= DMA_PACK_TIGHT; #endif #ifdef CONFIG_FB_MSM_MDP30 /* * Software workaround: On 7x25/7x27, the MDP will not * respond if dma_w is 1 pixel. Set the update width to * 2 pixels and adjust the x offset if needed. */ if (iBuf->dma_w == 1) { iBuf->dma_w = 2; if (iBuf->dma_x == (iBuf->ibuf_width - 2)) iBuf->dma_x--; } #endif if (mfd->fb_imgType == MDP_BGR_565) dma2_cfg_reg |= DMA_PACK_PATTERN_BGR; else if (mfd->fb_imgType == MDP_RGBA_8888) dma2_cfg_reg |= DMA_PACK_PATTERN_BGR; else dma2_cfg_reg |= DMA_PACK_PATTERN_RGB; if (outBpp == 4) { dma2_cfg_reg |= DMA_IBUF_C3ALPHA_EN; dma2_cfg_reg |= DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888; } if (outBpp == 2) dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565; mddi_ld_param = 0; mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt; if ((mfd->panel_info.type == MDDI_PANEL) || (mfd->panel_info.type == EXT_MDDI_PANEL)) { dma2_cfg_reg |= DMA_OUT_SEL_MDDI; mddi_dest = TRUE; if (mfd->panel_info.type == MDDI_PANEL) { mdp_total_vdopkts++; if (mfd->panel_info.pdest == DISPLAY_1) { dma2_cfg_reg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY; mddi_ld_param = 0; #ifdef MDDI_HOST_WINDOW_WORKAROUND mddi_window_adjust(mfd, iBuf->dma_x, iBuf->dma_w - 1, iBuf->dma_y, iBuf->dma_h - 1); #endif } else { dma2_cfg_reg |= DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY; mddi_ld_param = 1; #ifdef MDDI_HOST_WINDOW_WORKAROUND mddi_window_adjust(mfd, iBuf->dma_x, iBuf->dma_w - 1, iBuf->dma_y, iBuf->dma_h - 1); #endif } } else { dma2_cfg_reg |= DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL; mddi_ld_param = 2; } } else { if (mfd->panel_info.pdest == DISPLAY_1) { dma2_cfg_reg |= DMA_AHBM_LCD_SEL_PRIMARY; outp32(MDP_EBI2_LCD0, mfd->data_port_phys); } else { dma2_cfg_reg |= DMA_AHBM_LCD_SEL_SECONDARY; outp32(MDP_EBI2_LCD1, mfd->data_port_phys); } } dma2_cfg_reg |= DMA_DITHER_EN; src = (uint8 *) iBuf->buf; /* starting input address */ src += iBuf->dma_x * outBpp + iBuf->dma_y * ystride; mdp_curr_dma2_update_width = iBuf->dma_w; mdp_curr_dma2_update_height = iBuf->dma_h; /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); #ifdef CONFIG_FB_MSM_MDP22 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0184, (iBuf->dma_h << 16 | iBuf->dma_w)); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0188, src); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x018C, ystride); #else MDP_OUTP(MDP_BASE + 0x90004, (iBuf->dma_h << 16 | iBuf->dma_w)); MDP_OUTP(MDP_BASE + 0x90008, src); MDP_OUTP(MDP_BASE + 0x9000c, ystride); #endif if (mfd->panel_info.bpp == 18) { mddi_pkt_desc = MDDI_VDO_PACKET_DESC; dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */ DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; } else if (mfd->panel_info.bpp == 24) { mddi_pkt_desc = MDDI_VDO_PACKET_DESC_24; dma2_cfg_reg |= DMA_DSTC0G_8BITS | /* 888 24BPP */ DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS; } else { mddi_pkt_desc = MDDI_VDO_PACKET_DESC_16; dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */ DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; } if (mddi_dest) { #ifdef CONFIG_FB_MSM_MDP22 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0194, (iBuf->dma_y << 16) | iBuf->dma_x); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0, mddi_ld_param); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4, (mddi_pkt_desc << 16) | mddi_vdo_packet_reg); #else MDP_OUTP(MDP_BASE + 0x90010, (iBuf->dma_y << 16) | iBuf->dma_x); MDP_OUTP(MDP_BASE + 0x00090, mddi_ld_param); MDP_OUTP(MDP_BASE + 0x00094, (mddi_pkt_desc << 16) | mddi_vdo_packet_reg); #endif } else { /* setting EBI2 LCDC write window */ pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w, iBuf->dma_h); } /* dma2 config register */ #ifdef MDP_HW_VSYNC MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg); if ((mfd->use_mdp_vsync) && (mfd->ibuf.vsync_enable) && (mfd->panel_info.lcd.vsync_enable)) { uint32 start_y; if (vsync_start_y_adjust <= iBuf->dma_y) start_y = iBuf->dma_y - vsync_start_y_adjust; else start_y = (mfd->total_lcd_lines - 1) - (vsync_start_y_adjust - iBuf->dma_y); /* * MDP VSYNC clock must be On by now so, we don't have to * re-enable it */ MDP_OUTP(MDP_BASE + 0x210, start_y); MDP_OUTP(MDP_BASE + 0x20c, 1); /* enable prim vsync */ } else { MDP_OUTP(MDP_BASE + 0x20c, 0); /* disable prim vsync */ } #else #ifdef CONFIG_FB_MSM_MDP22 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0180, dma2_cfg_reg); #else MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg); #endif #endif /* MDP_HW_VSYNC */ /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); }
int mdp4_lcdc_on(struct platform_device *pdev) { int lcdc_width; int lcdc_height; int lcdc_bpp; int lcdc_border_clr; int lcdc_underflow_clr; int lcdc_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; vctrl = &vsync_ctrl_db[cndx]; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); 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->vsync_irq_enabled = 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__); 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_LCDC); ret = mdp4_overlay_format2pipe(pipe); if (ret < 0) printk(KERN_INFO "%s: format2pipe failed\n", __func__); mdp4_init_writeback_buf(mfd, MDP4_MIXER0); pipe->ov_blt_addr = 0; pipe->dma_blt_addr = 0; vctrl->base_pipe = pipe; /* keep it */ } else { pipe = vctrl->base_pipe; } 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; if (mfd->display_iova) pipe->srcp0_addr = mfd->display_iova + buf_offset; else pipe->srcp0_addr = (uint32)(buf + buf_offset); pipe->srcp0_ystride = fbi->fix.line_length; pipe->bpp = bpp; mdp4_overlay_mdp_pipe_req(pipe, mfd); mdp4_calc_blt_mdp_bw(mfd, pipe); atomic_set(&vctrl->suspend, 0); mdp4_overlay_dmap_xy(pipe); 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); /* * LCDC 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; lcdc_border_clr = mfd->panel_info.lcdc.border_clr; lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr; lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew; lcdc_width = var->xres + mfd->panel_info.lcdc.xres_pad; lcdc_height = var->yres + mfd->panel_info.lcdc.yres_pad; lcdc_bpp = mfd->panel_info.bpp; hsync_period = hsync_pulse_width + h_back_porch + h_front_porch; if ((mfd->panel_info.type == LVDS_PANEL) && (mfd->panel_info.lvds.channel_mode == LVDS_DUAL_CHANNEL_MODE)) hsync_period += lcdc_width / 2; else hsync_period += lcdc_width; hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; hsync_start_x = hsync_pulse_width + h_back_porch; 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 + lcdc_height + v_front_porch) * hsync_period; display_v_start = (vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew; display_v_end = vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1; if (lcdc_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 (lcdc_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; } #ifdef CONFIG_FB_MSM_MDP40 if (mfd->panel_info.lcdc.is_sync_active_high) { hsync_polarity = 0; vsync_polarity = 0; } else { hsync_polarity = 1; vsync_polarity = 1; } lcdc_underflow_clr |= 0x80000000; /* enable recovery */ #else hsync_polarity = 0; vsync_polarity = 0; #endif 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 + LCDC_BASE + 0x4, hsync_ctrl); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x8, vsync_period); MDP_OUTP(MDP_BASE + LCDC_BASE + 0xc, vsync_pulse_width * hsync_period); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x10, display_hctl); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x14, display_v_start); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x18, display_v_end); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x28, lcdc_border_clr); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x2c, lcdc_underflow_clr); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x30, lcdc_hsync_skew); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x38, ctrl_polarity); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x1c, active_hctl); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x20, active_v_start); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x24, active_v_end); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); mdp_histogram_ctrl_all(TRUE); mdp4_overlay_lcdc_start(); mutex_unlock(&mfd->dma->ov_mutex); return ret; }
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; static bool first_video_on = true; 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; vctrl = &vsync_ctrl_db[cndx]; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; vctrl->mfd = mfd; vctrl->dev = mfd->fbi->dev; 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 (first_video_on) first_video_on = false; else { if (mfd->ref_cnt == 0) { int ndx; for (ndx=1; ndx<4; ndx++) { pipe = mdp4_overlay_ndx2pipe(ndx); if (pipe && pipe->pipe_used) mdp4_overlay_unset(mfd->fbi, ndx); } } } 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__); 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; mdp4_init_writeback_buf(mfd, MDP4_MIXER0); } else { pipe = vctrl->base_pipe; } #ifdef CONTINUOUS_SPLASH mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); if (!(mfd->cont_splash_done)) { mfd->cont_splash_done = 1; mdp4_dsi_video_wait4dmap_done(0); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); mdelay(20); mipi_dsi_controller_cfg(0); } #endif 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_mdp_pipe_req(pipe, mfd); atomic_set(&vctrl->suspend, 0); mdp4_overlay_dmap_xy(pipe); 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); mdp4_mixer_stage_commit(pipe->mixer_num); 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; hsync_polarity = 0; vsync_polarity = 0; data_en_polarity = 0; ctrl_polarity = (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); if ((mfd->cont_splash_done)) { 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); } else { mfd->cont_splash_done = 1; mdp_clk_ctrl(0); } mdp_histogram_ctrl_all(TRUE); if (!vctrl->sysfs_created) { ret = sysfs_create_group(&vctrl->dev->kobj, &vsync_fs_attr_group); if (ret) { pr_err("%s: sysfs group creation failed, ret=%d\n", __func__, ret); return ret; } kobject_uevent(&vctrl->dev->kobj, KOBJ_ADD); pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__); vctrl->sysfs_created = 1; } return ret; }
void mdp_hw_init(void) { int i; /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); /* debug interface write access */ outpdw(MDP_BASE + 0x60, 1); outp32(MDP_INTR_ENABLE, MDP_ANY_INTR_MASK); outp32(MDP_EBI2_PORTMAP_MODE, 0x3); outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8, 0x0); outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc, 0x0); outpdw(MDP_BASE + 0x60, 0x1); mdp_load_lut_param(); /* * clear up unused fg/main registers */ /* comp.plane 2&3 ystride */ MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0120, 0x0); /* unpacked pattern */ MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x012c, 0x0); /* unpacked pattern */ MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0130, 0x0); /* unpacked pattern */ MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0134, 0x0); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0158, 0x0); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x15c, 0x0); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0160, 0x0); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0170, 0x0); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0174, 0x0); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x017c, 0x0); /* comp.plane 2 */ MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0114, 0x0); /* comp.plane 3 */ MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0118, 0x0); /* clear up unused bg registers */ MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8, 0); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0, 0); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc, 0); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0, 0); MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4, 0); #ifndef CONFIG_FB_MSM_MDP22 MDP_OUTP(MDP_BASE + 0xE0000, 0); MDP_OUTP(MDP_BASE + 0x100, 0xffffffff); MDP_OUTP(MDP_BASE + 0x90070, 0); MDP_OUTP(MDP_BASE + 0x94010, 1); MDP_OUTP(MDP_BASE + 0x9401c, 2); /* LGE_CHANGE_S * Change code to apply new LUT for display quality. 2010-08-03. [email protected] */ mdp_load_m3s_lut(1); // nornal #endif /* * limit vector * pre gets applied before color matrix conversion * post is after ccs */ writel(mdp_plv[0], MDP_CSC_PRE_LV1n(0)); writel(mdp_plv[1], MDP_CSC_PRE_LV1n(1)); writel(mdp_plv[2], MDP_CSC_PRE_LV1n(2)); writel(mdp_plv[3], MDP_CSC_PRE_LV1n(3)); #ifdef CONFIG_FB_MSM_MDP31 writel(mdp_plv[2], MDP_CSC_PRE_LV1n(4)); writel(mdp_plv[3], MDP_CSC_PRE_LV1n(5)); writel(0, MDP_CSC_POST_LV1n(0)); writel(0xff, MDP_CSC_POST_LV1n(1)); writel(0, MDP_CSC_POST_LV1n(2)); writel(0xff, MDP_CSC_POST_LV1n(3)); writel(0, MDP_CSC_POST_LV1n(4)); writel(0xff, MDP_CSC_POST_LV1n(5)); writel(0, MDP_CSC_PRE_LV2n(0)); writel(0xff, MDP_CSC_PRE_LV2n(1)); writel(0, MDP_CSC_PRE_LV2n(2)); writel(0xff, MDP_CSC_PRE_LV2n(3)); writel(0, MDP_CSC_PRE_LV2n(4)); writel(0xff, MDP_CSC_PRE_LV2n(5)); writel(mdp_plv[0], MDP_CSC_POST_LV2n(0)); writel(mdp_plv[1], MDP_CSC_POST_LV2n(1)); writel(mdp_plv[2], MDP_CSC_POST_LV2n(2)); writel(mdp_plv[3], MDP_CSC_POST_LV2n(3)); writel(mdp_plv[2], MDP_CSC_POST_LV2n(4)); writel(mdp_plv[3], MDP_CSC_POST_LV2n(5)); #endif /* primary forward matrix */ for (i = 0; i < MDP_CCS_SIZE; i++) writel(mdp_ccs_rgb2yuv.ccs[i], MDP_CSC_PFMVn(i)); #ifdef CONFIG_FB_MSM_MDP31 for (i = 0; i < MDP_BV_SIZE; i++) writel(mdp_ccs_rgb2yuv.bv[i], MDP_CSC_POST_BV2n(i)); writel(0, MDP_CSC_PRE_BV2n(0)); writel(0, MDP_CSC_PRE_BV2n(1)); writel(0, MDP_CSC_PRE_BV2n(2)); #endif /* primary reverse matrix */ for (i = 0; i < MDP_CCS_SIZE; i++) writel(mdp_ccs_yuv2rgb.ccs[i], MDP_CSC_PRMVn(i)); for (i = 0; i < MDP_BV_SIZE; i++) writel(mdp_ccs_yuv2rgb.bv[i], MDP_CSC_PRE_BV1n(i)); #ifdef CONFIG_FB_MSM_MDP31 writel(0, MDP_CSC_POST_BV1n(0)); writel(0, MDP_CSC_POST_BV1n(1)); writel(0, MDP_CSC_POST_BV1n(2)); outpdw(MDP_BASE + 0x30010, 0x03e0); outpdw(MDP_BASE + 0x30014, 0x0360); outpdw(MDP_BASE + 0x30018, 0x0120); outpdw(MDP_BASE + 0x3001c, 0x0140); #endif mdp_init_scale_table(); #ifndef CONFIG_FB_MSM_MDP31 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0104, ((16 << 6) << 16) | (16) << 6); #endif wmb(); /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); }
void mdp4_dma_s_update_lcd(struct msm_fb_data_type *mfd, struct mdp4_overlay_pipe *pipe) { MDPIBUF *iBuf = &mfd->ibuf; uint32 outBpp = iBuf->bpp; uint16 mddi_vdo_packet_reg; uint32 dma_s_cfg_reg; dma_s_cfg_reg = 0; if (mfd->fb_imgType == MDP_RGBA_8888) dma_s_cfg_reg |= DMA_PACK_PATTERN_BGR; /* on purpose */ else if (mfd->fb_imgType == MDP_BGR_565) dma_s_cfg_reg |= DMA_PACK_PATTERN_BGR; else dma_s_cfg_reg |= DMA_PACK_PATTERN_RGB; if (outBpp == 4) dma_s_cfg_reg |= (1 << 26); /* xRGB8888 */ else if (outBpp == 2) dma_s_cfg_reg |= DMA_IBUF_FORMAT_RGB565; dma_s_cfg_reg |= DMA_DITHER_EN; /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); /* PIXELSIZE */ MDP_OUTP(MDP_BASE + 0xa0004, (pipe->dst_h << 16 | pipe->dst_w)); MDP_OUTP(MDP_BASE + 0xa0008, pipe->srcp0_addr); /* ibuf address */ MDP_OUTP(MDP_BASE + 0xa000c, pipe->srcp0_ystride);/* ystride */ if (mfd->panel_info.bpp == 24) { dma_s_cfg_reg |= DMA_DSTC0G_8BITS | /* 666 18BPP */ DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS; } else if (mfd->panel_info.bpp == 18) { dma_s_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */ DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; } else { dma_s_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */ DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; } MDP_OUTP(MDP_BASE + 0xa0010, (pipe->dst_y << 16) | pipe->dst_x); /* 1 for dma_s, client_id = 0 */ MDP_OUTP(MDP_BASE + 0x00090, 1); mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt; if (mfd->panel_info.bpp == 24) MDP_OUTP(MDP_BASE + 0x00094, (MDDI_VDO_PACKET_DESC_24 << 16) | mddi_vdo_packet_reg); else if (mfd->panel_info.bpp == 16) MDP_OUTP(MDP_BASE + 0x00094, (MDDI_VDO_PACKET_DESC_16 << 16) | mddi_vdo_packet_reg); else MDP_OUTP(MDP_BASE + 0x00094, (MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg); MDP_OUTP(MDP_BASE + 0x00098, 0x01); MDP_OUTP(MDP_BASE + 0xa0000, dma_s_cfg_reg); mdp4_mddi_vsync_enable(mfd, pipe, 1); /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); }
static void mdp4_overlay_dtv_alloc_pipe(struct msm_fb_data_type *mfd, int32 ptype) { int ret = 0; struct fb_info *fbi = mfd->fbi; struct mdp4_overlay_pipe *pipe; if (dtv_pipe != NULL) return; pr_debug("%s: ptype=%d\n", __func__, ptype); pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER1); if (pipe == NULL) { pr_err("%s: pipe_alloc failed\n", __func__); return; } pipe->pipe_used++; pipe->mixer_stage = MDP4_MIXER_STAGE_BASE; pipe->mixer_num = MDP4_MIXER1; if (ptype == OVERLAY_TYPE_BF) { mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); /* LSP_BORDER_COLOR */ MDP_OUTP(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x5004, ((0x0 & 0xFFF) << 16) | /* 12-bit B */ (0x0 & 0xFFF)); /* 12-bit G */ /* MSP_BORDER_COLOR */ MDP_OUTP(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x5008, (0x0 & 0xFFF)); /* 12-bit R */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); } else { switch (mfd->ibuf.bpp) { case 2: pipe->src_format = MDP_RGB_565; break; case 3: pipe->src_format = MDP_RGB_888; break; case 4: default: if (hdmi_prim_display) pipe->src_format = MSMFB_DEFAULT_TYPE; else pipe->src_format = MDP_ARGB_8888; break; } } 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->srcp0_ystride = fbi->fix.line_length; ret = mdp4_overlay_format2pipe(pipe); if (ret < 0) pr_warn("%s: format2type failed\n", __func__); mdp4_overlay_dmae_xy(pipe); /* dma_e */ mdp4_overlayproc_cfg(pipe); if (pipe->pipe_type == OVERLAY_TYPE_RGB) { pipe->srcp0_addr = (uint32) mfd->ibuf.buf; mdp4_overlay_rgb_setup(pipe); } mdp4_mixer_stage_up(pipe); mdp4_overlay_reg_flush(pipe, 1); dtv_pipe = pipe; /* keep it */ }
void mdp4_overlay_update_lcd(struct msm_fb_data_type *mfd) { MDPIBUF *iBuf = &mfd->ibuf; uint8 *src; int ptype; uint32 mddi_ld_param; uint16 mddi_vdo_packet_reg; struct mdp4_overlay_pipe *pipe; int ret; if (mfd->key != MFD_KEY) return; mddi_mfd = mfd; /* keep it */ init_completion(&mdp4_overlay_completion); /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); if (mddi_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, FALSE); if (pipe == NULL) printk(KERN_INFO "%s: pipe_alloc failed\n", __func__); pipe->pipe_used++; pipe->mixer_num = MDP4_MIXER0; pipe->src_format = mfd->fb_imgType; mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_MDDI); ret = mdp4_overlay_format2pipe(pipe); if (ret < 0) printk(KERN_INFO "%s: format2type failed\n", __func__); mddi_pipe = pipe; /* keep it */ mddi_ld_param = 0; mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt; if (mfd->panel_info.type == MDDI_PANEL) { if (mfd->panel_info.pdest == DISPLAY_1) mddi_ld_param = 0; else mddi_ld_param = 1; } else { mddi_ld_param = 2; } MDP_OUTP(MDP_BASE + 0x00090, mddi_ld_param); if (mfd->panel_info.bpp == 24) MDP_OUTP(MDP_BASE + 0x00094, (MDDI_VDO_PACKET_DESC_24 << 16) | mddi_vdo_packet_reg); else if (mfd->panel_info.bpp == 16) MDP_OUTP(MDP_BASE + 0x00094, (MDDI_VDO_PACKET_DESC_16 << 16) | mddi_vdo_packet_reg); else MDP_OUTP(MDP_BASE + 0x00094, (MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg); MDP_OUTP(MDP_BASE + 0x00098, 0x01); } else { pipe = mddi_pipe; } /* 0 for dma_p, client_id = 0 */ MDP_OUTP(MDP_BASE + 0x00090, 0); src = (uint8 *) iBuf->buf; #ifdef WHOLESCREEN { struct fb_info *fbi; fbi = mfd->fbi; 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->dst_y = 0; pipe->dst_x = 0; pipe->srcp0_addr = (uint32)src; pipe->srcp0_ystride = fbi->fix.line_length; } #else if (mdp4_overlay_active(MDP4_MIXER0)) { struct fb_info *fbi; fbi = mfd->fbi; 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->dst_y = 0; pipe->dst_x = 0; pipe->srcp0_addr = (uint32) src; pipe->srcp0_ystride = fbi->fix.line_length; } else { /* starting input address */ src += (iBuf->dma_x + iBuf->dma_y * iBuf->ibuf_width) * iBuf->bpp; pipe->src_height = iBuf->dma_h; pipe->src_width = iBuf->dma_w; pipe->src_h = iBuf->dma_h; pipe->src_w = iBuf->dma_w; pipe->src_y = 0; pipe->src_x = 0; pipe->dst_h = iBuf->dma_h; pipe->dst_w = iBuf->dma_w; pipe->dst_y = iBuf->dma_y; pipe->dst_x = iBuf->dma_x; pipe->srcp0_addr = (uint32) src; pipe->srcp0_ystride = iBuf->ibuf_width * iBuf->bpp; } #endif pipe->mixer_stage = MDP4_MIXER_STAGE_BASE; mdp4_overlay_rgb_setup(pipe); mdp4_mixer_stage_up(pipe); mdp4_overlayproc_cfg(pipe); mdp4_overlay_dmap_xy(pipe); mdp4_overlay_dmap_cfg(mfd, 0); mdp4_mddi_vsync_enable(mfd, pipe, 0); /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); }
int mdp4_lcdc_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 undx, need_wait = 0; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); vctrl = &vsync_ctrl_db[cndx]; pipe = vctrl->base_pipe; atomic_set(&vctrl->suspend, 1); atomic_set(&vctrl->vsync_resume, 0); msleep(20); /* >= 17 ms */ complete_all(&vctrl->vsync_comp); 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_lcdc_wait4ov(0); } mdp_histogram_ctrl_all(FALSE); MDP_OUTP(MDP_BASE + LCDC_BASE, 0); lcdc_enabled = 0; if (vctrl->vsync_irq_enabled) { vctrl->vsync_irq_enabled = 0; vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM); } 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 */ vp->update_cnt = 0; /* empty queue */ } if (pipe) { /* sanity check, free pipes besides base layer */ mdp4_overlay_unset_mixer(pipe->mixer_num); 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); 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); } } /* MDP clock disable */ mdp_clk_ctrl(0); mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); 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; unsigned long flags; int need_wait = 0; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); vctrl = &vsync_ctrl_db[cndx]; pipe = vctrl->base_pipe; atomic_set(&vctrl->suspend, 1); atomic_set(&vctrl->vsync_resume, 0); msleep(20); /* >= 17 ms */ complete_all(&vctrl->vsync_comp); 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); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); dsi_video_enabled = 0; if (pipe) { /* sanity check, free pipes besides base layer */ mdp4_overlay_unset_mixer(pipe->mixer_num); 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); 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); } } /* mdp clock off */ mdp_clk_ctrl(0); mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); return ret; }
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; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; mdp4_overlay_ctrl_db_reset(); 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 (dsi_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__); 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__); dsi_pipe = pipe; /* keep it */ init_completion(&dsi_video_comp); mdp4_init_writeback_buf(mfd, MDP4_MIXER0); pipe->blt_addr = 0; } else { pipe = dsi_pipe; } #if defined(CONFIG_FB_MSM_MIPI_LGIT_CMD_WVGA_INVERSE_PT_PANEL) || \ defined(CONFIG_FB_MSM_MIPI_LGIT_VIDEO_WVGA_INVERSE_PT_PANEL) pipe->mfd = mfd; #endif /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); if (!(mfd->cont_splash_done)) { mfd->cont_splash_done = 1; mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); mdp4_overlay_dsi_video_wait4event(mfd, INTR_DMA_P_DONE); /* disable timing generator */ MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); mipi_dsi_controller_cfg(0); } if (is_mdp4_hw_reset()) { mdp4_hw_init(); outpdw(MDP_BASE + 0x0038, mdp4_display_intf); } 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->srcp0_ystride = fbi->fix.line_length; pipe->bpp = bpp; 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 pipe->dst_h = fbi->var.yres; pipe->dst_w = fbi->var.xres; mdp4_overlay_dmap_xy(pipe); /* dma_p */ mdp4_overlay_dmap_cfg(mfd, 1); mdp4_overlay_rgb_setup(pipe); mdp4_mixer_stage_up(pipe); mdp4_overlayproc_cfg(pipe); /* * 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.mipi.xres_pad; dsi_height = mfd->panel_info.yres + mfd->panel_info.mipi.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_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); /* LGE_CHANGE * Add QCT patches for blue screen issue after 1041 patches * 2012-03-15, [email protected] */ #ifdef QCT_PATCH mdp4_overlay_reg_flush(pipe, 1); #endif mdp_histogram_ctrl_all(TRUE); ret = panel_next_on(pdev); if (ret == 0) { if (display_on != NULL) { msleep(50); display_on(pdev); } } /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); return ret; }
void mdp_config_vsync(struct msm_fb_data_type *mfd) { /* vsync on primary lcd only for now */ if ((mfd->dest != DISPLAY_LCD) || (mfd->panel_info.pdest != DISPLAY_1) || (!vsync_mode)) { goto err_handle; } vsync_clk_status = 0; if (mfd->panel_info.lcd.vsync_enable) { mfd->total_porch_lines = mfd->panel_info.lcd.v_back_porch + mfd->panel_info.lcd.v_front_porch + mfd->panel_info.lcd.v_pulse_width; mfd->total_lcd_lines = mfd->panel_info.yres + mfd->total_porch_lines; mfd->lcd_ref_usec_time = 100000000 / mfd->panel_info.lcd.refx100; mfd->vsync_handler_pending = FALSE; mfd->last_vsync_timetick.tv.sec = 0; mfd->last_vsync_timetick.tv.nsec = 0; #ifdef MDP_HW_VSYNC if (mdp_vsync_clk == NULL) mdp_vsync_clk = clk_get(NULL, "mdp_vsync_clk"); if (IS_ERR(mdp_vsync_clk)) { printk(KERN_ERR "error: can't get mdp_vsync_clk!\n"); mfd->use_mdp_vsync = 0; } else mfd->use_mdp_vsync = 1; if (mfd->use_mdp_vsync) { uint32 vsync_cnt_cfg, vsync_cnt_cfg_dem; uint32 mdp_vsync_clk_speed_hz; mdp_vsync_clk_speed_hz = clk_get_rate(mdp_vsync_clk); if (mdp_vsync_clk_speed_hz == 0) { mfd->use_mdp_vsync = 0; } else { /* * Do this calculation in 2 steps for * rounding uint32 properly. */ vsync_cnt_cfg_dem = (mfd->panel_info.lcd.refx100 * mfd->total_lcd_lines) / 100; vsync_cnt_cfg = (mdp_vsync_clk_speed_hz) / vsync_cnt_cfg_dem; /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); mdp_hw_vsync_clk_enable(mfd); mdp_set_sync_cfg_0(mfd, vsync_cnt_cfg); #ifdef CONFIG_FB_MSM_MDP40 if (mdp_hw_revision < MDP4_REVISION_V2_1) mdp_set_sync_cfg_1(mfd, vsync_cnt_cfg); #endif /* * load the last line + 1 to be in the * safety zone */ vsync_load_cnt = mfd->panel_info.yres; /* line counter init value at the next pulse */ MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_INIT_VAL, vsync_load_cnt); #ifdef CONFIG_FB_MSM_MDP40 if (mdp_hw_revision < MDP4_REVISION_V2_1) { MDP_OUTP(MDP_BASE + MDP_SEC_VSYNC_INIT_VAL, vsync_load_cnt); } #endif /* * external vsync source pulse width and * polarity flip */ MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_OUT_CTRL, BIT(0)); #ifdef CONFIG_FB_MSM_MDP40 if (mdp_hw_revision < MDP4_REVISION_V2_1) { MDP_OUTP(MDP_BASE + MDP_SEC_VSYNC_OUT_CTRL, BIT(0)); MDP_OUTP(MDP_BASE + MDP_VSYNC_SEL, 0x20); } #endif /* threshold */ MDP_OUTP(MDP_BASE + 0x200, (vsync_above_th << 16) | (vsync_start_th)); mdp_hw_vsync_clk_disable(mfd); /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); } } #else mfd->use_mdp_vsync = 0; hrtimer_init(&mfd->dma_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); mfd->dma_hrtimer.function = mdp_dma2_vsync_hrtimer_handler; mfd->vsync_width_boundary = vmalloc(mfd->panel_info.xres * 4); #endif #ifdef CONFIG_FB_MSM_MDDI mfd->channel_irq = 0; if (mfd->panel_info.lcd.hw_vsync_mode) { u32 vsync_gpio = mfd->vsync_gpio; u32 ret; if (vsync_gpio == -1) { MSM_FB_INFO("vsync_gpio not defined!\n"); goto err_handle; } ret = gpio_tlmm_config(GPIO_CFG (vsync_gpio, (mfd->use_mdp_vsync) ? 1 : 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (ret) goto err_handle; /* * if use_mdp_vsync, then no interrupt need since * mdp_vsync is feed directly to mdp to reset the * write pointer counter. therefore no irq_handler * need to reset write pointer counter. */ if (!mfd->use_mdp_vsync) { mfd->channel_irq = MSM_GPIO_TO_INT(vsync_gpio); if (request_irq (mfd->channel_irq, &mdp_hw_vsync_handler_proxy, IRQF_TRIGGER_FALLING, "VSYNC_GPIO", (void *)mfd)) { MSM_FB_INFO ("irq=%d failed! vsync_gpio=%d\n", mfd->channel_irq, vsync_gpio); goto err_handle; } } } #endif mdp_hw_vsync_clk_enable(mfd); mdp_set_vsync((unsigned long)mfd); } return; err_handle: if (mfd->vsync_width_boundary) vfree(mfd->vsync_width_boundary); mfd->panel_info.lcd.vsync_enable = FALSE; printk(KERN_ERR "%s: failed!\n", __func__); }
static void mdp_dma_schedule(struct msm_fb_data_type *mfd, uint32 term) { /* * dma2 configure VSYNC block * vsync supported on Primary LCD only for now */ int32 mdp_lcd_rd_cnt; uint32 usec_wait_time; uint32 start_y; /* * ToDo: if we can move HRT timer callback to workqueue, we can * move DMA2 power on under mdp_pipe_kickoff(). * This will save a power for hrt time wait. * However if the latency for context switch (hrt irq -> workqueue) * is too big, we will miss the vsync timing. */ if (term == MDP_DMA2_TERM) mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE); mdp_dma2_update_time_in_usec = MDP_KTIME2USEC(mdp_dma2_last_update_time); if ((!mfd->ibuf.vsync_enable) || (!mfd->panel_info.lcd.vsync_enable) || (mfd->use_mdp_vsync)) { mdp_pipe_kickoff(term, mfd); return; } /* SW vsync logic starts here */ /* get current rd counter */ mdp_lcd_rd_cnt = mdp_get_lcd_line_counter(mfd); if (mdp_dma2_update_time_in_usec != 0) { uint32 num, den; /* * roi width boundary calculation to know the size of pixel * width that MDP can send faster or slower than LCD read * pointer */ num = mdp_last_dma2_update_width * mdp_last_dma2_update_height; den = (((mfd->panel_info.lcd.refx100 * mfd->total_lcd_lines) / 1000) * (mdp_dma2_update_time_in_usec / 100)) / 1000; if (den == 0) mfd->vsync_width_boundary[mdp_last_dma2_update_width] = mfd->panel_info.xres + 1; else mfd->vsync_width_boundary[mdp_last_dma2_update_width] = (int)(num / den); } if (mfd->vsync_width_boundary[mdp_last_dma2_update_width] > mdp_curr_dma2_update_width) { /* MDP wrp is faster than LCD rdp */ mdp_lcd_rd_cnt += mdp_lcd_rd_cnt_offset_fast; } else { /* MDP wrp is slower than LCD rdp */ mdp_lcd_rd_cnt -= mdp_lcd_rd_cnt_offset_slow; } if (mdp_lcd_rd_cnt < 0) mdp_lcd_rd_cnt = mfd->total_lcd_lines + mdp_lcd_rd_cnt; else if (mdp_lcd_rd_cnt > mfd->total_lcd_lines) mdp_lcd_rd_cnt = mdp_lcd_rd_cnt - mfd->total_lcd_lines - 1; /* get wrt pointer position */ start_y = mfd->ibuf.dma_y; /* measure line difference between start_y and rd counter */ if (start_y > mdp_lcd_rd_cnt) { /* * *100 for lcd_ref_hzx100 was already multiplied by 100 * *1000000 is for usec conversion */ if ((start_y - mdp_lcd_rd_cnt) <= mdp_vsync_usec_wait_line_too_short) usec_wait_time = 0; else usec_wait_time = ((start_y - mdp_lcd_rd_cnt) * 1000000) / ((mfd->total_lcd_lines * mfd->panel_info.lcd.refx100) / 100); } else { if ((start_y + (mfd->total_lcd_lines - mdp_lcd_rd_cnt)) <= mdp_vsync_usec_wait_line_too_short) usec_wait_time = 0; else usec_wait_time = ((start_y + (mfd->total_lcd_lines - mdp_lcd_rd_cnt)) * 1000000) / ((mfd->total_lcd_lines * mfd->panel_info.lcd.refx100) / 100); } mdp_last_dma2_update_width = mdp_curr_dma2_update_width; mdp_last_dma2_update_height = mdp_curr_dma2_update_height; if (usec_wait_time == 0) { mdp_pipe_kickoff(term, mfd); } else { ktime_t wait_time; wait_time.tv.sec = 0; wait_time.tv.nsec = usec_wait_time * 1000; if (msm_fb_debug_enabled) { vt = ktime_get_real(); mdp_expected_usec_wait = usec_wait_time; } hrtimer_start(&mfd->dma_hrtimer, wait_time, HRTIMER_MODE_REL); } }
void mdp_pipe_kickoff(uint32 term, struct msm_fb_data_type *mfd) { /* complete all the writes before starting */ wmb(); /* kick off PPP engine */ if (term == MDP_PPP_TERM) { if (mdp_debug[MDP_PPP_BLOCK]) jiffies_to_timeval(jiffies, &mdp_ppp_timeval); /* let's turn on PPP block */ mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_ON, FALSE); mdp_enable_irq(term); INIT_COMPLETION(mdp_ppp_comp); mdp_ppp_waiting = TRUE; outpdw(MDP_BASE + 0x30, 0x1000); wait_for_completion_killable(&mdp_ppp_comp); mdp_disable_irq(term); if (mdp_debug[MDP_PPP_BLOCK]) { struct timeval now; jiffies_to_timeval(jiffies, &now); mdp_ppp_timeval.tv_usec = now.tv_usec - mdp_ppp_timeval.tv_usec; MSM_FB_INFO("MDP-PPP: %d\n", (int)mdp_ppp_timeval.tv_usec); } } else if (term == MDP_DMA2_TERM) { if (mdp_debug[MDP_DMA2_BLOCK]) { MSM_FB_INFO("MDP-DMA2: %d\n", (int)mdp_dma2_timeval.tv_usec); jiffies_to_timeval(jiffies, &mdp_dma2_timeval); } /* DMA update timestamp */ mdp_dma2_last_update_time = ktime_get_real(); /* let's turn on DMA2 block */ #if 0 mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE); #endif #ifdef CONFIG_MSM_MDP22 outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x0044, 0x0);/* start DMA */ #else mdp_lut_enable(); #ifdef CONFIG_MSM_MDP40 outpdw(MDP_BASE + 0x000c, 0x0); /* start DMA */ #else outpdw(MDP_BASE + 0x0044, 0x0); /* start DMA */ #endif #endif #ifdef CONFIG_MSM_MDP40 } else if (term == MDP_DMA_S_TERM) { mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_ON, FALSE); outpdw(MDP_BASE + 0x0010, 0x0); /* start DMA */ } else if (term == MDP_DMA_E_TERM) { mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_ON, FALSE); outpdw(MDP_BASE + 0x0014, 0x0); /* start DMA */ } else if (term == MDP_OVERLAY0_TERM) { mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE); mdp_lut_enable(); outpdw(MDP_BASE + 0x0004, 0); } else if (term == MDP_OVERLAY1_TERM) { mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_ON, FALSE); mdp_lut_enable(); outpdw(MDP_BASE + 0x0008, 0); } #else } else if (term == MDP_DMA_S_TERM) {
/*LGE_CHANGE_E LCD Reset After Data Pulled Down*/ static int mipi_dsi_off(struct platform_device *pdev) { int ret = 0; struct msm_fb_data_type *mfd; struct msm_panel_info *pinfo; mfd = platform_get_drvdata(pdev); pinfo = &mfd->panel_info; if (mdp_rev >= MDP_REV_41) mutex_lock(&mfd->dma->ov_mutex); else down(&mfd->dma->mutex); mdp4_overlay_dsi_state_set(ST_DSI_SUSPEND); /* * Description: dsi clock is need to perform shutdown. * mdp4_dsi_cmd_dma_busy_wait() will enable dsi clock if disabled. * also, wait until dma (overlay and dmap) finish. */ if (mfd->panel_info.type == MIPI_CMD_PANEL) { if (mdp_rev >= MDP_REV_41) { mdp4_dsi_cmd_dma_busy_wait(mfd); mdp4_dsi_blt_dmap_busy_wait(mfd); mipi_dsi_mdp_busy_wait(mfd); } else { mdp3_dsi_cmd_dma_busy_wait(mfd); } } /* * Desctiption: change to DSI_CMD_MODE since it needed to * tx DCS dsiplay off comamnd to panel */ //LGE_CHANGE_S [Kiran] Change LCD sleep sequence /*LGE_CHANGE_S: [email protected] 05-03-2012*/ /*LCD Reset After data pulled Down*/ #if 0 if(lglogo_firstboot) { mipi_dsi_op_mode_config(DSI_CMD_MODE); } #endif /*LGE_CHANGE_E LCD Reset After Data Pulled Down*/ //LGE_CHANGE_E [Kiran] Change LCD sleep sequence if (mfd->panel_info.type == MIPI_CMD_PANEL) { if (pinfo->lcd.vsync_enable) { if (pinfo->lcd.hw_vsync_mode && vsync_gpio >= 0) { if (MDP_REV_303 != mdp_rev) gpio_free(vsync_gpio); } mipi_dsi_set_tear_off(mfd); } } ret = panel_next_off(pdev); #ifdef CONFIG_MSM_BUS_SCALING mdp_bus_scale_update_request(0); #endif /*LGE_START: [email protected] 25-2-2012*/ /*In case of ESD no delays required in power off*/ //LGE_CHANGE_S [Kiran] Change LCD sleep sequence #ifdef CONFIG_LGE_LCD_ESD_DETECTION if (true == is_esd_occured) { printk("ESD.Paneloff ASAP\n"); } else #endif msleep(300); //LGE_CHANGE_E [Kiran] Change LCD sleep sequence /*LGE_END: [email protected]*/ #ifdef CONFIG_FB_MSM_MIPI_DSI_LG4573B_BOOT_LOGO if(lglogo_firstboot) { printk(KERN_INFO "[DISPLAY]::%s\n",__func__); local_bh_disable(); lglogo_mipi_dsi_clk_disable(); local_bh_enable(); } else #endif { local_bh_disable(); mipi_dsi_clk_disable(); local_bh_enable(); } /* disbale dsi engine */ MIPI_OUTP(MIPI_DSI_BASE + 0x0000, 0); mipi_dsi_phy_ctrl(0); #ifdef CONFIG_FB_MSM_MIPI_DSI_LG4573B_BOOT_LOGO if(!lglogo_firstboot) #endif { local_bh_disable(); mipi_dsi_ahb_ctrl(0); local_bh_enable(); } //LGE_CHANGE_S [Kiran] Change LCD sleep sequence #if 1 /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); /*Turning off DMA_P block*/ mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); #endif //LGE_CHANGE_E [Kiran] Change LCD sleep sequence /*LGE_CHANGE_S: [email protected] 05-03-2012*/ /*LCD Reset After data pulled Down*/ mipi_ldp_lcd_panel_poweroff(); /*LGE_CHANGE_E LCD Reset After Data Pulled Down*/ if (mipi_dsi_pdata && mipi_dsi_pdata->dsi_power_save) mipi_dsi_pdata->dsi_power_save(0); if (mdp_rev >= MDP_REV_41) mutex_unlock(&mfd->dma->ov_mutex); else up(&mfd->dma->mutex); pr_debug("%s-:\n", __func__); #ifdef CONFIG_FB_MSM_MIPI_DSI_LG4573B_BOOT_LOGO lglogo_firstboot = FALSE; #endif return ret; }
int mdp_lcdc_on(struct platform_device *pdev) { int lcdc_width; int lcdc_height; int lcdc_bpp; int lcdc_border_clr; int lcdc_underflow_clr; int lcdc_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; 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; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; fbi = mfd->fbi; var = &fbi->var; /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf += fbi->var.xoffset * bpp + fbi->var.yoffset * fbi->fix.line_length; if (lcdc_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); if (pipe == NULL) printk(KERN_INFO "%s: pipe_alloc failed\n", __func__); pipe->pipe_used++; pipe->mixer_stage = MDP4_MIXER_STAGE_BASE; pipe->mixer_num = MDP4_MIXER0; pipe->src_format = mfd->fb_imgType; ret = mdp4_overlay_format2pipe(pipe); if (ret < 0) printk(KERN_INFO "%s: format2pipe failed\n", __func__); lcdc_pipe = pipe; /* keep it */ } else { pipe = lcdc_pipe; } 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->srcp0_addr = (uint32) buf; pipe->srcp0_ystride = fbi->fix.line_length; mdp4_overlay_dmap_xy(pipe); mdp4_overlay_dmap_cfg(mfd, 1); mdp4_overlay_rgb_setup(pipe); mdp4_mixer_stage_up(pipe); mdp4_overlayproc_cfg(pipe); /* * LCDC 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; lcdc_border_clr = mfd->panel_info.lcdc.border_clr; lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr; lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew; lcdc_width = mfd->panel_info.xres; lcdc_height = mfd->panel_info.yres; lcdc_bpp = mfd->panel_info.bpp; hsync_period = hsync_pulse_width + h_back_porch + lcdc_width + h_front_porch; hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; hsync_start_x = hsync_pulse_width + h_back_porch; 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 + lcdc_height + v_front_porch) * hsync_period; display_v_start = (vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew; display_v_end = vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1; if (lcdc_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 (lcdc_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; } #ifdef CONFIG_FB_MSM_MDP40 hsync_polarity = 1; vsync_polarity = 1; lcdc_underflow_clr |= 0x80000000; /* enable recovery */ #else hsync_polarity = 0; vsync_polarity = 0; #endif data_en_polarity = 0; ctrl_polarity = (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x4, hsync_ctrl); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x8, vsync_period); MDP_OUTP(MDP_BASE + LCDC_BASE + 0xc, vsync_pulse_width * hsync_period); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x10, display_hctl); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x14, display_v_start); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x18, display_v_end); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x28, lcdc_border_clr); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x2c, lcdc_underflow_clr); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x30, lcdc_hsync_skew); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x38, ctrl_polarity); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x1c, active_hctl); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x20, active_v_start); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x24, active_v_end); ret = panel_next_on(pdev); if (ret == 0) { /* enable LCDC block */ MDP_OUTP(MDP_BASE + LCDC_BASE, 1); mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE); } /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); return ret; }
int mdp4_lcdc_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 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_lcdc_wait4vsync(cndx); atomic_set(&vctrl->vsync_resume, 0); complete_all(&vctrl->vsync_comp); //yanghai add the iommu patch 2013.5.25 #ifdef CONFIG_VENDOR_EDIT vctrl->wait_vsync_cnt = 0; #endif //yanghai add end 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_lcdc_wait4ov(0); } mdp_histogram_ctrl_all(FALSE); lcdc_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_lcdc_pipe_clean(vp); } if (pipe) { /* sanity check, free pipes besides base layer */ mdp4_overlay_unset_mixer(pipe->mixer_num); 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); 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_lcdc_tg_off(vctrl); atomic_set(&vctrl->suspend, 1); /* MDP clock disable */ mdp_clk_ctrl(0); mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); mutex_unlock(&mfd->dma->ov_mutex); return ret; }
void mdp4_overlay_update_dsi_cmd(struct msm_fb_data_type *mfd) { MDPIBUF *iBuf = &mfd->ibuf; uint8 *src; int ptype; struct mdp4_overlay_pipe *pipe; int bpp; int ret; if (mfd->key != MFD_KEY) return; dsi_mfd = mfd; /* keep it */ /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); if (dsi_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, 0); if (pipe == NULL) printk(KERN_INFO "%s: pipe_alloc failed\n", __func__); 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_CMD); ret = mdp4_overlay_format2pipe(pipe); if (ret < 0) printk(KERN_INFO "%s: format2type failed\n", __func__); #ifdef DSI_CLK_CTRL init_timer(&dsi_clock_timer); dsi_clock_timer.function = dsi_clock_tout; dsi_clock_timer.data = (unsigned long) mfd;; #endif dsi_pipe = pipe; /* keep it */ /* * configure dsi stream id * dma_p = 0, dma_s = 1 */ MDP_OUTP(MDP_BASE + 0x000a0, 0x10); /* enable dsi trigger on dma_p */ MDP_OUTP(MDP_BASE + 0x000a4, 0x01); } else { pipe = dsi_pipe; } /* whole screen for base layer */ src = (uint8 *) iBuf->buf; { struct fb_info *fbi; fbi = mfd->fbi; if (pipe->is_3d) { bpp = fbi->var.bits_per_pixel / 8; pipe->src_height = pipe->src_height_3d; pipe->src_width = pipe->src_width_3d; pipe->src_h = pipe->src_height_3d; pipe->src_w = pipe->src_width_3d; pipe->dst_h = pipe->src_height_3d; pipe->dst_w = pipe->src_width_3d; pipe->srcp0_ystride = msm_fb_line_length(0, pipe->src_width, bpp); } else { /* 2D */ 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->dst_h = fbi->var.yres; pipe->dst_w = fbi->var.xres; pipe->srcp0_ystride = fbi->fix.line_length; } pipe->src_y = 0; pipe->src_x = 0; pipe->dst_y = 0; pipe->dst_x = 0; pipe->srcp0_addr = (uint32)src; } mdp4_overlay_rgb_setup(pipe); mdp4_mixer_stage_up(pipe); mdp4_overlayproc_cfg(pipe); mdp4_overlay_dmap_xy(pipe); mdp4_overlay_dmap_cfg(mfd, 0); mdp4_mipi_vsync_enable(mfd, pipe, 0); /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); wmb(); }
int mdp_lcdc_on(struct platform_device *pdev) { int lcdc_width; int lcdc_height; int lcdc_bpp; int lcdc_border_clr; int lcdc_underflow_clr; int lcdc_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; 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; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; fbi = mfd->fbi; var = &fbi->var; /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); if (is_mdp4_hw_reset()) { mdp4_hw_init(); outpdw(MDP_BASE + 0x0038, mdp4_display_intf); } bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf += fbi->var.xoffset * bpp + fbi->var.yoffset * fbi->fix.line_length; if (lcdc_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, 0); if (pipe == NULL) printk(KERN_INFO "%s: pipe_alloc failed\n", __func__); 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_LCDC); ret = mdp4_overlay_format2pipe(pipe); if (ret < 0) printk(KERN_INFO "%s: format2pipe failed\n", __func__); lcdc_pipe = pipe; /* keep it */ init_completion(&lcdc_comp); } else { pipe = lcdc_pipe; } 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->srcp0_addr = (uint32) buf; pipe->srcp0_ystride = fbi->fix.line_length; mdp4_overlay_dmap_xy(pipe); mdp4_overlay_dmap_cfg(mfd, 1); mdp4_overlay_rgb_setup(pipe); mdp4_mixer_stage_up(pipe); mdp4_overlayproc_cfg(pipe); /* * LCDC 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; lcdc_border_clr = mfd->panel_info.lcdc.border_clr; lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr; lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew; lcdc_width = var->xres; lcdc_height = var->yres; lcdc_bpp = mfd->panel_info.bpp; hsync_period = hsync_pulse_width + h_back_porch + lcdc_width + h_front_porch; hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; hsync_start_x = hsync_pulse_width + h_back_porch; 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 + lcdc_height + v_front_porch) * hsync_period; display_v_start = (vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew; display_v_end = vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1; if (lcdc_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 (lcdc_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; } #ifdef CONFIG_FB_MSM_MDP40 hsync_polarity = 1; vsync_polarity = 1; lcdc_underflow_clr |= 0x80000000; /* enable recovery */ #else hsync_polarity = 0; vsync_polarity = 0; #endif #if defined(CONFIG_MACH_ARIESVE) || defined(CONFIG_MACH_APACHE) data_en_polarity =1; #elif defined(CONFIG_MACH_ANCORA) || defined(CONFIG_MACH_ANCORA_TMO) data_en_polarity =0; #elif defined(CONFIG_MACH_GODART) data_en_polarity =0; #else data_en_polarity =0; #endif printk(KERN_CRIT " LCDC polarity :%d \n", (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity)); ctrl_polarity = (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x4, hsync_ctrl); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x8, vsync_period); MDP_OUTP(MDP_BASE + LCDC_BASE + 0xc, vsync_pulse_width * hsync_period); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x10, display_hctl); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x14, display_v_start); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x18, display_v_end); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x28, lcdc_border_clr); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x2c, lcdc_underflow_clr); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x30, lcdc_hsync_skew); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x38, ctrl_polarity); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x1c, active_hctl); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x20, active_v_start); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x24, active_v_end); mdp4_overlay_reg_flush(pipe, 1); #ifdef CONFIG_MSM_BUS_SCALING mdp_bus_scale_update_request(2); #endif mdp_histogram_ctrl(TRUE); #if defined (CONFIG_MACH_ANCORA) // 1) vsync 2) panel on and : LSI LDI Requirement if(board_lcd_hw_revision==3) //for HYDIS { ret = panel_next_on(pdev); if (ret == 0) { /* enable LCDC block */ MDP_OUTP(MDP_BASE + LCDC_BASE, 1); mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE); } /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); } else { /* enable LCDC block */ MDP_OUTP(MDP_BASE + LCDC_BASE, 1); mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE); /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); ret = panel_next_on(pdev); if (ret != 0) { MDP_OUTP(MDP_BASE + LCDC_BASE, 0); } } #elif defined(CONFIG_MACH_APACHE) /* enable LCDC block */ MDP_OUTP(MDP_BASE + LCDC_BASE, 1); mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE); /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); ret = panel_next_on(pdev); if (ret != 0) { MDP_OUTP(MDP_BASE + LCDC_BASE, 0); } #else // 1) panel on and 2) vsync ret = panel_next_on(pdev); if (ret == 0) { /* enable LCDC block */ MDP_OUTP(MDP_BASE + LCDC_BASE, 1); mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE); } /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); #endif return ret; }
void mdp4_dsi_cmd_3d(struct msm_fb_data_type *mfd, struct msmfb_overlay_3d *r3d) { struct fb_info *fbi; struct mdp4_overlay_pipe *pipe; int bpp; uint8 *src = NULL; if (dsi_pipe == NULL) return; dsi_pipe->is_3d = r3d->is_3d; dsi_pipe->src_height_3d = r3d->height; dsi_pipe->src_width_3d = r3d->width; pipe = dsi_pipe; if (pipe->is_3d) mdp4_overlay_panel_3d(pipe->mixer_num, MDP4_3D_SIDE_BY_SIDE); else mdp4_overlay_panel_3d(pipe->mixer_num, MDP4_3D_NONE); if (mfd->panel_power_on) mdp4_dsi_cmd_dma_busy_wait(mfd); fbi = mfd->fbi; if (pipe->is_3d) { bpp = fbi->var.bits_per_pixel / 8; pipe->src_height = pipe->src_height_3d; pipe->src_width = pipe->src_width_3d; pipe->src_h = pipe->src_height_3d; pipe->src_w = pipe->src_width_3d; pipe->dst_h = pipe->src_height_3d; pipe->dst_w = pipe->src_width_3d; pipe->srcp0_ystride = msm_fb_line_length(0, pipe->src_width, bpp); } else { /* 2D */ 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->dst_h = fbi->var.yres; pipe->dst_w = fbi->var.xres; pipe->srcp0_ystride = fbi->fix.line_length; } pipe->src_y = 0; pipe->src_x = 0; pipe->dst_y = 0; pipe->dst_x = 0; pipe->srcp0_addr = (uint32)src; mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); mdp4_overlay_rgb_setup(pipe); mdp4_mixer_stage_up(pipe); mdp4_overlayproc_cfg(pipe); mdp4_overlay_dmap_xy(pipe); mdp4_overlay_dmap_cfg(mfd, 0); /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); }
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); if (!(mfd->cont_splash_done)) { mfd->cont_splash_done = 1; mdp4_dsi_video_tg_off(vctrl); mipi_dsi_controller_cfg(0); /* Clks are enabled in probe. Disabling clocks now */ mdp_clk_ctrl(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 mdp4_atv_on(struct platform_device *pdev) { uint8 *buf; 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; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; fbi = mfd->fbi; var = &fbi->var; bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf += fbi->var.xoffset * bpp + fbi->var.yoffset * fbi->fix.line_length; if (atv_pipe == NULL) { ptype = mdp4_overlay_format2type(mfd->fb_imgType); pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER1, 0); if (pipe == NULL) return -EBUSY; pipe->pipe_used++; pipe->mixer_stage = MDP4_MIXER_STAGE_BASE; pipe->mixer_num = MDP4_MIXER1; pipe->src_format = mfd->fb_imgType; mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_ATV); mdp4_overlay_format2pipe(pipe); atv_pipe = pipe; /* keep it */ } else { pipe = atv_pipe; } printk(KERN_INFO "mdp4_atv_overlay: pipe=%x ndx=%d\n", (int)pipe, pipe->pipe_ndx); /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); /* Turn the next panel on, get correct resolution before configuring overlay pipe */ ret = panel_next_on(pdev); pr_info("%s: fbi->var.yres: %d | fbi->var.xres: %d", __func__, fbi->var.yres, fbi->var.xres); /* MDP4 Config */ 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->srcp0_addr = (uint32) buf; pipe->srcp0_ystride = fbi->fix.line_length; mdp4_overlay_dmae_xy(pipe); /* dma_e */ mdp4_overlay_dmae_cfg(mfd, 1); mdp4_overlay_rgb_setup(pipe); mdp4_mixer_stage_up(pipe); mdp4_overlayproc_cfg(pipe); if (ret == 0) mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_ON, FALSE); /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); return ret; }
static int mdp4_dtv_start(struct msm_fb_data_type *mfd) { int dtv_width; int dtv_height; int dtv_bpp; int dtv_border_clr; int dtv_underflow_clr; int dtv_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; struct fb_info *fbi; struct fb_var_screeninfo *var; struct vsycn_ctrl *vctrl; vctrl = &vsync_ctrl_db[0]; if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; fbi = mfd->fbi; var = &fbi->var; vctrl->mfd = mfd; mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); if (hdmi_prim_display) { if (is_mdp4_hw_reset()) { mdp4_hw_init(); outpdw(MDP_BASE + 0x0038, mdp4_display_intf); } } mdp4_overlay_dmae_cfg(mfd, 0); /* * DTV 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; dtv_border_clr = mfd->panel_info.lcdc.border_clr; dtv_underflow_clr = mfd->panel_info.lcdc.underflow_clr; dtv_hsync_skew = mfd->panel_info.lcdc.hsync_skew; pr_info("%s: <ID=%d %dx%d (%d,%d,%d), (%d,%d,%d) %dMHz>\n", __func__, var->reserved[3], var->xres, var->yres, var->right_margin, var->hsync_len, var->left_margin, var->lower_margin, var->vsync_len, var->upper_margin, var->pixclock/1000/1000); dtv_width = var->xres; dtv_height = var->yres; dtv_bpp = mfd->panel_info.bpp; hsync_period = hsync_pulse_width + h_back_porch + dtv_width + h_front_porch; hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; hsync_start_x = hsync_pulse_width + h_back_porch; 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 + dtv_height + v_front_porch) * hsync_period; display_v_start = (vsync_pulse_width + v_back_porch) * hsync_period + dtv_hsync_skew; display_v_end = vsync_period - (v_front_porch * hsync_period) + dtv_hsync_skew - 1; if (dtv_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 (dtv_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; } dtv_underflow_clr |= 0x80000000; /* enable recovery */ hsync_polarity = fbi->var.yres >= 720 ? 0 : 1; vsync_polarity = fbi->var.yres >= 720 ? 0 : 1; data_en_polarity = 0; ctrl_polarity = (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); MDP_OUTP(MDP_BASE + DTV_BASE + 0x4, hsync_ctrl); MDP_OUTP(MDP_BASE + DTV_BASE + 0x8, vsync_period); MDP_OUTP(MDP_BASE + DTV_BASE + 0xc, vsync_pulse_width * hsync_period); MDP_OUTP(MDP_BASE + DTV_BASE + 0x18, display_hctl); MDP_OUTP(MDP_BASE + DTV_BASE + 0x1c, display_v_start); MDP_OUTP(MDP_BASE + DTV_BASE + 0x20, display_v_end); MDP_OUTP(MDP_BASE + DTV_BASE + 0x40, dtv_border_clr); MDP_OUTP(MDP_BASE + DTV_BASE + 0x44, dtv_underflow_clr); MDP_OUTP(MDP_BASE + DTV_BASE + 0x48, dtv_hsync_skew); MDP_OUTP(MDP_BASE + DTV_BASE + 0x50, ctrl_polarity); MDP_OUTP(MDP_BASE + DTV_BASE + 0x2c, active_hctl); MDP_OUTP(MDP_BASE + DTV_BASE + 0x30, active_v_start); MDP_OUTP(MDP_BASE + DTV_BASE + 0x38, active_v_end); /* Test pattern 8 x 8 pixel */ /* MDP_OUTP(MDP_BASE + DTV_BASE + 0x4C, 0x80000808); */ /* enable DTV block */ MDP_OUTP(MDP_BASE + DTV_BASE, 1); return 0; }
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; 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; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; fbi = mfd->fbi; var = &fbi->var; bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf += fbi->var.xoffset * bpp + fbi->var.yoffset * fbi->fix.line_length; if (dsi_pipe == NULL) { ptype = mdp4_overlay_format2type(mfd->fb_imgType); if (ptype < 0) printk(KERN_INFO "[MDP4] %s: format2type failed\n", __func__); pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0, 0); if (pipe == NULL) { printk(KERN_INFO "[MDP4] %s: pipe_alloc failed\n", __func__); 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 "[MDP4] %s: format2type failed\n", __func__); dsi_pipe = pipe; /* keep it */ init_completion(&dsi_video_comp); writeback_offset = mdp4_overlay_writeback_setup( fbi, pipe, buf, bpp); } else { pipe = dsi_pipe; } /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); if (is_mdp4_hw_reset()) { mdp4_hw_init(); outpdw(MDP_BASE + 0x0038, mdp4_display_intf); } 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->srcp0_addr = (uint32) buf; pipe->srcp0_ystride = fbi->fix.line_length; pipe->bpp = bpp; mdp4_overlay_dmap_xy(pipe); /* dma_p */ mdp4_overlay_dmap_cfg(mfd, 1); mdp4_overlay_rgb_setup(pipe); mdp4_mixer_stage_up(pipe); mdp4_overlayproc_cfg(pipe); /* * 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; dsi_height = mfd->panel_info.yres; 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_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); mdp4_overlay_reg_flush(pipe, 1); mdp_histogram_ctrl(TRUE); ret = panel_next_on(pdev); if (ret == 0) { /* enable DSI block */ MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1); mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE); if (display_on != NULL) { msleep(50); display_on(pdev); } } /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); return ret; }
/* 3D side by side */ void mdp4_dsi_cmd_3d_sbys(struct msm_fb_data_type *mfd, struct msmfb_overlay_3d *r3d) { struct fb_info *fbi; int bpp; uint8 *src = NULL; int cndx = 0; struct vsycn_ctrl *vctrl; struct mdp4_overlay_pipe *pipe; vctrl = &vsync_ctrl_db[cndx]; pipe = vctrl->base_pipe; if (pipe == NULL) return; if (pipe->pipe_used == 0 || pipe->mixer_stage != MDP4_MIXER_STAGE_BASE) { pr_err("%s: NOT baselayer\n", __func__); return; } pipe->is_3d = r3d->is_3d; pipe->src_height_3d = r3d->height; pipe->src_width_3d = r3d->width; if (pipe->is_3d) mdp4_overlay_panel_3d(pipe->mixer_num, MDP4_3D_SIDE_BY_SIDE); else mdp4_overlay_panel_3d(pipe->mixer_num, MDP4_3D_NONE); fbi = mfd->fbi; if (pipe->is_3d) { bpp = fbi->var.bits_per_pixel / 8; pipe->src_height = pipe->src_height_3d; pipe->src_width = pipe->src_width_3d; pipe->src_h = pipe->src_height_3d; pipe->src_w = pipe->src_width_3d; pipe->dst_h = pipe->src_height_3d; pipe->dst_w = pipe->src_width_3d; pipe->srcp0_ystride = msm_fb_line_length(0, pipe->src_width, bpp); } else { /* 2D */ 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->dst_h = fbi->var.yres; pipe->dst_w = fbi->var.xres; pipe->srcp0_ystride = fbi->fix.line_length; } pipe->src_y = 0; pipe->src_x = 0; pipe->dst_y = 0; pipe->dst_x = 0; pipe->srcp0_addr = (uint32)src; mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); mdp_clk_ctrl(1); mdp4_overlay_rgb_setup(pipe); mdp4_overlay_reg_flush(pipe, 1); mdp4_mixer_stage_up(pipe, 0); mdp4_overlayproc_cfg(pipe); mdp4_overlay_dmap_xy(pipe); mdp4_overlay_dmap_cfg(mfd, 0); mdp4_mixer_stage_commit(pipe->mixer_num); /* MDP cmd block disable */ mdp_clk_ctrl(0); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); }
void lut_tune(int num, unsigned int *pLutTable ) { // int fb; struct fb_info *info; struct fb_cmap test_cmap; struct fb_cmap *cmap; static int mdp_lut_i = 0; u16 r_1, g_1, b_1;//for final assignment // fb = open("/dev/graphics/fb0", O_RDWR); info = registered_fb[0]; __u16 *r, *g, *b, i; int j = 0; cmap = &test_cmap; //===================================== // cmap allocation //===================================== cmap->red = 0; cmap->green = 0; cmap->blue = 0; cmap->transp = 0; cmap->start = 0; cmap->len = num; // MAX_LUT_SIZE;//LUT has 256 entries cmap->red = kmalloc(cmap->len * sizeof(__u16), GFP_KERNEL); if (!cmap->red) { printk(KERN_ERR "can't malloc cmap!"); goto fail_rest; } cmap->green = kmalloc(cmap->len * sizeof(__u16), GFP_KERNEL); if (!cmap->green) { printk(KERN_ERR "can't malloc cmap!"); goto fail_rest; } cmap->blue = kmalloc(cmap->len * sizeof(__u16), GFP_KERNEL); if (!cmap->blue) { printk(KERN_ERR "can't malloc cmap!"); goto fail_rest; } r = cmap->red; g = cmap->green; b = cmap->blue; j = 0; DPRINT("cmap->len %d\n",cmap->len); /* Assigning the cmap*/ for (i = 0; i < cmap->len; i++) { *r++ = pLutTable[j++]; *g++ = pLutTable[j++]; *b++ = pLutTable[j++]; } #if 1 /*instead of an ioctl*/ mutex_lock(&msm_fb_ioctl_lut_sem1); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); //ret = mdp_lut_hw_update(cmap); j = 0; for (i = 0; i < cmap->len; i++) { // r_1 = mDNIe_data_R[i]; // g_1 = mDNIe_data_G[i]; // b_1 = mDNIe_data_B[i]; r_1 = pLutTable[j++]; g_1 = pLutTable[j++]; b_1 = pLutTable[j++]; #ifdef CONFIG_FB_MSM_MDP40 MDP_OUTP(MDP_BASE + 0x94800 + #else MDP_OUTP(MDP_BASE + 0x93800 + #endif (0x400*mdp_lut_i) + cmap->start*4 + i*4, ((g_1 & 0xff) | ((b_1 & 0xff) << 8) | ((r_1 & 0xff) << 16))); } MDP_OUTP(MDP_BASE + 0x90070, (mdp_lut_i << 10) | 0x17); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); mdp_lut_i = (mdp_lut_i + 1)%2; mutex_unlock(&msm_fb_ioctl_lut_sem1); #else info->fbops->fb_open && info->fbops->fb_ioctl(info, MSMFB_SET_LUT, cmap); #endif fail_rest: free_cmap(cmap); // close(fb); }