diff options
author | Mauro Carvalho Chehab <mchehab@kernel.org> | 2022-11-15 12:11:46 +0000 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@kernel.org> | 2022-11-15 12:11:46 +0000 |
commit | b9fbe29c59065c24df9e9fb3153db36403d45e2d (patch) | |
tree | 225ae3efb742a482022906210bb765cb8ebe5e32 /drivers/staging | |
parent | a7bab6f8b73fe15a6181673149734a2756845dae (diff) | |
parent | 16f3211110c86e724a97c00bffc7352ab89fc94c (diff) | |
download | linux-b9fbe29c59065c24df9e9fb3153db36403d45e2d.tar.bz2 |
Merge tag 'br-v6.2d' of git://linuxtv.org/hverkuil/media_tree into media_stage
Tag branch
* tag 'br-v6.2d' of git://linuxtv.org/hverkuil/media_tree: (35 commits)
media: saa7164: remove variable cnt
atomisp: fix potential NULL pointer dereferences
radio-terratec: Remove variable p
media: platform: s5p-mfc: Fix spelling mistake "mmaping" -> "mmapping"
media: platform: mtk-mdp3: remove unused VIDEO_MEDIATEK_VPU config
media: vivid: remove redundant assignment to variable checksum
media: cedrus: h264: Optimize mv col buffer allocation
media: cedrus: h265: Associate mv col buffers with buffer
media: mediatek: vcodec: fix h264 cavlc bitstream fail
media: cedrus: hevc: Fix offset adjustments
media: imx-jpeg: Fix Coverity issue in probe
media: v4l2-ioctl.c: Unify YCbCr/YUV terms in format descriptions
media: atomisp: Fix spelling mistake "mis-match" -> "mismatch"
media: c8sectpfe: Add missed header(s)
media: adv748x: afe: Select input port when initializing AFE
media: vimc: Update device configuration in the documentation
media: adv748x: Remove dead function declaration
media: mxl5005s: Make array RegAddr static const
media: atomisp: Fix spelling mistake "modee" -> "mode"
media: meson/vdec: always init coef_node_start
...
Diffstat (limited to 'drivers/staging')
8 files changed, 129 insertions, 114 deletions
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c index c72d0e344671..eeb66b3b79ab 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c @@ -3288,7 +3288,7 @@ int atomisp_css_cp_dvs2_coefs(struct atomisp_sub_device *asd, if (!IS_ISP2401) { if (sizeof(*cur) != sizeof(coefs->grid) || memcmp(&coefs->grid, cur, sizeof(coefs->grid))) { - dev_err(asd->isp->dev, "dvs grid mis-match!\n"); + dev_err(asd->isp->dev, "dvs grid mismatch!\n"); /* If the grid info in the argument differs from the current grid info, we tell the caller to reset the grid size and try again. */ @@ -3344,7 +3344,7 @@ int atomisp_css_cp_dvs2_coefs(struct atomisp_sub_device *asd, if (sizeof(*cur) != sizeof(dvs2_coefs.grid) || memcmp(&dvs2_coefs.grid, cur, sizeof(dvs2_coefs.grid))) { - dev_err(asd->isp->dev, "dvs grid mis-match!\n"); + dev_err(asd->isp->dev, "dvs grid mismatch!\n"); /* If the grid info in the argument differs from the current grid info, we tell the caller to reset the grid size and try again. */ @@ -3692,14 +3692,14 @@ void atomisp_handle_parameter_and_buffer(struct atomisp_video_pipe *pipe) unsigned long irqflags; bool need_to_enqueue_buffer = false; - lockdep_assert_held(&asd->isp->mutex); - if (!asd) { dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", __func__, pipe->vdev.name); return; } + lockdep_assert_held(&asd->isp->mutex); + if (atomisp_is_vf_pipe(pipe)) return; @@ -3774,14 +3774,14 @@ int atomisp_set_parameters(struct video_device *vdev, struct atomisp_css_params *css_param = &asd->params.css_param; int ret; - lockdep_assert_held(&asd->isp->mutex); - if (!asd) { dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", __func__, vdev->name); return -EINVAL; } + lockdep_assert_held(&asd->isp->mutex); + if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) { dev_err(asd->isp->dev, "%s: internal error!\n", __func__); return -EINVAL; diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c index fdc05548d972..b36cbde7036a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c +++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c @@ -3180,7 +3180,7 @@ static int atomisp_compare_dvs_grid(struct atomisp_sub_device *asd, } if (sizeof(*cur) != sizeof(*atomgrid)) { - dev_err(asd->isp->dev, "dvs grid mis-match!\n"); + dev_err(asd->isp->dev, "dvs grid mismatch!\n"); return -EINVAL; } diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h index 1c7938d8ccb5..8f79424bedb2 100644 --- a/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h +++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h @@ -161,7 +161,7 @@ STORAGE_CLASS_PIXELGEN_C void pixelgen_ctrl_dump_state( state->syng_stat_fcnt); ia_css_print("Pixel Generator ID %d syng stat done 0x%x\n", ID, state->syng_stat_done); - ia_css_print("Pixel Generator ID %d tpg modee 0x%x\n", ID, state->tpg_mode); + ia_css_print("Pixel Generator ID %d tpg mode 0x%x\n", ID, state->tpg_mode); ia_css_print("Pixel Generator ID %d tpg hcnt mask 0x%x\n", ID, state->tpg_hcnt_mask); ia_css_print("Pixel Generator ID %d tpg hcnt mask 0x%x\n", ID, diff --git a/drivers/staging/media/meson/vdec/codec_vp9.c b/drivers/staging/media/meson/vdec/codec_vp9.c index 897f5d7a6aad..cf0f58d982c8 100644 --- a/drivers/staging/media/meson/vdec/codec_vp9.c +++ b/drivers/staging/media/meson/vdec/codec_vp9.c @@ -1649,8 +1649,7 @@ static void adapt_coef_probs(int prev_kf, int cur_kf, int pre_fc, else if (coef_count_node_start == VP9_MV_BITS_1_COUNT_START) coef_node_start = VP9_MV_BITS_1_START; - else if (coef_count_node_start == - VP9_MV_CLASS0_HP_0_COUNT_START) + else /* node_start == VP9_MV_CLASS0_HP_0_COUNT_START */ coef_node_start = VP9_MV_CLASS0_HP_0_START; den = count[coef_count_node_start] + diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h index a6a649bacc95..5904294f3108 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h @@ -100,7 +100,15 @@ struct cedrus_buffer { struct { unsigned int position; enum cedrus_h264_pic_type pic_type; + void *mv_col_buf; + dma_addr_t mv_col_buf_dma; + ssize_t mv_col_buf_size; } h264; + struct { + void *mv_col_buf; + dma_addr_t mv_col_buf_dma; + ssize_t mv_col_buf_size; + } h265; } codec; }; @@ -117,10 +125,6 @@ struct cedrus_ctx { union { struct { - void *mv_col_buf; - dma_addr_t mv_col_buf_dma; - ssize_t mv_col_buf_field_size; - ssize_t mv_col_buf_size; void *pic_info_buf; dma_addr_t pic_info_buf_dma; ssize_t pic_info_buf_size; @@ -134,10 +138,6 @@ struct cedrus_ctx { ssize_t intra_pred_buf_size; } h264; struct { - void *mv_col_buf; - dma_addr_t mv_col_buf_addr; - ssize_t mv_col_buf_size; - ssize_t mv_col_buf_unit_size; void *neighbor_info_buf; dma_addr_t neighbor_info_buf_addr; void *entry_points_buf; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c index c139a37a567c..dfb401df138a 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c @@ -54,17 +54,13 @@ static void cedrus_h264_write_sram(struct cedrus_dev *dev, cedrus_write(dev, VE_AVC_SRAM_PORT_DATA, *buffer++); } -static dma_addr_t cedrus_h264_mv_col_buf_addr(struct cedrus_ctx *ctx, - unsigned int position, +static dma_addr_t cedrus_h264_mv_col_buf_addr(struct cedrus_buffer *buf, unsigned int field) { - dma_addr_t addr = ctx->codec.h264.mv_col_buf_dma; - - /* Adjust for the position */ - addr += position * ctx->codec.h264.mv_col_buf_field_size * 2; + dma_addr_t addr = buf->codec.h264.mv_col_buf_dma; /* Adjust for the field */ - addr += field * ctx->codec.h264.mv_col_buf_field_size; + addr += field * buf->codec.h264.mv_col_buf_size / 2; return addr; } @@ -76,7 +72,6 @@ static void cedrus_fill_ref_pic(struct cedrus_ctx *ctx, struct cedrus_h264_sram_ref_pic *pic) { struct vb2_buffer *vbuf = &buf->m2m_buf.vb.vb2_buf; - unsigned int position = buf->codec.h264.position; pic->top_field_order_cnt = cpu_to_le32(top_field_order_cnt); pic->bottom_field_order_cnt = cpu_to_le32(bottom_field_order_cnt); @@ -84,14 +79,12 @@ static void cedrus_fill_ref_pic(struct cedrus_ctx *ctx, pic->luma_ptr = cpu_to_le32(cedrus_buf_addr(vbuf, &ctx->dst_fmt, 0)); pic->chroma_ptr = cpu_to_le32(cedrus_buf_addr(vbuf, &ctx->dst_fmt, 1)); - pic->mv_col_top_ptr = - cpu_to_le32(cedrus_h264_mv_col_buf_addr(ctx, position, 0)); - pic->mv_col_bot_ptr = - cpu_to_le32(cedrus_h264_mv_col_buf_addr(ctx, position, 1)); + pic->mv_col_top_ptr = cpu_to_le32(cedrus_h264_mv_col_buf_addr(buf, 0)); + pic->mv_col_bot_ptr = cpu_to_le32(cedrus_h264_mv_col_buf_addr(buf, 1)); } -static void cedrus_write_frame_list(struct cedrus_ctx *ctx, - struct cedrus_run *run) +static int cedrus_write_frame_list(struct cedrus_ctx *ctx, + struct cedrus_run *run) { struct cedrus_h264_sram_ref_pic pic_list[CEDRUS_H264_FRAME_NUM]; const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params; @@ -146,6 +139,31 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx, output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf); output_buf->codec.h264.position = position; + if (!output_buf->codec.h264.mv_col_buf_size) { + const struct v4l2_ctrl_h264_sps *sps = run->h264.sps; + unsigned int field_size; + + field_size = DIV_ROUND_UP(ctx->src_fmt.width, 16) * + DIV_ROUND_UP(ctx->src_fmt.height, 16) * 16; + if (!(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE)) + field_size = field_size * 2; + if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)) + field_size = field_size * 2; + + output_buf->codec.h264.mv_col_buf_size = field_size * 2; + /* Buffer is never accessed by CPU, so we can skip kernel mapping. */ + output_buf->codec.h264.mv_col_buf = + dma_alloc_attrs(dev->dev, + output_buf->codec.h264.mv_col_buf_size, + &output_buf->codec.h264.mv_col_buf_dma, + GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING); + + if (!output_buf->codec.h264.mv_col_buf) { + output_buf->codec.h264.mv_col_buf_size = 0; + return -ENOMEM; + } + } + if (decode->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_FIELD; else if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD) @@ -162,6 +180,8 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx, pic_list, sizeof(pic_list)); cedrus_write(dev, VE_H264_OUTPUT_FRAME_IDX, position); + + return 0; } #define CEDRUS_MAX_REF_IDX 32 @@ -496,6 +516,7 @@ static void cedrus_h264_irq_disable(struct cedrus_ctx *ctx) static int cedrus_h264_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) { struct cedrus_dev *dev = ctx->dev; + int ret; cedrus_engine_enable(ctx); @@ -506,7 +527,9 @@ static int cedrus_h264_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) ctx->codec.h264.neighbor_info_buf_dma); cedrus_write_scaling_lists(ctx, run); - cedrus_write_frame_list(ctx, run); + ret = cedrus_write_frame_list(ctx, run); + if (ret) + return ret; cedrus_set_params(ctx, run); @@ -517,8 +540,6 @@ static int cedrus_h264_start(struct cedrus_ctx *ctx) { struct cedrus_dev *dev = ctx->dev; unsigned int pic_info_size; - unsigned int field_size; - unsigned int mv_col_size; int ret; /* @@ -566,38 +587,6 @@ static int cedrus_h264_start(struct cedrus_ctx *ctx) goto err_pic_buf; } - field_size = DIV_ROUND_UP(ctx->src_fmt.width, 16) * - DIV_ROUND_UP(ctx->src_fmt.height, 16) * 16; - - /* - * FIXME: This is actually conditional to - * V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE not being set, we - * might have to rework this if memory efficiency ever is - * something we need to work on. - */ - field_size = field_size * 2; - - /* - * FIXME: This is actually conditional to - * V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY not being set, we might - * have to rework this if memory efficiency ever is something - * we need to work on. - */ - field_size = field_size * 2; - ctx->codec.h264.mv_col_buf_field_size = field_size; - - mv_col_size = field_size * 2 * CEDRUS_H264_FRAME_NUM; - ctx->codec.h264.mv_col_buf_size = mv_col_size; - ctx->codec.h264.mv_col_buf = - dma_alloc_attrs(dev->dev, - ctx->codec.h264.mv_col_buf_size, - &ctx->codec.h264.mv_col_buf_dma, - GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING); - if (!ctx->codec.h264.mv_col_buf) { - ret = -ENOMEM; - goto err_neighbor_buf; - } - if (ctx->src_fmt.width > 2048) { /* * Formulas for deblock and intra prediction buffer sizes @@ -613,7 +602,7 @@ static int cedrus_h264_start(struct cedrus_ctx *ctx) GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING); if (!ctx->codec.h264.deblk_buf) { ret = -ENOMEM; - goto err_mv_col_buf; + goto err_neighbor_buf; } /* @@ -641,12 +630,6 @@ err_deblk_buf: ctx->codec.h264.deblk_buf_dma, DMA_ATTR_NO_KERNEL_MAPPING); -err_mv_col_buf: - dma_free_attrs(dev->dev, ctx->codec.h264.mv_col_buf_size, - ctx->codec.h264.mv_col_buf, - ctx->codec.h264.mv_col_buf_dma, - DMA_ATTR_NO_KERNEL_MAPPING); - err_neighbor_buf: dma_free_attrs(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE, ctx->codec.h264.neighbor_info_buf, @@ -664,11 +647,26 @@ err_pic_buf: static void cedrus_h264_stop(struct cedrus_ctx *ctx) { struct cedrus_dev *dev = ctx->dev; + struct cedrus_buffer *buf; + struct vb2_queue *vq; + unsigned int i; + + 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)); + + if (buf->codec.h264.mv_col_buf_size > 0) { + dma_free_attrs(dev->dev, + buf->codec.h264.mv_col_buf_size, + buf->codec.h264.mv_col_buf, + buf->codec.h264.mv_col_buf_dma, + DMA_ATTR_NO_KERNEL_MAPPING); + + buf->codec.h264.mv_col_buf_size = 0; + } + } - dma_free_attrs(dev->dev, ctx->codec.h264.mv_col_buf_size, - ctx->codec.h264.mv_col_buf, - ctx->codec.h264.mv_col_buf_dma, - DMA_ATTR_NO_KERNEL_MAPPING); dma_free_attrs(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE, ctx->codec.h264.neighbor_info_buf, ctx->codec.h264.neighbor_info_buf_dma, diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c index 3f2946c8f174..5d3da50ce46a 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; @@ -242,6 +242,18 @@ static void cedrus_h265_skip_bits(struct cedrus_dev *dev, int num) } } +static u32 cedrus_h265_show_bits(struct cedrus_dev *dev, int num) +{ + cedrus_write(dev, VE_DEC_H265_TRIGGER, + VE_DEC_H265_TRIGGER_SHOW_BITS | + VE_DEC_H265_TRIGGER_TYPE_N_BITS(num)); + + cedrus_wait_for(dev, VE_DEC_H265_STATUS, + VE_DEC_H265_STATUS_VLD_BUSY); + + return cedrus_read(dev, VE_DEC_H265_BITS_READ); +} + static void cedrus_h265_write_scaling_list(struct cedrus_ctx *ctx, struct cedrus_run *run) { @@ -400,13 +412,14 @@ 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]; - u8 *padding; + u8 padding; int count; u32 reg; @@ -416,6 +429,7 @@ 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); /* * If entry points offsets are present, we should get them @@ -433,31 +447,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; } } @@ -520,21 +528,22 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) if (slice_params->data_byte_offset == 0) return -EOPNOTSUPP; - padding = (u8 *)vb2_plane_vaddr(&run->src->vb2_buf, 0) + - slice_params->data_byte_offset - 1; + cedrus_h265_skip_bits(dev, (slice_params->data_byte_offset - 1) * 8); + + padding = cedrus_h265_show_bits(dev, 8); /* at least one bit must be set in that byte */ - if (*padding == 0) + if (padding == 0) return -EINVAL; for (count = 0; count < 8; count++) - if (*padding & (1 << count)) + if (padding & (1 << count)) break; /* Include the one bit. */ count++; - cedrus_h265_skip_bits(dev, slice_params->data_byte_offset * 8 - count); + cedrus_h265_skip_bits(dev, 8 - count); /* Bitstream parameters. */ @@ -803,9 +812,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, @@ -832,14 +838,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); - ctx->codec.h265.mv_col_buf_size = 0; + for (i = 0; i < vq->num_buffers; i++) { + buf = vb2_to_cedrus_buffer(vb2_get_buffer(vq, i)); + + 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, diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h index d81f7513ade0..655c05b389cf 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h @@ -505,6 +505,8 @@ #define VE_DEC_H265_LOW_ADDR_ENTRY_POINTS_BUF(a) \ SHIFT_AND_MASK_BITS(a, 7, 0) +#define VE_DEC_H265_BITS_READ (VE_ENGINE_DEC_H265 + 0xdc) + #define VE_DEC_H265_SRAM_OFFSET (VE_ENGINE_DEC_H265 + 0xe0) #define VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L0 0x00 |