diff options
author | Rob Herring <r.herring@freescale.com> | 2008-03-20 20:40:44 -0500 |
---|---|---|
committer | Daniel Schaeffer <daniel.schaeffer@timesys.com> | 2008-08-25 15:20:53 -0400 |
commit | 662f25ae696af4c95215b34fe39f02316820a80f (patch) | |
tree | db8f76623451f91ab0f91d233627fe0dfd72173a /drivers | |
parent | 80a7540e963c10fe431ca7e9c65ffc3efc62f3f2 (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.c | 7 | ||||
-rw-r--r-- | drivers/video/mxc/mxc_ipuv3_fb.c | 21 |
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; |