media: mfc: Support buffer batch mode
authorAyoung Sim <a.sim@samsung.com>
Tue, 25 Jul 2017 08:11:29 +0000 (17:11 +0900)
committerSunyoung Kang <sy0816.kang@samsung.com>
Tue, 29 May 2018 06:59:18 +0000 (15:59 +0900)
Eight images in buffer container is handled

Change-Id: I12999f1a5800da019810de3618ce46d14fa41492
Signed-off-by: Jiho Chang <jiho04.chang@samsung.com>
Signed-off-by: Ayoung Sim <a.sim@samsung.com>
12 files changed:
drivers/media/platform/exynos/mfc/s5p_mfc_common.h
drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h
drivers/media/platform/exynos/mfc/s5p_mfc_dec_vb2_ops.c
drivers/media/platform/exynos/mfc/s5p_mfc_enc_vb2_ops.c
drivers/media/platform/exynos/mfc/s5p_mfc_irq.c
drivers/media/platform/exynos/mfc/s5p_mfc_mem.c
drivers/media/platform/exynos/mfc/s5p_mfc_mem.h
drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c
drivers/media/platform/exynos/mfc/s5p_mfc_opr.c
drivers/media/platform/exynos/mfc/s5p_mfc_queue.c
drivers/media/platform/exynos/mfc/s5p_mfc_queue.h
drivers/media/platform/exynos/mfc/s5p_mfc_reg.c

index e97e36ad4228f9a509ee8cffe96b5b0687fb395c..baea4468e290573bca8a0b2862e77c1a416429c6 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/sched/clock.h>
 #include <linux/ion_exynos.h>
+#include <linux/dmabuf_container.h>
 #include <media/videobuf2-dma-sg.h>
 #include <asm/cacheflush.h>
 
 #define ON_RES_CHANGE(ctx)     (((ctx)->state >= MFCINST_RES_CHANGE_INIT) &&   \
                                 ((ctx)->state <= MFCINST_RES_CHANGE_END))
 
+#define IS_BUFFER_BATCH_MODE(ctx)      ((ctx)->num_bufs_in_vb > 0)
+
 /* UHD resoluition */
 #define MFC_UHD_RES            (3840 * 2160)
 #define IS_UHD_RES(ctx)                (((ctx)->img_width * (ctx)->img_height) == MFC_UHD_RES)
index 52115947c6d88fd22d81779c0869da751c718cc1..1b1767038cff286d8bad1a8932524ea40cfb73ec 100644 (file)
@@ -47,6 +47,9 @@
 /* Maximum number of temporal layers */
 #define VIDEO_MAX_TEMPORAL_LAYERS      7
 
+#define MAX_NUM_IMAGES_IN_VB           8
+#define MAX_NUM_BUFCON_BUFS            32
+
 /*
  *  MFC version
  */
@@ -222,7 +225,11 @@ struct s5p_mfc_debug {
 struct s5p_mfc_buf {
        struct vb2_v4l2_buffer vb;
        struct list_head list;
-       dma_addr_t addr[MFC_MAX_PLANES];
+       dma_addr_t addr[MAX_NUM_IMAGES_IN_VB][MFC_MAX_PLANES];
+       struct dma_buf *dmabufs[MAX_NUM_IMAGES_IN_VB][MFC_MAX_PLANES];
+       struct dma_buf_attachment *attachments[MAX_NUM_IMAGES_IN_VB][MFC_MAX_PLANES];
+       int next_index;
+       int done_index;
        int used;
        unsigned char *vir_addr;
 };
@@ -1321,6 +1328,8 @@ struct s5p_mfc_ctx {
        unsigned long raw_protect_flag;
        unsigned long stream_protect_flag;
        struct _otf_handle *otf_handle;
+
+       int num_bufs_in_vb;
 };
 
 #endif /* __S5P_MFC_DATA_STRUCT_H */
index a965d2e0ab8fa4aa905387938b4c4001df692275..cadcd56f31fa687c8bb75758b0ef1b212fed60ee 100644 (file)
@@ -181,26 +181,26 @@ static int s5p_mfc_dec_buf_init(struct vb2_buffer *vb)
 
                start_raw = s5p_mfc_mem_get_daddr_vb(vb, 0);
                if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12N) {
-                       buf->addr[0] = start_raw;
-                       buf->addr[1] = NV12N_CBCR_BASE(start_raw,
+                       buf->addr[0][0] = start_raw;
+                       buf->addr[0][1] = NV12N_CBCR_BASE(start_raw,
                                                        ctx->img_width,
                                                        ctx->img_height);
                } else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12N_10B) {
-                       buf->addr[0] = start_raw;
-                       buf->addr[1] = NV12N_10B_CBCR_BASE(start_raw,
+                       buf->addr[0][0] = start_raw;
+                       buf->addr[0][1] = NV12N_10B_CBCR_BASE(start_raw,
                                                        ctx->img_width,
                                                        ctx->img_height);
                } else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420N) {
-                       buf->addr[0] = start_raw;
-                       buf->addr[1] = YUV420N_CB_BASE(start_raw,
+                       buf->addr[0][0] = start_raw;
+                       buf->addr[0][1] = YUV420N_CB_BASE(start_raw,
                                                        ctx->img_width,
                                                        ctx->img_height);
-                       buf->addr[2] = YUV420N_CR_BASE(start_raw,
+                       buf->addr[0][2] = YUV420N_CR_BASE(start_raw,
                                                        ctx->img_width,
                                                        ctx->img_height);
                } else {
                        for (i = 0; i < ctx->dst_fmt->mem_planes; i++)
-                               buf->addr[i] = s5p_mfc_mem_get_daddr_vb(vb, i);
+                               buf->addr[0][i] = s5p_mfc_mem_get_daddr_vb(vb, i);
                }
 
                if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_DST,
@@ -211,7 +211,7 @@ static int s5p_mfc_dec_buf_init(struct vb2_buffer *vb)
                if (ret < 0)
                        return ret;
 
-               buf->addr[0] = s5p_mfc_mem_get_daddr_vb(vb, 0);
+               buf->addr[0][0] = s5p_mfc_mem_get_daddr_vb(vb, 0);
 
                if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_SRC,
                                        vb->index) < 0)
@@ -580,7 +580,7 @@ static void s5p_mfc_dec_buf_queue(struct vb2_buffer *vb)
                mfc_debug(2, "Src queue: 0x%p\n", &ctx->src_buf_queue);
                mfc_debug(2, "Adding to src: 0x%p (0x%08llx, 0x%08llx)\n", vb,
                                s5p_mfc_mem_get_daddr_vb(vb, 0),
-                               buf->addr[0]);
+                               buf->addr[0][0]);
                if (dec->dst_memtype == V4L2_MEMORY_DMABUF &&
                                ctx->state < MFCINST_HEAD_PARSED && !ctx->is_drm)
                        stream_vir = vb2_plane_vaddr(vb, 0);
@@ -590,7 +590,7 @@ static void s5p_mfc_dec_buf_queue(struct vb2_buffer *vb)
                s5p_mfc_add_tail_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, buf);
 
                MFC_TRACE_CTX("Q src[%d] fd: %d, %#llx\n",
-                               vb->index, vb->planes[0].m.fd, buf->addr[0]);
+                               vb->index, vb->planes[0].m.fd, buf->addr[0][0]);
        } else if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
                index = vb->index;
                mfc_debug(2, "Dst queue: 0x%p\n", &ctx->dst_buf_queue);
