DMA SPI Slave Issues

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

DMA SPI Slave Issues

1,395 Views
curtis1
Contributor II

I have implemented a DMA SPI slave driver for Linux and I am seeing a strange issue.

I have a data structure that is 4096 bytes long. When I initiate a SPI transfer on the master side, I find that I have to transfer an additional 4 bytes to collect the full message on the slave side. The strange part is that these extra 4 bytes do not end up in any buffers. Performing a CRC32 on the data structure on the master side, then slave side shows that the data is consistent as long as I add the extra 4 bytes. 

Can someone offer some guidance as to where the last 4 bytes are going? And why the extra bytes are necessary?

I have configured the SPI device as follows:

reg = 0;
reg |= IMX6_ECSPI_DMA_RXTDEN;
reg |= IMX6_ECSPI_DMA_RX_LEN(SPI_DMA_RX_BURST_LEN); // RX_DMA_LENGTH = 32
reg |= IMX6_ECSPI_DMA_RXDEN;
reg |= IMX6_ECSPI_DMA_RX_THR(SPI_DMA_RX_THRESHOLD - 1); // RX_THRESHOLD = 31
writel(reg, spislv->base + IMX6_ECSPI_DMA);

The DMA (slave side) is configured to fill a buffer of 4096 bytes in 32 word (128 byte) increments. The Linux DMA engine is configured as follows:

slave_config.dst_addr = (dma_addr_t) spislv->phybase + IMX6_ECSPI_DATA_TX;
slave_config.src_addr = (dma_addr_t) spislv->phybase + IMX6_ECSPI_DATA_RX;
slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
slave_config.src_maxburst = SPI_DMA_RX_BURST_LEN; // 32 Words
slave_config.dst_maxburst = SPI_DMA_RX_BURST_LEN; // 32 Words
slave_config.device_fc = true;
slave_config.direction = DMA_DEV_TO_MEM;

if (dmaengine_slave_config(spislv->dma.rx_dma_chan, &slave_config)) {
    dev_err(&spislv->pdev->dev, "can't configure rx dma channel\n");
    return -EINVAL;
}
rx_desc = dmaengine_prep_dma_cyclic(spislv->dma.rx_dma_chan,
        spislv->dma.handle,
        2 * SPI_RX_BUFF_SIZE, // 2 * 4096 Bytes 
        SPI_RX_BUFF_SIZE, // 4096 Bytes
        DMA_DEV_TO_MEM,
        DMA_PREP_INTERRUPT);
if (!rx_desc)
 return -ENOMEM;
Labels (2)
0 Kudos
3 Replies

968 Views
igorpadykov
NXP Employee
NXP Employee

Hi Curtis

probably extra 4 bytes may be explained that SDMA has 36-byte FIFO according to

sect.55.4.3.1 Burst DMA Unit i.MX6DQ Reference Manual

http://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

968 Views
curtis1
Contributor II

Hi Igor,

That almost makes sense. However, I would expect to require 8 extra bytes. And where are these bytes going?

Furthermore, the reference manual mentions 36 byte fifo, but only 8 words deep. 36 bytes should be 9 word fifo, am I missing something?

Cheers,

Curtis

0 Kudos

968 Views
igorpadykov
NXP Employee
NXP Employee

Hi Curtis

one can try to narrow down problem testing with smaller number like 512 or less.

As for 4096, does it work without sdma.

Also there are some ecspi related errata described in i.MX6DQ Errata

https://www.nxp.com/docs/en/errata/IMX6DQCE.pdf

It makes sense to try latest nxp linux L4.14.78_1.0.0 
https://source.codeaurora.org/external/imx/linux-imx/tree/?h=imx_4.14.78_1.0.0_ga

Best regards
igor

0 Kudos