summaryrefslogtreecommitdiffstats
path: root/meta-rcar-gen3/recipes-kernel/linux/linux-renesas/0002-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-for-resi.patch
diff options
context:
space:
mode:
authorScott Murray <scott.murray@konsulko.com>2017-11-30 13:31:13 -0500
committerScott Murray <scott.murray@konsulko.com>2017-11-30 18:33:40 +0000
commit592c4aca65cc41ea9e5757084ae1d488d2bbd8b0 (patch)
treed50ed692acae0b9d1942722ffc933d947366daf7 /meta-rcar-gen3/recipes-kernel/linux/linux-renesas/0002-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-for-resi.patch
parentbdc832727d28d715f417b831daa78537609b6208 (diff)
[COMMUNITY] Add M3 audio quality patcheseel_4.99.4eel/4.99.44.99.4eel-orig
Add the patches from SPEC-1057 for M3 audio quality to linux-renesas. Bug-AGL: SPEC-1057 Change-Id: Ia1413521034519ca9b49c481a55e519864857ce6 Signed-off-by: Scott Murray <scott.murray@konsulko.com>
Diffstat (limited to 'meta-rcar-gen3/recipes-kernel/linux/linux-renesas/0002-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-for-resi.patch')
-rw-r--r--meta-rcar-gen3/recipes-kernel/linux/linux-renesas/0002-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-for-resi.patch104
1 files changed, 104 insertions, 0 deletions
diff --git a/meta-rcar-gen3/recipes-kernel/linux/linux-renesas/0002-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-for-resi.patch b/meta-rcar-gen3/recipes-kernel/linux/linux-renesas/0002-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-for-resi.patch
new file mode 100644
index 0000000..3454dff
--- /dev/null
+++ b/meta-rcar-gen3/recipes-kernel/linux/linux-renesas/0002-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-for-resi.patch
@@ -0,0 +1,104 @@
+From f5c857fb5913dcb4eea2e213ee69790b6dc127dd Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 13 Nov 2017 13:34:04 +0900
+Subject: [PATCH 2/3] dmaengine: rcar-dmac: use TCRB instead of TCR for residue
+
+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 PluseAudio 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 receaved,
+it requests enough size to DMAC. But in reality, it might receave very
+few data. In such case, DMAC just buffered it untile transferable size,
+and no TCRB updated.
+
+In such case, this buffered data will be transfered 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>
+---
+ 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 16ebd5d..9cb85b2 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 fulshed */
++ 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
+