aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Chen <b02280@freescale.com>2011-11-21 10:16:07 +0800
committerEric Miao <eric.miao@linaro.org>2011-11-29 16:43:17 +0800
commit8b0dcb03b780ea8f5b45a3d885ebe9bc4947f578 (patch)
treef8a3cbfd9f315a29b2a5824101a3a93452b795af
parent8f9282ee34a072f2d2b867412bdb7abf1f43072a (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.c28
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);