diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 12b93867e665..5aa8d8774d0c 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,8 @@ #define CODA_DEFAULT_GAMMA 4096 #define CODA9_DEFAULT_GAMMA 24576 /* 0.75 * 32768 */ +static void coda_free_bitstream_buffer(struct coda_ctx *ctx); + static inline int coda_is_initialized(struct coda_dev *dev) { return coda_read(dev, CODA_REG_BIT_CUR_PC) != 0; @@ -389,21 +392,7 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx, if (dev->devtype->product == CODA_DX6) return 0; - if (ctx->psbuf.vaddr) { - v4l2_err(&dev->v4l2_dev, "psmembuf still allocated\n"); - return -EBUSY; - } - if (ctx->slicebuf.vaddr) { - v4l2_err(&dev->v4l2_dev, "slicebuf still allocated\n"); - return -EBUSY; - } - if (ctx->workbuf.vaddr) { - v4l2_err(&dev->v4l2_dev, "context buffer still allocated\n"); - ret = -EBUSY; - return -ENOMEM; - } - - if (q_data->fourcc == V4L2_PIX_FMT_H264) { + if (!ctx->slicebuf.vaddr && q_data->fourcc == V4L2_PIX_FMT_H264) { /* worst case slice size */ size = (DIV_ROUND_UP(q_data->width, 16) * DIV_ROUND_UP(q_data->height, 16)) * 3200 / 8 + 512; @@ -417,7 +406,7 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx, } } - if (dev->devtype->product == CODA_7541) { + if (!ctx->psbuf.vaddr && dev->devtype->product == CODA_7541) { ret = coda_alloc_context_buf(ctx, &ctx->psbuf, CODA7_PS_BUF_SIZE, "psbuf"); if (ret < 0) { @@ -427,16 +416,19 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx, } } - size = dev->devtype->workbuf_size; - if (dev->devtype->product == CODA_960 && - q_data->fourcc == V4L2_PIX_FMT_H264) - size += CODA9_PS_SAVE_SIZE; - ret = coda_alloc_context_buf(ctx, &ctx->workbuf, size, "workbuf"); - if (ret < 0) { - v4l2_err(&dev->v4l2_dev, - "failed to allocate %d byte context buffer", - ctx->workbuf.size); - goto err; + if (!ctx->workbuf.vaddr) { + size = dev->devtype->workbuf_size; + if (dev->devtype->product == CODA_960 && + q_data->fourcc == V4L2_PIX_FMT_H264) + size += CODA9_PS_SAVE_SIZE; + ret = coda_alloc_context_buf(ctx, &ctx->workbuf, size, + "workbuf"); + if (ret < 0) { + v4l2_err(&dev->v4l2_dev, + "failed to allocate %d byte context buffer", + ctx->workbuf.size); + goto err; + } } return 0; @@ -1337,6 +1329,7 @@ static void coda_bit_release(struct coda_ctx *ctx) mutex_lock(&ctx->buffer_mutex); coda_free_framebuffers(ctx); coda_free_context_buffers(ctx); + coda_free_bitstream_buffer(ctx); mutex_unlock(&ctx->buffer_mutex); } @@ -1354,6 +1347,38 @@ const struct coda_context_ops coda_bit_encode_ops = { * Decoder context operations */ +static int coda_alloc_bitstream_buffer(struct coda_ctx *ctx, + struct coda_q_data *q_data) +{ + if (ctx->bitstream.vaddr) + return 0; + + ctx->bitstream.size = roundup_pow_of_two(q_data->sizeimage * 2); + ctx->bitstream.vaddr = dma_alloc_writecombine( + &ctx->dev->plat_dev->dev, ctx->bitstream.size, + &ctx->bitstream.paddr, GFP_KERNEL); + if (!ctx->bitstream.vaddr) { + v4l2_err(&ctx->dev->v4l2_dev, + "failed to allocate bitstream ringbuffer"); + return -ENOMEM; + } + kfifo_init(&ctx->bitstream_fifo, + ctx->bitstream.vaddr, ctx->bitstream.size); + + return 0; +} + +static void coda_free_bitstream_buffer(struct coda_ctx *ctx) +{ + if (ctx->bitstream.vaddr == NULL) + return; + + dma_free_writecombine(&ctx->dev->plat_dev->dev, ctx->bitstream.size, + ctx->bitstream.vaddr, ctx->bitstream.paddr); + ctx->bitstream.vaddr = NULL; + kfifo_init(&ctx->bitstream_fifo, NULL, 0); +} + static int coda_decoder_reqbufs(struct coda_ctx *ctx, struct v4l2_requestbuffers *rb) { @@ -1368,7 +1393,13 @@ static int coda_decoder_reqbufs(struct coda_ctx *ctx, ret = coda_alloc_context_buffers(ctx, q_data_src); if (ret < 0) return ret; + ret = coda_alloc_bitstream_buffer(ctx, q_data_src); + if (ret < 0) { + coda_free_context_buffers(ctx); + return ret; + } } else { + coda_free_bitstream_buffer(ctx); coda_free_context_buffers(ctx); } @@ -1736,7 +1767,7 @@ static void coda_finish_decode(struct coda_ctx *ctx) * by up to 512 bytes */ if (ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) { - if (coda_get_bitstream_payload(ctx) >= CODA_MAX_FRAME_SIZE - 512) + if (coda_get_bitstream_payload(ctx) >= ctx->bitstream.size - 512) kfifo_init(&ctx->bitstream_fifo, ctx->bitstream.vaddr, ctx->bitstream.size); } diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index a8a6c36a1f00..3a852ac6a8c3 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -1723,20 +1723,6 @@ static int coda_open(struct file *file) goto err_dma_alloc; } } - if (ctx->use_bit && ctx->inst_type == CODA_INST_DECODER) { - ctx->bitstream.size = CODA_MAX_FRAME_SIZE; - ctx->bitstream.vaddr = dma_alloc_writecombine( - &dev->plat_dev->dev, ctx->bitstream.size, - &ctx->bitstream.paddr, GFP_KERNEL); - if (!ctx->bitstream.vaddr) { - v4l2_err(&dev->v4l2_dev, - "failed to allocate bitstream ringbuffer"); - ret = -ENOMEM; - goto err_dma_writecombine; - } - } - kfifo_init(&ctx->bitstream_fifo, - ctx->bitstream.vaddr, ctx->bitstream.size); mutex_init(&ctx->bitstream_mutex); mutex_init(&ctx->buffer_mutex); INIT_LIST_HEAD(&ctx->buffer_meta_list); @@ -1750,10 +1736,6 @@ static int coda_open(struct file *file) return 0; -err_dma_writecombine: - if (ctx->dev->devtype->product == CODA_DX6) - coda_free_aux_buf(dev, &ctx->workbuf); - coda_free_aux_buf(dev, &ctx->parabuf); err_dma_alloc: v4l2_ctrl_handler_free(&ctx->ctrls); err_ctrls_setup: @@ -1798,10 +1780,6 @@ static int coda_release(struct file *file) list_del(&ctx->list); coda_unlock(ctx); - if (ctx->bitstream.vaddr) { - dma_free_writecombine(&dev->plat_dev->dev, ctx->bitstream.size, - ctx->bitstream.vaddr, ctx->bitstream.paddr); - } if (ctx->dev->devtype->product == CODA_DX6) coda_free_aux_buf(dev, &ctx->workbuf); diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h index 57d070ce6665..01d940c630b3 100644 --- a/drivers/media/platform/coda/coda.h +++ b/drivers/media/platform/coda/coda.h @@ -26,7 +26,6 @@ #include "coda_regs.h" #define CODA_MAX_FRAMEBUFFERS 8 -#define CODA_MAX_FRAME_SIZE 0x100000 #define FMO_SLICE_SAVE_BUF_SIZE (32) enum {