diff options
author | Jason Chen <b02280@freescale.com> | 2011-11-21 10:16:07 +0800 |
---|---|---|
committer | Eric Miao <eric.miao@linaro.org> | 2011-11-29 16:43:17 +0800 |
commit | 8b0dcb03b780ea8f5b45a3d885ebe9bc4947f578 (patch) | |
tree | f8a3cbfd9f315a29b2a5824101a3a93452b795af | |
parent | 8f9282ee34a072f2d2b867412bdb7abf1f43072a (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>
-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 f2861bcd563..260b41a3ddf 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); |