lkml.org 
[lkml]   [2022]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 112/563] media: coda: fix CODA960 JPEG encoder buffer overflow
    Date
    From: Philipp Zabel <p.zabel@pengutronix.de>

    [ Upstream commit 1a59cd88f55068710f6549bee548846661673780 ]

    Stop the CODA960 JPEG encoder from overflowing capture buffers.
    The bitstream buffer overflow interrupt doesn't seem to be connected,
    so this has to be handled via timeout instead.

    Reported-by: Martin Weber <martin.weber@br-automation.com>
    Fixes: 96f6f62c4656 ("media: coda: jpeg: add CODA960 JPEG encoder support")
    Tested-by: Martin Weber <martin.weber@br-automation.com>
    Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
    Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
    Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/media/platform/coda/coda-common.c | 8 +++++---
    drivers/media/platform/coda/coda-jpeg.c | 21 ++++++++++++++++++++-
    2 files changed, 25 insertions(+), 4 deletions(-)

    diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
    index 87a2c706f7477..1eed69d29149f 100644
    --- a/drivers/media/platform/coda/coda-common.c
    +++ b/drivers/media/platform/coda/coda-common.c
    @@ -1537,11 +1537,13 @@ static void coda_pic_run_work(struct work_struct *work)

    if (!wait_for_completion_timeout(&ctx->completion,
    msecs_to_jiffies(1000))) {
    - dev_err(dev->dev, "CODA PIC_RUN timeout\n");
    + if (ctx->use_bit) {
    + dev_err(dev->dev, "CODA PIC_RUN timeout\n");

    - ctx->hold = true;
    + ctx->hold = true;

    - coda_hw_reset(ctx);
    + coda_hw_reset(ctx);
    + }

    if (ctx->ops->run_timeout)
    ctx->ops->run_timeout(ctx);
    diff --git a/drivers/media/platform/coda/coda-jpeg.c b/drivers/media/platform/coda/coda-jpeg.c
    index b11cfbe166dd3..a72f4655e5ad5 100644
    --- a/drivers/media/platform/coda/coda-jpeg.c
    +++ b/drivers/media/platform/coda/coda-jpeg.c
    @@ -1127,7 +1127,8 @@ static int coda9_jpeg_prepare_encode(struct coda_ctx *ctx)
    coda_write(dev, 0, CODA9_REG_JPEG_GBU_BT_PTR);
    coda_write(dev, 0, CODA9_REG_JPEG_GBU_WD_PTR);
    coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBSR);
    - coda_write(dev, 0, CODA9_REG_JPEG_BBC_STRM_CTRL);
    + coda_write(dev, BIT(31) | ((end_addr - start_addr - header_len) / 256),
    + CODA9_REG_JPEG_BBC_STRM_CTRL);
    coda_write(dev, 0, CODA9_REG_JPEG_GBU_CTRL);
    coda_write(dev, 0, CODA9_REG_JPEG_GBU_FF_RPTR);
    coda_write(dev, 127, CODA9_REG_JPEG_GBU_BBER);
    @@ -1257,6 +1258,23 @@ static void coda9_jpeg_finish_encode(struct coda_ctx *ctx)
    coda_hw_reset(ctx);
    }

    +static void coda9_jpeg_encode_timeout(struct coda_ctx *ctx)
    +{
    + struct coda_dev *dev = ctx->dev;
    + u32 end_addr, wr_ptr;
    +
    + /* Handle missing BBC overflow interrupt via timeout */
    + end_addr = coda_read(dev, CODA9_REG_JPEG_BBC_END_ADDR);
    + wr_ptr = coda_read(dev, CODA9_REG_JPEG_BBC_WR_PTR);
    + if (wr_ptr >= end_addr - 256) {
    + v4l2_err(&dev->v4l2_dev, "JPEG too large for capture buffer\n");
    + coda9_jpeg_finish_encode(ctx);
    + return;
    + }
    +
    + coda_hw_reset(ctx);
    +}
    +
    static void coda9_jpeg_release(struct coda_ctx *ctx)
    {
    int i;
    @@ -1276,6 +1294,7 @@ const struct coda_context_ops coda9_jpeg_encode_ops = {
    .start_streaming = coda9_jpeg_start_encoding,
    .prepare_run = coda9_jpeg_prepare_encode,
    .finish_run = coda9_jpeg_finish_encode,
    + .run_timeout = coda9_jpeg_encode_timeout,
    .release = coda9_jpeg_release,
    };

    --
    2.34.1


    \
     
     \ /
      Last update: 2022-01-25 04:10    [W:2.360 / U:0.116 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site