Hi,
We are developing a solution using FlexSPI to read some values from a FPGA and we are having issues with the FlexSPI driver when running DMA.
This issue is reproduced in i.MX8M Mini and Plus.
So far we managed to:
1. Initialize the DMA channels for FlexSPI (SDMA1, channels 36 and 37).
&flexspi {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexspi0>;
dmas = <&sdma1 36 8 2>, <&sdma1 37 8 1>;
dma-names = "tx", "rx";
fpga0: fpga@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
compatible = "fpga,fspi";
spi-max-frequency = <100000>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
};
(dma_request_slave_channel_reason , dma_alloc_coherent and dmaengine_slave_config all returned OK)
Our DMA channel config:
cfg.src_addr = (phys_addr_t)(f->iobase + FSPI_RFDR);
cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
cfg.src_maxburst = 2;
cfg.direction = DMA_DEV_TO_MEM;
2. Use the IP mode for FlexSPI without DMA without issues.
So, we are modifying the spi-nxp-fspi driver and trying to get DMA + IP mode working.
IPRXFCR:
- IPRXFCR_DMA_EN set.
- IPRXFCR_CLR set (for clearing RX FIFO)
- Write 1 with IPRXFCR_WMRK (This one we are not too sure)
- Run the DMA submit
However, we always get a DMA timeout. Here is the snippet of the DMA request (based on spi-fsl-dspi.c) :
static int fspi_next_xfer_dma_submit(struct nxp_fspi *f)
{
struct device *dev = f->dev;
struct nxp_fspi_dma *dma = f->dma;
dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx,
dma->rx_dma_phys,
dma->curr_xfer_len *
DMA_SLAVE_BUSWIDTH_4_BYTES,
DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->rx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
return -EIO;
}
dma->rx_desc->callback = fspi_rx_dma_callback;
dma->rx_desc->callback_param = f;
if (dma_submit_error(dmaengine_submit(dma->rx_desc))) {
dev_err(dev, "DMA submit failed\n");
return -EINVAL;
}
reinit_completion(&f->dma->cmd_rx_complete);
dma_async_issue_pending(dma->chan_rx);
return 0;
}
Here are the status of the related registers after failing the transfer (in hex):
IPRXFCR: 0002
(RXDMAEN 1)
INTR: 0060
(IPTXWE 1 IPRXWA 1)
INTEN: 0001
(IPCMDGE 1)
We are testing this with the interface we made to test the driver that creates a device in /dev/. This sample program simply tries to read the RX FIFO buffer with a dd read operation to this created device. We should get some stored data (or 0s) but we are always getting a DMA RX timeout.
Any idea? We think that we are probably not setting the watermark levels correctly but don't really know what we should set them to. Thanks.
EDIT: We found out that the problem is the callback (fspi_rx_dma_callback) is never being called. However, we don't know why....