summaryrefslogtreecommitdiffstats
path: root/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/media/sunxi/cedrus/cedrus_h265.c')
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_h265.c73
1 files changed, 37 insertions, 36 deletions
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
index 625f77a8c..9f13c942a 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
@@ -90,12 +90,13 @@ static void cedrus_h265_sram_write_data(struct cedrus_dev *dev, void *data,
}
static inline dma_addr_t
-cedrus_h265_frame_info_mv_col_buf_addr(struct cedrus_ctx *ctx,
- unsigned int index, unsigned int field)
+cedrus_h265_frame_info_mv_col_buf_addr(struct vb2_buffer *buf,
+ unsigned int field)
{
- return ctx->codec.h265.mv_col_buf_addr + index *
- ctx->codec.h265.mv_col_buf_unit_size +
- field * ctx->codec.h265.mv_col_buf_unit_size / 2;
+ struct cedrus_buffer *cedrus_buf = vb2_to_cedrus_buffer(buf);
+
+ return cedrus_buf->codec.h265.mv_col_buf_dma +
+ field * cedrus_buf->codec.h265.mv_col_buf_size / 2;
}
static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
@@ -108,9 +109,8 @@ static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
dma_addr_t dst_luma_addr = cedrus_dst_buf_addr(ctx, buf, 0);
dma_addr_t dst_chroma_addr = cedrus_dst_buf_addr(ctx, buf, 1);
dma_addr_t mv_col_buf_addr[2] = {
- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buf->index, 0),
- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buf->index,
- field_pic ? 1 : 0)
+ cedrus_h265_frame_info_mv_col_buf_addr(buf, 0),
+ cedrus_h265_frame_info_mv_col_buf_addr(buf, field_pic ? 1 : 0)
};
u32 offset = VE_DEC_H265_SRAM_OFFSET_FRAME_INFO +
VE_DEC_H265_SRAM_OFFSET_FRAME_INFO_UNIT * index;
@@ -412,12 +412,13 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
unsigned int width_in_ctb_luma, ctb_size_luma;
unsigned int log2_max_luma_coding_block_size;
unsigned int ctb_addr_x, ctb_addr_y;
+ struct cedrus_buffer *cedrus_buf;
dma_addr_t src_buf_addr;
- dma_addr_t src_buf_end_addr;
u32 chroma_log2_weight_denom;
u32 num_entry_point_offsets;
u32 output_pic_list_index;
u32 pic_order_cnt[2];
+ size_t slice_bytes;
u8 padding;
int count;
u32 reg;
@@ -428,6 +429,8 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
decode_params = run->h265.decode_params;
pred_weight_table = &slice_params->pred_weight_table;
num_entry_point_offsets = slice_params->num_entry_point_offsets;
+ cedrus_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
+ slice_bytes = vb2_get_plane_payload(&run->src->vb2_buf, 0);
/*
* If entry points offsets are present, we should get them
@@ -445,31 +448,25 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_luma);
/* MV column buffer size and allocation. */
- if (!ctx->codec.h265.mv_col_buf_size) {
- unsigned int num_buffers =
- run->dst->vb2_buf.vb2_queue->num_buffers;
-
+ if (!cedrus_buf->codec.h265.mv_col_buf_size) {
/*
* Each CTB requires a MV col buffer with a specific unit size.
* Since the address is given with missing lsb bits, 1 KiB is
* added to each buffer to ensure proper alignment.
*/
- ctx->codec.h265.mv_col_buf_unit_size =
+ cedrus_buf->codec.h265.mv_col_buf_size =
DIV_ROUND_UP(ctx->src_fmt.width, ctb_size_luma) *
DIV_ROUND_UP(ctx->src_fmt.height, ctb_size_luma) *
CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE + SZ_1K;
- ctx->codec.h265.mv_col_buf_size = num_buffers *
- ctx->codec.h265.mv_col_buf_unit_size;
-
/* Buffer is never accessed by CPU, so we can skip kernel mapping. */
- ctx->codec.h265.mv_col_buf =
+ cedrus_buf->codec.h265.mv_col_buf =
dma_alloc_attrs(dev->dev,
- ctx->codec.h265.mv_col_buf_size,
- &ctx->codec.h265.mv_col_buf_addr,
+ cedrus_buf->codec.h265.mv_col_buf_size,
+ &cedrus_buf->codec.h265.mv_col_buf_dma,
GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING);
- if (!ctx->codec.h265.mv_col_buf) {
- ctx->codec.h265.mv_col_buf_size = 0;
+ if (!cedrus_buf->codec.h265.mv_col_buf) {
+ cedrus_buf->codec.h265.mv_col_buf_size = 0;
return -ENOMEM;
}
}
@@ -481,7 +478,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
cedrus_write(dev, VE_DEC_H265_BITS_OFFSET, 0);
- reg = slice_params->bit_size;
+ reg = slice_bytes * 8;
cedrus_write(dev, VE_DEC_H265_BITS_LEN, reg);
/* Source beginning and end addresses. */
@@ -495,10 +492,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
cedrus_write(dev, VE_DEC_H265_BITS_ADDR, reg);
- src_buf_end_addr = src_buf_addr +
- DIV_ROUND_UP(slice_params->bit_size, 8);
-
- reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_end_addr);
+ reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_addr + slice_bytes);
cedrus_write(dev, VE_DEC_H265_BITS_END_ADDR, reg);
/* Coding tree block address */
@@ -816,9 +810,6 @@ static int cedrus_h265_start(struct cedrus_ctx *ctx)
{
struct cedrus_dev *dev = ctx->dev;
- /* The buffer size is calculated at setup time. */
- ctx->codec.h265.mv_col_buf_size = 0;
-
/* Buffer is never accessed by CPU, so we can skip kernel mapping. */
ctx->codec.h265.neighbor_info_buf =
dma_alloc_attrs(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
@@ -845,14 +836,24 @@ static int cedrus_h265_start(struct cedrus_ctx *ctx)
static void cedrus_h265_stop(struct cedrus_ctx *ctx)
{
struct cedrus_dev *dev = ctx->dev;
+ struct cedrus_buffer *buf;
+ struct vb2_queue *vq;
+ unsigned int i;
- if (ctx->codec.h265.mv_col_buf_size > 0) {
- dma_free_attrs(dev->dev, ctx->codec.h265.mv_col_buf_size,
- ctx->codec.h265.mv_col_buf,
- ctx->codec.h265.mv_col_buf_addr,
- DMA_ATTR_NO_KERNEL_MAPPING);
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+ for (i = 0; i < vq->num_buffers; i++) {
+ buf = vb2_to_cedrus_buffer(vb2_get_buffer(vq, i));
- ctx->codec.h265.mv_col_buf_size = 0;
+ if (buf->codec.h265.mv_col_buf_size > 0) {
+ dma_free_attrs(dev->dev,
+ buf->codec.h265.mv_col_buf_size,
+ buf->codec.h265.mv_col_buf,
+ buf->codec.h265.mv_col_buf_dma,
+ DMA_ATTR_NO_KERNEL_MAPPING);
+
+ buf->codec.h265.mv_col_buf_size = 0;
+ }
}
dma_free_attrs(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,