I'm using the mxc_dma functions to do large, recurring DMA transfers (up to 512K bytes in length) from a 16-bit wide FPGA device on the EIM in the i.mx53.
I'm using the latest on the imx_2.6.35_maintain branch from the FSL linux-2.6-imx.git repository.
The problem I'm having is that my DMA callback routine keeps getting called after the data should all have been transferred.
First I call mxc_dma_disable() to disable the channel.
Here's the 16 buffers I request using mxc_dma_config(dma_channel, req, 16, MXC_DMA_MODE_READ):
[ 431.740287] req[0]: src_addr=0xf2000000 dst_addr=0x71f80000 num_of_bytes=32768
[ 431.770668] req[1]: src_addr=0xf2000000 dst_addr=0x71f88000 num_of_bytes=32768
[ 431.779915] req[2]: src_addr=0xf2000000 dst_addr=0x71f90000 num_of_bytes=32768
[ 431.800661] req[3]: src_addr=0xf2000000 dst_addr=0x71f98000 num_of_bytes=32768
[ 431.809910] req[4]: src_addr=0xf2000000 dst_addr=0x71fa0000 num_of_bytes=32768
[ 431.840658] req[5]: src_addr=0xf2000000 dst_addr=0x71fa8000 num_of_bytes=32768
[ 431.849906] req[6]: src_addr=0xf2000000 dst_addr=0x71fb0000 num_of_bytes=32768
[ 431.872501] req[7]: src_addr=0xf2000000 dst_addr=0x71fb8000 num_of_bytes=32768
[ 431.888411] req[8]: src_addr=0xf2000000 dst_addr=0x71fc0000 num_of_bytes=32768
[ 431.908045] req[9]: src_addr=0xf2000000 dst_addr=0x71fc8000 num_of_bytes=32768
[ 431.921424] req[10]: src_addr=0xf2000000 dst_addr=0x71fd0000 num_of_bytes=32768
[ 431.932638] req[11]: src_addr=0xf2000000 dst_addr=0x71fd8000 num_of_bytes=32768
[ 431.947103] req[12]: src_addr=0xf2000000 dst_addr=0x71fe0000 num_of_bytes=32768
[ 431.958613] req[13]: src_addr=0xf2000000 dst_addr=0x71fe8000 num_of_bytes=32768
[ 431.983398] req[14]: src_addr=0xf2000000 dst_addr=0x71ff0000 num_of_bytes=32768
[ 432.003369] req[15]: src_addr=0xf2000000 dst_addr=0x71ff8000 num_of_bytes=32768
Then I call mxc_dma_callback_set(), and mxc_dma_enable().
In the callback, I check for the error_status, and update my remaining count, then print a debug message:
[ 432.026618] dma_done_callback count=32768 remaining=491520
[ 432.034276] dma_done_callback count=32768 remaining=458752
[ 432.041906] dma_done_callback count=32768 remaining=425984
[ 432.049443] dma_done_callback count=32768 remaining=393216
[ 432.057022] dma_done_callback count=32768 remaining=360448
[ 432.064600] dma_done_callback count=32768 remaining=327680
[ 432.072174] dma_done_callback count=32768 remaining=294912
[ 432.079705] dma_done_callback count=32768 remaining=262144
[ 432.087275] dma_done_callback count=32768 remaining=229376
[ 432.094836] dma_done_callback count=32768 remaining=196608
[ 432.102397] dma_done_callback count=32768 remaining=163840
[ 432.109916] dma_done_callback count=32768 remaining=131072
[ 432.117473] dma_done_callback count=32768 remaining=98304
[ 432.124946] dma_done_callback count=32768 remaining=65536
[ 432.132422] dma_done_callback count=32768 remaining=32768
[ 432.139911] dma_done_callback count=32768 remaining=0
[ 432.147023] DMA complete
Now all the bytes I've wanted to have transferred should have been transferred.
I diagnose this, and then call mxc_dma_disable() on the channel.
Every time you see a "DMA complete" message, mxc_dma_disable() was called.
However, the callbacks keep coming. I call mxc_dma_disable() on each of them, but it doesn't help:
[ 432.151811] dma_done_callback count=32768 remaining=-32768
[ 432.159314] DMA complete
[ 432.163966] dma_done_callback count=32768 remaining=-65536
[ 432.171515] DMA complete
[ 432.176085] dma_done_callback count=32768 remaining=-98304
[ 432.183627] DMA complete
[ 432.188197] dma_done_callback count=32768 remaining=-131072
[ 432.195821] DMA complete
[ 432.200392] dma_done_callback count=32768 remaining=-163840
[ 432.208017] DMA complete
[ 432.212627] dma_done_callback count=32768 remaining=-196608
[ 432.220208] DMA complete
[ 432.224818] dma_done_callback count=32768 remaining=-229376
[ 432.232444] DMA complete
[ 432.237015] dma_done_callback count=32768 remaining=-262144
[ 432.244639] DMA complete
[ 432.249209] dma_done_callback count=32768 remaining=-294912
[ 432.256831] DMA complete
[ 432.261443] dma_done_callback count=32768 remaining=-327680
[ 432.269024] DMA complete
[ 432.273634] dma_done_callback count=32768 remaining=-360448
[ 432.281260] DMA complete
[ 432.285831] dma_done_callback count=32768 remaining=-393216
[ 432.293453] DMA complete
[ 432.298024] dma_done_callback count=32768 remaining=-425984
[ 432.305648] DMA complete
[ 432.310218] dma_done_callback count=32768 remaining=-458752
[ 432.317840] DMA complete
[ 432.322453] dma_done_callback count=32768 remaining=-491520
[ 432.330033] DMA complete
[ 432.334641] dma_done_callback count=32768 remaining=-524288
[ 432.342267] DMA complete
[ 432.346837] dma_done_callback count=32768 remaining=-557056
[ 432.354474] DMA complete
[ 432.359047] dma_done_callback count=32768 remaining=-589824
[ 432.366670] DMA complete
[ 432.371285] dma_done_callback count=32768 remaining=-622592
[ 432.378866] DMA complete
[ 432.383474] dma_done_callback count=32768 remaining=-655360
[ 432.391102] DMA complete
[ 432.395671] dma_done_callback count=32768 remaining=-688128
[ 432.403296] DMA complete
[ 432.407865] dma_done_callback count=32768 remaining=-720896
[ 432.415487] DMA complete
[ 432.420055] dma_done_callback count=32768 remaining=-753664
[ 432.427677] DMA complete
[ 432.432289] dma_done_callback count=32768 remaining=-786432
[ 432.439871] DMA complete
[ 432.444477] dma_done_callback count=32768 remaining=-819200
[ 432.452104] DMA complete
[ 432.456675] dma_done_callback count=32768 remaining=-851968
[ 432.464302] DMA complete
[ 432.468873] dma_done_callback count=32768 remaining=-884736
[ 432.476496] DMA complete
[ 432.481110] dma_done_callback count=32768 remaining=-917504
[ 432.488692] DMA complete
[ 432.493300] dma_done_callback count=32768 remaining=-950272
[ 432.500924] DMA complete
[ 432.505494] dma_done_callback count=32768 remaining=-983040
[ 432.513118] DMA complete
[ 432.517688] dma_done_callback count=32768 remaining=-1015808
[ 432.525399] DMA complete
[ 432.529970] dma_done_callback count=32768 remaining=-1048576
[ 432.537679] DMA complete
eventually, the completion is noticed by another part of my driver:
[ 432.548644] DMA took 520 msec
Every transfer with a given transfer size does not necessarily get the same number of extra callbacks.
The count isn't always 32K, either (see below).
The same thing happens with fewer buffers (this was a 64K transfer):
[ 140.417783] req[0]: src_addr=0xf2000000 dst_addr=0x71f80000 num_of_bytes=32768
[ 140.427689] req[1]: src_addr=0xf2000000 dst_addr=0x71f88000 num_of_bytes=32768
[ 140.441628] dma_done_callback count=32768 remaining=32768
[ 140.449152] dma_done_callback count=32768 remaining=0
[ 140.456219] DMA complete
[ 140.461215] dma_done_callback count=8 remaining=-8
[ 140.468012] DMA complete
[ 140.472571] dma_done_callback count=32768 remaining=-32776
[ 140.480062] DMA complete
[ 140.484622] dma_done_callback count=32768 remaining=-65544
[ 140.492113] DMA complete
[ 140.496671] dma_done_callback count=32768 remaining=-98312
[ 140.504162] DMA complete
[ 140.508778] dma_done_callback count=32768 remaining=-131080
[ 140.516359] DMA complete
[ 140.520920] dma_done_callback count=32768 remaining=-163848
[ 140.528497] DMA complete
[ 140.533055] dma_done_callback count=32768 remaining=-196616
[ 140.540633] DMA complete
[ 140.552313] DMA took 110 msec
Changing the chunk size from 32K to 4K didn't help; it would get to 256K/512K of the transfer and hang.
Does anyone have an idea why this may be happening?
Ned
This discussion is closed since no activity. If you still need help, please feel free to reply with an update to this
discussion, or create another discussion.
Thanks,
Yixing
Ned
Had your issue got resolved? If yes, we are going to close the discussion in 3 days. If you still need help please feel
free to contact Freescale.
Thanks,
Yixing
Hi Ned,
Have you been able to fix or work around your issue with the i.MX53's SDMA? Unfortunately, we don't have any available expertise in the apps team who can help you with this at this time. One thing that you might try, if you haven't already, is to visit this site - http://billauer.co.il/blog/2011/10/imx-sdma-howto-memory-map/. This seems like a pretty good tutorial, but may not be totally applicable to your particular needs - DMA'ing over the EIM.