* [PATCH 0/2] Fix issues with frame reception from CSI on i.MX31 @ 2011-01-26 8:49 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-26 8:49 UTC (permalink / raw) To: linux-media Cc: Guennadi Liakhovetski, Dan Williams, linux-arm-kernel, Detlev Zundel, Markus Niebel, Anatolij Gustschin On some camera systems we do not tolerate the losing of captured frames. We observed losing of the first frame from CSI when double buffering is used (multiple buffers queued by the mx3-camera driver). The patches provide fixes for the observed problem. Anatolij Gustschin (2): v4l: soc-camera: start stream after queueing the buffers dma: ipu_idmac: do not lose valid received data in the irq handler drivers/dma/ipu/ipu_idmac.c | 50 -------------------------------------- drivers/media/video/soc_camera.c | 4 +- 2 files changed, 2 insertions(+), 52 deletions(-) ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 0/2] Fix issues with frame reception from CSI on i.MX31 @ 2011-01-26 8:49 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-26 8:49 UTC (permalink / raw) To: linux-arm-kernel On some camera systems we do not tolerate the losing of captured frames. We observed losing of the first frame from CSI when double buffering is used (multiple buffers queued by the mx3-camera driver). The patches provide fixes for the observed problem. Anatolij Gustschin (2): v4l: soc-camera: start stream after queueing the buffers dma: ipu_idmac: do not lose valid received data in the irq handler drivers/dma/ipu/ipu_idmac.c | 50 -------------------------------------- drivers/media/video/soc_camera.c | 4 +- 2 files changed, 2 insertions(+), 52 deletions(-) ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/2] v4l: soc-camera: start stream after queueing the buffers 2011-01-26 8:49 ` Anatolij Gustschin @ 2011-01-26 8:49 ` Anatolij Gustschin -1 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-26 8:49 UTC (permalink / raw) To: linux-media Cc: Guennadi Liakhovetski, Dan Williams, linux-arm-kernel, Detlev Zundel, Markus Niebel, Anatolij Gustschin Some camera systems have strong requirement for capturing an exact number of frames after starting the stream and do not tolerate losing captured frames. By starting the stream after the videobuf has queued the buffers, we ensure that no frame will be lost. Signed-off-by: Anatolij Gustschin <agust@denx.de> --- drivers/media/video/soc_camera.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index a66811b..7299de0 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -646,11 +646,11 @@ static int soc_camera_streamon(struct file *file, void *priv, if (icd->streamer != file) return -EBUSY; - v4l2_subdev_call(sd, video, s_stream, 1); - /* This calls buf_queue from host driver's videobuf_queue_ops */ ret = videobuf_streamon(&icd->vb_vidq); + v4l2_subdev_call(sd, video, s_stream, 1); + return ret; } -- 1.7.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 1/2] v4l: soc-camera: start stream after queueing the buffers @ 2011-01-26 8:49 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-26 8:49 UTC (permalink / raw) To: linux-arm-kernel Some camera systems have strong requirement for capturing an exact number of frames after starting the stream and do not tolerate losing captured frames. By starting the stream after the videobuf has queued the buffers, we ensure that no frame will be lost. Signed-off-by: Anatolij Gustschin <agust@denx.de> --- drivers/media/video/soc_camera.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index a66811b..7299de0 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -646,11 +646,11 @@ static int soc_camera_streamon(struct file *file, void *priv, if (icd->streamer != file) return -EBUSY; - v4l2_subdev_call(sd, video, s_stream, 1); - /* This calls buf_queue from host driver's videobuf_queue_ops */ ret = videobuf_streamon(&icd->vb_vidq); + v4l2_subdev_call(sd, video, s_stream, 1); + return ret; } -- 1.7.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* Re: [PATCH 1/2] v4l: soc-camera: start stream after queueing the buffers 2011-01-26 8:49 ` Anatolij Gustschin @ 2011-01-29 19:16 ` Guennadi Liakhovetski -1 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-01-29 19:16 UTC (permalink / raw) To: Anatolij Gustschin Cc: linux-media, Dan Williams, linux-arm-kernel, Detlev Zundel, Markus Niebel On Wed, 26 Jan 2011, Anatolij Gustschin wrote: > Some camera systems have strong requirement for capturing > an exact number of frames after starting the stream and do > not tolerate losing captured frames. By starting the stream > after the videobuf has queued the buffers, we ensure that > no frame will be lost. > > Signed-off-by: Anatolij Gustschin <agust@denx.de> > --- > drivers/media/video/soc_camera.c | 4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c > index a66811b..7299de0 100644 > --- a/drivers/media/video/soc_camera.c > +++ b/drivers/media/video/soc_camera.c > @@ -646,11 +646,11 @@ static int soc_camera_streamon(struct file *file, void *priv, > if (icd->streamer != file) > return -EBUSY; > > - v4l2_subdev_call(sd, video, s_stream, 1); > - > /* This calls buf_queue from host driver's videobuf_queue_ops */ > ret = videobuf_streamon(&icd->vb_vidq); > > + v4l2_subdev_call(sd, video, s_stream, 1); > + After a bit more testing I'll make this to + if (!ret) + v4l2_subdev_call(sd, video, s_stream, 1); + Ok? Or you can submit a v2 yourself, if you like - when you fix the comment in the other patch from this series. > return ret; > } > > -- > 1.7.1 Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/2] v4l: soc-camera: start stream after queueing the buffers @ 2011-01-29 19:16 ` Guennadi Liakhovetski 0 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-01-29 19:16 UTC (permalink / raw) To: linux-arm-kernel On Wed, 26 Jan 2011, Anatolij Gustschin wrote: > Some camera systems have strong requirement for capturing > an exact number of frames after starting the stream and do > not tolerate losing captured frames. By starting the stream > after the videobuf has queued the buffers, we ensure that > no frame will be lost. > > Signed-off-by: Anatolij Gustschin <agust@denx.de> > --- > drivers/media/video/soc_camera.c | 4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c > index a66811b..7299de0 100644 > --- a/drivers/media/video/soc_camera.c > +++ b/drivers/media/video/soc_camera.c > @@ -646,11 +646,11 @@ static int soc_camera_streamon(struct file *file, void *priv, > if (icd->streamer != file) > return -EBUSY; > > - v4l2_subdev_call(sd, video, s_stream, 1); > - > /* This calls buf_queue from host driver's videobuf_queue_ops */ > ret = videobuf_streamon(&icd->vb_vidq); > > + v4l2_subdev_call(sd, video, s_stream, 1); > + After a bit more testing I'll make this to + if (!ret) + v4l2_subdev_call(sd, video, s_stream, 1); + Ok? Or you can submit a v2 yourself, if you like - when you fix the comment in the other patch from this series. > return ret; > } > > -- > 1.7.1 Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 1/2] v4l: soc-camera: start stream after queueing the buffers 2011-01-29 19:16 ` Guennadi Liakhovetski @ 2011-01-29 19:24 ` Anatolij Gustschin -1 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-29 19:24 UTC (permalink / raw) To: Guennadi Liakhovetski Cc: linux-media, Dan Williams, linux-arm-kernel, Detlev Zundel, Markus Niebel On Sat, 29 Jan 2011 20:16:42 +0100 (CET) Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: ... > > --- a/drivers/media/video/soc_camera.c > > +++ b/drivers/media/video/soc_camera.c > > @@ -646,11 +646,11 @@ static int soc_camera_streamon(struct file *file, void *priv, > > if (icd->streamer != file) > > return -EBUSY; > > > > - v4l2_subdev_call(sd, video, s_stream, 1); > > - > > /* This calls buf_queue from host driver's videobuf_queue_ops */ > > ret = videobuf_streamon(&icd->vb_vidq); > > > > + v4l2_subdev_call(sd, video, s_stream, 1); > > + > > After a bit more testing I'll make this to > > + if (!ret) > + v4l2_subdev_call(sd, video, s_stream, 1); > + > > Ok? Or you can submit a v2 yourself, if you like - when you fix the > comment in the other patch from this series. I'll submit a v2 patch since I have to resubmit the other patch, too. Thanks, Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/2] v4l: soc-camera: start stream after queueing the buffers @ 2011-01-29 19:24 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-29 19:24 UTC (permalink / raw) To: linux-arm-kernel On Sat, 29 Jan 2011 20:16:42 +0100 (CET) Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: ... > > --- a/drivers/media/video/soc_camera.c > > +++ b/drivers/media/video/soc_camera.c > > @@ -646,11 +646,11 @@ static int soc_camera_streamon(struct file *file, void *priv, > > if (icd->streamer != file) > > return -EBUSY; > > > > - v4l2_subdev_call(sd, video, s_stream, 1); > > - > > /* This calls buf_queue from host driver's videobuf_queue_ops */ > > ret = videobuf_streamon(&icd->vb_vidq); > > > > + v4l2_subdev_call(sd, video, s_stream, 1); > > + > > After a bit more testing I'll make this to > > + if (!ret) > + v4l2_subdev_call(sd, video, s_stream, 1); > + > > Ok? Or you can submit a v2 yourself, if you like - when you fix the > comment in the other patch from this series. I'll submit a v2 patch since I have to resubmit the other patch, too. Thanks, Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/2 v2] v4l: soc-camera: start stream after queueing the buffers 2011-01-26 8:49 ` Anatolij Gustschin @ 2011-01-31 12:19 ` Anatolij Gustschin -1 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-31 12:19 UTC (permalink / raw) To: linux-media Cc: linux-arm-kernel, Guennadi Liakhovetski, Detlev Zundel, Markus Niebel Some camera systems have strong requirement for capturing an exact number of frames after starting the stream and do not tolerate losing captured frames. By starting the stream after the videobuf has queued the buffers, we ensure that no frame will be lost. Signed-off-by: Anatolij Gustschin <agust@denx.de> --- v2: Check for return value of videobuf_streamon() before starting the stream, as suggested by Guennadi. drivers/media/video/soc_camera.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index a66811b..e09bec0 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -646,11 +646,12 @@ static int soc_camera_streamon(struct file *file, void *priv, if (icd->streamer != file) return -EBUSY; - v4l2_subdev_call(sd, video, s_stream, 1); - /* This calls buf_queue from host driver's videobuf_queue_ops */ ret = videobuf_streamon(&icd->vb_vidq); + if (!ret) + v4l2_subdev_call(sd, video, s_stream, 1); + return ret; } -- 1.7.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 1/2 v2] v4l: soc-camera: start stream after queueing the buffers @ 2011-01-31 12:19 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-31 12:19 UTC (permalink / raw) To: linux-arm-kernel Some camera systems have strong requirement for capturing an exact number of frames after starting the stream and do not tolerate losing captured frames. By starting the stream after the videobuf has queued the buffers, we ensure that no frame will be lost. Signed-off-by: Anatolij Gustschin <agust@denx.de> --- v2: Check for return value of videobuf_streamon() before starting the stream, as suggested by Guennadi. drivers/media/video/soc_camera.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index a66811b..e09bec0 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -646,11 +646,12 @@ static int soc_camera_streamon(struct file *file, void *priv, if (icd->streamer != file) return -EBUSY; - v4l2_subdev_call(sd, video, s_stream, 1); - /* This calls buf_queue from host driver's videobuf_queue_ops */ ret = videobuf_streamon(&icd->vb_vidq); + if (!ret) + v4l2_subdev_call(sd, video, s_stream, 1); + return ret; } -- 1.7.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 2/2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-01-26 8:49 ` Anatolij Gustschin @ 2011-01-26 8:49 ` Anatolij Gustschin -1 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-26 8:49 UTC (permalink / raw) To: linux-media Cc: Guennadi Liakhovetski, Dan Williams, linux-arm-kernel, Detlev Zundel, Markus Niebel, Anatolij Gustschin Currently when two or more buffers are queued by the camera driver and so the double buffering is enabled in the idmac, we lose the first frame comming from CSI since it is just dropped by the interrupt handler. The reason for this dropping is that the interrupt handler misleadingly assumes that the cur_buf flag is pointing to the buffer used by the IDMAC. Actually it is not the case since the CUR_BUF flag will be flipped by the FSU when the FSU is sending the <TASK>_NEW_FRM_RDY signal when new frame data is delivered by the CSI. When sending this singal, FSU updates the DMA_CUR_BUF and the DMA_BUFx_RDY flags: the DMA_CUR_BUF is flipped, the DMA_BUFx_RDY is cleared, indicating that the frame data is beeing written by the IDMAC to the pointed buffer. DMA_BUFx_RDY is supposed to be set to the ready state again by the MCU, when it has handled the received data. DMA_BUFx_RDY won't be set by the IPU, so waiting for this event in the interrupt handler is wrong. Actually there is no spurious interrupt as described in the comments, this is the valid DMAIC_7_EOF interrupt indicating reception of the frame from CSI. This has been verified on the hardware which is triggering the image sensor by the programmable state machine, allowing to obtain exact number of frames. On this hardware we do not tolerate losing frames. This patch also removes resetting the DMA_BUFx_RDY flags of all channels in ipu_disable_channel() since transfers on other DMA channels might be triggered by other running tasks and the buffers should always be ready for data sending or reception. Signed-off-by: Anatolij Gustschin <agust@denx.de> --- drivers/dma/ipu/ipu_idmac.c | 50 ------------------------------------------- 1 files changed, 0 insertions(+), 50 deletions(-) diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index cb26ee9..c1a125e 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan, reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN); - /* - * Problem (observed with channel DMAIC_7): after enabling the channel - * and initialising buffers, there comes an interrupt with current still - * pointing at buffer 0, whereas it should use buffer 0 first and only - * generate an interrupt when it is done, then current should already - * point to buffer 1. This spurious interrupt also comes on channel - * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the - * first interrupt, there comes the second with current correctly - * pointing to buffer 1 this time. But sometimes this second interrupt - * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling - * the channel seems to prevent the channel from hanging, but it doesn't - * prevent the spurious interrupt. This might also be unsafe. Think - * about the IDMAC controller trying to switch to a buffer, when we - * clear the ready bit, and re-enable it a moment later. - */ - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY); - - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY); - spin_unlock_irqrestore(&ipu->lock, flags); return 0; @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id) /* Other interrupts do not interfere with this channel */ spin_lock(&ichan->lock); - if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 && - ((curbuf >> chan_id) & 1) == ichan->active_buffer && - !list_is_last(ichan->queue.next, &ichan->queue))) { - int i = 100; - - /* This doesn't help. See comment in ipu_disable_channel() */ - while (--i) { - curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); - if (((curbuf >> chan_id) & 1) != ichan->active_buffer) - break; - cpu_relax(); - } - - if (!i) { - spin_unlock(&ichan->lock); - dev_dbg(dev, - "IRQ on active buffer on channel %x, active " - "%d, ready %x, %x, current %x!\n", chan_id, - ichan->active_buffer, ready0, ready1, curbuf); - return IRQ_NONE; - } else - dev_dbg(dev, - "Buffer deactivated on channel %x, active " - "%d, ready %x, %x, current %x, rest %d!\n", chan_id, - ichan->active_buffer, ready0, ready1, curbuf, i); - } - if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) || (!ichan->active_buffer && (ready0 >> chan_id) & 1) )) { -- 1.7.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 2/2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-01-26 8:49 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-26 8:49 UTC (permalink / raw) To: linux-arm-kernel Currently when two or more buffers are queued by the camera driver and so the double buffering is enabled in the idmac, we lose the first frame comming from CSI since it is just dropped by the interrupt handler. The reason for this dropping is that the interrupt handler misleadingly assumes that the cur_buf flag is pointing to the buffer used by the IDMAC. Actually it is not the case since the CUR_BUF flag will be flipped by the FSU when the FSU is sending the <TASK>_NEW_FRM_RDY signal when new frame data is delivered by the CSI. When sending this singal, FSU updates the DMA_CUR_BUF and the DMA_BUFx_RDY flags: the DMA_CUR_BUF is flipped, the DMA_BUFx_RDY is cleared, indicating that the frame data is beeing written by the IDMAC to the pointed buffer. DMA_BUFx_RDY is supposed to be set to the ready state again by the MCU, when it has handled the received data. DMA_BUFx_RDY won't be set by the IPU, so waiting for this event in the interrupt handler is wrong. Actually there is no spurious interrupt as described in the comments, this is the valid DMAIC_7_EOF interrupt indicating reception of the frame from CSI. This has been verified on the hardware which is triggering the image sensor by the programmable state machine, allowing to obtain exact number of frames. On this hardware we do not tolerate losing frames. This patch also removes resetting the DMA_BUFx_RDY flags of all channels in ipu_disable_channel() since transfers on other DMA channels might be triggered by other running tasks and the buffers should always be ready for data sending or reception. Signed-off-by: Anatolij Gustschin <agust@denx.de> --- drivers/dma/ipu/ipu_idmac.c | 50 ------------------------------------------- 1 files changed, 0 insertions(+), 50 deletions(-) diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index cb26ee9..c1a125e 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan, reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN); - /* - * Problem (observed with channel DMAIC_7): after enabling the channel - * and initialising buffers, there comes an interrupt with current still - * pointing at buffer 0, whereas it should use buffer 0 first and only - * generate an interrupt when it is done, then current should already - * point to buffer 1. This spurious interrupt also comes on channel - * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the - * first interrupt, there comes the second with current correctly - * pointing to buffer 1 this time. But sometimes this second interrupt - * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling - * the channel seems to prevent the channel from hanging, but it doesn't - * prevent the spurious interrupt. This might also be unsafe. Think - * about the IDMAC controller trying to switch to a buffer, when we - * clear the ready bit, and re-enable it a moment later. - */ - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY); - - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY); - spin_unlock_irqrestore(&ipu->lock, flags); return 0; @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id) /* Other interrupts do not interfere with this channel */ spin_lock(&ichan->lock); - if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 && - ((curbuf >> chan_id) & 1) == ichan->active_buffer && - !list_is_last(ichan->queue.next, &ichan->queue))) { - int i = 100; - - /* This doesn't help. See comment in ipu_disable_channel() */ - while (--i) { - curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); - if (((curbuf >> chan_id) & 1) != ichan->active_buffer) - break; - cpu_relax(); - } - - if (!i) { - spin_unlock(&ichan->lock); - dev_dbg(dev, - "IRQ on active buffer on channel %x, active " - "%d, ready %x, %x, current %x!\n", chan_id, - ichan->active_buffer, ready0, ready1, curbuf); - return IRQ_NONE; - } else - dev_dbg(dev, - "Buffer deactivated on channel %x, active " - "%d, ready %x, %x, current %x, rest %d!\n", chan_id, - ichan->active_buffer, ready0, ready1, curbuf, i); - } - if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) || (!ichan->active_buffer && (ready0 >> chan_id) & 1) )) { -- 1.7.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-01-26 8:49 ` Anatolij Gustschin @ 2011-01-27 8:22 ` Anatolij Gustschin -1 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-27 8:22 UTC (permalink / raw) To: Anatolij Gustschin Cc: linux-media, Guennadi Liakhovetski, Dan Williams, linux-arm-kernel, Detlev Zundel, Markus Niebel Reading the commit message again I now realize that there is a mistake. On Wed, 26 Jan 2011 09:49:49 +0100 Anatolij Gustschin <agust@denx.de> wrote: ... > received data. DMA_BUFx_RDY won't be set by the IPU, so waiting > for this event in the interrupt handler is wrong. This should read 'DMAIC_x_CUR_BUF flag won't be flipped here by the IPU, so waiting for this event in the EOF interrupt handler is wrong.' I'll submit another patch fixing the commit message. Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-01-27 8:22 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-27 8:22 UTC (permalink / raw) To: linux-arm-kernel Reading the commit message again I now realize that there is a mistake. On Wed, 26 Jan 2011 09:49:49 +0100 Anatolij Gustschin <agust@denx.de> wrote: ... > received data. DMA_BUFx_RDY won't be set by the IPU, so waiting > for this event in the interrupt handler is wrong. This should read 'DMAIC_x_CUR_BUF flag won't be flipped here by the IPU, so waiting for this event in the EOF interrupt handler is wrong.' I'll submit another patch fixing the commit message. Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-01-27 8:22 ` Anatolij Gustschin @ 2011-01-31 5:56 ` Dan Williams -1 siblings, 0 replies; 56+ messages in thread From: Dan Williams @ 2011-01-31 5:56 UTC (permalink / raw) To: Anatolij Gustschin Cc: Detlev Zundel, Markus Niebel, Guennadi Liakhovetski, linux-arm-kernel, linux-media On Thu, Jan 27, 2011 at 12:22 AM, Anatolij Gustschin <agust@denx.de> wrote: > Reading the commit message again I now realize that there is > a mistake. > > On Wed, 26 Jan 2011 09:49:49 +0100 > Anatolij Gustschin <agust@denx.de> wrote: > ... >> received data. DMA_BUFx_RDY won't be set by the IPU, so waiting >> for this event in the interrupt handler is wrong. > > This should read 'DMAIC_x_CUR_BUF flag won't be flipped here by > the IPU, so waiting for this event in the EOF interrupt handler > is wrong.' > > I'll submit another patch fixing the commit message. > Ok, also looking for a reviewed/acked by Guennadi. -- Dan ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-01-31 5:56 ` Dan Williams 0 siblings, 0 replies; 56+ messages in thread From: Dan Williams @ 2011-01-31 5:56 UTC (permalink / raw) To: linux-arm-kernel On Thu, Jan 27, 2011 at 12:22 AM, Anatolij Gustschin <agust@denx.de> wrote: > Reading the commit message again I now realize that there is > a mistake. > > On Wed, 26 Jan 2011 09:49:49 +0100 > Anatolij Gustschin <agust@denx.de> wrote: > ... >> received data. DMA_BUFx_RDY won't be set by the IPU, so waiting >> for this event in the interrupt handler is wrong. > > This should read 'DMAIC_x_CUR_BUF flag won't be flipped here by > the IPU, so waiting for this event in the EOF interrupt handler > is wrong.' > > I'll submit another patch fixing the commit message. > Ok, also looking for a reviewed/acked by Guennadi. -- Dan ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-01-26 8:49 ` Anatolij Gustschin @ 2011-01-31 12:22 ` Anatolij Gustschin -1 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-31 12:22 UTC (permalink / raw) To: linux-media Cc: linux-arm-kernel, Guennadi Liakhovetski, Dan Williams, Detlev Zundel, Markus Niebel Currently when two or more buffers are queued by the camera driver and so the double buffering is enabled in the idmac, we lose one frame comming from CSI since the reporting of arrival of the first frame is deferred by the DMAIC_7_EOF interrupt handler and reporting of the arrival of the last frame is not done at all. So when requesting N frames from the image sensor we actually receive N - 1 frames in user space. The reason for this behaviour is that the DMAIC_7_EOF interrupt handler misleadingly assumes that the CUR_BUF flag is pointing to the buffer used by the IDMAC. Actually it is not the case since the CUR_BUF flag will be flipped by the FSU when the FSU is sending the <TASK>_NEW_FRM_RDY signal when new frame data is delivered by the CSI. When sending this singal, FSU updates the DMA_CUR_BUF and the DMA_BUFx_RDY flags: the DMA_CUR_BUF is flipped, the DMA_BUFx_RDY is cleared, indicating that the frame data is beeing written by the IDMAC to the pointed buffer. DMA_BUFx_RDY is supposed to be set to the ready state again by the MCU, when it has handled the received data. DMAIC_7_CUR_BUF flag won't be flipped here by the IPU, so waiting for this event in the EOF interrupt handler is wrong. Actually there is no spurious interrupt as described in the comments, this is the valid DMAIC_7_EOF interrupt indicating reception of the frame from CSI. The patch removes code that waits for flipping of the DMAIC_7_CUR_BUF flag in the DMAIC_7_EOF interrupt handler. As the comment in the current code denotes, this waiting doesn't help anyway. As a result of this removal the reporting of the first arrived frame is not deferred to the time of arrival of the next frame and the drivers software flag 'ichan->active_buffer' is in sync with DMAIC_7_CUR_BUF flag, so the reception of all requested frames works. This has been verified on the hardware which is triggering the image sensor by the programmable state machine, allowing to obtain exact number of frames. On this hardware we do not tolerate losing frames. This patch also removes resetting the DMA_BUFx_RDY flags of all channels in ipu_disable_channel() since transfers on other DMA channels might be triggered by other running tasks and the buffers should always be ready for data sending or reception. Signed-off-by: Anatolij Gustschin <agust@denx.de> --- v2: Revise the commit message to provide more and correct information about the observed problem and proposed fix drivers/dma/ipu/ipu_idmac.c | 50 ------------------------------------------- 1 files changed, 0 insertions(+), 50 deletions(-) diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index cb26ee9..c1a125e 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan, reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN); - /* - * Problem (observed with channel DMAIC_7): after enabling the channel - * and initialising buffers, there comes an interrupt with current still - * pointing at buffer 0, whereas it should use buffer 0 first and only - * generate an interrupt when it is done, then current should already - * point to buffer 1. This spurious interrupt also comes on channel - * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the - * first interrupt, there comes the second with current correctly - * pointing to buffer 1 this time. But sometimes this second interrupt - * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling - * the channel seems to prevent the channel from hanging, but it doesn't - * prevent the spurious interrupt. This might also be unsafe. Think - * about the IDMAC controller trying to switch to a buffer, when we - * clear the ready bit, and re-enable it a moment later. - */ - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY); - - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY); - spin_unlock_irqrestore(&ipu->lock, flags); return 0; @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id) /* Other interrupts do not interfere with this channel */ spin_lock(&ichan->lock); - if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 && - ((curbuf >> chan_id) & 1) == ichan->active_buffer && - !list_is_last(ichan->queue.next, &ichan->queue))) { - int i = 100; - - /* This doesn't help. See comment in ipu_disable_channel() */ - while (--i) { - curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); - if (((curbuf >> chan_id) & 1) != ichan->active_buffer) - break; - cpu_relax(); - } - - if (!i) { - spin_unlock(&ichan->lock); - dev_dbg(dev, - "IRQ on active buffer on channel %x, active " - "%d, ready %x, %x, current %x!\n", chan_id, - ichan->active_buffer, ready0, ready1, curbuf); - return IRQ_NONE; - } else - dev_dbg(dev, - "Buffer deactivated on channel %x, active " - "%d, ready %x, %x, current %x, rest %d!\n", chan_id, - ichan->active_buffer, ready0, ready1, curbuf, i); - } - if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) || (!ichan->active_buffer && (ready0 >> chan_id) & 1) )) { -- 1.7.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-01-31 12:22 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-31 12:22 UTC (permalink / raw) To: linux-arm-kernel Currently when two or more buffers are queued by the camera driver and so the double buffering is enabled in the idmac, we lose one frame comming from CSI since the reporting of arrival of the first frame is deferred by the DMAIC_7_EOF interrupt handler and reporting of the arrival of the last frame is not done at all. So when requesting N frames from the image sensor we actually receive N - 1 frames in user space. The reason for this behaviour is that the DMAIC_7_EOF interrupt handler misleadingly assumes that the CUR_BUF flag is pointing to the buffer used by the IDMAC. Actually it is not the case since the CUR_BUF flag will be flipped by the FSU when the FSU is sending the <TASK>_NEW_FRM_RDY signal when new frame data is delivered by the CSI. When sending this singal, FSU updates the DMA_CUR_BUF and the DMA_BUFx_RDY flags: the DMA_CUR_BUF is flipped, the DMA_BUFx_RDY is cleared, indicating that the frame data is beeing written by the IDMAC to the pointed buffer. DMA_BUFx_RDY is supposed to be set to the ready state again by the MCU, when it has handled the received data. DMAIC_7_CUR_BUF flag won't be flipped here by the IPU, so waiting for this event in the EOF interrupt handler is wrong. Actually there is no spurious interrupt as described in the comments, this is the valid DMAIC_7_EOF interrupt indicating reception of the frame from CSI. The patch removes code that waits for flipping of the DMAIC_7_CUR_BUF flag in the DMAIC_7_EOF interrupt handler. As the comment in the current code denotes, this waiting doesn't help anyway. As a result of this removal the reporting of the first arrived frame is not deferred to the time of arrival of the next frame and the drivers software flag 'ichan->active_buffer' is in sync with DMAIC_7_CUR_BUF flag, so the reception of all requested frames works. This has been verified on the hardware which is triggering the image sensor by the programmable state machine, allowing to obtain exact number of frames. On this hardware we do not tolerate losing frames. This patch also removes resetting the DMA_BUFx_RDY flags of all channels in ipu_disable_channel() since transfers on other DMA channels might be triggered by other running tasks and the buffers should always be ready for data sending or reception. Signed-off-by: Anatolij Gustschin <agust@denx.de> --- v2: Revise the commit message to provide more and correct information about the observed problem and proposed fix drivers/dma/ipu/ipu_idmac.c | 50 ------------------------------------------- 1 files changed, 0 insertions(+), 50 deletions(-) diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index cb26ee9..c1a125e 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan, reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN); - /* - * Problem (observed with channel DMAIC_7): after enabling the channel - * and initialising buffers, there comes an interrupt with current still - * pointing at buffer 0, whereas it should use buffer 0 first and only - * generate an interrupt when it is done, then current should already - * point to buffer 1. This spurious interrupt also comes on channel - * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the - * first interrupt, there comes the second with current correctly - * pointing to buffer 1 this time. But sometimes this second interrupt - * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling - * the channel seems to prevent the channel from hanging, but it doesn't - * prevent the spurious interrupt. This might also be unsafe. Think - * about the IDMAC controller trying to switch to a buffer, when we - * clear the ready bit, and re-enable it a moment later. - */ - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY); - - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY); - spin_unlock_irqrestore(&ipu->lock, flags); return 0; @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id) /* Other interrupts do not interfere with this channel */ spin_lock(&ichan->lock); - if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 && - ((curbuf >> chan_id) & 1) == ichan->active_buffer && - !list_is_last(ichan->queue.next, &ichan->queue))) { - int i = 100; - - /* This doesn't help. See comment in ipu_disable_channel() */ - while (--i) { - curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); - if (((curbuf >> chan_id) & 1) != ichan->active_buffer) - break; - cpu_relax(); - } - - if (!i) { - spin_unlock(&ichan->lock); - dev_dbg(dev, - "IRQ on active buffer on channel %x, active " - "%d, ready %x, %x, current %x!\n", chan_id, - ichan->active_buffer, ready0, ready1, curbuf); - return IRQ_NONE; - } else - dev_dbg(dev, - "Buffer deactivated on channel %x, active " - "%d, ready %x, %x, current %x, rest %d!\n", chan_id, - ichan->active_buffer, ready0, ready1, curbuf, i); - } - if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) || (!ichan->active_buffer && (ready0 >> chan_id) & 1) )) { -- 1.7.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-01-31 12:22 ` Anatolij Gustschin @ 2011-02-03 10:09 ` Guennadi Liakhovetski -1 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-03 10:09 UTC (permalink / raw) To: Anatolij Gustschin Cc: linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel Hi Anatolij On Mon, 31 Jan 2011, Anatolij Gustschin wrote: I'm afraid there seems to be a problem with your patch. I have no idea what is causing it, but I'm just observing some wrong behaviour, that is not there without it. Namely, I added a debug print to the IDMAC interrupt handler curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4); + printk(KERN_DEBUG "%s(): IDMAC irq %d, buf %d, current %d\n", __func__, + irq, ichan->active_buffer, (curbuf >> chan_id) & 1); if (err & (1 << chan_id)) { idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4); and without your patch I see buffer numbers correctly toggling all the time like idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 1 idmac_interrupt(): IDMAC irq 177, buf 1, current 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 1 idmac_interrupt(): IDMAC irq 177, buf 1, current 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 1 ... Yes, the first interrupt is different, that's where I'm dropping / postponing it. With your patch only N (equal to the number of buffers used, I think) first interrupts toggle, then always only one buffer is used: idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 ... Verified with both capture.c and mplayer. Could you, please, verify whether you get the same behaviour and what the problem could be? Thanks Guennadi > Currently when two or more buffers are queued by the camera driver > and so the double buffering is enabled in the idmac, we lose one > frame comming from CSI since the reporting of arrival of the first > frame is deferred by the DMAIC_7_EOF interrupt handler and reporting > of the arrival of the last frame is not done at all. So when requesting > N frames from the image sensor we actually receive N - 1 frames in > user space. > > The reason for this behaviour is that the DMAIC_7_EOF interrupt > handler misleadingly assumes that the CUR_BUF flag is pointing to the > buffer used by the IDMAC. Actually it is not the case since the > CUR_BUF flag will be flipped by the FSU when the FSU is sending the > <TASK>_NEW_FRM_RDY signal when new frame data is delivered by the CSI. > When sending this singal, FSU updates the DMA_CUR_BUF and the > DMA_BUFx_RDY flags: the DMA_CUR_BUF is flipped, the DMA_BUFx_RDY > is cleared, indicating that the frame data is beeing written by > the IDMAC to the pointed buffer. DMA_BUFx_RDY is supposed to be > set to the ready state again by the MCU, when it has handled the > received data. DMAIC_7_CUR_BUF flag won't be flipped here by the > IPU, so waiting for this event in the EOF interrupt handler is wrong. > Actually there is no spurious interrupt as described in the comments, > this is the valid DMAIC_7_EOF interrupt indicating reception of the > frame from CSI. > > The patch removes code that waits for flipping of the DMAIC_7_CUR_BUF > flag in the DMAIC_7_EOF interrupt handler. As the comment in the > current code denotes, this waiting doesn't help anyway. As a result > of this removal the reporting of the first arrived frame is not > deferred to the time of arrival of the next frame and the drivers > software flag 'ichan->active_buffer' is in sync with DMAIC_7_CUR_BUF > flag, so the reception of all requested frames works. > > This has been verified on the hardware which is triggering the > image sensor by the programmable state machine, allowing to > obtain exact number of frames. On this hardware we do not tolerate > losing frames. > > This patch also removes resetting the DMA_BUFx_RDY flags of > all channels in ipu_disable_channel() since transfers on other > DMA channels might be triggered by other running tasks and the > buffers should always be ready for data sending or reception. > > Signed-off-by: Anatolij Gustschin <agust@denx.de> > --- > v2: > Revise the commit message to provide more and correct > information about the observed problem and proposed fix > > drivers/dma/ipu/ipu_idmac.c | 50 ------------------------------------------- > 1 files changed, 0 insertions(+), 50 deletions(-) > > diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c > index cb26ee9..c1a125e 100644 > --- a/drivers/dma/ipu/ipu_idmac.c > +++ b/drivers/dma/ipu/ipu_idmac.c > @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan, > reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); > idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN); > > - /* > - * Problem (observed with channel DMAIC_7): after enabling the channel > - * and initialising buffers, there comes an interrupt with current still > - * pointing at buffer 0, whereas it should use buffer 0 first and only > - * generate an interrupt when it is done, then current should already > - * point to buffer 1. This spurious interrupt also comes on channel > - * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the > - * first interrupt, there comes the second with current correctly > - * pointing to buffer 1 this time. But sometimes this second interrupt > - * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling > - * the channel seems to prevent the channel from hanging, but it doesn't > - * prevent the spurious interrupt. This might also be unsafe. Think > - * about the IDMAC controller trying to switch to a buffer, when we > - * clear the ready bit, and re-enable it a moment later. > - */ > - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); > - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); > - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY); > - > - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); > - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); > - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY); > - > spin_unlock_irqrestore(&ipu->lock, flags); > > return 0; > @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id) > > /* Other interrupts do not interfere with this channel */ > spin_lock(&ichan->lock); > - if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 && > - ((curbuf >> chan_id) & 1) == ichan->active_buffer && > - !list_is_last(ichan->queue.next, &ichan->queue))) { > - int i = 100; > - > - /* This doesn't help. See comment in ipu_disable_channel() */ > - while (--i) { > - curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); > - if (((curbuf >> chan_id) & 1) != ichan->active_buffer) > - break; > - cpu_relax(); > - } > - > - if (!i) { > - spin_unlock(&ichan->lock); > - dev_dbg(dev, > - "IRQ on active buffer on channel %x, active " > - "%d, ready %x, %x, current %x!\n", chan_id, > - ichan->active_buffer, ready0, ready1, curbuf); > - return IRQ_NONE; > - } else > - dev_dbg(dev, > - "Buffer deactivated on channel %x, active " > - "%d, ready %x, %x, current %x, rest %d!\n", chan_id, > - ichan->active_buffer, ready0, ready1, curbuf, i); > - } > - > if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) || > (!ichan->active_buffer && (ready0 >> chan_id) & 1) > )) { > -- > 1.7.1 > --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-03 10:09 ` Guennadi Liakhovetski 0 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-03 10:09 UTC (permalink / raw) To: linux-arm-kernel Hi Anatolij On Mon, 31 Jan 2011, Anatolij Gustschin wrote: I'm afraid there seems to be a problem with your patch. I have no idea what is causing it, but I'm just observing some wrong behaviour, that is not there without it. Namely, I added a debug print to the IDMAC interrupt handler curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4); + printk(KERN_DEBUG "%s(): IDMAC irq %d, buf %d, current %d\n", __func__, + irq, ichan->active_buffer, (curbuf >> chan_id) & 1); if (err & (1 << chan_id)) { idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4); and without your patch I see buffer numbers correctly toggling all the time like idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 1 idmac_interrupt(): IDMAC irq 177, buf 1, current 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 1 idmac_interrupt(): IDMAC irq 177, buf 1, current 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 1 ... Yes, the first interrupt is different, that's where I'm dropping / postponing it. With your patch only N (equal to the number of buffers used, I think) first interrupts toggle, then always only one buffer is used: idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 ... Verified with both capture.c and mplayer. Could you, please, verify whether you get the same behaviour and what the problem could be? Thanks Guennadi > Currently when two or more buffers are queued by the camera driver > and so the double buffering is enabled in the idmac, we lose one > frame comming from CSI since the reporting of arrival of the first > frame is deferred by the DMAIC_7_EOF interrupt handler and reporting > of the arrival of the last frame is not done at all. So when requesting > N frames from the image sensor we actually receive N - 1 frames in > user space. > > The reason for this behaviour is that the DMAIC_7_EOF interrupt > handler misleadingly assumes that the CUR_BUF flag is pointing to the > buffer used by the IDMAC. Actually it is not the case since the > CUR_BUF flag will be flipped by the FSU when the FSU is sending the > <TASK>_NEW_FRM_RDY signal when new frame data is delivered by the CSI. > When sending this singal, FSU updates the DMA_CUR_BUF and the > DMA_BUFx_RDY flags: the DMA_CUR_BUF is flipped, the DMA_BUFx_RDY > is cleared, indicating that the frame data is beeing written by > the IDMAC to the pointed buffer. DMA_BUFx_RDY is supposed to be > set to the ready state again by the MCU, when it has handled the > received data. DMAIC_7_CUR_BUF flag won't be flipped here by the > IPU, so waiting for this event in the EOF interrupt handler is wrong. > Actually there is no spurious interrupt as described in the comments, > this is the valid DMAIC_7_EOF interrupt indicating reception of the > frame from CSI. > > The patch removes code that waits for flipping of the DMAIC_7_CUR_BUF > flag in the DMAIC_7_EOF interrupt handler. As the comment in the > current code denotes, this waiting doesn't help anyway. As a result > of this removal the reporting of the first arrived frame is not > deferred to the time of arrival of the next frame and the drivers > software flag 'ichan->active_buffer' is in sync with DMAIC_7_CUR_BUF > flag, so the reception of all requested frames works. > > This has been verified on the hardware which is triggering the > image sensor by the programmable state machine, allowing to > obtain exact number of frames. On this hardware we do not tolerate > losing frames. > > This patch also removes resetting the DMA_BUFx_RDY flags of > all channels in ipu_disable_channel() since transfers on other > DMA channels might be triggered by other running tasks and the > buffers should always be ready for data sending or reception. > > Signed-off-by: Anatolij Gustschin <agust@denx.de> > --- > v2: > Revise the commit message to provide more and correct > information about the observed problem and proposed fix > > drivers/dma/ipu/ipu_idmac.c | 50 ------------------------------------------- > 1 files changed, 0 insertions(+), 50 deletions(-) > > diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c > index cb26ee9..c1a125e 100644 > --- a/drivers/dma/ipu/ipu_idmac.c > +++ b/drivers/dma/ipu/ipu_idmac.c > @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan, > reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); > idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN); > > - /* > - * Problem (observed with channel DMAIC_7): after enabling the channel > - * and initialising buffers, there comes an interrupt with current still > - * pointing at buffer 0, whereas it should use buffer 0 first and only > - * generate an interrupt when it is done, then current should already > - * point to buffer 1. This spurious interrupt also comes on channel > - * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the > - * first interrupt, there comes the second with current correctly > - * pointing to buffer 1 this time. But sometimes this second interrupt > - * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling > - * the channel seems to prevent the channel from hanging, but it doesn't > - * prevent the spurious interrupt. This might also be unsafe. Think > - * about the IDMAC controller trying to switch to a buffer, when we > - * clear the ready bit, and re-enable it a moment later. > - */ > - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); > - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); > - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY); > - > - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); > - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); > - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY); > - > spin_unlock_irqrestore(&ipu->lock, flags); > > return 0; > @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id) > > /* Other interrupts do not interfere with this channel */ > spin_lock(&ichan->lock); > - if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 && > - ((curbuf >> chan_id) & 1) == ichan->active_buffer && > - !list_is_last(ichan->queue.next, &ichan->queue))) { > - int i = 100; > - > - /* This doesn't help. See comment in ipu_disable_channel() */ > - while (--i) { > - curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); > - if (((curbuf >> chan_id) & 1) != ichan->active_buffer) > - break; > - cpu_relax(); > - } > - > - if (!i) { > - spin_unlock(&ichan->lock); > - dev_dbg(dev, > - "IRQ on active buffer on channel %x, active " > - "%d, ready %x, %x, current %x!\n", chan_id, > - ichan->active_buffer, ready0, ready1, curbuf); > - return IRQ_NONE; > - } else > - dev_dbg(dev, > - "Buffer deactivated on channel %x, active " > - "%d, ready %x, %x, current %x, rest %d!\n", chan_id, > - ichan->active_buffer, ready0, ready1, curbuf, i); > - } > - > if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) || > (!ichan->active_buffer && (ready0 >> chan_id) & 1) > )) { > -- > 1.7.1 > --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-03 10:09 ` Guennadi Liakhovetski @ 2011-02-04 9:19 ` Markus Niebel -1 siblings, 0 replies; 56+ messages in thread From: Markus Niebel @ 2011-02-04 9:19 UTC (permalink / raw) To: Guennadi Liakhovetski Cc: Anatolij Gustschin, linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel Hello Guennadi, hello Anatolij I've tried that with my setup: Hardware: i.MX35, special CCD camera over FPGA Kernel: 2.6.34 patch v4l: soc-camera: start stream after queueing the buffers is applied and our camera driver handles streamon / streamoff so that no sync signal / clock is provided, when not streaming. Our setup works with 4 buffers What we see is as we would expect plus no difference with 1st buffer: [ 206.770000] i5ccdhb i5ccdhb.0: soc_i5ccdhb_s_stream - enable 1 [ 207.350000] i5ccdhb i5ccdhb.0: i5ccdhb_streamon: fps (29.412) [ 207.370000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 207.410000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 207.440000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 207.470000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 207.540000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 207.580000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 207.610000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 207.650000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 207.680000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 207.710000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 207.750000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 207.780000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 ... [ 241.370000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 241.410000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 241.440000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 241.470000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 241.510000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 241.540000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 241.580000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 241.610000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 257.190000] i5ccdhb i5ccdhb.0: soc_i5ccdhb_s_stream - enable 0 Am 03.02.2011 11:09, schrieb Guennadi Liakhovetski: > Hi Anatolij > > On Mon, 31 Jan 2011, Anatolij Gustschin wrote: > > I'm afraid there seems to be a problem with your patch. I have no idea > what is causing it, but I'm just observing some wrong behaviour, that is > not there without it. Namely, I added a debug print to the IDMAC interrupt > handler > > curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); > err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4); > > + printk(KERN_DEBUG "%s(): IDMAC irq %d, buf %d, current %d\n", __func__, > + irq, ichan->active_buffer, (curbuf>> chan_id)& 1); > > if (err& (1<< chan_id)) { > idmac_write_ipureg(&ipu_data, 1<< chan_id, IPU_INT_STAT_4); > > and without your patch I see buffer numbers correctly toggling all the > time like > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > ... > > Yes, the first interrupt is different, that's where I'm dropping / > postponing it. With your patch only N (equal to the number of buffers > used, I think) first interrupts toggle, then always only one buffer is > used: > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > ... > > Verified with both capture.c and mplayer. Could you, please, verify > whether you get the same behaviour and what the problem could be? > > Thanks > Guennadi > >> Currently when two or more buffers are queued by the camera driver >> and so the double buffering is enabled in the idmac, we lose one >> frame comming from CSI since the reporting of arrival of the first >> frame is deferred by the DMAIC_7_EOF interrupt handler and reporting >> of the arrival of the last frame is not done at all. So when requesting >> N frames from the image sensor we actually receive N - 1 frames in >> user space. >> >> The reason for this behaviour is that the DMAIC_7_EOF interrupt >> handler misleadingly assumes that the CUR_BUF flag is pointing to the >> buffer used by the IDMAC. Actually it is not the case since the >> CUR_BUF flag will be flipped by the FSU when the FSU is sending the >> <TASK>_NEW_FRM_RDY signal when new frame data is delivered by the CSI. >> When sending this singal, FSU updates the DMA_CUR_BUF and the >> DMA_BUFx_RDY flags: the DMA_CUR_BUF is flipped, the DMA_BUFx_RDY >> is cleared, indicating that the frame data is beeing written by >> the IDMAC to the pointed buffer. DMA_BUFx_RDY is supposed to be >> set to the ready state again by the MCU, when it has handled the >> received data. DMAIC_7_CUR_BUF flag won't be flipped here by the >> IPU, so waiting for this event in the EOF interrupt handler is wrong. >> Actually there is no spurious interrupt as described in the comments, >> this is the valid DMAIC_7_EOF interrupt indicating reception of the >> frame from CSI. >> >> The patch removes code that waits for flipping of the DMAIC_7_CUR_BUF >> flag in the DMAIC_7_EOF interrupt handler. As the comment in the >> current code denotes, this waiting doesn't help anyway. As a result >> of this removal the reporting of the first arrived frame is not >> deferred to the time of arrival of the next frame and the drivers >> software flag 'ichan->active_buffer' is in sync with DMAIC_7_CUR_BUF >> flag, so the reception of all requested frames works. >> >> This has been verified on the hardware which is triggering the >> image sensor by the programmable state machine, allowing to >> obtain exact number of frames. On this hardware we do not tolerate >> losing frames. >> >> This patch also removes resetting the DMA_BUFx_RDY flags of >> all channels in ipu_disable_channel() since transfers on other >> DMA channels might be triggered by other running tasks and the >> buffers should always be ready for data sending or reception. >> >> Signed-off-by: Anatolij Gustschin<agust@denx.de> >> --- >> v2: >> Revise the commit message to provide more and correct >> information about the observed problem and proposed fix >> >> drivers/dma/ipu/ipu_idmac.c | 50 ------------------------------------------- >> 1 files changed, 0 insertions(+), 50 deletions(-) >> >> diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c >> index cb26ee9..c1a125e 100644 >> --- a/drivers/dma/ipu/ipu_idmac.c >> +++ b/drivers/dma/ipu/ipu_idmac.c >> @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan, >> reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); >> idmac_write_icreg(ipu, reg& ~chan_mask, IDMAC_CHA_EN); >> >> - /* >> - * Problem (observed with channel DMAIC_7): after enabling the channel >> - * and initialising buffers, there comes an interrupt with current still >> - * pointing at buffer 0, whereas it should use buffer 0 first and only >> - * generate an interrupt when it is done, then current should already >> - * point to buffer 1. This spurious interrupt also comes on channel >> - * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the >> - * first interrupt, there comes the second with current correctly >> - * pointing to buffer 1 this time. But sometimes this second interrupt >> - * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling >> - * the channel seems to prevent the channel from hanging, but it doesn't >> - * prevent the spurious interrupt. This might also be unsafe. Think >> - * about the IDMAC controller trying to switch to a buffer, when we >> - * clear the ready bit, and re-enable it a moment later. >> - */ >> - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); >> - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); >> - idmac_write_ipureg(ipu, reg& ~(1UL<< channel), IPU_CHA_BUF0_RDY); >> - >> - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); >> - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); >> - idmac_write_ipureg(ipu, reg& ~(1UL<< channel), IPU_CHA_BUF1_RDY); >> - >> spin_unlock_irqrestore(&ipu->lock, flags); >> >> return 0; >> @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id) >> >> /* Other interrupts do not interfere with this channel */ >> spin_lock(&ichan->lock); >> - if (unlikely(chan_id != IDMAC_SDC_0&& chan_id != IDMAC_SDC_1&& >> - ((curbuf>> chan_id)& 1) == ichan->active_buffer&& >> - !list_is_last(ichan->queue.next,&ichan->queue))) { >> - int i = 100; >> - >> - /* This doesn't help. See comment in ipu_disable_channel() */ >> - while (--i) { >> - curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); >> - if (((curbuf>> chan_id)& 1) != ichan->active_buffer) >> - break; >> - cpu_relax(); >> - } >> - >> - if (!i) { >> - spin_unlock(&ichan->lock); >> - dev_dbg(dev, >> - "IRQ on active buffer on channel %x, active " >> - "%d, ready %x, %x, current %x!\n", chan_id, >> - ichan->active_buffer, ready0, ready1, curbuf); >> - return IRQ_NONE; >> - } else >> - dev_dbg(dev, >> - "Buffer deactivated on channel %x, active " >> - "%d, ready %x, %x, current %x, rest %d!\n", chan_id, >> - ichan->active_buffer, ready0, ready1, curbuf, i); >> - } >> - >> if (unlikely((ichan->active_buffer&& (ready1>> chan_id)& 1) || >> (!ichan->active_buffer&& (ready0>> chan_id)& 1) >> )) { >> -- >> 1.7.1 >> > > --- > Guennadi Liakhovetski, Ph.D. > Freelance Open-Source Software Developer > http://www.open-technology.de/ > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-04 9:19 ` Markus Niebel 0 siblings, 0 replies; 56+ messages in thread From: Markus Niebel @ 2011-02-04 9:19 UTC (permalink / raw) To: linux-arm-kernel Hello Guennadi, hello Anatolij I've tried that with my setup: Hardware: i.MX35, special CCD camera over FPGA Kernel: 2.6.34 patch v4l: soc-camera: start stream after queueing the buffers is applied and our camera driver handles streamon / streamoff so that no sync signal / clock is provided, when not streaming. Our setup works with 4 buffers What we see is as we would expect plus no difference with 1st buffer: [ 206.770000] i5ccdhb i5ccdhb.0: soc_i5ccdhb_s_stream - enable 1 [ 207.350000] i5ccdhb i5ccdhb.0: i5ccdhb_streamon: fps (29.412) [ 207.370000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 207.410000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 207.440000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 207.470000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 207.540000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 207.580000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 207.610000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 207.650000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 207.680000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 207.710000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 207.750000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 207.780000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 ... [ 241.370000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 241.410000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 241.440000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 241.470000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 241.510000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 241.540000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 241.580000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 [ 241.610000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 [ 257.190000] i5ccdhb i5ccdhb.0: soc_i5ccdhb_s_stream - enable 0 Am 03.02.2011 11:09, schrieb Guennadi Liakhovetski: > Hi Anatolij > > On Mon, 31 Jan 2011, Anatolij Gustschin wrote: > > I'm afraid there seems to be a problem with your patch. I have no idea > what is causing it, but I'm just observing some wrong behaviour, that is > not there without it. Namely, I added a debug print to the IDMAC interrupt > handler > > curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); > err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4); > > + printk(KERN_DEBUG "%s(): IDMAC irq %d, buf %d, current %d\n", __func__, > + irq, ichan->active_buffer, (curbuf>> chan_id)& 1); > > if (err& (1<< chan_id)) { > idmac_write_ipureg(&ipu_data, 1<< chan_id, IPU_INT_STAT_4); > > and without your patch I see buffer numbers correctly toggling all the > time like > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > ... > > Yes, the first interrupt is different, that's where I'm dropping / > postponing it. With your patch only N (equal to the number of buffers > used, I think) first interrupts toggle, then always only one buffer is > used: > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > ... > > Verified with both capture.c and mplayer. Could you, please, verify > whether you get the same behaviour and what the problem could be? > > Thanks > Guennadi > >> Currently when two or more buffers are queued by the camera driver >> and so the double buffering is enabled in the idmac, we lose one >> frame comming from CSI since the reporting of arrival of the first >> frame is deferred by the DMAIC_7_EOF interrupt handler and reporting >> of the arrival of the last frame is not done at all. So when requesting >> N frames from the image sensor we actually receive N - 1 frames in >> user space. >> >> The reason for this behaviour is that the DMAIC_7_EOF interrupt >> handler misleadingly assumes that the CUR_BUF flag is pointing to the >> buffer used by the IDMAC. Actually it is not the case since the >> CUR_BUF flag will be flipped by the FSU when the FSU is sending the >> <TASK>_NEW_FRM_RDY signal when new frame data is delivered by the CSI. >> When sending this singal, FSU updates the DMA_CUR_BUF and the >> DMA_BUFx_RDY flags: the DMA_CUR_BUF is flipped, the DMA_BUFx_RDY >> is cleared, indicating that the frame data is beeing written by >> the IDMAC to the pointed buffer. DMA_BUFx_RDY is supposed to be >> set to the ready state again by the MCU, when it has handled the >> received data. DMAIC_7_CUR_BUF flag won't be flipped here by the >> IPU, so waiting for this event in the EOF interrupt handler is wrong. >> Actually there is no spurious interrupt as described in the comments, >> this is the valid DMAIC_7_EOF interrupt indicating reception of the >> frame from CSI. >> >> The patch removes code that waits for flipping of the DMAIC_7_CUR_BUF >> flag in the DMAIC_7_EOF interrupt handler. As the comment in the >> current code denotes, this waiting doesn't help anyway. As a result >> of this removal the reporting of the first arrived frame is not >> deferred to the time of arrival of the next frame and the drivers >> software flag 'ichan->active_buffer' is in sync with DMAIC_7_CUR_BUF >> flag, so the reception of all requested frames works. >> >> This has been verified on the hardware which is triggering the >> image sensor by the programmable state machine, allowing to >> obtain exact number of frames. On this hardware we do not tolerate >> losing frames. >> >> This patch also removes resetting the DMA_BUFx_RDY flags of >> all channels in ipu_disable_channel() since transfers on other >> DMA channels might be triggered by other running tasks and the >> buffers should always be ready for data sending or reception. >> >> Signed-off-by: Anatolij Gustschin<agust@denx.de> >> --- >> v2: >> Revise the commit message to provide more and correct >> information about the observed problem and proposed fix >> >> drivers/dma/ipu/ipu_idmac.c | 50 ------------------------------------------- >> 1 files changed, 0 insertions(+), 50 deletions(-) >> >> diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c >> index cb26ee9..c1a125e 100644 >> --- a/drivers/dma/ipu/ipu_idmac.c >> +++ b/drivers/dma/ipu/ipu_idmac.c >> @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan, >> reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); >> idmac_write_icreg(ipu, reg& ~chan_mask, IDMAC_CHA_EN); >> >> - /* >> - * Problem (observed with channel DMAIC_7): after enabling the channel >> - * and initialising buffers, there comes an interrupt with current still >> - * pointing at buffer 0, whereas it should use buffer 0 first and only >> - * generate an interrupt when it is done, then current should already >> - * point to buffer 1. This spurious interrupt also comes on channel >> - * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the >> - * first interrupt, there comes the second with current correctly >> - * pointing to buffer 1 this time. But sometimes this second interrupt >> - * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling >> - * the channel seems to prevent the channel from hanging, but it doesn't >> - * prevent the spurious interrupt. This might also be unsafe. Think >> - * about the IDMAC controller trying to switch to a buffer, when we >> - * clear the ready bit, and re-enable it a moment later. >> - */ >> - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); >> - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); >> - idmac_write_ipureg(ipu, reg& ~(1UL<< channel), IPU_CHA_BUF0_RDY); >> - >> - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); >> - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); >> - idmac_write_ipureg(ipu, reg& ~(1UL<< channel), IPU_CHA_BUF1_RDY); >> - >> spin_unlock_irqrestore(&ipu->lock, flags); >> >> return 0; >> @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id) >> >> /* Other interrupts do not interfere with this channel */ >> spin_lock(&ichan->lock); >> - if (unlikely(chan_id != IDMAC_SDC_0&& chan_id != IDMAC_SDC_1&& >> - ((curbuf>> chan_id)& 1) == ichan->active_buffer&& >> - !list_is_last(ichan->queue.next,&ichan->queue))) { >> - int i = 100; >> - >> - /* This doesn't help. See comment in ipu_disable_channel() */ >> - while (--i) { >> - curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); >> - if (((curbuf>> chan_id)& 1) != ichan->active_buffer) >> - break; >> - cpu_relax(); >> - } >> - >> - if (!i) { >> - spin_unlock(&ichan->lock); >> - dev_dbg(dev, >> - "IRQ on active buffer on channel %x, active " >> - "%d, ready %x, %x, current %x!\n", chan_id, >> - ichan->active_buffer, ready0, ready1, curbuf); >> - return IRQ_NONE; >> - } else >> - dev_dbg(dev, >> - "Buffer deactivated on channel %x, active " >> - "%d, ready %x, %x, current %x, rest %d!\n", chan_id, >> - ichan->active_buffer, ready0, ready1, curbuf, i); >> - } >> - >> if (unlikely((ichan->active_buffer&& (ready1>> chan_id)& 1) || >> (!ichan->active_buffer&& (ready0>> chan_id)& 1) >> )) { >> -- >> 1.7.1 >> > > --- > Guennadi Liakhovetski, Ph.D. > Freelance Open-Source Software Developer > http://www.open-technology.de/ > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-04 9:19 ` Markus Niebel @ 2011-02-04 9:37 ` Guennadi Liakhovetski -1 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-04 9:37 UTC (permalink / raw) To: Markus Niebel Cc: Anatolij Gustschin, linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel Hi Markus On Fri, 4 Feb 2011, Markus Niebel wrote: > Hello Guennadi, hello Anatolij > > I've tried that with my setup: > > Hardware: i.MX35, special CCD camera over FPGA > Kernel: 2.6.34 > > patch v4l: soc-camera: start stream after queueing the buffers is applied and > our camera driver handles streamon / streamoff so that no sync signal / clock > is provided, when not streaming. > > Our setup works with 4 buffers > > What we see is as we would expect plus no difference with 1st buffer: But you haven't applied the patch, that my reply was actually referring to - the change to ipu_idmac.c? I think, that's the one, killing the double-buffering. But thanks for testing the streamon patch too! Thanks Guennadi > > [ 206.770000] i5ccdhb i5ccdhb.0: soc_i5ccdhb_s_stream - enable 1 > [ 207.350000] i5ccdhb i5ccdhb.0: i5ccdhb_streamon: fps (29.412) > [ 207.370000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 207.410000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 207.440000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 207.470000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 207.540000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 207.580000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 207.610000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 207.650000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 207.680000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 207.710000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 207.750000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 207.780000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > ... > [ 241.370000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 241.410000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 241.440000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 241.470000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 241.510000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 241.540000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 241.580000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 241.610000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 257.190000] i5ccdhb i5ccdhb.0: soc_i5ccdhb_s_stream - enable 0 > > > > Am 03.02.2011 11:09, schrieb Guennadi Liakhovetski: > > Hi Anatolij > > > > On Mon, 31 Jan 2011, Anatolij Gustschin wrote: > > > > I'm afraid there seems to be a problem with your patch. I have no idea > > what is causing it, but I'm just observing some wrong behaviour, that is > > not there without it. Namely, I added a debug print to the IDMAC interrupt > > handler > > > > curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); > > err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4); > > > > + printk(KERN_DEBUG "%s(): IDMAC irq %d, buf %d, current %d\n", > > __func__, > > + irq, ichan->active_buffer, (curbuf>> chan_id)& 1); > > > > if (err& (1<< chan_id)) { > > idmac_write_ipureg(&ipu_data, 1<< chan_id, IPU_INT_STAT_4); > > > > and without your patch I see buffer numbers correctly toggling all the > > time like > > > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > > ... > > > > Yes, the first interrupt is different, that's where I'm dropping / > > postponing it. With your patch only N (equal to the number of buffers > > used, I think) first interrupts toggle, then always only one buffer is > > used: > > > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > ... > > > > Verified with both capture.c and mplayer. Could you, please, verify > > whether you get the same behaviour and what the problem could be? > > > > Thanks > > Guennadi > > > > > Currently when two or more buffers are queued by the camera driver > > > and so the double buffering is enabled in the idmac, we lose one > > > frame comming from CSI since the reporting of arrival of the first > > > frame is deferred by the DMAIC_7_EOF interrupt handler and reporting > > > of the arrival of the last frame is not done at all. So when requesting > > > N frames from the image sensor we actually receive N - 1 frames in > > > user space. > > > > > > The reason for this behaviour is that the DMAIC_7_EOF interrupt > > > handler misleadingly assumes that the CUR_BUF flag is pointing to the > > > buffer used by the IDMAC. Actually it is not the case since the > > > CUR_BUF flag will be flipped by the FSU when the FSU is sending the > > > <TASK>_NEW_FRM_RDY signal when new frame data is delivered by the CSI. > > > When sending this singal, FSU updates the DMA_CUR_BUF and the > > > DMA_BUFx_RDY flags: the DMA_CUR_BUF is flipped, the DMA_BUFx_RDY > > > is cleared, indicating that the frame data is beeing written by > > > the IDMAC to the pointed buffer. DMA_BUFx_RDY is supposed to be > > > set to the ready state again by the MCU, when it has handled the > > > received data. DMAIC_7_CUR_BUF flag won't be flipped here by the > > > IPU, so waiting for this event in the EOF interrupt handler is wrong. > > > Actually there is no spurious interrupt as described in the comments, > > > this is the valid DMAIC_7_EOF interrupt indicating reception of the > > > frame from CSI. > > > > > > The patch removes code that waits for flipping of the DMAIC_7_CUR_BUF > > > flag in the DMAIC_7_EOF interrupt handler. As the comment in the > > > current code denotes, this waiting doesn't help anyway. As a result > > > of this removal the reporting of the first arrived frame is not > > > deferred to the time of arrival of the next frame and the drivers > > > software flag 'ichan->active_buffer' is in sync with DMAIC_7_CUR_BUF > > > flag, so the reception of all requested frames works. > > > > > > This has been verified on the hardware which is triggering the > > > image sensor by the programmable state machine, allowing to > > > obtain exact number of frames. On this hardware we do not tolerate > > > losing frames. > > > > > > This patch also removes resetting the DMA_BUFx_RDY flags of > > > all channels in ipu_disable_channel() since transfers on other > > > DMA channels might be triggered by other running tasks and the > > > buffers should always be ready for data sending or reception. > > > > > > Signed-off-by: Anatolij Gustschin<agust@denx.de> > > > --- > > > v2: > > > Revise the commit message to provide more and correct > > > information about the observed problem and proposed fix > > > > > > drivers/dma/ipu/ipu_idmac.c | 50 > > > ------------------------------------------- > > > 1 files changed, 0 insertions(+), 50 deletions(-) > > > > > > diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c > > > index cb26ee9..c1a125e 100644 > > > --- a/drivers/dma/ipu/ipu_idmac.c > > > +++ b/drivers/dma/ipu/ipu_idmac.c > > > @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, > > > struct idmac_channel *ichan, > > > reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); > > > idmac_write_icreg(ipu, reg& ~chan_mask, IDMAC_CHA_EN); > > > > > > - /* > > > - * Problem (observed with channel DMAIC_7): after enabling the channel > > > - * and initialising buffers, there comes an interrupt with current > > > still > > > - * pointing at buffer 0, whereas it should use buffer 0 first and only > > > - * generate an interrupt when it is done, then current should already > > > - * point to buffer 1. This spurious interrupt also comes on channel > > > - * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the > > > - * first interrupt, there comes the second with current correctly > > > - * pointing to buffer 1 this time. But sometimes this second interrupt > > > - * doesn't come and the channel hangs. Clearing BUFx_RDY when > > > disabling > > > - * the channel seems to prevent the channel from hanging, but it > > > doesn't > > > - * prevent the spurious interrupt. This might also be unsafe. Think > > > - * about the IDMAC controller trying to switch to a buffer, when we > > > - * clear the ready bit, and re-enable it a moment later. > > > - */ > > > - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); > > > - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); > > > - idmac_write_ipureg(ipu, reg& ~(1UL<< channel), IPU_CHA_BUF0_RDY); > > > - > > > - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); > > > - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); > > > - idmac_write_ipureg(ipu, reg& ~(1UL<< channel), IPU_CHA_BUF1_RDY); > > > - > > > spin_unlock_irqrestore(&ipu->lock, flags); > > > > > > return 0; > > > @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void > > > *dev_id) > > > > > > /* Other interrupts do not interfere with this channel */ > > > spin_lock(&ichan->lock); > > > - if (unlikely(chan_id != IDMAC_SDC_0&& chan_id != IDMAC_SDC_1&& > > > - ((curbuf>> chan_id)& 1) == ichan->active_buffer&& > > > - !list_is_last(ichan->queue.next,&ichan->queue))) { > > > - int i = 100; > > > - > > > - /* This doesn't help. See comment in ipu_disable_channel() */ > > > - while (--i) { > > > - curbuf = idmac_read_ipureg(&ipu_data, > > > IPU_CHA_CUR_BUF); > > > - if (((curbuf>> chan_id)& 1) != ichan->active_buffer) > > > - break; > > > - cpu_relax(); > > > - } > > > - > > > - if (!i) { > > > - spin_unlock(&ichan->lock); > > > - dev_dbg(dev, > > > - "IRQ on active buffer on channel %x, active " > > > - "%d, ready %x, %x, current %x!\n", chan_id, > > > - ichan->active_buffer, ready0, ready1, curbuf); > > > - return IRQ_NONE; > > > - } else > > > - dev_dbg(dev, > > > - "Buffer deactivated on channel %x, active " > > > - "%d, ready %x, %x, current %x, rest %d!\n", > > > chan_id, > > > - ichan->active_buffer, ready0, ready1, curbuf, > > > i); > > > - } > > > - > > > if (unlikely((ichan->active_buffer&& (ready1>> chan_id)& 1) || > > > (!ichan->active_buffer&& (ready0>> chan_id)& 1) > > > )) { > > > -- > > > 1.7.1 > > > > > > > --- > > Guennadi Liakhovetski, Ph.D. > > Freelance Open-Source Software Developer > > http://www.open-technology.de/ > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-media" in > > the body of a message to majordomo@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html > --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-04 9:37 ` Guennadi Liakhovetski 0 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-04 9:37 UTC (permalink / raw) To: linux-arm-kernel Hi Markus On Fri, 4 Feb 2011, Markus Niebel wrote: > Hello Guennadi, hello Anatolij > > I've tried that with my setup: > > Hardware: i.MX35, special CCD camera over FPGA > Kernel: 2.6.34 > > patch v4l: soc-camera: start stream after queueing the buffers is applied and > our camera driver handles streamon / streamoff so that no sync signal / clock > is provided, when not streaming. > > Our setup works with 4 buffers > > What we see is as we would expect plus no difference with 1st buffer: But you haven't applied the patch, that my reply was actually referring to - the change to ipu_idmac.c? I think, that's the one, killing the double-buffering. But thanks for testing the streamon patch too! Thanks Guennadi > > [ 206.770000] i5ccdhb i5ccdhb.0: soc_i5ccdhb_s_stream - enable 1 > [ 207.350000] i5ccdhb i5ccdhb.0: i5ccdhb_streamon: fps (29.412) > [ 207.370000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 207.410000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 207.440000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 207.470000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 207.540000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 207.580000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 207.610000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 207.650000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 207.680000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 207.710000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 207.750000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 207.780000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > ... > [ 241.370000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 241.410000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 241.440000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 241.470000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 241.510000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 241.540000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 241.580000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > [ 241.610000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > [ 257.190000] i5ccdhb i5ccdhb.0: soc_i5ccdhb_s_stream - enable 0 > > > > Am 03.02.2011 11:09, schrieb Guennadi Liakhovetski: > > Hi Anatolij > > > > On Mon, 31 Jan 2011, Anatolij Gustschin wrote: > > > > I'm afraid there seems to be a problem with your patch. I have no idea > > what is causing it, but I'm just observing some wrong behaviour, that is > > not there without it. Namely, I added a debug print to the IDMAC interrupt > > handler > > > > curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); > > err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4); > > > > + printk(KERN_DEBUG "%s(): IDMAC irq %d, buf %d, current %d\n", > > __func__, > > + irq, ichan->active_buffer, (curbuf>> chan_id)& 1); > > > > if (err& (1<< chan_id)) { > > idmac_write_ipureg(&ipu_data, 1<< chan_id, IPU_INT_STAT_4); > > > > and without your patch I see buffer numbers correctly toggling all the > > time like > > > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > > ... > > > > Yes, the first interrupt is different, that's where I'm dropping / > > postponing it. With your patch only N (equal to the number of buffers > > used, I think) first interrupts toggle, then always only one buffer is > > used: > > > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > ... > > > > Verified with both capture.c and mplayer. Could you, please, verify > > whether you get the same behaviour and what the problem could be? > > > > Thanks > > Guennadi > > > > > Currently when two or more buffers are queued by the camera driver > > > and so the double buffering is enabled in the idmac, we lose one > > > frame comming from CSI since the reporting of arrival of the first > > > frame is deferred by the DMAIC_7_EOF interrupt handler and reporting > > > of the arrival of the last frame is not done at all. So when requesting > > > N frames from the image sensor we actually receive N - 1 frames in > > > user space. > > > > > > The reason for this behaviour is that the DMAIC_7_EOF interrupt > > > handler misleadingly assumes that the CUR_BUF flag is pointing to the > > > buffer used by the IDMAC. Actually it is not the case since the > > > CUR_BUF flag will be flipped by the FSU when the FSU is sending the > > > <TASK>_NEW_FRM_RDY signal when new frame data is delivered by the CSI. > > > When sending this singal, FSU updates the DMA_CUR_BUF and the > > > DMA_BUFx_RDY flags: the DMA_CUR_BUF is flipped, the DMA_BUFx_RDY > > > is cleared, indicating that the frame data is beeing written by > > > the IDMAC to the pointed buffer. DMA_BUFx_RDY is supposed to be > > > set to the ready state again by the MCU, when it has handled the > > > received data. DMAIC_7_CUR_BUF flag won't be flipped here by the > > > IPU, so waiting for this event in the EOF interrupt handler is wrong. > > > Actually there is no spurious interrupt as described in the comments, > > > this is the valid DMAIC_7_EOF interrupt indicating reception of the > > > frame from CSI. > > > > > > The patch removes code that waits for flipping of the DMAIC_7_CUR_BUF > > > flag in the DMAIC_7_EOF interrupt handler. As the comment in the > > > current code denotes, this waiting doesn't help anyway. As a result > > > of this removal the reporting of the first arrived frame is not > > > deferred to the time of arrival of the next frame and the drivers > > > software flag 'ichan->active_buffer' is in sync with DMAIC_7_CUR_BUF > > > flag, so the reception of all requested frames works. > > > > > > This has been verified on the hardware which is triggering the > > > image sensor by the programmable state machine, allowing to > > > obtain exact number of frames. On this hardware we do not tolerate > > > losing frames. > > > > > > This patch also removes resetting the DMA_BUFx_RDY flags of > > > all channels in ipu_disable_channel() since transfers on other > > > DMA channels might be triggered by other running tasks and the > > > buffers should always be ready for data sending or reception. > > > > > > Signed-off-by: Anatolij Gustschin<agust@denx.de> > > > --- > > > v2: > > > Revise the commit message to provide more and correct > > > information about the observed problem and proposed fix > > > > > > drivers/dma/ipu/ipu_idmac.c | 50 > > > ------------------------------------------- > > > 1 files changed, 0 insertions(+), 50 deletions(-) > > > > > > diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c > > > index cb26ee9..c1a125e 100644 > > > --- a/drivers/dma/ipu/ipu_idmac.c > > > +++ b/drivers/dma/ipu/ipu_idmac.c > > > @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, > > > struct idmac_channel *ichan, > > > reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); > > > idmac_write_icreg(ipu, reg& ~chan_mask, IDMAC_CHA_EN); > > > > > > - /* > > > - * Problem (observed with channel DMAIC_7): after enabling the channel > > > - * and initialising buffers, there comes an interrupt with current > > > still > > > - * pointing at buffer 0, whereas it should use buffer 0 first and only > > > - * generate an interrupt when it is done, then current should already > > > - * point to buffer 1. This spurious interrupt also comes on channel > > > - * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the > > > - * first interrupt, there comes the second with current correctly > > > - * pointing to buffer 1 this time. But sometimes this second interrupt > > > - * doesn't come and the channel hangs. Clearing BUFx_RDY when > > > disabling > > > - * the channel seems to prevent the channel from hanging, but it > > > doesn't > > > - * prevent the spurious interrupt. This might also be unsafe. Think > > > - * about the IDMAC controller trying to switch to a buffer, when we > > > - * clear the ready bit, and re-enable it a moment later. > > > - */ > > > - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); > > > - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); > > > - idmac_write_ipureg(ipu, reg& ~(1UL<< channel), IPU_CHA_BUF0_RDY); > > > - > > > - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); > > > - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); > > > - idmac_write_ipureg(ipu, reg& ~(1UL<< channel), IPU_CHA_BUF1_RDY); > > > - > > > spin_unlock_irqrestore(&ipu->lock, flags); > > > > > > return 0; > > > @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void > > > *dev_id) > > > > > > /* Other interrupts do not interfere with this channel */ > > > spin_lock(&ichan->lock); > > > - if (unlikely(chan_id != IDMAC_SDC_0&& chan_id != IDMAC_SDC_1&& > > > - ((curbuf>> chan_id)& 1) == ichan->active_buffer&& > > > - !list_is_last(ichan->queue.next,&ichan->queue))) { > > > - int i = 100; > > > - > > > - /* This doesn't help. See comment in ipu_disable_channel() */ > > > - while (--i) { > > > - curbuf = idmac_read_ipureg(&ipu_data, > > > IPU_CHA_CUR_BUF); > > > - if (((curbuf>> chan_id)& 1) != ichan->active_buffer) > > > - break; > > > - cpu_relax(); > > > - } > > > - > > > - if (!i) { > > > - spin_unlock(&ichan->lock); > > > - dev_dbg(dev, > > > - "IRQ on active buffer on channel %x, active " > > > - "%d, ready %x, %x, current %x!\n", chan_id, > > > - ichan->active_buffer, ready0, ready1, curbuf); > > > - return IRQ_NONE; > > > - } else > > > - dev_dbg(dev, > > > - "Buffer deactivated on channel %x, active " > > > - "%d, ready %x, %x, current %x, rest %d!\n", > > > chan_id, > > > - ichan->active_buffer, ready0, ready1, curbuf, > > > i); > > > - } > > > - > > > if (unlikely((ichan->active_buffer&& (ready1>> chan_id)& 1) || > > > (!ichan->active_buffer&& (ready0>> chan_id)& 1) > > > )) { > > > -- > > > 1.7.1 > > > > > > > --- > > Guennadi Liakhovetski, Ph.D. > > Freelance Open-Source Software Developer > > http://www.open-technology.de/ > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-media" in > > the body of a message to majordomo at vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html > --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-04 9:37 ` Guennadi Liakhovetski @ 2011-02-04 11:37 ` Markus Niebel -1 siblings, 0 replies; 56+ messages in thread From: Markus Niebel @ 2011-02-04 11:37 UTC (permalink / raw) To: Guennadi Liakhovetski Cc: Anatolij Gustschin, linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel Hello Guennadi, sorry, forget to explicitly write it in my mail, I also applied the patch in question: dma: ipu_idmac: do not lose valid received data in the irq handler Will try the other way round without the patch later ... Thanks Markus Am 04.02.2011 10:37, schrieb Guennadi Liakhovetski: > Hi Markus > > On Fri, 4 Feb 2011, Markus Niebel wrote: > >> Hello Guennadi, hello Anatolij >> >> I've tried that with my setup: >> >> Hardware: i.MX35, special CCD camera over FPGA >> Kernel: 2.6.34 >> >> patch v4l: soc-camera: start stream after queueing the buffers is applied and >> our camera driver handles streamon / streamoff so that no sync signal / clock >> is provided, when not streaming. >> >> Our setup works with 4 buffers >> >> What we see is as we would expect plus no difference with 1st buffer: > > But you haven't applied the patch, that my reply was actually referring to > - the change to ipu_idmac.c? I think, that's the one, killing the > double-buffering. But thanks for testing the streamon patch too! > > Thanks > Guennadi > >> >> [ 206.770000] i5ccdhb i5ccdhb.0: soc_i5ccdhb_s_stream - enable 1 >> [ 207.350000] i5ccdhb i5ccdhb.0: i5ccdhb_streamon: fps (29.412) >> [ 207.370000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 207.410000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 207.440000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 207.470000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 207.540000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 207.580000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 207.610000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 207.650000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 207.680000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 207.710000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 207.750000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 207.780000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> ... >> [ 241.370000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 241.410000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 241.440000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 241.470000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 241.510000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 241.540000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 241.580000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 241.610000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 257.190000] i5ccdhb i5ccdhb.0: soc_i5ccdhb_s_stream - enable 0 >> >> >> >> Am 03.02.2011 11:09, schrieb Guennadi Liakhovetski: >>> Hi Anatolij >>> >>> On Mon, 31 Jan 2011, Anatolij Gustschin wrote: >>> >>> I'm afraid there seems to be a problem with your patch. I have no idea >>> what is causing it, but I'm just observing some wrong behaviour, that is >>> not there without it. Namely, I added a debug print to the IDMAC interrupt >>> handler >>> >>> curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); >>> err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4); >>> >>> + printk(KERN_DEBUG "%s(): IDMAC irq %d, buf %d, current %d\n", >>> __func__, >>> + irq, ichan->active_buffer, (curbuf>> chan_id)& 1); >>> >>> if (err& (1<< chan_id)) { >>> idmac_write_ipureg(&ipu_data, 1<< chan_id, IPU_INT_STAT_4); >>> >>> and without your patch I see buffer numbers correctly toggling all the >>> time like >>> >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 1 >>> idmac_interrupt(): IDMAC irq 177, buf 1, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 1 >>> idmac_interrupt(): IDMAC irq 177, buf 1, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 1 >>> ... >>> >>> Yes, the first interrupt is different, that's where I'm dropping / >>> postponing it. With your patch only N (equal to the number of buffers >>> used, I think) first interrupts toggle, then always only one buffer is >>> used: >>> >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> ... >>> >>> Verified with both capture.c and mplayer. Could you, please, verify >>> whether you get the same behaviour and what the problem could be? >>> >>> Thanks >>> Guennadi >>> >>>> Currently when two or more buffers are queued by the camera driver >>>> and so the double buffering is enabled in the idmac, we lose one >>>> frame comming from CSI since the reporting of arrival of the first >>>> frame is deferred by the DMAIC_7_EOF interrupt handler and reporting >>>> of the arrival of the last frame is not done at all. So when requesting >>>> N frames from the image sensor we actually receive N - 1 frames in >>>> user space. >>>> >>>> The reason for this behaviour is that the DMAIC_7_EOF interrupt >>>> handler misleadingly assumes that the CUR_BUF flag is pointing to the >>>> buffer used by the IDMAC. Actually it is not the case since the >>>> CUR_BUF flag will be flipped by the FSU when the FSU is sending the >>>> <TASK>_NEW_FRM_RDY signal when new frame data is delivered by the CSI. >>>> When sending this singal, FSU updates the DMA_CUR_BUF and the >>>> DMA_BUFx_RDY flags: the DMA_CUR_BUF is flipped, the DMA_BUFx_RDY >>>> is cleared, indicating that the frame data is beeing written by >>>> the IDMAC to the pointed buffer. DMA_BUFx_RDY is supposed to be >>>> set to the ready state again by the MCU, when it has handled the >>>> received data. DMAIC_7_CUR_BUF flag won't be flipped here by the >>>> IPU, so waiting for this event in the EOF interrupt handler is wrong. >>>> Actually there is no spurious interrupt as described in the comments, >>>> this is the valid DMAIC_7_EOF interrupt indicating reception of the >>>> frame from CSI. >>>> >>>> The patch removes code that waits for flipping of the DMAIC_7_CUR_BUF >>>> flag in the DMAIC_7_EOF interrupt handler. As the comment in the >>>> current code denotes, this waiting doesn't help anyway. As a result >>>> of this removal the reporting of the first arrived frame is not >>>> deferred to the time of arrival of the next frame and the drivers >>>> software flag 'ichan->active_buffer' is in sync with DMAIC_7_CUR_BUF >>>> flag, so the reception of all requested frames works. >>>> >>>> This has been verified on the hardware which is triggering the >>>> image sensor by the programmable state machine, allowing to >>>> obtain exact number of frames. On this hardware we do not tolerate >>>> losing frames. >>>> >>>> This patch also removes resetting the DMA_BUFx_RDY flags of >>>> all channels in ipu_disable_channel() since transfers on other >>>> DMA channels might be triggered by other running tasks and the >>>> buffers should always be ready for data sending or reception. >>>> >>>> Signed-off-by: Anatolij Gustschin<agust@denx.de> >>>> --- >>>> v2: >>>> Revise the commit message to provide more and correct >>>> information about the observed problem and proposed fix >>>> >>>> drivers/dma/ipu/ipu_idmac.c | 50 >>>> ------------------------------------------- >>>> 1 files changed, 0 insertions(+), 50 deletions(-) >>>> >>>> diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c >>>> index cb26ee9..c1a125e 100644 >>>> --- a/drivers/dma/ipu/ipu_idmac.c >>>> +++ b/drivers/dma/ipu/ipu_idmac.c >>>> @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, >>>> struct idmac_channel *ichan, >>>> reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); >>>> idmac_write_icreg(ipu, reg& ~chan_mask, IDMAC_CHA_EN); >>>> >>>> - /* >>>> - * Problem (observed with channel DMAIC_7): after enabling the channel >>>> - * and initialising buffers, there comes an interrupt with current >>>> still >>>> - * pointing at buffer 0, whereas it should use buffer 0 first and only >>>> - * generate an interrupt when it is done, then current should already >>>> - * point to buffer 1. This spurious interrupt also comes on channel >>>> - * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the >>>> - * first interrupt, there comes the second with current correctly >>>> - * pointing to buffer 1 this time. But sometimes this second interrupt >>>> - * doesn't come and the channel hangs. Clearing BUFx_RDY when >>>> disabling >>>> - * the channel seems to prevent the channel from hanging, but it >>>> doesn't >>>> - * prevent the spurious interrupt. This might also be unsafe. Think >>>> - * about the IDMAC controller trying to switch to a buffer, when we >>>> - * clear the ready bit, and re-enable it a moment later. >>>> - */ >>>> - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); >>>> - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); >>>> - idmac_write_ipureg(ipu, reg& ~(1UL<< channel), IPU_CHA_BUF0_RDY); >>>> - >>>> - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); >>>> - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); >>>> - idmac_write_ipureg(ipu, reg& ~(1UL<< channel), IPU_CHA_BUF1_RDY); >>>> - >>>> spin_unlock_irqrestore(&ipu->lock, flags); >>>> >>>> return 0; >>>> @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void >>>> *dev_id) >>>> >>>> /* Other interrupts do not interfere with this channel */ >>>> spin_lock(&ichan->lock); >>>> - if (unlikely(chan_id != IDMAC_SDC_0&& chan_id != IDMAC_SDC_1&& >>>> - ((curbuf>> chan_id)& 1) == ichan->active_buffer&& >>>> - !list_is_last(ichan->queue.next,&ichan->queue))) { >>>> - int i = 100; >>>> - >>>> - /* This doesn't help. See comment in ipu_disable_channel() */ >>>> - while (--i) { >>>> - curbuf = idmac_read_ipureg(&ipu_data, >>>> IPU_CHA_CUR_BUF); >>>> - if (((curbuf>> chan_id)& 1) != ichan->active_buffer) >>>> - break; >>>> - cpu_relax(); >>>> - } >>>> - >>>> - if (!i) { >>>> - spin_unlock(&ichan->lock); >>>> - dev_dbg(dev, >>>> - "IRQ on active buffer on channel %x, active " >>>> - "%d, ready %x, %x, current %x!\n", chan_id, >>>> - ichan->active_buffer, ready0, ready1, curbuf); >>>> - return IRQ_NONE; >>>> - } else >>>> - dev_dbg(dev, >>>> - "Buffer deactivated on channel %x, active " >>>> - "%d, ready %x, %x, current %x, rest %d!\n", >>>> chan_id, >>>> - ichan->active_buffer, ready0, ready1, curbuf, >>>> i); >>>> - } >>>> - >>>> if (unlikely((ichan->active_buffer&& (ready1>> chan_id)& 1) || >>>> (!ichan->active_buffer&& (ready0>> chan_id)& 1) >>>> )) { >>>> -- >>>> 1.7.1 >>>> >>> >>> --- >>> Guennadi Liakhovetski, Ph.D. >>> Freelance Open-Source Software Developer >>> http://www.open-technology.de/ >>> -- >>> To unsubscribe from this list: send the line "unsubscribe linux-media" in >>> the body of a message to majordomo@vger.kernel.org >>> More majordomo info at http://vger.kernel.org/majordomo-info.html >> > > --- > Guennadi Liakhovetski, Ph.D. > Freelance Open-Source Software Developer > http://www.open-technology.de/ > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-04 11:37 ` Markus Niebel 0 siblings, 0 replies; 56+ messages in thread From: Markus Niebel @ 2011-02-04 11:37 UTC (permalink / raw) To: linux-arm-kernel Hello Guennadi, sorry, forget to explicitly write it in my mail, I also applied the patch in question: dma: ipu_idmac: do not lose valid received data in the irq handler Will try the other way round without the patch later ... Thanks Markus Am 04.02.2011 10:37, schrieb Guennadi Liakhovetski: > Hi Markus > > On Fri, 4 Feb 2011, Markus Niebel wrote: > >> Hello Guennadi, hello Anatolij >> >> I've tried that with my setup: >> >> Hardware: i.MX35, special CCD camera over FPGA >> Kernel: 2.6.34 >> >> patch v4l: soc-camera: start stream after queueing the buffers is applied and >> our camera driver handles streamon / streamoff so that no sync signal / clock >> is provided, when not streaming. >> >> Our setup works with 4 buffers >> >> What we see is as we would expect plus no difference with 1st buffer: > > But you haven't applied the patch, that my reply was actually referring to > - the change to ipu_idmac.c? I think, that's the one, killing the > double-buffering. But thanks for testing the streamon patch too! > > Thanks > Guennadi > >> >> [ 206.770000] i5ccdhb i5ccdhb.0: soc_i5ccdhb_s_stream - enable 1 >> [ 207.350000] i5ccdhb i5ccdhb.0: i5ccdhb_streamon: fps (29.412) >> [ 207.370000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 207.410000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 207.440000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 207.470000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 207.540000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 207.580000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 207.610000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 207.650000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 207.680000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 207.710000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 207.750000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 207.780000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> ... >> [ 241.370000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 241.410000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 241.440000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 241.470000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 241.510000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 241.540000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 241.580000] idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >> [ 241.610000] idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >> [ 257.190000] i5ccdhb i5ccdhb.0: soc_i5ccdhb_s_stream - enable 0 >> >> >> >> Am 03.02.2011 11:09, schrieb Guennadi Liakhovetski: >>> Hi Anatolij >>> >>> On Mon, 31 Jan 2011, Anatolij Gustschin wrote: >>> >>> I'm afraid there seems to be a problem with your patch. I have no idea >>> what is causing it, but I'm just observing some wrong behaviour, that is >>> not there without it. Namely, I added a debug print to the IDMAC interrupt >>> handler >>> >>> curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); >>> err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4); >>> >>> + printk(KERN_DEBUG "%s(): IDMAC irq %d, buf %d, current %d\n", >>> __func__, >>> + irq, ichan->active_buffer, (curbuf>> chan_id)& 1); >>> >>> if (err& (1<< chan_id)) { >>> idmac_write_ipureg(&ipu_data, 1<< chan_id, IPU_INT_STAT_4); >>> >>> and without your patch I see buffer numbers correctly toggling all the >>> time like >>> >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 1 >>> idmac_interrupt(): IDMAC irq 177, buf 1, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 1 >>> idmac_interrupt(): IDMAC irq 177, buf 1, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 1 >>> ... >>> >>> Yes, the first interrupt is different, that's where I'm dropping / >>> postponing it. With your patch only N (equal to the number of buffers >>> used, I think) first interrupts toggle, then always only one buffer is >>> used: >>> >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 1, current 1 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> idmac_interrupt(): IDMAC irq 177, buf 0, current 0 >>> ... >>> >>> Verified with both capture.c and mplayer. Could you, please, verify >>> whether you get the same behaviour and what the problem could be? >>> >>> Thanks >>> Guennadi >>> >>>> Currently when two or more buffers are queued by the camera driver >>>> and so the double buffering is enabled in the idmac, we lose one >>>> frame comming from CSI since the reporting of arrival of the first >>>> frame is deferred by the DMAIC_7_EOF interrupt handler and reporting >>>> of the arrival of the last frame is not done at all. So when requesting >>>> N frames from the image sensor we actually receive N - 1 frames in >>>> user space. >>>> >>>> The reason for this behaviour is that the DMAIC_7_EOF interrupt >>>> handler misleadingly assumes that the CUR_BUF flag is pointing to the >>>> buffer used by the IDMAC. Actually it is not the case since the >>>> CUR_BUF flag will be flipped by the FSU when the FSU is sending the >>>> <TASK>_NEW_FRM_RDY signal when new frame data is delivered by the CSI. >>>> When sending this singal, FSU updates the DMA_CUR_BUF and the >>>> DMA_BUFx_RDY flags: the DMA_CUR_BUF is flipped, the DMA_BUFx_RDY >>>> is cleared, indicating that the frame data is beeing written by >>>> the IDMAC to the pointed buffer. DMA_BUFx_RDY is supposed to be >>>> set to the ready state again by the MCU, when it has handled the >>>> received data. DMAIC_7_CUR_BUF flag won't be flipped here by the >>>> IPU, so waiting for this event in the EOF interrupt handler is wrong. >>>> Actually there is no spurious interrupt as described in the comments, >>>> this is the valid DMAIC_7_EOF interrupt indicating reception of the >>>> frame from CSI. >>>> >>>> The patch removes code that waits for flipping of the DMAIC_7_CUR_BUF >>>> flag in the DMAIC_7_EOF interrupt handler. As the comment in the >>>> current code denotes, this waiting doesn't help anyway. As a result >>>> of this removal the reporting of the first arrived frame is not >>>> deferred to the time of arrival of the next frame and the drivers >>>> software flag 'ichan->active_buffer' is in sync with DMAIC_7_CUR_BUF >>>> flag, so the reception of all requested frames works. >>>> >>>> This has been verified on the hardware which is triggering the >>>> image sensor by the programmable state machine, allowing to >>>> obtain exact number of frames. On this hardware we do not tolerate >>>> losing frames. >>>> >>>> This patch also removes resetting the DMA_BUFx_RDY flags of >>>> all channels in ipu_disable_channel() since transfers on other >>>> DMA channels might be triggered by other running tasks and the >>>> buffers should always be ready for data sending or reception. >>>> >>>> Signed-off-by: Anatolij Gustschin<agust@denx.de> >>>> --- >>>> v2: >>>> Revise the commit message to provide more and correct >>>> information about the observed problem and proposed fix >>>> >>>> drivers/dma/ipu/ipu_idmac.c | 50 >>>> ------------------------------------------- >>>> 1 files changed, 0 insertions(+), 50 deletions(-) >>>> >>>> diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c >>>> index cb26ee9..c1a125e 100644 >>>> --- a/drivers/dma/ipu/ipu_idmac.c >>>> +++ b/drivers/dma/ipu/ipu_idmac.c >>>> @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, >>>> struct idmac_channel *ichan, >>>> reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); >>>> idmac_write_icreg(ipu, reg& ~chan_mask, IDMAC_CHA_EN); >>>> >>>> - /* >>>> - * Problem (observed with channel DMAIC_7): after enabling the channel >>>> - * and initialising buffers, there comes an interrupt with current >>>> still >>>> - * pointing at buffer 0, whereas it should use buffer 0 first and only >>>> - * generate an interrupt when it is done, then current should already >>>> - * point to buffer 1. This spurious interrupt also comes on channel >>>> - * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the >>>> - * first interrupt, there comes the second with current correctly >>>> - * pointing to buffer 1 this time. But sometimes this second interrupt >>>> - * doesn't come and the channel hangs. Clearing BUFx_RDY when >>>> disabling >>>> - * the channel seems to prevent the channel from hanging, but it >>>> doesn't >>>> - * prevent the spurious interrupt. This might also be unsafe. Think >>>> - * about the IDMAC controller trying to switch to a buffer, when we >>>> - * clear the ready bit, and re-enable it a moment later. >>>> - */ >>>> - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); >>>> - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); >>>> - idmac_write_ipureg(ipu, reg& ~(1UL<< channel), IPU_CHA_BUF0_RDY); >>>> - >>>> - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); >>>> - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); >>>> - idmac_write_ipureg(ipu, reg& ~(1UL<< channel), IPU_CHA_BUF1_RDY); >>>> - >>>> spin_unlock_irqrestore(&ipu->lock, flags); >>>> >>>> return 0; >>>> @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void >>>> *dev_id) >>>> >>>> /* Other interrupts do not interfere with this channel */ >>>> spin_lock(&ichan->lock); >>>> - if (unlikely(chan_id != IDMAC_SDC_0&& chan_id != IDMAC_SDC_1&& >>>> - ((curbuf>> chan_id)& 1) == ichan->active_buffer&& >>>> - !list_is_last(ichan->queue.next,&ichan->queue))) { >>>> - int i = 100; >>>> - >>>> - /* This doesn't help. See comment in ipu_disable_channel() */ >>>> - while (--i) { >>>> - curbuf = idmac_read_ipureg(&ipu_data, >>>> IPU_CHA_CUR_BUF); >>>> - if (((curbuf>> chan_id)& 1) != ichan->active_buffer) >>>> - break; >>>> - cpu_relax(); >>>> - } >>>> - >>>> - if (!i) { >>>> - spin_unlock(&ichan->lock); >>>> - dev_dbg(dev, >>>> - "IRQ on active buffer on channel %x, active " >>>> - "%d, ready %x, %x, current %x!\n", chan_id, >>>> - ichan->active_buffer, ready0, ready1, curbuf); >>>> - return IRQ_NONE; >>>> - } else >>>> - dev_dbg(dev, >>>> - "Buffer deactivated on channel %x, active " >>>> - "%d, ready %x, %x, current %x, rest %d!\n", >>>> chan_id, >>>> - ichan->active_buffer, ready0, ready1, curbuf, >>>> i); >>>> - } >>>> - >>>> if (unlikely((ichan->active_buffer&& (ready1>> chan_id)& 1) || >>>> (!ichan->active_buffer&& (ready0>> chan_id)& 1) >>>> )) { >>>> -- >>>> 1.7.1 >>>> >>> >>> --- >>> Guennadi Liakhovetski, Ph.D. >>> Freelance Open-Source Software Developer >>> http://www.open-technology.de/ >>> -- >>> To unsubscribe from this list: send the line "unsubscribe linux-media" in >>> the body of a message to majordomo at vger.kernel.org >>> More majordomo info at http://vger.kernel.org/majordomo-info.html >> > > --- > Guennadi Liakhovetski, Ph.D. > Freelance Open-Source Software Developer > http://www.open-technology.de/ > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-03 10:09 ` Guennadi Liakhovetski @ 2011-02-04 9:35 ` Anatolij Gustschin -1 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-02-04 9:35 UTC (permalink / raw) To: Guennadi Liakhovetski Cc: linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel Hi all, On Thu, 3 Feb 2011 11:09:54 +0100 (CET) Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: ... > Yes, the first interrupt is different, that's where I'm dropping / > postponing it. With your patch only N (equal to the number of buffers > used, I think) first interrupts toggle, then always only one buffer is > used: > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > ... > > Verified with both capture.c and mplayer. Could you, please, verify > whether you get the same behaviour and what the problem could be? Currently I'm quite busy, but I'll look at it this week end. Thanks, Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-04 9:35 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-02-04 9:35 UTC (permalink / raw) To: linux-arm-kernel Hi all, On Thu, 3 Feb 2011 11:09:54 +0100 (CET) Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: ... > Yes, the first interrupt is different, that's where I'm dropping / > postponing it. With your patch only N (equal to the number of buffers > used, I think) first interrupts toggle, then always only one buffer is > used: > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > ... > > Verified with both capture.c and mplayer. Could you, please, verify > whether you get the same behaviour and what the problem could be? Currently I'm quite busy, but I'll look at it this week end. Thanks, Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-03 10:09 ` Guennadi Liakhovetski @ 2011-02-05 13:35 ` Anatolij Gustschin -1 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-02-05 13:35 UTC (permalink / raw) To: Guennadi Liakhovetski Cc: linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel Hi Guennadi, On Thu, 3 Feb 2011 11:09:54 +0100 (CET) Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > Hi Anatolij > > On Mon, 31 Jan 2011, Anatolij Gustschin wrote: > > I'm afraid there seems to be a problem with your patch. I have no idea > what is causing it, but I'm just observing some wrong behaviour, that is > not there without it. Namely, I added a debug print to the IDMAC interrupt > handler > > curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); > err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4); > > + printk(KERN_DEBUG "%s(): IDMAC irq %d, buf %d, current %d\n", __func__, > + irq, ichan->active_buffer, (curbuf >> chan_id) & 1); > > if (err & (1 << chan_id)) { > idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4); > > and without your patch I see buffer numbers correctly toggling all the > time like > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > ... > > Yes, the first interrupt is different, that's where I'm dropping / > postponing it. With your patch only N (equal to the number of buffers > used, I think) first interrupts toggle, then always only one buffer is > used: > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > ... > > Verified with both capture.c and mplayer. Could you, please, verify > whether you get the same behaviour and what the problem could be? Now I did some further testing with idmac patch applied and with added debug print in the IDMAC interrupt handler. There is no problem. Testing with capture.c (4 buffers used as default) shows that buffer numbers toggle correctly for all 100 captured frames: ... mx3-camera mx3-camera.0: MX3 Camera driver attached to camera 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 ... idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 mx3-camera mx3-camera.0: MX3 Camera driver detached from camera 0 Also testing with my test application didn't show any problem. When using more than 1 buffer (tested with 2, 3 and 4 queued buffers) double buffering works as expected and frame numbers toggle correctly. Capturing 30 frames produce: mx3-camera mx3-camera.0: MX3 Camera driver attached to camera 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 mx3-camera mx3-camera.0: MX3 Camera driver detached from camera 0 Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-05 13:35 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-02-05 13:35 UTC (permalink / raw) To: linux-arm-kernel Hi Guennadi, On Thu, 3 Feb 2011 11:09:54 +0100 (CET) Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > Hi Anatolij > > On Mon, 31 Jan 2011, Anatolij Gustschin wrote: > > I'm afraid there seems to be a problem with your patch. I have no idea > what is causing it, but I'm just observing some wrong behaviour, that is > not there without it. Namely, I added a debug print to the IDMAC interrupt > handler > > curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); > err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4); > > + printk(KERN_DEBUG "%s(): IDMAC irq %d, buf %d, current %d\n", __func__, > + irq, ichan->active_buffer, (curbuf >> chan_id) & 1); > > if (err & (1 << chan_id)) { > idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4); > > and without your patch I see buffer numbers correctly toggling all the > time like > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > ... > > Yes, the first interrupt is different, that's where I'm dropping / > postponing it. With your patch only N (equal to the number of buffers > used, I think) first interrupts toggle, then always only one buffer is > used: > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > ... > > Verified with both capture.c and mplayer. Could you, please, verify > whether you get the same behaviour and what the problem could be? Now I did some further testing with idmac patch applied and with added debug print in the IDMAC interrupt handler. There is no problem. Testing with capture.c (4 buffers used as default) shows that buffer numbers toggle correctly for all 100 captured frames: ... mx3-camera mx3-camera.0: MX3 Camera driver attached to camera 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 ... idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 mx3-camera mx3-camera.0: MX3 Camera driver detached from camera 0 Also testing with my test application didn't show any problem. When using more than 1 buffer (tested with 2, 3 and 4 queued buffers) double buffering works as expected and frame numbers toggle correctly. Capturing 30 frames produce: mx3-camera mx3-camera.0: MX3 Camera driver attached to camera 0 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 idmac_interrupt(): IDMAC irq 177, buf 0, current 0 idmac_interrupt(): IDMAC irq 177, buf 1, current 1 mx3-camera mx3-camera.0: MX3 Camera driver detached from camera 0 Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-05 13:35 ` Anatolij Gustschin @ 2011-02-05 16:36 ` Guennadi Liakhovetski -1 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-05 16:36 UTC (permalink / raw) To: Anatolij Gustschin Cc: linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel On Sat, 5 Feb 2011, Anatolij Gustschin wrote: > Hi Guennadi, > > On Thu, 3 Feb 2011 11:09:54 +0100 (CET) > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > > > Hi Anatolij > > > > On Mon, 31 Jan 2011, Anatolij Gustschin wrote: > > > > I'm afraid there seems to be a problem with your patch. I have no idea > > what is causing it, but I'm just observing some wrong behaviour, that is > > not there without it. Namely, I added a debug print to the IDMAC interrupt > > handler > > > > curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); > > err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4); > > > > + printk(KERN_DEBUG "%s(): IDMAC irq %d, buf %d, current %d\n", __func__, > > + irq, ichan->active_buffer, (curbuf >> chan_id) & 1); > > > > if (err & (1 << chan_id)) { > > idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4); > > > > and without your patch I see buffer numbers correctly toggling all the > > time like > > > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > > ... > > > > Yes, the first interrupt is different, that's where I'm dropping / > > postponing it. With your patch only N (equal to the number of buffers > > used, I think) first interrupts toggle, then always only one buffer is > > used: > > > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > ... > > > > Verified with both capture.c and mplayer. Could you, please, verify > > whether you get the same behaviour and what the problem could be? > > Now I did some further testing with idmac patch applied and with > added debug print in the IDMAC interrupt handler. There is no problem. > Testing with capture.c (4 buffers used as default) shows that buffer > numbers toggle correctly for all 100 captured frames: Hm, interesting, I'll have to look at my testing in more detail then (once back from FOSDEM). Could you maybe try mplayer too? Thanks Guennadi > ... > mx3-camera mx3-camera.0: MX3 Camera driver attached to camera 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > ... > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > mx3-camera mx3-camera.0: MX3 Camera driver detached from camera 0 > > Also testing with my test application didn't show any problem. > When using more than 1 buffer (tested with 2, 3 and 4 queued > buffers) double buffering works as expected and frame numbers > toggle correctly. Capturing 30 frames produce: > > mx3-camera mx3-camera.0: MX3 Camera driver attached to camera 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > mx3-camera mx3-camera.0: MX3 Camera driver detached from camera 0 > > Anatolij > --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-05 16:36 ` Guennadi Liakhovetski 0 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-05 16:36 UTC (permalink / raw) To: linux-arm-kernel On Sat, 5 Feb 2011, Anatolij Gustschin wrote: > Hi Guennadi, > > On Thu, 3 Feb 2011 11:09:54 +0100 (CET) > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > > > Hi Anatolij > > > > On Mon, 31 Jan 2011, Anatolij Gustschin wrote: > > > > I'm afraid there seems to be a problem with your patch. I have no idea > > what is causing it, but I'm just observing some wrong behaviour, that is > > not there without it. Namely, I added a debug print to the IDMAC interrupt > > handler > > > > curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); > > err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4); > > > > + printk(KERN_DEBUG "%s(): IDMAC irq %d, buf %d, current %d\n", __func__, > > + irq, ichan->active_buffer, (curbuf >> chan_id) & 1); > > > > if (err & (1 << chan_id)) { > > idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4); > > > > and without your patch I see buffer numbers correctly toggling all the > > time like > > > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 1 > > ... > > > > Yes, the first interrupt is different, that's where I'm dropping / > > postponing it. With your patch only N (equal to the number of buffers > > used, I think) first interrupts toggle, then always only one buffer is > > used: > > > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > > ... > > > > Verified with both capture.c and mplayer. Could you, please, verify > > whether you get the same behaviour and what the problem could be? > > Now I did some further testing with idmac patch applied and with > added debug print in the IDMAC interrupt handler. There is no problem. > Testing with capture.c (4 buffers used as default) shows that buffer > numbers toggle correctly for all 100 captured frames: Hm, interesting, I'll have to look at my testing in more detail then (once back from FOSDEM). Could you maybe try mplayer too? Thanks Guennadi > ... > mx3-camera mx3-camera.0: MX3 Camera driver attached to camera 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > ... > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > mx3-camera mx3-camera.0: MX3 Camera driver detached from camera 0 > > Also testing with my test application didn't show any problem. > When using more than 1 buffer (tested with 2, 3 and 4 queued > buffers) double buffering works as expected and frame numbers > toggle correctly. Capturing 30 frames produce: > > mx3-camera mx3-camera.0: MX3 Camera driver attached to camera 0 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > idmac_interrupt(): IDMAC irq 177, buf 0, current 0 > idmac_interrupt(): IDMAC irq 177, buf 1, current 1 > mx3-camera mx3-camera.0: MX3 Camera driver detached from camera 0 > > Anatolij > --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-05 16:36 ` Guennadi Liakhovetski @ 2011-02-05 20:04 ` Anatolij Gustschin -1 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-02-05 20:04 UTC (permalink / raw) To: Guennadi Liakhovetski Cc: linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel On Sat, 5 Feb 2011 17:36:37 +0100 (CET) Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: ... > > > Verified with both capture.c and mplayer. Could you, please, verify > > > whether you get the same behaviour and what the problem could be? > > > > Now I did some further testing with idmac patch applied and with > > added debug print in the IDMAC interrupt handler. There is no problem. > > Testing with capture.c (4 buffers used as default) shows that buffer > > numbers toggle correctly for all 100 captured frames: > > Hm, interesting, I'll have to look at my testing in more detail then > (once back from FOSDEM). Could you maybe try mplayer too? I can't try mplayer since I don't have mplayer setup for this. But looking at the mplayer source I don't see why it should behave differently. Depending on mode mplayer queues 2 or 6 buffers. Testing with my test app with 6 queued buffers shows no issues, here the buffer numbers toggle correctly, too. Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-05 20:04 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-02-05 20:04 UTC (permalink / raw) To: linux-arm-kernel On Sat, 5 Feb 2011 17:36:37 +0100 (CET) Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: ... > > > Verified with both capture.c and mplayer. Could you, please, verify > > > whether you get the same behaviour and what the problem could be? > > > > Now I did some further testing with idmac patch applied and with > > added debug print in the IDMAC interrupt handler. There is no problem. > > Testing with capture.c (4 buffers used as default) shows that buffer > > numbers toggle correctly for all 100 captured frames: > > Hm, interesting, I'll have to look at my testing in more detail then > (once back from FOSDEM). Could you maybe try mplayer too? I can't try mplayer since I don't have mplayer setup for this. But looking at the mplayer source I don't see why it should behave differently. Depending on mode mplayer queues 2 or 6 buffers. Testing with my test app with 6 queued buffers shows no issues, here the buffer numbers toggle correctly, too. Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-05 20:04 ` Anatolij Gustschin @ 2011-02-07 11:09 ` Guennadi Liakhovetski -1 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-07 11:09 UTC (permalink / raw) To: Anatolij Gustschin Cc: linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel On Sat, 5 Feb 2011, Anatolij Gustschin wrote: > On Sat, 5 Feb 2011 17:36:37 +0100 (CET) > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > ... > > > > Verified with both capture.c and mplayer. Could you, please, verify > > > > whether you get the same behaviour and what the problem could be? > > > > > > Now I did some further testing with idmac patch applied and with > > > added debug print in the IDMAC interrupt handler. There is no problem. > > > Testing with capture.c (4 buffers used as default) shows that buffer > > > numbers toggle correctly for all 100 captured frames: > > > > Hm, interesting, I'll have to look at my testing in more detail then > > (once back from FOSDEM). Could you maybe try mplayer too? > > I can't try mplayer since I don't have mplayer setup for this. > But looking at the mplayer source I don't see why it should > behave differently. Depending on mode mplayer queues 2 or 6 > buffers. Testing with my test app with 6 queued buffers shows > no issues, here the buffer numbers toggle correctly, too. Ok, I've done a couple more tests. With larger frames, and, therefore lower fps - yes, with your patch buffers toggle correctly. Whereas in my tests with smaller frames and higher fps either only one buffer is used, or one is used much more often, than the other, e.g., 0 0 0 1 0 0 0 1 0... Could you try to verify? Without your patch with any fps buffers toggle consistently. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-07 11:09 ` Guennadi Liakhovetski 0 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-07 11:09 UTC (permalink / raw) To: linux-arm-kernel On Sat, 5 Feb 2011, Anatolij Gustschin wrote: > On Sat, 5 Feb 2011 17:36:37 +0100 (CET) > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > ... > > > > Verified with both capture.c and mplayer. Could you, please, verify > > > > whether you get the same behaviour and what the problem could be? > > > > > > Now I did some further testing with idmac patch applied and with > > > added debug print in the IDMAC interrupt handler. There is no problem. > > > Testing with capture.c (4 buffers used as default) shows that buffer > > > numbers toggle correctly for all 100 captured frames: > > > > Hm, interesting, I'll have to look at my testing in more detail then > > (once back from FOSDEM). Could you maybe try mplayer too? > > I can't try mplayer since I don't have mplayer setup for this. > But looking at the mplayer source I don't see why it should > behave differently. Depending on mode mplayer queues 2 or 6 > buffers. Testing with my test app with 6 queued buffers shows > no issues, here the buffer numbers toggle correctly, too. Ok, I've done a couple more tests. With larger frames, and, therefore lower fps - yes, with your patch buffers toggle correctly. Whereas in my tests with smaller frames and higher fps either only one buffer is used, or one is used much more often, than the other, e.g., 0 0 0 1 0 0 0 1 0... Could you try to verify? Without your patch with any fps buffers toggle consistently. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-07 11:09 ` Guennadi Liakhovetski @ 2011-02-07 11:21 ` Anatolij Gustschin -1 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-02-07 11:21 UTC (permalink / raw) To: Guennadi Liakhovetski Cc: linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel On Mon, 7 Feb 2011 12:09:15 +0100 (CET) Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: ... > > I can't try mplayer since I don't have mplayer setup for this. > > But looking at the mplayer source I don't see why it should > > behave differently. Depending on mode mplayer queues 2 or 6 > > buffers. Testing with my test app with 6 queued buffers shows > > no issues, here the buffer numbers toggle correctly, too. > > Ok, I've done a couple more tests. With larger frames, and, therefore > lower fps - yes, with your patch buffers toggle correctly. Whereas in my > tests with smaller frames and higher fps either only one buffer is used, > or one is used much more often, than the other, e.g., 0 0 0 1 0 0 0 1 0... > Could you try to verify? Without your patch with any fps buffers toggle > consistently. How small are the frames in you test? What is the highest fps value in your test? Thanks, Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-07 11:21 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-02-07 11:21 UTC (permalink / raw) To: linux-arm-kernel On Mon, 7 Feb 2011 12:09:15 +0100 (CET) Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: ... > > I can't try mplayer since I don't have mplayer setup for this. > > But looking at the mplayer source I don't see why it should > > behave differently. Depending on mode mplayer queues 2 or 6 > > buffers. Testing with my test app with 6 queued buffers shows > > no issues, here the buffer numbers toggle correctly, too. > > Ok, I've done a couple more tests. With larger frames, and, therefore > lower fps - yes, with your patch buffers toggle correctly. Whereas in my > tests with smaller frames and higher fps either only one buffer is used, > or one is used much more often, than the other, e.g., 0 0 0 1 0 0 0 1 0... > Could you try to verify? Without your patch with any fps buffers toggle > consistently. How small are the frames in you test? What is the highest fps value in your test? Thanks, Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-07 11:21 ` Anatolij Gustschin @ 2011-02-07 11:35 ` Guennadi Liakhovetski -1 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-07 11:35 UTC (permalink / raw) To: Anatolij Gustschin Cc: linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel On Mon, 7 Feb 2011, Anatolij Gustschin wrote: > On Mon, 7 Feb 2011 12:09:15 +0100 (CET) > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > ... > > > I can't try mplayer since I don't have mplayer setup for this. > > > But looking at the mplayer source I don't see why it should > > > behave differently. Depending on mode mplayer queues 2 or 6 > > > buffers. Testing with my test app with 6 queued buffers shows > > > no issues, here the buffer numbers toggle correctly, too. > > > > Ok, I've done a couple more tests. With larger frames, and, therefore > > lower fps - yes, with your patch buffers toggle correctly. Whereas in my > > tests with smaller frames and higher fps either only one buffer is used, > > or one is used much more often, than the other, e.g., 0 0 0 1 0 0 0 1 0... > > Could you try to verify? Without your patch with any fps buffers toggle > > consistently. > > How small are the frames in you test? What is the highest fps value in > your test? QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. Just try different frams sizes, go down to 64x48 or something. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-07 11:35 ` Guennadi Liakhovetski 0 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-07 11:35 UTC (permalink / raw) To: linux-arm-kernel On Mon, 7 Feb 2011, Anatolij Gustschin wrote: > On Mon, 7 Feb 2011 12:09:15 +0100 (CET) > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > ... > > > I can't try mplayer since I don't have mplayer setup for this. > > > But looking at the mplayer source I don't see why it should > > > behave differently. Depending on mode mplayer queues 2 or 6 > > > buffers. Testing with my test app with 6 queued buffers shows > > > no issues, here the buffer numbers toggle correctly, too. > > > > Ok, I've done a couple more tests. With larger frames, and, therefore > > lower fps - yes, with your patch buffers toggle correctly. Whereas in my > > tests with smaller frames and higher fps either only one buffer is used, > > or one is used much more often, than the other, e.g., 0 0 0 1 0 0 0 1 0... > > Could you try to verify? Without your patch with any fps buffers toggle > > consistently. > > How small are the frames in you test? What is the highest fps value in > your test? QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. Just try different frams sizes, go down to 64x48 or something. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-07 11:35 ` Guennadi Liakhovetski @ 2011-02-07 13:01 ` Detlev Zundel -1 siblings, 0 replies; 56+ messages in thread From: Detlev Zundel @ 2011-02-07 13:01 UTC (permalink / raw) To: Guennadi Liakhovetski Cc: Anatolij Gustschin, linux-media, linux-arm-kernel, Dan Williams, Markus Niebel Hi Guennadi, >> How small are the frames in you test? What is the highest fps value in >> your test? > > QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. > Just try different frams sizes, go down to 64x48 or something. Is this a "real" usage scenario? It feels that this is not what most users will do and it certainly is not relevant for our application. Is it possible that if you are interested in such a scenario that you do the testing? We have spent quite a lot of time to fix the driver for real (well full frame) capturing already and I am relucatant to spend more time for corner cases. Maybe we should document this as "known limitations" of the setup? What do you think? I'll much rather have a driver working for real world scenarios than for marginal test cases. Thanks Detlev -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-40 Fax: (+49)-8142-66989-80 Email: dzu@denx.de ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-07 13:01 ` Detlev Zundel 0 siblings, 0 replies; 56+ messages in thread From: Detlev Zundel @ 2011-02-07 13:01 UTC (permalink / raw) To: linux-arm-kernel Hi Guennadi, >> How small are the frames in you test? What is the highest fps value in >> your test? > > QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. > Just try different frams sizes, go down to 64x48 or something. Is this a "real" usage scenario? It feels that this is not what most users will do and it certainly is not relevant for our application. Is it possible that if you are interested in such a scenario that you do the testing? We have spent quite a lot of time to fix the driver for real (well full frame) capturing already and I am relucatant to spend more time for corner cases. Maybe we should document this as "known limitations" of the setup? What do you think? I'll much rather have a driver working for real world scenarios than for marginal test cases. Thanks Detlev -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-40 Fax: (+49)-8142-66989-80 Email: dzu at denx.de ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-07 13:01 ` Detlev Zundel @ 2011-02-07 13:35 ` Guennadi Liakhovetski -1 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-07 13:35 UTC (permalink / raw) To: Detlev Zundel Cc: Anatolij Gustschin, linux-media, linux-arm-kernel, Dan Williams, Markus Niebel Hi Detlev On Mon, 7 Feb 2011, Detlev Zundel wrote: > Hi Guennadi, > > >> How small are the frames in you test? What is the highest fps value in > >> your test? > > > > QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. > > Just try different frams sizes, go down to 64x48 or something. > > Is this a "real" usage scenario? It feels that this is not what most > users will do and it certainly is not relevant for our application. QVGA at 25 / 50 / 60 fps is _certainly_ very much a real-life scenario. > Is it possible that if you are interested in such a scenario that you do > the testing? We have spent quite a lot of time to fix the driver for > real (well full frame) capturing already and I am relucatant to spend > more time for corner cases. Maybe we should document this as "known > limitations" of the setup? What do you think? I'll much rather have a > driver working for real world scenarios than for marginal test cases. I am interested in avoiding regressions. In principle, this is a DMA driver, which I am not maintaining. Dan asked for my ack, so, I tested it and found an issue, which I would prefer to have resolved before committing. Of course, I don't have a decisive voice in this matter, so, the patch can also be merged without my ack. Otherwise - of course you don't have to continue testing, I will try to look at the issue as the time permits, and Dan will have to decide, whether he is prepared to commit this patch in its present form, or he would prefer this issue to be clarified. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-07 13:35 ` Guennadi Liakhovetski 0 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-07 13:35 UTC (permalink / raw) To: linux-arm-kernel Hi Detlev On Mon, 7 Feb 2011, Detlev Zundel wrote: > Hi Guennadi, > > >> How small are the frames in you test? What is the highest fps value in > >> your test? > > > > QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. > > Just try different frams sizes, go down to 64x48 or something. > > Is this a "real" usage scenario? It feels that this is not what most > users will do and it certainly is not relevant for our application. QVGA at 25 / 50 / 60 fps is _certainly_ very much a real-life scenario. > Is it possible that if you are interested in such a scenario that you do > the testing? We have spent quite a lot of time to fix the driver for > real (well full frame) capturing already and I am relucatant to spend > more time for corner cases. Maybe we should document this as "known > limitations" of the setup? What do you think? I'll much rather have a > driver working for real world scenarios than for marginal test cases. I am interested in avoiding regressions. In principle, this is a DMA driver, which I am not maintaining. Dan asked for my ack, so, I tested it and found an issue, which I would prefer to have resolved before committing. Of course, I don't have a decisive voice in this matter, so, the patch can also be merged without my ack. Otherwise - of course you don't have to continue testing, I will try to look at the issue as the time permits, and Dan will have to decide, whether he is prepared to commit this patch in its present form, or he would prefer this issue to be clarified. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-07 13:35 ` Guennadi Liakhovetski @ 2011-02-07 14:43 ` Detlev Zundel -1 siblings, 0 replies; 56+ messages in thread From: Detlev Zundel @ 2011-02-07 14:43 UTC (permalink / raw) To: Guennadi Liakhovetski Cc: Anatolij Gustschin, linux-media, linux-arm-kernel, Dan Williams, Markus Niebel Hi Guennadi, > Hi Detlev > > On Mon, 7 Feb 2011, Detlev Zundel wrote: > >> Hi Guennadi, >> >> >> How small are the frames in you test? What is the highest fps value in >> >> your test? >> > >> > QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. >> > Just try different frams sizes, go down to 64x48 or something. >> >> Is this a "real" usage scenario? It feels that this is not what most >> users will do and it certainly is not relevant for our application. > > QVGA at 25 / 50 / 60 fps is _certainly_ very much a real-life scenario. Yes, sure. It was the 64x48 pixel you suggested which I believe to be of doubtful value here. >> Is it possible that if you are interested in such a scenario that you do >> the testing? We have spent quite a lot of time to fix the driver for >> real (well full frame) capturing already and I am relucatant to spend >> more time for corner cases. Maybe we should document this as "known >> limitations" of the setup? What do you think? I'll much rather have a >> driver working for real world scenarios than for marginal test cases. > > I am interested in avoiding regressions. In principle, this is a DMA > driver, which I am not maintaining. Dan asked for my ack, so, I tested it > and found an issue, which I would prefer to have resolved before > committing. Of course, I don't have a decisive voice in this matter, so, > the patch can also be merged without my ack. Otherwise - of course you > don't have to continue testing, I will try to look at the issue as the > time permits, and Dan will have to decide, whether he is prepared to > commit this patch in its present form, or he would prefer this issue to be > clarified. I'm fully in line with not wanting any regressions. But is it a regression if two independent testers report that the patch _improves_ the current situation? As was shown by Anatolijs log, the current driver certainly has a bug with respect to the handling of individual frames. This buggy behaviour only never showed up because nobody used the driver on such a granularity. We certainly appreciate if you can look into your scenario. Thanks Detlev -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-40 Fax: (+49)-8142-66989-80 Email: dzu@denx.de ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-07 14:43 ` Detlev Zundel 0 siblings, 0 replies; 56+ messages in thread From: Detlev Zundel @ 2011-02-07 14:43 UTC (permalink / raw) To: linux-arm-kernel Hi Guennadi, > Hi Detlev > > On Mon, 7 Feb 2011, Detlev Zundel wrote: > >> Hi Guennadi, >> >> >> How small are the frames in you test? What is the highest fps value in >> >> your test? >> > >> > QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. >> > Just try different frams sizes, go down to 64x48 or something. >> >> Is this a "real" usage scenario? It feels that this is not what most >> users will do and it certainly is not relevant for our application. > > QVGA at 25 / 50 / 60 fps is _certainly_ very much a real-life scenario. Yes, sure. It was the 64x48 pixel you suggested which I believe to be of doubtful value here. >> Is it possible that if you are interested in such a scenario that you do >> the testing? We have spent quite a lot of time to fix the driver for >> real (well full frame) capturing already and I am relucatant to spend >> more time for corner cases. Maybe we should document this as "known >> limitations" of the setup? What do you think? I'll much rather have a >> driver working for real world scenarios than for marginal test cases. > > I am interested in avoiding regressions. In principle, this is a DMA > driver, which I am not maintaining. Dan asked for my ack, so, I tested it > and found an issue, which I would prefer to have resolved before > committing. Of course, I don't have a decisive voice in this matter, so, > the patch can also be merged without my ack. Otherwise - of course you > don't have to continue testing, I will try to look at the issue as the > time permits, and Dan will have to decide, whether he is prepared to > commit this patch in its present form, or he would prefer this issue to be > clarified. I'm fully in line with not wanting any regressions. But is it a regression if two independent testers report that the patch _improves_ the current situation? As was shown by Anatolijs log, the current driver certainly has a bug with respect to the handling of individual frames. This buggy behaviour only never showed up because nobody used the driver on such a granularity. We certainly appreciate if you can look into your scenario. Thanks Detlev -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-40 Fax: (+49)-8142-66989-80 Email: dzu at denx.de ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-07 11:35 ` Guennadi Liakhovetski @ 2011-02-07 13:45 ` Anatolij Gustschin -1 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-02-07 13:45 UTC (permalink / raw) To: Guennadi Liakhovetski Cc: linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel On Mon, 7 Feb 2011 12:35:44 +0100 (CET) Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > On Mon, 7 Feb 2011, Anatolij Gustschin wrote: > > > On Mon, 7 Feb 2011 12:09:15 +0100 (CET) > > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > > ... > > > > I can't try mplayer since I don't have mplayer setup for this. > > > > But looking at the mplayer source I don't see why it should > > > > behave differently. Depending on mode mplayer queues 2 or 6 > > > > buffers. Testing with my test app with 6 queued buffers shows > > > > no issues, here the buffer numbers toggle correctly, too. > > > > > > Ok, I've done a couple more tests. With larger frames, and, therefore > > > lower fps - yes, with your patch buffers toggle correctly. Whereas in my > > > tests with smaller frames and higher fps either only one buffer is used, > > > or one is used much more often, than the other, e.g., 0 0 0 1 0 0 0 1 0... > > > Could you try to verify? Without your patch with any fps buffers toggle > > > consistently. > > > > How small are the frames in you test? What is the highest fps value in > > your test? > > QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. > Just try different frams sizes, go down to 64x48 or something. Testing of 960x243 frames at 30 fps has been done during all my previous tests. I didn't see any issues at 30 fps. Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-07 13:45 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-02-07 13:45 UTC (permalink / raw) To: linux-arm-kernel On Mon, 7 Feb 2011 12:35:44 +0100 (CET) Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > On Mon, 7 Feb 2011, Anatolij Gustschin wrote: > > > On Mon, 7 Feb 2011 12:09:15 +0100 (CET) > > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > > ... > > > > I can't try mplayer since I don't have mplayer setup for this. > > > > But looking at the mplayer source I don't see why it should > > > > behave differently. Depending on mode mplayer queues 2 or 6 > > > > buffers. Testing with my test app with 6 queued buffers shows > > > > no issues, here the buffer numbers toggle correctly, too. > > > > > > Ok, I've done a couple more tests. With larger frames, and, therefore > > > lower fps - yes, with your patch buffers toggle correctly. Whereas in my > > > tests with smaller frames and higher fps either only one buffer is used, > > > or one is used much more often, than the other, e.g., 0 0 0 1 0 0 0 1 0... > > > Could you try to verify? Without your patch with any fps buffers toggle > > > consistently. > > > > How small are the frames in you test? What is the highest fps value in > > your test? > > QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. > Just try different frams sizes, go down to 64x48 or something. Testing of 960x243 frames at 30 fps has been done during all my previous tests. I didn't see any issues at 30 fps. Anatolij ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-07 13:45 ` Anatolij Gustschin @ 2011-02-07 14:00 ` Guennadi Liakhovetski -1 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-07 14:00 UTC (permalink / raw) To: Anatolij Gustschin Cc: linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel On Mon, 7 Feb 2011, Anatolij Gustschin wrote: > On Mon, 7 Feb 2011 12:35:44 +0100 (CET) > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > > > On Mon, 7 Feb 2011, Anatolij Gustschin wrote: > > > > > On Mon, 7 Feb 2011 12:09:15 +0100 (CET) > > > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > > > ... > > > > > I can't try mplayer since I don't have mplayer setup for this. > > > > > But looking at the mplayer source I don't see why it should > > > > > behave differently. Depending on mode mplayer queues 2 or 6 > > > > > buffers. Testing with my test app with 6 queued buffers shows > > > > > no issues, here the buffer numbers toggle correctly, too. > > > > > > > > Ok, I've done a couple more tests. With larger frames, and, therefore > > > > lower fps - yes, with your patch buffers toggle correctly. Whereas in my > > > > tests with smaller frames and higher fps either only one buffer is used, > > > > or one is used much more often, than the other, e.g., 0 0 0 1 0 0 0 1 0... > > > > Could you try to verify? Without your patch with any fps buffers toggle > > > > consistently. > > > > > > How small are the frames in you test? What is the highest fps value in > > > your test? > > > > QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. > > Just try different frams sizes, go down to 64x48 or something. > > Testing of 960x243 frames at 30 fps has been done during all my previous > tests. I didn't see any issues at 30 fps. Thanks for the clarification. You certainly realise, that your frame is 3 times as large as mine. Sorry for not mentioning this before, I do appreciate your effort, and have a generally positive feeling at least regarding your IDMAC patch, but I don't want to just trust my feeling, that's why I tried to study the patch a bit more carefully. I also understand that you don't have infinite time to dedicate to this work. Neither do I. So, I will try as good as I can to try to find out the reason for this behaviour, any help from your side is greatly appreciated. But if we don't clarify this before the 2.6.39 merge window, I'm not sure, whether it would be smart to commit the patch as is. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-07 14:00 ` Guennadi Liakhovetski 0 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-07 14:00 UTC (permalink / raw) To: linux-arm-kernel On Mon, 7 Feb 2011, Anatolij Gustschin wrote: > On Mon, 7 Feb 2011 12:35:44 +0100 (CET) > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > > > On Mon, 7 Feb 2011, Anatolij Gustschin wrote: > > > > > On Mon, 7 Feb 2011 12:09:15 +0100 (CET) > > > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > > > ... > > > > > I can't try mplayer since I don't have mplayer setup for this. > > > > > But looking at the mplayer source I don't see why it should > > > > > behave differently. Depending on mode mplayer queues 2 or 6 > > > > > buffers. Testing with my test app with 6 queued buffers shows > > > > > no issues, here the buffer numbers toggle correctly, too. > > > > > > > > Ok, I've done a couple more tests. With larger frames, and, therefore > > > > lower fps - yes, with your patch buffers toggle correctly. Whereas in my > > > > tests with smaller frames and higher fps either only one buffer is used, > > > > or one is used much more often, than the other, e.g., 0 0 0 1 0 0 0 1 0... > > > > Could you try to verify? Without your patch with any fps buffers toggle > > > > consistently. > > > > > > How small are the frames in you test? What is the highest fps value in > > > your test? > > > > QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. > > Just try different frams sizes, go down to 64x48 or something. > > Testing of 960x243 frames at 30 fps has been done during all my previous > tests. I didn't see any issues at 30 fps. Thanks for the clarification. You certainly realise, that your frame is 3 times as large as mine. Sorry for not mentioning this before, I do appreciate your effort, and have a generally positive feeling at least regarding your IDMAC patch, but I don't want to just trust my feeling, that's why I tried to study the patch a bit more carefully. I also understand that you don't have infinite time to dedicate to this work. Neither do I. So, I will try as good as I can to try to find out the reason for this behaviour, any help from your side is greatly appreciated. But if we don't clarify this before the 2.6.39 merge window, I'm not sure, whether it would be smart to commit the patch as is. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-07 13:45 ` Anatolij Gustschin @ 2011-02-07 16:49 ` Guennadi Liakhovetski -1 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-07 16:49 UTC (permalink / raw) To: Anatolij Gustschin Cc: linux-media, linux-arm-kernel, Dan Williams, Detlev Zundel, Markus Niebel On Mon, 7 Feb 2011, Anatolij Gustschin wrote: > On Mon, 7 Feb 2011 12:35:44 +0100 (CET) > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > > > On Mon, 7 Feb 2011, Anatolij Gustschin wrote: > > > > > On Mon, 7 Feb 2011 12:09:15 +0100 (CET) > > > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > > > ... > > > > > I can't try mplayer since I don't have mplayer setup for this. > > > > > But looking at the mplayer source I don't see why it should > > > > > behave differently. Depending on mode mplayer queues 2 or 6 > > > > > buffers. Testing with my test app with 6 queued buffers shows > > > > > no issues, here the buffer numbers toggle correctly, too. > > > > > > > > Ok, I've done a couple more tests. With larger frames, and, therefore > > > > lower fps - yes, with your patch buffers toggle correctly. Whereas in my > > > > tests with smaller frames and higher fps either only one buffer is used, > > > > or one is used much more often, than the other, e.g., 0 0 0 1 0 0 0 1 0... > > > > Could you try to verify? Without your patch with any fps buffers toggle > > > > consistently. > > > > > > How small are the frames in you test? What is the highest fps value in > > > your test? > > > > QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. > > Just try different frams sizes, go down to 64x48 or something. > > Testing of 960x243 frames at 30 fps has been done during all my previous > tests. I didn't see any issues at 30 fps. Ok, I've found the reason. Buffer number repeats, when there is an underrun, which is happening in my tests, when frames are arriving quickly enough, but the user-space is not fast enough to process them, e.g., when it is writing them to files over NFS or even just displaying on the LCD. Without your patch these underruns happen just as well, they just don't get recognised, because there's always one buffer delayed, so, the queue is never empty. Dan, please add my Reviewed-(and-tested-)by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-07 16:49 ` Guennadi Liakhovetski 0 siblings, 0 replies; 56+ messages in thread From: Guennadi Liakhovetski @ 2011-02-07 16:49 UTC (permalink / raw) To: linux-arm-kernel On Mon, 7 Feb 2011, Anatolij Gustschin wrote: > On Mon, 7 Feb 2011 12:35:44 +0100 (CET) > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > > > On Mon, 7 Feb 2011, Anatolij Gustschin wrote: > > > > > On Mon, 7 Feb 2011 12:09:15 +0100 (CET) > > > Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > > > ... > > > > > I can't try mplayer since I don't have mplayer setup for this. > > > > > But looking at the mplayer source I don't see why it should > > > > > behave differently. Depending on mode mplayer queues 2 or 6 > > > > > buffers. Testing with my test app with 6 queued buffers shows > > > > > no issues, here the buffer numbers toggle correctly, too. > > > > > > > > Ok, I've done a couple more tests. With larger frames, and, therefore > > > > lower fps - yes, with your patch buffers toggle correctly. Whereas in my > > > > tests with smaller frames and higher fps either only one buffer is used, > > > > or one is used much more often, than the other, e.g., 0 0 0 1 0 0 0 1 0... > > > > Could you try to verify? Without your patch with any fps buffers toggle > > > > consistently. > > > > > > How small are the frames in you test? What is the highest fps value in > > > your test? > > > > QVGA, don't know fps exactly, pretty high, between 20 and 60fps, I think. > > Just try different frams sizes, go down to 64x48 or something. > > Testing of 960x243 frames at 30 fps has been done during all my previous > tests. I didn't see any issues at 30 fps. Ok, I've found the reason. Buffer number repeats, when there is an underrun, which is happening in my tests, when frames are arriving quickly enough, but the user-space is not fast enough to process them, e.g., when it is writing them to files over NFS or even just displaying on the LCD. Without your patch these underruns happen just as well, they just don't get recognised, because there's always one buffer delayed, so, the queue is never empty. Dan, please add my Reviewed-(and-tested-)by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler 2011-02-07 16:49 ` Guennadi Liakhovetski @ 2011-02-14 9:57 ` Dan Williams -1 siblings, 0 replies; 56+ messages in thread From: Dan Williams @ 2011-02-14 9:57 UTC (permalink / raw) To: Guennadi Liakhovetski Cc: Anatolij Gustschin, Markus Niebel, Detlev Zundel, linux-arm-kernel, linux-media, Koul, Vinod On Mon, Feb 7, 2011 at 8:49 AM, Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > Ok, I've found the reason. Buffer number repeats, when there is an > underrun, which is happening in my tests, when frames are arriving quickly > enough, but the user-space is not fast enough to process them, e.g., when > it is writing them to files over NFS or even just displaying on the LCD. > Without your patch these underruns happen just as well, they just don't > get recognised, because there's always one buffer delayed, so, the queue > is never empty. > > Dan, please add my > > Reviewed-(and-tested-)by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Thanks, applied v2. -- Dan ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/2 v2] dma: ipu_idmac: do not lose valid received data in the irq handler @ 2011-02-14 9:57 ` Dan Williams 0 siblings, 0 replies; 56+ messages in thread From: Dan Williams @ 2011-02-14 9:57 UTC (permalink / raw) To: linux-arm-kernel On Mon, Feb 7, 2011 at 8:49 AM, Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote: > Ok, I've found the reason. Buffer number repeats, when there is an > underrun, which is happening in my tests, when frames are arriving quickly > enough, but the user-space is not fast enough to process them, e.g., when > it is writing them to files over NFS or even just displaying on the LCD. > Without your patch these underruns happen just as well, they just don't > get recognised, because there's always one buffer delayed, so, the queue > is never empty. > > Dan, please add my > > Reviewed-(and-tested-)by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Thanks, applied v2. -- Dan ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 0/2] Fix issues with frame reception from CSI on i.MX31 2011-01-26 8:49 ` Anatolij Gustschin @ 2011-01-28 7:46 ` Anatolij Gustschin -1 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-28 7:46 UTC (permalink / raw) To: linux-media Cc: Guennadi Liakhovetski, Dan Williams, linux-arm-kernel, Detlev Zundel, Markus Niebel On Wed, 26 Jan 2011 09:49:47 +0100 Anatolij Gustschin <agust@denx.de> wrote: > On some camera systems we do not tolerate the losing of > captured frames. We observed losing of the first frame > from CSI when double buffering is used (multiple buffers > queued by the mx3-camera driver). > > The patches provide fixes for the observed problem. > > Anatolij Gustschin (2): > v4l: soc-camera: start stream after queueing the buffers > dma: ipu_idmac: do not lose valid received data in the irq handler > > drivers/dma/ipu/ipu_idmac.c | 50 -------------------------------------- > drivers/media/video/soc_camera.c | 4 +- > 2 files changed, 2 insertions(+), 52 deletions(-) Here I provide some more information on what has been done to analyse the observed problem with one lost frame when capturing an exact number of frames. To be able to see whether some errors by hardware problems or channel or image sensor parameters miss-configuration appear or not and to catch such potential errors we added new IRQ handlers for IPU error interrupts. The patch for these handlers is inlined below, if someone is interested in it. This extension requires setting CONFIG_MX3_IPU_IRQS=10 in the kernel configuration. Also debug output has been activated in the mx3_camera driver. Two buffers are queued by the test application, so double buffering will be used. To simplify matters the image sensor is triggered to deliver only 3 frames. Here is the resulting debug log from the drivers. It is quoted, so I can add comments on related places: ... > [ 66.560000] mx3-camera mx3-camera.0: Set SENS_CONF to b00, rate 45314285 > [ 66.560000] mx3-camera mx3-camera.0: MX3 Camera driver attached to camera 0 > [ 66.560000] mx3-camera mx3-camera.0: Set format 960x243 > [ 66.560000] ipu-core ipu-core: timeout = 0 * 10ms > [ 66.560000] ipu-core ipu-core: init channel = 7 > [ 66.560000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x0 > [ 66.560000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 66.560000] dma dma0chan7: Found channel 0x7, irq 177 > [ 66.570000] Got SOF IRQ 179 on Channel 7 > [ 66.570000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 66.570000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 66.570000] __________________________________________ > [ 66.570000] mx3-camera mx3-camera.0: Sensor set 960x243 > [ 66.570000] mx3-camera mx3-camera.0: requested bus width 10 bit: 0 > [ 66.570000] mx3-camera mx3-camera.0: Flags cam: 0x7215 host: 0xf2fd common: 0x7215 > [ 66.570000] mx3-camera mx3-camera.0: Set SENS_CONF to 700 > [ 66.570000] mx3-camera mx3-camera.0: Set format 2056x1547 > [ 66.580000] ipu-core ipu-core: timeout = 0 * 10ms > [ 66.580000] ipu-core ipu-core: init channel = 7 > [ 66.580000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 66.580000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 66.580000] dma dma0chan7: Found channel 0x7, irq 177 > [ 66.590000] mx3-camera mx3-camera.0: Sensor set 2056x1547 > [ 66.590000] mx3-camera mx3-camera.0: requested bus width 10 bit: 0 > [ 66.590000] mx3-camera mx3-camera.0: Flags cam: 0x7215 host: 0xf2fd common: 0x7215 > [ 66.590000] mx3-camera mx3-camera.0: Set SENS_CONF to 700 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010070, data = 0x00000000 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010071, data = 0x00004000 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010072, data = 0x00000000 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010073, data = 0x0A807000 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010074, data = 0x00000006 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010078, data = 0x86800000 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010079, data = 0x00000000 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x0001007A, data = 0x3E0E403B > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x0001007B, data = 0x00000002 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x0001007C, data = 0x00000000 > [ 66.870000] dma dma0chan7: Submitting sg c798a7ac > [ 66.870000] dma dma0chan7: Updated sg c798a7ac on channel 0x7 buffer 0 > [ 66.870000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 66.870000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 66.870000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 66.870000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 66.870000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 66.870000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 66.870000] mx3-camera mx3-camera.0: Submitted cookie 2 DMA 0x86800000 > [ 66.890000] dma dma0chan7: Submitting sg c798a4ac > [ 66.890000] dma dma0chan7: Updated sg c798a4ac on channel 0x7 buffer 1 > [ 66.890000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 66.890000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x3 > [ 66.890000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 66.890000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x3 > [ 66.890000] mx3-camera mx3-camera.0: Submitted cookie 3 DMA 0x86c00000 So far, two buffers have been prepared. When double buffering is activated, DMAIC_7_CUR_BUF flag will be set, DMAIC_7_BUF0_RDY and DMAIC_7_BUF1_RDY are set by the driver, indicating that the both buffers are ready for DMA transfers. Image sensor trigger sequence is started now. > [ 66.940000] Got SOF IRQ 179 on Channel 7 > [ 66.940000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 66.940000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 66.940000] __________________________________________ > [ 66.940000] Got NF ACK IRQ 178 on Channel 7 > [ 66.940000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 66.940000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 66.940000] __________________________________________ > [ 67.020000] Got EOF IRQ 180 on Channel 7 > [ 67.020000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.020000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.020000] __________________________________________ When CSI starts to deliver image data, CSI_NF and NF ACK interrupts are triggered. At this time we see, that the DMAIC_7_CUR_BUF flag has been flipped to point to the first buffer 0 and the DMAIC_7_BUSY flag is set, indicating that IDMAC is writing to the buffer 0. When the frame data has been received, CSI_EOF interrupt is generated. At this time IDMAC has transmitted the data to the buffer 0 and is not busy any more: the DMAIC_7_BUSY flag is not set. DMAIC_7_CUR_BUF flag is pointing to the buffer 0. DMAIC_7_BUF0_RDY flag has been reset when CSI_NF interrupt occurred, indicating that the buffer 0 is being written by the DMA. We got EOF IRQ 180 (which is CSI_EOF), the DMA tranfer is done, the data is sitting in the buffer 0. The buffer 1 is ready for DMA transfers and will be used when the next image frame arrives. > [ 67.020000] dma dma0chan7: IDMAC irq 177, buf 0 > [ 67.020000] dma dma0chan7: IRQ on active buffer on channel 7, active 0, ready 0, 80, current 0! Now the DMAIC_7_EOF interrupt (end of frame on the DMA channel) is triggered and the interrupt handler should (among other things) now call the done callback of the mx3_camera driver. But the handler waits here for DMAIC_7_CUR_BUF to flip, and after the wait counter becomes zero, the handler returns (DMAIC_7_CUR_BUF won't flip here, it will flip first when the new frame data is comming and some buffer is found to be in the ready state). The frame arrived and is sitting in the buffer 0, but the reporting of this reception is not done here. > [ 67.180000] Got SOF IRQ 179 on Channel 7 > [ 67.180000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 67.180000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.180000] __________________________________________ > [ 67.180000] Got NF ACK IRQ 178 on Channel 7 > [ 67.180000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 67.180000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.180000] __________________________________________ Here we see it. CSI_NF and NF ACK interrupts occurred as the next frame from the camera sensor is being received. The buffer 1 was previously ready, so FSU flipped the DMAIC_7_CUR_BUF flag to point to the buffer 1. DMAIC_7_BUF1_RDY flag is reset, the new frame data is being written to the buffer 1, DMAIC_7_BUSY flag indicates channel 7 DMA busy status. > [ 67.260000] Got EOF IRQ 180 on Channel 7 > [ 67.260000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.260000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.260000] __________________________________________ CSI_EOF interrupt is triggered. The next frame data has been received and is sitting in the buffer 1, DMAIC_7_BUSY is reset, so the DMA transfer is completed. We have received two frames so far. > [ 67.260000] dma dma0chan7: IDMAC irq 177, buf 0 > [ 67.260000] dma dma0chan7: IDMAC irq 177, dma 0x86800000, next dma 0x86c00000, current 0, curbuf 0x00000080 > [ 67.260000] ipu-core ipu-core: callback cookie 2, active DMA 0x86800000 > [ 67.330000] dma dma0chan7: Submitting sg c798a7ac > [ 67.330000] dma dma0chan7: Updated sg c798a7ac on channel 0x7 buffer 0 > [ 67.330000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.330000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.330000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.330000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.330000] mx3-camera mx3-camera.0: Submitted cookie 4 DMA 0x86800000 DMAIC_7_EOF interrupt for the second frame occured and the channels active_buffer software flag 'ichan->active_buffer' is pointing to the buffer 0, so the interrupt handler reported the reception of the first frame in buffer 0 to the user space, the buffer 0 has been dequeued and then enqueued again and is now ready for frame data reception. DMAIC_7_BUF0_RDY flag is now set, indicating that the buffer 0 is ready. The buffer 0 is prepared for reception of the third frame. The second frame is still sitting in the buffer 1. The driver's software flag 'ichan->active_buffer' is flipped to 1. > [ 67.430000] Got SOF IRQ 179 on Channel 7 > [ 67.430000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 67.430000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.430000] __________________________________________ > [ 67.430000] Got NF ACK IRQ 178 on Channel 7 > [ 67.430000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 67.430000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.430000] __________________________________________ CSI starts to deliver image data of the third frame , CSI_NF and NF ACK interrupts are triggered. The buffer 0 was previously ready, so it became current buffer: DMAIC_7_BUSY flag is set, DMAIC_7_CUR_BUF flag is pointing to the buffer 0. > [ 67.510000] Got EOF IRQ 180 on Channel 7 > [ 67.510000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.510000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.510000] __________________________________________ End of frame for the third frame is signalled, DMAIC_7_BUSY flag is cleared, so reception is completed, the data of the third frame is in buffer 0 now. The data of the second frame is still in the buffer 1. > [ 67.510000] dma dma0chan7: IDMAC irq 177, buf 1 > [ 67.510000] dma dma0chan7: IDMAC irq 177, dma 0x86c00000, next dma 0x86800000, current 1, curbuf 0x00000000 > [ 67.510000] ipu-core ipu-core: callback cookie 3, active DMA 0x86c00000 > [ 67.570000] dma dma0chan7: Submitting sg c798a4ac > [ 67.570000] dma dma0chan7: Updated sg c798a4ac on channel 0x7 buffer 1 > [ 67.570000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.570000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.570000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.570000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.570000] mx3-camera mx3-camera.0: Submitted cookie 5 DMA 0x86c00000 DMAIC_7_EOF interrupt for the third frame occured. The driver's software flag 'ichan->active_buffer' was pointing to buffer 1, so the interrupt handler reports the reception of the second frame. The buffer 1 is dequeued and then enqueued again, second frame is arrived in user space. Since we requested only three frames from the image sensor, no more frames will be delivered and no interrupts from the CSI or DMAIC_7_EOF will occure. The third frame has been received and is sitting in the buffer 0, but this won't be reported. Instead of requested three frames we got only two frames. So we can see that in order ot get N frames we have to request N + 1 frames from the image sensor. In camera applications with continuous image stream such behaviour might be acceptable. But in our use case we _must_ be able to receive exact the same number of frames as we have requested. > [ 70.580000] mx3-camera mx3-camera.0: Release active DMA 0x86800000 (state 3), queue not empty > [ 70.580000] mx3-camera mx3-camera.0: free_buffer (vb=0xc798a740) 0x4138c000 3180632 > [ 70.580000] mx3-camera mx3-camera.0: Release DMA 0x86c00000 (state 5), queue not empty > [ 70.580000] mx3-camera mx3-camera.0: free_buffer (vb=0xc798a440) 0x41695000 3180632 No IPU error interrupts appeared in the log, no IPU error interrupts have been signalled: grep ipu_irq /proc/interrupts 176: 2 ipu_irq IDMAC EOF 14 177: 3 ipu_irq IDMAC EOF 7 178: 3 ipu_irq DMAIC NF ACK 179: 4 ipu_irq IC SOF 180: 3 ipu_irq IC EOF 181: 0 ipu_irq IC NFB4EOF ERR 182: 0 ipu_irq BAYER BUF OVF ERR 183: 0 ipu_irq ENC BUF OVF ERR 184: 0 ipu_irq BAYER FRM LOST ERR 185: 0 ipu_irq ENC FRM LOST ERR PATCH '2/2 dma: ipu_idmac: do not lose valid received data in the irq handler' fixes this problem. Using it we are able to receive exact number of requested frames when using double buffering. The problem doesn't appear when only one buffer is queued. Here is the log how things look like with the patch 2/2 applied: > [ 71.800000] mx3-camera mx3-camera.0: Set SENS_CONF to b00, rate 45314285 > [ 71.800000] mx3-camera mx3-camera.0: MX3 Camera driver attached to camera 0 > [ 71.800000] mx3-camera mx3-camera.0: Set format 960x243 > [ 71.800000] ipu-core ipu-core: timeout = 0 * 10ms > [ 71.800000] ipu-core ipu-core: init channel = 7 > [ 71.800000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 71.800000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 71.800000] dma dma0chan7: Found channel 0x7, irq 177 > [ 71.810000] Got SOF IRQ 179 on Channel 7 > [ 71.810000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 71.810000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 71.810000] __________________________________________ > [ 71.810000] mx3-camera mx3-camera.0: Sensor set 960x243 > [ 71.810000] mx3-camera mx3-camera.0: requested bus width 10 bit: 0 > [ 71.810000] mx3-camera mx3-camera.0: Flags cam: 0x7215 host: 0xf2fd common: 0x7215 > [ 71.810000] mx3-camera mx3-camera.0: Set SENS_CONF to 700 > [ 71.810000] mx3-camera mx3-camera.0: Set format 2056x1547 > [ 71.810000] ipu-core ipu-core: timeout = 0 * 10ms > [ 71.810000] ipu-core ipu-core: init channel = 7 > [ 71.810000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 71.810000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 71.810000] dma dma0chan7: Found channel 0x7, irq 177 > [ 71.830000] mx3-camera mx3-camera.0: Sensor set 2056x1547 > [ 71.830000] mx3-camera mx3-camera.0: requested bus width 10 bit: 0 > [ 71.830000] mx3-camera mx3-camera.0: Flags cam: 0x7215 host: 0xf2fd common: 0x7215 > [ 71.830000] mx3-camera mx3-camera.0: Set SENS_CONF to 700 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010070, data = 0x00000000 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010071, data = 0x00004000 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010072, data = 0x00000000 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010073, data = 0x0A807000 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010074, data = 0x00000006 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010078, data = 0x86800000 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010079, data = 0x00000000 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x0001007A, data = 0x3E0E403B > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x0001007B, data = 0x00000002 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x0001007C, data = 0x00000000 > [ 72.100000] dma dma0chan7: Submitting sg c798a32c > [ 72.100000] dma dma0chan7: Updated sg c798a32c on channel 0x7 buffer 0 > [ 72.100000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 72.100000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 72.100000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.100000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 72.100000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.100000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 72.100000] mx3-camera mx3-camera.0: Submitted cookie 2 DMA 0x86800000 > [ 72.120000] dma dma0chan7: Submitting sg c798a0ec > [ 72.120000] dma dma0chan7: Updated sg c798a0ec on channel 0x7 buffer 1 > [ 72.120000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.120000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x3 > [ 72.120000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.120000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x3 > [ 72.120000] mx3-camera mx3-camera.0: Submitted cookie 3 DMA 0x86c00000 > [ 72.170000] Got SOF IRQ 179 on Channel 7 > [ 72.170000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 72.170000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.170000] __________________________________________ > [ 72.170000] Got NF ACK IRQ 178 on Channel 7 > [ 72.170000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 72.170000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.170000] __________________________________________ > [ 72.250000] Got EOF IRQ 180 on Channel 7 > [ 72.250000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.250000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.250000] __________________________________________ > [ 72.250000] dma dma0chan7: IDMAC irq 177, buf 0 > [ 72.250000] dma dma0chan7: IDMAC irq 177, dma 0x86800000, next dma 0x86c00000, current 0, curbuf 0x00000000 > [ 72.250000] ipu-core ipu-core: callback cookie 2, active DMA 0x86800000 > [ 72.300000] dma dma0chan7: Submitting sg c798a32c > [ 72.300000] dma dma0chan7: Updated sg c798a32c on channel 0x7 buffer 0 > [ 72.300000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.300000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.300000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.300000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.300000] mx3-camera mx3-camera.0: Submitted cookie 4 DMA 0x86800000 > [ 72.420000] Got SOF IRQ 179 on Channel 7 > [ 72.420000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 72.420000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.420000] __________________________________________ > [ 72.420000] Got NF ACK IRQ 178 on Channel 7 > [ 72.420000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 72.420000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.420000] __________________________________________ > [ 72.500000] Got EOF IRQ 180 on Channel 7 > [ 72.500000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.500000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.500000] __________________________________________ > [ 72.500000] dma dma0chan7: IDMAC irq 177, buf 1 > [ 72.500000] dma dma0chan7: IDMAC irq 177, dma 0x86c00000, next dma 0x86800000, current 1, curbuf 0x00000080 > [ 72.500000] ipu-core ipu-core: callback cookie 3, active DMA 0x86c00000 > [ 72.550000] dma dma0chan7: Submitting sg c798a0ec > [ 72.550000] dma dma0chan7: Updated sg c798a0ec on channel 0x7 buffer 1 > [ 72.550000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.550000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.550000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.550000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.550000] mx3-camera mx3-camera.0: Submitted cookie 5 DMA 0x86c00000 > [ 72.660000] Got SOF IRQ 179 on Channel 7 > [ 72.660000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 72.660000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.660000] __________________________________________ > [ 72.660000] Got NF ACK IRQ 178 on Channel 7 > [ 72.660000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 72.660000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.660000] __________________________________________ > [ 72.740000] Got EOF IRQ 180 on Channel 7 > [ 72.740000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.740000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.740000] __________________________________________ > [ 72.740000] dma dma0chan7: IDMAC irq 177, buf 0 > [ 72.740000] dma dma0chan7: IDMAC irq 177, dma 0x86800000, next dma 0x86c00000, current 0, curbuf 0x00000000 > [ 72.740000] ipu-core ipu-core: callback cookie 4, active DMA 0x86800000 > [ 72.790000] dma dma0chan7: Submitting sg c798a32c > [ 72.790000] dma dma0chan7: Updated sg c798a32c on channel 0x7 buffer 0 > [ 72.790000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.790000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.790000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.790000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.790000] mx3-camera mx3-camera.0: Submitted cookie 6 DMA 0x86800000 > [ 72.790000] mx3-camera mx3-camera.0: Release DMA 0x86800000 (state 5), queue not empty > [ 72.790000] mx3-camera mx3-camera.0: free_buffer (vb=0xc798a2c0) 0x4138c000 3180632 > [ 72.790000] mx3-camera mx3-camera.0: Release active DMA 0x86c00000 (state 3), queue not empty > [ 72.790000] mx3-camera mx3-camera.0: free_buffer (vb=0xc798a080) 0x41695000 3180632 We can see here that alls three frames could be received and read out by the test application. Here is the used debug patch for interested parties: drivers/dma/ipu/ipu_idmac.c | 143 +++++++++++++++++++++++++++++++++++++- drivers/media/video/mx3_camera.c | 2 +- 2 files changed, 141 insertions(+), 4 deletions(-) diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index d696915..f9fa0b3 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -8,7 +8,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - +#define DEBUG #include <linux/init.h> #include <linux/platform_device.h> #include <linux/err.h> @@ -910,6 +910,8 @@ static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx) goto dequeue; } + dump_idmac_reg(ipu); + if (ichan->status < IPU_CHANNEL_ENABLED) { ret = ipu_enable_channel(idmac, ichan); if (ret < 0) { @@ -1472,22 +1474,106 @@ static void idmac_terminate_all(struct dma_chan *chan) static irqreturn_t ic_sof_irq(int irq, void *dev_id) { struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); printk(KERN_DEBUG "Got SOF IRQ %d on Channel %d\n", irq, ichan->dma_chan.chan_id); - disable_irq_nosync(irq); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + /*disable_irq_nosync(irq);*/ return IRQ_HANDLED; } static irqreturn_t ic_eof_irq(int irq, void *dev_id) { struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); printk(KERN_DEBUG "Got EOF IRQ %d on Channel %d\n", irq, ichan->dma_chan.chan_id); - disable_irq_nosync(irq); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + /*disable_irq_nosync(irq);*/ + return IRQ_HANDLED; +} + +static irqreturn_t ic_nf_ack_irq(int irq, void *dev_id) +{ + struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); + printk(KERN_DEBUG "Got NF ACK IRQ %d on Channel %d\n", + irq, ichan->dma_chan.chan_id); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + return IRQ_HANDLED; +} + +static irqreturn_t ic_nfb4_eof_err_irq(int irq, void *dev_id) +{ + struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); + printk(KERN_DEBUG "Got NF B4 EOF ERR IRQ %d on Channel %d\n", + irq, ichan->dma_chan.chan_id); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + return IRQ_HANDLED; +} + +static irqreturn_t ic_bay_ovf_err_irq(int irq, void *dev_id) +{ + struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); + printk(KERN_DEBUG "Got BAYER BUF OVF ERR IRQ %d on Channel %d\n", + irq, ichan->dma_chan.chan_id); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + return IRQ_HANDLED; +} + +static irqreturn_t ic_enc_ovf_err_irq(int irq, void *dev_id) +{ + struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); + printk(KERN_DEBUG "Got ENC BUF OVF ERR IRQ %d on Channel %d\n", + irq, ichan->dma_chan.chan_id); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); return IRQ_HANDLED; } +static irqreturn_t ic_bay_frm_lost_err_irq(int irq, void *dev_id) +{ + struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); + printk(KERN_DEBUG "Got BAYER FRM LOST ERR IRQ %d on Channel %d\n", + irq, ichan->dma_chan.chan_id); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + return IRQ_HANDLED; +} + +static irqreturn_t ic_enc_frm_lost_err_irq(int irq, void *dev_id) +{ + struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); + printk(KERN_DEBUG "Got ENC FRM LOST ERR IRQ %d on Channel %d\n", + irq, ichan->dma_chan.chan_id); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + return IRQ_HANDLED; +} + + static int ic_sof = -EINVAL, ic_eof = -EINVAL; +static int ic_nf_ack = -EINVAL, ic_nfb4_eof_err = -EINVAL; +static int ic_bay_ovf_err = -EINVAL, ic_enc_ovf_err = -EINVAL; +static int ic_bay_frm_lost_err = -EINVAL, ic_enc_frm_lost_err = -EINVAL; #endif static int idmac_alloc_chan_resources(struct dma_chan *chan) @@ -1526,12 +1612,33 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan) #ifdef DEBUG if (chan->chan_id == IDMAC_IC_7) { + ic_nf_ack = ipu_irq_map(39); + if (ic_nf_ack > 0) + request_irq(ic_nf_ack, ic_nf_ack_irq, 0, "DMAIC NF ACK", ichan); ic_sof = ipu_irq_map(69); if (ic_sof > 0) request_irq(ic_sof, ic_sof_irq, 0, "IC SOF", ichan); ic_eof = ipu_irq_map(70); if (ic_eof > 0) request_irq(ic_eof, ic_eof_irq, 0, "IC EOF", ichan); + ic_nfb4_eof_err = ipu_irq_map(103); + if (ic_nfb4_eof_err > 0) + request_irq(ic_nfb4_eof_err, ic_nfb4_eof_err_irq, 0, "IC NFB4EOF ERR", ichan); + + ic_bay_ovf_err = ipu_irq_map(128); + if (ic_bay_ovf_err > 0) + request_irq(ic_bay_ovf_err, ic_bay_ovf_err_irq, 0, "BAYER BUF OVF ERR", ichan); + ic_enc_ovf_err = ipu_irq_map(129); + if (ic_enc_ovf_err > 0) + request_irq(ic_enc_ovf_err, ic_enc_ovf_err_irq, 0, "ENC BUF OVF ERR", ichan); + + ic_bay_frm_lost_err = ipu_irq_map(139); + if (ic_bay_frm_lost_err > 0) + request_irq(ic_bay_frm_lost_err, ic_bay_frm_lost_err_irq, 0, "BAYER FRM LOST ERR", ichan); + + ic_enc_frm_lost_err = ipu_irq_map(140); + if (ic_enc_frm_lost_err > 0) + request_irq(ic_enc_frm_lost_err, ic_enc_frm_lost_err_irq, 0, "ENC FRM LOST ERR", ichan); } #endif @@ -1562,6 +1669,11 @@ static void idmac_free_chan_resources(struct dma_chan *chan) if (ichan->status > IPU_CHANNEL_FREE) { #ifdef DEBUG if (chan->chan_id == IDMAC_IC_7) { + if (ic_nf_ack > 0) { + free_irq(ic_nf_ack, ichan); + ipu_irq_unmap(39); + ic_nf_ack = -EINVAL; + } if (ic_sof > 0) { free_irq(ic_sof, ichan); ipu_irq_unmap(69); @@ -1572,6 +1684,31 @@ static void idmac_free_chan_resources(struct dma_chan *chan) ipu_irq_unmap(70); ic_eof = -EINVAL; } + if (ic_nfb4_eof_err > 0) { + free_irq(ic_nfb4_eof_err, ichan); + ipu_irq_unmap(103); + ic_nfb4_eof_err = -EINVAL; + } + if (ic_bay_ovf_err > 0) { + free_irq(ic_bay_ovf_err, ichan); + ipu_irq_unmap(128); + ic_bay_ovf_err = -EINVAL; + } + if (ic_enc_ovf_err > 0) { + free_irq(ic_enc_ovf_err, ichan); + ipu_irq_unmap(129); + ic_enc_ovf_err = -EINVAL; + } + if (ic_bay_frm_lost_err > 0) { + free_irq(ic_bay_frm_lost_err, ichan); + ipu_irq_unmap(139); + ic_bay_frm_lost_err = -EINVAL; + } + if (ic_enc_frm_lost_err > 0) { + free_irq(ic_enc_frm_lost_err, ichan); + ipu_irq_unmap(140); + ic_enc_frm_lost_err = -EINVAL; + } } #endif free_irq(ichan->eof_irq, ichan); diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index 2322798..9e566dd 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c @@ -8,7 +8,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - +#define DEBUG #include <linux/init.h> #include <linux/module.h> #include <linux/version.h> -- 1.7.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 0/2] Fix issues with frame reception from CSI on i.MX31 @ 2011-01-28 7:46 ` Anatolij Gustschin 0 siblings, 0 replies; 56+ messages in thread From: Anatolij Gustschin @ 2011-01-28 7:46 UTC (permalink / raw) To: linux-arm-kernel On Wed, 26 Jan 2011 09:49:47 +0100 Anatolij Gustschin <agust@denx.de> wrote: > On some camera systems we do not tolerate the losing of > captured frames. We observed losing of the first frame > from CSI when double buffering is used (multiple buffers > queued by the mx3-camera driver). > > The patches provide fixes for the observed problem. > > Anatolij Gustschin (2): > v4l: soc-camera: start stream after queueing the buffers > dma: ipu_idmac: do not lose valid received data in the irq handler > > drivers/dma/ipu/ipu_idmac.c | 50 -------------------------------------- > drivers/media/video/soc_camera.c | 4 +- > 2 files changed, 2 insertions(+), 52 deletions(-) Here I provide some more information on what has been done to analyse the observed problem with one lost frame when capturing an exact number of frames. To be able to see whether some errors by hardware problems or channel or image sensor parameters miss-configuration appear or not and to catch such potential errors we added new IRQ handlers for IPU error interrupts. The patch for these handlers is inlined below, if someone is interested in it. This extension requires setting CONFIG_MX3_IPU_IRQS=10 in the kernel configuration. Also debug output has been activated in the mx3_camera driver. Two buffers are queued by the test application, so double buffering will be used. To simplify matters the image sensor is triggered to deliver only 3 frames. Here is the resulting debug log from the drivers. It is quoted, so I can add comments on related places: ... > [ 66.560000] mx3-camera mx3-camera.0: Set SENS_CONF to b00, rate 45314285 > [ 66.560000] mx3-camera mx3-camera.0: MX3 Camera driver attached to camera 0 > [ 66.560000] mx3-camera mx3-camera.0: Set format 960x243 > [ 66.560000] ipu-core ipu-core: timeout = 0 * 10ms > [ 66.560000] ipu-core ipu-core: init channel = 7 > [ 66.560000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x0 > [ 66.560000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 66.560000] dma dma0chan7: Found channel 0x7, irq 177 > [ 66.570000] Got SOF IRQ 179 on Channel 7 > [ 66.570000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 66.570000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 66.570000] __________________________________________ > [ 66.570000] mx3-camera mx3-camera.0: Sensor set 960x243 > [ 66.570000] mx3-camera mx3-camera.0: requested bus width 10 bit: 0 > [ 66.570000] mx3-camera mx3-camera.0: Flags cam: 0x7215 host: 0xf2fd common: 0x7215 > [ 66.570000] mx3-camera mx3-camera.0: Set SENS_CONF to 700 > [ 66.570000] mx3-camera mx3-camera.0: Set format 2056x1547 > [ 66.580000] ipu-core ipu-core: timeout = 0 * 10ms > [ 66.580000] ipu-core ipu-core: init channel = 7 > [ 66.580000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 66.580000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 66.580000] dma dma0chan7: Found channel 0x7, irq 177 > [ 66.590000] mx3-camera mx3-camera.0: Sensor set 2056x1547 > [ 66.590000] mx3-camera mx3-camera.0: requested bus width 10 bit: 0 > [ 66.590000] mx3-camera mx3-camera.0: Flags cam: 0x7215 host: 0xf2fd common: 0x7215 > [ 66.590000] mx3-camera mx3-camera.0: Set SENS_CONF to 700 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010070, data = 0x00000000 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010071, data = 0x00004000 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010072, data = 0x00000000 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010073, data = 0x0A807000 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010074, data = 0x00000006 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010078, data = 0x86800000 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x00010079, data = 0x00000000 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x0001007A, data = 0x3E0E403B > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x0001007B, data = 0x00000002 > [ 66.870000] ipu-core ipu-core: write param mem - addr = 0x0001007C, data = 0x00000000 > [ 66.870000] dma dma0chan7: Submitting sg c798a7ac > [ 66.870000] dma dma0chan7: Updated sg c798a7ac on channel 0x7 buffer 0 > [ 66.870000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 66.870000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 66.870000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 66.870000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 66.870000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 66.870000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 66.870000] mx3-camera mx3-camera.0: Submitted cookie 2 DMA 0x86800000 > [ 66.890000] dma dma0chan7: Submitting sg c798a4ac > [ 66.890000] dma dma0chan7: Updated sg c798a4ac on channel 0x7 buffer 1 > [ 66.890000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 66.890000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x3 > [ 66.890000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 66.890000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x3 > [ 66.890000] mx3-camera mx3-camera.0: Submitted cookie 3 DMA 0x86c00000 So far, two buffers have been prepared. When double buffering is activated, DMAIC_7_CUR_BUF flag will be set, DMAIC_7_BUF0_RDY and DMAIC_7_BUF1_RDY are set by the driver, indicating that the both buffers are ready for DMA transfers. Image sensor trigger sequence is started now. > [ 66.940000] Got SOF IRQ 179 on Channel 7 > [ 66.940000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 66.940000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 66.940000] __________________________________________ > [ 66.940000] Got NF ACK IRQ 178 on Channel 7 > [ 66.940000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 66.940000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 66.940000] __________________________________________ > [ 67.020000] Got EOF IRQ 180 on Channel 7 > [ 67.020000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.020000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.020000] __________________________________________ When CSI starts to deliver image data, CSI_NF and NF ACK interrupts are triggered. At this time we see, that the DMAIC_7_CUR_BUF flag has been flipped to point to the first buffer 0 and the DMAIC_7_BUSY flag is set, indicating that IDMAC is writing to the buffer 0. When the frame data has been received, CSI_EOF interrupt is generated. At this time IDMAC has transmitted the data to the buffer 0 and is not busy any more: the DMAIC_7_BUSY flag is not set. DMAIC_7_CUR_BUF flag is pointing to the buffer 0. DMAIC_7_BUF0_RDY flag has been reset when CSI_NF interrupt occurred, indicating that the buffer 0 is being written by the DMA. We got EOF IRQ 180 (which is CSI_EOF), the DMA tranfer is done, the data is sitting in the buffer 0. The buffer 1 is ready for DMA transfers and will be used when the next image frame arrives. > [ 67.020000] dma dma0chan7: IDMAC irq 177, buf 0 > [ 67.020000] dma dma0chan7: IRQ on active buffer on channel 7, active 0, ready 0, 80, current 0! Now the DMAIC_7_EOF interrupt (end of frame on the DMA channel) is triggered and the interrupt handler should (among other things) now call the done callback of the mx3_camera driver. But the handler waits here for DMAIC_7_CUR_BUF to flip, and after the wait counter becomes zero, the handler returns (DMAIC_7_CUR_BUF won't flip here, it will flip first when the new frame data is comming and some buffer is found to be in the ready state). The frame arrived and is sitting in the buffer 0, but the reporting of this reception is not done here. > [ 67.180000] Got SOF IRQ 179 on Channel 7 > [ 67.180000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 67.180000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.180000] __________________________________________ > [ 67.180000] Got NF ACK IRQ 178 on Channel 7 > [ 67.180000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 67.180000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.180000] __________________________________________ Here we see it. CSI_NF and NF ACK interrupts occurred as the next frame from the camera sensor is being received. The buffer 1 was previously ready, so FSU flipped the DMAIC_7_CUR_BUF flag to point to the buffer 1. DMAIC_7_BUF1_RDY flag is reset, the new frame data is being written to the buffer 1, DMAIC_7_BUSY flag indicates channel 7 DMA busy status. > [ 67.260000] Got EOF IRQ 180 on Channel 7 > [ 67.260000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.260000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.260000] __________________________________________ CSI_EOF interrupt is triggered. The next frame data has been received and is sitting in the buffer 1, DMAIC_7_BUSY is reset, so the DMA transfer is completed. We have received two frames so far. > [ 67.260000] dma dma0chan7: IDMAC irq 177, buf 0 > [ 67.260000] dma dma0chan7: IDMAC irq 177, dma 0x86800000, next dma 0x86c00000, current 0, curbuf 0x00000080 > [ 67.260000] ipu-core ipu-core: callback cookie 2, active DMA 0x86800000 > [ 67.330000] dma dma0chan7: Submitting sg c798a7ac > [ 67.330000] dma dma0chan7: Updated sg c798a7ac on channel 0x7 buffer 0 > [ 67.330000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.330000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.330000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.330000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.330000] mx3-camera mx3-camera.0: Submitted cookie 4 DMA 0x86800000 DMAIC_7_EOF interrupt for the second frame occured and the channels active_buffer software flag 'ichan->active_buffer' is pointing to the buffer 0, so the interrupt handler reported the reception of the first frame in buffer 0 to the user space, the buffer 0 has been dequeued and then enqueued again and is now ready for frame data reception. DMAIC_7_BUF0_RDY flag is now set, indicating that the buffer 0 is ready. The buffer 0 is prepared for reception of the third frame. The second frame is still sitting in the buffer 1. The driver's software flag 'ichan->active_buffer' is flipped to 1. > [ 67.430000] Got SOF IRQ 179 on Channel 7 > [ 67.430000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 67.430000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.430000] __________________________________________ > [ 67.430000] Got NF ACK IRQ 178 on Channel 7 > [ 67.430000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 67.430000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.430000] __________________________________________ CSI starts to deliver image data of the third frame , CSI_NF and NF ACK interrupts are triggered. The buffer 0 was previously ready, so it became current buffer: DMAIC_7_BUSY flag is set, DMAIC_7_CUR_BUF flag is pointing to the buffer 0. > [ 67.510000] Got EOF IRQ 180 on Channel 7 > [ 67.510000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.510000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.510000] __________________________________________ End of frame for the third frame is signalled, DMAIC_7_BUSY flag is cleared, so reception is completed, the data of the third frame is in buffer 0 now. The data of the second frame is still in the buffer 1. > [ 67.510000] dma dma0chan7: IDMAC irq 177, buf 1 > [ 67.510000] dma dma0chan7: IDMAC irq 177, dma 0x86c00000, next dma 0x86800000, current 1, curbuf 0x00000000 > [ 67.510000] ipu-core ipu-core: callback cookie 3, active DMA 0x86c00000 > [ 67.570000] dma dma0chan7: Submitting sg c798a4ac > [ 67.570000] dma dma0chan7: Updated sg c798a4ac on channel 0x7 buffer 1 > [ 67.570000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.570000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.570000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 67.570000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 67.570000] mx3-camera mx3-camera.0: Submitted cookie 5 DMA 0x86c00000 DMAIC_7_EOF interrupt for the third frame occured. The driver's software flag 'ichan->active_buffer' was pointing to buffer 1, so the interrupt handler reports the reception of the second frame. The buffer 1 is dequeued and then enqueued again, second frame is arrived in user space. Since we requested only three frames from the image sensor, no more frames will be delivered and no interrupts from the CSI or DMAIC_7_EOF will occure. The third frame has been received and is sitting in the buffer 0, but this won't be reported. Instead of requested three frames we got only two frames. So we can see that in order ot get N frames we have to request N + 1 frames from the image sensor. In camera applications with continuous image stream such behaviour might be acceptable. But in our use case we _must_ be able to receive exact the same number of frames as we have requested. > [ 70.580000] mx3-camera mx3-camera.0: Release active DMA 0x86800000 (state 3), queue not empty > [ 70.580000] mx3-camera mx3-camera.0: free_buffer (vb=0xc798a740) 0x4138c000 3180632 > [ 70.580000] mx3-camera mx3-camera.0: Release DMA 0x86c00000 (state 5), queue not empty > [ 70.580000] mx3-camera mx3-camera.0: free_buffer (vb=0xc798a440) 0x41695000 3180632 No IPU error interrupts appeared in the log, no IPU error interrupts have been signalled: grep ipu_irq /proc/interrupts 176: 2 ipu_irq IDMAC EOF 14 177: 3 ipu_irq IDMAC EOF 7 178: 3 ipu_irq DMAIC NF ACK 179: 4 ipu_irq IC SOF 180: 3 ipu_irq IC EOF 181: 0 ipu_irq IC NFB4EOF ERR 182: 0 ipu_irq BAYER BUF OVF ERR 183: 0 ipu_irq ENC BUF OVF ERR 184: 0 ipu_irq BAYER FRM LOST ERR 185: 0 ipu_irq ENC FRM LOST ERR PATCH '2/2 dma: ipu_idmac: do not lose valid received data in the irq handler' fixes this problem. Using it we are able to receive exact number of requested frames when using double buffering. The problem doesn't appear when only one buffer is queued. Here is the log how things look like with the patch 2/2 applied: > [ 71.800000] mx3-camera mx3-camera.0: Set SENS_CONF to b00, rate 45314285 > [ 71.800000] mx3-camera mx3-camera.0: MX3 Camera driver attached to camera 0 > [ 71.800000] mx3-camera mx3-camera.0: Set format 960x243 > [ 71.800000] ipu-core ipu-core: timeout = 0 * 10ms > [ 71.800000] ipu-core ipu-core: init channel = 7 > [ 71.800000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 71.800000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 71.800000] dma dma0chan7: Found channel 0x7, irq 177 > [ 71.810000] Got SOF IRQ 179 on Channel 7 > [ 71.810000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 71.810000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 71.810000] __________________________________________ > [ 71.810000] mx3-camera mx3-camera.0: Sensor set 960x243 > [ 71.810000] mx3-camera mx3-camera.0: requested bus width 10 bit: 0 > [ 71.810000] mx3-camera mx3-camera.0: Flags cam: 0x7215 host: 0xf2fd common: 0x7215 > [ 71.810000] mx3-camera mx3-camera.0: Set SENS_CONF to 700 > [ 71.810000] mx3-camera mx3-camera.0: Set format 2056x1547 > [ 71.810000] ipu-core ipu-core: timeout = 0 * 10ms > [ 71.810000] ipu-core ipu-core: init channel = 7 > [ 71.810000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 71.810000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 71.810000] dma dma0chan7: Found channel 0x7, irq 177 > [ 71.830000] mx3-camera mx3-camera.0: Sensor set 2056x1547 > [ 71.830000] mx3-camera mx3-camera.0: requested bus width 10 bit: 0 > [ 71.830000] mx3-camera mx3-camera.0: Flags cam: 0x7215 host: 0xf2fd common: 0x7215 > [ 71.830000] mx3-camera mx3-camera.0: Set SENS_CONF to 700 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010070, data = 0x00000000 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010071, data = 0x00004000 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010072, data = 0x00000000 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010073, data = 0x0A807000 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010074, data = 0x00000006 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010078, data = 0x86800000 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x00010079, data = 0x00000000 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x0001007A, data = 0x3E0E403B > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x0001007B, data = 0x00000002 > [ 72.100000] ipu-core ipu-core: write param mem - addr = 0x0001007C, data = 0x00000000 > [ 72.100000] dma dma0chan7: Submitting sg c798a32c > [ 72.100000] dma dma0chan7: Updated sg c798a32c on channel 0x7 buffer 0 > [ 72.100000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4000, IDMAC_CHA_BUSY 0x4000 > [ 72.100000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 72.100000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x0, IDMAC_CHA_EN 0x4000, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.100000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 72.100000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.100000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x0, DB_MODE 0x0, TASKS_STAT 0x3 > [ 72.100000] mx3-camera mx3-camera.0: Submitted cookie 2 DMA 0x86800000 > [ 72.120000] dma dma0chan7: Submitting sg c798a0ec > [ 72.120000] dma dma0chan7: Updated sg c798a0ec on channel 0x7 buffer 1 > [ 72.120000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.120000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x3 > [ 72.120000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.120000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x3 > [ 72.120000] mx3-camera mx3-camera.0: Submitted cookie 3 DMA 0x86c00000 > [ 72.170000] Got SOF IRQ 179 on Channel 7 > [ 72.170000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 72.170000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.170000] __________________________________________ > [ 72.170000] Got NF ACK IRQ 178 on Channel 7 > [ 72.170000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 72.170000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.170000] __________________________________________ > [ 72.250000] Got EOF IRQ 180 on Channel 7 > [ 72.250000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.250000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.250000] __________________________________________ > [ 72.250000] dma dma0chan7: IDMAC irq 177, buf 0 > [ 72.250000] dma dma0chan7: IDMAC irq 177, dma 0x86800000, next dma 0x86c00000, current 0, curbuf 0x00000000 > [ 72.250000] ipu-core ipu-core: callback cookie 2, active DMA 0x86800000 > [ 72.300000] dma dma0chan7: Submitting sg c798a32c > [ 72.300000] dma dma0chan7: Updated sg c798a32c on channel 0x7 buffer 0 > [ 72.300000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.300000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.300000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.300000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.300000] mx3-camera mx3-camera.0: Submitted cookie 4 DMA 0x86800000 > [ 72.420000] Got SOF IRQ 179 on Channel 7 > [ 72.420000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 72.420000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.420000] __________________________________________ > [ 72.420000] Got NF ACK IRQ 178 on Channel 7 > [ 72.420000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 72.420000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.420000] __________________________________________ > [ 72.500000] Got EOF IRQ 180 on Channel 7 > [ 72.500000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.500000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x0, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.500000] __________________________________________ > [ 72.500000] dma dma0chan7: IDMAC irq 177, buf 1 > [ 72.500000] dma dma0chan7: IDMAC irq 177, dma 0x86c00000, next dma 0x86800000, current 1, curbuf 0x00000080 > [ 72.500000] ipu-core ipu-core: callback cookie 3, active DMA 0x86c00000 > [ 72.550000] dma dma0chan7: Submitting sg c798a0ec > [ 72.550000] dma dma0chan7: Updated sg c798a0ec on channel 0x7 buffer 1 > [ 72.550000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.550000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.550000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.550000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x80, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.550000] mx3-camera mx3-camera.0: Submitted cookie 5 DMA 0x86c00000 > [ 72.660000] Got SOF IRQ 179 on Channel 7 > [ 72.660000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 72.660000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.660000] __________________________________________ > [ 72.660000] Got NF ACK IRQ 178 on Channel 7 > [ 72.660000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4080 > [ 72.660000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.660000] __________________________________________ > [ 72.740000] Got EOF IRQ 180 on Channel 7 > [ 72.740000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.740000] ipu-core ipu-core: BUF0_RDY 0x0, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.740000] __________________________________________ > [ 72.740000] dma dma0chan7: IDMAC irq 177, buf 0 > [ 72.740000] dma dma0chan7: IDMAC irq 177, dma 0x86800000, next dma 0x86c00000, current 0, curbuf 0x00000000 > [ 72.740000] ipu-core ipu-core: callback cookie 4, active DMA 0x86800000 > [ 72.790000] dma dma0chan7: Submitting sg c798a32c > [ 72.790000] dma dma0chan7: Updated sg c798a32c on channel 0x7 buffer 0 > [ 72.790000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.790000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.790000] ipu-core ipu-core: IDMAC_CONF 0x70, IC_CONF 0x40000001, IDMAC_CHA_EN 0x4080, IDMAC_CHA_PRI 0x4080, IDMAC_CHA_BUSY 0x4000 > [ 72.790000] ipu-core ipu-core: BUF0_RDY 0x80, BUF1_RDY 0x80, CUR_BUF 0x0, DB_MODE 0x80, TASKS_STAT 0x7 > [ 72.790000] mx3-camera mx3-camera.0: Submitted cookie 6 DMA 0x86800000 > [ 72.790000] mx3-camera mx3-camera.0: Release DMA 0x86800000 (state 5), queue not empty > [ 72.790000] mx3-camera mx3-camera.0: free_buffer (vb=0xc798a2c0) 0x4138c000 3180632 > [ 72.790000] mx3-camera mx3-camera.0: Release active DMA 0x86c00000 (state 3), queue not empty > [ 72.790000] mx3-camera mx3-camera.0: free_buffer (vb=0xc798a080) 0x41695000 3180632 We can see here that alls three frames could be received and read out by the test application. Here is the used debug patch for interested parties: drivers/dma/ipu/ipu_idmac.c | 143 +++++++++++++++++++++++++++++++++++++- drivers/media/video/mx3_camera.c | 2 +- 2 files changed, 141 insertions(+), 4 deletions(-) diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index d696915..f9fa0b3 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -8,7 +8,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - +#define DEBUG #include <linux/init.h> #include <linux/platform_device.h> #include <linux/err.h> @@ -910,6 +910,8 @@ static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx) goto dequeue; } + dump_idmac_reg(ipu); + if (ichan->status < IPU_CHANNEL_ENABLED) { ret = ipu_enable_channel(idmac, ichan); if (ret < 0) { @@ -1472,22 +1474,106 @@ static void idmac_terminate_all(struct dma_chan *chan) static irqreturn_t ic_sof_irq(int irq, void *dev_id) { struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); printk(KERN_DEBUG "Got SOF IRQ %d on Channel %d\n", irq, ichan->dma_chan.chan_id); - disable_irq_nosync(irq); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + /*disable_irq_nosync(irq);*/ return IRQ_HANDLED; } static irqreturn_t ic_eof_irq(int irq, void *dev_id) { struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); printk(KERN_DEBUG "Got EOF IRQ %d on Channel %d\n", irq, ichan->dma_chan.chan_id); - disable_irq_nosync(irq); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + /*disable_irq_nosync(irq);*/ + return IRQ_HANDLED; +} + +static irqreturn_t ic_nf_ack_irq(int irq, void *dev_id) +{ + struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); + printk(KERN_DEBUG "Got NF ACK IRQ %d on Channel %d\n", + irq, ichan->dma_chan.chan_id); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + return IRQ_HANDLED; +} + +static irqreturn_t ic_nfb4_eof_err_irq(int irq, void *dev_id) +{ + struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); + printk(KERN_DEBUG "Got NF B4 EOF ERR IRQ %d on Channel %d\n", + irq, ichan->dma_chan.chan_id); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + return IRQ_HANDLED; +} + +static irqreturn_t ic_bay_ovf_err_irq(int irq, void *dev_id) +{ + struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); + printk(KERN_DEBUG "Got BAYER BUF OVF ERR IRQ %d on Channel %d\n", + irq, ichan->dma_chan.chan_id); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + return IRQ_HANDLED; +} + +static irqreturn_t ic_enc_ovf_err_irq(int irq, void *dev_id) +{ + struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); + printk(KERN_DEBUG "Got ENC BUF OVF ERR IRQ %d on Channel %d\n", + irq, ichan->dma_chan.chan_id); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); return IRQ_HANDLED; } +static irqreturn_t ic_bay_frm_lost_err_irq(int irq, void *dev_id) +{ + struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); + printk(KERN_DEBUG "Got BAYER FRM LOST ERR IRQ %d on Channel %d\n", + irq, ichan->dma_chan.chan_id); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + return IRQ_HANDLED; +} + +static irqreturn_t ic_enc_frm_lost_err_irq(int irq, void *dev_id) +{ + struct idmac_channel *ichan = dev_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); + printk(KERN_DEBUG "Got ENC FRM LOST ERR IRQ %d on Channel %d\n", + irq, ichan->dma_chan.chan_id); + dump_idmac_reg(ipu); + printk(KERN_DEBUG "__________________________________________\n"); + return IRQ_HANDLED; +} + + static int ic_sof = -EINVAL, ic_eof = -EINVAL; +static int ic_nf_ack = -EINVAL, ic_nfb4_eof_err = -EINVAL; +static int ic_bay_ovf_err = -EINVAL, ic_enc_ovf_err = -EINVAL; +static int ic_bay_frm_lost_err = -EINVAL, ic_enc_frm_lost_err = -EINVAL; #endif static int idmac_alloc_chan_resources(struct dma_chan *chan) @@ -1526,12 +1612,33 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan) #ifdef DEBUG if (chan->chan_id == IDMAC_IC_7) { + ic_nf_ack = ipu_irq_map(39); + if (ic_nf_ack > 0) + request_irq(ic_nf_ack, ic_nf_ack_irq, 0, "DMAIC NF ACK", ichan); ic_sof = ipu_irq_map(69); if (ic_sof > 0) request_irq(ic_sof, ic_sof_irq, 0, "IC SOF", ichan); ic_eof = ipu_irq_map(70); if (ic_eof > 0) request_irq(ic_eof, ic_eof_irq, 0, "IC EOF", ichan); + ic_nfb4_eof_err = ipu_irq_map(103); + if (ic_nfb4_eof_err > 0) + request_irq(ic_nfb4_eof_err, ic_nfb4_eof_err_irq, 0, "IC NFB4EOF ERR", ichan); + + ic_bay_ovf_err = ipu_irq_map(128); + if (ic_bay_ovf_err > 0) + request_irq(ic_bay_ovf_err, ic_bay_ovf_err_irq, 0, "BAYER BUF OVF ERR", ichan); + ic_enc_ovf_err = ipu_irq_map(129); + if (ic_enc_ovf_err > 0) + request_irq(ic_enc_ovf_err, ic_enc_ovf_err_irq, 0, "ENC BUF OVF ERR", ichan); + + ic_bay_frm_lost_err = ipu_irq_map(139); + if (ic_bay_frm_lost_err > 0) + request_irq(ic_bay_frm_lost_err, ic_bay_frm_lost_err_irq, 0, "BAYER FRM LOST ERR", ichan); + + ic_enc_frm_lost_err = ipu_irq_map(140); + if (ic_enc_frm_lost_err > 0) + request_irq(ic_enc_frm_lost_err, ic_enc_frm_lost_err_irq, 0, "ENC FRM LOST ERR", ichan); } #endif @@ -1562,6 +1669,11 @@ static void idmac_free_chan_resources(struct dma_chan *chan) if (ichan->status > IPU_CHANNEL_FREE) { #ifdef DEBUG if (chan->chan_id == IDMAC_IC_7) { + if (ic_nf_ack > 0) { + free_irq(ic_nf_ack, ichan); + ipu_irq_unmap(39); + ic_nf_ack = -EINVAL; + } if (ic_sof > 0) { free_irq(ic_sof, ichan); ipu_irq_unmap(69); @@ -1572,6 +1684,31 @@ static void idmac_free_chan_resources(struct dma_chan *chan) ipu_irq_unmap(70); ic_eof = -EINVAL; } + if (ic_nfb4_eof_err > 0) { + free_irq(ic_nfb4_eof_err, ichan); + ipu_irq_unmap(103); + ic_nfb4_eof_err = -EINVAL; + } + if (ic_bay_ovf_err > 0) { + free_irq(ic_bay_ovf_err, ichan); + ipu_irq_unmap(128); + ic_bay_ovf_err = -EINVAL; + } + if (ic_enc_ovf_err > 0) { + free_irq(ic_enc_ovf_err, ichan); + ipu_irq_unmap(129); + ic_enc_ovf_err = -EINVAL; + } + if (ic_bay_frm_lost_err > 0) { + free_irq(ic_bay_frm_lost_err, ichan); + ipu_irq_unmap(139); + ic_bay_frm_lost_err = -EINVAL; + } + if (ic_enc_frm_lost_err > 0) { + free_irq(ic_enc_frm_lost_err, ichan); + ipu_irq_unmap(140); + ic_enc_frm_lost_err = -EINVAL; + } } #endif free_irq(ichan->eof_irq, ichan); diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index 2322798..9e566dd 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c @@ -8,7 +8,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - +#define DEBUG #include <linux/init.h> #include <linux/module.h> #include <linux/version.h> -- 1.7.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
end of thread, other threads:[~2011-02-14 9:57 UTC | newest] Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-01-26 8:49 [PATCH 0/2] Fix issues with frame reception from CSI on i.MX31 Anatolij Gustschin 2011-01-26 8:49 ` Anatolij Gustschin 2011-01-26 8:49 ` [PATCH 1/2] v4l: soc-camera: start stream after queueing the buffers Anatolij Gustschin 2011-01-26 8:49 ` Anatolij Gustschin 2011-01-29 19:16 ` Guennadi Liakhovetski 2011-01-29 19:16 ` Guennadi Liakhovetski 2011-01-29 19:24 ` Anatolij Gustschin 2011-01-29 19:24 ` Anatolij Gustschin 2011-01-31 12:19 ` [PATCH 1/2 v2] " Anatolij Gustschin 2011-01-31 12:19 ` Anatolij Gustschin 2011-01-26 8:49 ` [PATCH 2/2] dma: ipu_idmac: do not lose valid received data in the irq handler Anatolij Gustschin 2011-01-26 8:49 ` Anatolij Gustschin 2011-01-27 8:22 ` Anatolij Gustschin 2011-01-27 8:22 ` Anatolij Gustschin 2011-01-31 5:56 ` Dan Williams 2011-01-31 5:56 ` Dan Williams 2011-01-31 12:22 ` [PATCH 2/2 v2] " Anatolij Gustschin 2011-01-31 12:22 ` Anatolij Gustschin 2011-02-03 10:09 ` Guennadi Liakhovetski 2011-02-03 10:09 ` Guennadi Liakhovetski 2011-02-04 9:19 ` Markus Niebel 2011-02-04 9:19 ` Markus Niebel 2011-02-04 9:37 ` Guennadi Liakhovetski 2011-02-04 9:37 ` Guennadi Liakhovetski 2011-02-04 11:37 ` Markus Niebel 2011-02-04 11:37 ` Markus Niebel 2011-02-04 9:35 ` Anatolij Gustschin 2011-02-04 9:35 ` Anatolij Gustschin 2011-02-05 13:35 ` Anatolij Gustschin 2011-02-05 13:35 ` Anatolij Gustschin 2011-02-05 16:36 ` Guennadi Liakhovetski 2011-02-05 16:36 ` Guennadi Liakhovetski 2011-02-05 20:04 ` Anatolij Gustschin 2011-02-05 20:04 ` Anatolij Gustschin 2011-02-07 11:09 ` Guennadi Liakhovetski 2011-02-07 11:09 ` Guennadi Liakhovetski 2011-02-07 11:21 ` Anatolij Gustschin 2011-02-07 11:21 ` Anatolij Gustschin 2011-02-07 11:35 ` Guennadi Liakhovetski 2011-02-07 11:35 ` Guennadi Liakhovetski 2011-02-07 13:01 ` Detlev Zundel 2011-02-07 13:01 ` Detlev Zundel 2011-02-07 13:35 ` Guennadi Liakhovetski 2011-02-07 13:35 ` Guennadi Liakhovetski 2011-02-07 14:43 ` Detlev Zundel 2011-02-07 14:43 ` Detlev Zundel 2011-02-07 13:45 ` Anatolij Gustschin 2011-02-07 13:45 ` Anatolij Gustschin 2011-02-07 14:00 ` Guennadi Liakhovetski 2011-02-07 14:00 ` Guennadi Liakhovetski 2011-02-07 16:49 ` Guennadi Liakhovetski 2011-02-07 16:49 ` Guennadi Liakhovetski 2011-02-14 9:57 ` Dan Williams 2011-02-14 9:57 ` Dan Williams 2011-01-28 7:46 ` [PATCH 0/2] Fix issues with frame reception from CSI on i.MX31 Anatolij Gustschin 2011-01-28 7:46 ` Anatolij Gustschin
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.