All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2 v3] dmaengine: rcar-dmac: ensure CHCR DE bit is actually 0 after clearing
  2017-11-17  2:08 [PATCH 0/2 v3] dmaengine: rcar-dmac: use TCRB instead of TCR Kuninori Morimoto
@ 2017-11-17  2:00 ` Kuninori Morimoto
  2017-11-17  2:09 ` [PATCH 2/2 v3] dmaengine: rcar-dmac: use TCRB instead of TCR for residue Kuninori Morimoto
  2017-11-29 14:13 ` [PATCH 0/2 v3] dmaengine: rcar-dmac: use TCRB instead of TCR Vinod Koul
  2 siblings, 0 replies; 4+ messages in thread
From: Kuninori Morimoto @ 2017-11-17  2:00 UTC (permalink / raw)
  To: Geert Uytterhoeven, Laurent Pinchart, Dan Williams, Vinod Koul
  Cc: Niklas Söderlund, dmaengine, linux-kernel, Hiroyuki Yokoyama

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

DMAC reads data from source device, and buffered it until transferable
size for sink device. Because of this behavior, DMAC is including
buffered data .

Now, CHCR DE bit is controlling DMA transfer enable/disable.

If DE bit was cleared during data transferring, or during buffering,
it will flush buffered data if source device was peripheral device
(The buffered data will be removed if source device was memory).
Because of this behavior, driver should ensure that DE bit is actually
0 after clearing.

This patch adds new rcar_dmac_chcr_de_barrier() and call it after CHCR
register access.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
Tested-by: Ryo Kodama <ryo.kodama.vz@renesas.com>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v2 -> v3

 - fixups many typo on gitlog / comment
 - added Geert's Tested-by

 drivers/dma/sh/rcar-dmac.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
index 2b2c7db..c99fd0f 100644
--- a/drivers/dma/sh/rcar-dmac.c
+++ b/drivers/dma/sh/rcar-dmac.c
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
 #include <linux/interrupt.h>
@@ -741,6 +742,24 @@ static int rcar_dmac_fill_hwdesc(struct rcar_dmac_chan *chan,
 /* -----------------------------------------------------------------------------
  * Stop and reset
  */
+static void rcar_dmac_chcr_de_barrier(struct rcar_dmac_chan *chan)
+{
+	u32 chcr;
+	unsigned int i;
+
+	/*
+	 * Ensure that the setting of the DE bit is actually 0 after
+	 * clearing it.
+	 */
+	for (i = 0; i < 1024; i++) {
+		chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
+		if (!(chcr & RCAR_DMACHCR_DE))
+			return;
+		udelay(1);
+	}
+
+	dev_err(chan->chan.device->dev, "CHCR DE check error\n");
+}
 
 static void rcar_dmac_chan_halt(struct rcar_dmac_chan *chan)
 {
@@ -749,6 +768,7 @@ static void rcar_dmac_chan_halt(struct rcar_dmac_chan *chan)
 	chcr &= ~(RCAR_DMACHCR_DSE | RCAR_DMACHCR_DSIE | RCAR_DMACHCR_IE |
 		  RCAR_DMACHCR_TE | RCAR_DMACHCR_DE);
 	rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr);
+	rcar_dmac_chcr_de_barrier(chan);
 }
 
 static void rcar_dmac_chan_reinit(struct rcar_dmac_chan *chan)
@@ -1481,6 +1501,8 @@ static irqreturn_t rcar_dmac_isr_channel(int irq, void *dev)
 	if (chcr & RCAR_DMACHCR_TE)
 		mask |= RCAR_DMACHCR_DE;
 	rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr & ~mask);
+	if (mask & RCAR_DMACHCR_DE)
+		rcar_dmac_chcr_de_barrier(chan);
 
 	if (chcr & RCAR_DMACHCR_DSE)
 		ret |= rcar_dmac_isr_desc_stage_end(chan);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 0/2 v3] dmaengine: rcar-dmac: use TCRB instead of TCR
@ 2017-11-17  2:08 Kuninori Morimoto
  2017-11-17  2:00 ` [PATCH 1/2 v3] dmaengine: rcar-dmac: ensure CHCR DE bit is actually 0 after clearing Kuninori Morimoto
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Kuninori Morimoto @ 2017-11-17  2:08 UTC (permalink / raw)
  To: Geert Uytterhoeven, Laurent Pinchart, Dan Williams, Vinod Koul
  Cc: Niklas Söderlund, dmaengine, linux-kernel, Hiroyuki Yokoyama


