media: isp: migrate isp driver to videobuf2
authorJacob Chen <cc@rock-chips.com>
Mon, 10 Jul 2017 02:43:08 +0000 (10:43 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Thu, 13 Jul 2017 03:33:10 +0000 (11:33 +0800)
Verify the functionality of isp driver with
sensor ov7750.
V4l2n or gstreamer is suitable for test.

Change-Id: I4f0cf68b84f4909dd1c132ec3506777f39d487ee
Signed-off-by: Jacob Chen <cc@rock-chips.com>
drivers/media/platform/rk-isp10/Kconfig
drivers/media/platform/rk-isp10/cif_isp10.c
drivers/media/platform/rk-isp10/cif_isp10.h
drivers/media/platform/rk-isp10/cif_isp10_img_src_v4l2-subdev.c
drivers/media/platform/rk-isp10/cif_isp10_isp.c
drivers/media/platform/rk-isp10/cif_isp10_isp.h
drivers/media/platform/rk-isp10/cif_isp10_pltfrm.c
drivers/media/platform/rk-isp10/cif_isp10_pltfrm.h
drivers/media/platform/rk-isp10/cif_isp10_v4l2.c

index bb2679b79677a0d3cd6463701cb86aac5f41e024..a51aac2410a236e9c96cabc1dbf7d68bab40af66 100644 (file)
@@ -1,9 +1,10 @@
 config VIDEO_RK_CIF_ISP10
        tristate "Rockchip cif isp10 camera sensors"
        depends on VIDEO_V4L2 && I2C
+       select VIDEOBUF2_CORE
        select VIDEOBUF_GEN
-       select VIDEOBUF_DMA_CONTIG
-       select VIDEOBUF_VMALLOC
+       select VIDEOBUF2_DMA_SG
+       select VIDEOBUF2_VMALLOC
        default n
 
        ---help---
index 3f1dd33a225d61bc2cca4697d9c2b496a5668ac6..dd44afe2bedf55c42dfc9f97c6deffd0be6b3251 100644 (file)
@@ -15,7 +15,8 @@
  */
 
 #include <linux/videodev2.h>
-#include <media/videobuf-dma-contig.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-dma-sg.h>
 #include "cif_isp10_regs.h"
 #include "cif_isp10.h"
 #include <linux/pm_runtime.h>
@@ -157,6 +158,7 @@ static const unsigned char uvq_table_base_zigzag[] = {
 
 static struct cif_isp10_fmt cif_isp10_output_format[] = {
 /* ************* YUV422 ************* */
+// index 0
 {
        .name           = "YUV422-Interleaved",
        .fourcc = V4L2_PIX_FMT_YUYV,
@@ -165,6 +167,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .rotation = false,
        .overlay = false,
 },
+// index 1
 {
        .name           = "YUV422-Interleaved",
        .fourcc = V4L2_PIX_FMT_YUYV,
@@ -173,6 +176,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .rotation = false,
        .overlay = false,
 },
+// index 2
 {
        .name           = "YVU422-Interleaved",
        .fourcc = V4L2_PIX_FMT_UYVY,
@@ -181,6 +185,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .rotation = false,
        .overlay = false,
 },
+// index 3
 {
        .name           = "YUV422-Planar",
        .fourcc = V4L2_PIX_FMT_YUV422P,
@@ -189,6 +194,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .rotation = false,
        .overlay = false,
 },
+// index 4
 {
        .name           = "YUV422-Semi-Planar",
        .fourcc = V4L2_PIX_FMT_NV16,
@@ -198,6 +204,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .overlay = false,
 },
 /* ************* YUV420 ************* */
+// index 5
 {
        .name           = "YUV420-Planar",
        .fourcc = V4L2_PIX_FMT_YUV420,
@@ -206,6 +213,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .rotation = false,
        .overlay = false,
 },
+// index 6
 {
        .name           = "YUV420-Planar",
        .fourcc = V4L2_PIX_FMT_YUV420,
@@ -214,6 +222,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .rotation = false,
        .overlay = false,
 },
+// index 7
 {
        .name           = "YVU420-Planar",
        .fourcc = V4L2_PIX_FMT_YVU420,
@@ -222,6 +231,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .rotation = false,
        .overlay = false,
 },
+// index 8
 {
        .name           = "YUV420-Semi-Planar",
        .fourcc = V4L2_PIX_FMT_NV12,
@@ -230,6 +240,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .rotation = false,
        .overlay = false,
 },
+// index 9
 {
        .name           = "YVU420-Semi-Planar",
        .fourcc = V4L2_PIX_FMT_NV21,
@@ -239,6 +250,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .overlay = false,
 },
 /* ************* YUV400 ************* */
+// index 10
 {
        .name           = "YVU400-Grey-Planar",
        .fourcc = V4L2_PIX_FMT_GREY,
@@ -248,6 +260,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .overlay = false,
 },
 /* ************* YUV444 ************* */
+// index 11
 {
        .name           = "YVU444-Planar",
        .fourcc = V4L2_PIX_FMT_YUV444,
@@ -256,6 +269,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .rotation = false,
        .overlay = false,
 },
+// index 12
 {
        .name           = "YVU444-Semi-Planar",
        .fourcc = V4L2_PIX_FMT_NV24,
@@ -265,6 +279,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .overlay = false,
 },
 /* ************* JPEG ************* */
+// index 13
 {
        .name           = "JPEG",
        .fourcc = V4L2_PIX_FMT_JPEG,
@@ -274,6 +289,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .overlay = false,
 },
 /* ************ RGB565 *********** */
+// index 14
 {
        .name       = "RGB565",
        .fourcc = V4L2_PIX_FMT_RGB565,
@@ -283,6 +299,7 @@ static struct cif_isp10_fmt cif_isp10_output_format[] = {
        .overlay = false,
 },
 /* ************ SGRBG8 *********** */
+// index 15
 {
        .name       = "SGRBG8",
        .fourcc = V4L2_PIX_FMT_SGRBG8,
@@ -1134,6 +1151,7 @@ static int cif_isp10_img_src_select_strm_fmt(
                        img_src_width = strm_fmt_desc.min_frmsize.width;
                        img_src_height = strm_fmt_desc.min_frmsize.height;
                }
+
                if ((img_src_width >= target_width) &&
                        (img_src_height >= target_height)) {
                        u32 diff = abs(
@@ -1192,6 +1210,23 @@ static int cif_isp10_img_src_select_strm_fmt(
                                best_diff = diff;
                                matching_format_found = true;
                        }
+               // FIXME::GST set fomat(any@32768x32768) failed, force pass
+               } else {
+                       request_strm_fmt.frm_fmt.width =
+                               strm_fmt_desc.min_frmsize.width;
+                       request_strm_fmt.frm_fmt.height =
+                               strm_fmt_desc.min_frmsize.height;
+                       request_strm_fmt.frm_fmt.std_id =
+                               strm_fmt_desc.std_id;
+                       request_strm_fmt.frm_fmt.pix_fmt =
+                               strm_fmt_desc.pix_fmt;
+                       request_strm_fmt.frm_intrvl.numerator =
+                               strm_fmt_desc.min_intrvl.numerator;
+                       request_strm_fmt.frm_intrvl.denominator =
+                               strm_fmt_desc.min_intrvl.denominator;
+                       request_strm_fmt.frm_fmt.defrect =
+                               strm_fmt_desc.defrect;
+                       matching_format_found = true;
                }
        }
 
@@ -1913,7 +1948,6 @@ static int cif_isp10_config_mipi(
        mipi_ctrl =
                CIF_MIPI_CTRL_NUM_LANES(
                        dev->config.cam_itf.cfg.mipi.nb_lanes - 1) |
-               CIF_MIPI_CTRL_ERR_SOT_HS_ENA |
                CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP |
                CIF_MIPI_CTRL_SHUTDOWNLANES(shutdown_lanes) |
                CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_ENA |
@@ -2585,8 +2619,9 @@ static int cif_isp10_config_jpeg_enc(
                break;
        default:
                cif_isp10_pltfrm_pr_err(NULL,
-                       "format %s not supported as input for JPEG encoder\n",
-                       cif_isp10_pix_fmt_string(inp_fmt->pix_fmt));
+                       "format %s (%.8x) not supported as input for JPEG encoder\n",
+                       cif_isp10_pix_fmt_string(inp_fmt->pix_fmt),
+                       inp_fmt->pix_fmt);
                WARN_ON(1);
                break;
        }
@@ -3247,7 +3282,7 @@ static int cif_isp10_config_cif(
 
                cif_id = cif_ioread32(dev->config.base_addr + CIF_VI_ID);
                dev->config.out_of_buffer_stall =
-                               CIF_ISP10_ALWAYS_STALL_ON_NO_BUFS;
+                               CIF_ISP10_ALWAYS_STALL_ON_NO_BUFS ? 1 : 0;
 
                cif_isp10_pltfrm_pr_dbg(dev->dev,
                        "CIF_ID 0x%08x\n", cif_id);
@@ -3377,6 +3412,13 @@ static void cif_isp10_init_stream(
        enum cif_isp10_stream_id stream_id)
 {
        struct cif_isp10_stream *stream = NULL;
+       struct cif_isp10_frm_fmt frm_fmt;
+
+       frm_fmt.pix_fmt = CIF_YUV422I;
+       frm_fmt.width = dev->config.img_src_output.frm_fmt.width;
+       frm_fmt.height = dev->config.img_src_output.frm_fmt.height;
+       frm_fmt.stride = dev->config.img_src_output.frm_fmt.stride;
+       frm_fmt.quantization = 0;
 
        switch (stream_id) {
        case CIF_ISP10_STREAM_SP:
@@ -3384,6 +3426,16 @@ static void cif_isp10_init_stream(
                dev->config.sp_config.rsz_config.ycflt_adjust = false;
                dev->config.sp_config.rsz_config.ism_adjust = false;
                dev->config.mi_config.sp.busy = false;
+
+               // init default formats
+               dev->config.mi_config.sp.output = frm_fmt;
+               dev->config.mi_config.sp.llength =
+                       cif_isp10_calc_llength(
+                       frm_fmt.width,
+                       frm_fmt.stride,
+                       frm_fmt.pix_fmt);
+
+               dev->sp_stream.updt_cfg = true;
                break;
        case CIF_ISP10_STREAM_MP:
                stream = &dev->mp_stream;
@@ -3395,10 +3447,23 @@ static void cif_isp10_init_stream(
                dev->config.mp_config.rsz_config.ycflt_adjust = false;
                dev->config.mp_config.rsz_config.ism_adjust = false;
                dev->config.mi_config.mp.busy = false;
+
+               // init default formats
+               dev->config.mi_config.mp.output = frm_fmt;
+               dev->config.mi_config.mp.output.stride = frm_fmt.stride;
+
+               dev->config.mi_config.mp.llength =
+                       cif_isp10_calc_llength(
+                               frm_fmt.width,
+                               frm_fmt.stride,
+                               frm_fmt.pix_fmt);
+
+               dev->mp_stream.updt_cfg = true;
                break;
        case CIF_ISP10_STREAM_DMA:
                stream = &dev->dma_stream;
                dev->config.mi_config.dma.busy = false;
+               dev->dma_stream.updt_cfg = false;
                break;
        default:
                cif_isp10_pltfrm_pr_err(NULL,
@@ -3410,12 +3475,17 @@ static void cif_isp10_init_stream(
        INIT_LIST_HEAD(&stream->buf_queue);
        stream->next_buf = NULL;
        stream->curr_buf = NULL;
-       stream->updt_cfg = false;
        stream->stop = false;
        stream->stall = false;
 
        cif_isp10_pltfrm_event_clear(dev->dev, &stream->done);
-       stream->state = CIF_ISP10_STATE_INACTIVE;
+
+       if (stream->updt_cfg) {
+               stream->state = CIF_ISP10_STATE_READY;
+               cif_isp10_img_src_select_strm_fmt(dev);
+       } else {
+               stream->state = CIF_ISP10_STATE_INACTIVE;
+       }
 }
 
 static int cif_isp10_jpeg_gen_header(
@@ -3900,6 +3970,10 @@ err:
 static void cif_isp10_dma_next_buff(
        struct cif_isp10_device *dev)
 {
+#ifdef CIF_ISP10_MODE_DMA_SG
+       struct sg_table *sgt = NULL;
+#endif
+
        cif_isp10_pltfrm_pr_dbg(NULL, "\n");
 
        if (!list_empty(&dev->dma_stream.buf_queue) &&
@@ -3908,12 +3982,21 @@ static void cif_isp10_dma_next_buff(
                        WARN_ON(1);
                dev->dma_stream.curr_buf =
                        list_first_entry(&dev->dma_stream.buf_queue,
-                               struct videobuf_buffer, queue);
+                               struct cif_isp10_buffer, queue);
                list_del(&dev->dma_stream.curr_buf->queue);
-               dev->dma_stream.curr_buf->state = VIDEOBUF_ACTIVE;
+
+#ifdef CIF_ISP10_MODE_DMA_CONTIG
+               dev->config.mi_config.dma.next_buff_addr =
+                       vb2_dma_contig_plane_dma_addr(
+                               &dev->dma_stream.curr_buf->vb.vb2_buf, 0);
+#endif
+
+#ifdef CIF_ISP10_MODE_DMA_SG
+               sgt = vb2_dma_sg_plane_desc(
+                               &dev->dma_stream.curr_buf->vb.vb2_buf, 0);
                dev->config.mi_config.dma.next_buff_addr =
-                       videobuf_to_dma_contig(
-                               dev->dma_stream.curr_buf);
+                       sg_dma_address(sgt->sgl);
+#endif
                cif_isp10_mi_update_buff_addr(dev,
                        CIF_ISP10_STREAM_DMA);
                dev->config.mi_config.dma.busy = true;
@@ -3955,8 +4038,7 @@ static void cif_isp10_dma_ready(
                cif_isp10_pltfrm_pr_err(dev->dev,
                                        "dma icr err: 0x%x\n",
                                        mi_mis_tmp);
-       dev->dma_stream.curr_buf->state = VIDEOBUF_DONE;
-       wake_up(&dev->dma_stream.curr_buf->done);
+       wake_up(&dev->dma_stream.curr_buf->vb.vb2_buf.vb2_queue->done_wq);
        dev->dma_stream.curr_buf = NULL;
        dev->config.mi_config.dma.busy = false;
        cif_isp10_pltfrm_event_signal(dev->dev, &dev->dma_stream.done);
@@ -3967,7 +4049,17 @@ static int cif_isp10_mi_frame_end(
        enum cif_isp10_stream_id stream_id)
 {
        struct cif_isp10_stream *stream = NULL;
+       u32 cur_buff_addr = -1;
        u32 *next_buff_addr = NULL;
+       struct vb2_buffer *vb2_buf;
+       dma_addr_t tmp_addr;
+#ifdef CIF_ISP10_MODE_DMA_SG
+       struct sg_table *sgt = NULL;
+       struct scatterlist *sg;
+       dma_addr_t tmp_phy_addr;
+       int i;
+#endif
+
        CIF_ISP10_PLTFRM_MEM_IO_ADDR y_base_addr;
        int (*update_mi)(
                struct cif_isp10_device *dev);
@@ -4034,19 +4126,28 @@ static int cif_isp10_mi_frame_end(
                !(dev->config.jpeg_config.enable &&
                (stream_id == CIF_ISP10_STREAM_MP))) {
                stream->stall = dev->config.out_of_buffer_stall;
-       } else if ((stream->next_buf) &&
-               (videobuf_to_dma_contig(stream->next_buf) !=
-                       cif_ioread32(y_base_addr))) {
-               cif_isp10_pltfrm_pr_warn(dev->dev,
-                       "%s buffer queue is not advancing (0x%08x/0x%08x)\n",
-                       cif_isp10_stream_id_string(stream_id),
-                       (stream_id & CIF_ISP10_STREAM_MP) ?
-                               cif_ioread32(dev->config.base_addr +
-                               CIF_MI_MP_Y_BASE_AD_INIT) :
-                               cif_ioread32(dev->config.base_addr +
-                               CIF_MI_SP_Y_BASE_AD_INIT),
-                       cif_ioread32(y_base_addr));
-               stream->stall = true;
+       } else if ((stream->next_buf)) {
+#ifdef CIF_ISP10_MODE_DMA_CONTIG
+               tmp_addr = vb2_dma_contig_plane_dma_addr(
+                       &stream->next_buf->vb.vb2_buf, 0);
+#endif
+#ifdef CIF_ISP10_MODE_DMA_SG
+               sgt = vb2_dma_sg_plane_desc(
+                       &stream->next_buf->vb.vb2_buf, 0);
+               tmp_addr = sg_dma_address(sgt->sgl);
+#endif
+               if (tmp_addr != cif_ioread32(y_base_addr)) {
+                       cif_isp10_pltfrm_pr_warn(dev->dev,
+                               "%s buffer queue is not advancing (0x%08x/0x%08x)\n",
+                               cif_isp10_stream_id_string(stream_id),
+                               (stream_id & CIF_ISP10_STREAM_MP) ?
+                                       cif_ioread32(dev->config.base_addr +
+                                       CIF_MI_MP_Y_BASE_AD_INIT) :
+                                       cif_ioread32(dev->config.base_addr +
+                                       CIF_MI_SP_Y_BASE_AD_INIT),
+                               cif_ioread32(y_base_addr));
+                       stream->stall = true;
+               }
        }
 
        if (!stream->stall) {
@@ -4060,8 +4161,8 @@ static int cif_isp10_mi_frame_end(
                        (stream->next_buf)) {
                        bool wake_now;
 
-                       stream->curr_buf->field_count = dev->isp_dev.frame_id;
-                       stream->curr_buf->state = VIDEOBUF_DONE;
+                       vb2_buf = &stream->curr_buf->vb.vb2_buf;
+                       vb2_buffer_done(vb2_buf, VB2_BUF_STATE_DONE);
                        wake_now = false;
 
                        if (stream->metadata.d && dev->isp_dev.streamon) {
@@ -4069,7 +4170,7 @@ static int cif_isp10_mi_frame_end(
 
                                metadata = (struct v4l2_buffer_metadata_s *)
                                        (stream->metadata.d +
-                                       stream->curr_buf->i *
+                                       stream->curr_buf->vb.vb2_buf.index *
                                        CAMERA_METADATA_LEN);
                                metadata->frame_id = dev->isp_dev.frame_id;
                                metadata->frame_t.vs_t = dev->isp_dev.vs_t;
@@ -4089,7 +4190,8 @@ static int cif_isp10_mi_frame_end(
                                                &dev->isp_dev;
                                        work->frame_id =
                                                dev->isp_dev.frame_id;
-                                       work->vb = stream->curr_buf;
+                                       work->vb =
+                                               &stream->curr_buf->vb.vb2_buf;
                                        work->stream_id = stream->id;
                                        if (!queue_work(dev->isp_dev.readout_wq,
                                                (struct work_struct *)work)) {
@@ -4111,7 +4213,8 @@ static int cif_isp10_mi_frame_end(
                        if (wake_now) {
                                cif_isp10_pltfrm_pr_dbg(NULL,
                                        "frame done\n");
-                               wake_up(&stream->curr_buf->done);
+                               vb2_buf = &stream->curr_buf->vb.vb2_buf;
+                               wake_up(&vb2_buf->vb2_queue->done_wq);
                        }
                        stream->curr_buf = NULL;
                }
@@ -4132,41 +4235,82 @@ static int cif_isp10_mi_frame_end(
                if (!list_empty(&stream->buf_queue)) {
                        stream->next_buf =
                                list_first_entry(&stream->buf_queue,
-                                       struct videobuf_buffer, queue);
+                                       struct cif_isp10_buffer, queue);
                        list_del(&stream->next_buf->queue);
-                       stream->next_buf->state = VIDEOBUF_ACTIVE;
-                       *next_buff_addr = videobuf_to_dma_contig(
-                               stream->next_buf);
+#ifdef CIF_ISP10_MODE_DMA_CONTIG
+                       *next_buff_addr = vb2_dma_contig_plane_dma_addr(
+                               &stream->next_buf->vb.vb2_buf, 0);
+#endif
+#ifdef CIF_ISP10_MODE_DMA_SG
+                       sgt = vb2_dma_sg_plane_desc(
+                               &stream->next_buf->vb.vb2_buf, 0);
+                       *next_buff_addr = sg_dma_address(sgt->sgl);
+#endif
                } else if (
-               !dev->config.out_of_buffer_stall ||
+               (!dev->config.out_of_buffer_stall ||
                (dev->config.jpeg_config.enable &&
-               (stream_id == CIF_ISP10_STREAM_MP))) {
-/*
- * If mi restart after switch off for buffer is empty,
- * mi may be restart failed. So mi write data to last
- * buffer, the last buffer isn't been release to user
- * until new buffer queue;
- *
- * if
- * *next_buff_addr = CIF_ISP10_INVALID_BUFF_ADDR;
- * mi will stop;
- */
+               (stream_id == CIF_ISP10_STREAM_MP))) &&
+               (stream->curr_buf)) {
+                       /*
+                        * If mi restart after switch off for buffer is empty,
+                        * mi may be restart failed. So mi write data to last
+                        * buffer, the last buffer isn't been release to user
+                        * until new buffer queue;
+                        *
+                        * if
+                        * *next_buff_addr = CIF_ISP10_INVALID_BUFF_ADDR;
+                        * mi will stop;
+                        */
+                       vb2_buf = &stream->curr_buf->vb.vb2_buf;
+#ifdef CIF_ISP10_MODE_DMA_CONTIG
                        *next_buff_addr =
-                       videobuf_to_dma_contig(
-                       stream->curr_buf);
+                               vb2_dma_contig_plane_dma_addr(vb2_buf, 0);
+#endif
+#ifdef CIF_ISP10_MODE_DMA_SG
+                       sgt = vb2_dma_sg_plane_desc(vb2_buf, 0);
+                       *next_buff_addr = sg_dma_address(sgt->sgl);
+#endif
                }
        }
        (void)update_mi(dev);
 
        stream->stall = false;
 
+       if (stream->curr_buf) {
+               // TODO::current vb2 buffer is null
+               if (!stream->curr_buf->vb.vb2_buf.planes[0].mem_priv) {
+                       cif_isp10_pltfrm_pr_err(dev->dev,
+                               "error isp buffer is null\n");
+                       return 0;
+               }
+
+#ifdef CIF_ISP10_MODE_DMA_CONTIG
+               cur_buff_addr = vb2_dma_contig_plane_dma_addr
+                       (&stream->curr_buf->vb.vb2_buf, 0);
+
+#endif
+#ifdef CIF_ISP10_MODE_DMA_SG
+               sgt = vb2_dma_sg_plane_desc(&stream->curr_buf->vb.vb2_buf, 0);
+               cur_buff_addr = sg_dma_address(sgt->sgl);
+
+               cif_isp10_pltfrm_pr_dbg(dev->dev,
+                       "current buffer scatter list: ");
+               for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+                       tmp_addr = sg_dma_address(sg);
+                       tmp_phy_addr = sg_phys(sg);
+                       cif_isp10_pltfrm_pr_dbg(dev->dev,
+                               "dma_addr: %pad  tmp_phy: %pad length: %.8x\n",
+                               &tmp_addr, &tmp_phy_addr, (int)sg_dma_len(sg));
+               }
+#endif
+       }
+
        cif_isp10_pltfrm_pr_dbg(dev->dev,
                "%s curr_buff: %d, 0x%08x next_buf: %d, 0x%x\n",
                cif_isp10_stream_id_string(stream_id),
-               (stream->curr_buf) ? stream->curr_buf->i : -1,
-               (stream->curr_buf) ? (int)videobuf_to_dma_contig
-               (stream->curr_buf) : -1,
-               (stream->next_buf) ? stream->next_buf->i : -1,
+               (stream->curr_buf) ? stream->curr_buf->vb.vb2_buf.index : -1,
+               cur_buff_addr,
+               (stream->next_buf) ? stream->next_buf->vb.vb2_buf.index : -1,
                *next_buff_addr);
 
        return 0;
@@ -4547,7 +4691,7 @@ static int cif_isp10_start(
        bool start_mp)
 {
        unsigned int ret;
-       struct videobuf_buffer *vb, *n;
+       struct vb2_buffer *vb, *n;
 
        cif_isp10_pltfrm_pr_dbg(dev->dev,
                "SP state = %s, MP state = %s, DMA state = %s, img_src state = %s, start_sp = %d, start_mp = %d\n",
@@ -4612,17 +4756,16 @@ static int cif_isp10_start(
                /* start sensor output! */
                dev->isp_dev.frame_id = 0;
                dev->isp_dev.frame_id_setexp = 0;
-               videobuf_queue_lock(&dev->isp_dev.vbq_stat);
+
                list_for_each_entry_safe(
-                       vb, n, &dev->isp_dev.vbq_stat.stream, queue) {
-                       if (vb->state == VIDEOBUF_DONE) {
-                               vb->field_count = -1;
+                       vb, n, &dev->isp_dev.stat, queued_entry) {
+                       if (vb->state == VB2_BUF_STATE_DONE) {
                                cif_isp10_pltfrm_pr_info(
                                        dev->dev,
-                                       "discard vb: %d\n", vb->i);
+                                       "discard vb: %d\n", vb->index);
                        }
                }
-               videobuf_queue_unlock(&dev->isp_dev.vbq_stat);
+               // spin_unlock_irq(&dev->isp_dev.lock);
 
                mutex_lock(&dev->img_src_exps.mutex);
                cif_isp10_img_src_ioctl(dev->img_src,
@@ -5199,7 +5342,7 @@ int cif_isp10_streamoff(
                (dev->sp_stream.state <= CIF_ISP10_STATE_INACTIVE)) {
                dev->isp_dev.input_width = 0;
                dev->isp_dev.input_height = 0;
-               dev->config.isp_config.ism_config.ism_en = 0;
+               dev->config.isp_config.ism_config.ism_en = false;
        }
 
        cif_isp10_pltfrm_pr_dbg(dev->dev,
@@ -5302,11 +5445,14 @@ int cif_isp10_s_fmt(
 
        switch (stream_id) {
        case CIF_ISP10_STREAM_SP:
-               return cif_isp10_s_fmt_sp(dev, strm_fmt, stride);
+               ret = cif_isp10_s_fmt_sp(dev, strm_fmt, stride);
+               break;
        case CIF_ISP10_STREAM_MP:
-               return cif_isp10_s_fmt_mp(dev, strm_fmt, stride);
+               ret = cif_isp10_s_fmt_mp(dev, strm_fmt, stride);
+               break;
        case CIF_ISP10_STREAM_DMA:
-               return cif_isp10_s_fmt_dma(dev, strm_fmt, stride);
+               ret = cif_isp10_s_fmt_dma(dev, strm_fmt, stride);
+               break;
        default:
                cif_isp10_pltfrm_pr_err(NULL,
                        "unknown/unsupported stream ID %d\n", stream_id);
@@ -5314,7 +5460,7 @@ int cif_isp10_s_fmt(
                goto err;
        }
 
-       return 0;
+       return ret;
 err:
        cif_isp10_pltfrm_pr_err(NULL,
                "failed with error %d\n", ret);
@@ -5485,7 +5631,6 @@ struct cif_isp10_device *cif_isp10_create(
        if (IS_ERR_VALUE(ret))
                goto err;
 
-       (void)cif_isp10_init(dev, CIF_ISP10_ALL_STREAMS);
        dev->pm_state = CIF_ISP10_PM_STATE_OFF;
        dev->sp_stream.state = CIF_ISP10_STATE_DISABLED;
        dev->sp_stream.id = CIF_ISP10_STREAM_SP;
@@ -5494,6 +5639,8 @@ struct cif_isp10_device *cif_isp10_create(
        dev->dma_stream.state = CIF_ISP10_STATE_DISABLED;
        dev->dma_stream.id = CIF_ISP10_STREAM_DMA;
        dev->config.mi_config.async_updt = 0;
+
+       (void)cif_isp10_init(dev, CIF_ISP10_ALL_STREAMS);
        cif_isp10_pltfrm_event_init(dev->dev, &dev->dma_stream.done);
        cif_isp10_pltfrm_event_init(dev->dev, &dev->sp_stream.done);
        cif_isp10_pltfrm_event_init(dev->dev, &dev->mp_stream.done);
@@ -5534,9 +5681,15 @@ int cif_isp10_s_input(
        enum cif_isp10_inp inp;
 
        cif_isp10_pltfrm_pr_dbg(dev->dev,
-               "setting input to %s\n",
+               "setting input to %s, [w-h]=[%d-%d], defrect=[%d-%d-%d-%d]\n",
                cif_isp10_inp_string(
-               cif_isp10_input_index2inp(dev, input)));
+               cif_isp10_input_index2inp(dev, input)),
+               dev->config.img_src_output.frm_fmt.width,
+               dev->config.img_src_output.frm_fmt.height,
+               dev->config.img_src_output.frm_fmt.defrect.left,
+               dev->config.img_src_output.frm_fmt.defrect.top,
+               dev->config.img_src_output.frm_fmt.defrect.width,
+               dev->config.img_src_output.frm_fmt.defrect.height);
 
        if (input >= dev->img_src_cnt + CIF_ISP10_INP_DMA_CNT()) {
                cif_isp10_pltfrm_pr_err(NULL,
@@ -5691,7 +5844,7 @@ int cif_isp10_s_isp_metadata(
 {
        unsigned int stream_id =
                readout_work->stream_id;
-       struct videobuf_buffer *vb =
+       struct vb2_buffer *vb =
                readout_work->vb;
        struct cif_isp10_stream *strm_dev = NULL;
        struct v4l2_buffer_metadata_s *metadata;
@@ -5713,7 +5866,7 @@ int cif_isp10_s_isp_metadata(
        if (vb && strm_dev->metadata.d) {
                metadata = (struct v4l2_buffer_metadata_s *)
                        (strm_dev->metadata.d +
-                       vb->i * CAMERA_METADATA_LEN);
+                       vb->index * CAMERA_METADATA_LEN);
 
                metadata->frame_id = readout_work->frame_id;
                isp_last =
@@ -5755,7 +5908,7 @@ int cif_isp10_s_isp_metadata(
        if (vb) {
                cif_isp10_pltfrm_pr_dbg(NULL,
                                "frame done\n");
-               wake_up(&vb->done);
+               wake_up(&vb->vb2_queue->done_wq);
        }
 
        return 0;
@@ -5850,7 +6003,8 @@ int cif_isp10_get_target_frm_size(
                *target_height = dev->config.mi_config.mp.output.height;
        } else {
                cif_isp10_pltfrm_pr_err(dev->dev,
-                       "cannot get target frame size, no path ready\n");
+                       "cannot get target frame size, no path ready, state(mp[%d]-sp[%d])\n",
+                       dev->mp_stream.state, dev->sp_stream.state);
                return -EFAULT;
        }
        return 0;
@@ -5910,7 +6064,7 @@ err:
 int cif_isp10_calc_min_out_buff_size(
        struct cif_isp10_device *dev,
        enum cif_isp10_stream_id stream_id,
-       u32 *size)
+       u32 *size, bool payload)
 {
        int ret = 0;
        enum cif_isp10_pix_fmt pix_fmt;
@@ -5955,8 +6109,8 @@ int cif_isp10_calc_min_out_buff_size(
                "mi_path->llength: 0x%x\n",
                mi_path->llength);
 
-       if (CIF_ISP10_PIX_FMT_IS_RAW_BAYER(pix_fmt) &&
-               CIF_ISP10_PIX_FMT_GET_BPP(pix_fmt) > 8)
+       if ((CIF_ISP10_PIX_FMT_IS_RAW_BAYER(pix_fmt) &&
+               CIF_ISP10_PIX_FMT_GET_BPP(pix_fmt) > 8) || payload)
                /* RAW input > 8BPP is stored with 16BPP by MI */
                bpp = 16;
        else
index c8eb6c5377ee8d4b792ef55b27d8243b63ba352a..cdc0a74c63d5ecf9ca150e824d82b9f53354dac6 100644 (file)
 #include <linux/platform_data/rk_isp10_platform.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-controls_rockchip.h>
+#include <media/videobuf2-v4l2.h>
+
+#include <linux/dma-iommu.h>
+#include <drm/rockchip_drm.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-buf.h>
+
 /*****************************************************************************/
+
+#if IS_ENABLED(CONFIG_VIDEOBUF2_DMA_CONTIG)
+#define CIF_ISP10_MODE_DMA_CONTIG 1
+#endif
+
+#if IS_ENABLED(CONFIG_VIDEOBUF2_DMA_SG)
+#define CIF_ISP10_MODE_DMA_SG 1
+#endif
+
+#if !defined(CIF_ISP10_MODE_DMA_CONTIG) && \
+       !defined(CIF_ISP10_MODE_DMA_SG)
+#error One of the videobuf buffer modes(COTING/SG) \
+       must be selected in the config
+#endif
+
 /* Definitions */
 
 #define CONFIG_CIF_ISP_AUTO_UPD_CFG_BUG
@@ -133,6 +155,7 @@ enum cif_isp10_cid {
        CIF_ISP10_CID_AUTO_FPS                    = 16,
        CIF_ISP10_CID_VBLANKING                   = 17,
        CIF_ISP10_CID_ISO_SENSITIVITY             = 18,
+       CIF_ISP10_CID_MIN_BUFFER_FOR_CAPTURE      = 19,
 
 };
 
@@ -426,15 +449,11 @@ struct cif_isp10_mi_config {
        struct cif_isp10_mi_path_config dma;
 };
 
-#ifdef NO_YET
 struct cif_isp10_buffer {
-       struct list_head list;
-       u32 dma_addr;
-       u32 size;
+       struct vb2_v4l2_buffer vb;
+       struct list_head queue;
+       unsigned long int size;
 };
-#else
-#define cif_isp10_buffer videobuf_buffer
-#endif
 
 struct cif_isp10_metadata_s {
        unsigned int cnt;
@@ -447,8 +466,8 @@ struct cif_isp10_stream {
        enum cif_isp10_state state;
        enum cif_isp10_state saved_state;
        struct list_head buf_queue;
-       struct videobuf_buffer *curr_buf;
-       struct videobuf_buffer *next_buf;
+       struct cif_isp10_buffer *curr_buf;
+       struct cif_isp10_buffer *next_buf;
        bool updt_cfg;
        bool stall;
        bool stop;
@@ -559,6 +578,23 @@ struct cif_isp10_fmt {
        unsigned char overlay;
 };
 
+#ifdef CIF_ISP10_MODE_DMA_SG
+struct cif_isp10_iommu {
+       int client_fd;
+       int map_fd;
+       unsigned long linear_addr;
+       unsigned long len;
+};
+
+struct cif_isp10_dma_buf {
+       struct dma_buf *dma_buffer;
+       struct dma_buf_attachment *attach;
+       struct sg_table *sgt;
+       dma_addr_t dma_addr;
+       int fd;
+};
+#endif
+
 struct cif_isp10_device {
        unsigned int dev_id;
        CIF_ISP10_PLTFRM_DEVICE dev;
@@ -572,6 +608,13 @@ struct cif_isp10_device {
        struct cif_isp10_img_src *img_src;
        struct cif_isp10_img_src *img_src_array[CIF_ISP10_NUM_INPUTS];
        unsigned int img_src_cnt;
+       struct vb2_alloc_ctx *alloc_ctx;
+
+#ifdef CIF_ISP10_MODE_DMA_SG
+       struct iommu_domain *domain;
+       struct cif_isp10_dma_buf dma_buffer[VB2_MAX_FRAME];
+       int dma_buf_cnt;
+#endif
        struct cif_isp10_img_src_exps img_src_exps;
 
        struct cif_isp10_config config;
@@ -608,6 +651,29 @@ int get_cif_isp10_output_format_desc_size(void);
 
 /* Clean code starts from here */
 
+static inline
+struct cif_isp10_stream *to_stream_by_id(struct cif_isp10_device *dev,
+                                        enum cif_isp10_stream_id id)
+{
+       if (WARN_ON(id != CIF_ISP10_STREAM_MP &&
+               id != CIF_ISP10_STREAM_SP &&
+               id != CIF_ISP10_STREAM_DMA &&
+               id != CIF_ISP10_STREAM_ISP))
+               return &dev->sp_stream;
+
+       switch (id) {
+       case CIF_ISP10_STREAM_MP:
+               return &dev->mp_stream;
+       case CIF_ISP10_STREAM_SP:
+               return &dev->sp_stream;
+       case CIF_ISP10_STREAM_DMA:
+               return &dev->dma_stream;
+       case CIF_ISP10_STREAM_ISP:
+               return NULL;
+       }
+       return NULL;
+}
+
 struct cif_isp10_device *cif_isp10_create(
        CIF_ISP10_PLTFRM_DEVICE pdev,
        void (*sof_event)(struct cif_isp10_device *dev, __u32 frame_sequence),
@@ -683,7 +749,8 @@ const char *cif_isp10_g_input_name(
 int cif_isp10_calc_min_out_buff_size(
        struct cif_isp10_device *dev,
        enum cif_isp10_stream_id stream_id,
-       u32 *size);
+       u32 *size,
+       bool payload);
 
 int cif_isp10_s_ctrl(
        struct cif_isp10_device *dev,
index 7b9b45e4b359b13f9ab2c9429d6ee179c54c413d..9871d9e8fbf9c173f9373ac159618e12f791bda0 100644 (file)
@@ -206,6 +206,8 @@ static int cif_isp10_v4l2_cid2v4l2_cid(u32 cif_isp10_cid)
                return V4L2_CID_HFLIP;
        case CIF_ISP10_CID_VFLIP:
                return V4L2_CID_VFLIP;
+       case CIF_ISP10_CID_MIN_BUFFER_FOR_CAPTURE:
+               return V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
        default:
                cif_isp10_pltfrm_pr_err(NULL,
                        "unknown/unsupported CIF ISP20 ID %d\n",
@@ -352,6 +354,9 @@ int cif_isp10_img_src_v4l2_subdev_g_ctrl(
                        }
                }
                *val = ctrl.value;
+       } else {
+               cif_isp10_pltfrm_pr_err(NULL,
+                       "subdevcall got err: %d\n", ret);
        }
        return ret;
 }
index a01f591ae5b00051947a5f36b66b5e216963d9d3..26de7f1ce214a554bcab71e5c74e1f00d9c664e3 100644 (file)
@@ -20,8 +20,8 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <linux/videodev2.h>
-#include <media/videobuf-core.h>
-#include <media/videobuf-vmalloc.h>    /* for ISP statistics */
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-vmalloc.h>   /* for ISP statistics */
 #include <linux/io.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
@@ -314,12 +314,16 @@ static void cifisp_reg_dump(const struct cif_isp10_isp_dev *isp_dev,
 static void cifisp_reg_dump_capture(const struct cif_isp10_isp_dev *isp_dev);
 #endif
 
+static struct cif_isp10_buffer *to_cif_isp10_vb(struct vb2_v4l2_buffer *vb)
+{
+       return container_of(vb, struct cif_isp10_buffer, vb);
+}
+
 static int cifisp_module_enable(struct cif_isp10_isp_dev *isp_dev,
        bool flag, __s32 *value, unsigned int module)
 {
        unsigned int *curr_ens, *updates, *new_ens;
        unsigned long lock_flags = 0;
-       int retval = 0;
 
        spin_lock_irqsave(&isp_dev->config_lock, lock_flags);
 
@@ -353,7 +357,7 @@ static int cifisp_module_enable(struct cif_isp10_isp_dev *isp_dev,
 end:
        spin_unlock_irqrestore(&isp_dev->config_lock, lock_flags);
 
-       return retval;
+       return 0;
 }
 
 /* ISP BP interface function */
@@ -2596,120 +2600,40 @@ static void cifisp_dpf_end(struct cif_isp10_isp_dev *isp_dev)
                CIF_ISP_DPF_MODE);
 }
 
-/* ================================QUEUE OPS ================== */
-static int cifisp_stat_vbq_setup(struct videobuf_queue *vq,
-                                unsigned int *cnt, unsigned int *size)
-{
-       *size = sizeof(struct cifisp_stat_buffer);
-
-       return 0;
-}
-
-static void cifisp_stat_vbq_release(struct videobuf_queue *vq,
-                                   struct videobuf_buffer *vb)
-{
-       CIFISP_DPRINT(CIFISP_DEBUG, "Releasing buffer entry!\n");
-
-       videobuf_waiton(vq, vb, 0, 0);
-
-       videobuf_vmalloc_free(vb);
-
-       CIFISP_DPRINT(CIFISP_DEBUG, "Releasing buffer exit!\n");
-}
-
-static int cifisp_stat_vbq_prepare(struct videobuf_queue *vq,
-                                  struct videobuf_buffer *vb,
-                                  enum v4l2_field field)
-{
-       int err = 0;
-
-       vb->size = sizeof(struct cifisp_stat_buffer);
-       vb->width = 0;
-       vb->height = 0;
-       vb->field = field;
-
-       if (vb->state == VIDEOBUF_NEEDS_INIT)
-               err = videobuf_iolock(vq, vb, NULL);
-
-       if (!err)
-               vb->state = VIDEOBUF_PREPARED;
-       else
-               cifisp_stat_vbq_release(vq, vb);
-
-       return err;
-}
-
-static void cifisp_stat_vbq_queue(struct videobuf_queue *vq,
-                                 struct videobuf_buffer *vb)
-{
-       struct cif_isp10_isp_dev *isp_dev = vq->priv_data;
-
-       vb->state = VIDEOBUF_QUEUED;
-
-       CIFISP_DPRINT(CIFISP_DEBUG, "Queueing stat buffer!\n");
-
-       list_add_tail(&vb->queue, &isp_dev->stat);
-}
-
-/* Queue Ops */
-static struct videobuf_queue_ops cifisp_stat_qops = {
-       .buf_setup = cifisp_stat_vbq_setup,
-       .buf_prepare = cifisp_stat_vbq_prepare,
-       .buf_queue = cifisp_stat_vbq_queue,
-       .buf_release = cifisp_stat_vbq_release,
-};
-
 /* ================== IOCTL implementation ========================= */
 static int cifisp_reqbufs(struct file *file, void *priv,
                          struct v4l2_requestbuffers *p)
 {
-       struct cif_isp10_isp_dev *isp_dev =
-               video_get_drvdata(video_devdata(file));
-
        CIFISP_DPRINT(CIFISP_DEBUG,
-                     " %s: %s: p->type %d p->count %d\n",
-                     ISP_VDEV_NAME, __func__, p->type, p->count);
-
-       return videobuf_reqbufs(&isp_dev->vbq_stat, p);
+                       " %s: %s: p->type %d p->count %d\n",
+                       ISP_VDEV_NAME, __func__, p->type, p->count);
+       return vb2_ioctl_reqbufs(file, priv, p);
 }
 
 static int cifisp_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
 {
-       struct cif_isp10_isp_dev *isp_dev =
-               video_get_drvdata(video_devdata(file));
-
        CIFISP_DPRINT(CIFISP_DEBUG,
                      " %s: %s: p->type %d p->index %d\n",
                      ISP_VDEV_NAME, __func__, p->type, p->index);
-
-       return videobuf_querybuf(&isp_dev->vbq_stat, p);
+       return vb2_ioctl_querybuf(file, priv, p);
 }
 
 static int cifisp_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
 {
-       struct cif_isp10_isp_dev *isp_dev =
-               video_get_drvdata(video_devdata(file));
-
        CIFISP_DPRINT(CIFISP_DEBUG,
                      " %s: %s: p->type %d p->index %d\n",
                      ISP_VDEV_NAME, __func__, p->type, p->index);
-
-       return videobuf_qbuf(&isp_dev->vbq_stat, p);
+       return vb2_ioctl_qbuf(file, priv, p);
 }
 
 /* ========================================================== */
 
 static int cifisp_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
 {
-       struct cif_isp10_isp_dev *isp_dev =
-               video_get_drvdata(video_devdata(file));
-
        CIFISP_DPRINT(CIFISP_DEBUG,
                      " %s: %s: p->type %d p->index %d\n",
                      ISP_VDEV_NAME, __func__, p->type, p->index);
-
-       return videobuf_dqbuf(&isp_dev->vbq_stat, p,
-                             file->f_flags & O_NONBLOCK);
+       return vb2_ioctl_dqbuf(file, priv, p);
 }
 
 static int cifisp_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
@@ -2717,7 +2641,7 @@ static int cifisp_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
        struct cif_isp10_isp_dev *isp_dev =
                video_get_drvdata(video_devdata(file));
 
-       int ret = videobuf_streamon(&isp_dev->vbq_stat);
+       int ret = vb2_ioctl_streamon(file, priv, i);
 
        if (ret == 0)
                isp_dev->streamon = true;
@@ -2731,13 +2655,12 @@ static int cifisp_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 /* ========================================================== */
 static int cifisp_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 {
+       int ret;
        struct cif_isp10_isp_dev *isp_dev =
                video_get_drvdata(video_devdata(file));
-       int ret;
 
        drain_workqueue(isp_dev->readout_wq);
-
-       ret = videobuf_streamoff(&isp_dev->vbq_stat);
+       ret = vb2_ioctl_streamoff(file, priv, i);
 
        if (ret == 0)
                isp_dev->streamon = false;
@@ -3167,11 +3090,9 @@ static const struct v4l2_ioctl_ops cifisp_ioctl = {
 static unsigned int cifisp_poll(struct file *file,
                                struct poll_table_struct *wait)
 {
-       struct cif_isp10_isp_dev *isp_dev =
-               video_get_drvdata(video_devdata(file));
        unsigned int ret;
 
-       ret = videobuf_poll_stream(file, &isp_dev->vbq_stat, wait);
+       ret = vb2_fop_poll(file, wait);
 
        CIFISP_DPRINT(CIFISP_DEBUG,
                      "Polling on vbq_stat buffer %d\n", ret);
@@ -3182,10 +3103,7 @@ static unsigned int cifisp_poll(struct file *file,
 /* ======================================================== */
 static int cifisp_mmap(struct file *file, struct vm_area_struct *vma)
 {
-       struct cif_isp10_isp_dev *isp_dev =
-               video_get_drvdata(video_devdata(file));
-
-       return videobuf_mmap_mapper(&isp_dev->vbq_stat, vma);
+       return vb2_fop_mmap(file, vma);
 }
 
 /* ddl@rock-chips.com: v1.0.8 */
@@ -3225,13 +3143,9 @@ static int cifisp_open(struct file *file)
 
 static int cifisp_close(struct file *file)
 {
-       struct cif_isp10_isp_dev *isp_dev =
-               video_get_drvdata(video_devdata(file));
-
        CIFISP_DPRINT(CIFISP_DEBUG, "cifisp_close\n");
 
-       videobuf_stop(&isp_dev->vbq_stat);
-       videobuf_mmap_free(&isp_dev->vbq_stat);
+       vb2_fop_release(file);
 
        /* cifisp_reset(file); */
        return 0;
@@ -3257,6 +3171,73 @@ static void cifisp_release(struct video_device *vdev)
        destroy_workqueue(isp_dev->readout_wq);
 }
 
+/************************************************************/
+static int cif_isp10_vb2_queue_setup(struct vb2_queue *vq,
+                       const void *parg,
+                       unsigned int *count, unsigned int *num_planes,
+                       unsigned int sizes[], void *alloc_ctxs[])
+{
+       sizes[0] = sizeof(struct cifisp_stat_buffer);
+       *num_planes = 1;
+
+       if (!*count)
+               *count = 2;
+
+       return 0;
+}
+
+static void cif_isp10_vb2_queue(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct cif_isp10_buffer *ispbuf = to_cif_isp10_vb(vbuf);
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct cif_isp10_isp_dev *isp_dev = vq->drv_priv;
+       unsigned long flags;
+
+       CIFISP_DPRINT(CIFISP_DEBUG, "Queueing stat buffer!\n");
+       spin_lock_irqsave(&isp_dev->irq_lock, flags);
+       list_add_tail(&ispbuf->queue, &isp_dev->stat);
+       spin_unlock_irqrestore(&isp_dev->irq_lock, flags);
+}
+
+static void cif_isp10_vb2_stop_streaming(struct vb2_queue *vq)
+{
+       struct cif_isp10_isp_dev *isp_dev = vq->drv_priv;
+       struct cif_isp10_buffer *buf, *tmp;
+       unsigned long flags;
+
+       spin_lock_irqsave(&isp_dev->irq_lock, flags);
+       list_for_each_entry_safe(buf, tmp, &isp_dev->stat, queue) {
+               list_del_init(&buf->queue);
+               vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+       }
+       spin_unlock_irqrestore(&isp_dev->irq_lock, flags);
+}
+
+static struct vb2_ops cif_isp10_vb2_ops = {
+       .queue_setup    = cif_isp10_vb2_queue_setup,
+       .buf_queue      = cif_isp10_vb2_queue,
+       .wait_prepare   = vb2_ops_wait_prepare,
+       .wait_finish    = vb2_ops_wait_finish,
+       .stop_streaming = cif_isp10_vb2_stop_streaming,
+};
+
+static int cif_isp10_init_vb2_queue(struct vb2_queue *q,
+       struct cif_isp10_isp_dev *isp_dev)
+{
+       memset(q, 0, sizeof(*q));
+
+       q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       q->io_modes = VB2_MMAP | VB2_USERPTR;
+       q->drv_priv = isp_dev;
+       q->ops = &cif_isp10_vb2_ops;
+       q->mem_ops = &vb2_vmalloc_memops;
+       q->buf_struct_size = sizeof(struct cif_isp10_buffer);
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+
+       return vb2_queue_init(q);
+}
+
 /************************************************************/
 int register_cifisp_device(struct cif_isp10_isp_dev *isp_dev,
        struct video_device *vdev_cifisp,
@@ -3288,16 +3269,10 @@ int register_cifisp_device(struct cif_isp10_isp_dev *isp_dev,
        vdev_cifisp->lock = &isp_dev->mutex;
        vdev_cifisp->v4l2_dev = v4l2_dev;
 
-       videobuf_queue_vmalloc_init(
-               &isp_dev->vbq_stat,
-               &cifisp_stat_qops,
-               NULL,
-               &isp_dev->irq_lock,
-               V4L2_BUF_TYPE_VIDEO_CAPTURE,
-               V4L2_FIELD_NONE,
-               sizeof(struct videobuf_buffer),
-               isp_dev,
-               NULL);  /* ext_lock: NULL */
+       cif_isp10_init_vb2_queue(&isp_dev->vb2_vidq, isp_dev);
+
+       vdev_cifisp->queue = &isp_dev->vb2_vidq;
+
 
        if (video_register_device(vdev_cifisp, VFL_TYPE_GRABBER, -1) < 0) {
                dev_err(&vdev_cifisp->dev,
@@ -3693,7 +3668,10 @@ static void cifisp_send_measurement(
        struct cif_isp10_isp_readout_work *meas_work)
 {
        unsigned long lock_flags = 0;
-       struct videobuf_buffer *vb = NULL;
+       struct cif_isp10_buffer *buf = NULL;
+       struct vb2_buffer *vb = NULL;
+       void *mem_addr;
+
        unsigned int active_meas = isp_dev->active_meas;
        struct cifisp_stat_buffer *stat_buf;
        struct cif_isp10_device *cif_dev =
@@ -3710,8 +3688,10 @@ static void cifisp_send_measurement(
        }
 
        if (!list_empty(&isp_dev->stat)) {
-               vb = list_first_entry(&isp_dev->stat,
-               struct videobuf_buffer, queue);
+               buf = list_first_entry(&isp_dev->stat,
+                       struct cif_isp10_buffer, queue);
+
+               vb = &buf->vb.vb2_buf;
        } else {
                spin_unlock_irqrestore(&isp_dev->irq_lock, lock_flags);
                CIFISP_DPRINT(CIFISP_DEBUG,
@@ -3720,9 +3700,11 @@ static void cifisp_send_measurement(
        }
 
        spin_unlock_irqrestore(&isp_dev->irq_lock, lock_flags);
-       vb->state = VIDEOBUF_ACTIVE;
+       vb->state = VB2_BUF_STATE_ACTIVE;
 
-       stat_buf = (struct cifisp_stat_buffer *)videobuf_to_vmalloc(vb);
+       mem_addr = vb->vb2_queue->mem_ops->vaddr(
+                               vb->planes[0].mem_priv);
+       stat_buf = (struct cifisp_stat_buffer *)mem_addr;
        memset(stat_buf, 0x00, sizeof(struct cifisp_stat_buffer));
 
        if (active_meas & CIF_ISP_AWB_DONE)
@@ -3749,9 +3731,8 @@ static void cifisp_send_measurement(
                        meas_work->frame_id);
                goto end;
        }
+       list_del(&buf->queue);
 
-       vb->ts = isp_dev->vs_t;
-       list_del(&vb->queue);
        spin_unlock_irqrestore(&isp_dev->irq_lock, lock_flags);
 
        if (active_meas & CIF_ISP_AWB_DONE) {
@@ -3787,19 +3768,16 @@ static void cifisp_send_measurement(
        }
        isp_dev->meas_stats.g_frame_id = meas_work->frame_id;
 
-       vb->field_count = meas_work->frame_id;
-       vb->state = VIDEOBUF_DONE;
-       wake_up(&vb->done);
+       vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+       wake_up(&vb->vb2_queue->done_wq);
 
        CIFISP_DPRINT(CIFISP_DEBUG,
-               "Measurement done(%d, %d)\n",
-               vb->field_count,
-               vb->i);
+               "Measurement done\n");
        vb = NULL;
 end:
 
-       if (vb && (vb->state == VIDEOBUF_ACTIVE))
-               vb->state = VIDEOBUF_QUEUED;
+       if (vb && (vb->state == VB2_BUF_STATE_ACTIVE))
+               vb->state = VB2_BUF_STATE_QUEUED;
 }
 
 void cifisp_isp_readout_work(struct work_struct *work)
@@ -4332,7 +4310,7 @@ int cifisp_isp_isr(struct cif_isp10_isp_dev *isp_dev, u32 isp_mis)
                 * Do the updates in the order of the processing flow.
                 */
                spin_lock(&isp_dev->config_lock);
-               if (cifisp_isp_isr_other_config(isp_dev, &time_left) == false)
+               if (!cifisp_isp_isr_other_config(isp_dev, &time_left))
                        cifisp_isp_isr_meas_config(isp_dev, &time_left);
                spin_unlock(&isp_dev->config_lock);
 
index 27f6bb6873c19b32a34554d0616951d33338bc7f..2c97e6effd50f829c312b7b03c0f607673cd3937 100644 (file)
@@ -18,7 +18,7 @@
 #define _CIF_ISP10_ISP_H
 
 #include <media/v4l2-common.h>
-#include <media/videobuf-core.h>
+#include <media/videobuf2-core.h>
 #include <media/rk-isp10-ioctl.h>
 #include <media/v4l2-controls_rockchip.h>
 
@@ -78,7 +78,6 @@ struct cif_isp10_isp_dev {
        spinlock_t irq_lock;
        /* ISP statistics related */
        spinlock_t req_lock;
-       struct videobuf_queue vbq_stat;
        struct list_head stat;
        void __iomem *base_addr;    /* registers base address */
 
@@ -94,6 +93,8 @@ struct cif_isp10_isp_dev {
        struct workqueue_struct *readout_wq;
 
        unsigned int *dev_id;
+
+       struct vb2_queue vb2_vidq;
 };
 
 enum cif_isp10_isp_readout_cmd {
@@ -107,7 +108,7 @@ struct cif_isp10_isp_readout_work {
 
        unsigned int frame_id;
        enum cif_isp10_isp_readout_cmd readout;
-       struct videobuf_buffer *vb;
+       struct vb2_buffer *vb;
        unsigned int stream_id;
 };
 
index 126a0375faa93131580632a11d923754cb646ae9..9304f83bbe27cc43ff3d08f9e4096ad9ea41a770 100644 (file)
@@ -713,6 +713,9 @@ static ssize_t cif_isp10_dbgfs_reg_trace_write(
 
        if (count > CIF_ISP10_DBGFS_BUF_SIZE) {
                cif_isp10_pltfrm_pr_err(dev, "command line too long\n");
+               if (!in_irq())
+                       spin_unlock_irqrestore(
+                               &cif_isp10_reg_trace.lock, flags);
                return -EINVAL;
        }
 
@@ -950,6 +953,190 @@ inline u32 cif_isp10_pltfrm_read_reg(
        return ioread32(addr);
 }
 
+#ifdef CIF_ISP10_MODE_DMA_SG
+int cif_isp10_dma_attach_device(struct cif_isp10_device *cif_isp10_dev)
+{
+       struct iommu_domain *domain = cif_isp10_dev->domain;
+       struct device *dev = cif_isp10_dev->dev;
+       int ret;
+
+       cif_isp10_pltfrm_pr_dbg(NULL, "camsys_drm_dma_attach_device\n");
+
+       ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
+       if (ret)
+               return ret;
+
+       dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
+       ret = iommu_attach_device(domain, dev);
+       if (ret) {
+               dev_err(dev, "Failed to attach iommu device\n");
+               return ret;
+       }
+
+       if (!common_iommu_setup_dma_ops(dev, 0x10000000, SZ_2G, domain->ops)) {
+               dev_err(dev, "Failed to set dma_ops\n");
+               iommu_detach_device(domain, dev);
+               ret = -ENODEV;
+       }
+
+       return ret;
+}
+
+void cif_isp10_dma_detach_device(struct cif_isp10_device *cif_isp10_dev)
+{
+       struct iommu_domain *domain = cif_isp10_dev->domain;
+       struct device *dev = cif_isp10_dev->dev;
+
+       cif_isp10_pltfrm_pr_dbg(NULL, "camsys_drm_dma_detach_device\n");
+
+       iommu_detach_device(domain, dev);
+}
+
+int cif_isp10_drm_iommu_cb(struct device *dev,
+       struct cif_isp10_device *cif_isp10_dev,
+       bool on)
+{
+       struct cif_isp10_iommu *iommu = NULL;
+       struct cif_isp10_iommu fake_iommu;
+       struct dma_buf *dma_buffer;
+       struct dma_buf_attachment *attach;
+       struct sg_table *sgt;
+       dma_addr_t dma_addr;
+       int index = 0;
+       int ret = 0;
+       struct cif_isp10_device *camsys_dev = cif_isp10_dev;
+
+       fake_iommu.client_fd = -1;
+       fake_iommu.len = 0;
+       fake_iommu.linear_addr = 0;
+       fake_iommu.map_fd = -1;
+       iommu = &fake_iommu;
+
+       if (on) {
+               /*ummap mapped fd first*/
+               int cur_mapped_cnt = camsys_dev->dma_buf_cnt;
+
+               for (index = 0; index < cur_mapped_cnt; index++) {
+                       if (camsys_dev->dma_buffer[index].fd == iommu->map_fd)
+                               break;
+               }
+
+               if (index != cur_mapped_cnt) {
+                       attach = camsys_dev->dma_buffer[index].attach;
+                       dma_buffer = camsys_dev->dma_buffer[index].dma_buffer;
+                       sgt = camsys_dev->dma_buffer[index].sgt;
+                       cif_isp10_pltfrm_pr_dbg(NULL,
+                               "exist mapped buf,release it before map:\n");
+                       cif_isp10_pltfrm_pr_dbg(NULL,
+                               "attach %p,dma_buf %p,sgt %p,fd %d,index %d\n",
+                               attach,
+                               dma_buffer,
+                               sgt,
+                               iommu->map_fd,
+                               index);
+                       dma_buf_unmap_attachment
+                               (attach,
+                               sgt,
+                               DMA_BIDIRECTIONAL);
+                       dma_buf_detach(dma_buffer, attach);
+                       dma_buf_put(dma_buffer);
+                       if (camsys_dev->dma_buf_cnt == 1)
+                               cif_isp10_dma_attach_device(camsys_dev);
+                       camsys_dev->dma_buf_cnt--;
+                       camsys_dev->dma_buffer[index].fd = -1;
+               }
+               /*get a free slot*/
+               for (index = 0; index < VB2_MAX_FRAME; index++)
+                       if (camsys_dev->dma_buffer[index].fd == -1)
+                               break;
+
+               if (index == VB2_MAX_FRAME)
+                       return -ENOMEM;
+
+               if (camsys_dev->dma_buf_cnt == 0) {
+                       ret = cif_isp10_dma_attach_device(camsys_dev);
+                       if (ret)
+                               return ret;
+               }
+
+               dma_buffer = dma_buf_get(iommu->map_fd);
+               if (IS_ERR(dma_buffer))
+                       return PTR_ERR(dma_buffer);
+               attach = dma_buf_attach(dma_buffer, dev);
+               if (IS_ERR(attach)) {
+                       dma_buf_put(dma_buffer);
+                       return PTR_ERR(attach);
+               }
+               sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+               if (IS_ERR(sgt)) {
+                       dma_buf_detach(dma_buffer, attach);
+                       dma_buf_put(dma_buffer);
+                       return PTR_ERR(sgt);
+               }
+               dma_addr = sg_dma_address(sgt->sgl);
+               camsys_dev->dma_buffer[index].dma_addr = dma_addr;
+               camsys_dev->dma_buffer[index].attach    = attach;
+               camsys_dev->dma_buffer[index].dma_buffer = dma_buffer;
+               camsys_dev->dma_buffer[index].sgt = sgt;
+               camsys_dev->dma_buffer[index].fd = iommu->map_fd;
+               iommu->linear_addr = dma_addr;
+               iommu->len = sg_dma_len(sgt->sgl);
+               camsys_dev->dma_buf_cnt++;
+
+               cif_isp10_pltfrm_pr_dbg(NULL,
+                       "dma buf map: dma_addr 0x%lx\n",
+                       (unsigned long)dma_addr);
+               cif_isp10_pltfrm_pr_dbg(NULL,
+                       "attach %p, dma_buf %p,sgt %p,fd %d,buf_cnt %d\n",
+                       attach,
+                       dma_buffer,
+                       sgt,
+                       iommu->map_fd,
+                       camsys_dev->dma_buf_cnt);
+       } else {
+               if (
+                       (camsys_dev->dma_buf_cnt == 0) ||
+                       (index < 0) ||
+                       (index >= VB2_MAX_FRAME))
+                       return -EINVAL;
+
+               for (index = 0; index < camsys_dev->dma_buf_cnt; index++) {
+                       if (camsys_dev->dma_buffer[index].fd == iommu->map_fd)
+                               break;
+               }
+               if (index == camsys_dev->dma_buf_cnt) {
+                       cif_isp10_pltfrm_pr_warn(NULL,
+                               "can't find map fd %d",
+                               iommu->map_fd);
+                       return -EINVAL;
+               }
+               attach = camsys_dev->dma_buffer[index].attach;
+               dma_buffer = camsys_dev->dma_buffer[index].dma_buffer;
+               sgt = camsys_dev->dma_buffer[index].sgt;
+               dma_addr = sg_dma_address(sgt->sgl);
+               cif_isp10_pltfrm_pr_dbg(NULL,
+                       "dma buf unmap: dma_addr 0x%lx",
+                       (unsigned long)dma_addr);
+               cif_isp10_pltfrm_pr_dbg(NULL,
+                       "attach %p,dma_buf %p,sgt %p,index %d",
+                       attach,
+                       dma_buffer,
+                       sgt,
+                       index);
+               dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
+               dma_buf_detach(dma_buffer, attach);
+               dma_buf_put(dma_buffer);
+               if (camsys_dev->dma_buf_cnt == 1)
+                       cif_isp10_dma_detach_device(camsys_dev);
+
+               camsys_dev->dma_buf_cnt--;
+               camsys_dev->dma_buffer[index].fd = -1;
+       }
+
+       return ret;
+}
+#endif
+
 int cif_isp10_pltfrm_dev_init(
        struct cif_isp10_device *cif_isp10_dev,
        struct device **_dev,
@@ -963,6 +1150,12 @@ int cif_isp10_pltfrm_dev_init(
        struct resource *res;
        void __iomem *base_addr;
        unsigned int i, irq;
+#ifdef CIF_ISP10_MODE_DMA_SG
+       struct iommu_domain *domain;
+       struct iommu_group *group;
+       struct device_node *np;
+       int err = 0;
+#endif
 
        dev_set_drvdata(dev, cif_isp10_dev);
        cif_isp10_dev->dev = dev;
@@ -1005,7 +1198,11 @@ int cif_isp10_pltfrm_dev_init(
                        irq,
                        cif_isp10_pltfrm_irq_handler,
                        NULL,
+#ifdef CIF_ISP10_MODE_DMA_SG
+                       0x80,
+#else
                        0,
+#endif
                        dev_driver_string(dev),
                        dev);
        if (IS_ERR_VALUE(ret)) {
@@ -1043,6 +1240,45 @@ int cif_isp10_pltfrm_dev_init(
        for (i = 0; i < ARRAY_SIZE(pdata->irq_handlers); i++)
                pdata->irq_handlers[i].mis = -EINVAL;
 
+#ifdef CIF_ISP10_MODE_DMA_SG
+               np = of_find_node_by_name(NULL, "isp0_mmu");
+               if (!np) {
+                       int index = 0;
+                       /* iommu domain */
+                       domain = iommu_domain_alloc(&platform_bus_type);
+                       if (!domain)
+                               goto err;
+
+                       err = iommu_get_dma_cookie(domain);
+                       if (err)
+                               goto err_free_domain;
+
+                       group = iommu_group_get(&pdev->dev);
+                       if (!group) {
+                               group = iommu_group_alloc();
+                               if (IS_ERR(group)) {
+                                       dev_err(&pdev->dev, "Failed to allocate IOMMU group\n");
+                                       goto err_put_cookie;
+                               }
+
+                               err = iommu_group_add_device(group, &pdev->dev);
+                               iommu_group_put(group);
+                               if (err) {
+                                       dev_err(&pdev->dev, "failed to add device to IOMMU group\n");
+                                       goto err_put_cookie;
+                               }
+                       }
+                       cif_isp10_dev->domain = domain;
+                       cif_isp10_dev->dma_buf_cnt = 0;
+                       for (index = 0; index < VB2_MAX_FRAME; index++)
+                               cif_isp10_dev->dma_buffer[index].fd = -1;
+
+                       cif_isp10_drm_iommu_cb(&pdev->dev, cif_isp10_dev, true);
+               } else {
+                       //cif_isp10_mrv_iommu_cb();
+               }
+#endif
+
        dev->platform_data = pdata;
 
        INIT_LIST_HEAD(&pdata->csi0_configs);
@@ -1093,6 +1329,13 @@ int cif_isp10_pltfrm_dev_init(
 #endif
 
        return 0;
+
+#ifdef CIF_ISP10_MODE_DMA_SG
+err_put_cookie:
+       iommu_put_dma_cookie(domain);
+err_free_domain:
+       iommu_domain_free(domain);
+#endif
 err:
        cif_isp10_pltfrm_pr_err(NULL, "failed with error %d\n", ret);
        if (!IS_ERR_OR_NULL(pdata))
@@ -1428,8 +1671,12 @@ err:
 }
 
 void cif_isp10_pltfrm_dev_release(
-       struct device *dev)
+       struct device *dev, struct cif_isp10_device *cif_isp10_dev)
 {
+#ifdef CIF_ISP10_MODE_DMA_SG
+               cif_isp10_drm_iommu_cb(dev, cif_isp10_dev, false);
+#endif
+
 #ifndef CONFIG_DEBUG_FS
        {
                struct cif_isp10_pltfrm_data *pdata =
index 4a205475958cfd32b61b55245b92d207c7c9a9fe..cc4e4118a1335a0dee7d94e9531b00ea5b2c331b 100644 (file)
@@ -159,7 +159,8 @@ int cif_isp10_pltfrm_dev_init(
        void __iomem **reg_base_addr);
 
 void cif_isp10_pltfrm_dev_release(
-       struct device *dev);
+       struct device *dev,
+       struct cif_isp10_device *cif_isp10_dev);
 
 int cif_isp10_pltfrm_pm_set_state(
        struct device *dev,
index 448ecfe4852f833051e191541df87fd01ed682a0..c68b5b59f1eb9ee61273d8fc710f104565da70e4 100644 (file)
@@ -18,7 +18,8 @@
 #include <media/v4l2-event.h>
 #include <media/v4l2-fh.h>
 #include <media/v4l2-ioctl.h>
-#include <media/videobuf-dma-contig.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-dma-sg.h>
 #include "cif_isp10.h"
 #include "cif_isp10_regs.h"
 #include "cif_isp10_version.h"
@@ -47,8 +48,12 @@ struct cif_isp10_v4l2_fh {
 
 /* One structure per video node */
 struct cif_isp10_v4l2_node {
-       struct videobuf_queue buf_queue;
+       struct vb2_queue buf_queue;
+       /* queue lock */
+       struct mutex qlock;
        struct video_device vdev;
+       struct media_pad pad;
+       struct cif_isp10_pipeline *pipe;
        int users;
        struct cif_isp10_v4l2_fh *owner;
 };
@@ -79,13 +84,24 @@ static struct cif_isp10_v4l2_node *to_node(struct cif_isp10_v4l2_fh *fh)
        return container_of(vdev, struct cif_isp10_v4l2_node, vdev);
 }
 
-static struct videobuf_queue *to_videobuf_queue(
+static inline struct cif_isp10_v4l2_node *queue_to_node(struct vb2_queue *q)
+{
+       return container_of(q, struct cif_isp10_v4l2_node, buf_queue);
+}
+
+static inline struct cif_isp10_buffer *to_cif_isp10_vb(
+       struct vb2_v4l2_buffer *vb)
+{
+       return container_of(vb, struct cif_isp10_buffer, vb);
+}
+
+static struct vb2_queue *to_vb2_queue(
        struct file *file)
 {
        struct cif_isp10_v4l2_fh *fh = to_fh(file);
        struct video_device *vdev = fh ? fh->fh.vdev : NULL;
        struct cif_isp10_v4l2_node *node = to_node(fh);
-       struct videobuf_queue *q;
+       struct vb2_queue *q;
 
        if (unlikely(!vdev)) {
                cif_isp10_pltfrm_pr_err(NULL,
@@ -123,13 +139,13 @@ static enum cif_isp10_stream_id to_stream_id(
 }
 
 static struct cif_isp10_device *to_cif_isp10_device(
-       struct videobuf_queue *queue)
+       struct vb2_queue *queue)
 {
-       return queue->priv_data;
+       return queue->drv_priv;
 }
 
 static enum cif_isp10_stream_id to_cif_isp10_stream_id(
-       struct videobuf_queue *queue)
+       struct vb2_queue *queue)
 {
        struct cif_isp10_v4l2_node *node =
                container_of(queue, struct cif_isp10_v4l2_node, buf_queue);
@@ -269,6 +285,8 @@ static int cif_isp10_v4l2_cid2cif_isp10_cid(u32 v4l2_cid)
                return CIF_ISP10_CID_ISO_SENSITIVITY;
        case RK_V4L2_CID_AUTO_FPS:
                return CIF_ISP10_CID_AUTO_FPS;
+       case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+               return CIF_ISP10_CID_MIN_BUFFER_FOR_CAPTURE;
        default:
                cif_isp10_pltfrm_pr_err(NULL,
                        "unknown/unsupported V4L2 CID 0x%x\n",
@@ -304,7 +322,7 @@ static enum cif_isp10_image_effect cif_isp10_v4l2_colorfx2cif_isp10_ie(
 }
 
 static enum cif_isp10_pix_fmt cif_isp10_v4l2_pix_fmt2cif_isp10_pix_fmt(
-       u32 v4l2_pix_fmt, struct videobuf_queue *queue)
+       u32 v4l2_pix_fmt, struct vb2_queue *queue)
 {
 /*struct cif_isp10_v4l2_node *node =
  *     container_of(queue, struct cif_isp10_v4l2_node, buf_queue);
@@ -425,25 +443,20 @@ static int cif_isp10_v4l2_streamon(
        enum v4l2_buf_type buf_type)
 {
        int ret;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
        static u32 streamon_cnt_sp;
        static u32 streamon_cnt_mp;
        static u32 streamon_cnt_dma;
-       struct cif_isp10_v4l2_fh *fh = to_fh(file);
-       struct cif_isp10_v4l2_node *node = to_node(fh);
        u32 stream_ids = to_stream_id(file);
 
-       if (node->owner != fh)
-               return -EBUSY;
-
        cif_isp10_pltfrm_pr_dbg(dev->dev, "%s(%d)\n",
                cif_isp10_v4l2_buf_type_string(queue->type),
                (stream_ids & CIF_ISP10_STREAM_MP) ? ++streamon_cnt_mp :
                ((stream_ids & CIF_ISP10_STREAM_SP) ? ++streamon_cnt_sp :
                ++streamon_cnt_dma));
 
-       ret = videobuf_streamon(queue);
+       ret = vb2_streamon(queue, buf_type);
        if (IS_ERR_VALUE(ret)) {
                cif_isp10_pltfrm_pr_err(dev->dev,
                        "videobuf_streamon failed\n");
@@ -452,13 +465,12 @@ static int cif_isp10_v4l2_streamon(
 
        ret = cif_isp10_streamon(dev, stream_ids);
        if (IS_ERR_VALUE(ret)) {
-               videobuf_queue_cancel(queue);
                goto err;
        }
 
        return 0;
 err:
-       (void)videobuf_mmap_free(queue);
+       (void)vb2_queue_release(queue);
        cif_isp10_pltfrm_pr_err(dev->dev, "failed with error %d\n", ret);
        return ret;
 }
@@ -468,33 +480,24 @@ static int cif_isp10_v4l2_do_streamoff(
 {
        int ret = 0;
        int err;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
-       struct cif_isp10_v4l2_fh *fh = to_fh(file);
-       struct cif_isp10_v4l2_node *node = to_node(fh);
        u32 stream_ids = to_stream_id(file);
 
        cif_isp10_pltfrm_pr_dbg(dev->dev, "%s\n",
                cif_isp10_v4l2_buf_type_string(queue->type));
 
-       if (node->owner != fh)
-               return -EBUSY;
-
        err = cif_isp10_streamoff(dev, stream_ids);
        if (IS_ERR_VALUE(err))
                ret = -EFAULT;
-       err = videobuf_streamoff(queue);
+       err = vb2_streamoff(queue, queue->type);
        if (IS_ERR_VALUE(err)) {
                cif_isp10_pltfrm_pr_err(dev->dev,
                        "videobuf_streamoff failed with error %d\n", err);
                ret = -EFAULT;
        }
-       err = videobuf_mmap_free(queue);
-       if (IS_ERR_VALUE(err)) {
-               cif_isp10_pltfrm_pr_err(dev->dev,
-                       "videobuf_mmap_free failed with error %d\n", err);
-               ret = -EFAULT;
-       }
+
+       vb2_queue_release(queue);
 
        if (IS_ERR_VALUE(ret))
                cif_isp10_pltfrm_pr_err(dev->dev,
@@ -523,20 +526,8 @@ static int cif_isp10_v4l2_qbuf(
        struct v4l2_buffer *buf)
 {
        int ret;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
-       struct cif_isp10_v4l2_fh *fh = to_fh(file);
-       struct cif_isp10_v4l2_node *node = to_node(fh);
-
-       cif_isp10_pltfrm_pr_dbg(NULL,
-               "%s buffer type %s, index %d, length %d\n",
-               cif_isp10_v4l2_buf_type_string(queue->type),
-               cif_isp10_v4l2_buf_type_string(buf->type),
-               buf->index, buf->length);
-
-       if (node->owner != fh)
-               return -EBUSY;
 
-       ret = videobuf_qbuf(queue, buf);
+       ret = vb2_ioctl_qbuf(file, priv, buf);
        if (IS_ERR_VALUE(ret))
                cif_isp10_pltfrm_pr_err(NULL,
                        "videobuf_qbuf failed with error %d\n", ret);
@@ -549,17 +540,8 @@ static int cif_isp10_v4l2_dqbuf(
        struct v4l2_buffer *buf)
 {
        int ret;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
-       struct cif_isp10_v4l2_fh *fh = to_fh(file);
-       struct cif_isp10_v4l2_node *node = to_node(fh);
 
-       cif_isp10_pltfrm_pr_dbg(NULL, "%s\n",
-               cif_isp10_v4l2_buf_type_string(queue->type));
-
-       if (node->owner != fh)
-               return -EBUSY;
-
-       ret = videobuf_dqbuf(queue, buf, file->f_flags & O_NONBLOCK);
+       ret = vb2_ioctl_dqbuf(file, priv, buf);
        if (IS_ERR_VALUE(ret) && (ret != -EAGAIN))
                cif_isp10_pltfrm_pr_err(NULL,
                        "videobuf_dqbuf failed with error %d\n", ret);
@@ -570,152 +552,17 @@ static int cif_isp10_v4l2_dqbuf(
        return ret;
 }
 
-static void cif_isp10_v4l2_buf_release(
-       struct videobuf_queue *queue,
-       struct videobuf_buffer *buf)
-{
-       cif_isp10_pltfrm_pr_dbg(NULL,
-               "%s\n",
-               cif_isp10_v4l2_buf_type_string(queue->type));
-
-       if (in_interrupt())
-               WARN_ON(1);
-
-       videobuf_dma_contig_free(queue, buf);
-
-       buf->state = VIDEOBUF_NEEDS_INIT;
-}
-
-static void cif_isp10_v4l2_buf_queue(
-       struct videobuf_queue *queue,
-       struct videobuf_buffer *buf)
-{
-       struct cif_isp10_device *dev = to_cif_isp10_device(queue);
-       enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
-
-       cif_isp10_pltfrm_pr_dbg(NULL,
-               "%s %dx%d, size %lu, bytesperline %d\n",
-               cif_isp10_v4l2_buf_type_string(queue->type),
-               buf->width, buf->height, buf->size, buf->bytesperline);
-
-       if (!IS_ERR_VALUE(cif_isp10_qbuf(dev, strm, buf)))
-               buf->state = VIDEOBUF_QUEUED;
-       else
-               cif_isp10_pltfrm_pr_err(NULL, "failed\n");
-}
-
-static int cif_isp10_v4l2_buf_setup(
-       struct videobuf_queue *queue,
-       unsigned int *cnt,
-       unsigned int *size)
-{
-       int ret;
-       struct cif_isp10_device *dev = to_cif_isp10_device(queue);
-       enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
-
-       cif_isp10_pltfrm_pr_dbg(NULL, "%s count %d, size %d\n",
-               cif_isp10_v4l2_buf_type_string(queue->type),
-               *cnt, *size);
-
-       ret = cif_isp10_calc_min_out_buff_size(
-               dev, strm, size);
-       if (IS_ERR_VALUE(ret)) {
-               cif_isp10_pltfrm_pr_err(NULL, "failed with error %d\n", ret);
-               return ret;
-       }
-
-       cif_isp10_pltfrm_pr_dbg(NULL, "%s count %d, size %d\n",
-               cif_isp10_v4l2_buf_type_string(queue->type),
-               *cnt, *size);
-
-       return 0;
-}
-
-static int cif_isp10_v4l2_buf_prepare(
-       struct videobuf_queue *queue,
-       struct videobuf_buffer *buf,
-       enum v4l2_field field)
-{
-       int ret;
-       struct cif_isp10_device *dev = to_cif_isp10_device(queue);
-       enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
-       u32 size;
-
-       cif_isp10_pltfrm_pr_dbg(NULL, "%s\n",
-               cif_isp10_v4l2_buf_type_string(queue->type));
-
-       ret = cif_isp10_calc_min_out_buff_size(
-               dev, strm, &size);
-       if (IS_ERR_VALUE(ret))
-               goto err;
-       buf->size = size;
-       if (strm == CIF_ISP10_STREAM_SP) {
-               buf->width =
-                       dev->config.mi_config.sp.output.width;
-               buf->height =
-                       dev->config.mi_config.sp.output.height;
-       } else if (strm == CIF_ISP10_STREAM_MP) {
-               buf->width =
-                       dev->config.mi_config.mp.output.width;
-               buf->height =
-                       dev->config.mi_config.mp.output.height;
-       } else if (strm == CIF_ISP10_STREAM_DMA) {
-               buf->width =
-                       dev->config.mi_config.dma.output.width;
-               buf->height =
-                       dev->config.mi_config.dma.output.height;
-       } else {
-               cif_isp10_pltfrm_pr_err(NULL,
-                       "wrong buffer queue %d\n", queue->type);
-               ret = -EINVAL;
-               goto err;
-       }
-       buf->field = field;
-
-       cif_isp10_pltfrm_pr_dbg(NULL, "%s buffer prepared %dx%d, size %d\n",
-               cif_isp10_v4l2_buf_type_string(queue->type),
-               buf->width, buf->height, size);
-
-       if (buf->state == VIDEOBUF_NEEDS_INIT) {
-               ret = videobuf_iolock(queue, buf, NULL);
-               if (IS_ERR_VALUE(ret)) {
-                       cif_isp10_pltfrm_pr_err(NULL,
-                               "videobuf_iolock failed with error %d\n", ret);
-                       goto err;
-               }
-       }
-       buf->state = VIDEOBUF_PREPARED;
-
-       return 0;
-err:
-       cif_isp10_pltfrm_pr_err(NULL, "failed with error %d\n", ret);
-       cif_isp10_v4l2_buf_release(queue, buf);
-       return ret;
-}
-
 static int cif_isp10_v4l2_reqbufs(
        struct file *file,
        void *priv,
        struct v4l2_requestbuffers *req)
 {
-       struct cif_isp10_v4l2_fh *fh = to_fh(file);
-       struct cif_isp10_v4l2_node *node = to_node(fh);
        int ret;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
        enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
 
-       cif_isp10_pltfrm_pr_dbg(NULL,
-               "%s requested type %s, count %d\n",
-               cif_isp10_v4l2_buf_type_string(queue->type),
-               cif_isp10_v4l2_buf_type_string(req->type),
-               req->count);
-
-       if (node->owner && node->owner != fh)
-               return -EBUSY;
-       node->owner = fh;
-
-       ret = videobuf_reqbufs(queue, req);
+       ret = vb2_ioctl_reqbufs(file, priv, req);
        if (IS_ERR_VALUE(ret)) {
                cif_isp10_pltfrm_pr_err(NULL,
                        "videobuf_reqbufs failed with error %d\n", ret);
@@ -730,13 +577,8 @@ static int cif_isp10_v4l2_querybuf(
        struct v4l2_buffer *buf)
 {
        int ret;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
-
-       cif_isp10_pltfrm_pr_dbg(NULL,
-               "%s, index %d\n",
-               cif_isp10_v4l2_buf_type_string(queue->type), buf->index);
 
-       ret = videobuf_querybuf(queue, buf);
+       ret = vb2_ioctl_querybuf(file, priv, buf);
        if (IS_ERR_VALUE(ret))
                cif_isp10_pltfrm_pr_err(NULL,
                        "videobuf_querybuf failed with error %d\n", ret);
@@ -749,7 +591,7 @@ static int cif_isp10_v4l2_s_ctrl(
        void *priv,
        struct v4l2_control *vc)
 {
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
        enum cif_isp10_cid id =
                cif_isp10_v4l2_cid2cif_isp10_cid(vc->id);
@@ -785,7 +627,7 @@ static int cif_isp10_v4l2_s_fmt(
        struct v4l2_format *f)
 {
        int ret;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
        struct cif_isp10_v4l2_fh *fh = to_fh(file);
        struct cif_isp10_v4l2_node *node = to_node(fh);
@@ -809,6 +651,13 @@ static int cif_isp10_v4l2_s_fmt(
                to_stream_id(file),
                &strm_fmt,
                f->fmt.pix.bytesperline);
+
+       //TODO:: check s_fmt format field and size;
+       f->fmt.pix.field = V4L2_FIELD_NONE;
+       cif_isp10_calc_min_out_buff_size(dev,
+               to_stream_id(file), &f->fmt.pix.sizeimage, false);
+       //f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.sizeimage);
+
        if (IS_ERR_VALUE(ret))
                goto err;
 
@@ -834,7 +683,7 @@ static int cif_isp10_v4l2_s_input(
        unsigned int i)
 {
        int ret;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
 
        cif_isp10_pltfrm_pr_dbg(dev->dev, "setting input to %d\n", i);
@@ -857,7 +706,7 @@ static int cif_isp10_v4l2_enum_framesizes(
 {
        /* THIS FUNCTION IS UNDER CONSTRUCTION */
        int ret;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
 
        if (IS_ERR_OR_NULL(dev->img_src)) {
@@ -873,15 +722,140 @@ err:
        return ret;
 }
 
-/* fops **********************************************************************/
+static int cif_isp10_v4l2_vb2_queue_setup(struct vb2_queue *queue,
+                       const void *parg,
+                       unsigned int *num_buffers, unsigned int *num_planes,
+                       unsigned int sizes[], void *alloc_ctxs[])
+{
+       int ret;
+       struct cif_isp10_device *dev = to_cif_isp10_device(queue);
+       enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
+
+       cif_isp10_pltfrm_pr_dbg(NULL,
+               "%s request planes %d count %d, size %d\n",
+               cif_isp10_v4l2_buf_type_string(queue->type),
+               *num_planes,
+               *num_buffers, sizes[0]);
+
+       if (*num_planes == 0)
+               *num_planes = 1;
+
+       if (*num_buffers == 0)
+               *num_buffers = 4;
+
+       alloc_ctxs[0] = dev->alloc_ctx;
+
+       ret = cif_isp10_calc_min_out_buff_size(dev, strm, &sizes[0], false);
+       //sizes[0] = PAGE_ALIGN(sizes[0] );
+       if (ret)
+               return -EINVAL;
+
+       cif_isp10_pltfrm_pr_dbg(NULL, "%s count %d, size %d\n",
+               cif_isp10_v4l2_buf_type_string(queue->type),
+               *num_buffers, sizes[0]);
+
+       return 0;
+}
+
+static void cif_isp10_v4l2_vb2_queue(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct cif_isp10_buffer *ispbuf = to_cif_isp10_vb(vbuf);
+       struct vb2_queue *queue = vb->vb2_queue;
+       struct cif_isp10_device *dev = to_cif_isp10_device(queue);
+       enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
+       struct cif_isp10_stream *stream = to_stream_by_id(dev, strm);
+       u32 size;
+
+       cif_isp10_pltfrm_pr_dbg(NULL,
+               "buffer type %s\n",
+               cif_isp10_v4l2_buf_type_string(queue->type));
 
-const struct videobuf_queue_ops cif_isp10_qops = {
-       .buf_setup = cif_isp10_v4l2_buf_setup,
-       .buf_prepare = cif_isp10_v4l2_buf_prepare,
-       .buf_queue = cif_isp10_v4l2_buf_queue,
-       .buf_release = cif_isp10_v4l2_buf_release,
+       list_add_tail(&ispbuf->queue, &stream->buf_queue);
+
+       cif_isp10_calc_min_out_buff_size(dev, strm, &size, true);
+       //size = PAGE_ALIGN(size);
+       vb2_set_plane_payload(vb, 0, size);
+}
+
+static void cif_isp10_v4l2_vb2_stop_streaming(struct vb2_queue *queue)
+{
+       struct cif_isp10_v4l2_node *node;
+       enum cif_isp10_stream_id strm = to_cif_isp10_stream_id(queue);
+       struct cif_isp10_stream *stream = NULL;
+       struct cif_isp10_device *dev;
+       struct cif_isp10_buffer *buf, *buf_tmp;
+       unsigned long lock_flags = 0;
+
+       node = queue_to_node(queue);
+
+       dev = video_get_drvdata(&node->vdev);
+
+       stream = to_stream_by_id(dev, strm);
+
+       spin_lock_irqsave(&dev->vbq_lock, lock_flags);
+
+       if (stream->curr_buf) {
+               vb2_buffer_done(&stream->curr_buf->vb.vb2_buf,
+                       VB2_BUF_STATE_ERROR);
+               stream->curr_buf = NULL;
+       }
+       if (stream->next_buf) {
+               vb2_buffer_done(&stream->next_buf->vb.vb2_buf,
+                       VB2_BUF_STATE_ERROR);
+               stream->next_buf = NULL;
+       }
+
+       list_for_each_entry_safe(buf, buf_tmp, &stream->buf_queue, queue) {
+               list_del(&buf->queue);
+               if (buf->vb.vb2_buf.state == VB2_BUF_STATE_ACTIVE)
+                       vb2_buffer_done(&buf->vb.vb2_buf,
+                               VB2_BUF_STATE_ERROR);
+       }
+       spin_unlock_irqrestore(&dev->vbq_lock, lock_flags);
+}
+
+static struct vb2_ops cif_isp10_v4l2_vb2_ops = {
+       .queue_setup    = cif_isp10_v4l2_vb2_queue_setup,
+       .buf_queue      = cif_isp10_v4l2_vb2_queue,
+       //.buf_cleanup  = cif_isp10_v4l2_vb2_release,
+       //.buf_init     = cif_isp10_v4l2_vb2_init,
+       .wait_prepare   = vb2_ops_wait_prepare,
+       .wait_finish    = vb2_ops_wait_finish,
+       .stop_streaming = cif_isp10_v4l2_vb2_stop_streaming,
 };
 
+static int cif_isp10_init_vb2_queue(struct vb2_queue *q,
+       struct cif_isp10_device *dev,
+       enum v4l2_buf_type buf_type)
+{
+       struct cif_isp10_v4l2_node *node;
+
+       memset(q, 0, sizeof(*q));
+       node = queue_to_node(q);
+       mutex_init(&node->qlock);
+
+       q->type = buf_type;
+       q->io_modes = VB2_MMAP | VB2_USERPTR;
+       q->drv_priv = dev;
+       q->ops = &cif_isp10_v4l2_vb2_ops;
+       q->buf_struct_size = sizeof(struct cif_isp10_buffer);
+       q->min_buffers_needed   = 4;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->lock = &node->qlock;
+
+#ifdef CIF_ISP10_MODE_DMA_CONTIG
+       q->mem_ops = &vb2_dma_contig_memops;
+       dev->alloc_ctx = vb2_dma_contig_init_ctx(dev->dev);
+#endif
+
+#ifdef CIF_ISP10_MODE_DMA_SG
+       q->mem_ops = &vb2_dma_sg_memops;
+       dev->alloc_ctx = vb2_dma_sg_init_ctx(dev->dev);
+#endif
+       return vb2_queue_init(q);
+}
+
 static int cif_isp10_v4l2_open(
        struct file *file)
 {
@@ -900,7 +874,7 @@ static int cif_isp10_v4l2_open(
                vdev->num, vdev->minor, vdev->name);
 
        if (vdev->minor == cif_isp10_v4l2_dev->node[SP_DEV].vdev.minor) {
-               buf_type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
+               buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                stream_id = CIF_ISP10_STREAM_SP;
        } else if (vdev->minor == cif_isp10_v4l2_dev->node[MP_DEV].vdev.minor) {
                buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -937,15 +911,8 @@ static int cif_isp10_v4l2_open(
        /* First open of the device, so initialize everything */
        node->owner = NULL;
 
-       videobuf_queue_dma_contig_init(
-               to_videobuf_queue(file),
-               &cif_isp10_qops,
-               dev->dev,
-               &dev->vbq_lock,
-               buf_type,
-               V4L2_FIELD_NONE,
-               sizeof(struct videobuf_buffer),
-               dev, NULL);
+       cif_isp10_init_vb2_queue(to_vb2_queue(file), dev, buf_type);
+       vdev->queue = to_vb2_queue(file);
 
        ret = cif_isp10_init(dev, to_stream_id(file));
        if (IS_ERR_VALUE(ret)) {
@@ -966,7 +933,7 @@ err:
 static int cif_isp10_v4l2_release(struct file *file)
 {
        int ret = 0;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
        struct cif_isp10_v4l2_fh *fh = to_fh(file);
        struct cif_isp10_v4l2_node *node = to_node(fh);
@@ -1006,6 +973,7 @@ static int cif_isp10_v4l2_release(struct file *file)
        return ret;
 }
 
+/*
 static unsigned int cif_isp10_v4l2_poll(
        struct file *file,
        struct poll_table_struct *wait)
@@ -1033,10 +1001,12 @@ static unsigned int cif_isp10_v4l2_poll(
        }
        return ret;
 }
+*/
 
 /*
  * VMA operations.
  */
+/*
 static void cif_isp10_v4l2_vm_open(struct vm_area_struct *vma)
 {
        struct cif_isp10_metadata_s *metadata =
@@ -1076,6 +1046,7 @@ int cif_isp10_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
 done:
        return retval;
 }
+*/
 
 const struct v4l2_file_operations cif_isp10_v4l2_fops = {
        .open = cif_isp10_v4l2_open,
@@ -1084,8 +1055,10 @@ const struct v4l2_file_operations cif_isp10_v4l2_fops = {
        .compat_ioctl32 = video_ioctl2,
 #endif
        .release = cif_isp10_v4l2_release,
-       .poll = cif_isp10_v4l2_poll,
-       .mmap = cif_isp10_v4l2_mmap,
+       //.poll = cif_isp10_v4l2_poll,
+       //.mmap = cif_isp10_v4l2_mmap,
+       .poll = vb2_fop_poll,
+       .mmap = vb2_fop_mmap,
 };
 
 /*TBD: clean up code below this line******************************************/
@@ -1093,8 +1066,7 @@ const struct v4l2_file_operations cif_isp10_v4l2_fops = {
 static int v4l2_querycap(struct file *file,
                         void *priv, struct v4l2_capability *cap)
 {
-       int ret = 0;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct video_device *vdev = video_devdata(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
        u32 stream_ids = to_stream_id(file);
@@ -1105,20 +1077,23 @@ static int v4l2_querycap(struct file *file,
                "platform:" DRIVER_NAME "-%03i",
                dev->dev_id);
 
-       if (stream_ids == CIF_ISP10_STREAM_SP)
-               cap->capabilities = V4L2_CAP_VIDEO_OVERLAY |
-                       V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+       if (stream_ids == CIF_ISP10_STREAM_SP) {
+               cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
                        V4L2_CAP_STREAMING;
-       else if (stream_ids == CIF_ISP10_STREAM_MP)
+               cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE |
+                       V4L2_CAP_STREAMING;
+       } else if (stream_ids == CIF_ISP10_STREAM_MP) {
                cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
-                       V4L2_CAP_VIDEO_CAPTURE_MPLANE |
                        V4L2_CAP_STREAMING;
+               cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE |
+                       V4L2_CAP_STREAMING;
+       }
        else if (stream_ids == CIF_ISP10_STREAM_DMA)
                cap->capabilities = V4L2_CAP_VIDEO_M2M_MPLANE |
                        V4L2_CAP_VIDEO_M2M;
        cap->capabilities |= V4L2_CAP_DEVICE_CAPS;
-       cap->device_caps = V4L2_CAP_DEVICE_CAPS;
-       return ret;
+       cap->device_caps |= V4L2_CAP_DEVICE_CAPS;
+       return 0;
 }
 
 static int cif_isp10_v4l2_subscribe_event(struct v4l2_fh *fh,
@@ -1153,8 +1128,9 @@ static void cif_isp10_v4l2_requeue_bufs(
        struct cif_isp10_device *dev,
        enum cif_isp10_stream_id stream_id)
 {
-       struct videobuf_buffer *buf;
-       struct videobuf_queue *q = NULL;
+       struct cif_isp10_buffer *ispbuf;
+       struct vb2_buffer *buf;
+       struct vb2_queue *q = NULL;
        struct cif_isp10_v4l2_device *cif_isp10_v4l2_dev =
                (struct cif_isp10_v4l2_device *)dev->nodes;
 
@@ -1169,22 +1145,22 @@ static void cif_isp10_v4l2_requeue_bufs(
 
        dev = to_cif_isp10_device(q);
 
-       list_for_each_entry(buf, &q->stream, stream) {
+       list_for_each_entry(buf, &q->queued_list, queued_entry) {
+               ispbuf = to_cif_isp10_vb(to_vb2_v4l2_buffer(buf));
                if (!IS_ERR_VALUE(cif_isp10_qbuf(
-                       to_cif_isp10_device(q), stream_id, buf))) {
+                       to_cif_isp10_device(q), stream_id, ispbuf))) {
                        spin_lock(&dev->vbreq_lock);
-                       if ((buf->state == VIDEOBUF_QUEUED) ||
-                           (buf->state == VIDEOBUF_ACTIVE) ||
-                           (buf->state == VIDEOBUF_DONE))
-                               buf->state = VIDEOBUF_QUEUED;
+                       if ((buf->state == VB2_BUF_STATE_QUEUED) ||
+                           (buf->state == VB2_BUF_STATE_ACTIVE))
+                               buf->state = VB2_BUF_STATE_ACTIVE;
                        else
                                cif_isp10_pltfrm_pr_err(NULL,
-                                       "ERR: buf->state is: %d\n",
-                                       buf->state);
+                                       "skip state change for buf: %d, state: %d\n",
+                                       buf->index, buf->state);
                        spin_unlock(&dev->vbreq_lock);
                } else {
                        cif_isp10_pltfrm_pr_err(NULL,
-                               "failed for buffer %d\n", buf->i);
+                               "failed for buffer %d\n", buf->index);
                }
        }
 }
@@ -1193,7 +1169,7 @@ static long v4l2_default_ioctl(struct file *file, void *fh,
                               bool valid_prio, unsigned int cmd, void *arg)
 {
        int ret = -EINVAL;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
 
        if (!arg) {
@@ -1229,12 +1205,6 @@ static long v4l2_default_ioctl(struct file *file, void *fh,
                        dev->config.isp_config.output.width;
                p_mode_data->isp_output_height =
                        dev->config.isp_config.output.height;
-
-               if (ret < 0) {
-                       cif_isp10_pltfrm_pr_err(dev->dev,
-                               "failed to get isp input info\n");
-                       return ret;
-               }
        } else if (cmd == RK_VIDIOC_CAMERA_MODULEINFO) {
                struct camera_module_info_s *p_camera_module =
                (struct camera_module_info_s *)arg;
@@ -1263,7 +1233,7 @@ static int v4l2_s_parm(
 static int v4l2_enum_input(struct file *file, void *priv,
                           struct v4l2_input *input)
 {
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
        const char *inp_name;
 
@@ -1377,11 +1347,23 @@ static int v4l2_enum_fmt_cap(struct file *file, void *fh,
 static int v4l2_g_ctrl(struct file *file, void *priv,
        struct v4l2_control *vc)
 {
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
        enum cif_isp10_cid id =
                cif_isp10_v4l2_cid2cif_isp10_cid(vc->id);
 
+       if (id == CIF_ISP10_CID_MIN_BUFFER_FOR_CAPTURE) {
+               /* Three buffers needed at least.
+                * one for MI_MP_Y_BASE_AD_INIT, one for MI_MP_Y_BASE_AD_SHD
+                * the other one stay in the waiting queue.
+                */
+               vc->value = 3;
+               cif_isp10_pltfrm_pr_dbg(dev->dev,
+                       "V4L2_CID_MIN_BUFFERS_FOR_CAPTURE %d\n",
+                       vc->value);
+               return 0;
+       }
+
        return cif_isp10_img_src_g_ctrl(dev->img_src,
                id, &vc->value);
 }
@@ -1391,7 +1373,7 @@ static int v4l2_s_ext_ctrls(struct file *file, void *priv,
 {
        struct cif_isp10_img_src_ctrl *ctrls;
        struct cif_isp10_img_src_ext_ctrl *ctrl;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
        int ret = -EINVAL;
        unsigned int i;
@@ -1438,7 +1420,7 @@ int cif_isp10_v4l2_cropcap(
        struct v4l2_cropcap *a)
 {
        int ret = 0;
-       struct videobuf_queue *queue = to_videobuf_queue(file);
+       struct vb2_queue *queue = to_vb2_queue(file);
        struct cif_isp10_device *dev = to_cif_isp10_device(queue);
        u32 target_width, target_height;
        u32 h_offs, v_offs;
@@ -1549,6 +1531,7 @@ int cif_isp10_v4l2_s_crop(
 const struct v4l2_ioctl_ops cif_isp10_v4l2_sp_ioctlops = {
        .vidioc_reqbufs = cif_isp10_v4l2_reqbufs,
        .vidioc_querybuf = cif_isp10_v4l2_querybuf,
+       .vidioc_create_bufs = vb2_ioctl_create_bufs,
        .vidioc_qbuf = cif_isp10_v4l2_qbuf,
        .vidioc_dqbuf = cif_isp10_v4l2_dqbuf,
        .vidioc_streamon = cif_isp10_v4l2_streamon,
@@ -1557,9 +1540,15 @@ const struct v4l2_ioctl_ops cif_isp10_v4l2_sp_ioctlops = {
        .vidioc_enum_input = v4l2_enum_input,
        .vidioc_g_ctrl = v4l2_g_ctrl,
        .vidioc_s_ctrl = cif_isp10_v4l2_s_ctrl,
+       .vidioc_s_fmt_vid_cap = cif_isp10_v4l2_s_fmt,
+       .vidioc_g_fmt_vid_cap = cif_isp10_v4l2_g_fmt,
+       .vidioc_s_fmt_vid_cap_mplane = cif_isp10_v4l2_s_fmt,
+       .vidioc_g_fmt_vid_cap_mplane = cif_isp10_v4l2_g_fmt,
        .vidioc_s_fmt_vid_overlay = cif_isp10_v4l2_s_fmt,
        .vidioc_g_fmt_vid_overlay = cif_isp10_v4l2_g_fmt,
        .vidioc_s_ext_ctrls = v4l2_s_ext_ctrls,
+       .vidioc_enum_fmt_vid_cap = v4l2_enum_fmt_cap,
+       .vidioc_enum_framesizes = cif_isp10_v4l2_enum_framesizes,
        .vidioc_querycap = v4l2_querycap,
        .vidioc_cropcap = cif_isp10_v4l2_cropcap,
        .vidioc_s_crop = cif_isp10_v4l2_s_crop,
@@ -1736,7 +1725,7 @@ static int cif_isp10_v4l2_drv_remove(struct platform_device *pdev)
        video_unregister_device(&cif_isp10_v4l2_dev->node[DMA_DEV].vdev);
        unregister_cifisp_device(&cif_isp10_v4l2_dev->node[ISP_DEV].vdev);
        v4l2_device_unregister(&cif_isp10_dev->v4l2_dev);
-       cif_isp10_pltfrm_dev_release(&pdev->dev);
+       cif_isp10_pltfrm_dev_release(&pdev->dev, cif_isp10_dev);
        cif_isp10_destroy(cif_isp10_dev);
 
        cif_isp10_v4l2_dev_cnt--;