[alsa-devel] twl4030: runtime audio capture channel swapping (kernel 3.18+)

Peter Ujfalusi peter.ujfalusi at ti.com
Thu Aug 11 11:14:02 CEST 2016


Hi Akram,

On 08/11/16 04:07, Akram Hameed wrote:
> Hei Peter,
> 
> Sorry to bother you directly, but I got no response to my questions on the
> alsa-devel list and since you seem to be a maintainer of the omap mcbsp and
> pcm code, I thought you would:

Sorry, it looks like I have missed your mail in alsa-devel. Adding it to CC
and also looping Jarkko.

> a) Want to be aware of my issues
> 
> b) Might help point me in a direction to fix things.
> 
> In short: I am capturing a stereo audio stream, 16-bit, 48kHz using a gumstix
> overo that is quite similar to the older beagleboards (we are using two
> variants - one is OMAP3530 based and the other, DM3730). Periodically, left
> channel audio will move to right channel and vice versa over time.
> 
> Previously my company was using a branch from kernel 3.0 (made by Steve
> Sakoman) and our audio capture was fine - no swapping, ever. Due to
> instabilities with the old mmc interface (unpredictable failures using newer
> UHS-3 cards), we have been forced to migrate to a newer kernel, and here I
> encounter the channel swap issue.
> 
> To me, it seems the problem is like what is described
> here: http://processors.wiki.ti.com/index.php/McBSP_Channel_Swapping
> Which I presume draws on a discussion you had years ago with one
> Ying: http://mailman.alsa-project.org/pipermail/alsa-devel/2011-February/036895.html
> 
> After spending quite some time reading and investigating the various
> registers, I come to the following conclusions:
> 
> 1) Audio codec (TWL) appears to be configured in the same between working
> (3.0) and non working (3.18) kernels, except that voice mode is active also
> and some gain settings are different (different defaults, I suppose). I have a
> comparison of these register maps if you want to see.
> 
> 2) McBSP2 is also configured the same between old and new kernels, though I
> note for some reason the ID pulled by dev_dbg looks spurious, though I guess
> unrelated to my issue.
> Configuring McBSP255  phys_base: 0x49022000
> **** McBSP255 regs ****
> DRR2:  0xf88a
> DRR1:  0x0000
> DXR2:  0x0000
> DXR1:  0x0000
> SPCR2: 0x0230
> SPCR1: 0x0031
> RCR2:  0x8041
> RCR1:  0x0040
> XCR2:  0x8041
> XCR1:  0x0040
> SRGR2: 0x001f
> SRGR1: 0x0f00
> PCR0:  0x000f
> ***********************

We must drop the DRR1/2 (and probably DXR1/2) dump... By reading the DRR
register with the debug code we introduce underflow. The data must be only
moved by the DMA from the DATA registers. If we have low threshold it is more
likely to cause channel swap and it is for sure going to introduce missing
data - the data is going to the kernel log instead of the receive buffer.

> 3) My channel swapping occurs when using dma_op_mode element OR threshold mode
> in kernel 3.18+ (I have only tested on 3.18 and 4.4, for the record). Setting
> a threshold of 960 with period size 10ms reduces the frequency of the swap. 
> 
> I did notice that DMA CCR is different between kernel 3 and 3.18 when
> operating in ELEMENT mode. 
> 
> Version 3 kernel:
> 
> DMA4:Chan5 @ 48056200:CCR=/dev/mem opened.
> Memory mapped at address 0x4013b000.
> Read at address  0x48056200 (0x4013b200): 0x01084482
> 
> 
> Version 3.18 kernel:
> 
> DMA4:Chan5 @ 48056200:CCR=/dev/mem opened.
> Memory mapped at address 0xb6fa1000.
> Read at address  0x48056200 (0xb6fa1200): 0x010C44A2	<- McBSP2 RX request.
> 
> 
> Interestingly, it appears the new kernel (3.18+) is using packet mode even
> when 'element' is selected. If I choose dma_op_mode THRESHOLD in the older
> kernel 3.0, I see the same 0x010C44A2 in the CCR as I do in 3.18+.