@@ -598,7 +598,7 @@ static void s5p_mfc_dec_buf_queue(struct vb2_buffer *vb)
                                s5p_mfc_mem_get_daddr_vb(vb, 0));
                for (i = 0; i < ctx->dst_fmt->num_planes; i++)
                        mfc_debug(2, "dec dst plane[%d]: %08llx\n",
-                                       i, buf->addr[i]);
+                                       i, buf->addr[0][i]);
                s5p_mfc_store_dpb(ctx, vb);
 
                if ((dec->dst_memtype == V4L2_MEMORY_USERPTR || dec->dst_memtype == V4L2_MEMORY_DMABUF) &&
@@ -607,7 +607,7 @@ static void s5p_mfc_dec_buf_queue(struct vb2_buffer *vb)
                        ctx->capture_state = QUEUE_BUFS_MMAPED;
 
                MFC_TRACE_CTX("Q dst[%d] fd: %d, %#llx / avail %#lx used %#x\n",
-                               index, vb->planes[0].m.fd, buf->addr[0],
+                               index, vb->planes[0].m.fd, buf->addr[0][0],
                                dec->available_dpb, dec->dynamic_used);
        } else {
                mfc_err_ctx("Unsupported buffer type (%d)\n", vq->type);
index cc2b04c1d079730811d054afbdfd41141cced790..44a178b83823885f6469e0c0a1354eef839645e6 100644 (file)
@@ -124,7 +124,7 @@ static int s5p_mfc_enc_buf_init(struct vb2_buffer *vb)
        struct vb2_queue *vq = vb->vb2_queue;
        struct s5p_mfc_ctx *ctx = vq->drv_priv;
        struct s5p_mfc_buf *buf = vb_to_mfc_buf(vb);
-       dma_addr_t start_raw;
+       struct dma_buf *dmabuf;
        int i, ret;
 
        mfc_debug_enter();
@@ -134,7 +134,7 @@ static int s5p_mfc_enc_buf_init(struct vb2_buffer *vb)
                if (ret < 0)
                        return ret;
 
-               buf->addr[0] = s5p_mfc_mem_get_daddr_vb(vb, 0);
+               buf->addr[0][0] = s5p_mfc_mem_get_daddr_vb(vb, 0);
 
                if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_DST,
                                        vb->index) < 0)
@@ -145,33 +145,55 @@ static int s5p_mfc_enc_buf_init(struct vb2_buffer *vb)
                if (ret < 0)
                        return ret;
 
-               start_raw = s5p_mfc_mem_get_daddr_vb(vb, 0);
-               if (start_raw == 0) {
-                       mfc_err_ctx("Plane mem not allocated.\n");
-                       return -ENOMEM;
-               }
-               if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12N) {
-                       buf->addr[0] = start_raw;
-                       buf->addr[1] = NV12N_CBCR_BASE(start_raw,
+               for (i = 0; i < ctx->src_fmt->num_planes; i++) {
+                       dmabuf = s5p_mfc_mem_get_dmabuf(vb->planes[i].m.fd);
+                       if (!dmabuf)
+                               return -ENOMEM;
+
+                       ctx->num_bufs_in_vb = s5p_mfc_bufcon_get_buf_count(dmabuf);
+                       mfc_debug(3, "bufcon count:%d\n", ctx->num_bufs_in_vb);
+
+                       if (IS_BUFFER_BATCH_MODE(ctx)) {
+                               int count = 0;
+
+                               count = s5p_mfc_bufcon_get_daddr(ctx, buf, dmabuf, i);
+                               if (count != ctx->num_bufs_in_vb) {
+                                       mfc_err_ctx("invalid buffer count %d != num_bufs_in_vb %d\n",
+                                                       count, ctx->num_bufs_in_vb);
+                                       return -EFAULT;
+                               }
+
+                               s5p_mfc_mem_put_dmabuf(dmabuf);
+                       } else {
+                               dma_addr_t start_raw;
+
+                               start_raw = s5p_mfc_mem_get_daddr_vb(vb, 0);
+                               if (start_raw == 0) {
+                                       mfc_err_ctx("Plane mem not allocated.\n");
+                                       return -ENOMEM;
+                               }
+                               if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12N) {
+                                       buf->addr[0][0] = start_raw;
+                                       buf->addr[0][1] = NV12N_CBCR_BASE(start_raw,
                                                        ctx->img_width,
                                                        ctx->img_height);
-               } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420N) {
-                       buf->addr[0] = start_raw;
-                       buf->addr[1] = YUV420N_CB_BASE(start_raw,
+                               } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420N) {
+                                       buf->addr[0][0] = start_raw;
+                                       buf->addr[0][1] = YUV420N_CB_BASE(start_raw,
                                                        ctx->img_width,
                                                        ctx->img_height);
-                       buf->addr[2] = YUV420N_CR_BASE(start_raw,
+                                       buf->addr[0][2] = YUV420N_CR_BASE(start_raw,
                                                        ctx->img_width,
                                                        ctx->img_height);
-               } else {
-                       for (i = 0; i < ctx->src_fmt->num_planes; i++)
-                               buf->addr[i] = s5p_mfc_mem_get_daddr_vb(vb, i);
-               }
-
-               if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_SRC,
-                                       vb->index) < 0)
-                       mfc_err_ctx("failed in init_buf_ctrls\n");
+                               } else {
+                                       buf->addr[0][i] = s5p_mfc_mem_get_daddr_vb(vb, i);
+                               }
 
+                               if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_SRC,
+                                                       vb->index) < 0)
+                                       mfc_err_ctx("failed in init_buf_ctrls\n");
+                       }
+               }
        } else {
                mfc_err_ctx("inavlid queue type: %d\n", vq->type);
                return -EINVAL;
@@ -371,9 +393,12 @@ static void s5p_mfc_enc_buf_queue(struct vb2_buffer *vb)
 
        mfc_debug_enter();
 
+       buf->next_index = 0;
+       buf->done_index = 0;
+
        if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
                mfc_debug(2, "dst queue: 0x%p\n", &ctx->dst_buf_queue);
-               mfc_debug(2, "Adding to dst vb: 0x%p, addr: %08llx\n", vb, buf->addr[0]);
+               mfc_debug(2, "Adding to dst vb: 0x%p, addr: %08llx\n", vb, buf->addr[0][0]);
 
                /* Mark destination as available for use by MFC */
                s5p_mfc_add_tail_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, buf);
index 9cb1433b908d5b11c769c509b2bcbdd66bb00570..21eaf54f00ba7b8b511ec1f8b1732b5ab69a4302 100644 (file)
@@ -173,7 +173,7 @@ static void mfc_handle_frame_copy_timestamp(struct s5p_mfc_ctx *ctx)
                return;
        }
 
-       ref_mb = s5p_mfc_find_buf(&ctx->buf_queue_lock, &ctx->ref_buf_queue, dec_y_addr);
+       ref_mb = s5p_mfc_find_buf(&ctx->buf_queue_lock, &ctx->ref_buf_queue, dec_y_addr, 0);
        if (ref_mb)
                ref_mb->vb.vb2_buf.timestamp = src_mb->vb.vb2_buf.timestamp;
 }
@@ -192,7 +192,7 @@ static void mfc_handle_frame_output_move(struct s5p_mfc_ctx *ctx,
                mfc_debug(2, "Listing: %d\n", ref_mb->vb.vb2_buf.index);
                /* Check if this is the buffer we're looking for */
                mfc_debug(2, "Found 0x%08llx, looking for 0x%08llx\n",
-                               ref_mb->addr[0], dspl_y_addr);
+                               ref_mb->addr[0][0], dspl_y_addr);
 
                index = ref_mb->vb.vb2_buf.index;
 
@@ -248,12 +248,12 @@ static void mfc_handle_frame_output_del(struct s5p_mfc_ctx *ctx,
        }
 
        ref_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
-                       &ctx->ref_buf_queue, dspl_y_addr);
+                       &ctx->ref_buf_queue, dspl_y_addr, 0);
        if (ref_mb) {
                mfc_debug(2, "Listing: %d\n", ref_mb->vb.vb2_buf.index);
                /* Check if this is the buffer we're looking for */
                mfc_debug(2, "Found 0x%08llx, looking for 0x%08llx\n",
-                               ref_mb->addr[0], dspl_y_addr);
+                               ref_mb->addr[0][0], dspl_y_addr);
 
                index = ref_mb->vb.vb2_buf.index;
 
