Re: [PATCH] media: synopsys: hdmirx: report DMA error interrupts
From: Dmitry Osipenko
Date: Mon Sep 28 2026 - 10:29:30 EST
23.09.2026 05:38, Thomas Weustenfeld пишет:
> hdmirx_start_streaming() enables FIFO_OVERFLOW_INT_EN,
> FIFO_UNDERFLOW_INT_EN, HDMIRX_AXI_ERROR_INT_EN and
> LAST_FRAME_AXI_UNFINISH_INT_EN in DMA_CONFIG4, but
> hdmirx_dma_irq_handler() only decodes HDMIRX_DMA_IDLE_INT and
> LINE_FLAG_INT_EN. Any of the four error interrupts therefore falls
> through the handler with handled still false and is discarded: no
> counter, no message at default verbosity, and nothing reported to
> userspace. The only trace is a v4l2_dbg level 3 line saying the irq was
> not handled, printing the raw status word.
>
> The practical effect is that a capture FIFO overflow -- the DMA failing
> to drain incoming pixels to memory, which loses whole runs of lines from
> the frame -- is completely silent. Frame cadence, DMA idle interrupts and
> buffer delivery all continue to look healthy while the delivered buffers
> contain unwritten lines. On affected boards this reads as unexplained
> video corruption with every normal indicator nominal.
>
> Measured on RK3588 with a 900 frame capture: a board writing a
> semi-planar format reported 907 DMA idle and 907 line flag interrupts as
> expected, plus 702 FIFO overflow interrupts, all of them dropped. An
> otherwise identical capture on a board writing a packed format at the
> same data rate reported none.
>
> Decode the four error bits, count them per stream, warn once per stream
> on the first occurrence of each, and log the totals when streaming stops.
> No functional change to the capture path.
>
> Signed-off-by: Thomas Weustenfeld <tw@xxxxxxxxx>
> ---
> .../platform/synopsys/hdmirx/snps_hdmirx.c | 47 +++++++++++++++++++
> 1 file changed, 47 insertions(+)
>
> diff --git a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
> index 25f8ca0d6d94..d7ff7aa4ebde 100644
> --- a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
> +++ b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
> @@ -117,6 +117,10 @@ struct hdmirx_stream {
> u32 sequence;
> u32 line_flag_int_cnt;
> u32 irq_stat;
> + u32 fifo_overflow_cnt;
> + u32 fifo_underflow_cnt;
> + u32 axi_error_cnt;
> + u32 last_frame_unfinish_cnt;
> };
>
> struct snps_hdmirx_dev {
> @@ -1567,6 +1571,15 @@ static void hdmirx_stop_streaming(struct vb2_queue *queue)
> hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, HDMIRX_DMA_EN, 0);
> return_all_buffers(stream, VB2_BUF_STATE_ERROR);
> mutex_unlock(&hdmirx_dev->stream_lock);
> +
> + if (stream->fifo_overflow_cnt || stream->fifo_underflow_cnt ||
> + stream->axi_error_cnt || stream->last_frame_unfinish_cnt)
> + v4l2_warn(v4l2_dev,
> + "dma errors over %u frames: fifo_overflow:%u fifo_underflow:%u axi_error:%u last_frame_unfinish:%u\n",
> + stream->sequence, stream->fifo_overflow_cnt,
> + stream->fifo_underflow_cnt, stream->axi_error_cnt,
> + stream->last_frame_unfinish_cnt);
> +
> v4l2_dbg(1, debug, v4l2_dev, "stream stopping finished\n");
> }
>
> @@ -1583,6 +1596,10 @@ static int hdmirx_start_streaming(struct vb2_queue *queue, unsigned int count)
> mutex_lock(&hdmirx_dev->stream_lock);
> stream->sequence = 0;
> stream->line_flag_int_cnt = 0;
> + stream->fifo_overflow_cnt = 0;
> + stream->fifo_underflow_cnt = 0;
> + stream->axi_error_cnt = 0;
> + stream->last_frame_unfinish_cnt = 0;
> stream->curr_buf = NULL;
> stream->next_buf = NULL;
> stream->irq_stat = 0;
> @@ -2080,6 +2097,31 @@ static void line_flag_int_handler(struct snps_hdmirx_dev *hdmirx_dev,
> *handled = true;
> }
>
> +static void dma_error_int_handler(struct snps_hdmirx_dev *hdmirx_dev,
> + u32 dma_stat1, bool *handled)
> +{
> + struct hdmirx_stream *stream = &hdmirx_dev->stream;
> + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
> +
> + if ((dma_stat1 & FIFO_OVERFLOW_INT_EN) && !stream->fifo_overflow_cnt++)
> + v4l2_warn(v4l2_dev,
> + "dma fifo overflow, captured lines are being dropped\n");
> +
> + if ((dma_stat1 & FIFO_UNDERFLOW_INT_EN) &&
> + !stream->fifo_underflow_cnt++)
> + v4l2_warn(v4l2_dev, "dma fifo underflow\n");
> +
> + if ((dma_stat1 & HDMIRX_AXI_ERROR_INT_EN) && !stream->axi_error_cnt++)
> + v4l2_err(v4l2_dev, "dma axi error\n");
> +
> + if ((dma_stat1 & LAST_FRAME_AXI_UNFINISH_INT_EN) &&
> + !stream->last_frame_unfinish_cnt++)
> + v4l2_warn(v4l2_dev,
> + "dma did not finish writing the last frame\n");
Can this result in a message storm? If yes, a generic rate-limited dev
print variants will be more preferable.
--
Best regards,
Dmitry