ionvideo: omx support osd display
authorjintao xu <jintao.xu@amlogic.com>
Thu, 31 Aug 2017 08:21:23 +0000 (16:21 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Fri, 1 Sep 2017 11:50:33 +0000 (04:50 -0700)
PD#150258: omx support osd display

Change-Id: I566e530e0ec2dc5e7eb73e33b90345552f6ae7fc
Signed-off-by: jintao xu <jintao.xu@amlogic.com>
17 files changed:
MAINTAINERS
arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts
arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts
arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts
arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts
arch/arm64/boot/dts/amlogic/gxl_p231_1g.dts
arch/arm64/boot/dts/amlogic/gxl_p231_2g.dts
arch/arm64/boot/dts/amlogic/gxl_p231_2g_buildroot.dts
arch/arm64/boot/dts/amlogic/gxl_skt.dts
arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts
arch/arm64/boot/dts/amlogic/gxm_skt.dts
drivers/amlogic/media/video_processor/ionvideo/Makefile
drivers/amlogic/media/video_processor/ionvideo/ion_priv.h [deleted file]
drivers/amlogic/media/video_processor/ionvideo/ionvideo.c
drivers/amlogic/media/video_processor/ionvideo/ionvideo.h
drivers/amlogic/media/video_processor/ionvideo/videobuf2-ion.c [deleted file]
drivers/amlogic/media/video_processor/ionvideo/videobuf2-ion.h [deleted file]

index 7c7a391..2801ac5 100644 (file)
@@ -14056,3 +14056,9 @@ AMLOGIC ADD PARTITION NORMAL & AB DTS
 M: Xindong Xu <xindong.xu@amlogic.com>
 F: arch/arm64/boot/dts/amlogic/partition_mbox_ab.dtsi
 F: arch/arm64/boot/dts/amlogic/partition_mbox_normal.dtsi
+
+AMLOGIC multimedia
+M:  JinTao Xu <jintao.xu@amlogic.com>
+F: drivers/amlogic/media/video_processor/ionvideo/ion_priv.h
+F: drivers/amlogic/media/video_processor/ionvideo/videobuf2-ion.c
+F: drivers/amlogic/media/video_processor/ionvideo/videobuf2-ion.h
\ No newline at end of file
index a87429e..1e26019 100644 (file)
@@ -81,7 +81,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x2000000>;
+                       size = <0x0 0x5000000>;
                        alignment = <0x0 0x400000>;
                };
 
index 23111bd..8c6a0e5 100644 (file)
@@ -81,7 +81,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x2000000>;
+                       size = <0x0 0x5000000>;
                        alignment = <0x0 0x400000>;
                };
 
index 3fd649e..da5583a 100644 (file)
@@ -90,7 +90,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x2000000>;
+                       size = <0x0 0x5000000>;
                        alignment = <0x0 0x400000>;
                };
 
index c7dfaf7..7084f79 100644 (file)
@@ -82,7 +82,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x2000000>;
+                       size = <0x0 0x5000000>;
                        alignment = <0x0 0x400000>;
                };
 
index 6b2aa49..39a3836 100644 (file)
@@ -82,7 +82,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x2000000>;
+                       size = <0x0 0x5000000>;
                        alignment = <0x0 0x400000>;
                };
 
index 35274c7..a24d8b0 100644 (file)
@@ -82,7 +82,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x2000000>;
+                       size = <0x0 0x5000000>;
                        alignment = <0x0 0x400000>;
                };
 
index 370f943..59fea62 100644 (file)
@@ -82,7 +82,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x2000000>;
+                       size = <0x0 0x5000000>;
                        alignment = <0x0 0x400000>;
                };
 
index 8395537..ac6ffe0 100644 (file)
@@ -80,7 +80,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x2000000>;
+                       size = <0x0 0x5000000>;
                        alignment = <0x0 0x400000>;
                };
 
index 67f5845..76b3f38 100644 (file)
@@ -81,7 +81,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x2000000>;
+                       size = <0x0 0x5000000>;
                        alignment = <0x0 0x400000>;
                };
 
index 773b4ee..cbc9295 100644 (file)
@@ -81,7 +81,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x2000000>;
+                       size = <0x0 0x5000000>;
                        alignment = <0x0 0x400000>;
                };
 
index 53f9cf7..54a0bea 100644 (file)
@@ -1,5 +1,4 @@
 asflags-y=-mfloat-abi=softfp -mfpu=neon
 ccflags-y += -Idrivers/staging/android/ion
 
-obj-$(CONFIG_AMLOGIC_VIDEOBUF2_ION) += videobuf2-ion.o
 obj-$(CONFIG_AMLOGIC_IONVIDEO) += ionvideo.o ppmgr2.o
