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:
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....
Hello,
In Linux FlexSPI driver do not have DMA support.
Best regards,
Aldo.
Hi Aldo, yes, we know that it doesn't have it, that is why we are trying to add it from our side (hence the question with the implementation).
Alvaro.
Hi @alvaro_tx
Have you managed to implement FlexSPI DMA support?
If so, could you please share your patch?
Thanks
Unfortunately no. We ended up using FlexSPI without DMA.