Yes, I have made a change that if we are in element mode we will still use
packet mode to transfer one sample per DMA request. Real element mode will be
used only in case of mono audio. If the audio is 2+ channels we are using
packet mode to transfer the sample. This does helped to avoid swaps as we
send/receive one sample at a time from/to McBSP.

> 4) I have not observed playback channel swapping. I am unsure why.
> 
> 5) I enabled underflow and overflow reporting in the McBSP IRQ handler (kernel
> 3.18+ since older 3 kernel did not have such a handler and I have not patched
> one in yet), and found several interesting things.

I can not recall the history, but between 3.0 and 3.18 we might moved to
dmaengine based PCM for OMAPs. But I still have no recollection to experience
capture side channel swap.

> a) Swap definitely is happening due to Overflow, but so far I only observe an
> overflow when using dma_op_mode THRESHOLD. When using dma_op_mode THRESHOLD,
> the swap does not seem to coincide with an underflow, so I am at a loss to
> explain further.

How does you application works? What are the parameters ALSA is configured for
capture/playback (cat /proc/asound/card0/pcm0p/sub0/hw_params; cat
/proc/asound/card0/pcm0c/sub0/hw_params) - number of periods, etc?

> b) In dma_op_mode ELEMENT, I get Underflow reported almost every second in
> this newer kernel (again, using 10ms period size). Channel swap only seems to
> occur ever few hours, however, and I do not believe I have observed the
> overflow at all in ELEMENT mode. So, the swap occurs due to underflow, maybe?

Underflow in McBSP or Underflow by ALSA?

Underflow in McBSP RX tells that DMA is trying to read data when the FIFO is
empty. This can only happen if something else is reading data also from the
McBSP since we configure the McBSP and sDMA in sync.

Overflow in McBSP happens when DAM is failing to read the data out from McBSP
FIFO in time - FIFO is full and McBSP discards the incoming data)

ALSA underflow is different, it happens when the application fails to process
the period in time and the DMA starts to rewrite the buffer. This happens when
you have one thread to capture/process/play. If the process/play takes more
time than we go round in the boffer (buffer time) we have ALSA underflow. You
can try to increase the number of periods or separate the capture and
process/play jobs into separate threads.

> My plan from now is to get my JTAG up and running and try and make the change
> "If you are working with 16-bit stereo data a nice solution is to configure
> the McBSP for a single 32-bit element instead of 2 16-bit elements. "

The McBSP driver does not have support for this ATM. There is a side effect of
this AFAIK: channels will be swapped, but I have not tested it.
Using 32bit element instead of 2x16bit helps in case when you do not have FIFO
for sure to give more time for the DMA. Also in case of underrun/overrun you
will be loosing both channel's data so the swap would not happen.

> If you have any helpful suggestions, I would really appreciate them. I am
> operating under the assumption I can leave the TWL codec settings as they are
> and just 'lie' to McBSP about the data framing. Namely, specify single phase
> frame with 1 word of 32 bits, and set DMA packet size to a 32bit word also.
> Since 16 bit mode operates by default in dual phase, I am not sure if the
> signalling will work correctly, but I guess I will find out.

Yeah, this is also going to be a problem. As twl4030 is using I2S when in
stereo mode, with fake mono 32bit you can not use I2S signals. But since McBSP
is looking for the start condition, configuring it for DSP_A mode will
probably going to start the reception/playback at the correct time.

> Again, my apologies for contacting you directly. Hopefully the information I
> have provided can help diagnosing the real problem in the kernel.

No problem. Sorry for that I have missed your mail in alsa-devel.

> For me, I
> must find a solution in the near-term so I will try to figure out some hacks
> as described in the Wiki article.

The wiki page was written for daVinci devices AFAIK where they don't have FIFO
for their McBSP.

-- 
Péter


More information about the Alsa-devel mailing list