static void mdp4_overlay_dtv_alloc_pipe(struct msm_fb_data_type *mfd, int32 ptype, struct vsycn_ctrl *vctrl) { int ret = 0; struct fb_info *fbi = mfd->fbi; struct mdp4_overlay_pipe *pipe; if (vctrl->base_pipe != NULL) return; 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_OUTP(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x5004, ((0x0 & 0xFFF) << 16) | (0x0 & 0xFFF)); MDP_OUTP(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x5008, (0x0 & 0xFFF)); pipe->src_format = MDP_ARGB_8888; } 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->dst_h = fbi->var.yres; pipe->dst_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; mdp4_overlay_mdp_pipe_req(pipe, mfd); ret = mdp4_overlay_format2pipe(pipe); if (ret < 0) pr_warn("%s: format2type failed\n", __func__); mdp4_overlay_dmae_xy(pipe); mdp4_overlayproc_cfg(pipe); if (pipe->pipe_type == OVERLAY_TYPE_RGB) { pipe->srcp0_addr = (uint32) mfd->ibuf.buf; mdp4_overlay_rgb_setup(pipe); } mdp4_overlay_reg_flush(pipe, 1); mdp4_mixer_stage_up(pipe, 0); mdp4_mixer_stage_commit(pipe->mixer_num); vctrl->base_pipe = pipe; }
static void mdp4_dtv_do_blt(struct msm_fb_data_type *mfd, int enable) { unsigned long flag; int data; int cndx = 0; struct vsycn_ctrl *vctrl; struct mdp4_overlay_pipe *pipe; vctrl = &vsync_ctrl_db[cndx]; pipe = vctrl->base_pipe; mdp4_allocate_writeback_buf(mfd, MDP4_MIXER1); if (!mfd->ov1_wb_buf->write_addr) { pr_info("%s: ctrl=%d blt_base NOT assigned\n", __func__, cndx); return; } spin_lock_irqsave(&vctrl->spin_lock, flag); if (enable && pipe->ov_blt_addr == 0) { pipe->ov_blt_addr = mfd->ov1_wb_buf->write_addr; pipe->dma_blt_addr = mfd->ov1_wb_buf->read_addr; pipe->blt_cnt = 0; pipe->ov_cnt = 0; pipe->blt_dmap_done = 0; pipe->blt_ov_koff = 0; pipe->blt_ov_done = 0; mdp4_stat.blt_dtv++; vctrl->blt_change++; } else if (enable == 0 && pipe->ov_blt_addr) { pipe->ov_blt_addr = 0; pipe->dma_blt_addr = 0; vctrl->blt_change++; } pr_info("%s: enable=%d change=%d blt_addr=%x\n", __func__, enable, vctrl->blt_change, (int)pipe->ov_blt_addr); if (!vctrl->blt_change) { spin_unlock_irqrestore(&vctrl->spin_lock, flag); return; } atomic_set(&vctrl->suspend, 1); spin_unlock_irqrestore(&vctrl->spin_lock, flag); data = inpdw(MDP_BASE + DTV_BASE); data &= 0x01; if (data) /* timing generator enabled */ mdp4_dtv_wait4dmae(0); if (pipe->ov_blt_addr == 0) { MDP_OUTP(MDP_BASE + DTV_BASE, 0); /* stop dtv */ msleep(20); mdp4_overlayproc_cfg(pipe); mdp4_overlay_dmae_xy(pipe); MDP_OUTP(MDP_BASE + DTV_BASE, 1); /* start dtv */ } atomic_set(&vctrl->suspend, 0); }
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_overlay_reg_flush(pipe, 1); mdp4_mixer_stage_up(pipe); dtv_pipe = pipe; /* keep it */ }
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); */ atomic_set(&dtv_on, true); 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 mdp4_atv_on(struct platform_device *pdev) { 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; #ifdef CONFIG_HUAWEI_KERNEL static boolean first_time = TRUE; #endif 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_offset = calc_fb_offset(mfd, fbi, bpp); if (atv_pipe == NULL) { ptype = mdp4_overlay_format2type(mfd->fb_imgType); pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER1); 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; 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); } 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_overlayproc_cfg(pipe); /* config it once for tv_out */ #ifdef CONFIG_HUAWEI_KERNEL if(first_time) { mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); outpdw(MDP_BASE + 0x18000, 0x20); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); first_time = FALSE; } #endif mdp4_overlay_reg_flush(pipe, 1); mdp4_mixer_stage_up(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; }
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; }