OMAP: DSS2: OMAPFB: Add support for switching memory regions
authorVille Syrjälä <ville.syrjala@nokia.com>
Wed, 17 Mar 2010 18:36:51 +0000 (20:36 +0200)
committerTomi Valkeinen <tomi.valkeinen@nokia.com>
Tue, 3 Aug 2010 12:18:46 +0000 (15:18 +0300)
Separate the memory region from the framebuffer device a little bit.
It's now possible to select the memory region used by the framebuffer
device using the new mem_idx parameter of omapfb_plane_info. If the
mem_idx is specified it will be interpreted as an index into the
memory regions array, if it's not specified the framebuffer's index is
used instead. So by default each framebuffer keeps using it's own
memory region which preserves backwards compatibility.

This allows cloning the same memory region to several overlays and yet
each overlay can be controlled independently since they can be
associated with separate framebuffer devices.

Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
drivers/video/omap2/omapfb/omapfb-ioctl.c
drivers/video/omap2/omapfb/omapfb-main.c
drivers/video/omap2/omapfb/omapfb-sysfs.c
drivers/video/omap2/omapfb/omapfb.h
include/linux/omapfb.h

index 9c7361871d786b4685e7469fa0eb99b5fa16c4b0..6635bd75affa0c73a8ad8c0e2e2bb6a0bc88971b 100644 (file)
 
 #include "omapfb.h"
 
