* [PATCH v4 0/4] media: imx-jpeg: Fix some motion-jpeg decoding
@ 2025-04-11 7:43 ming.qian
2025-04-11 7:43 ` [PATCH v4 1/4] media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead ming.qian
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: ming.qian @ 2025-04-11 7:43 UTC (permalink / raw)
To: mchehab, hverkuil-cisco, mirela.rabulea
Cc: shawnguo, s.hauer, kernel, festevam, xiahong.bao, eagle.zhou,
linux-imx, imx, linux-media, linux-kernel, linux-arm-kernel
From: Ming Qian <ming.qian@oss.nxp.com>
To support decoding motion-jpeg without DHT, driver will try to decode a
pattern jpeg before actual jpeg frame by use of linked descriptors
(This is called "repeat mode"), then the DHT in the pattern jpeg can be
used for decoding the motion-jpeg.
But there is some hardware limitation in the repeat mode, that may cause
corruption or decoding timeout.
Try to make workaround for these limitation in this patchset.
Ming Qian (4):
media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead
media: imx-jpeg: Cleanup after an allocation error
media: imx-jpeg: Change the pattern size to 128x64
media: imx-jpeg: Check decoding is ongoing for motion-jpeg
.../media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h | 1 +
.../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 120 +++++++++++++-----
.../media/platform/nxp/imx-jpeg/mxc-jpeg.h | 5 +
3 files changed, 97 insertions(+), 29 deletions(-)
--
2.43.0-rc1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v4 1/4] media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead
2025-04-11 7:43 [PATCH v4 0/4] media: imx-jpeg: Fix some motion-jpeg decoding ming.qian
@ 2025-04-11 7:43 ` ming.qian
2025-04-11 14:36 ` Frank Li
2025-04-11 7:43 ` [PATCH v4 2/4] media: imx-jpeg: Cleanup after an allocation error ming.qian
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: ming.qian @ 2025-04-11 7:43 UTC (permalink / raw)
To: mchehab, hverkuil-cisco, mirela.rabulea
Cc: shawnguo, s.hauer, kernel, festevam, xiahong.bao, eagle.zhou,
linux-imx, imx, linux-media, linux-kernel, linux-arm-kernel
From: Ming Qian <ming.qian@oss.nxp.com>
Move function mxc_jpeg_free_slot_data() above mxc_jpeg_alloc_slot_data()
allowing to call that function during allocation failures.
No functional changes are made.
Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
.../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 46 +++++++++++--------
1 file changed, 26 insertions(+), 20 deletions(-)
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
index 0e6ee997284b..b2f7e9ad1885 100644
--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
@@ -752,6 +752,32 @@ static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data)
return -1;
}
+static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
+{
+ /* free descriptor for decoding/encoding phase */
+ dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
+ jpeg->slot_data.desc,
+ jpeg->slot_data.desc_handle);
+ jpeg->slot_data.desc = NULL;
+ jpeg->slot_data.desc_handle = 0;
+
+ /* free descriptor for encoder configuration phase / decoder DHT */
+ dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
+ jpeg->slot_data.cfg_desc,
+ jpeg->slot_data.cfg_desc_handle);
+ jpeg->slot_data.cfg_desc_handle = 0;
+ jpeg->slot_data.cfg_desc = NULL;
+
+ /* free configuration stream */
+ dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
+ jpeg->slot_data.cfg_stream_vaddr,
+ jpeg->slot_data.cfg_stream_handle);
+ jpeg->slot_data.cfg_stream_vaddr = NULL;
+ jpeg->slot_data.cfg_stream_handle = 0;
+
+ jpeg->slot_data.used = false;
+}
+
static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
{
struct mxc_jpeg_desc *desc;
@@ -798,26 +824,6 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
return false;
}
-static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
-{
- /* free descriptor for decoding/encoding phase */
- dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
- jpeg->slot_data.desc,
- jpeg->slot_data.desc_handle);
-
- /* free descriptor for encoder configuration phase / decoder DHT */
- dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
- jpeg->slot_data.cfg_desc,
- jpeg->slot_data.cfg_desc_handle);
-
- /* free configuration stream */
- dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
- jpeg->slot_data.cfg_stream_vaddr,
- jpeg->slot_data.cfg_stream_handle);
-
- jpeg->slot_data.used = false;
-}
-
static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx,
struct vb2_v4l2_buffer *src_buf,
struct vb2_v4l2_buffer *dst_buf)
--
2.43.0-rc1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 2/4] media: imx-jpeg: Cleanup after an allocation error
2025-04-11 7:43 [PATCH v4 0/4] media: imx-jpeg: Fix some motion-jpeg decoding ming.qian
2025-04-11 7:43 ` [PATCH v4 1/4] media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead ming.qian
@ 2025-04-11 7:43 ` ming.qian
2025-04-11 7:43 ` [PATCH v4 3/4] media: imx-jpeg: Change the pattern size to 128x64 ming.qian
2025-04-11 7:43 ` [PATCH v4 4/4] media: imx-jpeg: Check decoding is ongoing for motion-jpeg ming.qian
3 siblings, 0 replies; 8+ messages in thread
From: ming.qian @ 2025-04-11 7:43 UTC (permalink / raw)
To: mchehab, hverkuil-cisco, mirela.rabulea
Cc: shawnguo, s.hauer, kernel, festevam, xiahong.bao, eagle.zhou,
linux-imx, imx, linux-media, linux-kernel, linux-arm-kernel
From: Ming Qian <ming.qian@oss.nxp.com>
When allocation failures are not cleaned up by the driver, further
allocation errors will be false-positives, which will cause buffers to
remain uninitialized and cause NULL pointer dereferences.
Ensure proper cleanup of failed allocations to prevent these issues.
Fixes: 2db16c6ed72c ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
index b2f7e9ad1885..12661c177f5a 100644
--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
@@ -820,6 +820,7 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
return true;
err:
dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot);
+ mxc_jpeg_free_slot_data(jpeg);
return false;
}
--
2.43.0-rc1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 3/4] media: imx-jpeg: Change the pattern size to 128x64
2025-04-11 7:43 [PATCH v4 0/4] media: imx-jpeg: Fix some motion-jpeg decoding ming.qian
2025-04-11 7:43 ` [PATCH v4 1/4] media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead ming.qian
2025-04-11 7:43 ` [PATCH v4 2/4] media: imx-jpeg: Cleanup after an allocation error ming.qian
@ 2025-04-11 7:43 ` ming.qian
2025-04-11 7:43 ` [PATCH v4 4/4] media: imx-jpeg: Check decoding is ongoing for motion-jpeg ming.qian
3 siblings, 0 replies; 8+ messages in thread
From: ming.qian @ 2025-04-11 7:43 UTC (permalink / raw)
To: mchehab, hverkuil-cisco, mirela.rabulea
Cc: shawnguo, s.hauer, kernel, festevam, xiahong.bao, eagle.zhou,
linux-imx, imx, linux-media, linux-kernel, linux-arm-kernel
From: Ming Qian <ming.qian@oss.nxp.com>
In order to decode a motion-jpeg bitstream, which doesn't provide a DHT,
the driver will first decode a pattern jpeg and use the DHT found in the
pattern to decode the first actual frame. This mode is called
"repeat-mode" and it utilizes linked descriptors.
The smallest supported resolution of 64x64 was used for that pattern to
not cause unneeded performance delay. This choice, however, can cause a
corrupted decoded picture of the first frame after the pattern, when the
resolution of that frame is larger than the pattern and is not aligned
to 64.
By altering the pattern size to 128x64, this corruption can be avoided.
That size has been confirmed to be safe by the hardware designers.
Additionally, a DMA buffer needs to be allocated to store the decoded
picture of the pattern image.
Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
.../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 42 +++++++++++++++----
.../media/platform/nxp/imx-jpeg/mxc-jpeg.h | 5 +++
2 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
index 12661c177f5a..45705c606769 100644
--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
@@ -535,7 +535,18 @@ static const unsigned char jpeg_sos_maximal[] = {
};
static const unsigned char jpeg_image_red[] = {
- 0xFC, 0x5F, 0xA2, 0xBF, 0xCA, 0x73, 0xFE, 0xFE,
+ 0xF9, 0xFE, 0x8A, 0xFC, 0x34, 0xFD, 0xC4, 0x28,
+ 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A,
+ 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0,
+ 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00,
+ 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02,
+ 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28,
+ 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A,
+ 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0,
+ 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00,
+ 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02,
+ 0x8A, 0x00, 0x28, 0xA0, 0x0F, 0xFF, 0xD0, 0xF9,
+ 0xFE, 0x8A, 0xFC, 0x34, 0xFD, 0xC4, 0x28, 0xA0,
0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00,
0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02,
0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28,
@@ -545,7 +556,7 @@ static const unsigned char jpeg_image_red[] = {
0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02,
0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28,
0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A,
- 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00
+ 0x00, 0x28, 0xA0, 0x0F
};
static const unsigned char jpeg_eoi[] = {
@@ -775,6 +786,13 @@ static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
jpeg->slot_data.cfg_stream_vaddr = NULL;
jpeg->slot_data.cfg_stream_handle = 0;
+ dma_free_coherent(jpeg->dev, jpeg->slot_data.cfg_dec_size,
+ jpeg->slot_data.cfg_dec_vaddr,
+ jpeg->slot_data.cfg_dec_daddr);
+ jpeg->slot_data.cfg_dec_size = 0;
+ jpeg->slot_data.cfg_dec_vaddr = NULL;
+ jpeg->slot_data.cfg_dec_daddr = 0;
+
jpeg->slot_data.used = false;
}
@@ -814,6 +832,14 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
goto err;
jpeg->slot_data.cfg_stream_vaddr = cfg_stm;
+ jpeg->slot_data.cfg_dec_size = MXC_JPEG_PATTERN_WIDTH * MXC_JPEG_PATTERN_HEIGHT * 2;
+ jpeg->slot_data.cfg_dec_vaddr = dma_alloc_coherent(jpeg->dev,
+ jpeg->slot_data.cfg_dec_size,
+ &jpeg->slot_data.cfg_dec_daddr,
+ GFP_ATOMIC);
+ if (!jpeg->slot_data.cfg_dec_vaddr)
+ goto err;
+
skip_alloc:
jpeg->slot_data.used = true;
@@ -1216,14 +1242,14 @@ static void mxc_jpeg_config_dec_desc(struct vb2_buffer *out_buf,
*/
*cfg_size = mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr,
V4L2_PIX_FMT_YUYV,
- MXC_JPEG_MIN_WIDTH,
- MXC_JPEG_MIN_HEIGHT);
+ MXC_JPEG_PATTERN_WIDTH,
+ MXC_JPEG_PATTERN_HEIGHT);
cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN;
- cfg_desc->buf_base0 = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+ cfg_desc->buf_base0 = jpeg->slot_data.cfg_dec_daddr;
cfg_desc->buf_base1 = 0;
- cfg_desc->imgsize = MXC_JPEG_MIN_WIDTH << 16;
- cfg_desc->imgsize |= MXC_JPEG_MIN_HEIGHT;
- cfg_desc->line_pitch = MXC_JPEG_MIN_WIDTH * 2;
+ cfg_desc->imgsize = MXC_JPEG_PATTERN_WIDTH << 16;
+ cfg_desc->imgsize |= MXC_JPEG_PATTERN_HEIGHT;
+ cfg_desc->line_pitch = MXC_JPEG_PATTERN_WIDTH * 2;
cfg_desc->stm_ctrl = STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV422);
cfg_desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1);
cfg_desc->stm_bufbase = cfg_stream_handle;
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
index 86e324b21aed..fdde45f7e163 100644
--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
+++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
@@ -28,6 +28,8 @@
#define MXC_JPEG_W_ALIGN 3
#define MXC_JPEG_MAX_SIZEIMAGE 0xFFFFFC00
#define MXC_JPEG_MAX_PLANES 2
+#define MXC_JPEG_PATTERN_WIDTH 128
+#define MXC_JPEG_PATTERN_HEIGHT 64
enum mxc_jpeg_enc_state {
MXC_JPEG_ENCODING = 0, /* jpeg encode phase */
@@ -117,6 +119,9 @@ struct mxc_jpeg_slot_data {
dma_addr_t desc_handle;
dma_addr_t cfg_desc_handle; // configuration descriptor dma address
dma_addr_t cfg_stream_handle; // configuration bitstream dma address
+ dma_addr_t cfg_dec_size;
+ void *cfg_dec_vaddr;
+ dma_addr_t cfg_dec_daddr;
};
struct mxc_jpeg_dev {
--
2.43.0-rc1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 4/4] media: imx-jpeg: Check decoding is ongoing for motion-jpeg
2025-04-11 7:43 [PATCH v4 0/4] media: imx-jpeg: Fix some motion-jpeg decoding ming.qian
` (2 preceding siblings ...)
2025-04-11 7:43 ` [PATCH v4 3/4] media: imx-jpeg: Change the pattern size to 128x64 ming.qian
@ 2025-04-11 7:43 ` ming.qian
2025-04-11 14:38 ` Frank Li
3 siblings, 1 reply; 8+ messages in thread
From: ming.qian @ 2025-04-11 7:43 UTC (permalink / raw)
To: mchehab, hverkuil-cisco, mirela.rabulea
Cc: shawnguo, s.hauer, kernel, festevam, xiahong.bao, eagle.zhou,
linux-imx, imx, linux-media, linux-kernel, linux-arm-kernel
From: Ming Qian <ming.qian@oss.nxp.com>
As the first frame in "repeat-mode" is the pattern, the pattern done
interrupt is ignored by the driver. With small resolution bitstreams,
the interrupts might fire too quickly and hardware combine two irqs to
once because irq handle have latency. Thus the driver might miss the
frame decode done interrupt from the first actual frame.
In order to avoid the driver wait for the frame done interrupt that has
been combined to the pattern done interrupt and been ignored, driver
will check the curr_desc and slot_status registers to figure out if the
decoding of actual frame is finished or not.
Firstly we check the curr_desc register,
- if it is still pointing to the pattern descriptor, the second actual
frame is not started, we can wait for its frame-done interrupt.
- if the curr_desc has pointed to the frame descriptor, then we check the
ongoing bit of slot_status register.
- if the ongoing bit is set to 1, the decoding of the actual frame is not
finished, we can wait for its frame-done interrupt.
- if the ongoing bit is set to 0, the decoding of the actual frame is
finished, we can't wait for the second interrupt, but mark it as done.
But there is still a small problem, that the curr_desc and slot_status
registers are not synchronous. curr_desc is updated when the
next_descpt_ptr is loaded, but the ongoing bit of slot_status is set
after the 32 bytes descriptor is loaded, there will be a short time
interval in between, which may cause fake false. Consider read register
is quite slow compared with IP read 32byte from memory, read twice
slot_status can avoid this situation.
Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
---
.../media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h | 1 +
.../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 31 ++++++++++++++++++-
2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
index d579c804b047..adb93e977be9 100644
--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
+++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
@@ -89,6 +89,7 @@
/* SLOT_STATUS fields for slots 0..3 */
#define SLOT_STATUS_FRMDONE (0x1 << 3)
#define SLOT_STATUS_ENC_CONFIG_ERR (0x1 << 8)
+#define SLOT_STATUS_ONGOING (0x1 << 31)
/* SLOT_IRQ_EN fields TBD */
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
index 45705c606769..4346dcdc9697 100644
--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
@@ -910,6 +910,34 @@ static u32 mxc_jpeg_get_plane_size(struct mxc_jpeg_q_data *q_data, u32 plane_no)
return size;
}
+static bool mxc_dec_is_ongoing(struct mxc_jpeg_ctx *ctx)
+{
+ struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
+ u32 curr_desc;
+ u32 slot_status;
+
+ curr_desc = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_CUR_DESCPT_PTR));
+ if (curr_desc == jpeg->slot_data.cfg_desc_handle)
+ return true;
+
+ slot_status = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_STATUS));
+ if (slot_status & SLOT_STATUS_ONGOING)
+ return true;
+
+ /*
+ * The curr_desc register is updated when next_descpt_ptr is loaded,
+ * the ongoing bit of slot_status is set when the 32 bytes descriptor is loaded.
+ * So there will be a short time interval in between, which may cause fake false.
+ * Consider read register is quite slow compared with IP read 32byte from memory,
+ * read twice slot_status can avoid this situation.
+ */
+ slot_status = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_STATUS));
+ if (slot_status & SLOT_STATUS_ONGOING)
+ return true;
+
+ return false;
+}
+
static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
{
struct mxc_jpeg_dev *jpeg = priv;
@@ -979,7 +1007,8 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
mxc_jpeg_enc_mode_go(dev, reg, mxc_jpeg_is_extended_sequential(q_data->fmt));
goto job_unlock;
}
- if (jpeg->mode == MXC_JPEG_DECODE && jpeg_src_buf->dht_needed) {
+ if (jpeg->mode == MXC_JPEG_DECODE && jpeg_src_buf->dht_needed &&
+ mxc_dec_is_ongoing(ctx)) {
jpeg_src_buf->dht_needed = false;
dev_dbg(dev, "Decoder DHT cfg finished. Start decoding...\n");
goto job_unlock;
--
2.43.0-rc1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v4 1/4] media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead
2025-04-11 7:43 ` [PATCH v4 1/4] media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead ming.qian
@ 2025-04-11 14:36 ` Frank Li
2025-04-11 18:47 ` Nicolas Dufresne
0 siblings, 1 reply; 8+ messages in thread
From: Frank Li @ 2025-04-11 14:36 UTC (permalink / raw)
To: ming.qian
Cc: mchehab, hverkuil-cisco, mirela.rabulea, shawnguo, s.hauer,
kernel, festevam, xiahong.bao, eagle.zhou, linux-imx, imx,
linux-media, linux-kernel, linux-arm-kernel
On Fri, Apr 11, 2025 at 03:43:40PM +0800, ming.qian@oss.nxp.com wrote:
> From: Ming Qian <ming.qian@oss.nxp.com>
>
> Move function mxc_jpeg_free_slot_data() above mxc_jpeg_alloc_slot_data()
> allowing to call that function during allocation failures.
> No functional changes are made.
>
> Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> ---
> .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 46 +++++++++++--------
> 1 file changed, 26 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
> index 0e6ee997284b..b2f7e9ad1885 100644
> --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
> +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
> @@ -752,6 +752,32 @@ static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data)
> return -1;
> }
>
> +static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
> +{
> + /* free descriptor for decoding/encoding phase */
> + dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
> + jpeg->slot_data.desc,
> + jpeg->slot_data.desc_handle);
> + jpeg->slot_data.desc = NULL;
> + jpeg->slot_data.desc_handle = 0;
You add above two lines, it is not simple move function. Move above two
line change to next patch.
Frank
> +
> + /* free descriptor for encoder configuration phase / decoder DHT */
> + dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
> + jpeg->slot_data.cfg_desc,
> + jpeg->slot_data.cfg_desc_handle);
> + jpeg->slot_data.cfg_desc_handle = 0;
> + jpeg->slot_data.cfg_desc = NULL;
The same here.
> +
> + /* free configuration stream */
> + dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
> + jpeg->slot_data.cfg_stream_vaddr,
> + jpeg->slot_data.cfg_stream_handle);
> + jpeg->slot_data.cfg_stream_vaddr = NULL;
> + jpeg->slot_data.cfg_stream_handle = 0;
The same here.
> +
> + jpeg->slot_data.used = false;
> +}
> +
> static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
> {
> struct mxc_jpeg_desc *desc;
> @@ -798,26 +824,6 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
> return false;
> }
>
> -static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
> -{
> - /* free descriptor for decoding/encoding phase */
> - dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
> - jpeg->slot_data.desc,
> - jpeg->slot_data.desc_handle);
> -
> - /* free descriptor for encoder configuration phase / decoder DHT */
> - dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
> - jpeg->slot_data.cfg_desc,
> - jpeg->slot_data.cfg_desc_handle);
> -
> - /* free configuration stream */
> - dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
> - jpeg->slot_data.cfg_stream_vaddr,
> - jpeg->slot_data.cfg_stream_handle);
> -
> - jpeg->slot_data.used = false;
> -}
> -
> static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx,
> struct vb2_v4l2_buffer *src_buf,
> struct vb2_v4l2_buffer *dst_buf)
> --
> 2.43.0-rc1
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 4/4] media: imx-jpeg: Check decoding is ongoing for motion-jpeg
2025-04-11 7:43 ` [PATCH v4 4/4] media: imx-jpeg: Check decoding is ongoing for motion-jpeg ming.qian
@ 2025-04-11 14:38 ` Frank Li
0 siblings, 0 replies; 8+ messages in thread
From: Frank Li @ 2025-04-11 14:38 UTC (permalink / raw)
To: ming.qian
Cc: mchehab, hverkuil-cisco, mirela.rabulea, shawnguo, s.hauer,
kernel, festevam, xiahong.bao, eagle.zhou, linux-imx, imx,
linux-media, linux-kernel, linux-arm-kernel
On Fri, Apr 11, 2025 at 03:43:43PM +0800, ming.qian@oss.nxp.com wrote:
> From: Ming Qian <ming.qian@oss.nxp.com>
>
> As the first frame in "repeat-mode" is the pattern, the pattern done
> interrupt is ignored by the driver. With small resolution bitstreams,
> the interrupts might fire too quickly and hardware combine two irqs to
> once because irq handle have latency. Thus the driver might miss the
> frame decode done interrupt from the first actual frame.
>
> In order to avoid the driver wait for the frame done interrupt that has
> been combined to the pattern done interrupt and been ignored, driver
> will check the curr_desc and slot_status registers to figure out if the
> decoding of actual frame is finished or not.
>
> Firstly we check the curr_desc register,
> - if it is still pointing to the pattern descriptor, the second actual
> frame is not started, we can wait for its frame-done interrupt.
> - if the curr_desc has pointed to the frame descriptor, then we check the
> ongoing bit of slot_status register.
> - if the ongoing bit is set to 1, the decoding of the actual frame is not
> finished, we can wait for its frame-done interrupt.
> - if the ongoing bit is set to 0, the decoding of the actual frame is
> finished, we can't wait for the second interrupt, but mark it as done.
>
> But there is still a small problem, that the curr_desc and slot_status
> registers are not synchronous. curr_desc is updated when the
> next_descpt_ptr is loaded, but the ongoing bit of slot_status is set
> after the 32 bytes descriptor is loaded, there will be a short time
> interval in between, which may cause fake false. Consider read register
> is quite slow compared with IP read 32byte from memory, read twice
> slot_status can avoid this situation.
>
> Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> ---
> .../media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h | 1 +
> .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 31 ++++++++++++++++++-
> 2 files changed, 31 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
> index d579c804b047..adb93e977be9 100644
> --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
> +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
> @@ -89,6 +89,7 @@
> /* SLOT_STATUS fields for slots 0..3 */
> #define SLOT_STATUS_FRMDONE (0x1 << 3)
> #define SLOT_STATUS_ENC_CONFIG_ERR (0x1 << 8)
> +#define SLOT_STATUS_ONGOING (0x1 << 31)
>
> /* SLOT_IRQ_EN fields TBD */
>
> diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
> index 45705c606769..4346dcdc9697 100644
> --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
> +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
> @@ -910,6 +910,34 @@ static u32 mxc_jpeg_get_plane_size(struct mxc_jpeg_q_data *q_data, u32 plane_no)
> return size;
> }
>
> +static bool mxc_dec_is_ongoing(struct mxc_jpeg_ctx *ctx)
> +{
> + struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
> + u32 curr_desc;
> + u32 slot_status;
> +
> + curr_desc = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_CUR_DESCPT_PTR));
> + if (curr_desc == jpeg->slot_data.cfg_desc_handle)
> + return true;
> +
> + slot_status = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_STATUS));
> + if (slot_status & SLOT_STATUS_ONGOING)
> + return true;
> +
> + /*
> + * The curr_desc register is updated when next_descpt_ptr is loaded,
> + * the ongoing bit of slot_status is set when the 32 bytes descriptor is loaded.
> + * So there will be a short time interval in between, which may cause fake false.
> + * Consider read register is quite slow compared with IP read 32byte from memory,
> + * read twice slot_status can avoid this situation.
> + */
> + slot_status = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_STATUS));
> + if (slot_status & SLOT_STATUS_ONGOING)
> + return true;
> +
> + return false;
> +}
> +
> static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
> {
> struct mxc_jpeg_dev *jpeg = priv;
> @@ -979,7 +1007,8 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
> mxc_jpeg_enc_mode_go(dev, reg, mxc_jpeg_is_extended_sequential(q_data->fmt));
> goto job_unlock;
> }
> - if (jpeg->mode == MXC_JPEG_DECODE && jpeg_src_buf->dht_needed) {
> + if (jpeg->mode == MXC_JPEG_DECODE && jpeg_src_buf->dht_needed &&
> + mxc_dec_is_ongoing(ctx)) {
> jpeg_src_buf->dht_needed = false;
> dev_dbg(dev, "Decoder DHT cfg finished. Start decoding...\n");
> goto job_unlock;
> --
> 2.43.0-rc1
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 1/4] media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead
2025-04-11 14:36 ` Frank Li
@ 2025-04-11 18:47 ` Nicolas Dufresne
0 siblings, 0 replies; 8+ messages in thread
From: Nicolas Dufresne @ 2025-04-11 18:47 UTC (permalink / raw)
To: Frank Li, ming.qian
Cc: mchehab, hverkuil-cisco, mirela.rabulea, shawnguo, s.hauer,
kernel, festevam, xiahong.bao, eagle.zhou, linux-imx, imx,
linux-media, linux-kernel, linux-arm-kernel
Le vendredi 11 avril 2025 à 10:36 -0400, Frank Li a écrit :
> On Fri, Apr 11, 2025 at 03:43:40PM +0800, ming.qian@oss.nxp.com wrote:
> > From: Ming Qian <ming.qian@oss.nxp.com>
> >
> > Move function mxc_jpeg_free_slot_data() above mxc_jpeg_alloc_slot_data()
> > allowing to call that function during allocation failures.
> > No functional changes are made.
> >
> > Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
> > Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> > ---
> > .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 46 +++++++++++--------
> > 1 file changed, 26 insertions(+), 20 deletions(-)
> >
> > diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
> > index 0e6ee997284b..b2f7e9ad1885 100644
> > --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
> > +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
> > @@ -752,6 +752,32 @@ static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data)
> > return -1;
> > }
> >
> > +static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
> > +{
> > + /* free descriptor for decoding/encoding phase */
> > + dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
> > + jpeg->slot_data.desc,
> > + jpeg->slot_data.desc_handle);
> > + jpeg->slot_data.desc = NULL;
> > + jpeg->slot_data.desc_handle = 0;
>
> You add above two lines, it is not simple move function. Move above two
> line change to next patch.
What about just making this its own commit, give you the chance to
write down that your making that function safe to be called multiple
times ?
Nicolas
>
> Frank
>
> > +
> > + /* free descriptor for encoder configuration phase / decoder DHT */
> > + dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
> > + jpeg->slot_data.cfg_desc,
> > + jpeg->slot_data.cfg_desc_handle);
> > + jpeg->slot_data.cfg_desc_handle = 0;
> > + jpeg->slot_data.cfg_desc = NULL;
>
> The same here.
>
> > +
> > + /* free configuration stream */
> > + dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
> > + jpeg->slot_data.cfg_stream_vaddr,
> > + jpeg->slot_data.cfg_stream_handle);
> > + jpeg->slot_data.cfg_stream_vaddr = NULL;
> > + jpeg->slot_data.cfg_stream_handle = 0;
>
> The same here.
>
> > +
> > + jpeg->slot_data.used = false;
> > +}
> > +
> > static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
> > {
> > struct mxc_jpeg_desc *desc;
> > @@ -798,26 +824,6 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
> > return false;
> > }
> >
> > -static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
> > -{
> > - /* free descriptor for decoding/encoding phase */
> > - dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
> > - jpeg->slot_data.desc,
> > - jpeg->slot_data.desc_handle);
> > -
> > - /* free descriptor for encoder configuration phase / decoder DHT */
> > - dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
> > - jpeg->slot_data.cfg_desc,
> > - jpeg->slot_data.cfg_desc_handle);
> > -
> > - /* free configuration stream */
> > - dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
> > - jpeg->slot_data.cfg_stream_vaddr,
> > - jpeg->slot_data.cfg_stream_handle);
> > -
> > - jpeg->slot_data.used = false;
> > -}
> > -
> > static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx,
> > struct vb2_v4l2_buffer *src_buf,
> > struct vb2_v4l2_buffer *dst_buf)
> > --
> > 2.43.0-rc1
> >
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-04-11 18:50 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-11 7:43 [PATCH v4 0/4] media: imx-jpeg: Fix some motion-jpeg decoding ming.qian
2025-04-11 7:43 ` [PATCH v4 1/4] media: imx-jpeg: Move mxc_jpeg_free_slot_data() ahead ming.qian
2025-04-11 14:36 ` Frank Li
2025-04-11 18:47 ` Nicolas Dufresne
2025-04-11 7:43 ` [PATCH v4 2/4] media: imx-jpeg: Cleanup after an allocation error ming.qian
2025-04-11 7:43 ` [PATCH v4 3/4] media: imx-jpeg: Change the pattern size to 128x64 ming.qian
2025-04-11 7:43 ` [PATCH v4 4/4] media: imx-jpeg: Check decoding is ongoing for motion-jpeg ming.qian
2025-04-11 14:38 ` Frank Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).