]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/commitdiff
OMAPDSS: OMAPFB: Asynchronous vsync notification
authorErik Gilling <konkers@android.com>
Tue, 9 Apr 2013 23:24:24 +0000 (16:24 -0700)
committerPraneeth Bajjuri <praneeth@ti.com>
Fri, 12 Jul 2013 22:28:58 +0000 (17:28 -0500)
Enabled and disabled through new OMAPFB_ENABLEVSYNC ioctl.  Events delivered
as switch events.

Change-Id: Ie473d96732c5bf2259bac6205d0295d698e6e48b
Signed-off-by: Erik Gilling <konkers@android.com>
Signed-off-by: Dan Murphy <dmurphy@ti.com>
Signed-off-by: Dandawate Saket <dsaket@ti.com>
drivers/video/omap2/omapfb/omapfb-ioctl.c
drivers/video/omap2/omapfb/omapfb-main.c
drivers/video/omap2/omapfb/omapfb.h
include/uapi/linux/omapfb.h

index ff5e497342bff4b1f7bd0b25f268ef3838b124cc..c92ed5d6445e6ab11bbc1779c777b1c1ecd5e78e 100644 (file)
@@ -900,6 +900,24 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
                break;
        }
 
+       case OMAPFB_ENABLEVSYNC:
+               if (get_user(p.crt, (__u32 __user *)arg)) {
+                       r = -EFAULT;
+                       break;
+               }
+
+               omapfb_lock(fbdev);
+               fbdev->vsync_active = !!p.crt;
+
+               if (display->state == OMAP_DSS_DISPLAY_ACTIVE) {
+                       if (p.crt)
+                               omapfb_enable_vsync(fbdev);
+                       else
+                               omapfb_disable_vsync(fbdev);
+               }
+               omapfb_unlock(fbdev);
+               break;
+
        default:
                dev_err(fbdev->dev, "Unknown ioctl 0x%x\n", cmd);
                r = -EINVAL;
index d62b536e57593d5d46972343f2111c928174ec90..783236d72595fa6381b75b8b9830b8fc1eb38661 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/omapfb.h>
+#include <linux/wait.h>
 
 #include <video/omapdss.h>
 #include <video/omapvrfb.h>
@@ -768,6 +769,11 @@ static int omapfb_open(struct fb_info *fbi, int user)
 
 static int omapfb_release(struct fb_info *fbi, int user)
 {
+       struct omapfb_info *ofbi = FB2OFB(fbi);
+       struct omapfb2_device *fbdev = ofbi->fbdev;
+
+       omapfb_disable_vsync(fbdev);
+
        return 0;
 }
 
@@ -1305,6 +1311,9 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
                                !d->auto_update_work_enabled)
                        omapfb_start_auto_update(fbdev, display);
 
+               if (fbdev->vsync_active)
+                       omapfb_enable_vsync(fbdev);
+
                break;
 
        case FB_BLANK_NORMAL:
@@ -1313,6 +1322,10 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
        case FB_BLANK_VSYNC_SUSPEND:
        case FB_BLANK_HSYNC_SUSPEND:
        case FB_BLANK_POWERDOWN:
+
+               if (fbdev->vsync_active)
+                       omapfb_disable_vsync(fbdev);
+
                if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
                        goto exit;
 
@@ -2477,6 +2490,39 @@ static int omapfb_init_connections(struct omapfb2_device *fbdev,
        return 0;
 }
 
+static void omapfb_send_vsync_work(struct work_struct *work)
+{
+       struct omapfb2_device *fbdev =
+               container_of(work, typeof(*fbdev), vsync_work);
+       char buf[64];
+       char *envp[2];
+
+       snprintf(buf, sizeof(buf), "VSYNC=%llu",
+               ktime_to_ns(fbdev->vsync_timestamp));
+       envp[0] = buf;
+       envp[1] = NULL;
+       kobject_uevent_env(&fbdev->dev->kobj, KOBJ_CHANGE, envp);
+}
+static void omapfb_vsync_isr(void *data, u32 mask)
+{
+       struct omapfb2_device *fbdev = data;
+       fbdev->vsync_timestamp = ktime_get();
+       schedule_work(&fbdev->vsync_work);
+}
+
+int omapfb_enable_vsync(struct omapfb2_device *fbdev)
+{
+       int r;
+       /* TODO: should determine correct IRQ like dss_mgr_wait_for_vsync does*/
+       r = omap_dispc_register_isr(omapfb_vsync_isr, fbdev, DISPC_IRQ_VSYNC);
+       return r;
+}
+
+void omapfb_disable_vsync(struct omapfb2_device *fbdev)
+{
+       omap_dispc_unregister_isr(omapfb_vsync_isr, fbdev, DISPC_IRQ_VSYNC);
+}
+
 static int __init omapfb_probe(struct platform_device *pdev)
 {
        struct omapfb2_device *fbdev = NULL;
@@ -2624,6 +2670,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
                goto cleanup;
        }
 
+       INIT_WORK(&fbdev->vsync_work, omapfb_send_vsync_work);
        return 0;
 
 cleanup:
@@ -2639,6 +2686,7 @@ static int __exit omapfb_remove(struct platform_device *pdev)
        struct omapfb2_device *fbdev = platform_get_drvdata(pdev);
 
        /* FIXME: wait till completion of pending events */
+       /* TODO: terminate vsync thread */
 
        omapfb_remove_sysfs(fbdev);
 
index 623cd872a36788f3dc8cccd25fa53b475995cb3a..f375ec81a937cb50852b4c4c48ed23b84854f675 100644 (file)
@@ -107,6 +107,15 @@ struct omapfb2_device {
        struct omap_overlay_manager *managers[10];
 
        struct workqueue_struct *auto_update_wq;
+       unsigned num_bpp_overrides;
+       struct {
+               struct omap_dss_device *dssdev;
+               u8 bpp;
+       } bpp_overrides[10];
+
+       bool vsync_active;
+       ktime_t vsync_timestamp;
+       struct work_struct vsync_work;
 };
 
 struct omapfb_colormode {
@@ -141,6 +150,8 @@ void omapfb_stop_auto_update(struct omapfb2_device *fbdev,
                struct omap_dss_device *display);
 int omapfb_get_update_mode(struct fb_info *fbi, enum omapfb_update_mode *mode);
 int omapfb_set_update_mode(struct fb_info *fbi, enum omapfb_update_mode mode);
+int omapfb_enable_vsync(struct omapfb2_device *fbdev);
+void omapfb_disable_vsync(struct omapfb2_device *fbdev);
 
 /* find the display connected to this fb, if any */
 static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
index 7c97bc00ac6d9682ddd8ae32e7ce69d16f4ad116..709a1f2b237acb1ce04cf623a58374f384a7fb89 100644 (file)
@@ -58,6 +58,7 @@
 #define OMAPFB_GET_VRAM_INFO   OMAP_IOR(61, struct omapfb_vram_info)
 #define OMAPFB_SET_TEARSYNC    OMAP_IOW(62, struct omapfb_tearsync_info)
 #define OMAPFB_GET_DISPLAY_INFO        OMAP_IOR(63, struct omapfb_display_info)
+#define OMAPFB_ENABLEVSYNC       OMAP_IOW(64, int)
 
 #define OMAPFB_CAPS_GENERIC_MASK       0x00000fff
 #define OMAPFB_CAPS_LCDC_MASK          0x00fff000