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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "alice.yuan" <alice.yuan@xxxxxxx>

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@xxxxxxx>
---
 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





[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux