This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/PROCESSOR-SDK-AM437X: How to use EDMA for custom device?

Part Number: PROCESSOR-SDK-AM437X


Tool/software: Linux

Hi all,

We have integrate an FPGA module through GPMC bus, and we have met some issues when using EDMA to copy data from the FPGA to memory.

1. Which dma channel should be used for our device?

    Refer to the TRM 10.3.20, some events were binding to specific module, so I can't use those channel, I can only use those "Reserved" channels such as channel 4, right?

2. I have use the dma engine api to use the edma, as follows:

bool fpga_dma_filter_fn(struct dma_chan *chan, void *param)
{
    int chan_id = *(unsigned int *)param;
    if (chan_id == chan->chan_id)
        return true;
 return false;
}

void dma_init()

{

   dma_cap_mask_t mask;

   dma_cap_zero(mask);

   dma_cap_set(DMA_SLAVE, mask);

   unsigned int id = 4;

   gFpgaDmaChan = dma_request_channel(mask, fpga_dma_filter_fn, &id);

}

int fpga_dma_read(dma_addr_t dst, unsigned int len)
{
    struct dma_slave_config config;
    struct dma_async_tx_descriptor *desc;
    unsigned long flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;

    config.direction = DMA_DEV_TO_MEM;
    config.dst_addr = dst;
    config.src_addr = FPGA_PHY_BASE + 6;  --> the source address
    config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
    config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
    config.dst_maxburst = 16;
    config.src_maxburst = 16;
    dmaengine_slave_config(gFpgaDmaChan, &config);

    desc = dmaengine_prep_slave_single(
        gFpgaDmaChan, dst, len, DMA_DEV_TO_MEM, flags);

    desc->callback = fpga_dma_callback;
    dmaengine_submit(desc);
    dma_async_issue_pending(gFpgaDmaChan);
    return 1;
}

void fpga_test()

{

        dma_addr_t dest;
        char *ptr = dma_alloc_coherent(NULL, 1024, &dest, GFP_DMA);
        memset(ptr, 0x11, 1024);
        fpga_dma_read(dest, 1024);
        mdelay(1000);
        for (int i=0;i<33;i++){
            printk("0x%x ", ptr[i]);
        }

}

When I call fpga_test, I found the DMA only copy the first  config.src_maxburst *  config.src_addr_width = 16 * 2 = 32 bytes, ptr[32] and later elements remains the default value(0x11).

How should I debug this issue? Do I use the dma api correctly?

Thanks!!!

  • Anyone can help me on this issue? Thanks!

  • Hi user,

    user4552302 said:

    1. Which dma channel should be used for our device?

        Refer to the TRM 10.3.20, some events were binding to specific module, so I can't use those channel, I can only use those "Reserved" channels such as channel 4, right?

    Do you want to transfer data directly from external FPGA chip to DDR3 memory? If yes, then you should use xdma_event_intrX pins and corresponding DMA_INTR_PINx EDMA events.


    If you first transfer the data from FPGA to GPMC, then use EDMA to transfer from GPMC to DDR3, you should use EDMA event 52 (GPMC).

    For more details and for EDMA API usage, refer to the below pointers:

    Regards,
    Pavel