Hi Vinod
Cc Geert, Laurent

These are v3 of dmaengine fixup for Renesas SoC.
Main diffs are fixup typo

Kuninori Morimoto (2):
  dmaengine: rcar-dmac: ensure CHCR DE bit is actually 0 after clearing
  dmaengine: rcar-dmac: use TCRB instead of TCR for residue

 drivers/dma/sh/rcar-dmac.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

-- 
1.9.1



Best regards
---
Kuninori Morimoto

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/2 v3] dmaengine: rcar-dmac: use TCRB instead of TCR for residue
  2017-11-17  2:08 [PATCH 0/2 v3] dmaengine: rcar-dmac: use TCRB instead of TCR Kuninori Morimoto
  2017-11-17  2:00 ` [PATCH 1/2 v3] dmaengine: rcar-dmac: ensure CHCR DE bit is actually 0 after clearing Kuninori Morimoto
@ 2017-11-17  2:09 ` Kuninori Morimoto
  2017-11-29 14:13 ` [PATCH 0/2 v3] dmaengine: rcar-dmac: use TCRB instead of TCR Vinod Koul
  2 siblings, 0 replies; 4+ messages in thread
From: Kuninori Morimoto @ 2017-11-17  2:09 UTC (permalink / raw)
  To: Geert Uytterhoeven, Laurent Pinchart, Dan Williams, Vinod Koul
  Cc: Niklas Söderlund, dmaengine, linux-kernel, Hiroyuki Yokoyama


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

SYS/RT/Audio DMAC includes independent data buffers for reading
and writing. Therefore, the read transfer counter and write transfer
counter have different values.
TCR indicates read counter, and TCRB indicates write counter.
The relationship is like below.

	        TCR       TCRB
	[SOURCE] -> [DMAC] -> [SINK]

In the MEM_TO_DEV direction, what really matters is how much data has
been written to the device. If the DMA is interrupted between read and
write, then, the data doesn't end up in the destination, so shouldn't
be counted. TCRB is thus the register we should use in this cases.

In the DEV_TO_MEM direction, the situation is more complex. Both the
read and write side are important. What matters from a data consumer
point of view is how much data has been written to memory.
On the other hand, if the transfer is interrupted between read and
write, we'll end up losing data. It can also be important to report.

In the MEM_TO_MEM direction, what matters is of course how much data
has been written to memory from data consumer point of view.
Here, because read and write have independent data buffers, it will
take a while for TCR and TCRB to become equal. Thus we should check
TCRB in this case, too.

Thus, all cases we should check TCRB instead of TCR.

Without this patch, Sound Capture has noise after PulseAudio support
(= 07b7acb51d2 ("ASoC: rsnd: update pointer more accurate")), because
the recorder will use wrong residue counter which indicates transferred
from sound device, but in reality the data was not yet put to memory
and recorder will record it.

However, because DMAC is buffering data until it can be transferable
size, TCRB might not be updated.
For example, if consumer doesn't know how much data can be received,
it requests enough size to DMAC. But in reality, it might receive very
few data. In such case, DMAC just buffered it until transferable size,
and no TCRB updated.

In such case, this buffered data will be transferred if CHCR::DE bit was
cleared, and this is happen if rcar_dmac_chan_halt(). In other word, it
happen when consumer called dmaengine_terminate_all().

Because of this behavior, it need to flush buffered data when it returns
"residue" (= dmaengine_tx_status()).
Otherwise, consumer might calculate wrong things if it called
dmaengine_tx_status() and dmaengine_terminate_all() consecutively.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
Tested-by: Ryo Kodama <ryo.kodama.vz@renesas.com>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v2 -> v3

 - fixups many typo on gitlog / comment
 - added Geert's Tested-by

 drivers/dma/sh/rcar-dmac.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
index c99fd0f..3bbd11d 100644
--- a/drivers/dma/sh/rcar-dmac.c
+++ b/drivers/dma/sh/rcar-dmac.c
@@ -761,6 +761,23 @@ static void rcar_dmac_chcr_de_barrier(struct rcar_dmac_chan *chan)
 	dev_err(chan->chan.device->dev, "CHCR DE check error\n");
 }
 
+static void rcar_dmac_sync_tcr(struct rcar_dmac_chan *chan)
+{
+	u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
+
+	if (!(chcr & RCAR_DMACHCR_DE))
+		return;
+
+	/* set DE=0 and flush remaining data */
+	rcar_dmac_chan_write(chan, RCAR_DMACHCR, (chcr & ~RCAR_DMACHCR_DE));
+
+	/* make sure all remaining data was flushed */
+	rcar_dmac_chcr_de_barrier(chan);
+
+	/* back DE */
+	rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr);
+}
+
 static void rcar_dmac_chan_halt(struct rcar_dmac_chan *chan)
 {
 	u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
@@ -1329,8 +1346,11 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan,
 		residue += chunk->size;
 	}
 
+	if (desc->direction == DMA_DEV_TO_MEM)
+		rcar_dmac_sync_tcr(chan);
+
 	/* Add the residue for the current chunk. */
-	residue += rcar_dmac_chan_read(chan, RCAR_DMATCR) << desc->xfer_shift;
+	residue += rcar_dmac_chan_read(chan, RCAR_DMATCRB) << desc->xfer_shift;
 
 	return residue;
 }
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2 v3] dmaengine: rcar-dmac: use TCRB instead of TCR
  2017-11-17  2:08 [PATCH 0/2 v3] dmaengine: rcar-dmac: use TCRB instead of TCR Kuninori Morimoto
  2017-11-17  2:00 ` [PATCH 1/2 v3] dmaengine: rcar-dmac: ensure CHCR DE bit is actually 0 after clearing Kuninori Morimoto
  2017-11-17  2:09 ` [PATCH 2/2 v3] dmaengine: rcar-dmac: use TCRB instead of TCR for residue Kuninori Morimoto
@ 2017-11-29 14:13 ` Vinod Koul
  2 siblings, 0 replies; 4+ messages in thread
From: Vinod Koul @ 2017-11-29 14:13 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: Geert Uytterhoeven, Laurent Pinchart, Dan Williams,
	Niklas Söderlund, dmaengine, linux-kernel,
	Hiroyuki Yokoyama

On Fri, Nov 17, 2017 at 02:08:16AM +0000, Kuninori Morimoto wrote:
> 
> Hi Vinod
> Cc Geert, Laurent
> 
> These are v3 of dmaengine fixup for Renesas SoC.
> Main diffs are fixup typo

Applied, thanks

-- 
~Vinod

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-11-29 14:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-17  2:08 [PATCH 0/2 v3] dmaengine: rcar-dmac: use TCRB instead of TCR Kuninori Morimoto
2017-11-17  2:00 ` [PATCH 1/2 v3] dmaengine: rcar-dmac: ensure CHCR DE bit is actually 0 after clearing Kuninori Morimoto
2017-11-17  2:09 ` [PATCH 2/2 v3] dmaengine: rcar-dmac: use TCRB instead of TCR for residue Kuninori Morimoto
2017-11-29 14:13 ` [PATCH 0/2 v3] dmaengine: rcar-dmac: use TCRB instead of TCR Vinod Koul

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.