cancel
Showing results for 
Search instead for 
Did you mean: 

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

GLaure
Senior

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

3 REPLIES 3
Erwan SZYMANSKI
ST Employee

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.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

Hi @Erwan SZYMANSKI​ ,

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

Best regards,

Gunther

GLaure
Senior

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