+static u8 get_mem_idx(struct omapfb_info *ofbi)
+{
+       if (ofbi->id == ofbi->region->id)
+               return 0;
+
+       return OMAPFB_MEM_IDX_ENABLED | ofbi->region->id;
+}
+
+static struct omapfb2_mem_region *get_mem_region(struct omapfb_info *ofbi,
+                                                u8 mem_idx)
+{
+       struct omapfb2_device *fbdev = ofbi->fbdev;
+
+       if (mem_idx & OMAPFB_MEM_IDX_ENABLED)
+               mem_idx &= OMAPFB_MEM_IDX_MASK;
+       else
+               mem_idx = ofbi->id;
+
+       if (mem_idx >= fbdev->num_fbs)
+               return NULL;
+
+       return &fbdev->regions[mem_idx];
+}
+
 static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
 {
        struct omapfb_info *ofbi = FB2OFB(fbi);
        struct omapfb2_device *fbdev = ofbi->fbdev;
        struct omap_overlay *ovl;
-       struct omap_overlay_info info;
+       struct omap_overlay_info old_info;
+       struct omapfb2_mem_region *old_rg, *new_rg;
        int r = 0;
 
        DBG("omapfb_setup_plane\n");
@@ -52,7 +77,14 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
        /* XXX uses only the first overlay */
        ovl = ofbi->overlays[0];
 
-       if (pi->enabled && !ofbi->region.size) {
+       old_rg = ofbi->region;
+       new_rg = get_mem_region(ofbi, pi->mem_idx);
+       if (!new_rg) {
+               r = -EINVAL;
+               goto out;
+       }
+
+       if (pi->enabled && !new_rg->size) {
                /*
                 * This plane's memory was freed, can't enable it
                 * until it's reallocated.
@@ -61,27 +93,60 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
                goto out;
        }
 
-       ovl->get_overlay_info(ovl, &info);
+       ovl->get_overlay_info(ovl, &old_info);
 
-       info.pos_x = pi->pos_x;
-       info.pos_y = pi->pos_y;
-       info.out_width = pi->out_width;
-       info.out_height = pi->out_height;
-       info.enabled = pi->enabled;
+       if (old_rg != new_rg) {
+               ofbi->region = new_rg;
+               set_fb_fix(fbi);
+       }
 
-       r = ovl->set_overlay_info(ovl, &info);
-       if (r)
-               goto out;
+       if (pi->enabled) {
+               struct omap_overlay_info info;
+
+               r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y,
+                       pi->out_width, pi->out_height);
+               if (r)
+                       goto undo;
 
-       if (ovl->manager) {
-               r = ovl->manager->apply(ovl->manager);
+               ovl->get_overlay_info(ovl, &info);
+
+               if (!info.enabled) {
+                       info.enabled = pi->enabled;
+                       r = ovl->set_overlay_info(ovl, &info);
+                       if (r)
+                               goto undo;
+               }
+       } else {
+               struct omap_overlay_info info;
+
+               ovl->get_overlay_info(ovl, &info);
+
+               info.enabled = pi->enabled;
+               info.pos_x = pi->pos_x;
+               info.pos_y = pi->pos_y;
+               info.out_width = pi->out_width;
+               info.out_height = pi->out_height;
+
+               r = ovl->set_overlay_info(ovl, &info);
                if (r)
-                       goto out;
+                       goto undo;
        }
 
-out:
-       if (r)
-               dev_err(fbdev->dev, "setup_plane failed\n");
+       if (ovl->manager)
+               ovl->manager->apply(ovl->manager);
+
+       return 0;
+
+ undo:
+       if (old_rg != new_rg) {
+               ofbi->region = old_rg;
+               set_fb_fix(fbi);
+       }
+
+       ovl->set_overlay_info(ovl, &old_info);
+ out:
+       dev_err(fbdev->dev, "setup_plane failed\n");
+
        return r;
 }
 
@@ -92,8 +157,8 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
        if (ofbi->num_overlays != 1) {
                memset(pi, 0, sizeof(*pi));
        } else {
-               struct omap_overlay_info *ovli;
                struct omap_overlay *ovl;
+               struct omap_overlay_info *ovli;
 
                ovl = ofbi->overlays[0];
                ovli = &ovl->info;
@@ -103,6 +168,7 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
                pi->enabled = ovli->enabled;
                pi->channel_out = 0; /* xxx */
                pi->mirror = 0;
+               pi->mem_idx = get_mem_idx(ofbi);
                pi->out_width = ovli->out_width;
                pi->out_height = ovli->out_height;
        }
@@ -123,11 +189,24 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
 
        size = PAGE_ALIGN(mi->size);
 
-       rg = &ofbi->region;
+       rg = ofbi->region;
 
-       for (i = 0; i < ofbi->num_overlays; i++) {
-               if (ofbi->overlays[i]->info.enabled)
-                       return -EBUSY;
+       if (atomic_read(&rg->map_count))
+               return -EBUSY;
+
+       for (i = 0; i < fbdev->num_fbs; i++) {
+               struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]);
+               int j;
+
+               if (ofbi2->region != rg)
+                       continue;
+
+               for (j = 0; j < ofbi2->num_overlays; j++) {
+                       if (ofbi2->overlays[j]->info.enabled) {
+                               r = -EBUSY;
+                               return r;
+                       }
+               }
        }
 
        if (rg->size != size || rg->type != mi->type) {
@@ -146,7 +225,7 @@ static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
        struct omapfb_info *ofbi = FB2OFB(fbi);
        struct omapfb2_mem_region *rg;
 
-       rg = &ofbi->region;
+       rg = ofbi->region;
        memset(mi, 0, sizeof(*mi));
 
        mi->size = rg->size;
index ccccf3d71a395920eb7cffe4e2318e500874c8db..4a0588022b33ab898ee216437b357f11bdf334c3 100644 (file)
@@ -157,7 +157,7 @@ static void fill_fb(struct fb_info *fbi)
 
 static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
 {
-       const struct vrfb *vrfb = &ofbi->region.vrfb;
+       const struct vrfb *vrfb = &ofbi->region->vrfb;
        unsigned offset;
 
        switch (rot) {
@@ -185,27 +185,27 @@ static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
 static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot)
 {
        if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
-               return ofbi->region.vrfb.paddr[rot]
+               return ofbi->region->vrfb.paddr[rot]
                        + omapfb_get_vrfb_offset(ofbi, rot);
        } else {
-               return ofbi->region.paddr;
+               return ofbi->region->paddr;
        }
 }
 
 static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi)
 {
        if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
-               return ofbi->region.vrfb.paddr[0];
+               return ofbi->region->vrfb.paddr[0];
        else
-               return ofbi->region.paddr;
+               return ofbi->region->paddr;
 }
 
 static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi)
 {
        if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
-               return ofbi->region.vrfb.vaddr[0];
+               return ofbi->region->vrfb.vaddr[0];
        else
-               return ofbi->region.vaddr;
+               return ofbi->region->vaddr;
 }
 
 static struct omapfb_colormode omapfb_colormodes[] = {
@@ -450,7 +450,7 @@ static int check_vrfb_fb_size(unsigned long region_size,
 static int check_fb_size(const struct omapfb_info *ofbi,
                struct fb_var_screeninfo *var)
 {
-       unsigned long max_frame_size = ofbi->region.size;
+       unsigned long max_frame_size = ofbi->region->size;
        int bytespp = var->bits_per_pixel >> 3;
        unsigned long line_size = var->xres_virtual * bytespp;
 
@@ -497,7 +497,7 @@ static int check_fb_size(const struct omapfb_info *ofbi,
 static int setup_vrfb_rotation(struct fb_info *fbi)
 {
        struct omapfb_info *ofbi = FB2OFB(fbi);
-       struct omapfb2_mem_region *rg = &ofbi->region;
+       struct omapfb2_mem_region *rg = ofbi->region;
        struct vrfb *vrfb = &rg->vrfb;
        struct fb_var_screeninfo *var = &fbi->var;
        struct fb_fix_screeninfo *fix = &fbi->fix;
@@ -558,9 +558,9 @@ static int setup_vrfb_rotation(struct fb_info *fbi)
                return r;
 
        /* used by open/write in fbmem.c */
-       fbi->screen_base = ofbi->region.vrfb.vaddr[0];
+       fbi->screen_base = ofbi->region->vrfb.vaddr[0];
 
-       fix->smem_start = ofbi->region.vrfb.paddr[0];
+       fix->smem_start = ofbi->region->vrfb.paddr[0];
 
        switch (var->nonstd) {
        case OMAPFB_COLOR_YUV422:
@@ -599,7 +599,7 @@ void set_fb_fix(struct fb_info *fbi)
        struct fb_fix_screeninfo *fix = &fbi->fix;
        struct fb_var_screeninfo *var = &fbi->var;
        struct omapfb_info *ofbi = FB2OFB(fbi);
-       struct omapfb2_mem_region *rg = &ofbi->region;
+       struct omapfb2_mem_region *rg = ofbi->region;
 
        DBG("set_fb_fix\n");
 
@@ -688,7 +688,7 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
                return -EINVAL;
 
        /* When no memory is allocated ignore the size check */
-       if (ofbi->region.size != 0 && check_fb_size(ofbi, var))
+       if (ofbi->region->size != 0 && check_fb_size(ofbi, var))
                return -EINVAL;
 
        if (var->xres + var->xoffset > var->xres_virtual)
@@ -856,7 +856,7 @@ static void omapfb_calc_addr(const struct omapfb_info *ofbi,
 }
 
 /* setup overlay according to the fb */
-static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
+int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
                u16 posx, u16 posy, u16 outw, u16 outh)
 {
        int r = 0;
@@ -892,7 +892,7 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
                yres = var->yres;
        }
 
-       if (ofbi->region.size)
+       if (ofbi->region->size)
                omapfb_calc_addr(ofbi, var, fix, rotation,
                                 &data_start_p, &data_start_v);
 
@@ -971,7 +971,7 @@ int omapfb_apply_changes(struct fb_info *fbi, int init)
 
                DBG("apply_changes, fb %d, ovl %d\n", ofbi->id, ovl->id);
 
-               if (ofbi->region.size == 0) {
+               if (ofbi->region->size == 0) {
                        /* the fb is not available. disable the overlay */
                        omapfb_overlay_enable(ovl, 0);
                        if (!init && ovl->manager)
@@ -1071,16 +1071,16 @@ static int omapfb_pan_display(struct fb_var_screeninfo *var,
 
 static void mmap_user_open(struct vm_area_struct *vma)
 {
-       struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data;
+       struct omapfb2_mem_region *rg = vma->vm_private_data;
 
-       atomic_inc(&ofbi->map_count);
+       atomic_inc(&rg->map_count);
 }
 
 static void mmap_user_close(struct vm_area_struct *vma)
 {
-       struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data;
+       struct omapfb2_mem_region *rg = vma->vm_private_data;
 
-       atomic_dec(&ofbi->map_count);
+       atomic_dec(&rg->map_count);
 }
 
 static struct vm_operations_struct mmap_user_ops = {
@@ -1092,6 +1092,7 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
 {
        struct omapfb_info *ofbi = FB2OFB(fbi);
        struct fb_fix_screeninfo *fix = &fbi->fix;
+       struct omapfb2_mem_region *rg;
        unsigned long off;
        unsigned long start;
        u32 len;
@@ -1102,6 +1103,8 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
                return -EINVAL;
        off = vma->vm_pgoff << PAGE_SHIFT;
 
+       rg = ofbi->region;
+
        start = omapfb_get_region_paddr(ofbi);
        len = fix->smem_len;
        if (off >= len)
@@ -1117,12 +1120,12 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
        vma->vm_flags |= VM_IO | VM_RESERVED;
        vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
        vma->vm_ops = &mmap_user_ops;
-       vma->vm_private_data = ofbi;
+       vma->vm_private_data = rg;
        if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
                             vma->vm_end - vma->vm_start, vma->vm_page_prot))
                return -EAGAIN;
        /* vm_ops.open won't be called for mmap itself. */
-       atomic_inc(&ofbi->map_count);
+       atomic_inc(&rg->map_count);
        return 0;
 }
 
@@ -1312,7 +1315,9 @@ static void omapfb_free_fbmem(struct fb_info *fbi)
        struct omapfb2_device *fbdev = ofbi->fbdev;
        struct omapfb2_mem_region *rg;
 
-       rg = &ofbi->region;
+       rg = ofbi->region;
+
+       WARN_ON(atomic_read(&rg->map_count));
 
        if (rg->paddr)
                if (omap_vram_free(rg->paddr, rg->size))
@@ -1367,8 +1372,15 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
        void __iomem *vaddr;
        int r;
 
-       rg = &ofbi->region;
-       memset(rg, 0, sizeof(*rg));
+       rg = ofbi->region;
+
+       rg->paddr = 0;
+       rg->vaddr = NULL;
+       memset(&rg->vrfb, 0, sizeof rg->vrfb);
+       rg->size = 0;
+       rg->type = 0;
+       rg->alloc = false;
+       rg->map = false;
 
        size = PAGE_ALIGN(size);
 
@@ -1621,7 +1633,7 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev)
        for (i = 0; i < fbdev->num_fbs; i++) {
                struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
                struct omapfb2_mem_region *rg;
-               rg = &ofbi->region;
+               rg = ofbi->region;
 
                DBG("region%d phys %08x virt %p size=%lu\n",
                                i,
@@ -1638,7 +1650,7 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
        struct omapfb_info *ofbi = FB2OFB(fbi);
        struct omapfb2_device *fbdev = ofbi->fbdev;
        struct omap_dss_device *display = fb2display(fbi);
-       struct omapfb2_mem_region *rg = &ofbi->region;
+       struct omapfb2_mem_region *rg = ofbi->region;
        unsigned long old_size = rg->size;
        unsigned long old_paddr = rg->paddr;
        int old_type = rg->type;
@@ -1721,7 +1733,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
        fbi->flags = FBINFO_FLAG_DEFAULT;
        fbi->pseudo_palette = fbdev->pseudo_palette;
 
-       if (ofbi->region.size == 0) {
+       if (ofbi->region->size == 0) {
                clear_fb_info(fbi);
                return 0;
        }
@@ -1883,6 +1895,9 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
                ofbi->fbdev = fbdev;
                ofbi->id = i;
 
+               ofbi->region = &fbdev->regions[i];
+               ofbi->region->id = i;
+
                /* assign these early, so that fb alloc can use them */
                ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB :
                        OMAP_DSS_ROT_DMA;
index 5179219128bd031f5e0303dcfce3e443aefab781..dea1aa46a7db6e6921af143ec0e3a28f49d9ab4c 100644 (file)
@@ -64,7 +64,7 @@ static ssize_t store_rotate_type(struct device *dev,
        if (rot_type == ofbi->rotation_type)
                goto out;
 
-       if (ofbi->region.size) {
+       if (ofbi->region->size) {
                r = -EBUSY;
                goto out;
        }
@@ -408,7 +408,7 @@ static ssize_t show_size(struct device *dev,
        struct fb_info *fbi = dev_get_drvdata(dev);
        struct omapfb_info *ofbi = FB2OFB(fbi);
 
-       return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region.size);
+       return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size);
 }
 
 static ssize_t store_size(struct device *dev, struct device_attribute *attr,
@@ -416,6 +416,8 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
 {
        struct fb_info *fbi = dev_get_drvdata(dev);
        struct omapfb_info *ofbi = FB2OFB(fbi);
+       struct omapfb2_device *fbdev = ofbi->fbdev;
+       struct omapfb2_mem_region *rg;
        unsigned long size;
        int r;
        int i;
@@ -425,15 +427,30 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
        if (!lock_fb_info(fbi))
                return -ENODEV;
 
-       for (i = 0; i < ofbi->num_overlays; i++) {
-               if (ofbi->overlays[i]->info.enabled) {
-                       r = -EBUSY;
-                       goto out;
+       rg = ofbi->region;
+
+       if (atomic_read(&rg->map_count)) {
+               r = -EBUSY;
+               goto out;
+       }
+
+       for (i = 0; i < fbdev->num_fbs; i++) {
+               struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]);
+               int j;
+
+               if (ofbi2->region != rg)
+                       continue;
+
+               for (j = 0; j < ofbi2->num_overlays; j++) {
+                       if (ofbi2->overlays[j]->info.enabled) {
+                               r = -EBUSY;
+                               goto out;
+                       }
                }
        }
 
-       if (size != ofbi->region.size) {
-               r = omapfb_realloc_fbmem(fbi, size, ofbi->region.type);
+       if (size != ofbi->region->size) {
+               r = omapfb_realloc_fbmem(fbi, size, ofbi->region->type);
                if (r) {
                        dev_err(dev, "realloc fbmem failed\n");
                        goto out;
@@ -453,7 +470,7 @@ static ssize_t show_phys(struct device *dev,
        struct fb_info *fbi = dev_get_drvdata(dev);
        struct omapfb_info *ofbi = FB2OFB(fbi);
 
-       return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region.paddr);
+       return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr);
 }
 
 static ssize_t show_virt(struct device *dev,
@@ -462,7 +479,7 @@ static ssize_t show_virt(struct device *dev,
        struct fb_info *fbi = dev_get_drvdata(dev);
        struct omapfb_info *ofbi = FB2OFB(fbi);
 
-       return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region.vaddr);
+       return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region->vaddr);
 }
 
 static struct device_attribute omapfb_attrs[] = {
index c9866be0460a1afbe7a150f53284c457f11a8dbd..02f1ba9b228c939f95759da30f183993dc4a064b 100644 (file)
@@ -44,6 +44,7 @@ extern unsigned int omapfb_debug;
 #define OMAPFB_MAX_OVL_PER_FB 3
 
 struct omapfb2_mem_region {
+       int             id;
        u32             paddr;
        void __iomem    *vaddr;
        struct vrfb     vrfb;
@@ -51,13 +52,13 @@ struct omapfb2_mem_region {
        u8              type;           /* OMAPFB_PLANE_MEM_* */
        bool            alloc;          /* allocated by the driver */
        bool            map;            /* kernel mapped by the driver */
+       atomic_t        map_count;
 };
 
 /* appended to fb_info */
 struct omapfb_info {
        int id;
-       struct omapfb2_mem_region region;
-       atomic_t map_count;
+       struct omapfb2_mem_region *region;
        int num_overlays;
        struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB];
        struct omapfb2_device *fbdev;
@@ -76,6 +77,7 @@ struct omapfb2_device {
 
        unsigned num_fbs;
        struct fb_info *fbs[10];
+       struct omapfb2_mem_region regions[10];
 
        unsigned num_displays;
        struct omap_dss_device *displays[10];
@@ -117,6 +119,9 @@ int omapfb_update_window(struct fb_info *fbi,
 int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
                        struct fb_var_screeninfo *var);
 
+int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
+               u16 posx, u16 posy, u16 outw, u16 outh);
+
 /* find the display connected to this fb, if any */
 static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
 {
index 9bdd91486b49d94c42e9ac00efd29e1b282a53b5..0ecf7311c1ae93d60d7dc08afed08a0892f7b6d5 100644 (file)
@@ -85,6 +85,9 @@
 #define OMAPFB_MEMTYPE_SRAM            1
 #define OMAPFB_MEMTYPE_MAX             1
 
+#define OMAPFB_MEM_IDX_ENABLED 0x80
+#define OMAPFB_MEM_IDX_MASK    0x7f
+
 enum omapfb_color_format {
        OMAPFB_COLOR_RGB565 = 0,
        OMAPFB_COLOR_YUV422,
@@ -136,7 +139,7 @@ struct omapfb_plane_info {
        __u8  enabled;
        __u8  channel_out;
        __u8  mirror;
-       __u8  reserved1;
+       __u8  mem_idx;
        __u32 out_width;
        __u32 out_height;
        __u32 reserved2[12];