DMA SPI Slave Issues

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

DMA SPI Slave Issues

1,471件の閲覧回数
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;
ラベル(2)
タグ(4)
0 件の賞賛
返信
3 返答(返信)

1,044件の閲覧回数
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 件の賞賛
返信

1,044件の閲覧回数
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 件の賞賛
返信

1,044件の閲覧回数
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 件の賞賛
返信