summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRob Herring <r.herring@freescale.com>2008-03-20 20:40:44 -0500
committerDaniel Schaeffer <daniel.schaeffer@timesys.com>2008-08-25 15:20:53 -0400
commit662f25ae696af4c95215b34fe39f02316820a80f (patch)
treedb8f76623451f91ab0f91d233627fe0dfd72173a /drivers
parent80a7540e963c10fe431ca7e9c65ffc3efc62f3f2 (diff)
ENGR00069555 IPU3 FB: fix pan and wait for vsync sync
This fixes synchronization between the framebuffer panning and wait for vsync functions. Fix FB overlay set position from kernel space. Signed-off-by: Rob Herring <r.herring@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/mxc/output/mxc_v4l2_output.c7
-rw-r--r--drivers/video/mxc/mxc_ipuv3_fb.c21
2 files changed, 22 insertions, 6 deletions
diff --git a/drivers/media/video/mxc/output/mxc_v4l2_output.c b/drivers/media/video/mxc/output/mxc_v4l2_output.c
index a1278a4fbdf5..34f39113d3a1 100644
--- a/drivers/media/video/mxc/output/mxc_v4l2_output.c
+++ b/drivers/media/video/mxc/output/mxc_v4l2_output.c
@@ -396,6 +396,7 @@ static int mxc_v4l2out_streamon(vout_data * vout)
u16 out_height;
ipu_channel_t display_input_ch = MEM_PP_MEM;
bool use_direct_adc = false;
+ mm_segment_t old_fs;
if (!vout)
return -EINVAL;
@@ -563,9 +564,13 @@ static int mxc_v4l2out_streamon(vout_data * vout)
fb_pos.x = vout->crop_current.left;
fb_pos.y = vout->crop_current.top;
- if (fbi->fbops->fb_ioctl)
+ if (fbi->fbops->fb_ioctl) {
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
fbi->fbops->fb_ioctl(fbi, MXCFB_SET_OVERLAY_POS,
(unsigned long)&fb_pos);
+ set_fs(old_fs);
+ }
vout->display_bufs[0] = fbi->fix.smem_start;
vout->display_bufs[1] = fbi->fix.smem_start +
diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c
index c3dd8eec3206..bfaac69f48a7 100644
--- a/drivers/video/mxc/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc/mxc_ipuv3_fb.c
@@ -465,16 +465,23 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
}
case MXCFB_WAIT_FOR_VSYNC:
{
- init_completion(&mxc_fbi->vsync_complete);
+ if (mxc_fbi->blank != FB_BLANK_UNBLANK)
+ break;
down(&mxc_fbi->flip_sem);
+ init_completion(&mxc_fbi->vsync_complete);
+
+ ipu_clear_irq(mxc_fbi->ipu_ch_irq);
ipu_enable_irq(mxc_fbi->ipu_ch_irq);
retval = wait_for_completion_interruptible_timeout(
&mxc_fbi->vsync_complete, 1 * HZ);
- if (retval > 0) {
+ if (retval == 0) {
dev_err(fbi->device,
- "MXCFB_WAIT_FOR_VSYNC: timeout\n");
+ "MXCFB_WAIT_FOR_VSYNC: timeout %d\n",
+ retval);
retval = -ETIME;
+ } else if (retval > 0) {
+ retval = 0;
}
break;
}
@@ -620,6 +627,9 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
dev_dbg(info->device, "Updating SDC BG buf %d address=0x%08lX\n",
mxc_fbi->cur_ipu_buf, base);
+ down(&mxc_fbi->flip_sem);
+ init_completion(&mxc_fbi->vsync_complete);
+
mxc_fbi->cur_ipu_buf = !mxc_fbi->cur_ipu_buf;
if (ipu_update_channel_buffer(mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
mxc_fbi->cur_ipu_buf, base) == 0) {
@@ -977,12 +987,14 @@ static int mxcfb_probe(struct platform_device *pdev)
mxcfbi->ipu_di = pdev->id;
ipu_disp_set_global_alpha(MEM_BG_SYNC, true, 0x80);
ipu_disp_set_color_key(MEM_BG_SYNC, false, 0);
+ mxcfbi->blank = FB_BLANK_UNBLANK;
strcpy(fbi->fix.id, "DISP3 BG");
} else if (pdev->id == 1) {
mxcfbi->ipu_ch_irq = IPU_IRQ_DC_SYNC_EOF;
mxcfbi->ipu_ch = MEM_DC_SYNC;
mxcfbi->ipu_di = pdev->id;
+ mxcfbi->blank = FB_BLANK_POWERDOWN;
strcpy(fbi->fix.id, "DISP3 BG - DI1");
} else if (pdev->id == 2) { /* Overlay */
@@ -990,6 +1002,7 @@ static int mxcfb_probe(struct platform_device *pdev)
mxcfbi->ipu_ch = MEM_FG_SYNC;
mxcfbi->ipu_di = -1;
mxcfbi->overlay = true;
+ mxcfbi->blank = FB_BLANK_POWERDOWN;
strcpy(fbi->fix.id, "DISP3 FG");
}
@@ -1007,8 +1020,6 @@ static int mxcfb_probe(struct platform_device *pdev)
fbi->var.yres_virtual = fbi->var.yres * 2;
#endif
- mxcfbi->blank = FB_BLANK_UNBLANK;
-
/* Need dummy values until real panel is configured */
fbi->var.xres = 240;
fbi->var.yres = 320;