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;