linux/drivers/dma
Russell King - ARM Linux d1a792f3b4 Update imx-sdma cyclic handling to report residue
I received a report this morning from one of the Novena developers that
the behaviour of the iMX6 ASoC codec driver (using imx-pcm-dma.c) was
sub-optimal under high system load.

While there are issues relating to system load remaining, upon reviewing
the ASoC imx-pcm-dma.c driver, it was noticed that it not using the
residue support, because SDMA doesn't support it.  This has the effect
that SDMA has to make multiple calls into the ASoC and ALSA code, one
for each period.

Since ALSA's snd_pcm_elapsed() does not need to be called multiple times
and it is entirely sufficient to call it once to update ALSA with the
current buffer position via the pointer method, we can do better here.
We can also avoid stopping the DMA entirely, just like real cyclic DMA
implementations behave.  While this means that we replay some old samples,
this is a nicer behaviour than having audio stop and restart.

The changes to achieve this are relatively minor - imx-sdma.c can track
where the DMA is to the nearest descriptor boundary - it does this
already when deciding how many callbacks to issue.  In doing this,
buf_tail always points at the descriptor which will complete next.

The residue is defined by the bytes remaining to the end of the buffer,
when the buffer is viewed as a single block of memory [start...end].
So, when we start out, there's a full buffer worth of residue, and this
counts down as we approach the end of the buffer, eventually becoming
zero at the end, before returning to the full buffer worth when we
wrap back to the start.

Moving the walking of the descriptors into the interrupt handler means
that we can update the BD_DONE flag at interrupt time, thus avoiding
a delayed tasklet stopping the cyclic DMA.

This means that the residue can be calculated from (total descriptors -
buf_tail) * descriptor size.  This is what the change below does.  We
update imx-pcm-dma.c to remove the NO_RESIDUE flag since we now provide
the residue.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
2014-07-01 12:23:42 +05:30
..
bestcomm
dw Merge branch 'topic/dw' into for-linus 2014-06-09 21:55:40 +05:30
ioat ioat: fix tasklet tear down 2014-02-25 09:44:20 -08:00
ipu
ppc4xx Merge branch 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma 2014-01-29 20:27:23 -08:00
sh dmaengine: sh: don't use dynamic static allocation 2014-06-03 11:35:33 +05:30
xilinx dma: Add Xilinx AXI Video Direct Memory Access Engine driver support 2014-04-30 10:44:13 +05:30
acpi-dma.c acpi-dma: convert to return error code when asked for channel 2014-02-11 23:30:50 +05:30
amba-pl08x.c dma: pl08x: Export pl08x_filter_id 2014-01-28 08:45:54 +05:30
at_hdmac_regs.h
at_hdmac.c dmaengine: at_hdmac: use tasklet_kill in teardown 2014-03-17 18:33:43 +05:30
bcm2835-dma.c dmaengine: Add DMA_PRIVATE to BCM2835 driver 2014-01-20 12:31:50 +05:30
coh901318_lli.c
coh901318.c
coh901318.h
cppi41.c dma: cppi41: handle 0-length packets 2014-07-01 12:15:48 +05:30
dma-jz4740.c
dmaengine.c dmaengine: fix dmaengine_unmap failure 2014-05-21 14:02:37 -07:00
dmaengine.h
dmatest.c Add new line to test result strings produced in verbose mode 2014-03-26 11:41:45 +05:30
edma.c dmaengine: edma: update DMA memcpy to use new param element 2014-04-30 10:36:57 +05:30
ep93xx_dma.c
fsl-edma.c dma: fix eDMA driver as a subsys_initcall 2014-04-16 12:03:47 +05:30
fsldma.c DMA: Freescale: move functions to avoid forward declarations 2014-05-02 22:17:43 +05:30
fsldma.h DMA: Freescale: change BWC from 256 bytes to 1024 bytes 2014-01-20 13:13:22 +05:30
imx-dma.c dma: imx-dma: Add missing module owner field 2014-03-06 20:51:09 +05:30
imx-sdma.c Update imx-sdma cyclic handling to report residue 2014-07-01 12:23:42 +05:30
intel_mid_dma_regs.h
intel_mid_dma.c
iop-adma.c
iovlock.c
k3dma.c dmaengine: k3dma: fix sparse warnings 2014-01-20 13:53:20 +05:30
Kconfig Merge branch 'topic/xilinx' into for-linus 2014-06-09 21:56:29 +05:30
Makefile dma: Add Xilinx AXI Video Direct Memory Access Engine driver support 2014-04-30 10:44:13 +05:30
mmp_pdma.c dma: mmp_pdma: add support for residue reporting 2014-05-07 12:33:40 +05:30
mmp_tdma.c dma: mmp_tdma: move to generic device tree binding 2014-03-06 14:49:54 +05:30
moxart-dma.c dmaengine: Add MOXA ART DMA engine driver 2014-01-20 12:32:46 +05:30
mpc512x_dma.c dmaengine: mpc512x: add support for peripheral transfers 2014-05-22 10:37:01 +05:30
mv_xor.c dma: mv_xor: Flush descriptors before activating a channel 2014-05-21 14:02:35 -07:00
mv_xor.h
mxs-dma.c
of-dma.c
omap-dma.c Merge branch 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma 2014-04-10 08:55:08 -07:00
pch_dma.c dmaengine: pch: fix compilation for alpha target 2014-05-22 18:50:49 +05:30
pl330.c Merge branch 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma 2014-01-29 20:27:23 -08:00
qcom_bam_dma.c dmaengine: add Qualcomm BAM dma driver 2014-04-05 20:44:26 +05:30
s3c24xx-dma.c dmaengine: s3c24xx-dma: Add cyclic transfer support 2014-06-01 22:22:51 +05:30
sa11x0-dma.c dmaengine: sa11x0: remove broken #ifdef 2014-05-21 11:40:49 +05:30
sirf-dma.c dmaengine: sirf: off by one in of_dma_sirfsoc_xlate() 2014-04-16 11:59:24 +05:30
ste_dma40_ll.c
ste_dma40_ll.h
ste_dma40.c dma: ste_dma40: Convert to the late system PM callbacks 2014-05-07 15:32:07 +05:30
tegra20-apb-dma.c Merge branch 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma 2014-01-29 20:27:23 -08:00
timb_dma.c
TODO
txx9dmac.c
txx9dmac.h
virt-dma.c
virt-dma.h dma: fix vchan_cookie_complete() debug print 2014-01-26 17:33:45 +05:30