From: Antti Hatala Date: Wed, 8 Sep 2010 23:11:20 +0000 (-0700) Subject: video: tegra: add multiple windows support to flip ioctl X-Git-Tag: firefly_0821_release~9834^2~572 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e4dc6f8eda5474df35aadc37a66bfac9015d5bba;p=firefly-linux-kernel-4.4.55.git video: tegra: add multiple windows support to flip ioctl Change-Id: I8521d1f6737e0972d8385e0ceecfc3a1bcae8550 Signed-off-by: Erik Gilling --- diff --git a/drivers/video/tegra/fb.c b/drivers/video/tegra/fb.c index 44550c1f283c..4c0d719bb69c 100644 --- a/drivers/video/tegra/fb.c +++ b/drivers/video/tegra/fb.c @@ -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; diff --git a/include/video/tegrafb.h b/include/video/tegrafb.h index cb040ae5f329..3d7a5a9d66e9 100644 --- a/include/video/tegrafb.h +++ b/include/video/tegrafb.h @@ -21,12 +21,60 @@ #include #include -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)