Hello. I am trying to develop a demo project of AXI DMA on Vivado v2014.4. An AXI DMA IP core was connected to the AXI ACP port of zynq. And the S_AXI_S2MM was connected with M_AXI_MM2S directly, so the DMA can receive the data sent by itself. The send and receive functions of AXI DMA have been successfully evaluated with a standalone program on SDK.
However, I failed in developing the Linux (3.17.0) driver of AXI DMA. To simplify the developing process, I did not use the AXI DMA driver provided by Xilinx, but tried to control the DMA by access its registers. The main part of the driver is as follows:
#define MM2S_DMACR 0x00
#define MM2S_DMASR 0x04
#define MM2S_SA 0x18
#define MM2S_LENGTH 0x28
#define S2MM_DMACR 0x30
#define S2MM_DMASR 0x34
#define S2MM_DA 0x48
#define S2MM_LENGTH 0x58
axi_dma_base_addr = (unsigned long)ioremap_nocache(AXI_DMA_PHY_ADDR,sizeof(u32)*24)u200B;
axi_dma_devp->tx_physical=virt_to_phys(axi_dma_devp->posMu_tx_dst);
axi_dma_devp->rx_physical=virt_to_phys(axi_dma_devp->result_rx_dst);
iowrite32(0x04, (void __iomem *)(axi_dma_base_addr + MM2S_DMACR));
while(ioread32((void __iomem *)(axi_dma_base_addr + MM2S_DMACR)) & 0x04);
iowrite32(0x04, (void __iomem *)(axi_dma_base_addr + S2MM_DMACR));
while(ioread32((void __iomem *)(axi_dma_base_addr + S2MM_DMACR)) & 0x04);
iowrite32(0x1001, (void __iomem *)(axi_dma_base_addr + MM2S_DMACR));
while(ioread32((void __iomem *)(axi_dma_base_addr + MM2S_DMASR)) & 0x01);
iowrite32(0x1001, (void __iomem *)(axi_dma_base_addr + S2MM_DMACR));
while(ioread32((void __iomem *)(axi_dma_base_addr + S2MM_DMASR)) & 0x01);
iowrite32(axi_dma_devp->tx_physical, (void __iomem *)(axi_dma_base_addr + MM2S_SA));
iowrite32(axi_dma_devp->rx_physical, (void __iomem *)(axi_dma_base_addr + S2MM_DA));
iowrite32(0x00000100, (void __iomem *)(axi_dma_base_addr + S2MM_LENGTH));
iowrite32(0x00000100, (void __iomem *)(axi_dma_base_addr + MM2S_LENGTH));
And the information returned from the kernel was:
S2MM_DMACR=0x11003
S2MM_DMASR=0x0
S2MM_DA=0x1cba9000
S2MM_LENGTH=0x0
MM2S_DMACR=0x11003
MM2S_DMASR=0x0
MM2S_SA=0x1cba8000
MM2S_LENGTH=0x0
It seemed that the driver failed to access the registers of MM2S_LENGTH and S2MM_LENGTH. So the send and receive operations did not start. The order of register operations in the driver is as same as that in the standalone program. But it did not work.
How can I solve this problem, thanks very much!