[PATCH linux-next/master 1/1] media: staging/imx7: Add handler the abnormal interrupt BIT_STATFF_INT

Alice Yuan alice.yuan at nxp.com
Thu Dec 7 18:19:40 PST 2023


From: "alice.yuan" <alice.yuan at nxp.com>

When do 2592x1944 resolution capture, we found some times the
"BIT_STATFF_INT" is abnormal, the stat fifo is not full, but
still the DMA transfer done interrupts generate, at this time
we will get broken frames.

>From the reference manual of imx8mm, we know the STATFIFO full
interrupt status, that indicates the number of data in the
STATFIFO reaches the trigger level. It defined clearly about
BIT_STATFF_INT, 0: STATFIFO is not full, 1: STATFIFO is full.

So we should handler the abnormal interrupts when BIT_STATFF_INT
is 0, the stat fifo is not full, we need to drop the broken
frames, and recovery from the abnormal status.

Signed-off-by: alice.yuan <alice.yuan at nxp.com>
---
 drivers/media/platform/nxp/imx7-media-csi.c | 25 ++++++++++++++++-----
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/nxp/imx7-media-csi.c b/drivers/media/platform/nxp/imx7-media-csi.c
index 15049c6aab37..9012b155c2d7 100644
--- a/drivers/media/platform/nxp/imx7-media-csi.c
+++ b/drivers/media/platform/nxp/imx7-media-csi.c
@@ -249,6 +249,7 @@ struct imx7_csi {
 	bool is_streaming;
 	int buf_num;
 	u32 frame_sequence;
+	int frame_skip;
 
 	bool last_eof;
 	struct completion last_eof_completion;
@@ -686,6 +687,7 @@ static void imx7_csi_enable(struct imx7_csi *csi)
 	imx7_csi_dmareq_rff_enable(csi);
 	imx7_csi_hw_enable(csi);
 
+	csi->frame_skip = 0;
 	if (csi->model == IMX7_CSI_IMX8MQ)
 		imx7_csi_baseaddr_switch_on_second_frame(csi);
 }
@@ -764,6 +766,12 @@ static irqreturn_t imx7_csi_irq_handler(int irq, void *data)
 		imx7_csi_error_recovery(csi);
 	}
 
+	if (!(status & BIT_STATFF_INT)) {
+		dev_warn(csi->dev, "Stat fifo is not full\n");
+		imx7_csi_error_recovery(csi);
+		csi->frame_skip++;
+	}
+
 	if (status & BIT_ADDR_CH_ERR_INT) {
 		imx7_csi_hw_disable(csi);
 
@@ -790,14 +798,19 @@ static irqreturn_t imx7_csi_irq_handler(int irq, void *data)
 
 	if ((status & BIT_DMA_TSF_DONE_FB1) ||
 	    (status & BIT_DMA_TSF_DONE_FB2)) {
-		imx7_csi_vb2_buf_done(csi);
-
-		if (csi->last_eof) {
-			complete(&csi->last_eof_completion);
-			csi->last_eof = false;
+		if (csi->frame_skip) {
+			dev_warn(csi->dev, "skip frame: %d\n", csi->frame_skip);
+			csi->frame_skip--;
+			goto out;
+		} else {
+			imx7_csi_vb2_buf_done(csi);
+			if (csi->last_eof) {
+				complete(&csi->last_eof_completion);
+				csi->last_eof = false;
+			}
 		}
 	}
-
+out:
 	spin_unlock(&csi->irqlock);
 
 	return IRQ_HANDLED;
-- 
2.37.1




More information about the linux-arm-kernel mailing list