@@ -484,7 +484,7 @@ static void mfc_handle_ref_frame(struct s5p_mfc_ctx *ctx)
                        &ctx->ref_buf_queue, &ctx->dst_buf_queue, dec_addr);
        if (dst_mb) {
                mfc_debug(2, "Found in dst queue = 0x%08llx, buf = 0x%08llx\n",
-                               dec_addr, dst_mb->addr[0]);
+                               dec_addr, dst_mb->addr[0][0]);
 
                if (!(dec->dynamic_set & s5p_mfc_get_dec_used_flag()))
                        dec->dynamic_used |= dec->dynamic_set;
@@ -779,30 +779,62 @@ static void mfc_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_type)
                        mfc_debug(2, "encoded[%d] addr: 0x%08llx\n",
                                                i, enc_addr[i]);
 
-               src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
-                       &ctx->src_buf_queue, enc_addr[0]);
-               if (src_mb) {
-                       index = src_mb->vb.vb2_buf.index;
-                       if (call_cop(ctx, recover_buf_ctrls_val, ctx,
-                                       &ctx->src_ctrls[index]) < 0)
-                               mfc_err_ctx("failed in recover_buf_ctrls_val\n");
+               if (IS_BUFFER_BATCH_MODE(ctx)) {
+                       src_mb = s5p_mfc_find_first_buf(&ctx->buf_queue_lock,
+                                       &ctx->src_buf_queue, enc_addr[0], ctx->num_bufs_in_vb);
+                       if (src_mb) {
+                               src_mb->done_index++;
+                               mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index);
 
-                       vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+                               index = src_mb->vb.vb2_buf.index;
 
-                       /* encoder src buffer CFW UNPROT */
-                       if (ctx->is_drm)
-                               s5p_mfc_raw_unprotect(ctx, src_mb, index);
-               }
+                               if (call_cop(ctx, recover_buf_ctrls_val, ctx,
+                                                       &ctx->src_ctrls[index]) < 0)
+                                       mfc_err_ctx("failed in recover_buf_ctrls_val\n");
+
+                               /* last image in a buffer container */
+                               if (src_mb->done_index == ctx->num_bufs_in_vb) {
+                                       src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
+                                                       &ctx->src_buf_queue, enc_addr[0],
+                                                       ctx->num_bufs_in_vb);
+                                       if (src_mb) {
+                                               for (i = 0; i < raw->num_planes; i++)
+                                                       s5p_mfc_bufcon_put_daddr(ctx, src_mb, i);
+                                               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+                                       }
+                               }
+
+                               /* encoder src buffer CFW UNPROT */
+                               if (ctx->is_drm)
+                                       s5p_mfc_raw_unprotect(ctx, src_mb, index);
+                       }
+               } else {
+                       /* normal single buffer */
+                       src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
+                                       &ctx->src_buf_queue, enc_addr[0], 0);
+                       if (src_mb) {
+                               index = src_mb->vb.vb2_buf.index;
+                               if (call_cop(ctx, recover_buf_ctrls_val, ctx,
+                                                       &ctx->src_ctrls[index]) < 0)
+                                       mfc_err_ctx("failed in recover_buf_ctrls_val\n");
 
-               ref_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
-                       &ctx->ref_buf_queue, enc_addr[0]);
-               if (ref_mb) {
-                       vb2_buffer_done(&ref_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+                               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
 
-                       /* encoder src buffer CFW UNPROT */
-                       if (ctx->is_drm) {
-                               index = ref_mb->vb.vb2_buf.index;
-                               s5p_mfc_raw_unprotect(ctx, ref_mb, index);
+                               /* encoder src buffer CFW UNPROT */
+                               if (ctx->is_drm)
+                                       s5p_mfc_raw_unprotect(ctx, src_mb, index);
+                       }
+
+                       ref_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
+                                       &ctx->ref_buf_queue, enc_addr[0], 0);
+                       if (ref_mb) {
+                               vb2_buffer_done(&ref_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+                               /* encoder src buffer CFW UNPROT */
+                               if (ctx->is_drm) {
+                                       index = ref_mb->vb.vb2_buf.index;
+                                       s5p_mfc_raw_unprotect(ctx, ref_mb, index);
+                               }
                        }
                }
        } else if (ctx->state == MFCINST_FINISHING) {
@@ -936,6 +968,9 @@ static int mfc_handle_stream(struct s5p_mfc_ctx *ctx)
        /* handle source buffer */
        mfc_handle_stream_input(ctx, slice_type);
 
+       if (IS_BUFFER_BATCH_MODE(ctx))
+               return 0;
+
        if (ctx->enc_res_change_re_input)
                ctx->enc_res_change_re_input = 0;
 
@@ -947,8 +982,10 @@ static int mfc_handle_stream(struct s5p_mfc_ctx *ctx)
                s5p_mfc_move_first_buf_used(&ctx->buf_queue_lock,
                        &ctx->ref_buf_queue, &ctx->src_buf_queue, MFC_QUEUE_ADD_BOTTOM);
 
-               /* slice_type = 4 && strm_size = 0, skipped enable
-                  should be considered */
+               /*
+                * slice_type = 4 && strm_size = 0, skipped enable
+                * should be considered
+                */
                if ((slice_type == -1) && (strm_size == 0))
                        s5p_mfc_change_state(ctx, MFCINST_RUNNING_NO_OUTPUT);
 
index f23ef7fe1f0c2b903f9b2aa8cf9dd85315c29f97..b5957363124fb7ecfe80b5133c95f672ccf61c8a 100644 (file)
@@ -188,3 +188,65 @@ void s5p_mfc_mem_ion_free(struct s5p_mfc_dev *dev,
        special_buf->daddr = 0;
        special_buf->vaddr = NULL;
 }
+
+void s5p_mfc_bufcon_put_daddr(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *mfc_buf, int plane)
+{
+       int i;
+
+       for (i = 0; i < ctx->num_bufs_in_vb; i++) {
+               if (mfc_buf->addr[i][plane]) {
+                       mfc_debug(4, "put batch buf addr[%d][%d]: 0x%08llx\n",
+                                       i, plane, mfc_buf->addr[i][plane]);
+                       ion_iovmm_unmap(mfc_buf->attachments[i][plane], mfc_buf->addr[i][plane]);
+               }
+               if (mfc_buf->attachments[i][plane])
+                       dma_buf_detach(mfc_buf->dmabufs[i][plane], mfc_buf->attachments[i][plane]);
+               if (mfc_buf->dmabufs[i][plane])
+                       dma_buf_put(mfc_buf->dmabufs[i][plane]);
+
+               mfc_buf->addr[i][plane] = 0;
+               mfc_buf->attachments[i][plane] = NULL;
+               mfc_buf->dmabufs[i][plane] = NULL;
+       }
+}
+
+int s5p_mfc_bufcon_get_daddr(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *mfc_buf,
+                                       struct dma_buf *bufcon_dmabuf, int plane)
+{
+       struct s5p_mfc_dev *dev = ctx->dev;
+       struct s5p_mfc_raw_info *raw = &ctx->raw_buf;
+       int i;
+
+       for (i = 0; i < ctx->num_bufs_in_vb; i++) {
+               mfc_buf->dmabufs[i][plane] = dmabuf_container_get_buffer(bufcon_dmabuf, i);
+               if (IS_ERR(mfc_buf->dmabufs[i][plane])) {
+                       mfc_err_ctx("Failed to get dma_buf (err %ld)",
+                                       PTR_ERR(mfc_buf->dmabufs[i][plane]));
+                       goto err_get_daddr;
+               }
+
+               mfc_buf->attachments[i][plane] = dma_buf_attach(mfc_buf->dmabufs[i][plane], dev->device);
+               if (IS_ERR(mfc_buf->attachments[i][plane])) {
+                       mfc_err_ctx("Failed to get dma_buf_attach (err %ld)",
+                                       PTR_ERR(mfc_buf->attachments[i][plane]));
+                       goto err_get_daddr;
+               }
+
+               mfc_buf->addr[i][plane] = ion_iovmm_map(mfc_buf->attachments[i][plane], 0,
+                               raw->plane_size[plane], DMA_BIDIRECTIONAL, 0);
+               if (IS_ERR_VALUE(mfc_buf->addr[i][plane])) {
+                       mfc_err_ctx("Failed to allocate iova (err %pa)",
+                                       &mfc_buf->addr[i][plane]);
+                       goto err_get_daddr;
+               }
+
+               mfc_debug(4, "get batch buf addr[%d][%d]: 0x%08llx, size: %d\n",
+                               i, plane, mfc_buf->addr[i][plane], raw->plane_size[plane]);
+       }
+
+       return i;
+
+err_get_daddr:
+       s5p_mfc_bufcon_put_daddr(ctx, mfc_buf, plane);
+       return -1;
+}
index 51d2746620436138c67d3527ec9d63062585bbcb..eb14659edca2c0a9eec4f3ebabe23139fc673d60 100644 (file)
@@ -30,6 +30,26 @@ static inline dma_addr_t s5p_mfc_mem_get_daddr_vb(
        return addr;
 }
 
+static inline struct dma_buf *s5p_mfc_mem_get_dmabuf(int fd)
+{
+       struct dma_buf *dmabuf = NULL;
+
+       dmabuf = dma_buf_get(fd);
+       WARN_ON(dmabuf == NULL);
+
+       return dmabuf;
+}
+
+static inline void s5p_mfc_mem_put_dmabuf(struct dma_buf *dmabuf)
+{
+       dma_buf_put(dmabuf);
+}
+
+static inline int s5p_mfc_bufcon_get_buf_count(struct dma_buf *dmabuf)
+{
+       return dmabuf_container_get_count(dmabuf);
+}
+
 struct vb2_mem_ops *s5p_mfc_mem_ops(void);
 
 void s5p_mfc_mem_set_cacheable(bool cacheable);
@@ -50,4 +70,7 @@ int s5p_mfc_mem_ion_alloc(struct s5p_mfc_dev *dev,
 void s5p_mfc_mem_ion_free(struct s5p_mfc_dev *dev,
                struct s5p_mfc_special_buf *special_buf);
 
+void s5p_mfc_bufcon_put_daddr(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *mfc_buf, int plane);
+int s5p_mfc_bufcon_get_daddr(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *mfc_buf,
+                                       struct dma_buf *bufcon_dmabuf, int plane);
 #endif /* __S5P_MFC_MEM_H */
index 2feab06f40187685e895d15f555e9290520e1ace..62d358e29782e042c783e2e0b56fe5fc90213280 100644 (file)
@@ -550,7 +550,7 @@ static int mfc_nal_q_run_in_buf_enc(struct s5p_mfc_ctx *ctx, EncoderInputStr *pI
        struct s5p_mfc_buf *src_mb, *dst_mb;
        struct s5p_mfc_raw_info *raw = NULL;
        dma_addr_t src_addr[3] = {0, 0, 0};
-       dma_addr_t addr_2bit[2];
+       dma_addr_t addr_2bit[2] = {0, 0};
        unsigned int index, i;
 
        mfc_debug_enter();
@@ -571,18 +571,46 @@ static int mfc_nal_q_run_in_buf_enc(struct s5p_mfc_ctx *ctx, EncoderInputStr *pI
 
        raw = &ctx->raw_buf;
 
-       /* move src_queue -> src_queue_nal_q */
-       src_mb = s5p_mfc_get_move_buf(&ctx->buf_queue_lock,
-               &ctx->src_buf_nal_queue, &ctx->src_buf_queue, MFC_BUF_SET_USED, MFC_QUEUE_ADD_BOTTOM);
-       if (!src_mb) {
-               mfc_err_dev("NAL Q: no src buffers\n");
-               return -EAGAIN;
-       }
+       if (IS_BUFFER_BATCH_MODE(ctx)) {
+               src_mb = s5p_mfc_get_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_SET_USED);
+               if (!src_mb) {
+                       mfc_err_dev("NAL Q: no src buffers\n");
+                       return -EAGAIN;
+               }
 
-       for (i = 0; i < raw->num_planes; i++) {
-               src_addr[i] = src_mb->addr[i];
-               mfc_debug(2, "NAL Q: enc src[%d] addr: 0x%08llx\n",
-                               i, src_addr[i]);
+               /* last image in a buffer container */
+               /* move src_queue -> src_queue_nal_q */
+               if (src_mb->next_index == (ctx->num_bufs_in_vb - 1)) {
+                       src_mb = s5p_mfc_get_move_buf(&ctx->buf_queue_lock,
+                                       &ctx->src_buf_nal_queue, &ctx->src_buf_queue,
+                                       MFC_BUF_SET_USED, MFC_QUEUE_ADD_BOTTOM);
+                       if (!src_mb) {
+                               mfc_err_dev("NAL Q: no src buffers\n");
+                               return -EAGAIN;
+                       }
+               }
+
+               for (i = 0; i < raw->num_planes; i++) {
+                       src_addr[i] = src_mb->addr[src_mb->next_index][i];
+                       mfc_debug(2, "NAL Q: enc batch buf[%d] src[%d] addr: 0x%08llx\n",
+                                       src_mb->next_index, i, src_addr[i]);
+               }
+               src_mb->next_index++;
+       } else {
+               /* move src_queue -> src_queue_nal_q */
+               src_mb = s5p_mfc_get_move_buf(&ctx->buf_queue_lock,
+                               &ctx->src_buf_nal_queue, &ctx->src_buf_queue,
+                               MFC_BUF_SET_USED, MFC_QUEUE_ADD_BOTTOM);
+               if (!src_mb) {
+                       mfc_err_dev("NAL Q: no src buffers\n");
+                       return -EAGAIN;
+               }
+
+               for (i = 0; i < raw->num_planes; i++) {
+                       src_addr[i] = src_mb->addr[0][i];
+                       mfc_debug(2, "NAL Q: enc src[%d] addr: 0x%08llx\n",
+                                       i, src_addr[i]);
+               }
        }
 
        for (i = 0; i < raw->num_planes; i++)
@@ -612,7 +640,7 @@ static int mfc_nal_q_run_in_buf_enc(struct s5p_mfc_ctx *ctx, EncoderInputStr *pI
                return -EAGAIN;
        }
 
-       pInStr->StreamBufferAddr = dst_mb->addr[0];
+       pInStr->StreamBufferAddr = dst_mb->addr[0][0];
        pInStr->StreamBufferSize = (unsigned int)vb2_plane_size(&dst_mb->vb.vb2_buf, 0);
        pInStr->StreamBufferSize = ALIGN(pInStr->StreamBufferSize, 512);
 
@@ -695,7 +723,7 @@ static int mfc_nal_q_run_in_buf_dec(struct s5p_mfc_ctx *ctx, DecoderInputStr *pI
        }
 
        /* src buffer setting */
-       buf_addr = src_mb->addr[0];
+       buf_addr = src_mb->addr[0][0];
        strm_size = src_mb->vb.vb2_buf.planes[0].bytesused;
        cpb_buf_size = ALIGN(dec->src_buf_size, STREAM_BUF_ALIGN);
        mfc_debug(2, "NAL Q: Src addr: 0x%08llx, size: %d\n", buf_addr, strm_size);
@@ -727,10 +755,10 @@ static int mfc_nal_q_run_in_buf_dec(struct s5p_mfc_ctx *ctx, DecoderInputStr *pI
 
        for (i = 0; i < raw->num_planes; i++) {
                pInStr->FrameSize[i] = raw->plane_size[i];
-               pInStr->FrameAddr[i] = dst_mb->addr[i];
+               pInStr->FrameAddr[i] = dst_mb->addr[0][i];
        }
        mfc_debug(2, "NAL Q: dst addr[0]: 0x%08llx\n",
-                       dst_mb->addr[0]);
+                       dst_mb->addr[0][0]);
 
        pInStr->ScratchBufAddr = ctx->codec_buf.daddr;
        pInStr->ScratchBufSize = ctx->scratch_buf_size;
@@ -747,7 +775,7 @@ static int mfc_nal_q_run_in_buf_dec(struct s5p_mfc_ctx *ctx, DecoderInputStr *pI
        pInStr->AvailableDpbFlagLower = dec->dynamic_set;
 
        MFC_TRACE_CTX("Set dst[%d] fd: %d, %#llx / avail %#lx used %#x\n",
-                       dst_index, dst_mb->vb.vb2_buf.planes[0].m.fd, dst_mb->addr[0],
+                       dst_index, dst_mb->vb.vb2_buf.planes[0].m.fd, dst_mb->addr[0][0],
                        dec->available_dpb, dec->dynamic_used);
 
        mfc_debug_leave();
@@ -771,13 +799,115 @@ static void mfc_nal_q_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
        mfc_debug(2, "NAL Q: recon c addr: 0x%08lx\n", enc_recon_c_addr);
 }
 
+static void mfc_nal_q_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_type,
+                               unsigned int strm_size, EncoderOutputStr *pOutStr)
+{
+       struct s5p_mfc_buf *src_mb, *ref_mb, *dst_mb;
+       dma_addr_t enc_addr[3] = { 0, 0, 0 };
+       struct s5p_mfc_raw_info *raw;
+       unsigned int i;
+
+       raw = &ctx->raw_buf;
+
+       if (slice_type >= 0) {
+               if (ctx->state == MFCINST_RUNNING_NO_OUTPUT ||
+                       ctx->state == MFCINST_RUNNING_BUF_FULL)
+                       ctx->state = MFCINST_RUNNING;
+
+               mfc_nal_q_get_enc_frame_buffer(ctx, &enc_addr[0],
+                                       raw->num_planes, pOutStr);
+
+               for (i = 0; i < raw->num_planes; i++)
+                       mfc_debug(2, "NAL Q: encoded[%d] addr: 0x%08llx\n", i,
+                                       enc_addr[i]);
+
+               if (IS_BUFFER_BATCH_MODE(ctx)) {
+                       src_mb = s5p_mfc_find_first_buf(&ctx->buf_queue_lock,
+                               &ctx->src_buf_queue, enc_addr[0], ctx->num_bufs_in_vb);
+                       if (src_mb) {
+                               src_mb->done_index++;
+                               mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index);
+                       } else {
+                               src_mb = s5p_mfc_find_first_buf(&ctx->buf_queue_lock,
+                                               &ctx->src_buf_nal_queue, enc_addr[0], ctx->num_bufs_in_vb);
+                               if (src_mb) {
+                                       src_mb->done_index++;
+                                       mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index);
+
+                                       /* last image in a buffer container */
+                                       if (src_mb->done_index == ctx->num_bufs_in_vb) {
+                                               src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
+                                                               &ctx->src_buf_nal_queue, enc_addr[0],
+                                                               ctx->num_bufs_in_vb);
+                                               if (src_mb) {
+                                                       for (i = 0; i < raw->num_planes; i++)
+                                                               s5p_mfc_bufcon_put_daddr(ctx, src_mb, i);
+                                                       vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+                                               }
+                                       }
+                               }
+                       }
+               } else {
+                       src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
+                                       &ctx->src_buf_nal_queue, enc_addr[0], 0);
+                       if (!src_mb) {
+                               mfc_err_dev("NAL Q: no src buffers\n");
+                               return;
+                       }
+
+                       vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+                       ref_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
+                                       &ctx->ref_buf_queue, enc_addr[0], 0);
+                       if (ref_mb)
+                               vb2_buffer_done(&ref_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+               }
+       } else if (s5p_mfc_is_queue_count_greater(&ctx->buf_queue_lock, &ctx->src_buf_nal_queue, 0)) {
+               if (IS_BUFFER_BATCH_MODE(ctx))
+                       return;
+
+               src_mb = s5p_mfc_get_move_buf_used(&ctx->buf_queue_lock,
+                               &ctx->ref_buf_queue, &ctx->src_buf_nal_queue);
+               if (!src_mb) {
+                       mfc_err_dev("NAL Q: no src buffers\n");
+                       return;
+               }
+
+               if (src_mb->used) {
+                       mfc_debug(2, "NAL Q: no output, src_queue_nal_q -> ref_queue, index:%d\n",
+                                       src_mb->vb.vb2_buf.index);
+               }
+
+               /*
+                * slice_type = 4 && strm_size = 0, skipped enable
+                * should be considered
+                */
+               if ((slice_type == -1) && (strm_size == 0)) {
+                       ctx->state = MFCINST_RUNNING_NO_OUTPUT;
+
+                       dst_mb = s5p_mfc_get_move_buf(&ctx->buf_queue_lock,
+                               &ctx->dst_buf_queue, &ctx->dst_buf_nal_queue, MFC_BUF_RESET_USED, MFC_QUEUE_ADD_TOP);
+                       if (!dst_mb) {
+                               mfc_err_dev("NAL Q: no dst buffers\n");
+                               return;
+                       }
+
+                       mfc_debug(2, "NAL Q: no output, dst_buf_nal_queue -> dst_buf_queue, index:%d\n",
+                                       dst_mb->vb.vb2_buf.index);
+               }
+
+               mfc_debug(2, "NAL Q: slice_type: %d, ctx->state: %d\n", slice_type, ctx->state);
+               mfc_debug(2, "NAL Q: enc src count: %d, enc ref count: %d\n",
+                         s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_queue),
+                         s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->ref_buf_queue));
+       }
+}
+
 static void mfc_nal_q_handle_stream(struct s5p_mfc_ctx *ctx, EncoderOutputStr *pOutStr)
 {
        struct s5p_mfc_enc *enc = ctx->enc_priv;
-       struct s5p_mfc_buf *src_mb, *dst_mb, *ref_mb;
-       struct s5p_mfc_raw_info *raw;
-       dma_addr_t enc_addr[3] = { 0, 0, 0 };
-       int slice_type, i;
+       struct s5p_mfc_buf *dst_mb;
+       int slice_type;
        unsigned int strm_size;
        unsigned int pic_count;
        unsigned int index;
@@ -799,9 +929,10 @@ static void mfc_nal_q_handle_stream(struct s5p_mfc_ctx *ctx, EncoderOutputStr *p
 */
        /* set encoded frame type */
        enc->frame_type = slice_type;
-       raw = &ctx->raw_buf;
 
        ctx->sequence++;
+
+       /* handle output buffer */
        if (strm_size > 0) {
                /* at least one more dest. buffers exist always  */
                dst_mb = s5p_mfc_get_del_buf(&ctx->buf_queue_lock, &ctx->dst_buf_nal_queue, MFC_BUF_NO_TOUCH_USED);
@@ -851,65 +982,8 @@ static void mfc_nal_q_handle_stream(struct s5p_mfc_ctx *ctx, EncoderOutputStr *p
                        vb2_buffer_done(&dst_mb->vb.vb2_buf, VB2_BUF_STATE_ERROR);
        }
 
-       if (slice_type >= 0) {
-               if (ctx->state == MFCINST_RUNNING_NO_OUTPUT ||
-                       ctx->state == MFCINST_RUNNING_BUF_FULL)
-                       ctx->state = MFCINST_RUNNING;
-
-               mfc_nal_q_get_enc_frame_buffer(ctx, &enc_addr[0],
-                                       raw->num_planes, pOutStr);
-
-               for (i = 0; i < raw->num_planes; i++)
-                       mfc_debug(2, "NAL Q: encoded[%d] addr: 0x%08llx\n", i,
-                                       enc_addr[i]);
-
-               src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
-                               &ctx->src_buf_nal_queue, enc_addr[0]);
-               if (!src_mb) {
-                       mfc_err_dev("NAL Q: no src buffers\n");
-                       return;
-               }
-
-               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-
-               ref_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
-                               &ctx->ref_buf_queue, enc_addr[0]);
-               if (ref_mb)
-                       vb2_buffer_done(&ref_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-       } else if (s5p_mfc_is_queue_count_greater(&ctx->buf_queue_lock, &ctx->src_buf_nal_queue, 0)) {
-               src_mb = s5p_mfc_get_move_buf_used(&ctx->buf_queue_lock,
-                               &ctx->ref_buf_queue, &ctx->src_buf_nal_queue);
-               if (!src_mb) {
-                       mfc_err_dev("NAL Q: no src buffers\n");
-                       return;
-               }
-
-               if (src_mb->used) {
-                       mfc_debug(2, "NAL Q: no output, src_queue_nal_q -> ref_queue, index:%d\n",
-                                       src_mb->vb.vb2_buf.index);
-               }
-
-               /* slice_type = 4 && strm_size = 0, skipped enable
-                  should be considered */
-               if ((slice_type == -1) && (strm_size == 0)) {
-                       ctx->state = MFCINST_RUNNING_NO_OUTPUT;
-
-                       dst_mb = s5p_mfc_get_move_buf(&ctx->buf_queue_lock,
-                               &ctx->dst_buf_queue, &ctx->dst_buf_nal_queue, MFC_BUF_RESET_USED, MFC_QUEUE_ADD_TOP);
-                       if (!dst_mb) {
-                               mfc_err_dev("NAL Q: no dst buffers\n");
-                               return;
-                       }
-
-                       mfc_debug(2, "NAL Q: no output, dst_buf_nal_queue -> dst_buf_queue, index:%d\n",
-                                       dst_mb->vb.vb2_buf.index);
-               }
-
-               mfc_debug(2, "NAL Q: slice_type: %d, ctx->state: %d\n", slice_type, ctx->state);
-               mfc_debug(2, "NAL Q: enc src count: %d, enc ref count: %d\n",
-                         s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_queue),
-                         s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->ref_buf_queue));
-       }
+       /* handle input buffer */
+       mfc_nal_q_handle_stream_input(ctx, slice_type, strm_size, pOutStr);
 
        mfc_debug_leave();
 
@@ -970,7 +1044,7 @@ static void mfc_nal_q_handle_ref_frame(struct s5p_mfc_ctx *ctx, DecoderOutputStr
        dst_mb = s5p_mfc_find_move_buf_used(&ctx->buf_queue_lock,
                &ctx->ref_buf_queue, &ctx->dst_buf_nal_queue, dec_addr);
        if (dst_mb) {
-               buf_addr = dst_mb->addr[0];
+               buf_addr = dst_mb->addr[0][0];
                mfc_debug(2, "NAL Q: Found in dst queue, "
                                "dec addr: 0x%08llx, buf addr: 0x%08llx, used: %d\n",
                                dec_addr, buf_addr, dst_mb->used);
@@ -1011,7 +1085,7 @@ static void mfc_nal_q_handle_frame_copy_timestamp(struct s5p_mfc_ctx *ctx, Decod
                return;
        }
 
-       ref_mb = s5p_mfc_find_buf(&ctx->buf_queue_lock, &ctx->ref_buf_queue, dec_y_addr);
+       ref_mb = s5p_mfc_find_buf(&ctx->buf_queue_lock, &ctx->ref_buf_queue, dec_y_addr, 0);
        if (ref_mb)
                ref_mb->vb.vb2_buf.timestamp = src_mb->vb.vb2_buf.timestamp;
 
@@ -1032,7 +1106,7 @@ static void mfc_nal_q_handle_frame_output_move(struct s5p_mfc_ctx *ctx,
                mfc_debug(2, "NAL Q: find display buf, index: %d\n", dst_mb->vb.vb2_buf.index);
                /* Check if this is the buffer we're looking for */
                mfc_debug(2, "NAL Q: buf addr: 0x%08llx, disp addr: 0x%08llx\n",
-                               dst_mb->addr[0], dspl_y_addr);
+                               dst_mb->addr[0][0], dspl_y_addr);
 
                index = dst_mb->vb.vb2_buf.index;
 
@@ -1090,12 +1164,12 @@ static void mfc_nal_q_handle_frame_output_del(struct s5p_mfc_ctx *ctx,
        }
 
        ref_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
-                       &ctx->ref_buf_queue, dspl_y_addr);
+                       &ctx->ref_buf_queue, dspl_y_addr, 0);
        if (ref_mb) {
                mfc_debug(2, "NAL Q: find display buf, index: %d\n", ref_mb->vb.vb2_buf.index);
                /* Check if this is the buffer we're looking for */
                mfc_debug(2, "NAL Q: buf addr: 0x%08llx, disp addr: 0x%08llx\n",
-                               ref_mb->addr[0], dspl_y_addr);
+                               ref_mb->addr[0][0], dspl_y_addr);
 
                index = ref_mb->vb.vb2_buf.index;
 
