diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-12-14 22:47:37 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-12-14 22:47:37 +0300 |
commit | fab0fca1da5cdc48be051715cd9787df04fdce3a (patch) | |
tree | 5d1228cdd22bdd0675090349cf41aeef53e8a14c /drivers/media/platform/coda/coda-bit.c | |
parent | ae1985b50afaf76aaa09946ee36b59eaecb2ffae (diff) | |
parent | 7ea4d23293300ca2f225595849a4fe444fb80ea4 (diff) | |
download | linux-fab0fca1da5cdc48be051715cd9787df04fdce3a.tar.xz |
Merge tag 'media/v5.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- some rework at the uAPI pixel format docs
- the smiapp driver has started to gain support for MIPI CSS camera
sensors and was renamed
- two new sensor drivers: ov02a10 and ov9734
- Meson gained a driver for the 2D acceleration unit
- Rockchip rkisp1 driver was promoted from staging
- Cedrus driver gained support for VP8
- two new remote controller keymaps were added
- the usual set of fixes cleanups and driver improvements
* tag 'media/v5.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (447 commits)
media: ccs: Add support for obtaining C-PHY configuration from firmware
media: ccs-pll: Print pixel rates
media: ccs: Print written register values
media: ccs: Add support for DDR OP SYS and OP PIX clocks
media: ccs-pll: Add support for DDR OP system and pixel clocks
media: ccs: Dual PLL support
media: ccs-pll: Add trivial dual PLL support
media: ccs-pll: Separate VT divisor limit calculation from the rest
media: ccs-pll: Fix VT post-PLL divisor calculation
media: ccs-pll: Make VT divisors 16-bit
media: ccs-pll: Rework bounds checks
media: ccs-pll: Print relevant information on PLL tree
media: ccs-pll: Better separate OP and VT sub-tree calculation
media: ccs-pll: Check for derating and overrating, support non-derating sensors
media: ccs-pll: Split off VT subtree calculation
media: ccs-pll: Add C-PHY support
media: ccs-pll: Add sanity checks
media: ccs-pll: Add support flexible OP PLL pixel clock divider
media: ccs-pll: Support two cycles per pixel on OP domain
media: ccs-pll: Add support for extended input PLL clock divider
...
Diffstat (limited to 'drivers/media/platform/coda/coda-bit.c')
-rw-r--r-- | drivers/media/platform/coda/coda-bit.c | 73 |
1 files changed, 51 insertions, 22 deletions
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index bf75927bac4e..2f42808c43a4 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -13,6 +13,7 @@ #include <linux/kernel.h> #include <linux/log2.h> #include <linux/platform_device.h> +#include <linux/ratelimit.h> #include <linux/reset.h> #include <linux/slab.h> #include <linux/videodev2.h> @@ -293,12 +294,11 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx, coda_dbg(1, ctx, "could not parse header, sequence initialization might fail\n"); } - } - /* Add padding before the first buffer, if it is too small */ - if (ctx->qsequence == 0 && payload < 512 && - ctx->codec->src_fourcc == V4L2_PIX_FMT_H264) - coda_h264_bitstream_pad(ctx, 512 - payload); + /* Add padding before the first buffer, if it is too small */ + if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264) + coda_h264_bitstream_pad(ctx, 512 - payload); + } ret = coda_bitstream_queue(ctx, vaddr, payload); if (ret < 0) { @@ -1837,6 +1837,29 @@ static bool coda_reorder_enable(struct coda_ctx *ctx) return profile > V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; } +static void coda_decoder_drop_used_metas(struct coda_ctx *ctx) +{ + struct coda_buffer_meta *meta, *tmp; + + /* + * All metas that end at or before the RD pointer (fifo out), + * are now consumed by the VPU and should be released. + */ + spin_lock(&ctx->buffer_meta_lock); + list_for_each_entry_safe(meta, tmp, &ctx->buffer_meta_list, list) { + if (ctx->bitstream_fifo.kfifo.out >= meta->end) { + coda_dbg(2, ctx, "releasing meta: seq=%d start=%d end=%d\n", + meta->sequence, meta->start, meta->end); + + list_del(&meta->list); + ctx->num_metas--; + ctx->first_frame_sequence++; + kfree(meta); + } + } + spin_unlock(&ctx->buffer_meta_lock); +} + static int __coda_decoder_seq_init(struct coda_ctx *ctx) { struct coda_q_data *q_data_src, *q_data_dst; @@ -1922,10 +1945,17 @@ static int __coda_decoder_seq_init(struct coda_ctx *ctx) } ctx->sequence_offset = ~0U; ctx->initialized = 1; + ctx->first_frame_sequence = 0; /* Update kfifo out pointer from coda bitstream read pointer */ coda_kfifo_sync_from_device(ctx); + /* + * After updating the read pointer, we need to check if + * any metas are consumed and should be released. + */ + coda_decoder_drop_used_metas(ctx); + if (coda_read(dev, CODA_RET_DEC_SEQ_SUCCESS) == 0) { v4l2_err(&dev->v4l2_dev, "CODA_COMMAND_SEQ_INIT failed, error code = 0x%x\n", @@ -2005,21 +2035,13 @@ static void coda_dec_seq_init_work(struct work_struct *work) struct coda_ctx *ctx = container_of(work, struct coda_ctx, seq_init_work); struct coda_dev *dev = ctx->dev; - int ret; mutex_lock(&ctx->buffer_mutex); mutex_lock(&dev->coda_mutex); - if (ctx->initialized == 1) - goto out; - - ret = __coda_decoder_seq_init(ctx); - if (ret < 0) - goto out; - - ctx->initialized = 1; + if (!ctx->initialized) + __coda_decoder_seq_init(ctx); -out: mutex_unlock(&dev->coda_mutex); mutex_unlock(&ctx->buffer_mutex); } @@ -2348,9 +2370,12 @@ static void coda_finish_decode(struct coda_ctx *ctx) } err_mb = coda_read(dev, CODA_RET_DEC_PIC_ERR_MB); - if (err_mb > 0) - v4l2_err(&dev->v4l2_dev, - "errors in %d macroblocks\n", err_mb); + if (err_mb > 0) { + if (__ratelimit(&dev->mb_err_rs)) + coda_dbg(1, ctx, "errors in %d macroblocks\n", err_mb); + v4l2_ctrl_s_ctrl(ctx->mb_err_cnt_ctrl, + v4l2_ctrl_g_ctrl(ctx->mb_err_cnt_ctrl) + err_mb); + } if (dev->devtype->product == CODA_HX4 || dev->devtype->product == CODA_7541) { @@ -2404,12 +2429,16 @@ static void coda_finish_decode(struct coda_ctx *ctx) v4l2_err(&dev->v4l2_dev, "decoded frame index out of range: %d\n", decoded_idx); } else { + int sequence; + decoded_frame = &ctx->internal_frames[decoded_idx]; val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM); if (ctx->sequence_offset == -1) ctx->sequence_offset = val; - val -= ctx->sequence_offset; + + sequence = val + ctx->first_frame_sequence + - ctx->sequence_offset; spin_lock(&ctx->buffer_meta_lock); if (!list_empty(&ctx->buffer_meta_list)) { meta = list_first_entry(&ctx->buffer_meta_list, @@ -2424,10 +2453,10 @@ static void coda_finish_decode(struct coda_ctx *ctx) * should be enough to detect most errors and saves us * from doing different things based on the format. */ - if ((val & 0xffff) != (meta->sequence & 0xffff)) { + if ((sequence & 0xffff) != (meta->sequence & 0xffff)) { v4l2_err(&dev->v4l2_dev, "sequence number mismatch (%d(%d) != %d)\n", - val, ctx->sequence_offset, + sequence, ctx->sequence_offset, meta->sequence); } decoded_frame->meta = *meta; @@ -2437,7 +2466,7 @@ static void coda_finish_decode(struct coda_ctx *ctx) v4l2_err(&dev->v4l2_dev, "empty timestamp list!\n"); memset(&decoded_frame->meta, 0, sizeof(struct coda_buffer_meta)); - decoded_frame->meta.sequence = val; + decoded_frame->meta.sequence = sequence; decoded_frame->meta.last = false; ctx->sequence_offset++; } |