diff --git a/drivers/amlogic/media/video_processor/ionvideo/ion_priv.h b/drivers/amlogic/media/video_processor/ionvideo/ion_priv.h
deleted file mode 100644 (file)
index c301dbb..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * drivers/amlogic/media/video_processor/ionvideo/ion_priv.h
- *
- * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- */
-
-#ifndef _ION_PRIV_H
-#define _ION_PRIV_H
-
-#include <ion.h>
-#include <linux/kref.h>
-#include <linux/mm_types.h>
-#include <linux/mutex.h>
-#include <linux/rbtree.h>
-#include <linux/sched.h>
-#include <linux/shrinker.h>
-#include <linux/types.h>
-
-struct ion_buffer *ion_handle_buffer(struct ion_handle *handle);
-
-/**
- * struct ion_buffer - metadata for a particular buffer
- * @ref:               refernce count
- * @node:              node in the ion_device buffers tree
- * @dev:               back pointer to the ion_device
- * @heap:              back pointer to the heap the buffer came from
- * @flags:             buffer specific flags
- * @size:              size of the buffer
- * @priv_virt:         private data to the buffer representable as
- *                     a void *
- * @priv_phys:         private data to the buffer representable as
- *                     an ion_phys_addr_t (and someday a phys_addr_t)
- * @lock:              protects the buffers cnt fields
- * @kmap_cnt:          number of times the buffer is mapped to the kernel
- * @vaddr:             the kenrel mapping if kmap_cnt is not zero
- * @dmap_cnt:          number of times the buffer is mapped for dma
- * @sg_table:          the sg table for the buffer if dmap_cnt is not zero
- * @dirty:             bitmask representing which pages of this buffer have
- *                     been dirtied by the cpu and need cache maintenance
- *                     before dma
- * @vmas:              list of vma's mapping this buffer
- * @handle_count:      count of handles referencing this buffer
- * @task_comm:         taskcomm of last client to reference this buffer in a
- *                     handle, used for debugging
- * @pid:               pid of last client to reference this buffer in a
- *                     handle, used for debugging
- */
-struct ion_buffer {
-       struct kref ref;
-       struct rb_node node;
-       struct ion_device *dev;
-       struct ion_heap *heap;
-       unsigned long flags;
-       size_t size;
-       union {
-               void *priv_virt;
-               ion_phys_addr_t priv_phys;
-       };
-       struct mutex lock;
-       int kmap_cnt;
-       void *vaddr;
-       int dmap_cnt;
-       struct sg_table *sg_table;
-       unsigned long *dirty;
-       struct list_head vmas;
-       /* used to track orphaned buffers */
-       int handle_count;
-       char task_comm[TASK_COMM_LEN];
-       pid_t pid;
-};
-
-/**
- * struct ion_heap_ops - ops to operate on a given heap
- * @allocate:          allocate memory
- * @free:              free memory
- * @phys               get physical address of a buffer (only define on
- *                     physically contiguous heaps)
- * @map_dma            map the memory for dma to a scatterlist
- * @unmap_dma          unmap the memory for dma
- * @map_kernel         map memory to the kernel
- * @unmap_kernel       unmap memory to the kernel
- * @map_user           map memory to userspace
- */
-struct ion_heap_ops {
-       int (*allocate)(struct ion_heap *heap,
-                        struct ion_buffer *buffer, unsigned long len,
-                        unsigned long align, unsigned long flags);
-       void (*free)(struct ion_buffer *buffer);
-       int (*phys)(struct ion_heap *heap, struct ion_buffer *buffer,
-                    ion_phys_addr_t *addr, size_t *len);
-       struct sg_table * (*map_dma)(struct ion_heap *heap,
-                                       struct ion_buffer *buffer);
-       void (*unmap_dma)(struct ion_heap *heap, struct ion_buffer *buffer);
-       void * (*map_kernel)(struct ion_heap *heap, struct ion_buffer *buffer);
-       void (*unmap_kernel)(struct ion_heap *heap, struct ion_buffer *buffer);
-       int (*map_user)(struct ion_heap *mapper, struct ion_buffer *buffer,
-                        struct vm_area_struct *vma);
-};
-
-/**
- * struct ion_heap - represents a heap in the system
- * @node:              rb node to put the heap on the device's tree of heaps
- * @dev:               back pointer to the ion_device
- * @type:              type of heap
- * @ops:               ops struct as above
- * @id:                        id of heap, also indicates priority of this heap when
- *                     allocating.  These are specified by platform data and
- *                     MUST be unique
- * @name:              used for debugging
- * @debug_show:                called when heap debug file is read to add any
- *                     heap specific debug info to output
- *
- * Represents a pool of memory from which buffers can be made.  In some
- * systems the only heap is regular system memory allocated via vmalloc.
- * On others, some blocks might require large physically contiguous buffers
- * that are allocated from a specially reserved heap.
- */
-struct ion_heap {
-       struct plist_node node;
-       struct ion_device *dev;
-       enum ion_heap_type type;
-       struct ion_heap_ops *ops;
-       unsigned int id;
-       const char *name;
-       int (*debug_show)(struct ion_heap *heap, struct seq_file *, void *);
-};
-
-/**
- * ion_buffer_cached - this ion buffer is cached
- * @buffer:            buffer
- *
- * indicates whether this ion buffer is cached
- */
-bool ion_buffer_cached(struct ion_buffer *buffer);
-
-/**
- * ion_buffer_fault_user_mappings - fault in user mappings of this buffer
- * @buffer:            buffer
- *
- * indicates whether userspace mappings of this buffer will be faulted
- * in, this can affect how buffers are allocated from the heap.
- */
-bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer);
-
-/**
- * ion_device_create - allocates and returns an ion device
- * @custom_ioctl:      arch specific ioctl function if applicable
- *
- * returns a valid device or -PTR_ERR
- */
-struct ion_device *ion_device_create(long (*custom_ioctl)
-                                    (struct ion_client *client,
-                                     unsigned int cmd,
-                                     unsigned long arg));
-
-/**
- * ion_device_destroy - free and device and it's resource
- * @dev:               the device
- */
-void ion_device_destroy(struct ion_device *dev);
-
-/**
- * ion_device_add_heap - adds a heap to the ion device
- * @dev:               the device
- * @heap:              the heap to add
- */
-void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap);
-
-/**
- * some helpers for common operations on buffers using the sg_table
- * and vaddr fields
- */
-void *ion_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer);
-void ion_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer);
-int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
-                       struct vm_area_struct *area);
-int ion_heap_buffer_zero(struct ion_buffer *buffer);
-
-
-/**
- * functions for creating and destroying the built in ion heaps.
- * architectures can add their own custom architecture specific
- * heaps as appropriate.
- */
-
-struct ion_heap *ion_heap_create(struct ion_platform_heap *platform_heap);
-void ion_heap_destroy(struct ion_heap *heap);
-
-struct ion_heap *
-       ion_system_heap_create(struct ion_platform_heap *platform_heap);
-
-void ion_system_heap_destroy(struct ion_heap *heap);
-
-struct ion_heap *
-       ion_system_contig_heap_create(struct ion_platform_heap *platform_heap);
-
-void ion_system_contig_heap_destroy(struct ion_heap *heap);
-
-struct ion_heap *
-       ion_carveout_heap_create(struct ion_platform_heap *platform_heap);
-
-void ion_carveout_heap_destroy(struct ion_heap *heap);
-
-struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *platform_heap);
-void ion_chunk_heap_destroy(struct ion_heap *heap);
-/**
- * kernel api to allocate/free from carveout -- used when carveout is
- * used to back an architecture specific custom heap
- */
-ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap, unsigned long size,
-                                     unsigned long align);
-void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr,
-                      unsigned long size);
-/**
- * The carveout heap returns physical addresses, since 0 may be a valid
- * physical address, this is used to indicate allocation failed
- */
-#define ION_CARVEOUT_ALLOCATE_FAIL -1
-
-/**
- * functions for creating and destroying a heap pool -- allows you
- * to keep a pool of pre allocated memory to use from your heap.  Keeping
- * a pool of memory that is ready for dma, ie any cached mapping have been
- * invalidated from the cache, provides a significant performance benefit on
- * many systems
- */
-
-/**
- * struct ion_page_pool - pagepool struct
- * @high_count:                number of highmem items in the pool
- * @low_count:         number of lowmem items in the pool
- * @high_items:                list of highmem items
- * @low_items:         list of lowmem items
- * @shrinker:          a shrinker for the items
- * @mutex:             lock protecting this struct and especially the count
- *                     item list
- * @alloc:             function to be used to allocate pageory when the pool
- *                     is empty
- * @free:              function to be used to free pageory back to the system
- *                     when the shrinker fires
- * @gfp_mask:          gfp_mask to use from alloc
- * @order:             order of pages in the pool
- * @list:              plist node for list of pools
- *
- * Allows you to keep a pool of pre allocated pages to use from your heap.
- * Keeping a pool of pages that is ready for dma, ie any cached mapping have
- * been invalidated from the cache, provides a significant performance benefit
- * on many systems
- */
-struct ion_page_pool {
-       int high_count;
-       int low_count;
-       struct list_head high_items;
-       struct list_head low_items;
-       struct mutex mutex;
-       void * (*alloc)(struct ion_page_pool *pool);
-       void (*free)(struct ion_page_pool *pool, struct page *page);
-       gfp_t gfp_mask;
-       unsigned int order;
-       struct plist_node list;
-};
-
-struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order);
-void ion_page_pool_destroy(struct ion_page_pool *pool);
-void *ion_page_pool_alloc(struct ion_page_pool *pool);
-void ion_page_pool_free(struct ion_page_pool *pool, struct page *page);
-
-#endif /* _ION_PRIV_H */
index 8fd9f57..1760f89 100644 (file)
 #include <media/videobuf2-core.h>
 #include <media/videobuf2-v4l2.h>
 #include <linux/platform_device.h>
+#include <linux/amlogic/major.h>
 
 #define IONVIDEO_MODULE_NAME "ionvideo"
 
 #define IONVIDEO_VERSION "1.0"
 #define RECEIVER_NAME "ionvideo"
+#define IONVIDEO_DEVICE_NAME   "ionvideo"
 
 #define V4L2_CID_USER_AMLOGIC_IONVIDEO_BASE  (V4L2_CID_USER_BASE + 0x1100)
-
+#define SCALE_4K_TO_1080P 1
 static struct mutex ppmgr2_ge2d_canvas_mutex;
 
 static unsigned int video_nr_base = 13;
@@ -226,13 +228,10 @@ static int canvas_is_valid(struct ionvideo_dev *dev, int index)
 #endif
 
 static int ionvideo_fillbuff(struct ionvideo_dev *dev,
-                               struct ionvideo_buffer *buf)
+                               struct v4l2_buffer *buf)
 {
 
        struct vframe_s *vf;
-#ifdef IONVIDEO_DEBUG
-       struct vb2_buffer *vb = &(buf->vb);
-#endif
        int ret = 0;
        /* ------------------------------------------------------- */
 #if 0
@@ -256,26 +255,7 @@ static int ionvideo_fillbuff(struct ionvideo_dev *dev,
 
        }
        if (dev->freerun_mode == 0) {
-               if ((vf->type & 0x1) == VIDTYPE_INTERLACE) {
-                       if ((dev->ppmgr2_dev.bottom_first
-                               && (vf->type & 0x2)) || (dev
-                               ->ppmgr2_dev
-                               .bottom_first
-                               == 0
-                               && ((vf
-                               ->type
-                               & 0x2)
-                               == 0))) {
-                               buf->pts = vf->pts;
-                               buf->duration = vf->duration;
-                       }
-               } else {
-                       buf->pts = vf->pts;
-                       buf->duration = vf->duration;
-               }
-#ifdef IONVIDEO_DEBUG
-               ret = ppmgr2_process(vf, &dev->ppmgr2_dev, vb->v4l2_buf.index);
-#endif
+               ret = ppmgr2_process(vf, &dev->ppmgr2_dev, buf->index);
                if (ret) {
                        vf_put(vf, dev->vf_receiver_name);
                        return ret;
@@ -300,7 +280,19 @@ static int ionvideo_fillbuff(struct ionvideo_dev *dev,
                        dev->ppmgr2_dev.dst_width = vf->width;
                if (vf->height <= dev->height)
                        dev->ppmgr2_dev.dst_height = vf->height;
-
+#if SCALE_4K_TO_1080P
+               if (vf->width > dev->width || vf->height > dev->height) {
+                       if (vf->width*dev->height >= dev->width*vf->height) {
+                               dev->ppmgr2_dev.dst_width = dev->width;
+                               dev->ppmgr2_dev.dst_height = vf->height
+                                       * dev->width / vf->width;
+               } else {
+                               dev->ppmgr2_dev.dst_width = vf->width
+                                       * dev->height / vf->height;
+                               dev->ppmgr2_dev.dst_height = dev->height;
+                       }
+               }
+#endif
                if ((dev->ppmgr2_dev.dst_width >= 1920) && (dev->ppmgr2_dev
                        .dst_height
                        >= 1080)
@@ -312,21 +304,22 @@ static int ionvideo_fillbuff(struct ionvideo_dev *dev,
                                * scaling_rate
                                                        / 100;
                }
-#ifdef IONVIDEO_DEBUG
-               ret = ppmgr2_process(vf, &dev->ppmgr2_dev, vb->v4l2_buf.index);
-#endif
+               ret = ppmgr2_process(vf, &dev->ppmgr2_dev, buf->index);
                if (ret) {
                        vf_put(vf, dev->vf_receiver_name);
                        return ret;
                }
                videoc_omx_compute_pts(dev, vf);
+               buf->timecode.frames = 0;
+               if (vf->flag & VFRAME_FLAG_ERROR_RECOVERY)
+                       buf->timecode.frames |= 1;
+               if (vf->flag & VFRAME_FLAG_SYNCFRAME)
+                       buf->timecode.frames |= 2;
                vf_put(vf, dev->vf_receiver_name);
-#ifdef IONVIDEO_DEBUG
-               buf->vb.v4l2_buf.timestamp.tv_sec = dev->pts >> 32;
-               buf->vb.v4l2_buf.timestamp.tv_usec = dev->pts & 0xFFFFFFFF;
-               buf->vb.v4l2_buf.timecode.type = dev->ppmgr2_dev.dst_width;
-               buf->vb.v4l2_buf.timecode.flags = dev->ppmgr2_dev.dst_height;
-#endif
+               buf->timestamp.tv_sec = dev->pts >> 32;
+               buf->timestamp.tv_usec = dev->pts & 0xFFFFFFFF;
+               buf->timecode.type = dev->ppmgr2_dev.dst_width;
+               buf->timecode.flags = dev->ppmgr2_dev.dst_height;
        }
        /* ------------------------------------------------------- */
        return 0;
@@ -348,8 +341,7 @@ static int ionvideo_size_changed(struct ionvideo_dev *dev, int aw, int ah)
 static void ionvideo_thread_tick(struct ionvideo_dev *dev)
 {
        struct ionvideo_dmaqueue *dma_q = &dev->vidq;
-       struct ionvideo_buffer *buf;
-       unsigned long flags = 0;
+       struct v4l2_buffer *buf;
        struct vframe_s *vf;
 
        int w, h;
@@ -360,6 +352,14 @@ static void ionvideo_thread_tick(struct ionvideo_dev *dev)
        if (!dev)
                return;
 
+       if (dev->active_state == ION_INACTIVE_REQ) {
+               dev->active_state = ION_INACTIVE;
+               complete(&dev->inactive_done);
+       }
+
+       if (dev->active_state == ION_INACTIVE)
+               return;
+
        vf = vf_peek(dev->vf_receiver_name);
        if (!vf) {
                dev->vf_wait_cnt++;
@@ -384,28 +384,25 @@ static void ionvideo_thread_tick(struct ionvideo_dev *dev)
                usleep_range(4000, 5000);
                return;
        }
-       spin_lock_irqsave(&dev->slock, flags);
-       if (list_empty(&dma_q->active)) {
+       mutex_lock(&dev->mutex_input);
+       if (v4l2q_empty(&dev->input_queue)) {
                dprintk(dev, 3, "No active queue to serve\n");
-               spin_unlock_irqrestore(&dev->slock, flags);
+               mutex_unlock(&dev->mutex_input);
                schedule_timeout_interruptible(msecs_to_jiffies(20));
                return;
        }
-       buf = list_entry(dma_q->active.next, struct ionvideo_buffer, list);
-       spin_unlock_irqrestore(&dev->slock, flags);
+       buf = v4l2q_pop(&dev->input_queue);
+       mutex_unlock(&dev->mutex_input);
        /* Fill buffer */
        if (ionvideo_fillbuff(dev, buf))
                return;
        dev->vf_wait_cnt = 0;
 
-       spin_lock_irqsave(&dev->slock, flags);
-       list_del(&buf->list);
-       spin_unlock_irqrestore(&dev->slock, flags);
-       vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+       mutex_lock(&dev->mutex_output);
+       v4l2q_push(&dev->output_queue, buf);
        dma_q->vb_ready++;
-#ifdef IONVIDEO_DEBUG
-       dprintk(dev, 4, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index);
-#endif
+       mutex_unlock(&dev->mutex_output);
+       dprintk(dev, 4, "[%p/%d] done\n", buf, buf->index);
 }
 
 #define frames_to_ms(frames)                                   \
@@ -455,11 +452,13 @@ static int ionvideo_thread(void *data)
        return 0;
 }
 
-static int ionvideo_start_generating(struct ionvideo_dev *dev)
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 {
+       struct ionvideo_dev *dev = video_drvdata(file);
        struct ionvideo_dmaqueue *dma_q = &dev->vidq;
 
        dev->is_omx_video_started = 1;
+       dma_q->vb_ready = 0;
 
        dprintk(dev, 2, "%s\n", __func__);
 
@@ -483,8 +482,9 @@ static int ionvideo_start_generating(struct ionvideo_dev *dev)
        return 0;
 }
 
-static void ionvideo_stop_generating(struct ionvideo_dev *dev)
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 {
+       struct ionvideo_dev *dev = video_drvdata(file);
        struct ionvideo_dmaqueue *dma_q = &dev->vidq;
 
        dprintk(dev, 2, "%s\n", __func__);
@@ -500,158 +500,9 @@ static void ionvideo_stop_generating(struct ionvideo_dev *dev)
         * Typical driver might need to wait here until dma engine stops.
         * In this case we can abort imiedetly, so it's just a noop.
         */
-
-       /* Release all active buffers */
-       while (!list_empty(&dma_q->active)) {
-               struct ionvideo_buffer *buf;
-
-               buf = list_entry(dma_q->active.next, struct ionvideo_buffer,
-                                       list);
-               list_del(&buf->list);
-               vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
-#ifdef IONVIDEO_DEBUG
-               dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index);
-#endif
-       }
-}
-/* ------------------------------------------------------------------
- * Videobuf operations
- * ------------------------------------------------------------------
- */
-#ifdef IONVIDEO_DEBUG
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
-                       unsigned int *nbuffers, unsigned int *nplanes,
-                       unsigned int sizes[], void *alloc_ctxs[])
-{
-       struct ionvideo_dev *dev = vb2_get_drv_priv(vq);
-       unsigned long size;
-
-       if (fmt)
-               size = fmt->fmt.pix.sizeimage;
-       else
-               size = (dev->width * dev->height * dev->pixelsize) >> 3;
-
-       if (size == 0)
-               return -EINVAL;
-
-       if (*nbuffers == 0)
-               *nbuffers = 32;
-
-       while (size * *nbuffers > vid_limit * MAX_WIDTH * MAX_HEIGHT)
-               (*nbuffers)--;
-
-       *nplanes = 1;
-
-       sizes[0] = size;
-
-       /*
-        * videobuf2-vmalloc allocator is context-less so no need to set
-        * alloc_ctxs array.
-        */
-
-       dprintk(dev, 2, "%s, count=%d, size=%ld\n", __func__, *nbuffers, size);
-
-       return 0;
-}
-#endif
-
-static int buffer_prepare(struct vb2_buffer *vb)
-{
-       struct ionvideo_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-       struct ionvideo_buffer *buf = container_of(vb, struct ionvideo_buffer,
-                                                       vb);
-       unsigned long size;
-#ifdef IONVIDEO_DEBUG
-       dprintk(dev, 2, "%s, field=%d\n", __func__, vb->v4l2_buf.field);
-#endif
-       WARN_ON(dev->fmt == NULL);
-
-       /*
-        * Theses properties only change when queue is idle, see s_fmt.
-        * The below checks should not be performed here, on each
-        * buffer_prepare (i.e. on each qbuf). Most of the code in this function
-        * should thus be moved to buffer_init and s_fmt.
-        */
-       if (dev->width < 48 || dev->width > MAX_WIDTH
-               || dev->height < 32 || dev->height > MAX_HEIGHT)
-               return -EINVAL;
-
-       size = (dev->width * dev->height * dev->pixelsize) >> 3;
-       if (vb2_plane_size(vb, 0) < size) {
-               dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n",
-                       __func__, vb2_plane_size(vb, 0), size);
-               return -EINVAL;
-       }
-
-       vb2_set_plane_payload(&buf->vb, 0, size);
-
-       buf->fmt = dev->fmt;
-
        return 0;
 }
 
-static void buffer_queue(struct vb2_buffer *vb)
-{
-       struct ionvideo_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-       struct ionvideo_buffer *buf = container_of(vb, struct ionvideo_buffer,
-                                                       vb);
-       struct ionvideo_dmaqueue *vidq = &dev->vidq;
-       unsigned long flags = 0;
-
-       dprintk(dev, 2, "%s\n", __func__);
-
-       spin_lock_irqsave(&dev->slock, flags);
-       list_add_tail(&buf->list, &vidq->active);
-       spin_unlock_irqrestore(&dev->slock, flags);
-}
-
-static int start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-       struct ionvideo_dev *dev = vb2_get_drv_priv(vq);
-       struct ionvideo_dmaqueue *dma_q = &dev->vidq;
-
-       dev->is_actived = 1;
-       dma_q->vb_ready = 0;
-       dprintk(dev, 2, "%s\n", __func__);
-       return ionvideo_start_generating(dev);
-}
-
-/* abort streaming and wait for last buffer */
-static void stop_streaming(struct vb2_queue *vq)
-{
-       struct ionvideo_dev *dev = vb2_get_drv_priv(vq);
-
-       dev->is_actived = 0;
-       dprintk(dev, 2, "%s\n", __func__);
-       ionvideo_stop_generating(dev);
-}
-
-static void ionvideo_lock(struct vb2_queue *vq)
-{
-       struct ionvideo_dev *dev = vb2_get_drv_priv(vq);
-
-       mutex_lock(&dev->mutex);
-}
-
-static void ionvideo_unlock(struct vb2_queue *vq)
-{
-       struct ionvideo_dev *dev = vb2_get_drv_priv(vq);
-
-       mutex_unlock(&dev->mutex);
-}
-
-static const struct vb2_ops ionvideo_video_qops = {
-#ifdef IONVIDEO_DEBUG
-       .queue_setup = queue_setup,
-#endif
-       .buf_prepare = buffer_prepare,
-       .buf_queue = buffer_queue,
-       .start_streaming = start_streaming,
-       .stop_streaming = stop_streaming,
-       .wait_prepare = ionvideo_unlock,
-       .wait_finish = ionvideo_lock,
-};
-
 /* ------------------------------------------------------------------
  * IOCTL vidioc handling
  * ------------------------------------------------------------------
@@ -678,23 +529,22 @@ static int vidioc_open(struct file *file)
        dprintk(dev, 2, "vidioc_open\n");
        IONVID_INFO("ionvideo open\n");
        init_waitqueue_head(&dev->wq);
-       return v4l2_fh_open(file);
+       return 0;
 }
 
-static int vidioc_release(struct file *file)
+static int vidioc_close(struct file *file)
 {
        struct ionvideo_dev *dev = video_drvdata(file);
 
-       ionvideo_stop_generating(dev);
-       IONVID_INFO("ionvideo_stop_generating!!!!\n");
+       IONVID_INFO("vidioc_close!!!!\n");
        ppmgr2_release(&(dev->ppmgr2_dev));
-       dprintk(dev, 2, "vidioc_release\n");
-       IONVID_INFO("ionvideo release\n");
+       dprintk(dev, 2, "vidioc_close\n");
+       IONVID_INFO("vidioc_close\n");
        if (dev->fd_num > 0)
                dev->fd_num--;
 
        dev->once_record = 0;
-       return vb2_fop_release(file);
+       return 0;
 }
 
 static int vidioc_querycap(struct file *file, void *priv,
@@ -731,9 +581,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
                                struct v4l2_format *f)
 {
        struct ionvideo_dev *dev = video_drvdata(file);
-       struct vb2_queue *q = &dev->vb_vidq;
-       int ret = 0;
-       unsigned long flags;
 
        if (dev->freerun_mode == 0) {
                if (dev->c_width == 0 || dev->c_height == 0)
@@ -741,11 +588,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 
                f->fmt.pix.width = dev->c_width;
                f->fmt.pix.height = dev->c_height;
-               spin_lock_irqsave(&q->done_lock, flags);
-               ret = list_empty(&q->done_list);
-               spin_unlock_irqrestore(&q->done_lock, flags);
-               if (!ret)
-                       return -EAGAIN;
 
        } else {
                f->fmt.pix.width = dev->width;
@@ -793,17 +635,12 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
                                struct v4l2_format *f)
 {
        struct ionvideo_dev *dev = video_drvdata(file);
-       struct vb2_queue *q = &dev->vb_vidq;
 
        int ret = vidioc_try_fmt_vid_cap(file, priv, f);
 
        if (ret < 0)
                return ret;
 
-       if (vb2_is_busy(q)) {
-               dprintk(dev, 1, "%s device busy\n", __func__);
-               return -EBUSY;
-       }
        dev->fmt = get_format(f);
        dev->pixelsize = dev->fmt->depth;
        dev->width = f->fmt.pix.width;
@@ -814,46 +651,31 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
        return 0;
 }
 
-static int vidioc_enum_framesizes(struct file *file, void *fh,
-                                       struct v4l2_frmsizeenum *fsize)
-{
-       static const struct v4l2_frmsize_stepwise sizes = {
-               48, MAX_WIDTH, 4, 32, MAX_HEIGHT, 1};
-       int i;
-
-       if (fsize->index)
-               return -EINVAL;
-       for (i = 0; i < ARRAY_SIZE(formats); i++)
-               if (formats[i].fourcc == fsize->pixel_format)
-                       break;
-       if (i == ARRAY_SIZE(formats))
-               return -EINVAL;
-       fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
-       fsize->stepwise = sizes;
-       return 0;
-}
-
 static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
 {
        struct ionvideo_dev *dev = video_drvdata(file);
        struct ionvideo_dmaqueue *dma_q = &dev->vidq;
        struct ppmgr2_device *ppmgr2_dev = &(dev->ppmgr2_dev);
-       int ret = 0;
+       struct dma_buf *dbuf = NULL;
+       struct ion_buffer *buffer = NULL;
+       struct sg_table *table = NULL;
+       struct page *page = NULL;
+       void *phy_addr = NULL;
 
-       p->length = 0;
-       ret = vb2_ioctl_qbuf(file, priv, p);
-       if (ret != 0)
-               return ret;
+       dev->ionvideo_input[p->index] = *p;
 
+       mutex_lock(&dev->mutex_input);
+       v4l2q_push(&dev->input_queue, &(dev->ionvideo_input[p->index]));
+       mutex_unlock(&dev->mutex_input);
 
        if (!ppmgr2_dev->phy_addr[p->index]) {
-               struct vb2_buffer *vb;
-               struct vb2_queue *q;
-               void *phy_addr = NULL;
+               dbuf = dma_buf_get(p->m.fd);
+               buffer = dbuf->priv;
+               table = buffer->sg_table;
+               page = sg_page(table->sgl);
+               phy_addr = (void *)PFN_PHYS(page_to_pfn(page));
+               dma_buf_put(dbuf);
 
-               q = dev->vdev.queue;
-               vb = q->bufs[p->index];
-               phy_addr = vb2_plane_cookie(vb, 0);
                ppmgr2_dev->phy_addr[p->index] = phy_addr;
                ppmgr2_dev->dst_buffer_width = ALIGN(dev->width, 32);
                ppmgr2_dev->dst_buffer_height = dev->height;
@@ -870,9 +692,10 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
                }
        }
        wake_up_interruptible(&dma_q->wq);
-       return ret;
+       return 0;
 }
 
+/*
 static int vidioc_synchronization_dqbuf(struct file *file, void *priv,
                                        struct v4l2_buffer *p)
 {
@@ -886,7 +709,6 @@ static int vidioc_synchronization_dqbuf(struct file *file, void *priv,
 
        q = dev->vdev.queue;
        if (dev->receiver_register) {
-               /* clear the frame buffer queue */
                while (!list_empty(&q->done_list)) {
                        ret = vb2_ioctl_dqbuf(file, priv, p);
                        if (ret)
@@ -983,65 +805,43 @@ static int vidioc_synchronization_dqbuf(struct file *file, void *priv,
 
        return 0;
 }
+*/
 
 static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
 {
        struct ionvideo_dev *dev = video_drvdata(file);
        struct ionvideo_dmaqueue *dma_q = &dev->vidq;
-       int ret = 0;
+       struct v4l2_buffer *out_put = NULL;
 
+/*
        if (dev->freerun_mode == 0)
                return vidioc_synchronization_dqbuf(file, priv, p);
+*/
 
-       ret = vb2_ioctl_dqbuf(file, priv, p);
-       if (ret == 0)
-               dma_q->vb_ready--;
-       return ret;
-}
-
-#define NUM_INPUTS 10
-/* only one input in this sample driver */
-static int vidioc_enum_input(struct file *file, void *priv,
-                               struct v4l2_input *inp)
-{
-       if (inp->index >= NUM_INPUTS)
-               return -EINVAL;
-
-       inp->type = V4L2_INPUT_TYPE_CAMERA;
-       sprintf(inp->name, "Camera %u", inp->index);
-       return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
-       struct ionvideo_dev *dev = video_drvdata(file);
+       mutex_lock(&dev->mutex_output);
+       out_put = v4l2q_pop(&dev->output_queue);
 
-       *i = dev->input;
+       if (out_put != NULL) {
+               dma_q->vb_ready--;
+               *p = *out_put;
+       } else {
+               mutex_unlock(&dev->mutex_output);
+               return -EAGAIN;
+       }
+       mutex_unlock(&dev->mutex_output);
        return 0;
 }
 
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
-       struct ionvideo_dev *dev = video_drvdata(file);
-
-       if (i >= NUM_INPUTS)
-               return -EINVAL;
-
-       if (i == dev->input)
-               return 0;
-
-       dev->input = i;
-       return 0;
-}
+#define NUM_INPUTS 10
 
 /* ------------------------------------------------------------------
  * File operations for the device
  * ------------------------------------------------------------------
  */
