Is something using DMA channel 0?

Philip Ashmore contact at philipashmore.com
Sun Nov 10 10:01:42 EST 2013


On 07/11/13 07:17, Craig McGeachie wrote:
> On 11/07/2013 05:57 PM, Philip Ashmore wrote:
>> Hi there.
>>
>> Please forgive me in advance if I'm posting this question on the wrong
>> list.
>>
>> I wrote a C++ library to control the Bcm2835 from user space:
>> v3c-raspi: http://sourceforge.net/projects/v3craspi/
>>
>> But it appears that something writes to the DMA channel 0 control
>> register at random intervals - I managed to get the i2s example running
>> for 5 seconds before the problem occurred. Other times it happens almost
>> immediately.
>>
>> I posted this bug originally:
>>
>> Is something using dma channel 0?
>> https://bugs.launchpad.net/raspbian/+bug/1231791
>>
>> Then I found someone else who wanted to do something like it:
>>
>> How fast is GPIO+DMA? Multi I2S input
>> http://raspberrypi.stackexchange.com/questions/9646/how-fast-is-gpiodma-multi-i2s-input/10287#10287
>>
>>
>> But no responses to either regarding my issue.
> 
> You don't say which version of the kernel you're using for the Raspberry
> Pi, so I assume that most likely you're using whatever comes with the
> distribution which will be sourced from the 3.6 branch of
> https://github.com/raspberrypi/linux.
> 
> This being the case, then typically the framebuffer driver will use
> DMA#0. It's the only channel available for use by the ARM that has an
> external 8 entry FIFO attached to it, so it's the most efficient for
> memory to memory block copy, which the framebuffer uses for its copyarea
> implementation, if it can.  I imagine this function would be invoked
> every time the console shifts up for a new line.  Or for any sort of
> bulk rectangle move in X11.
> 
> I had a quick look at some of your code.  You're manipulating IO memory
> directly through /dev/mem, so you'll be bypassing the arbitration
> mechanisms in arch/arm/mach-bcm2708/dma.c.  If you are interfering with
> DMA#0 when the kernel doesn't expect you to be, then I'm a little
> surprised you don't see a bit of corruption on the console display.
> 
> You mentioned elsewhere about setting dma.dmachans in cmdline.txt. While
> this might stop dma.c from allocating DMA#0 if it were passed through, I
> would doubt that it was passed through to the kernel by the videocore
> bootloader.  cat /proc/cmdline and check the output.  If your value for
> dma.dmachans is there, look for a second value that the bootloader
> added.  See if your value was just replaced (n.b. I'm too lazy to
> actually try this myself and see what happens).
> 
> If your value is the only one displayed in /proc/cmdline, then I really
> have no idea what's happening.
> 
> Incidentally, you mention passing 0x7ffe as the channel mask.  I suspect
> that this is not safe.  The typical value I see is 0x7f35 meaning that
> the videocore has reserved channels 1, 3, 6, 7, and 15 for itself.  You
Is this documented somewhere?
There should be a wiki that contains definitive information for this.
Better still, the kernel should be able to ask the videocore which DMA
channels it uses, as kernels and broadcom blobs can be mixed and
matched, unless this list of reserved channels doesn't change.

I got it mostly working now, but more detailed reference documentation
and an updated BCM document would have helped me rule out stuff and
forced me to re-examine my own code sooner.

The workflow I use:

 - edit documents in kate on my PC (I use Trinity)
 - compile in Qemu : make -j9
 - run program over nfs share on Raspberry Pi via ssh

allows for quick tests and edits and I can even reboot the 'pi while
updated sources are compiling, but sometimes the nfs share doesn't
notice there's a new executable on the host, so spotting a problem and
working through possible solutions to it can sometimes make for
interesting times, especially if you've also got a DMA channel pissing
GPIO data into random memory.

An then there's i2s with it's "cout << '.' << flush" every couple of
seconds - I probably had the solution and skipped it onto the next
iteration without realising :(

Oh, and the other useful resource would of course be code written and
tested by others.
I guess once I've got this nailed down and published it can be a
resource for others - I'm sure an 8 channel digital signal analyser
capable of 4M samples/sec is bound to be of use to someone, although how
consistent it is and whether bus contention issues mess with the timing
are the subject of future experiments and someone with a better signal
analyser than I have (a bus pirate).

This still leaves the question: how do user mode programs arbitrate DMA
channel usage?

I guess the only way to do it for now is to reserve DMA channels using
dma.dmachans and configure the programs you want to use so they don't
conflict.

I'll go with dma.dmachans=0x7f04 to let user mode programs use DMA
channels 0,4 and 5 as I don't use the console much.

> probably don't want to tell ARM core code that it can use these
> channels.  That said, I think most of the time it won't be an issue.
> Kernel code makes very little use of the DMA channels.
> 
>> Is this the right place to post this question?
> 
> I really couldn't say. Despite you getting a, hopefully, helpful answer
> here, I would have thought that http://www.raspberrypi.org/forum would
> have been a better place.
> 
> Cheers,
> Craig.
> 
Thanks everyone for your input, I sure hope the relevant information
gets posted somewhere!

Regards,
Philip Ashmore



More information about the linux-rpi-kernel mailing list