aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2015-03-24 13:30:52 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-10 09:07:58 -0400
commitad532d37b2958f6c7652429be36ddd46a65ab67a (patch)
treea9cf7cc63cd123c88512d4363f6ae9b5b4910d7d
parent73751da61c00db9914ae1c47a25f7462722bc76b (diff)
[media] coda: allocate bitstream buffer from REQBUFS, size depends on the format
Allocating the bitstream buffer only when the format is set allows to guarantee that at least two frames fit into the bitstream buffer. For small frame sizes a smaller bitstream buffer can be allocated. Since the bitstream buffer size now depends on the format, replace CODA_MAX_FRAME_SIZE with ctx->bitstream.size where appropriate and remove the now unused constant. Since REQBUFS can be called multiple times, but the format can't be changed unless REQBUFS 0 was called before, we can just keep the allocated context and bitstream buffers if REQBUFS is called multiple times with a non-zero buffer count. [fixed a resource leak preventing repeatedly decoding] Signed-off-by: Peter Seiderer <ps.report@gmx.net> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Signed-off-by: Kamil Debski <k.debski@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/platform/coda/coda-bit.c85
-rw-r--r--drivers/media/platform/coda/coda-common.c22
-rw-r--r--drivers/media/platform/coda/coda.h1
3 files changed, 58 insertions, 50 deletions
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 @@
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/irqreturn.h> 16#include <linux/irqreturn.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/log2.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
19#include <linux/reset.h> 20#include <linux/reset.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
@@ -36,6 +37,8 @@
36#define CODA_DEFAULT_GAMMA 4096 37#define CODA_DEFAULT_GAMMA 4096
37#define CODA9_DEFAULT_GAMMA 24576 /* 0.75 * 32768 */ 38#define CODA9_DEFAULT_GAMMA 24576 /* 0.75 * 32768 */
38 39
40static void coda_free_bitstream_buffer(struct coda_ctx *ctx);
41
39static inline int coda_is_initialized(struct coda_dev *dev) 42static inline int coda_is_initialized(struct coda_dev *dev)
40{ 43{
41 return coda_read(dev, CODA_REG_BIT_CUR_PC) != 0; 44 return coda_read(dev, CODA_REG_BIT_CUR_PC) != 0;
@@ -389,21 +392,7 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx,
389 if (dev->devtype->product == CODA_DX6) 392 if (dev->devtype->product == CODA_DX6)
390 return 0; 393 return 0;
391 394
392 if (ctx->psbuf.vaddr) { 395 if (!ctx->slicebuf.vaddr && q_data->fourcc == V4L2_PIX_FMT_H264) {
393 v4l2_err(&dev->v4l2_dev, "psmembuf still allocated\n");
394 return -EBUSY;
395 }
396 if (ctx->slicebuf.vaddr) {
397 v4l2_err(&dev->v4l2_dev, "slicebuf still allocated\n");
398 return -EBUSY;
399 }
400 if (ctx->workbuf.vaddr) {
401 v4l2_err(&dev->v4l2_dev, "context buffer still allocated\n");
402 ret = -EBUSY;
403 return -ENOMEM;
404 }
405
406 if (q_data->fourcc == V4L2_PIX_FMT_H264) {
407 /* worst case slice size */ 396 /* worst case slice size */
408 size = (DIV_ROUND_UP(q_data->width, 16) * 397 size = (DIV_ROUND_UP(q_data->width, 16) *
409 DIV_ROUND_UP(q_data->height, 16)) * 3200 / 8 + 512; 398 DIV_ROUND_UP(q_data->height, 16)) * 3200 / 8 + 512;
@@ -417,7 +406,7 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx,
417 } 406 }
418 } 407 }
419 408
420 if (dev->devtype->product == CODA_7541) { 409 if (!ctx->psbuf.vaddr && dev->devtype->product == CODA_7541) {
421 ret = coda_alloc_context_buf(ctx, &ctx->psbuf, 410 ret = coda_alloc_context_buf(ctx, &ctx->psbuf,
422 CODA7_PS_BUF_SIZE, "psbuf"); 411 CODA7_PS_BUF_SIZE, "psbuf");
423 if (ret < 0) { 412 if (ret < 0) {
@@ -427,16 +416,19 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx,
427 } 416 }
428 } 417 }
429 418
430 size = dev->devtype->workbuf_size; 419 if (!ctx->workbuf.vaddr) {
431 if (dev->devtype->product == CODA_960 && 420 size = dev->devtype->workbuf_size;
432 q_data->fourcc == V4L2_PIX_FMT_H264) 421 if (dev->devtype->product == CODA_960 &&
433 size += CODA9_PS_SAVE_SIZE; 422 q_data->fourcc == V4L2_PIX_FMT_H264)
434 ret = coda_alloc_context_buf(ctx, &ctx->workbuf, size, "workbuf"); 423 size += CODA9_PS_SAVE_SIZE;
435 if (ret < 0) { 424 ret = coda_alloc_context_buf(ctx, &ctx->workbuf, size,
436 v4l2_err(&dev->v4l2_dev, 425 "workbuf");
437 "failed to allocate %d byte context buffer", 426 if (ret < 0) {
438 ctx->workbuf.size); 427 v4l2_err(&dev->v4l2_dev,
439 goto err; 428 "failed to allocate %d byte context buffer",
429 ctx->workbuf.size);
430 goto err;
431 }
440 } 432 }
441 433
442 return 0; 434 return 0;
@@ -1337,6 +1329,7 @@ static void coda_bit_release(struct coda_ctx *ctx)
1337 mutex_lock(&ctx->buffer_mutex); 1329 mutex_lock(&ctx->buffer_mutex);
1338 coda_free_framebuffers(ctx); 1330 coda_free_framebuffers(ctx);
1339 coda_free_context_buffers(ctx); 1331 coda_free_context_buffers(ctx);
1332 coda_free_bitstream_buffer(ctx);
1340 mutex_unlock(&ctx->buffer_mutex); 1333 mutex_unlock(&ctx->buffer_mutex);
1341} 1334}
1342 1335
@@ -1354,6 +1347,38 @@ const struct coda_context_ops coda_bit_encode_ops = {
1354 * Decoder context operations 1347 * Decoder context operations
1355 */ 1348 */
1356 1349
1350static int coda_alloc_bitstream_buffer(struct coda_ctx *ctx,
1351 struct coda_q_data *q_data)
1352{
1353 if (ctx->bitstream.vaddr)
1354 return 0;
1355
1356 ctx->bitstream.size = roundup_pow_of_two(q_data->sizeimage * 2);
1357 ctx->bitstream.vaddr = dma_alloc_writecombine(
1358 &ctx->dev->plat_dev->dev, ctx->bitstream.size,
1359 &ctx->bitstream.paddr, GFP_KERNEL);
1360 if (!ctx->bitstream.vaddr) {
1361 v4l2_err(&ctx->dev->v4l2_dev,
1362 "failed to allocate bitstream ringbuffer");
1363 return -ENOMEM;
1364 }
1365 kfifo_init(&ctx->bitstream_fifo,
1366 ctx->bitstream.vaddr, ctx->bitstream.size);
1367
1368 return 0;
1369}
1370
1371static void coda_free_bitstream_buffer(struct coda_ctx *ctx)
1372{
1373 if (ctx->bitstream.vaddr == NULL)
1374 return;
1375
1376 dma_free_writecombine(&ctx->dev->plat_dev->dev, ctx->bitstream.size,
1377 ctx->bitstream.vaddr, ctx->bitstream.paddr);
1378 ctx->bitstream.vaddr = NULL;
1379 kfifo_init(&ctx->bitstream_fifo, NULL, 0);
1380}
1381
1357static int coda_decoder_reqbufs(struct coda_ctx *ctx, 1382static int coda_decoder_reqbufs(struct coda_ctx *ctx,
1358 struct v4l2_requestbuffers *rb) 1383 struct v4l2_requestbuffers *rb)
1359{ 1384{
@@ -1368,7 +1393,13 @@ static int coda_decoder_reqbufs(struct coda_ctx *ctx,
1368 ret = coda_alloc_context_buffers(ctx, q_data_src); 1393 ret = coda_alloc_context_buffers(ctx, q_data_src);
1369 if (ret < 0) 1394 if (ret < 0)
1370 return ret; 1395 return ret;
1396 ret = coda_alloc_bitstream_buffer(ctx, q_data_src);
1397 if (ret < 0) {
1398 coda_free_context_buffers(ctx);
1399 return ret;
1400 }
1371 } else { 1401 } else {
1402 coda_free_bitstream_buffer(ctx);
1372 coda_free_context_buffers(ctx); 1403 coda_free_context_buffers(ctx);
1373 } 1404 }
1374 1405
@@ -1736,7 +1767,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
1736 * by up to 512 bytes 1767 * by up to 512 bytes
1737 */ 1768 */
1738 if (ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) { 1769 if (ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) {
1739 if (coda_get_bitstream_payload(ctx) >= CODA_MAX_FRAME_SIZE - 512) 1770 if (coda_get_bitstream_payload(ctx) >= ctx->bitstream.size - 512)
1740 kfifo_init(&ctx->bitstream_fifo, 1771 kfifo_init(&ctx->bitstream_fifo,
1741 ctx->bitstream.vaddr, ctx->bitstream.size); 1772 ctx->bitstream.vaddr, ctx->bitstream.size);
1742 } 1773 }
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)
1723 goto err_dma_alloc; 1723 goto err_dma_alloc;
1724 } 1724 }
1725 } 1725 }
1726 if (ctx->use_bit && ctx->inst_type == CODA_INST_DECODER) {
1727 ctx->bitstream.size = CODA_MAX_FRAME_SIZE;
1728 ctx->bitstream.vaddr = dma_alloc_writecombine(
1729 &dev->plat_dev->dev, ctx->bitstream.size,
1730 &ctx->bitstream.paddr, GFP_KERNEL);
1731 if (!ctx->bitstream.vaddr) {
1732 v4l2_err(&dev->v4l2_dev,
1733 "failed to allocate bitstream ringbuffer");
1734 ret = -ENOMEM;
1735 goto err_dma_writecombine;
1736 }
1737 }
1738 kfifo_init(&ctx->bitstream_fifo,
1739 ctx->bitstream.vaddr, ctx->bitstream.size);
1740 mutex_init(&ctx->bitstream_mutex); 1726 mutex_init(&ctx->bitstream_mutex);
1741 mutex_init(&ctx->buffer_mutex); 1727 mutex_init(&ctx->buffer_mutex);
1742 INIT_LIST_HEAD(&ctx->buffer_meta_list); 1728 INIT_LIST_HEAD(&ctx->buffer_meta_list);
@@ -1750,10 +1736,6 @@ static int coda_open(struct file *file)
1750 1736
1751 return 0; 1737 return 0;
1752 1738
1753err_dma_writecombine:
1754 if (ctx->dev->devtype->product == CODA_DX6)
1755 coda_free_aux_buf(dev, &ctx->workbuf);
1756 coda_free_aux_buf(dev, &ctx->parabuf);
1757err_dma_alloc: 1739err_dma_alloc:
1758 v4l2_ctrl_handler_free(&ctx->ctrls); 1740 v4l2_ctrl_handler_free(&ctx->ctrls);
1759err_ctrls_setup: 1741err_ctrls_setup:
@@ -1798,10 +1780,6 @@ static int coda_release(struct file *file)
1798 list_del(&ctx->list); 1780 list_del(&ctx->list);
1799 coda_unlock(ctx); 1781 coda_unlock(ctx);
1800 1782
1801 if (ctx->bitstream.vaddr) {
1802 dma_free_writecombine(&dev->plat_dev->dev, ctx->bitstream.size,
1803 ctx->bitstream.vaddr, ctx->bitstream.paddr);
1804 }
1805 if (ctx->dev->devtype->product == CODA_DX6) 1783 if (ctx->dev->devtype->product == CODA_DX6)
1806 coda_free_aux_buf(dev, &ctx->workbuf); 1784 coda_free_aux_buf(dev, &ctx->workbuf);
1807 1785
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 @@
26#include "coda_regs.h" 26#include "coda_regs.h"
27 27
28#define CODA_MAX_FRAMEBUFFERS 8 28#define CODA_MAX_FRAMEBUFFERS 8
29#define CODA_MAX_FRAME_SIZE 0x100000
30#define FMO_SLICE_SAVE_BUF_SIZE (32) 29#define FMO_SLICE_SAVE_BUF_SIZE (32)
31 30
32enum { 31enum {