OMAPDSS: switch FBIO_WAITFORVSYNC to the new code
[pandora-kernel.git] / drivers / video / omap2 / omapfb / omapfb-ioctl.c
index a0ac95c..99d7662 100644 (file)
@@ -31,7 +31,6 @@
 
 #include <video/omapdss.h>
 #include <plat/vrfb.h>
-#include <plat/vram.h>
 
 #include "omapfb.h"
 
@@ -70,7 +69,7 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
 
        DBG("omapfb_setup_plane\n");
 
-       if (ofbi->num_overlays != 1) {
+       if (ofbi->num_overlays == 0) {
                r = -EINVAL;
                goto out;
        }
@@ -185,7 +184,7 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
 {
        struct omapfb_info *ofbi = FB2OFB(fbi);
 
-       if (ofbi->num_overlays != 1) {
+       if (ofbi->num_overlays == 0) {
                memset(pi, 0, sizeof(*pi));
        } else {
                struct omap_overlay *ovl;
@@ -592,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);
@@ -613,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;
@@ -780,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");
@@ -802,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:
@@ -848,14 +935,15 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
                break;
 
        case OMAPFB_GET_VRAM_INFO: {
-               unsigned long vram, free, largest;
-
                DBG("ioctl GET_VRAM_INFO\n");
 
-               omap_vram_get_info(&vram, &free, &largest);
-               p.vram_info.total = vram;
-               p.vram_info.free = free;
-               p.vram_info.largest_free_block = largest;
+               /*
+                * We don't have the ability to get this vram info anymore.
+                * Fill in something that should keep the applications working.
+                */
+               p.vram_info.total = SZ_1M * 64;
+               p.vram_info.free = SZ_1M * 64;
+               p.vram_info.largest_free_block = SZ_1M * 64;
 
                if (copy_to_user((void __user *)arg, &p.vram_info,
                                        sizeof(p.vram_info)))