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