#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)
/* 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
*/
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;
};
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 */
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,
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)
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);
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);
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) &&
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);
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();
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)
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;
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);
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;
}
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;
}
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;
&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;
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) {
/* 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;
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);
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;
+}
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);
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 */
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();
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++)
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);
}
/* 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);
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;
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();
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;
*/
/* 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);
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();
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);
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;
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;
}
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;
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);
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);
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;
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;
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;
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--;
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);
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--;
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--;
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--;
}
}
-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) {
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;
+ }
}
}
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) {
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);
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");
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);
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));
{
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));
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);
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;
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;