Skip to main content
Explorer
February 10, 2023
Question

STM32MP157F: Dmaengine dmaengine_prep_dma_memcpy vs dmaengine_prep_dma_cyclic? Hardware vs Software triggered. (Linux)

  • February 10, 2023
  • 2 replies
  • 1607 views

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:

https://community.st.com/s/question/0D53W0000274CNFSA2/stm32mdmac-fast-overlapped-dma-transaction-problem

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

    This topic has been closed for replies.

    2 replies

    Technical Moderator
    February 10, 2023

    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.

    GLaureAuthor
    Explorer
    February 12, 2023

    Hi @Erwan SZYMANSKI​ ,

    thank you for your response. I will have a look at stm32-adc.c.

    Best regards,

    Gunther

    GLaureAuthor
    Explorer
    February 13, 2023

    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 ...