Open bperez77 opened 8 years ago
Hi.
I'm trying to implement the multi-channel support, but I'm having some problems. I'm using this DT:
[...] amba_pl: amba_pl { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; ranges ; axi_dma_0: dma@40400000 { #dma-cells = <1>; clock-names = "s_axi_lite_aclk", "m_axi_sg_aclk", "m_axi_mm2s_aclk", "m_axi_s2mm_aclk"; clocks = <&clkc 15>, <&clkc 15>, <&clkc 15>, <&clkc 15>; compatible = "xlnx,axi-dma-1.00.a"; interrupt-parent = <&intc>; interrupts = <0 29 4 0 30 4>; reg = <0x40400000 0x10000>; xlnx,addrwidth = <0x20>; xlnx,include-sg ; xlnx,mcdma ; dma-channel@40400000 { compatible = "xlnx,axi-dma-mm2s-channel"; dma-channels = <0x2>; interrupts = <0 29 4>; xlnx,datawidth = <0x20>; xlnx,device-id = <0x0>; }; dma-channel@40400030 { compatible = "xlnx,axi-dma-s2mm-channel"; dma-channels = <0x1>; interrupts = <0 30 4>; xlnx,datawidth = <0x20>; xlnx,device-id = <0x1>; }; }; axidma_chrdev: axidma_chrdev@0 { compatible = "xlnx,axidma-chrdev"; dmas = <&axi_dma_0 0 &axi_dma_0 1 &axi_dma_0 2>; dma-names = "tx0", "tx1", "rx0"; }; }; [...]
With some tweaks in the code I am able to get the three DMA channels in dma_request_slave_channel
, however the read/write operations always time out.
As suggested on various threads, the structure is AXI DMA -> AXIS interconnect -> multiple devices (see the full BD here).
I've also tried with a simple module written from scratch: without the multi-channel both the reads and the writes work but, when I enable the multi-channel and add the interconnect and the two slaves, it only times out.
Any idea?
Yeah, as you found out, I haven't yet had a chance to add MCDMA support yet to the driver. Can you post the changes you've made to the driver on this thread? I can take a look over and see what the issue might be.
I'm not sure where you made all the changes, but if I had to guess, I'd imagine there's something in axidma_prep_transfer
that needs to be changed.
I'm working on a test scratch module right now, I haven't modified this driver yet.
It partially works now, I've found that the MCDMA works only with dmaengine_prep_interleaved_dma
and not with dmaengine_prep_slave_sg
. The main problem is related to the IRQs: the AXIDMA IP core has only two interrupt lines but the Xilinx DMA IRQ handler doesn't demultiplex the interrupt and always completes the descriptor of the first called handler (which should be the first registered).
I've modified xilinx_dma.c adding the correct demultiplexing and the TX seems to work now but the RX doesn't work yet.
I see that Xilinx has recently released (2017.3) a dedicated AXI MCDMA module with dedicated interrupt lines however, even if they claim they have Linux drivers, I haven't found any matching driver in their repository. I'll try to contact them and ask for more informations.
Sorry for the late reply, I missed the notification. I see, yeah things get more complicated with the IRQs because of the multiple channels. It doesn't surprise me they don't have it up yet for their backend driver; I faced similar issues with other features when I first started the driver. It's definitely not uncommon for Xilinx to overpromise and underdeliver.
It's interesting that the TX works properly but the RX times out. I'm guessing you're trying this with a simple loopback example? I can't see a reason why the RX wouldn't work.
According to the DMA doc all the channels must be configured before the data comes in. This complicates things, as we would need an extra reset line to keep the interconnects disabled (but not the DMA engine) until the DMA is fully configured.
For now I'm using multiple DMA controllers, maybe in the future I'll try again to make it work.
According to the DMA doc all the channels must be configured before the data comes in. This complicates things, as we would need an extra reset line to keep the interconnects disabled (but not the DMA engine) until the DMA is fully configured.
For now I'm using multiple DMA controllers, maybe in the future I'll try again to make it work.
Corna, can you please do a quick write up on how to compile your code? I am running into issue of copy_to_user not being available
The Zynq processing system has a limited number of DMA channels, so sharing the channel between multiple agents can be useful, if they have low bandwidth requirements.