index 07d1223275feb30b14d5abbc04f7651346d9b89b..cea014465a0550d4a1304acd9de21ea450cac137 100644 (file)
@@ -62,7 +62,7 @@ int s5p_mfc_run_dec_init(struct s5p_mfc_ctx *ctx)
                        0, src_mb->vb.vb2_buf.planes[0].bytesused);
        }
 
-       mfc_debug(2, "Header addr: 0x%08llx\n", src_mb->addr[0]);
+       mfc_debug(2, "Header addr: 0x%08llx\n", src_mb->addr[0][0]);
        s5p_mfc_clean_ctx_int_flags(ctx);
        s5p_mfc_init_decode(ctx);
 
@@ -235,7 +235,7 @@ int s5p_mfc_run_enc_init(struct s5p_mfc_ctx *ctx)
 
        s5p_mfc_set_enc_stride(ctx);
 
-       mfc_debug(2, "Header addr: 0x%08llx\n", dst_mb->addr[0]);
+       mfc_debug(2, "Header addr: 0x%08llx\n", dst_mb->addr[0][0]);
        s5p_mfc_clean_ctx_int_flags(ctx);
 
        ret = s5p_mfc_init_encode(ctx);
@@ -259,7 +259,13 @@ int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
                return -EAGAIN;
        }
 
-       last_frame = mfc_check_last_frame(ctx, src_mb);
+       if (IS_BUFFER_BATCH_MODE(ctx)) {
+               /* last image in a buffer container */
+               if (src_mb->next_index == (ctx->num_bufs_in_vb - 1))
+                       last_frame = mfc_check_last_frame(ctx, src_mb);
+       } else {
+               last_frame = mfc_check_last_frame(ctx, src_mb);
+       }
 
        index = src_mb->vb.vb2_buf.index;
 
index 235dd26371870eae5a5d621a66884ad6409071a2..2d326a83dea996a2c635fdb0aa78ba55a7f3133a 100644 (file)
@@ -56,7 +56,7 @@ int s5p_mfc_peek_buf_csd(spinlock_t *plock, struct s5p_mfc_buf_queue *queue)
        csd = mfc_buf->vb.reserved2 & FLAG_CSD ? 1 : 0;
 
        mfc_debug(2, "mfc_buf: 0x%p\n", mfc_buf);
-       mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0]);
+       mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0][0]);
 
        spin_unlock_irqrestore(plock, flags);
        return csd;
@@ -82,7 +82,7 @@ struct s5p_mfc_buf *s5p_mfc_get_buf(spinlock_t *plock, struct s5p_mfc_buf_queue
                mfc_buf->used = used;
 
        mfc_debug(2, "mfc_buf: 0x%p\n", mfc_buf);
-       mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0]);
+       mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0][0]);
 
        spin_unlock_irqrestore(plock, flags);
        return mfc_buf;
@@ -108,7 +108,7 @@ struct s5p_mfc_buf *s5p_mfc_get_del_buf(spinlock_t *plock, struct s5p_mfc_buf_qu
                mfc_buf->used = used;
 
        mfc_debug(2, "mfc_buf: 0x%p\n", mfc_buf);
-       mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0]);
+       mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0][0]);
 
        list_del(&mfc_buf->list);
        queue->count--;
@@ -135,7 +135,7 @@ struct s5p_mfc_buf *s5p_mfc_get_del_if_consumed(spinlock_t *plock, struct s5p_mf
        mfc_buf = list_entry(queue->head.next, struct s5p_mfc_buf, list);
 
        mfc_debug(2, "mfc_buf: 0x%p\n", mfc_buf);
-       mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0]);
+       mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0][0]);
 
        remained = (unsigned int)(mfc_buf->vb.vb2_buf.planes[0].bytesused - consumed);
 
@@ -178,7 +178,7 @@ struct s5p_mfc_buf *s5p_mfc_get_move_buf(spinlock_t *plock,
                mfc_buf->used = used;
 
        mfc_debug(2, "mfc_buf: 0x%p\n", mfc_buf);
-       mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0]);
+       mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0][0]);
 
        list_del(&mfc_buf->list);
        from_queue->count--;
@@ -212,7 +212,7 @@ struct s5p_mfc_buf *s5p_mfc_get_move_buf_used(spinlock_t *plock,
 
        if (mfc_buf->used) {
                mfc_debug(2, "mfc_buf: 0x%p\n", mfc_buf);
-               mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0]);
+               mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0][0]);
 
                list_del(&mfc_buf->list);
                from_queue->count--;
@@ -245,8 +245,9 @@ struct s5p_mfc_buf *s5p_mfc_get_move_buf_addr(spinlock_t *plock,
 
        mfc_buf = list_entry(from_queue->head.next, struct s5p_mfc_buf, list);
 
-       if (mfc_buf->addr[0] == addr) {
-               mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0]);
+       if (mfc_buf->addr[0][0] == addr) {
+               mfc_debug(2, "mfc_buf: 0x%p\n", mfc_buf);
+               mfc_debug(2, "First plane address: 0x%08llx\n", mfc_buf->addr[0][0]);
 
                list_del(&mfc_buf->list);
                from_queue->count--;
@@ -262,18 +263,35 @@ struct s5p_mfc_buf *s5p_mfc_get_move_buf_addr(spinlock_t *plock,
        }
 }
 
