GPCDMA memory to memory low performance

try dma1 doesn’t work
/sys/module/dmatest/parameters# echo dma1chan18 > channel
/sys/module/dmatest/parameters# echo 4194304 > ./test_buf_size
/sys/module/dmatest/parameters# echo y > run

/sys/module/dmatest/parameters# echo dma0chan18 > channel
/sys/module/dmatest/parameters# echo y > run
[ 2210.050589] dmatest: dma0chan18-copy: summary 50 tests, 0 failures 56 iops 114917 KB/s (0)

Ok, don’t need to focus the performance of the GPCDMA, which is not suitable for memory to memory.

Hi @os.kernel,

So, dma1 channels are not ennumerated in your case to, so dma1 channels can’t be exclusively requested or not suitable to DMA_MEMCPY transaction type.

Then new test with dmaengine_get() followed by dma_find_channel(…) is needed to measure performance of dma channel released default by kernel.

I have checked sources.

  1. dma1 (2930000.adma) is used by tegra-adma driver . It’s not compatible to MEM to MEM transfer. So, only dma0 (2600000.dma tegra-gpcdma) could be used to memory to memory transfer with bandwidth less then 111000 KB/s. There is no faster option.
  2. No driver register channels to shared usage, so dmaengine_get() followed by dma_find_channel() is unusable. ( so dmaengine_get is used only in /kernel-4.9/drivers/video/fbdev/mx3fb.c, and dma_find_channel never used in linux 4.9 kernel source, may be it’s dead API in this version)

dma_cap_set(DMA_SLAVE, tdma->dma_dev.cap_mask);
dma_cap_set(DMA_PRIVATE, tdma->dma_dev.cap_mask);
dma_cap_set(DMA_CYCLIC, tdma->dma_dev.cap_mask);


tdma-> = &pdev->dev;
tdma->dma_dev.device_alloc_chan_resources =
tdma->dma_dev.device_free_chan_resources =
tdma->dma_dev.device_issue_pending = tegra_adma_issue_pending;
tdma->dma_dev.device_prep_dma_cyclic = tegra_adma_prep_dma_cyclic;
tdma->dma_dev.device_config = tegra_adma_slave_config;
tdma->dma_dev.device_tx_status = tegra_adma_tx_status;
tdma->dma_dev.device_terminate_all = tegra_adma_terminate_all;
tdma->dma_dev.device_pause = tegra_adma_pause;
tdma->dma_dev.device_resume = tegra_adma_resume;

tdma->dma_dev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
tdma->dma_dev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
tdma->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
tdma->dma_dev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;

dma_cap_set(DMA_SLAVE, tdma->dma_dev.cap_mask);
dma_cap_set(DMA_PRIVATE, tdma->dma_dev.cap_mask);
dma_cap_set(DMA_CYCLIC, tdma->dma_dev.cap_mask);
dma_cap_set(DMA_MEMCPY, tdma->dma_dev.cap_mask);
dma_cap_set(DMA_MEMSET, tdma->dma_dev.cap_mask);

@crazy_yorick Ok, thanks.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.