From 6938379d1b38c9fc44c264f9d77458ee1fa7391a Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Tue, 10 Nov 2009 13:37:30 -0500 Subject: [PATCH] ENGR00118147 IPUv3 FB:Synchronize DP local alpha update with sdc FB Synchronize DP local alpha update with sdc framebuffer in pan display. Signed-off-by: Liu Ying --- drivers/mxc/ipu3/ipu_common.c | 16 ++++++++--- drivers/video/mxc/mxc_ipuv3_fb.c | 47 ++++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c index e654eeea92a..b7ad5c2a242 100644 --- a/drivers/mxc/ipu3/ipu_common.c +++ b/drivers/mxc/ipu3/ipu_common.c @@ -1130,16 +1130,21 @@ int32_t ipu_select_buffer(ipu_channel_t channel, ipu_buffer_t type, uint32_t bufNum) { uint32_t dma_chan = channel_2_dma(channel, type); + uint32_t reg; if (dma_chan == IDMA_CHAN_INVALID) return -EINVAL; if (bufNum == 0) { /*Mark buffer 0 as ready. */ - __raw_writel(idma_mask(dma_chan), IPU_CHA_BUF0_RDY(dma_chan)); + reg = __raw_readl(IPU_CHA_BUF0_RDY(dma_chan)); + __raw_writel(idma_mask(dma_chan) | reg, + IPU_CHA_BUF0_RDY(dma_chan)); } else { /*Mark buffer 1 as ready. */ - __raw_writel(idma_mask(dma_chan), IPU_CHA_BUF1_RDY(dma_chan)); + reg = __raw_readl(IPU_CHA_BUF1_RDY(dma_chan)); + __raw_writel(idma_mask(dma_chan) | reg, + IPU_CHA_BUF1_RDY(dma_chan)); } if (channel == MEM_VDI_PRP_VF_MEM) _ipu_vdi_toggle_top_field_man(); @@ -1163,13 +1168,16 @@ int32_t ipu_select_multi_vdi_buffer(uint32_t bufNum) idma_mask(channel_2_dma(MEM_VDI_PRP_VF_MEM_P, IPU_INPUT_BUFFER))| idma_mask(dma_chan)| idma_mask(channel_2_dma(MEM_VDI_PRP_VF_MEM_N, IPU_INPUT_BUFFER)); + uint32_t reg; if (bufNum == 0) { /*Mark buffer 0 as ready. */ - __raw_writel(mask_bit, IPU_CHA_BUF0_RDY(dma_chan)); + reg = __raw_readl(IPU_CHA_BUF0_RDY(dma_chan)); + __raw_writel(mask_bit | reg, IPU_CHA_BUF0_RDY(dma_chan)); } else { /*Mark buffer 1 as ready. */ - __raw_writel(mask_bit, IPU_CHA_BUF1_RDY(dma_chan)); + reg = __raw_readl(IPU_CHA_BUF0_RDY(dma_chan)); + __raw_writel(mask_bit | reg, IPU_CHA_BUF1_RDY(dma_chan)); } _ipu_vdi_toggle_top_field_man(); return 0; diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c index 604185faf05..27a6c32fbf2 100644 --- a/drivers/video/mxc/mxc_ipuv3_fb.c +++ b/drivers/video/mxc/mxc_ipuv3_fb.c @@ -224,8 +224,8 @@ static int _setup_disp_channel2(struct fb_info *fbi) fbi->var.xres, fbi->var.yres, fbi->var.xres, IPU_ROTATE_NONE, - mxc_fbi->alpha_phy_addr0, mxc_fbi->alpha_phy_addr1, + mxc_fbi->alpha_phy_addr0, 0, 0); if (retval) { dev_err(fbi->device, @@ -1030,9 +1030,12 @@ static int mxcfb_blank(int blank, struct fb_info *info) static int mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par; + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par, + *mxc_graphic_fbi = NULL; u_int y_bottom; - unsigned long base; + unsigned long base, active_alpha_phy_addr = 0; + bool loc_alpha_en = false; + int i = 0; if (var->xoffset > 0) { dev_dbg(info->device, "x panning not supported\n"); @@ -1055,8 +1058,31 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) base *= (var->bits_per_pixel) / 8; base += info->fix.smem_start; - dev_dbg(info->device, "Updating SDC BG buf %d address=0x%08lX\n", - mxc_fbi->cur_ipu_buf, base); + dev_dbg(info->device, "Updating SDC %s buf %d address=0x%08lX\n", + info->fix.id, mxc_fbi->cur_ipu_buf, base); + + /* Check if DP local alpha is enabled and find the graphic fb */ + if (mxc_fbi->ipu_ch == MEM_BG_SYNC || mxc_fbi->ipu_ch == MEM_FG_SYNC) { + for (i = 0; i < num_registered_fb; i++) { + char *idstr = registered_fb[i]->fix.id; + if ((strcmp(idstr, "DISP3 BG") == 0 || + strcmp(idstr, "DISP3 FG") == 0) && + ((struct mxcfb_info *) + (registered_fb[i]->par))->alpha_chan_en) { + loc_alpha_en = true; + mxc_graphic_fbi = (struct mxcfb_info *) + (registered_fb[i]->par); + active_alpha_phy_addr = mxc_fbi->cur_ipu_buf ? + mxc_graphic_fbi->alpha_phy_addr1 : + mxc_graphic_fbi->alpha_phy_addr0; + dev_dbg(info->device, "Updating SDC graphic " + "buf %d address=0x%08lX\n", + mxc_fbi->cur_ipu_buf, + active_alpha_phy_addr); + break; + } + } + } down(&mxc_fbi->flip_sem); init_completion(&mxc_fbi->vsync_complete); @@ -1064,6 +1090,17 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) mxc_fbi->cur_ipu_buf = !mxc_fbi->cur_ipu_buf; if (ipu_update_channel_buffer(mxc_fbi->ipu_ch, IPU_INPUT_BUFFER, mxc_fbi->cur_ipu_buf, base) == 0) { + /* Update the DP local alpha buffer only for graphic plane */ + if (loc_alpha_en && mxc_graphic_fbi == mxc_fbi && + ipu_update_channel_buffer(mxc_graphic_fbi->ipu_ch, + IPU_ALPHA_IN_BUFFER, + mxc_fbi->cur_ipu_buf, + active_alpha_phy_addr) == 0) { + ipu_select_buffer(mxc_graphic_fbi->ipu_ch, + IPU_ALPHA_IN_BUFFER, + mxc_fbi->cur_ipu_buf); + } + ipu_select_buffer(mxc_fbi->ipu_ch, IPU_INPUT_BUFFER, mxc_fbi->cur_ipu_buf); ipu_clear_irq(mxc_fbi->ipu_ch_irq);