Page 1 of 1

DMA synchronization of buffer ioremapped from the SRAM

Posted: Sun Oct 23, 2011 10:05 am
by wzab
I'm trying to get the USART working in sync mode at 6Mb/s. It appeared, that to achieve that I have to move the RX buffer to the internal SRAM.
I allocate the buffer with request_mem_region and map it with ioremap to obtain the virtual address for kernel.
However, after that, the dma_sync_single_for_cpu called from atmel_rx_from_dma causes the kernel panic.
So my question is:
1. Is it necessary to synchronize the DMA buffers located in the internal SRAM?
2. If yes, what are the proper functions to perform this synchronization?
I've checked the system diagram (Fig. 2-1 in the doc6221 - ... oc6221.pdf ) and I can see, that the SRAM is accessible via the switch matrix, and therefore via the cache system, so synchronization is probably necessary...
I have analyzed how the dma_sync_single_for_cpu works and it seems, that I can call directly:
Unfortunately it appears, that the above function does not accept neither ioremapped virtual address of the buffer nor the virtual address obtained via __phys_to_virt from the physical address of the buffer.
Use of both triggers the bug at: ... ing.c#L451
I have found, that that my buffer
is allocated at 0x200000 (SRAM0) and ioremapped to 0xc4890000, while
high_memory is at 0xc4000000. Therefore my buffer address fails the
test of address validity at ... ory.h#L292 .

It could suggest that accesses to my buffer bypass the cache (as it is above high_memory location), but when I simply skip the synchronization routines, I still get corrupted data.
On comp.arch.embedded I received a suggestion that the problem may be associated with handling of accesses by a Bus Matrix...
TIA & Regards,

Re: DMA synchronization of buffer ioremapped from the SRAM

Posted: Sun Feb 24, 2019 4:07 pm
by maohong
Hi wzab,
The version of github 2.2.39 already supports DMA communication, but there are problems during debugging.

When I use DMA to receive data from the serial port, I added some logs for debugging. I found that the function atmel_rx_from_dma() can be called, but the log shows pending=0, ring->head=0, sg_dma_len(&atmel_port->sg_rx) =4096, State.residue=4096, the status of dmastat is DMA_IN_PROGRESS, obviously no serial port data is received. I don't understand why the interrupt has been received, but the DMA does not start receiving serial data.

Could you give me some advice?

Best Regards