X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fvideo%2Fomap2%2Fomapfb%2Fomapfb-ioctl.c;h=6355dfeb3d8b18b6c6434fd147505b97d2bd3623;hb=00943e97e1fcda39c59f503e36f161b99feaf1f7;hp=233aab08270c2010b9f6e011d1e4001e30f81adf;hpb=5a928e75172fe4bb3895033b2cbc569f4123aa86;p=pandora-kernel.git diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 233aab08270c..6355dfeb3d8b 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -591,6 +591,70 @@ static int omapfb_wait_for_go(struct fb_info *fbi) return r; } +static int omapfb_do_vsync(struct fb_info *fbi, + struct omap_dss_device *display, u32 *frame, bool force) +{ + unsigned long timeout = usecs_to_jiffies(16667 * 2); + struct omapfb_info *ofbi = FB2OFB(fbi); + static u32 frame_tv; + bool is_tv = false; + u32 frame_dummy = 0; + int i, r; + + if (frame == NULL) + frame = &frame_dummy; + + /* try to find the first enabled overlay+display pair */ + for (i = 0; i < ofbi->num_overlays; i++) { + struct omap_overlay_manager *manager; + + if (!ofbi->overlays[i]->info.enabled) + continue; + + manager = ofbi->overlays[i]->manager; + if (!manager) + continue; + + if (manager->device->state + == OMAP_DSS_DISPLAY_ACTIVE) + { + display = manager->device; + break; + } + } + + if (display->type == OMAP_DISPLAY_TYPE_VENC) + is_tv = true; + + r = dispc_runtime_get(); + if (r) + return r; + + /* this is unsafe pandora hack, but should work as fb + * is compiled in (no worry about rmmod) and there + * is no way to rm fb instances at runtime */ + unlock_fb_info(fbi); + + if (is_tv) { + u32 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; + r = omap_dispc_wait_for_irq_interruptible_timeout(irq, + timeout); + /* there is no real frame counter for TV */ + *frame = ++frame_tv; + } + else { + r = omap_dispc_wait_for_vsync_on_frame(frame, + timeout, force); + } + + if (!lock_fb_info(fbi)) + printk(KERN_ERR "omapfb: lock_fb_info failed\n"); + + dispc_runtime_put(); + + return r; +} + int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) { struct omapfb_info *ofbi = FB2OFB(fbi); @@ -612,6 +676,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) struct omapfb_tearsync_info tearsync_info; struct omapfb_display_info display_info; u32 crt; + u32 frame; } p; int r = 0; @@ -801,6 +866,28 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) r = omapfb_wait_for_go(fbi); break; + case OMAPFB_WAITFORVSYNC_FRAME: + if (get_user(p.frame, (__u32 __user *)arg)) { + r = -EFAULT; + break; + } + r = omapfb_do_vsync(fbi, display, &p.frame, false); + /* report the frame # regardless */ + if (copy_to_user((void __user *)arg, &p.frame, + sizeof(p.frame))) + r = -EFAULT; + break; + + case OMAPFB_GET_LINE_STATUS: + r = omap_dispc_get_line_status(); + if (r < 0) + break; + if (copy_to_user((void __user *)arg, &r, sizeof(r))) + r = -EFAULT; + else + r = 0; + break; + /* LCD and CTRL tests do the same thing for backward * compatibility */ case OMAPFB_LCD_TEST: