OMAPDSS: switch FBIO_WAITFORVSYNC to the new code
[pandora-kernel.git] / drivers / video / omap2 / omapfb / omapfb-ioctl.c
index 233aab0..99d7662 100644 (file)
@@ -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;
@@ -779,7 +844,8 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
                        r = -ENODEV;
                        break;
                }
-               /* FALLTHROUGH */
+               r = omapfb_do_vsync(fbi, display, NULL, true);
+               break;
 
        case OMAPFB_WAITFORVSYNC:
                DBG("ioctl WAITFORVSYNC\n");
@@ -801,6 +867,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: