From e90fad8cbaf3e9d27bab0331165c620fc17e6c2d Mon Sep 17 00:00:00 2001 From: Ayoung Sim Date: Wed, 29 Nov 2017 14:44:04 +0900 Subject: [PATCH] media: mfc: consider the single buffer when batch mode Change-Id: I45b7eb36df98a7730acbb615f069e48c460fd500 Signed-off-by: Ayoung Sim --- .../platform/exynos/mfc/s5p_mfc_common.h | 2 +- .../platform/exynos/mfc/s5p_mfc_data_struct.h | 3 ++- .../platform/exynos/mfc/s5p_mfc_enc_vb2_ops.c | 22 +++++++++------- .../media/platform/exynos/mfc/s5p_mfc_irq.c | 17 ++++++------- .../media/platform/exynos/mfc/s5p_mfc_mem.c | 4 +-- .../media/platform/exynos/mfc/s5p_mfc_nal_q.c | 20 +++++++-------- .../media/platform/exynos/mfc/s5p_mfc_opr.c | 4 +-- .../media/platform/exynos/mfc/s5p_mfc_queue.c | 25 ++++++++++++------- .../media/platform/exynos/mfc/s5p_mfc_queue.h | 6 ++--- .../media/platform/exynos/mfc/s5p_mfc_reg.c | 2 +- 10 files changed, 57 insertions(+), 48 deletions(-) diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_common.h b/drivers/media/platform/exynos/mfc/s5p_mfc_common.h index baea4468e290..750a231c53d9 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_common.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_common.h @@ -137,7 +137,7 @@ #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) +#define IS_BUFFER_BATCH_MODE(ctx) ((ctx)->batch_mode == 1) /* UHD resoluition */ #define MFC_UHD_RES (3840 * 2160) diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h b/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h index fbbbfeeb1a2d..4c44d42d4e5e 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h @@ -231,6 +231,7 @@ struct s5p_mfc_buf { int next_index; int done_index; int used; + int num_bufs_in_vb; unsigned char *vir_addr; }; @@ -1344,7 +1345,7 @@ struct s5p_mfc_ctx { unsigned long stream_protect_flag; struct _otf_handle *otf_handle; - int num_bufs_in_vb; + int batch_mode; }; #endif /* __S5P_MFC_DATA_STRUCT_H */ diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_vb2_ops.c b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_vb2_ops.c index 67b696f3e51e..2cc3c43c1ca1 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_vb2_ops.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_vb2_ops.c @@ -150,20 +150,24 @@ static int s5p_mfc_enc_buf_init(struct vb2_buffer *vb) 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); + buf->num_bufs_in_vb = s5p_mfc_bufcon_get_buf_count(dmabuf); + mfc_debug(3, "bufcon count:%d\n", buf->num_bufs_in_vb); + if (!ctx->batch_mode && buf->num_bufs_in_vb > 0) { + ctx->batch_mode = 1; + mfc_debug(3, "buffer batch mode enabled\n"); + } - if (IS_BUFFER_BATCH_MODE(ctx)) { + if (buf->num_bufs_in_vb > 0) { int count = 0; - ctx->framerate = ctx->num_bufs_in_vb * ENC_DEFAULT_CAM_CAPTURE_FPS; + ctx->framerate = buf->num_bufs_in_vb * ENC_DEFAULT_CAM_CAPTURE_FPS; mfc_debug(3, "framerate: %ld\n", ctx->framerate); count = s5p_mfc_bufcon_get_daddr(ctx, buf, dmabuf, i); - if (count != ctx->num_bufs_in_vb) { + if (count != buf->num_bufs_in_vb) { s5p_mfc_mem_put_dmabuf(dmabuf); mfc_err_ctx("invalid buffer count %d != num_bufs_in_vb %d\n", - count, ctx->num_bufs_in_vb); + count, buf->num_bufs_in_vb); return -EFAULT; } @@ -194,11 +198,11 @@ static int s5p_mfc_enc_buf_init(struct vb2_buffer *vb) 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"); } } + 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; diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c index c9c98d359228..8e188b6b6fd7 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c @@ -174,7 +174,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, 0); + ref_mb = s5p_mfc_find_buf(&ctx->buf_queue_lock, &ctx->ref_buf_queue, dec_y_addr); if (ref_mb) ref_mb->vb.vb2_buf.timestamp = src_mb->vb.vb2_buf.timestamp; } @@ -249,7 +249,7 @@ 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, 0); + &ctx->ref_buf_queue, dspl_y_addr); 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 */ @@ -816,7 +816,7 @@ static void mfc_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_type) 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); + &ctx->src_buf_queue, enc_addr[0]); if (src_mb) { src_mb->done_index++; mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index); @@ -829,11 +829,10 @@ static void mfc_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_type) mfc_handle_stream_copy_timestamp(ctx, src_mb); - /* last image in a buffer container */ - if (src_mb->done_index == ctx->num_bufs_in_vb) { + /* single buffer || last image in a buffer container */ + if (!src_mb->num_bufs_in_vb || src_mb->done_index == src_mb->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); + &ctx->src_buf_queue, enc_addr[0]); if (src_mb) vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE); } @@ -845,7 +844,7 @@ static void mfc_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_type) } else { /* normal single buffer */ src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock, - &ctx->src_buf_queue, enc_addr[0], 0); + &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, @@ -860,7 +859,7 @@ static void mfc_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_type) } ref_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock, - &ctx->ref_buf_queue, enc_addr[0], 0); + &ctx->ref_buf_queue, enc_addr[0]); if (ref_mb) { vb2_buffer_done(&ref_mb->vb.vb2_buf, VB2_BUF_STATE_DONE); diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_mem.c b/drivers/media/platform/exynos/mfc/s5p_mfc_mem.c index b5957363124f..9fe6c624b133 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_mem.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_mem.c @@ -193,7 +193,7 @@ void s5p_mfc_bufcon_put_daddr(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *mfc_b { int i; - for (i = 0; i < ctx->num_bufs_in_vb; i++) { + for (i = 0; i < mfc_buf->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]); @@ -217,7 +217,7 @@ int s5p_mfc_bufcon_get_daddr(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *mfc_bu struct s5p_mfc_raw_info *raw = &ctx->raw_buf; int i; - for (i = 0; i < ctx->num_bufs_in_vb; i++) { + for (i = 0; i < mfc_buf->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)", diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c b/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c index 4d55a1f33f5c..1fcff1c51616 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c @@ -580,7 +580,7 @@ static int mfc_nal_q_run_in_buf_enc(struct s5p_mfc_ctx *ctx, EncoderInputStr *pI /* last image in a buffer container */ /* move src_queue -> src_queue_nal_q */ - if (src_mb->next_index == (ctx->num_bufs_in_vb - 1)) { + if (src_mb->next_index == (src_mb->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); @@ -857,7 +857,7 @@ static void mfc_nal_q_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_typ 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); + &ctx->src_buf_queue, enc_addr[0]); if (src_mb) { src_mb->done_index++; mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index); @@ -865,7 +865,7 @@ static void mfc_nal_q_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_typ mfc_nal_q_handle_stream_copy_timestamp(ctx, src_mb); } 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); + &ctx->src_buf_nal_queue, enc_addr[0]); if (src_mb) { src_mb->done_index++; mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index); @@ -873,10 +873,9 @@ static void mfc_nal_q_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_typ mfc_nal_q_handle_stream_copy_timestamp(ctx, src_mb); /* last image in a buffer container */ - if (src_mb->done_index == ctx->num_bufs_in_vb) { + if (src_mb->done_index == src_mb->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); + &ctx->src_buf_nal_queue, enc_addr[0]); if (src_mb) vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE); } @@ -884,7 +883,7 @@ static void mfc_nal_q_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_typ } } else { src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock, - &ctx->src_buf_nal_queue, enc_addr[0], 0); + &ctx->src_buf_nal_queue, enc_addr[0]); if (!src_mb) { mfc_err_dev("NAL Q: no src buffers\n"); return; @@ -893,7 +892,7 @@ static void mfc_nal_q_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_typ 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); + &ctx->ref_buf_queue, enc_addr[0]); if (ref_mb) vb2_buffer_done(&ref_mb->vb.vb2_buf, VB2_BUF_STATE_DONE); } @@ -1120,7 +1119,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, 0); + ref_mb = s5p_mfc_find_buf(&ctx->buf_queue_lock, &ctx->ref_buf_queue, dec_y_addr); if (ref_mb) ref_mb->vb.vb2_buf.timestamp = src_mb->vb.vb2_buf.timestamp; @@ -1198,8 +1197,7 @@ static void mfc_nal_q_handle_frame_output_del(struct s5p_mfc_ctx *ctx, frame_type = pOutStr->DisplayFrameType & S5P_FIMV_DISPLAY_FRAME_MASK; } - ref_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock, - &ctx->ref_buf_queue, dspl_y_addr, 0); + ref_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock, &ctx->ref_buf_queue, dspl_y_addr); 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 */ diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_opr.c b/drivers/media/platform/exynos/mfc/s5p_mfc_opr.c index cea014465a05..e20f7a0c35a8 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_opr.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_opr.c @@ -259,9 +259,9 @@ int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) return -EAGAIN; } - if (IS_BUFFER_BATCH_MODE(ctx)) { + if (src_mb->num_bufs_in_vb > 0) { /* last image in a buffer container */ - if (src_mb->next_index == (ctx->num_bufs_in_vb - 1)) + if (src_mb->next_index == (src_mb->num_bufs_in_vb - 1)) last_frame = mfc_check_last_frame(ctx, src_mb); } else { last_frame = mfc_check_last_frame(ctx, src_mb); diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_queue.c b/drivers/media/platform/exynos/mfc/s5p_mfc_queue.c index 2d326a83dea9..8639b326de62 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_queue.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_queue.c @@ -264,7 +264,7 @@ struct s5p_mfc_buf *s5p_mfc_get_move_buf_addr(spinlock_t *plock, } 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) + dma_addr_t addr) { unsigned long flags; struct s5p_mfc_buf *mfc_buf = NULL; @@ -281,8 +281,8 @@ struct s5p_mfc_buf *s5p_mfc_find_first_buf(spinlock_t *plock, struct s5p_mfc_buf mfc_debug(2, "Looking for this address: 0x%08llx\n", addr); mfc_buf = list_entry(queue->head.next, struct s5p_mfc_buf, list); - if (search_queue > 0) { - for (i = 0; i < search_queue; i++) { + if (mfc_buf->num_bufs_in_vb > 0) { + for (i = 0; i < mfc_buf->num_bufs_in_vb; 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) { @@ -305,7 +305,7 @@ struct s5p_mfc_buf *s5p_mfc_find_first_buf(spinlock_t *plock, struct s5p_mfc_buf } struct s5p_mfc_buf *s5p_mfc_find_buf(spinlock_t *plock, struct s5p_mfc_buf_queue *queue, - dma_addr_t addr, int search_queue) + dma_addr_t addr) { unsigned long flags; struct s5p_mfc_buf *mfc_buf = NULL; @@ -316,8 +316,8 @@ struct s5p_mfc_buf *s5p_mfc_find_buf(spinlock_t *plock, struct s5p_mfc_buf_queue 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++) { + if (mfc_buf->num_bufs_in_vb > 0) { + for (i = 0; i < mfc_buf->num_bufs_in_vb; 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) { @@ -341,7 +341,7 @@ struct s5p_mfc_buf *s5p_mfc_find_buf(spinlock_t *plock, struct s5p_mfc_buf_queue } struct s5p_mfc_buf *s5p_mfc_find_del_buf(spinlock_t *plock, struct s5p_mfc_buf_queue *queue, - dma_addr_t addr, int search_queue) + dma_addr_t addr) { unsigned long flags; struct s5p_mfc_buf *mfc_buf = NULL; @@ -352,8 +352,8 @@ struct s5p_mfc_buf *s5p_mfc_find_del_buf(spinlock_t *plock, struct s5p_mfc_buf_q 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++) { + if (mfc_buf->num_bufs_in_vb > 0) { + for (i = 0; i < mfc_buf->num_bufs_in_vb; i++) { mb_addr = mfc_buf->addr[i][0]; mfc_debug(2, "batch buf[%d] plane[0] addr: 0x%08llx\n", i, mb_addr); @@ -910,6 +910,13 @@ void s5p_mfc_cleanup_nal_queue(struct s5p_mfc_ctx *ctx) src_mb->used = 0; + /* If it is not buffer batch mode, index is always zero */ + if (src_mb->next_index > src_mb->done_index) { + mfc_debug(2, "NAL Q: batch buf next index[%d] recover to %d\n", + src_mb->next_index, src_mb->done_index); + src_mb->next_index = src_mb->done_index; + } + list_del(&src_mb->list); ctx->src_buf_nal_queue.count--; diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_queue.h b/drivers/media/platform/exynos/mfc/s5p_mfc_queue.h index 02a25b2947ad..3432f806e429 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_queue.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_queue.h @@ -123,11 +123,11 @@ struct s5p_mfc_buf *s5p_mfc_get_move_buf_addr(spinlock_t *plock, 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); + dma_addr_t addr); struct s5p_mfc_buf *s5p_mfc_find_buf(spinlock_t *plock, struct s5p_mfc_buf_queue *queue, - dma_addr_t addr, int search_queue); + dma_addr_t addr); struct s5p_mfc_buf *s5p_mfc_find_del_buf(spinlock_t *plock, struct s5p_mfc_buf_queue *queue, - dma_addr_t addr, int search_queue); + dma_addr_t addr); 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); diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_reg.c b/drivers/media/platform/exynos/mfc/s5p_mfc_reg.c index 84dac78172dd..114d1032255b 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_reg.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_reg.c @@ -356,7 +356,7 @@ void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx, goto buffer_set; } - if (IS_BUFFER_BATCH_MODE(ctx)) { + if (mfc_buf->num_bufs_in_vb > 0) { 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", -- 2.20.1