media: coda: fix CODA960 JPEG encoder buffer overflow
[ 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: 96f6f62c46
("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>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
1da628d351
commit
89f518b153
@@ -1537,11 +1537,13 @@ static void coda_pic_run_work(struct work_struct *work)
|
|||||||
|
|
||||||
if (!wait_for_completion_timeout(&ctx->completion,
|
if (!wait_for_completion_timeout(&ctx->completion,
|
||||||
msecs_to_jiffies(1000))) {
|
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)
|
if (ctx->ops->run_timeout)
|
||||||
ctx->ops->run_timeout(ctx);
|
ctx->ops->run_timeout(ctx);
|
||||||
|
@@ -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_BT_PTR);
|
||||||
coda_write(dev, 0, CODA9_REG_JPEG_GBU_WD_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_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_CTRL);
|
||||||
coda_write(dev, 0, CODA9_REG_JPEG_GBU_FF_RPTR);
|
coda_write(dev, 0, CODA9_REG_JPEG_GBU_FF_RPTR);
|
||||||
coda_write(dev, 127, CODA9_REG_JPEG_GBU_BBER);
|
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);
|
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)
|
static void coda9_jpeg_release(struct coda_ctx *ctx)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -1276,6 +1294,7 @@ const struct coda_context_ops coda9_jpeg_encode_ops = {
|
|||||||
.start_streaming = coda9_jpeg_start_encoding,
|
.start_streaming = coda9_jpeg_start_encoding,
|
||||||
.prepare_run = coda9_jpeg_prepare_encode,
|
.prepare_run = coda9_jpeg_prepare_encode,
|
||||||
.finish_run = coda9_jpeg_finish_encode,
|
.finish_run = coda9_jpeg_finish_encode,
|
||||||
|
.run_timeout = coda9_jpeg_encode_timeout,
|
||||||
.release = coda9_jpeg_release,
|
.release = coda9_jpeg_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user