05-12-2015 02:08 PM
I am working on a project that includes using the Zynq PL330 DMA controller to transfer memory back and forth between host and the endpoint via a PCIe interconnect. However, we are running into some issues using it through the standard Linux DMA API. I've tried this with kernels petalinux 2014.2 - 4, xlnx 3.17, and 4.1, and they all had similar issues.
To our understanding, the memory transfers happen in the amounts of bus width * burst size, which only amounts to very small transfers and takes long to do. We tried increasing the burst size to something large, but found that it corrupts the data being transferred. We were only able to get transfers to work with a bus width aligned to the addresses and length and a burst size of 1. Ideally, we want to transfer something like, 64KB of data in one go without it being split up in these bursts.
Is there any information that can be provided to us that can give us the solution we need? Any configuration that we can change to get this to work?
05-13-2015 09:57 AM
From what I have seen, in struct dma_slave_config, the dst_maxburst and src_maxburst parameters are ignored in the pl330.c driver. I am surprised if changing these values changed your program behaviour. I had to replace 2 lines like this in pl330.c from this
desc->rqcfg.brst_len = 1
desc->rqcfg.brst_len = pch->burst_len
You usually cannot have a super large burst size. It is limited by the bus-width and burst length on each end of the transfer. Lesser of the two ends. Most DRAM has a BL of 8 words. However, I found that a burst length of 2 will double transfer speeds, 4 will increase by 4 times. Small burst lengths can be useful.
05-13-2015 10:23 AM
05-13-2015 03:59 PM
Not sure if I anything more to add. Some clarification.
- What is the destination type? Memory or device?
- What is the source type? Memory or device?
- What is the destination width in bytes? Burst length in words?
- What is the source width in bytes? Burst length in words?
- Does you PL handle the beats or bursts? My background is on the PS side of things. I vaguely remember my FPGA guy has to specifically handle the beats.
- What corruption are you seeing? I found that bad burst length values caused data to be repeated.
05-13-2015 07:31 PM
- Destination is device memory
- Source is local memory
- We are calling device->device_prep_dma_memcpy() and that grabs the saved user set bus width and length
- Our PL should be able to handle the bursts since it's not AXI lite
- We see different types of corruption depending on the width and length parameters. The only successful case is width=4 and len=1
The corruption we are seeing with width=8 and len=1, as well as width=4 and len=2
pl330_prep_dma_memcpy: src=0x2eae54c0, dst=0xa6004000, len=0x80 pl330_prep_dma_memcpy: burst shift=3, size=8, len=1 [Source] 0x2EAE54C0 : 41 C4 5A 5B 66 26 D0 B8 BD D4 8B 21 C3 2B F7 6B 0x2EAE54D0 : 42 7F B3 4A 6A A1 C8 98 87 DC F1 83 8D 58 B8 92 0x2EAE54E0 : 67 93 74 BD 38 20 23 1B B3 E3 DD 93 BA 40 B4 C2 0x2EAE54F0 : 93 D2 D4 27 78 5A 2C AB CA 57 2E E1 FF C1 71 42 0x2EAE5500 : D8 03 60 3A CB DD 2B E4 56 81 E3 B5 E5 4A 12 A4 0x2EAE5510 : 75 37 1A 51 B7 BE E2 6C 0D 2A 5E 63 B4 A1 79 5A 0x2EAE5520 : 30 DA FD 36 D7 A7 BB 36 E6 81 6B 53 30 07 31 06 0x2EAE5530 : EF 2D 86 05 55 1E 41 2F DF 50 F5 30 71 BB 3B 1B [Destination] 0xA6004000 : 41 C4 5A 5B 00 00 00 00 BD D4 8B 21 00 00 00 00 0xA6004010 : 42 7F B3 4A 00 00 00 00 87 DC F1 83 00 00 00 00 0xA6004020 : 67 93 74 BD 00 00 00 00 B3 E3 DD 93 00 00 00 00 0xA6004030 : 93 D2 D4 27 00 00 00 00 CA 57 2E E1 00 00 00 00 0xA6004040 : D8 03 60 3A 00 00 00 00 56 81 E3 B5 00 00 00 00 0xA6004050 : 75 37 1A 51 00 00 00 00 0D 2A 5E 63 00 00 00 00 0xA6004060 : 30 DA FD 36 00 00 00 00 E6 81 6B 53 00 00 00 00 0xA6004070 : EF 2D 86 05 00 00 00 00 DF 50 F5 30 00 00 00 00
05-14-2015 09:43 AM
The source address of 0x2eae54c0 corresponds to a DDR controller attached to memory with either 16 or 32 bit bus width. The destiination address of 0xa6004000 corresponds to PL, M_AXI_GP1, 32 bit width. I think the width you should use is 32 bits.
I deal with the PS side. You are beyond my PL knowledge. What macro block is behind 0xa6004000 in the PL? I am guessing a BRAM block doesn't know how to deal with PL330 signaling and only puts 32 bit one word onto the bus. On subsequent data beats, no data is on the bus and zeroes are read back. A PL330 block would put more than one word on the bus sequentially up to the burst length.
Sorry that's all I got. Hopefully somebody more knowledgeable can comment on the PL size of things,