-static const struct v4l2_file_operations ionvideo_fops = {
+static const struct v4l2_file_operations ionvideo_v4l2_fops = {
        .owner = THIS_MODULE,
        .open = vidioc_open,
-       .release = vidioc_release,
+       .release = vidioc_close,
        .read = vb2_fop_read,
        .poll = vb2_fop_poll,
        .unlocked_ioctl = video_ioctl2,/* V4L2 ioctl handler */
@@ -1054,29 +854,18 @@ static const struct v4l2_ioctl_ops ionvideo_ioctl_ops = {
        .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
        .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
        .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
-       .vidioc_enum_framesizes = vidioc_enum_framesizes,
-       .vidioc_reqbufs = vb2_ioctl_reqbufs,
-       .vidioc_create_bufs = vb2_ioctl_create_bufs,
-       .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
-       .vidioc_querybuf = vb2_ioctl_querybuf,
        .vidioc_qbuf = vidioc_qbuf,
        .vidioc_dqbuf = vidioc_dqbuf,
-       .vidioc_enum_input = vidioc_enum_input,
-       .vidioc_g_input = vidioc_g_input,
-       .vidioc_s_input = vidioc_s_input,
-       .vidioc_streamon = vb2_ioctl_streamon,
-       .vidioc_streamoff = vb2_ioctl_streamoff,
-       .vidioc_log_status = v4l2_ctrl_log_status,
-       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
-       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+       .vidioc_streamon = vidioc_streamon,
+       .vidioc_streamoff = vidioc_streamoff,
        .vidioc_s_ctrl = vidioc_s_ctrl,
 };
 
 static const struct video_device ionvideo_template = {
        .name = "ionvideo",
-       .fops = &ionvideo_fops,
+       .fops = &ionvideo_v4l2_fops,
        .ioctl_ops = &ionvideo_ioctl_ops,
-       .release = video_device_release_empty,
+       .release = video_device_release,
 };
 
 /* -----------------------------------------------------------------
@@ -1084,7 +873,7 @@ static const struct video_device ionvideo_template = {
  * -----------------------------------------------------------------
  */
 /* struct vb2_dc_conf * ionvideo_dma_ctx = NULL; */
-static int ionvideo_release(void)
+static int ionvideo_v4l2_release(void)
 {
        struct ionvideo_dev *dev;
        struct list_head *list;
@@ -1116,49 +905,45 @@ static int ionvideo_release(void)
 
 static int video_receiver_event_fun(int type, void *data, void *private_data)
 {
-#ifdef CONFIG_AM_VOUT
-       char *configured[2];
-       char framerate[20] = {0};
-#endif
        struct ionvideo_dev *dev = (struct ionvideo_dev *)private_data;
 
        if (type == VFRAME_EVENT_PROVIDER_UNREG) {
                dev->receiver_register = 0;
                dev->is_omx_video_started = 0;
+               if (dev->active_state == ION_ACTIVE) {
+                       /*if player killed thread may have exit.*/
+                       dev->active_state = ION_INACTIVE_REQ;
+                       wait_for_completion_timeout(&dev->inactive_done,
+                               msecs_to_jiffies(100));
+               }
+
                /*tsync_avevent(VIDEO_STOP, 0);*/
                IONVID_INFO("unreg:ionvideo\n");
        } else if (type == VFRAME_EVENT_PROVIDER_REG) {
                dev->receiver_register = 1;
                dev->is_omx_video_started = 1;
                dev->ppmgr2_dev.interlaced_num = 0;
+               dev->active_state = ION_ACTIVE;
+               init_completion(&dev->inactive_done);
+
+               v4l2q_init(&dev->input_queue, IONVIDEO_POOL_SIZE + 1,
+                               &dev->ionvideo_input_queue[0]);
+               v4l2q_init(&dev->output_queue, IONVIDEO_POOL_SIZE + 1,
+                               &dev->ionvideo_output_queue[0]);
                IONVID_INFO("reg:ionvideo\n");
        } else if (type == VFRAME_EVENT_PROVIDER_QUREY_STATE) {
                if (dev->vf_wait_cnt > 1)
                        return RECEIVER_INACTIVE;
                return RECEIVER_ACTIVE;
        } else if (type == VFRAME_EVENT_PROVIDER_FR_HINT) {
-               if ((data != NULL) && (ionvideo_seek_flag == 0)) {
 #ifdef CONFIG_AM_VOUT
-                       /*set_vframe_rate_hint((unsigned long)(data));*/
-                       sprintf(framerate, "FRAME_RATE_HINT=%lu",
-                       (unsigned long)data);
-                       configured[0] = framerate;
-                       configured[1] = NULL;
-                       kobject_uevent_env(&(dev->vdev.dev.kobj),
-                               KOBJ_CHANGE, configured);
-                       pr_info("%s: sent uevent %s\n",
-                                       __func__, configured[0]);
+               if ((data != NULL) && (ionvideo_seek_flag == 0))
+                       set_vframe_rate_hint((unsigned long)(data));
 #endif
-               }
        } else if (type == VFRAME_EVENT_PROVIDER_FR_END_HINT) {
 #ifdef CONFIG_AM_VOUT
                if (ionvideo_seek_flag == 0) {
-                       configured[0] = "FRAME_RATE_END_HINT";
-                       configured[1] = NULL;
-                       kobject_uevent_env(&(dev->vdev.dev.kobj),
-                                       KOBJ_CHANGE, configured);
-                       pr_info("%s: sent uevent %s\n",
-                               __func__, configured[0]);
+                       set_vframe_rate_end_hint();
                }
 #endif
        }
@@ -1174,7 +959,6 @@ static int __init ionvideo_create_instance(int inst)
 {
        struct ionvideo_dev *dev;
        struct video_device *vfd;
-       struct vb2_queue *q;
        int ret;
        unsigned long flags;
 
@@ -1199,26 +983,6 @@ static int __init ionvideo_create_instance(int inst)
        /* initialize locks */
        spin_lock_init(&dev->slock);
 
-       /* initialize queue */
-       q = &dev->vb_vidq;
-       q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
-       q->drv_priv = dev;
-       q->buf_struct_size = sizeof(struct ionvideo_buffer);
-       q->ops = &ionvideo_video_qops;
-       q->mem_ops = &vb2_ion_memops;
-#ifdef IONVIDEO_DEBUG
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-#else
-       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-#endif
-
-#ifdef IONVIDEO_DEBUG
-       ret = vb2_queue_init(q);
-       if (ret)
-               goto unreg_dev;
-#endif
-
        mutex_init(&dev->mutex);
 
        /* init video dma queues */
@@ -1230,23 +994,19 @@ static int __init ionvideo_create_instance(int inst)
        *vfd = ionvideo_template;
        vfd->dev_debug = debug;
        vfd->v4l2_dev = &dev->v4l2_dev;
-       vfd->queue = q;
-#ifdef IONVIDEO_DEBUG
-       set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
-#endif
 
        /*
         * Provide a mutex to v4l2 core. It will be used to protect
         * all fops and v4l2 ioctls.
         */
-       vfd->lock = &dev->mutex;
-       video_set_drvdata(vfd, dev);
 
        ret = video_register_device(vfd, VFL_TYPE_GRABBER,
                                inst + video_nr_base);
        if (ret < 0)
                goto unreg_dev;
 
+       video_set_drvdata(vfd, dev);
+
        dev->inst = inst;
        snprintf(dev->vf_receiver_name, ION_VF_RECEIVER_NAME_SIZE,
                (inst == 0) ? RECEIVER_NAME : RECEIVER_NAME ".%x",
@@ -1264,6 +1024,9 @@ static int __init ionvideo_create_instance(int inst)
        list_add_tail(&dev->ionvideo_devlist, &ionvideo_devlist);
        ionvideo_devlist_unlock(flags);
 
+       mutex_init(&dev->mutex_input);
+       mutex_init(&dev->mutex_output);
+
        return 0;
 
 unreg_dev:
@@ -1284,9 +1047,7 @@ int ionvideo_assign_map(char **receiver_name, int *inst)
        list_for_each(p, &ionvideo_devlist) {
                dev = list_entry(p, struct ionvideo_dev, ionvideo_devlist);
 
-               if ((dev->inst == *inst) && (!dev->mapped)) {
-                       dev->mapped = true;
-                       *inst = dev->inst;
+               if (dev->inst == *inst) {
                        *receiver_name = dev->vf_receiver_name;
                        ionvideo_devlist_unlock(flags);
                        return 0;
@@ -1297,8 +1058,9 @@ int ionvideo_assign_map(char **receiver_name, int *inst)
 
        return -ENODEV;
 }
+EXPORT_SYMBOL(ionvideo_assign_map);
 
-int ionvideo_alloc_map(char **receiver_name, int *inst)
+int ionvideo_alloc_map(int *inst)
 {
        unsigned long flags;
        struct ionvideo_dev *dev = NULL;
@@ -1312,7 +1074,6 @@ int ionvideo_alloc_map(char **receiver_name, int *inst)
                if ((dev->inst >= 0) && (!dev->mapped)) {
                        dev->mapped = true;
                        *inst = dev->inst;
-                       *receiver_name = dev->vf_receiver_name;
                        ionvideo_devlist_unlock(flags);
                        return 0;
                }
@@ -1424,6 +1185,67 @@ __ATTR_NULL };
 static struct class ionvideo_class = {.name = "ionvideo", .class_attrs =
 ion_video_class_attrs, };
 
+static int ionvideo_open(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static int ionvideo_release(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static long ionvideo_ioctl(struct file *file,
+                           unsigned int cmd,
+                           ulong arg)
+{
+       long ret = 0;
+       void __user *argp = (void __user *)arg;
+
+       switch (cmd) {
+       case IONVIDEO_IOCTL_ALLOC_ID:{
+                       u32 ionvideo_id = 0;
+
+                       ret = ionvideo_alloc_map(&ionvideo_id);
+                       if (ret != 0)
+                               break;
+                       put_user(ionvideo_id, (u32 __user *)argp);
+               }
+               break;
+       case IONVIDEO_IOCTL_FREE_ID:{
+                       u32 ionvideo_id;
+
+                       get_user(ionvideo_id, (u32 __user *)argp);
+                       ionvideo_release_map(ionvideo_id);
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+       return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long ionvideo_compat_ioctl(struct file *file,
+                               unsigned int cmd,
+                               ulong arg)
+{
+       long ret = 0;
+
+       ret = ionvideo_ioctl(file, cmd, (ulong)compat_ptr(arg));
+       return ret;
+}
+#endif
+static const struct file_operations ionvideo_fops = {
+       .owner = THIS_MODULE,
+       .open = ionvideo_open,
+       .release = ionvideo_release,
+       .unlocked_ioctl = ionvideo_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = ionvideo_compat_ioctl,
+#endif
+       .poll = NULL,
+};
 /* This routine allocates from 1 to n_devs virtual drivers.
  * The real maximum number of virtual drivers will depend on how many drivers
  * will succeed. This is limited to the maximum number of devices that
@@ -1433,9 +1255,6 @@ static int ionvideo_driver_probe(struct platform_device *pdev)
 {
        int ret = 0, i;
 
-       ret = class_register(&ionvideo_class);
-       if (ret < 0)
-               return ret;
        if (n_devs <= 0)
                n_devs = 1;
 
@@ -1468,8 +1287,7 @@ static int ionvideo_driver_probe(struct platform_device *pdev)
 
 static int ionvideo_drv_remove(struct platform_device *pdev)
 {
-       ionvideo_release();
-       class_unregister(&ionvideo_class);
+       ionvideo_v4l2_release();
        return 0;
 }
 
@@ -1492,17 +1310,49 @@ static struct platform_driver ionvideo_drv = {
 
 static int __init ionvideo_init(void)
 {
+       int ret = -1;
+       struct device *devp;
+
+       ret = class_register(&ionvideo_class);
+       if (ret < 0)
+               return ret;
+
+       ret = register_chrdev(IONVIDEO_MAJOR, "ionvideo", &ionvideo_fops);
+       if (ret < 0) {
+               pr_err("Can't allocate major for ionvideo device\n");
+               goto error1;
+       }
+
+       devp = device_create(&ionvideo_class,
+                               NULL,
+                               MKDEV(IONVIDEO_MAJOR, 0),
+                               NULL,
+                               IONVIDEO_DEVICE_NAME);
+       if (IS_ERR(devp)) {
+               pr_err("failed to create ionvideo device node\n");
+               ret = PTR_ERR(devp);
+               return ret;
+       }
+
        if (platform_driver_register(&ionvideo_drv)) {
                pr_err("Failed to register ionvideo driver\n");
                return -ENODEV;
        }
-
        return 0;
+
+error1:
+       unregister_chrdev(IONVIDEO_MAJOR, "ionvideo");
+       class_unregister(&ionvideo_class);
+       return ret;
+
 }
 
 static void __exit ionvideo_exit(void)
 {
        platform_driver_unregister(&ionvideo_drv);
+       device_destroy(&ionvideo_class, MKDEV(IONVIDEO_MAJOR, 0));
+       unregister_chrdev(IONVIDEO_MAJOR, IONVIDEO_DEVICE_NAME);
+       class_unregister(&ionvideo_class);
 }
 
 MODULE_DESCRIPTION("Video Technology Magazine Ion Video Capture Board");
index a5a4a6a..14bb5f9 100644 (file)
@@ -35,7 +35,6 @@
 #include <media/v4l2-fh.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-common.h>
-#include <media/videobuf2-core.h>
 
 #include <linux/mm.h>
 /* #include <mach/mod_gate.h> */
@@ -48,7 +47,6 @@
 
 #include <linux/amlogic/media/frame_sync/timestamp.h>
 #include <linux/amlogic/media/frame_sync/tsync.h>
-#include "videobuf2-ion.h"
 
 /* Wake up at about 30 fps */
 #define WAKE_NUMERATOR 30
@@ -57,6 +55,8 @@
 #define MAX_WIDTH 4096
 #define MAX_HEIGHT 4096
 
+#define IONVIDEO_POOL_SIZE 16
+
 #define IONVID_INFO(fmt, args...) pr_info("ionvid: info: "fmt"", ## args)
 #define IONVID_DBG(fmt, args...) pr_debug("ionvid: dbg: "fmt"", ## args)
 #define IONVID_ERR(fmt, args...) pr_err("ionvid: err: "fmt"", ## args)
@@ -74,6 +74,92 @@ do {                                                    \
 
 #define PPMGR2_CANVAS_INDEX_SRC (PPMGR2_CANVAS_INDEX + 3)
 
+struct v4l2q_s {
+       int rp;
+       int wp;
+       int size;
+       int pre_rp;
+       int pre_wp;
+       struct v4l2_buffer **pool;
+};
+
+static inline void v4l2q_lookup_start(struct v4l2q_s *q)
+{
+       q->pre_rp = q->rp;
+       q->pre_wp = q->wp;
+}
+static inline void v4l2q_lookup_end(struct v4l2q_s *q)
+{
+       q->rp = q->pre_rp;
+       q->wp = q->pre_wp;
+}
+
+static inline void v4l2q_init(struct v4l2q_s *q, u32 size,
+               struct v4l2_buffer **pool)
+{
+       q->rp = q->wp = 0;
+       q->size = size;
+       q->pool = pool;
+}
+
+static inline bool v4l2q_empty(struct v4l2q_s *q)
+{
+       return q->rp == q->wp;
+}
+
+static inline void v4l2q_push(struct v4l2q_s *q, struct v4l2_buffer *vf)
+{
+       int wp = q->wp;
+
+       /*ToDo*/
+       smp_mb();
+
+       q->pool[wp] = vf;
+
+       /*ToDo*/
+       smp_wmb();
+
+       q->wp = (wp == (q->size - 1)) ? 0 : (wp + 1);
+}
+
+static inline struct v4l2_buffer *v4l2q_pop(struct v4l2q_s *q)
+{
+       struct v4l2_buffer *vf;
+       int rp;
+
+       if (v4l2q_empty(q))
+               return NULL;
+
+       rp = q->rp;
+
+       /*ToDo*/
+       smp_rmb();
+
+       vf = q->pool[rp];
+
+       /*ToDo*/
+       smp_mb();
+
+       q->rp = (rp == (q->size - 1)) ? 0 : (rp + 1);
+
+       return vf;
+}
+
+static inline struct v4l2_buffer *v4l2q_peek(struct v4l2q_s *q)
+{
+       return (v4l2q_empty(q)) ? NULL : q->pool[q->rp];
+}
+
+static inline int v4l2q_level(struct v4l2q_s *q)
+{
+       int level = q->wp - q->rp;
+
+       if (level < 0)
+               level += q->size;
+
+       return level;
+}
+
 /* ------------------------------------------------------------------
  * Basic structures
  * ------------------------------------------------------------------
@@ -89,7 +175,6 @@ struct ionvideo_fmt {
 /* buffer for one video frame */
 struct ionvideo_buffer {
        /* common v4l buffer stuff -- must be first */
-       struct vb2_buffer vb;
        struct list_head list;
        const struct ionvideo_fmt *fmt;
        u64 pts;
@@ -131,6 +216,35 @@ struct ppmgr2_device {
 
 #define ION_VF_RECEIVER_NAME_SIZE 32
 
+#define ION_ACTIVE 0
+#define ION_INACTIVE_REQ 1
+#define ION_INACTIVE 2
+
+struct ion_buffer {
+       struct kref ref;
+       union {
+               struct rb_node node;
+               struct list_head list;
+       };
+       struct ion_device *dev;
+       struct ion_heap *heap;
+       unsigned long flags;
+       unsigned long private_flags;
+       size_t size;
+       void *priv_virt;
+       struct mutex lock;
+       int kmap_cnt;
+       void *vaddr;
+       int dmap_cnt;
+       struct sg_table *sg_table;
+       struct page **pages;
+       struct list_head vmas;
+       /* used to track orphaned buffers */
+       int handle_count;
+       char task_comm[TASK_COMM_LEN];
+       pid_t pid;
+};
+
 struct ionvideo_dev {
        struct list_head ionvideo_devlist;
        struct v4l2_device v4l2_dev;
@@ -154,7 +268,6 @@ struct ionvideo_dev {
        const struct ionvideo_fmt *fmt;
        unsigned int width, height;
        unsigned int c_width, c_height;
-       struct vb2_queue vb_vidq;
        unsigned int field_count;
 
        unsigned int pixelsize;
@@ -179,6 +292,16 @@ struct ionvideo_dev {
        bool mapped;
        bool thread_stopped;
        int vf_wait_cnt;
+       int active_state;
+       struct completion inactive_done;
+
+       struct v4l2q_s input_queue;
+       struct v4l2q_s output_queue;
+       struct v4l2_buffer *ionvideo_input_queue[IONVIDEO_POOL_SIZE + 1];
+       struct v4l2_buffer *ionvideo_output_queue[IONVIDEO_POOL_SIZE + 1];
+       struct mutex mutex_input;
+       struct mutex mutex_output;
+       struct v4l2_buffer ionvideo_input[IONVIDEO_POOL_SIZE + 1];
 };
 
 unsigned int get_ionvideo_debug(void);
@@ -196,4 +319,8 @@ void ppmgr2_set_mirror(struct ppmgr2_device *ppd, int mirror);
 void ppmgr2_set_paint_mode(struct ppmgr2_device *ppd, int paint_mode);
 int v4l_to_ge2d_format(int v4l2_format);
 
+#define IONVIDEO_IOC_MAGIC  'I'
+#define IONVIDEO_IOCTL_ALLOC_ID   _IOW(IONVIDEO_IOC_MAGIC, 0x00, int)
+#define IONVIDEO_IOCTL_FREE_ID    _IOW(IONVIDEO_IOC_MAGIC, 0x01, int)
+
 #endif
diff --git a/drivers/amlogic/media/video_processor/ionvideo/videobuf2-ion.c b/drivers/amlogic/media/video_processor/ionvideo/videobuf2-ion.c
deleted file mode 100644 (file)
index 2039af4..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * drivers/amlogic/media/video_processor/ionvideo/videobuf2-ion.c
- *
- * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- */
-
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-memops.h>
-
-/*#include <asm/mach/map.h>*/
-#include <ion.h>
-#include "ion_priv.h"
-#include "videobuf2-ion.h"
-
-struct vb2_ion_buf {
-       void *vaddr;
-       struct page **pages;
-       struct vm_area_struct *vma;
-       int write;
-       unsigned long size;
-       unsigned int n_pages;
-       atomic_t refcount;
-       struct vb2_vmarea_handler handler;
-       struct dma_buf *dbuf;
-};
-
-static void vb2_ion_put(void *buf_priv);
-
-#ifdef IONVIDEO_DEBUG
-static void *vb2_ion_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_flags)
-{
-       struct vb2_ion_buf *buf;
-
-       buf = kzalloc(sizeof(*buf), GFP_KERNEL | gfp_flags);
-       if (!buf)
-               return NULL;
-
-       buf->size = size;
-       buf->vaddr = vmalloc_user(buf->size);
-       buf->handler.refcount = &buf->refcount;
-       buf->handler.put = vb2_ion_put;
-       buf->handler.arg = buf;
-
-       if (!buf->vaddr) {
-               pr_debug("ion of size %ld failed\n", buf->size);
-               kfree(buf);
-               return NULL;
-       }
-
-       atomic_inc(&buf->refcount);
-       return buf;
-}
-#endif
-
-static void vb2_ion_put(void *buf_priv)
-{
-       struct vb2_ion_buf *buf = buf_priv;
-
-       if (atomic_dec_and_test(&buf->refcount)) {
-               vfree(buf->vaddr);
-               kfree(buf);
-       }
-}
-
-#ifdef IONVIDEO_DEBUG
-static void *vb2_ion_get_userptr(void *alloc_ctx, unsigned long vaddr,
-                                       unsigned long size, int write)
-{
-       struct vb2_ion_buf *buf;
-       unsigned long first, last;
-       int n_pages, offset;
-       struct vm_area_struct *vma;
-       dma_addr_t physp;
-
-       buf = kzalloc(sizeof(*buf), GFP_KERNEL);
-       if (!buf)
-               return NULL;
-
-       buf->write = write;
-       offset = vaddr & ~PAGE_MASK;
-       buf->size = size;
-
-       vma = find_vma(current->mm, vaddr);
-       if (vma && (vma->vm_flags & VM_PFNMAP) && (vma->vm_pgoff)) {
-#ifdef IONVIDEO_DEBUG
-               if (vb2_get_contig_userptr(vaddr, size, &vma, &physp))
-                       goto fail_pages_array_alloc;
-#endif
-               buf->vma = vma;
-               buf->vaddr = ioremap_nocache(physp, size);
-               if (!buf->vaddr)
-                       goto fail_pages_array_alloc;
-       } else {
-               first = vaddr >> PAGE_SHIFT;
-               last = (vaddr + size - 1) >> PAGE_SHIFT;
-               buf->n_pages = last - first + 1;
-               buf->pages = kcalloc(buf->n_pages, sizeof(struct page *),
-                                       GFP_KERNEL);
-               if (!buf->pages)
-                       goto fail_pages_array_alloc;
-
-               /* current->mm->mmap_sem is taken by videobuf2 core */
-#ifdef IONVIDEO_DEBUG
-               n_pages = get_user_pages(current, current->mm,
-                                               vaddr & PAGE_MASK, buf->n_pages,
-                                               write, 1, /* force */
-                                               buf->pages, NULL);
-#endif
-               if (n_pages != buf->n_pages)
-                       goto fail_get_user_pages;
-
-               buf->vaddr = vm_map_ram(buf->pages, buf->n_pages, -1,
-                                       PAGE_KERNEL);
-               if (!buf->vaddr)
-                       goto fail_get_user_pages;
-       }
-
-       buf->vaddr += offset;
-       return buf;
-
-fail_get_user_pages:
-       pr_debug("get_user_pages requested/got: %d/%d]\n", n_pages,
-                       buf->n_pages);
-       while (--n_pages >= 0)
-               put_page(buf->pages[n_pages]);
-       kfree(buf->pages);
-
-fail_pages_array_alloc: kfree(buf);
-
-       return NULL;
-}
-#endif
-
-static void vb2_ion_put_userptr(void *buf_priv)
-{
-       struct vb2_ion_buf *buf = buf_priv;
-       unsigned long vaddr = (unsigned long)buf->vaddr & PAGE_MASK;
-       unsigned int i;
-
-       if (buf->pages) {
-               if (vaddr)
-                       vm_unmap_ram((void *)vaddr, buf->n_pages);
-               for (i = 0; i < buf->n_pages; ++i) {
-                       if (buf->write)
-                               set_page_dirty_lock(buf->pages[i]);
-                       put_page(buf->pages[i]);
-               }
-               kfree(buf->pages);
-       } else {
-#ifdef IONVIDEO_DEBUG
-               if (buf->vma)
-                       vb2_put_vma(buf->vma);
-#endif
-               iounmap(buf->vaddr);
-       }
-       kfree(buf);
-}
-
-static void *vb2_ion_vaddr(void *buf_priv)
-{
-       struct vb2_ion_buf *buf = buf_priv;
-
-       if (!buf->vaddr) {
-               pr_err("Address of an unallocated plane requested");
-               pr_err("or cannot map user pointer\n");
-               return NULL;
-       }
-
-       return buf->vaddr;
-}
-
-static unsigned int vb2_ion_num_users(void *buf_priv)
-{
-       struct vb2_ion_buf *buf = buf_priv;
-
-       return atomic_read(&buf->refcount);
-}
-
-static int vb2_ion_mmap(void *buf_priv, struct vm_area_struct *vma)
-{
-       struct vb2_ion_buf *buf = buf_priv;
-       int ret;
-
-       pr_info("11vb2_ion_mmap\n");
-       if (!buf) {
-               pr_err("No memory to map\n");
-               return -EINVAL;
-       }
-
-       ret = remap_vmalloc_range(vma, buf->vaddr, 0);
-       if (ret) {
-               pr_err("Remapping ion memory, error: %d\n", ret);
-               return ret;
-       }
-
-       /*
-        * Make sure that vm_areas for 2 buffers won't be merged together
-        */
-       vma->vm_flags |= VM_DONTEXPAND;
-
-       /*
-        * Use common vm_area operations to track buffer refcount.
-        */
-       vma->vm_private_data = &buf->handler;
-       vma->vm_ops = &vb2_common_vm_ops;
-
-       vma->vm_ops->open(vma);
-       pr_info("22vb2_ion_mmap\n");
-       return 0;
-}
-
-/*********************************************/
-/*       callbacks for DMABUF buffers        */
-/*********************************************/
-
-static int vb2_ion_map_dmabuf(void *mem_priv)
-{
-       /* struct vb2_ion_buf *buf = mem_priv; */
-       /*  */
-       /* struct ion_buffer *buffer = buf->dbuf->priv; */
-       /* int mtype = MT_MEMORY_NONCACHED; */
-       /*  */
-       /* if (buffer->flags & ION_FLAG_CACHED) */
-       /* mtype = MT_MEMORY; */
-#if 0
-       buf->vaddr = __arm_ioremap(buffer->priv_phys, buffer->size, mtype);
-
-       return buf->vaddr ? 0 : -EFAULT;
-#else
-       return 0;
-#endif
-}
-
-static void vb2_ion_unmap_dmabuf(void *mem_priv)
-{
-       /* struct vb2_ion_buf *buf = mem_priv; */
-
-#if 0
-       __arm_iounmap(buf->vaddr);
-
-       buf->vaddr = NULL;
-#endif
-}
-
-static void vb2_ion_detach_dmabuf(void *mem_priv)
-{
-       struct vb2_ion_buf *buf = mem_priv;
-
-       if (buf->vaddr)
-               dma_buf_vunmap(buf->dbuf, buf->vaddr);
-
-       kfree(buf);
-}
-
-#ifdef IONVIDEO_DEBUG
-static void *vb2_ion_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
-                                       unsigned long size, int write)
-{
-       struct vb2_ion_buf *buf;
-
-       if (dbuf->size < size)
-               return ERR_PTR(-EFAULT);
-
-       buf = kzalloc(sizeof(*buf), GFP_KERNEL);
-       if (!buf)
-               return ERR_PTR(-ENOMEM);
-
-       buf->dbuf = dbuf;
-       buf->write = write;
-       buf->size = size;
-
-       return buf;
-}
-#endif
-
-static void *vb2_ion_cookie(void *buf_priv)
-{
-       struct vb2_ion_buf *buf = buf_priv;
-
-       struct ion_buffer *buffer = buf->dbuf->priv;
-#if 0
-       return (void *)buffer->priv_phys;
-#endif
-       struct sg_table *table = buffer->priv_virt;
-       struct page *page = sg_page(table->sgl);
-
-       ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page));
-
-       return (void *)paddr;
-}
-
-const struct vb2_mem_ops vb2_ion_memops = {
-#ifdef IONVIDEO_DEBUG
-       .alloc = vb2_ion_alloc,
-#endif
-       .put = vb2_ion_put,
-#ifdef IONVIDEO_DEBUG
-       .get_userptr = vb2_ion_get_userptr,
-#endif
-       .put_userptr = vb2_ion_put_userptr,
-       .map_dmabuf = vb2_ion_map_dmabuf,
-       .unmap_dmabuf = vb2_ion_unmap_dmabuf,
-#ifdef IONVIDEO_DEBUG
-       .attach_dmabuf = vb2_ion_attach_dmabuf,
-#endif
-       .detach_dmabuf = vb2_ion_detach_dmabuf,
-       .vaddr = vb2_ion_vaddr,
-       .mmap = vb2_ion_mmap,
-       .num_users = vb2_ion_num_users,
-       .cookie = vb2_ion_cookie,
-};
-EXPORT_SYMBOL_GPL(vb2_ion_memops);
-
-MODULE_DESCRIPTION("ion memory handling routines for videobuf2");
-MODULE_AUTHOR("Shuai Cao <shuai.cao@amlogic.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/amlogic/media/video_processor/ionvideo/videobuf2-ion.h b/drivers/amlogic/media/video_processor/ionvideo/videobuf2-ion.h
deleted file mode 100644 (file)
index b152557..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * drivers/amlogic/media/video_processor/ionvideo/videobuf2-ion.h
- *
- * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- */
-
-#ifndef _MEDIA_VIDEOBUF2_ION_H
-#define _MEDIA_VIDEOBUF2_ION_H
-
-#include <media/videobuf2-core.h>
-
-extern const struct vb2_mem_ops vb2_ion_memops;
-
-#endif