video: tegra: add multiple windows support to flip ioctl
authorAntti Hatala <ahatala@nvidia.com>
Wed, 8 Sep 2010 23:11:20 +0000 (16:11 -0700)
committerColin Cross <ccross@android.com>
Wed, 6 Oct 2010 23:51:21 +0000 (16:51 -0700)
Change-Id: I8521d1f6737e0972d8385e0ceecfc3a1bcae8550
Signed-off-by: Erik Gilling <konkers@android.com>
drivers/video/tegra/fb.c
include/video/tegrafb.h

index 44550c1f283c7d695b86d0ef17b7f3ed538e485d..4c0d719bb69c853204fb15ee9793d53eb70d30c9 100644 (file)
@@ -278,10 +278,59 @@ err:
        return err;
 }
 
+static void tegra_fb_set_windowattr(struct tegra_fb_info *tegra_fb,
+                                   struct tegra_dc_win *win,
+                                   struct tegra_fb_windowattr *attr)
+{
+       if (!attr->buff_id) {
+               win->flags = 0;
+               return;
+       }
+       win->flags = TEGRA_WIN_FLAG_ENABLED;
+       if (attr->blend == TEGRA_FB_WIN_BLEND_PREMULT)
+               win->flags |= TEGRA_WIN_FLAG_BLEND_PREMULT;
+       else if (attr->blend == TEGRA_FB_WIN_BLEND_COVERAGE)
+               win->flags |= TEGRA_WIN_FLAG_BLEND_COVERAGE;
+       win->fmt = attr->pixformat;
+       win->x = attr->x;
+       win->y = attr->y;
+       win->w = attr->w;
+       win->h = attr->h;
+       win->out_x = attr->out_x;
+       win->out_y = attr->out_y;
+       win->out_w = attr->out_w;
+       win->out_h = attr->out_h;
+       win->z = attr->z;
+       // STOPSHIP need to check perms on handle
+       win->phys_addr = nvmap_pin_single((struct nvmap_handle *)attr->buff_id);
+       win->phys_addr += attr->offset;
+       win->stride = attr->stride;
+       if ((s32)attr->pre_syncpt_id >= 0) {
+               nvhost_syncpt_wait_timeout(&tegra_fb->ndev->host->syncpt,
+                                          attr->pre_syncpt_id,
+                                          attr->pre_syncpt_val,
+                                          msecs_to_jiffies(500));
+       }
+}
+
+static void tegra_fb_set_windowhandle(struct tegra_fb_info *tegra_fb,
+                                     struct tegra_dc_win *win,
+                                     unsigned long handle)
+{
+       if (win->cur_handle)
+               nvmap_unpin((struct nvmap_handle **)&win->cur_handle, 1);
+       win->cur_handle = handle;
+}
+
 static int tegra_fb_flip(struct tegra_fb_info *tegra_fb,
                         struct tegra_fb_flip_args *args)
 {
+       struct tegra_dc_win *win;
+       struct tegra_dc_win *wins[TEGRA_FB_FLIP_N_WINDOWS];
+       struct tegra_dc_win **w = wins;
+       struct tegra_dc *dc = tegra_fb->win->dc;
        int err = 0;
+       int i;
 
        if (WARN_ON(!tegra_fb->nvmap_file))
                return -EFAULT;
@@ -289,21 +338,28 @@ static int tegra_fb_flip(struct tegra_fb_info *tegra_fb,
        if (WARN_ON(!tegra_fb->ndev))
                return -EFAULT;
 
-       // XXX need to check perms on handle
-       tegra_fb->win->phys_addr = nvmap_pin_single((struct nvmap_handle *) args->buff_id);
-
-       if ((s32)args->pre_syncpt_id >= 0) {
-               nvhost_syncpt_wait_timeout(&tegra_fb->ndev->host->syncpt, args->pre_syncpt_id,
-                                  args->pre_syncpt_val, msecs_to_jiffies(500));
+       for (i = 0; i < TEGRA_FB_FLIP_N_WINDOWS; i++) {
+               int idx = args->win[i].index;
+               win = tegra_dc_get_window(dc, idx);
+               if (win) {
+                       tegra_fb_set_windowattr(tegra_fb, win, &args->win[i]);
+                       *w++ = win;
+               } else if (idx != -1) {
+                       dev_warn(&tegra_fb->ndev->dev,
+                                "invalid window index %d on flip\n", idx);
+               }
        }
 
-       err = tegra_dc_update_windows(&tegra_fb->win, 1);
+       err = tegra_dc_update_windows(wins, w - wins);
        if (err < 0)
                return err;
 
-       if (tegra_fb->win->cur_handle)
-               nvmap_unpin((struct nvmap_handle **) &tegra_fb->win->cur_handle, 1);
-       tegra_fb->win->cur_handle = args->buff_id;
+       for (i = 0; i < TEGRA_FB_FLIP_N_WINDOWS; i++) {
+               win = tegra_dc_get_window(dc, args->win[i].index);
+               if (win)
+                       tegra_fb_set_windowhandle(tegra_fb, win,
+                                                 args->win[i].buff_id);
+       }
 
        args->post_syncpt_val = err;
        args->post_syncpt_id = tegra_dc_get_syncpt_id(tegra_fb->win->dc);
@@ -311,9 +367,6 @@ static int tegra_fb_flip(struct tegra_fb_info *tegra_fb,
        return 0;
 }
 
-
-/* TODO: implement private window ioctls to set overlay x,y */
-
 static int tegra_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 {
        struct tegra_fb_info *tegra_fb = info->par;
index cb040ae5f329d0d711bda60735df660d0e4f306a..3d7a5a9d66e9aab40f017e1647234b169ffe1b16 100644 (file)
 #include <linux/types.h>
 #include <asm/ioctl.h>
 
-struct tegra_fb_flip_args {
+#define TEGRA_FB_WIN_FMT_P1            0
+#define TEGRA_FB_WIN_FMT_P2            1
+#define TEGRA_FB_WIN_FMT_P4            2
+#define TEGRA_FB_WIN_FMT_P8            3
+#define TEGRA_FB_WIN_FMT_B4G4R4A4      4
+#define TEGRA_FB_WIN_FMT_B5G5R5A       5
+#define TEGRA_FB_WIN_FMT_B5G6R5                6
+#define TEGRA_FB_WIN_FMT_AB5G5R5       7
+#define TEGRA_FB_WIN_FMT_B8G8R8A8      12
+#define TEGRA_FB_WIN_FMT_R8G8B8A8      13
+#define TEGRA_FB_WIN_FMT_B6x2G6x2R6x2A8        14
+#define TEGRA_FB_WIN_FMT_R6x2G6x2B6x2A8        15
+#define TEGRA_FB_WIN_FMT_YCbCr422      16
+#define TEGRA_FB_WIN_FMT_YUV422                17
+#define TEGRA_FB_WIN_FMT_YCbCr420P     18
+#define TEGRA_FB_WIN_FMT_YUV420P       19
+#define TEGRA_FB_WIN_FMT_YCbCr422P     20
+#define TEGRA_FB_WIN_FMT_YUV422P       21
+#define TEGRA_FB_WIN_FMT_YCbCr422R     22
+#define TEGRA_FB_WIN_FMT_YUV422R       23
+#define TEGRA_FB_WIN_FMT_YCbCr422RA    24
+#define TEGRA_FB_WIN_FMT_YUV422RA      25
+
+#define TEGRA_FB_WIN_BLEND_NONE        0
+#define TEGRA_FB_WIN_BLEND_PREMULT 1
+#define TEGRA_FB_WIN_BLEND_COVERAGE 2
+
+/* set index to -1 to ignore window data */
+struct tegra_fb_windowattr {
+       __s32   index;
        __u32   buff_id;
+       __u32   blend;
+       __u32   offset;
+       __u32   stride;
+       __u32   pixformat;
+       __u32   x;
+       __u32   y;
+       __u32   w;
+       __u32   h;
+       __u32   out_x;
+       __u32   out_y;
+       __u32   out_w;
+       __u32   out_h;
+       __u32   z;
        __u32   pre_syncpt_id;
        __u32   pre_syncpt_val;
-       __u32   post_syncpt_id;
-       __u32   post_syncpt_val;
+};
+
+#define TEGRA_FB_FLIP_N_WINDOWS                3
+
+struct tegra_fb_flip_args {
+       struct tegra_fb_windowattr win[TEGRA_FB_FLIP_N_WINDOWS];
+       __u32 post_syncpt_id;
+       __u32 post_syncpt_val;
 };
 
 #define FBIO_TEGRA_SET_NVMAP_FD        _IOW('F', 0x40, __u32)