Hi,
On 03/22/2013 01:49 PM, Peter Meerwald wrote:
I'm running Linux 3.7 on a beagle-xm and observe very reproducible stereo channel swapping issue on playback of a stereo stream (one channel has a sine, the other is zero); the channel swap occurs on starting the playback
it appears that the swapping issue is back, probably due to the DMA rework in recent kernel?
kernel 3.4 does not have the issue
Well, then, I guess, you'll have to bisect it down.
here it is: 946cc36ae550ea52adee0f42ac5034a34b5393be is the first bad commit commit 946cc36ae550ea52adee0f42ac5034a34b5393be Author: Peter Ujfalusi peter.ujfalusi@ti.com Date: Fri Sep 14 15:05:58 2012 +0300
ASoC: omap-pcm: Convert to use dmaengine Original author: Russell King <rmk+kernel@arm.linux.org.uk> Switch the omap-pcm to use dmaengine. Certain features are not supported by after dmaengine conversion: 1. No period wakeup mode DMA engine has no way to communicate this information through standard channels. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Tested-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Yes the issue surfaced again with the dmaengine conversion. But at the end it boils down to the OMAP dmaengine implementation. For audio to work correctly we expect that the DMA _is_ started after the omap_dma_issue_pending() call, but it is not true for OMAP.
omap_dma_issue_pending() will start a tasklet which is in charge to start the DMA.
In audio case this is how the call chain looks like:
beagle-gentoo ~ # aplay media/2ch-left-since.wav -q [ 473.128753] omap-dma-engine omap-dma-engine: allocating channel for 33 [ 473.139587] omap_mcbsp_dai_set_dai_fmt [ 473.148345] omap_mcbsp_dai_hw_params: [ 473.155822] omap_mcbsp_config: [ 473.160369] omap_pcm_trigger: start [ 473.164062] omap_dma_prep_dma_cyclic (dma_ch: 2) [ 473.173828] omap_dma_issue_pending (dma_ch: 2) [ 473.177795] omap_mcbsp_dai_trigger: start [ 473.182006] omap_mcbsp_start [ 473.189025] omap_dma_sched [ 473.191864] omap_dma_start_sg (dma_ch: 2)
You can see that McBSP is started before the DMA because of the tasklet in drivers/dma/dma-omap.c
Russell: can we remove the tasklet use from dma-omap and start the DMA right away in omap_dma_issue_pending()? This is the only way to prevent channel swap when starting audio. Other devices might not care if the DMA is not started at the time we tell it to start, but for audio we need to make sure it is.