diff mbox series

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

Message ID 20231208021940.883259-1-alice.yuan@nxp.com (mailing list archive)
State New
Headers show
Series [linux-next/master,1/1] media: staging/imx7: Add handler the abnormal interrupt BIT_STATFF_INT | expand

Commit Message

Alice Yuan Dec. 8, 2023, 2:19 a.m. UTC
From: "alice.yuan" <alice.yuan@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@nxp.com>
---
 drivers/media/platform/nxp/imx7-media-csi.c | 25 ++++++++++++++++-----
 1 file changed, 19 insertions(+), 6 deletions(-)

Comments

Alice Yuan Jan. 29, 2024, 5:59 a.m. UTC | #1
@rmfrfs@gmail.com@Laurent Pinchart@martin.kepplinger@puri.sm@kernel@puri.sm@linux-media@vger.kernel.org

Any feedback?

Thanks
------------
B&R.
Name: Alice Yuan
Address: No.192, Zhangjiang Liangjing Road, Pudong New Area, Shanghai

> -----Original Message-----
> From: Alice Yuan
> Sent: 2023年12月8日 10:15
> To: rmfrfs@gmail.com; Laurent Pinchart
> <laurent.pinchart@ideasonboard.com>; martin.kepplinger@puri.sm;
> kernel@puri.sm; linux-media@vger.kernel.org
> Cc: LnxRevLi <LnxRevLi@nxp.com>; linux-devel@linux.nxdi.nxp.com;
> kernel@pengutronix.de; dl-linux-imx <linux-imx@nxp.com>;
> dri-devel@lists.freedesktop.org; linux-arm-kernel@lists.infradead.org;
> patchwork-lst@pengutronix.de
> Subject: [PATCH linux-next/master 1/1] media: staging/imx7: Add handler the
> abnormal interrupt BIT_STATFF_INT
> 
> From: "alice.yuan" <alice.yuan@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@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
diff mbox series

Patch

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;