-struct s5p_mfc_buf *s5p_mfc_find_buf(spinlock_t *plock, struct s5p_mfc_buf_queue *queue,
-               dma_addr_t addr)
+struct s5p_mfc_buf *s5p_mfc_find_first_buf(spinlock_t *plock, struct s5p_mfc_buf_queue *queue,
+               dma_addr_t addr, int search_queue)
 {
        unsigned long flags;
        struct s5p_mfc_buf *mfc_buf = NULL;
        dma_addr_t mb_addr;
+       int i;
 
        spin_lock_irqsave(plock, flags);
 
+       if (list_empty(&queue->head)) {
+               mfc_debug(2, "queue is empty\n");
+               spin_unlock_irqrestore(plock, flags);
+               return mfc_buf;
+       }
+
        mfc_debug(2, "Looking for this address: 0x%08llx\n", addr);
-       list_for_each_entry(mfc_buf, &queue->head, list) {
-               mb_addr = mfc_buf->addr[0];
+       mfc_buf = list_entry(queue->head.next, struct s5p_mfc_buf, list);
+       if (search_queue > 0) {
+               for (i = 0; i < search_queue; i++) {
+                       mb_addr = mfc_buf->addr[i][0];
+                       mfc_debug(2, "batch buf[%d] plane[0] addr: 0x%08llx\n", i, mb_addr);
+                       if (addr == mb_addr) {
+                               spin_unlock_irqrestore(plock, flags);
+                               return mfc_buf;
+                       }
+               }
+       } else {
+               mb_addr = mfc_buf->addr[0][0];
                mfc_debug(2, "plane[0] addr: 0x%08llx\n", mb_addr);
 
                if (addr == mb_addr) {
@@ -286,24 +304,75 @@ struct s5p_mfc_buf *s5p_mfc_find_buf(spinlock_t *plock, struct s5p_mfc_buf_queue
        return NULL;
 }
 
+struct s5p_mfc_buf *s5p_mfc_find_buf(spinlock_t *plock, struct s5p_mfc_buf_queue *queue,
+               dma_addr_t addr, int search_queue)
+{
+       unsigned long flags;
+       struct s5p_mfc_buf *mfc_buf = NULL;
+       dma_addr_t mb_addr;
+       int i;
+
+       spin_lock_irqsave(plock, flags);
+
+       mfc_debug(2, "Looking for this address: 0x%08llx\n", addr);
+       list_for_each_entry(mfc_buf, &queue->head, list) {
+               if (search_queue > 0) {
+                       for (i = 0; i < search_queue; i++) {
+                               mb_addr = mfc_buf->addr[i][0];
+                               mfc_debug(2, "batch buf[%d] plane[0] addr: 0x%08llx\n", i, mb_addr);
+                               if (addr == mb_addr) {
+                                       spin_unlock_irqrestore(plock, flags);
+                                       return mfc_buf;
+                               }
+                       }
+               } else {
+                       mb_addr = mfc_buf->addr[0][0];
+                       mfc_debug(2, "plane[0] addr: 0x%08llx\n", mb_addr);
+
+                       if (addr == mb_addr) {
+                               spin_unlock_irqrestore(plock, flags);
+                               return mfc_buf;
+                       }
+               }
+       }
+
+       spin_unlock_irqrestore(plock, flags);
+       return NULL;
+}
+
 struct s5p_mfc_buf *s5p_mfc_find_del_buf(spinlock_t *plock, struct s5p_mfc_buf_queue *queue,
-               dma_addr_t addr)
+               dma_addr_t addr, int search_queue)
 {
        unsigned long flags;
        struct s5p_mfc_buf *mfc_buf = NULL;
        dma_addr_t mb_addr;
-       int found = 0;
+       int found = 0, i;
 
        spin_lock_irqsave(plock, flags);
 
        mfc_debug(2, "Looking for this address: 0x%08llx\n", addr);
        list_for_each_entry(mfc_buf, &queue->head, list) {
-               mb_addr = mfc_buf->addr[0];
-               mfc_debug(2, "plane[0] addr: 0x%08llx\n", mb_addr);
+               if (search_queue > 0) {
+                       for (i = 0; i < search_queue; i++) {
+                               mb_addr = mfc_buf->addr[i][0];
+                               mfc_debug(2, "batch buf[%d] plane[0] addr: 0x%08llx\n", i, mb_addr);
+
+                               if (addr == mb_addr) {
+                                       found = 1;
+                                       break;
+                               }
+                       }
 
-               if (addr == mb_addr) {
-                       found = 1;
-                       break;
+                       if (found)
+                               break;
+               } else {
+                       mb_addr = mfc_buf->addr[0][0];
+                       mfc_debug(2, "plane[0] addr: 0x%08llx\n", mb_addr);
+
+                       if (addr == mb_addr) {
+                               found = 1;
+                               break;
+                       }
                }
        }
 
@@ -332,7 +401,7 @@ struct s5p_mfc_buf *s5p_mfc_find_move_buf(spinlock_t *plock,
 
        mfc_debug(2, "Looking for this address: 0x%08llx\n", addr);
        list_for_each_entry(mfc_buf, &from_queue->head, list) {
-               mb_addr = mfc_buf->addr[0];
+               mb_addr = mfc_buf->addr[0][0];
                mfc_debug(2, "plane[0] addr: 0x%08llx\n", mb_addr);
 
                if (addr == mb_addr) {
@@ -371,7 +440,7 @@ struct s5p_mfc_buf *s5p_mfc_find_move_buf_used(spinlock_t *plock,
 
        mfc_debug(2, "Looking for this address: 0x%08llx\n", addr);
        list_for_each_entry(mfc_buf, &from_queue->head, list) {
-               mb_addr = mfc_buf->addr[0];
+               mb_addr = mfc_buf->addr[0][0];
                mfc_debug(2, "plane[0] addr: 0x%08llx, used: %d\n",
                                mb_addr, mfc_buf->used);
 
@@ -900,7 +969,7 @@ int s5p_mfc_is_last_frame(struct s5p_mfc_ctx *ctx)
        src_mb = list_entry(ctx->src_buf_queue.head.next, struct s5p_mfc_buf, list);
 
        mfc_debug(2, "mfc_buf: 0x%p\n", src_mb);
-       mfc_debug(2, "First plane address: 0x%08llx\n", src_mb->addr[0]);
+       mfc_debug(2, "First plane address: 0x%08llx\n", src_mb->addr[0][0]);
 
        if (src_mb->vb.reserved2 & FLAG_LAST_FRAME) {
                mfc_debug(2, "last frame!\n");
index d6dadedc22dcc9f98790ec1677d16adbc56eb066..02a25b2947ad32e99f3b84c44b06608db6a24bdd 100644 (file)
@@ -122,10 +122,12 @@ struct s5p_mfc_buf *s5p_mfc_get_move_buf_addr(spinlock_t *plock,
                struct s5p_mfc_buf_queue *to_queue, struct s5p_mfc_buf_queue *from_queue,
                dma_addr_t addr);
 
+struct s5p_mfc_buf *s5p_mfc_find_first_buf(spinlock_t *plock, struct s5p_mfc_buf_queue *queue,
+               dma_addr_t addr, int search_queue);
 struct s5p_mfc_buf *s5p_mfc_find_buf(spinlock_t *plock, struct s5p_mfc_buf_queue *queue,
-               dma_addr_t addr);
+               dma_addr_t addr, int search_queue);
 struct s5p_mfc_buf *s5p_mfc_find_del_buf(spinlock_t *plock, struct s5p_mfc_buf_queue *queue,
-               dma_addr_t addr);
+               dma_addr_t addr, int search_queue);
 struct s5p_mfc_buf *s5p_mfc_find_move_buf(spinlock_t *plock,
                struct s5p_mfc_buf_queue *to_queue, struct s5p_mfc_buf_queue *from_queue,
                dma_addr_t addr, unsigned int released_flag);
index 29b9e60b073be6a566cd4e71ab4946d9de4a8ddd..84dac78172dd0a9eb4e5f8dc2ac1a6b44c6892b3 100644 (file)
@@ -310,7 +310,7 @@ int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *m
        cpb_buf_size = ALIGN(dec->src_buf_size, STREAM_BUF_ALIGN);
 
        if (mfc_buf) {
-               addr = mfc_buf->addr[0];
+               addr = mfc_buf->addr[0][0];
                if (strm_size > set_strm_size_max(cpb_buf_size)) {
                        mfc_info_ctx("Decrease strm_size because of %d align: %u -> %u\n",
                                STREAM_BUF_ALIGN, strm_size, set_strm_size_max(cpb_buf_size));
@@ -348,16 +348,29 @@ void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
 {
        struct s5p_mfc_dev *dev = ctx->dev;
        dma_addr_t addr[3] = { 0, 0, 0 };
-       dma_addr_t addr_2bit[2];
+       dma_addr_t addr_2bit[2] = { 0, 0 };
        int i;
 
-       if (mfc_buf) {
+       if (!mfc_buf) {
+               mfc_debug(3, "enc zero buffer set\n");
+               goto buffer_set;
+       }
+
+       if (IS_BUFFER_BATCH_MODE(ctx)) {
+               for (i = 0; i < num_planes; i++) {
+                       addr[i] = mfc_buf->addr[mfc_buf->next_index][i];
+                       mfc_debug(2, "enc batch buf[%d] src[%d] addr: 0x%08llx\n",
+                                       mfc_buf->next_index, i, addr[i]);
+               }
+               mfc_buf->next_index++;
+       } else {
                for (i = 0; i < num_planes; i++) {
-                       addr[i] = mfc_buf->addr[i];
+                       addr[i] = mfc_buf->addr[0][i];
                        mfc_debug(2, "enc src[%d] addr: 0x%08llx\n", i, addr[i]);
                }
        }
 
+buffer_set:
        for (i = 0; i < num_planes; i++)
                MFC_WRITEL(addr[i], S5P_FIMV_E_SOURCE_FIRST_ADDR + (i * 4));
 
@@ -386,7 +399,7 @@ int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
        dma_addr_t addr;
        unsigned int size, offset;
 
-       addr = mfc_buf->addr[0];
+       addr = mfc_buf->addr[0][0];
        offset = mfc_buf->vb.vb2_buf.planes[0].data_offset;
        size = (unsigned int)vb2_plane_size(&mfc_buf->vb.vb2_buf, 0);
        size = ALIGN(size, 512);
@@ -445,13 +458,13 @@ int s5p_mfc_set_dynamic_dpb(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *dst_mb)
        set_bit(dst_index, &dec->available_dpb);
        dec->dynamic_set = 1 << dst_index;
        mfc_debug(2, "ADDING Flag after: 0x%lx\n", dec->available_dpb);
-       mfc_debug(2, "Dst addr [%d] = 0x%08llx\n", dst_index, dst_mb->addr[0]);
+       mfc_debug(2, "Dst addr [%d] = 0x%08llx\n", dst_index, dst_mb->addr[0][0]);
 
        /* for debugging about black bar detection */
        if (FW_HAS_BLACK_BAR_DETECT(dev) && dec->detect_black_bar) {
                for (i = 0; i < raw->num_planes; i++) {
                        dec->frame_vaddr[i][dec->frame_cnt] = vb2_plane_vaddr(&dst_mb->vb.vb2_buf, i);
-                       dec->frame_daddr[i][dec->frame_cnt] = dst_mb->addr[i];
+                       dec->frame_daddr[i][dec->frame_cnt] = dst_mb->addr[0][i];
                        dec->frame_size[i][dec->frame_cnt] = raw->plane_size[i];
                        dec->index[i][dec->frame_cnt] = dst_index;
                        dec->fd[i][dec->frame_cnt] = dst_mb->vb.vb2_buf.planes[0].m.fd;
@@ -467,12 +480,12 @@ int s5p_mfc_set_dynamic_dpb(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *dst_mb)
        for (i = 0; i < raw->num_planes; i++) {
                MFC_WRITEL(raw->plane_size[i],
                                S5P_FIMV_D_FIRST_PLANE_DPB_SIZE + i*4);
-               MFC_WRITEL(dst_mb->addr[i],
+               MFC_WRITEL(dst_mb->addr[0][i],
                                S5P_FIMV_D_FIRST_PLANE_DPB0 + (i*0x100 + dst_index*4));
        }
 
        MFC_TRACE_CTX("Set dst[%d] fd: %d, %#llx / avail %#lx used %#x\n",
-                       dst_index, dst_mb->vb.vb2_buf.planes[0].m.fd, dst_mb->addr[0],
+                       dst_index, dst_mb->vb.vb2_buf.planes[0].m.fd, dst_mb->addr[0][0],
                        dec->available_dpb, dec->dynamic_used);
 
        return 0;