aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/mxc/mxc_ipuv3_fb.c63
-rw-r--r--drivers/video/mxc/mxcfb.c1
-rw-r--r--include/linux/mxcfb.h2
3 files changed, 31 insertions, 35 deletions
diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c
index b3bf655f6f04..efdb664a1d7b 100644
--- a/drivers/video/mxc/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc/mxc_ipuv3_fb.c
@@ -83,7 +83,6 @@ struct mxcfb_info {
u32 pseudo_palette[16];
bool wait4vsync;
- uint32_t waitcnt;
struct semaphore flip_sem;
struct semaphore alpha_flip_sem;
struct completion vsync_complete;
@@ -305,7 +304,7 @@ static int _setup_disp_channel2(struct fb_info *fbi)
fb_stride = fbi->fix.line_length;
}
- mxc_fbi->cur_ipu_buf = 1;
+ mxc_fbi->cur_ipu_buf = 2;
sema_init(&mxc_fbi->flip_sem, 1);
if (mxc_fbi->alpha_chan_en) {
mxc_fbi->cur_ipu_alpha_buf = 1;
@@ -324,6 +323,8 @@ static int _setup_disp_channel2(struct fb_info *fbi)
IPU_ROTATE_NONE,
base,
base,
+ (fbi->var.accel_flags ==
+ FB_ACCEL_TRIPLE_FLAG) ? base : 0,
0, 0);
if (retval) {
dev_err(fbi->device,
@@ -339,6 +340,7 @@ static int _setup_disp_channel2(struct fb_info *fbi)
IPU_ROTATE_NONE,
mxc_fbi->alpha_phy_addr1,
mxc_fbi->alpha_phy_addr0,
+ 0,
0, 0);
if (retval) {
dev_err(fbi->device,
@@ -1300,12 +1302,13 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
loc_alpha_en = true;
mxc_graphic_fbi = (struct mxcfb_info *)
(registered_fb[i]->par);
- active_alpha_phy_addr = mxc_fbi->cur_ipu_buf ?
+ active_alpha_phy_addr =
+ mxc_fbi->cur_ipu_alpha_buf ?
mxc_graphic_fbi->alpha_phy_addr1 :
mxc_graphic_fbi->alpha_phy_addr0;
- dev_dbg(info->device, "Updating SDC graphic "
+ dev_dbg(info->device, "Updating SDC alpha "
"buf %d address=0x%08lX\n",
- mxc_fbi->cur_ipu_buf,
+ !mxc_fbi->cur_ipu_alpha_buf,
active_alpha_phy_addr);
break;
}
@@ -1314,7 +1317,8 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
down(&mxc_fbi->flip_sem);
- mxc_fbi->cur_ipu_buf = !mxc_fbi->cur_ipu_buf;
+ mxc_fbi->cur_ipu_buf = (++mxc_fbi->cur_ipu_buf) % 3;
+ mxc_fbi->cur_ipu_alpha_buf = !mxc_fbi->cur_ipu_alpha_buf;
dev_dbg(info->device, "Updating SDC %s buf %d address=0x%08lX\n",
info->fix.id, mxc_fbi->cur_ipu_buf, base);
@@ -1325,11 +1329,11 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
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,
+ mxc_fbi->cur_ipu_alpha_buf,
active_alpha_phy_addr) == 0) {
ipu_select_buffer(mxc_graphic_fbi->ipu_ch,
IPU_ALPHA_IN_BUFFER,
- mxc_fbi->cur_ipu_buf);
+ mxc_fbi->cur_ipu_alpha_buf);
}
ipu_select_buffer(mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
@@ -1338,9 +1342,20 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
ipu_enable_irq(mxc_fbi->ipu_ch_irq);
} else {
dev_err(info->device,
- "Error updating SDC buf %d to address=0x%08lX\n",
- mxc_fbi->cur_ipu_buf, base);
- mxc_fbi->cur_ipu_buf = !mxc_fbi->cur_ipu_buf;
+ "Error updating SDC buf %d to address=0x%08lX, "
+ "current buf %d, buf0 ready %d, buf1 ready %d, "
+ "buf2 ready %d\n", mxc_fbi->cur_ipu_buf, base,
+ ipu_get_cur_buffer_idx(mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER),
+ ipu_check_buffer_ready(mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER, 0),
+ ipu_check_buffer_ready(mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER, 1),
+ ipu_check_buffer_ready(mxc_fbi->ipu_ch,
+ IPU_INPUT_BUFFER, 2));
+ mxc_fbi->cur_ipu_buf = (++mxc_fbi->cur_ipu_buf) % 3;
+ mxc_fbi->cur_ipu_buf = (++mxc_fbi->cur_ipu_buf) % 3;
+ mxc_fbi->cur_ipu_alpha_buf = !mxc_fbi->cur_ipu_alpha_buf;
ipu_clear_irq(mxc_fbi->ipu_ch_irq);
ipu_enable_irq(mxc_fbi->ipu_ch_irq);
return -EBUSY;
@@ -1436,30 +1451,8 @@ static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id)
ipu_disable_irq(irq);
mxc_fbi->wait4vsync = 0;
} else {
- if (!ipu_check_buffer_ready(mxc_fbi->ipu_ch,
- IPU_INPUT_BUFFER, mxc_fbi->cur_ipu_buf)
- || (mxc_fbi->waitcnt > 1)) {
- /*
- * This code wait for EOF irq to make sure current
- * buffer showed.
- *
- * Buffer ready will be clear after this buffer
- * begin to show. If it keep 1, it represents this
- * irq come from previous buffer. If so, wait for
- * EOF irq again.
- *
- * Normally, waitcnt will not > 1, if so, something
- * is wrong, then clear it manually.
- */
- if (mxc_fbi->waitcnt > 1)
- ipu_clear_buffer_ready(mxc_fbi->ipu_ch,
- IPU_INPUT_BUFFER,
- mxc_fbi->cur_ipu_buf);
- up(&mxc_fbi->flip_sem);
- ipu_disable_irq(irq);
- mxc_fbi->waitcnt = 0;
- } else
- mxc_fbi->waitcnt++;
+ up(&mxc_fbi->flip_sem);
+ ipu_disable_irq(irq);
}
return IRQ_HANDLED;
}
diff --git a/drivers/video/mxc/mxcfb.c b/drivers/video/mxc/mxcfb.c
index 52694e49e69d..4dffee5dbde3 100644
--- a/drivers/video/mxc/mxcfb.c
+++ b/drivers/video/mxc/mxcfb.c
@@ -241,6 +241,7 @@ static int mxcfb_set_par(struct fb_info *fbi)
fbi->fix.smem_start +
(fbi->fix.line_length * fbi->var.yres),
fbi->fix.smem_start,
+ 0,
0, 0);
if (retval) {
dev_err(fbi->device,
diff --git a/include/linux/mxcfb.h b/include/linux/mxcfb.h
index 58158eee72dc..a92494c3f11a 100644
--- a/include/linux/mxcfb.h
+++ b/include/linux/mxcfb.h
@@ -29,6 +29,8 @@
#define FB_SYNC_CLK_IDLE_EN 0x10000000
#define FB_SYNC_SHARP_MODE 0x08000000
#define FB_SYNC_SWAP_RGB 0x04000000
+#define FB_ACCEL_TRIPLE_FLAG 0x00000000
+#define FB_ACCEL_DOUBLE_FLAG 0x00000001
struct mxcfb_gbl_alpha {
int enable;