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_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; }
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 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; 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); vsync_cntrl.vsync_irq_enabled = 0; /* 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 += calc_fb_offset(mfd, fbi, bpp); dma2_cfg_reg = DMA_PACK_ALIGN_LSB | 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 */ curr = inpdw(MDP_BASE + DMA_P_BASE); mask = 0x0FFFFFFF; dma2_cfg_reg = (dma2_cfg_reg & mask) | (curr & ~mask); 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 = 0; 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_histogram_ctrl_all(TRUE); /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_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; 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; }
/* timing generator off */ static void mdp4_dsi_video_tg_off(struct vsycn_ctrl *vctrl) { MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); /* turn off timing generator */ /* some delay after turning off the tg */ msleep(20); }
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; }
void mdp4_overlay_update_dsi_cmd(struct msm_fb_data_type *mfd) { int ptype; struct mdp4_overlay_pipe *pipe; int ret; int cndx = 0; struct vsycn_ctrl *vctrl; if (mfd->key != MFD_KEY) return; vctrl = &vsync_ctrl_db[cndx]; /* MDP cmd block enable */ mdp_clk_ctrl(1); 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; } 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__); vctrl->base_pipe = pipe; /* keep it */ mdp4_init_writeback_buf(mfd, MDP4_MIXER0); pipe->ov_blt_addr = 0; pipe->dma_blt_addr = 0; MDP_OUTP(MDP_BASE + 0x021c, 10); /* read pointer */ /* * configure dsi stream id * dma_p = 0, dma_s = 1 */ MDP_OUTP(MDP_BASE + 0x000a0, 0x10); /* disable dsi trigger */ MDP_OUTP(MDP_BASE + 0x000a4, 0x00); mdp4_overlay_setup_pipe_addr(mfd, pipe); mdp4_overlay_rgb_setup(pipe); mdp4_overlay_reg_flush(pipe, 1); 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_clk_ctrl(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_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); }
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); }
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 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; 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; }
void mdp_lcdc_update(struct msm_fb_data_type *mfd) { struct fb_info *fbi = mfd->fbi; uint8 *buf; int bpp; unsigned long flag; uint32 dma_base; int irq_block = MDP_DMA2_TERM; #ifdef CONFIG_FB_MSM_MDP40 int intr = INTR_DMA_P_DONE; #endif if (!mfd->panel_power_on) return; /* no need to power on cmd block since it's lcdc mode */ if (!mfd->ibuf.visible_swapped) { 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; } else { /* we've done something to update the pointer. */ bpp = mfd->ibuf.bpp; buf = mfd->ibuf.buf; } dma_base = DMA_P_BASE; #ifdef CONFIG_FB_MSM_MDP40 if (mfd->panel.type == HDMI_PANEL) { intr = INTR_DMA_E_DONE; irq_block = MDP_DMA_E_TERM; dma_base = DMA_E_BASE; } #endif /* starting address */ MDP_OUTP(MDP_BASE + dma_base + 0x8, (uint32) buf); /* enable LCDC irq */ spin_lock_irqsave(&mdp_spin_lock, flag); mdp_enable_irq(irq_block); INIT_COMPLETION(mfd->dma->comp); mfd->dma->waiting = TRUE; #ifdef CONFIG_FB_MSM_MDP40 outp32(MDP_INTR_CLEAR, intr); mdp_intr_mask |= intr; outp32(MDP_INTR_ENABLE, mdp_intr_mask); #else outp32(MDP_INTR_CLEAR, LCDC_FRAME_START); mdp_intr_mask |= LCDC_FRAME_START; outp32(MDP_INTR_ENABLE, mdp_intr_mask); #endif spin_unlock_irqrestore(&mdp_spin_lock, flag); if (mfd->ibuf.vsync_enable) wait_for_completion_killable(&mfd->dma->comp); mdp_disable_irq(irq_block); }
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; if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; if (dtv_pipe == NULL) return -EINVAL; fbi = mfd->fbi; var = &fbi->var; 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); 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 0; }
/* * make sure the MIPI_DSI_WRITEBACK_SIZE defined at boardfile * has enough space h * w * 3 * 2 */ static void mdp4_dsi_video_do_blt(struct msm_fb_data_type *mfd, int enable) { unsigned long flag; 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_MIXER0); if (mfd->ov0_wb_buf->write_addr == 0) { pr_info("%s: no blt_base assigned\n", __func__); return; } spin_lock_irqsave(&vctrl->spin_lock, flag); if (enable && pipe->ov_blt_addr == 0) { pipe->ov_blt_addr = mfd->ov0_wb_buf->write_addr; pipe->dma_blt_addr = mfd->ov0_wb_buf->read_addr; pipe->ov_cnt = 0; pipe->dmap_cnt = 0; vctrl->ov_koff = 0; vctrl->ov_done = 0; vctrl->blt_free = 0; mdp4_stat.blt_dsi_video++; vctrl->blt_change++; } else if (enable == 0 && pipe->ov_blt_addr) { pipe->ov_blt_addr = 0; pipe->dma_blt_addr = 0; vctrl->blt_free = 4; /* 4 commits to free wb buf */ vctrl->blt_change++; } pr_info("%s: changed=%d enable=%d ov_blt_addr=%x\n", __func__, vctrl->blt_change, enable, (int)pipe->ov_blt_addr); if (!vctrl->blt_change) { spin_unlock_irqrestore(&vctrl->spin_lock, flag); return; } spin_unlock_irqrestore(&vctrl->spin_lock, flag); if (vctrl->blt_ctrl == OVERLAY_BLT_SWITCH_TG_OFF) { int tg_enabled; pr_info("%s: blt enabled by switching TG off\n", __func__); vctrl->blt_change = 0; tg_enabled = inpdw(MDP_BASE + DSI_VIDEO_BASE) & 0x01; if (tg_enabled) { mdp4_dsi_video_wait4vsync(cndx); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); mdp4_dsi_video_wait4dmap_done(0); } mdp4_overlayproc_cfg(pipe); mdp4_overlay_dmap_xy(pipe); if (pipe->ov_blt_addr) { mdp4_dsi_video_blt_ov_update(pipe); pipe->ov_cnt++; /* Prefill one frame */ vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM); /* kickoff overlay0 engine */ mdp4_stat.kickoff_ov0++; vctrl->ov_koff++; /* make up for prefill */ outpdw(MDP_BASE + 0x0004, 0); } if (tg_enabled) { /* * need wait for more than 1 ms to * make sure lanes' fifo is empty and * lanes in stop state befroe reset * controller */ usleep(2000); mipi_dsi_sw_reset(); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1); } } }
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); }
int mdp4_dsi_video_on(struct platform_device *pdev) { int dsi_width; int dsi_height; int dsi_bpp; int dsi_border_clr; int dsi_underflow_clr; int dsi_hsync_skew; int hsync_period; int hsync_ctrl; int vsync_period; int display_hctl; int display_v_start; int display_v_end; int active_hctl; int active_h_start; int active_h_end; int active_v_start; int active_v_end; int ctrl_polarity; int h_back_porch; int h_front_porch; int v_back_porch; int v_front_porch; int hsync_pulse_width; int vsync_pulse_width; int hsync_polarity; int vsync_polarity; int data_en_polarity; int hsync_start_x; int hsync_end_x; uint8 *buf; unsigned int buf_offset; int bpp, ptype; struct fb_info *fbi; struct fb_var_screeninfo *var; struct msm_fb_data_type *mfd; struct mdp4_overlay_pipe *pipe; int ret = 0; int cndx = 0; struct vsycn_ctrl *vctrl; struct msm_panel_info *pinfo; vctrl = &vsync_ctrl_db[cndx]; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); pinfo = &mfd->panel_info; if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; mutex_lock(&mfd->dma->ov_mutex); vctrl->mfd = mfd; vctrl->dev = mfd->fbi->dev; vctrl->blt_ctrl = pinfo->lcd.blt_ctrl; vctrl->vsync_irq_enabled = 0; vsync_irq_cnt = 0; /* mdp clock on */ mdp_clk_ctrl(1); fbi = mfd->fbi; var = &fbi->var; bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf_offset = calc_fb_offset(mfd, fbi, bpp); if (vctrl->base_pipe == NULL) { ptype = mdp4_overlay_format2type(mfd->fb_imgType); if (ptype < 0) printk(KERN_INFO "%s: format2type failed\n", __func__); pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0); if (pipe == NULL) { printk(KERN_INFO "%s: pipe_alloc failed\n", __func__); mutex_unlock(&mfd->dma->ov_mutex); return -EBUSY; } pipe->pipe_used++; pipe->mixer_stage = MDP4_MIXER_STAGE_BASE; pipe->mixer_num = MDP4_MIXER0; pipe->src_format = mfd->fb_imgType; mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_DSI_VIDEO); ret = mdp4_overlay_format2pipe(pipe); if (ret < 0) printk(KERN_INFO "%s: format2type failed\n", __func__); pipe->ov_blt_addr = 0; pipe->dma_blt_addr = 0; vctrl->base_pipe = pipe; /* keep it */ mdp4_init_writeback_buf(mfd, MDP4_MIXER0); } else { pipe = vctrl->base_pipe; } atomic_set(&vctrl->suspend, 0); pipe->src_height = fbi->var.yres; pipe->src_width = fbi->var.xres; pipe->src_h = fbi->var.yres; pipe->src_w = fbi->var.xres; pipe->src_y = 0; pipe->src_x = 0; pipe->dst_h = fbi->var.yres; pipe->dst_w = fbi->var.xres; pipe->srcp0_ystride = fbi->fix.line_length; pipe->bpp = bpp; if (mfd->display_iova) pipe->srcp0_addr = mfd->display_iova + buf_offset; else pipe->srcp0_addr = (uint32)(buf + buf_offset); pipe->dst_h = fbi->var.yres; pipe->dst_w = fbi->var.xres; mdp4_overlay_solidfill_init(pipe); mdp4_overlay_mdp_pipe_req(pipe, mfd); mdp4_calc_blt_mdp_bw(mfd, pipe); mdp4_overlay_dmap_xy(pipe); /* dma_p */ mdp4_overlay_dmap_cfg(mfd, 1); mdp4_overlay_rgb_setup(pipe); mdp4_overlayproc_cfg(pipe); mdp4_overlay_reg_flush(pipe, 1); mdp4_mixer_stage_up(pipe, 0); mdp4_mixer_stage_commit(pipe->mixer_num); /* * DSI timing setting */ h_back_porch = var->left_margin; h_front_porch = var->right_margin; v_back_porch = var->upper_margin; v_front_porch = var->lower_margin; hsync_pulse_width = var->hsync_len; vsync_pulse_width = var->vsync_len; dsi_border_clr = mfd->panel_info.lcdc.border_clr; dsi_underflow_clr = mfd->panel_info.lcdc.underflow_clr; dsi_hsync_skew = mfd->panel_info.lcdc.hsync_skew; dsi_width = mfd->panel_info.xres + mfd->panel_info.lcdc.xres_pad; dsi_height = mfd->panel_info.yres + mfd->panel_info.lcdc.yres_pad; dsi_bpp = mfd->panel_info.bpp; hsync_period = hsync_pulse_width + h_back_porch + dsi_width + h_front_porch; hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; hsync_start_x = h_back_porch + hsync_pulse_width; hsync_end_x = hsync_period - h_front_porch - 1; display_hctl = (hsync_end_x << 16) | hsync_start_x; vsync_period = (vsync_pulse_width + v_back_porch + dsi_height + v_front_porch); display_v_start = ((vsync_pulse_width + v_back_porch) * hsync_period) + dsi_hsync_skew; display_v_end = ((vsync_period - v_front_porch) * hsync_period) + dsi_hsync_skew - 1; if (dsi_width != var->xres) { active_h_start = hsync_start_x + first_pixel_start_x; active_h_end = active_h_start + var->xres - 1; active_hctl = ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start; } else { active_hctl = 0; } if (dsi_height != var->yres) { active_v_start = display_v_start + first_pixel_start_y * hsync_period; active_v_end = active_v_start + (var->yres) * hsync_period - 1; active_v_start |= ACTIVE_START_Y_EN; } else { active_v_start = 0; active_v_end = 0; } dsi_underflow_clr |= 0x80000000; /* enable recovery */ hsync_polarity = 0; vsync_polarity = 0; data_en_polarity = 0; ctrl_polarity = (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x4, hsync_ctrl); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x8, vsync_period * hsync_period); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0xc, vsync_pulse_width * hsync_period); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x10, display_hctl); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x14, display_v_start); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x18, display_v_end); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x1c, active_hctl); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x20, active_v_start); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x24, active_v_end); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x28, dsi_border_clr); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x2c, dsi_underflow_clr); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x30, dsi_hsync_skew); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x38, ctrl_polarity); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); mdp_histogram_ctrl_all(TRUE); mdp4_overlay_dsi_video_start(); mutex_unlock(&mfd->dma->ov_mutex); return ret; }
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__); }
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 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); /*MHL CTS 3.2.3.4 Video Quantization Ranges*/ //MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x70, 0x00D9001E); MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x70, 0x00EB0010); MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x74, 0x00EB0010); MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x78, 0x00EB0010); /* 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; // hsil if (mdp_lcdc_on_flg) { printk("[kkw] %s(%d) mdp_lcdc_on start called twice\n", __func__, __LINE__); return 0; } mdp_lcdc_on_flg = 1; printk("[HSIL] %s(%d) mdp_lcdc_on start\n", __func__, __LINE__); 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 defined(CONFIG_MACH_TASS) || defined(CONFIG_MACH_BENI) || defined(CONFIG_MACH_LUCAS) || defined(CONFIG_MACH_COOPER) || defined(CONFIG_MACH_CALLISTO) dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_DITHER_EN | DMA_OUT_SEL_LCDC; #else dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_OUT_SEL_LCDC; #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 (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 #if defined(CONFIG_MACH_CALLISTO) || defined(CONFIG_MACH_LUCAS) //#if defined(CONFIG_MACH_CALLISTO) // minhyo100515 printk("polarity setting\n"); // minhyodebug hsync_polarity = 1; // active low vsync_polarity = 1; // active low #else hsync_polarity = 0; vsync_polarity = 0; #endif #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) { DBG("==============++minhyodebug : LCD CONTROLLER Registers Setting\n"); 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); #if 1 // minhyodebug printk("display_hctl = 0x%x\n", display_hctl); printk("display_v_start = 0x%x\n", display_v_start); printk("display_v_end = 0x%x\n", display_v_end); printk("lcdc_border_clr = 0x%x\n", lcdc_border_clr); printk("lcdc_underflow_clr = 0x%x\n", lcdc_underflow_clr); printk("lcdc_hsync_skew = 0x%x\n", lcdc_hsync_skew); printk("ctrl_polarity = 0x%x\n", ctrl_polarity); printk("active_hctl = 0x%x\n", active_hctl); printk("active_v_start = 0x%x\n", active_v_start); printk("active_v_end = 0x%x\n", active_v_end); #endif } 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); } #if defined(CONFIG_MACH_TOTORO_CTC) // (1) vsync and (2) panel on /* 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); ret = panel_next_on(pdev); #else // (1) panel on and (2) vsync 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); #endif printk("[HSIL] %s(%d) mdp_lcdc_on end\n", __func__, __LINE__); 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 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 (first_video_on) first_video_on = false; else { if (mfd->ref_cnt == 0) { //clean all pipes before base pipe and layer pipes are allocated 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; /* keep it */ mdp4_init_writeback_buf(mfd, MDP4_MIXER0); } else { pipe = vctrl->base_pipe; } #ifdef CONTINUOUS_SPLASH /* 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; mdp4_dsi_video_wait4dmap_done(0); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); mdelay(20); mipi_dsi_controller_cfg(0); mdp_clk_ctrl(0); } #endif pipe->src_height = mfd->ovr_dst_height; /* fbi->var.yres; */ pipe->src_width = mfd->ovr_dst_width; /* fbi->var.xres; */ pipe->src_h = mfd->ovr_src_height; /* fbi->var.yres; */ pipe->src_w = mfd->ovr_src_width; /* fbi->var.xres; */ pipe->src_y = 0; pipe->src_x = 0; pipe->dst_h = mfd->ovr_dst_height; /* fbi->var.yres; */ pipe->dst_w = mfd->ovr_dst_width; /* 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 = mfd->ovr_dst_height; /* fbi->var.yres; */ pipe->dst_w = mfd->ovr_dst_width; /* fbi->var.xres; */ mdp4_overlay_mdp_pipe_req(pipe, mfd); atomic_set(&vctrl->suspend, 0); 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; } #ifdef CONFIG_FB_MSM_RESOLUTION_OVERRIDE active_hctl = 0; active_v_start = 0; active_v_end = 0; #endif 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); return ret; }
/* * make sure the MIPI_DSI_WRITEBACK_SIZE defined at boardfile * has enough space h * w * 3 * 2 */ static void mdp4_dsi_video_do_blt(struct msm_fb_data_type *mfd, int enable) { unsigned long flag; int data; int change = 0; mdp4_allocate_writeback_buf(mfd, MDP4_MIXER0); if (mfd->ov0_wb_buf->phys_addr == 0) { pr_info("%s: no blt_base assigned\n", __func__); return; } spin_lock_irqsave(&mdp_spin_lock, flag); if (enable && dsi_pipe->blt_addr == 0) { dsi_pipe->blt_addr = mfd->ov0_wb_buf->phys_addr; dsi_pipe->blt_cnt = 0; dsi_pipe->ov_cnt = 0; dsi_pipe->dmap_cnt = 0; mdp4_stat.blt_dsi_video++; change++; } else if (enable == 0 && dsi_pipe->blt_addr) { dsi_pipe->blt_addr = 0; change++; } if (!change) { spin_unlock_irqrestore(&mdp_spin_lock, flag); return; } pr_debug("%s: enable=%d blt_addr=%x\n", __func__, enable, (int)dsi_pipe->blt_addr); blt_cfg_changed = 1; #if defined (LGE_BLT_LOCKUP_WR) blt_ent++; #endif spin_unlock_irqrestore(&mdp_spin_lock, flag); /* * may need mutex here to sync with whom dsiable * timing generator */ data = inpdw(MDP_BASE + DSI_VIDEO_BASE); data &= 0x01; if (data) { /* timing generator enabled */ mdp4_overlay_dsi_video_wait4event(mfd, INTR_DMA_P_DONE); mdp4_overlay_dsi_video_wait4event(mfd, INTR_PRIMARY_VSYNC); } #if 0 /* removed by MSM8960AAAAANLYA1049A */ if (data) { /* timing generator enabled */ if (dsi_pipe->blt_addr) { MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1); mdp4_overlay_dsi_video_prefill(mfd); mdp4_overlay_dsi_video_prefill(mfd); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); } mipi_dsi_sw_reset(); mipi_dsi_controller_cfg(1); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1); } #endif }
/* * make sure the MIPI_DSI_WRITEBACK_SIZE defined at boardfile * has enough space h * w * 3 * 2 */ static void mdp4_dsi_video_do_blt(struct msm_fb_data_type *mfd, int enable) { unsigned long flag; 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_MIXER0); if (mfd->ov0_wb_buf->write_addr == 0) { pr_info("%s: no blt_base assigned\n", __func__); return; } spin_lock_irqsave(&vctrl->spin_lock, flag); if (enable && pipe->ov_blt_addr == 0) { pipe->ov_blt_addr = mfd->ov0_wb_buf->write_addr; pipe->dma_blt_addr = mfd->ov0_wb_buf->read_addr; pipe->ov_cnt = 0; pipe->dmap_cnt = 0; vctrl->ov_koff = 0; vctrl->ov_done = 0; vctrl->blt_free = 0; mdp4_stat.blt_dsi_video++; vctrl->blt_change++; } else if (enable == 0 && pipe->ov_blt_addr) { pipe->ov_blt_addr = 0; pipe->dma_blt_addr = 0; vctrl->blt_free = 4; /* 4 commits to free wb buf */ vctrl->blt_change++; } pr_info("%s: changed=%d enable=%d ov_blt_addr=%x\n", __func__, vctrl->blt_change, enable, (int)pipe->ov_blt_addr); if (!vctrl->blt_change) { spin_unlock_irqrestore(&vctrl->spin_lock, flag); return; } spin_unlock_irqrestore(&vctrl->spin_lock, flag); if (mdp_ov0_blt_ctl == MDP4_BLT_SWITCH_TG_OFF) { int tg_enabled; pr_debug("%s: blt enabled by switching TG off\n", __func__); tg_enabled = inpdw(MDP_BASE + DSI_VIDEO_BASE) & 0x01; if (tg_enabled) { mdp4_dsi_video_wait4dmap_done(0); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); msleep(20); } mdp4_overlayproc_cfg(pipe); mdp4_overlay_dmap_xy(pipe); if (tg_enabled) { if (pipe->ov_blt_addr) { spin_lock_irqsave(&vctrl->spin_lock, flag); pipe->ov_cnt++; vctrl->ov_koff++; /* kickoff overlay engine */ mdp4_stat.kickoff_ov0++; INIT_COMPLETION(vctrl->ov_comp); vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM); outpdw(MDP_BASE + 0x0004, 0); spin_unlock_irqrestore(&vctrl->spin_lock, flag); mdp4_dsi_video_wait4ov(0); } mipi_dsi_sw_reset(); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1); } vctrl->blt_change = 0; } }
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; 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; /* 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_offset = calc_fb_offset(mfd, fbi, bpp); 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); 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); mdp4_init_writeback_buf(mfd, MDP4_MIXER0); pipe->blt_addr = 0; } 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; 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; pipe->bpp = bpp; 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 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); mdp4_overlay_reg_flush(pipe, 1); #ifdef CONFIG_MSM_BUS_SCALING mdp_bus_scale_update_request(2); #endif mdp_histogram_ctrl_all(TRUE); ret = panel_next_on(pdev); if (ret == 0) 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; }
/* * make sure the MIPI_DSI_WRITEBACK_SIZE defined at boardfile * has enough space h * w * 3 * 2 */ static void mdp4_dsi_video_do_blt(struct msm_fb_data_type *mfd, int enable) { unsigned long flag; int data; int change = 0; mdp4_allocate_writeback_buf(mfd, MDP4_MIXER0); if (mfd->ov0_wb_buf->phys_addr == 0) { pr_info("%s: no blt_base assigned\n", __func__); return; } spin_lock_irqsave(&mdp_spin_lock, flag); if (enable && dsi_pipe->blt_addr == 0) { dsi_pipe->blt_addr = mfd->ov0_wb_buf->phys_addr; dsi_pipe->blt_cnt = 0; dsi_pipe->ov_cnt = 0; dsi_pipe->dmap_cnt = 0; mdp4_stat.blt_dsi_video++; change++; } else if (enable == 0 && dsi_pipe->blt_addr) { dsi_pipe->blt_addr = 0; change++; } #ifdef FEATURE_QUALCOMM_BUG_FIX_LCD_MDP_TIMING_GENERATOR_ON if (!change) { spin_unlock_irqrestore(&mdp_spin_lock, flag); return; } #endif pr_debug("%s: enable=%d blt_addr=%x\n", __func__, enable, (int)dsi_pipe->blt_addr); #ifdef FEATURE_QUALCOMM_BUG_FIX_LCD_MDP_TIMING_GENERATOR_ON blt_cfg_changed = 1; #endif spin_unlock_irqrestore(&mdp_spin_lock, flag); #ifndef FEATURE_QUALCOMM_BUG_FIX_LCD_MDP_TIMING_GENERATOR_ON if (!change) return; #endif /* * may need mutex here to sync with whom dsiable * timing generator */ data = inpdw(MDP_BASE + DSI_VIDEO_BASE); data &= 0x01; if (data) { /* timing generator enabled */ mdp4_overlay_dsi_video_wait4event(mfd, INTR_DMA_P_DONE); #ifdef FEATURE_QUALCOMM_BUG_FIX_LCD_MDP_TIMING_GENERATOR_ON // mdp4_overlay_dsi_video_wait4event(mfd, INTR_PRIMARY_VSYNC); if(enable) { mdp4_overlay_dsi_video_wait4event(mfd, INTR_DMA_P_DONE); } else { mdp4_overlay_dsi_video_wait4event(mfd, INTR_DMA_P_DONE); mdp4_overlay_dsi_video_wait4event(mfd, INTR_PRIMARY_VSYNC); } #else MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); msleep(20); /* make sure last frame is finished */ mipi_dsi_controller_cfg(0); #endif } #ifndef FEATURE_QUALCOMM_BUG_FIX_LCD_MDP_TIMING_GENERATOR_ON mdp4_overlayproc_cfg(dsi_pipe); mdp4_overlay_dmap_xy(dsi_pipe); if (data) { /* timing generator enabled */ if (dsi_pipe->blt_addr) { MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1); mdp4_overlay_dsi_video_prefill(mfd); mdp4_overlay_dsi_video_prefill(mfd); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); } mipi_dsi_sw_reset(); mipi_dsi_controller_cfg(1); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1); } #endif }
/*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; }
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); }