2023-02-09 11:46 PM
Hello all!
We have implemented our custom driver that uses DMA to copy a large amount of data from the FMC interface (FPGA mapped to it) to the RAM.
For very fast data acquisition the setup time for new DMA transactions becomes critical.
I tried an overlapping approach:
But this did not work. Then I tried to use dmaengine_prep_dma_cyclic to copth the FPGA data into a larger coherent memory region. Then using dmaengine_prep_dma_memcpy to copy it to its final destination.
But: the transaction created with dmaengine_prep_dma_cyclic does not want to start!
dmaengine_prep_dma_memcpy works fine.
I think this is because of the difference between software vs hardware triggered DMA transactions (memcopy.
Looking into stm32-mdma.c is see that dmaengine_prep_dma_memcpy has its own setup routine whereas dmaengine_prep_dma_cyclic use stm32_mdma_set_xfer_param() that always configures a HW request.
My big big question:
Is there a way to use dmaengine_prep_dma_cyclic for a MEMORY to MEMORY DMA transaction (software triggered)? This would be the perfect solution to my performance problem...
Bye Gunther
2023-02-10 02:42 PM
Hello @GLaure ,
I am not a DMA expert, but I know that we have a ST driver that uses dma_cyclic transfer. This is linked to the ADC IP.
I think you can take a look at the drivers/iio/adc/stm32-adc.c driver to have an example of how we can use the DMA cyclic transfer, and how to trigger it (you have specific steps to respect).
Kind regards,
Erwan.
2023-02-12 02:04 AM
Hi @Erwan SZYMANSKI ,
thank you for your response. I will have a look at stm32-adc.c.
Best regards,
Gunther
2023-02-13 07:42 AM
I had a look stm32-adc.c does not do anything different when setting up the dma.
static int stm32_adc_dma_start(struct iio_dev *indio_dev)
{
struct stm32_adc *adc = iio_priv(indio_dev);
struct dma_async_tx_descriptor *desc;
dma_cookie_t cookie;
int ret;
if (!adc->dma_chan)
return 0;
dev_dbg(&indio_dev->dev, "%s size=%d watermark=%d\n", __func__,
adc->rx_buf_sz, adc->rx_buf_sz / 2);
/* Prepare a DMA cyclic transaction */
desc = dmaengine_prep_dma_cyclic(adc->dma_chan,
adc->rx_dma_buf,
adc->rx_buf_sz, adc->rx_buf_sz / 2,
DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT);
if (!desc)
return -EBUSY;
desc->callback = stm32_adc_dma_buffer_done;
desc->callback_param = indio_dev;
cookie = dmaengine_submit(desc);
ret = dma_submit_error(cookie);
if (ret) {
dmaengine_terminate_sync(adc->dma_chan);
return ret;
}
/* Issue pending DMA requests */
dma_async_issue_pending(adc->dma_chan);
return 0;
}
I believe the FMC in NOR Flash mode does not create the necessary start signal/interrupt.
It may be necessary to patch stm32-mdma.c ...