On Wed May 21 09:54:07 2025 +0800, Ming Qian wrote: > Applications may set data_offset when it refers to an output queue. So > driver need to account for it when getting the start address of input > image in the plane. > > Meanwhile the mxc-jpeg codec requires the address (plane address + > data_offset) to be 16-aligned. > > Fixes: 2db16c6ed72c ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG > Encoder/Decoder") > Signed-off-by: Ming Qian <ming.q...@oss.nxp.com> > Reviewed-by: Frank Li <frank...@nxp.com> > Signed-off-by: Nicolas Dufresne <nicolas.dufre...@collabora.com> > Signed-off-by: Hans Verkuil <hverk...@xs4all.nl>
Patch committed. Thanks, Hans Verkuil drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 47 ++++++++++++++++++++------ drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h | 1 + 2 files changed, 37 insertions(+), 11 deletions(-) --- diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index 5c17bc58181e..8681dd193033 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -598,6 +598,27 @@ static void _bswap16(u16 *a) *a = ((*a & 0x00FF) << 8) | ((*a & 0xFF00) >> 8); } +static dma_addr_t mxc_jpeg_get_plane_dma_addr(struct vb2_buffer *buf, unsigned int plane_no) +{ + if (plane_no >= buf->num_planes) + return 0; + return vb2_dma_contig_plane_dma_addr(buf, plane_no) + buf->planes[plane_no].data_offset; +} + +static void *mxc_jpeg_get_plane_vaddr(struct vb2_buffer *buf, unsigned int plane_no) +{ + if (plane_no >= buf->num_planes) + return NULL; + return vb2_plane_vaddr(buf, plane_no) + buf->planes[plane_no].data_offset; +} + +static unsigned long mxc_jpeg_get_plane_payload(struct vb2_buffer *buf, unsigned int plane_no) +{ + if (plane_no >= buf->num_planes) + return 0; + return vb2_get_plane_payload(buf, plane_no) - buf->planes[plane_no].data_offset; +} + static void print_mxc_buf(struct mxc_jpeg_dev *jpeg, struct vb2_buffer *buf, unsigned long len) { @@ -610,11 +631,11 @@ static void print_mxc_buf(struct mxc_jpeg_dev *jpeg, struct vb2_buffer *buf, return; for (plane_no = 0; plane_no < buf->num_planes; plane_no++) { - payload = vb2_get_plane_payload(buf, plane_no); + payload = mxc_jpeg_get_plane_payload(buf, plane_no); if (len == 0) len = payload; - dma_addr = vb2_dma_contig_plane_dma_addr(buf, plane_no); - vaddr = vb2_plane_vaddr(buf, plane_no); + dma_addr = mxc_jpeg_get_plane_dma_addr(buf, plane_no); + vaddr = mxc_jpeg_get_plane_vaddr(buf, plane_no); v4l2_dbg(3, debug, &jpeg->v4l2_dev, "plane %d (vaddr=%p dma_addr=%x payload=%ld):", plane_no, vaddr, dma_addr, payload); @@ -712,16 +733,15 @@ static void mxc_jpeg_addrs(struct mxc_jpeg_desc *desc, struct mxc_jpeg_q_data *q_data; q_data = mxc_jpeg_get_q_data(ctx, raw_buf->type); - desc->buf_base0 = vb2_dma_contig_plane_dma_addr(raw_buf, 0); + desc->buf_base0 = mxc_jpeg_get_plane_dma_addr(raw_buf, 0); desc->buf_base1 = 0; if (img_fmt == STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV420)) { if (raw_buf->num_planes == 2) - desc->buf_base1 = vb2_dma_contig_plane_dma_addr(raw_buf, 1); + desc->buf_base1 = mxc_jpeg_get_plane_dma_addr(raw_buf, 1); else desc->buf_base1 = desc->buf_base0 + q_data->sizeimage[0]; } - desc->stm_bufbase = vb2_dma_contig_plane_dma_addr(jpeg_buf, 0) + - offset; + desc->stm_bufbase = mxc_jpeg_get_plane_dma_addr(jpeg_buf, 0) + offset; } static bool mxc_jpeg_is_extended_sequential(const struct mxc_jpeg_fmt *fmt) @@ -1029,8 +1049,8 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) vb2_set_plane_payload(&dst_buf->vb2_buf, 1, payload); } dev_dbg(dev, "Decoding finished, payload size: %ld + %ld\n", - vb2_get_plane_payload(&dst_buf->vb2_buf, 0), - vb2_get_plane_payload(&dst_buf->vb2_buf, 1)); + mxc_jpeg_get_plane_payload(&dst_buf->vb2_buf, 0), + mxc_jpeg_get_plane_payload(&dst_buf->vb2_buf, 1)); } /* short preview of the results */ @@ -1889,8 +1909,8 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb) struct mxc_jpeg_sof *psof = NULL; struct mxc_jpeg_sos *psos = NULL; struct mxc_jpeg_src_buf *jpeg_src_buf = vb2_to_mxc_buf(vb); - u8 *src_addr = (u8 *)vb2_plane_vaddr(vb, 0); - u32 size = vb2_get_plane_payload(vb, 0); + u8 *src_addr = (u8 *)mxc_jpeg_get_plane_vaddr(vb, 0); + u32 size = mxc_jpeg_get_plane_payload(vb, 0); int ret; memset(&header, 0, sizeof(header)); @@ -2027,6 +2047,11 @@ static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb) i, vb2_plane_size(vb, i), sizeimage); return -EINVAL; } + if (!IS_ALIGNED(mxc_jpeg_get_plane_dma_addr(vb, i), MXC_JPEG_ADDR_ALIGNMENT)) { + dev_err(dev, "planes[%d] address is not %d aligned\n", + i, MXC_JPEG_ADDR_ALIGNMENT); + return -EINVAL; + } } if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) { vb2_set_plane_payload(vb, 0, 0); diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h index fdde45f7e163..44e46face6d1 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h @@ -30,6 +30,7 @@ #define MXC_JPEG_MAX_PLANES 2 #define MXC_JPEG_PATTERN_WIDTH 128 #define MXC_JPEG_PATTERN_HEIGHT 64 +#define MXC_JPEG_ADDR_ALIGNMENT 16 enum mxc_jpeg_enc_state { MXC_JPEG_ENCODING = 0, /* jpeg encode phase */