From b98d0bac24b401d48597f05bc54b3032d8ddfffe Mon Sep 17 00:00:00 2001 From: Jason Chen Date: Mon, 21 Nov 2011 10:16:07 +0800 Subject: ENGR00162665 ipuv3 fb: fix non-interleave format wrong color issue fix fb offset base address under non-interleave format. Signed-off-by: Jason Chen (cherry picked from commit cd4b89bfc1b47cf9f25ca600db92531f6e676e89) --- drivers/video/mxc/mxc_ipuv3_fb.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c index e669590f979..63807917350 100644 --- a/drivers/video/mxc/mxc_ipuv3_fb.c +++ b/drivers/video/mxc/mxc_ipuv3_fb.c @@ -84,7 +84,7 @@ struct mxcfb_info { u32 pseudo_palette[16]; bool mode_found; - bool wait4vsync; + volatile bool wait4vsync; struct semaphore flip_sem; struct semaphore alpha_flip_sem; struct completion vsync_complete; @@ -232,8 +232,7 @@ static int _setup_disp_channel2(struct fb_info *fbi) } fbi->var.xoffset = 0; - base = (fbi->var.yoffset * fbi->var.xres_virtual + fbi->var.xoffset); - base = (fbi->var.bits_per_pixel) * base / 8; + base = (fbi->var.yoffset * fb_stride + fbi->var.xoffset); base += fbi->fix.smem_start; retval = ipu_init_channel_buffer(mxc_fbi->ipu, @@ -931,7 +930,7 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) init_completion(&mxc_fbi->vsync_complete); ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq); - mxc_fbi->wait4vsync = 1; + mxc_fbi->wait4vsync = true; ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq); retval = wait_for_completion_interruptible_timeout( &mxc_fbi->vsync_complete, 1 * HZ); @@ -939,7 +938,7 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) dev_err(fbi->device, "MXCFB_WAIT_FOR_VSYNC: timeout %d\n", retval); - mxc_fbi->wait4vsync = 0; + mxc_fbi->wait4vsync = false; retval = -ETIME; } else if (retval > 0) { retval = 0; @@ -1158,6 +1157,7 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) u_int y_bottom; unsigned long base, active_alpha_phy_addr = 0; bool loc_alpha_en = false; + int fb_stride; int i; if (info->var.yoffset == var->yoffset) @@ -1187,8 +1187,20 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) if (y_bottom > info->var.yres_virtual) return -EINVAL; - base = (var->yoffset * var->xres_virtual + var->xoffset); - base = (var->bits_per_pixel) * base / 8; + switch (bpp_to_pixfmt(info)) { + case IPU_PIX_FMT_YUV420P2: + case IPU_PIX_FMT_YVU420P: + case IPU_PIX_FMT_NV12: + case IPU_PIX_FMT_YUV422P: + case IPU_PIX_FMT_YVU422P: + case IPU_PIX_FMT_YUV420P: + fb_stride = info->var.xres_virtual; + break; + default: + fb_stride = info->fix.line_length; + } + + base = (var->yoffset * fb_stride + var->xoffset); base += info->fix.smem_start; /* Check if DP local alpha is enabled and find the graphic fb */ @@ -1364,7 +1376,7 @@ static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id) if (mxc_fbi->wait4vsync) { complete(&mxc_fbi->vsync_complete); ipu_disable_irq(mxc_fbi->ipu, irq); - mxc_fbi->wait4vsync = 0; + mxc_fbi->wait4vsync = false; } else { up(&mxc_fbi->flip_sem); ipu_disable_irq(mxc_fbi->ipu, irq); -- cgit v1.2.3