diff options
author | Jason Chen <b02280@freescale.com> | 2011-11-21 10:16:07 +0800 |
---|---|---|
committer | Jason Liu <r64343@freescale.com> | 2012-01-09 21:07:36 +0800 |
commit | 378e84e7983f289f96d19787b26fcf64e5fdeb85 (patch) | |
tree | 7f187ca16c0813e71c35fd9581d0ca8f7641efad /drivers/video | |
parent | de4ebae4b0b26ff7d88b813ab4294529741523c7 (diff) |
ENGR00162665 ipuv3 fb: fix non-interleave format wrong color issue
fix fb offset base address under non-interleave format.
Signed-off-by: Jason Chen <b02280@freescale.com>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/mxc/mxc_ipuv3_fb.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c index e669590f979c..63807917350a 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); |