The upper limit for DMA transfer length on MX28 is 0x4000 bytes,
otherwise the DMA refuses to operate.

Signed-off-by: Marek Vasut <ma...@denx.de>
Cc: Fabio Estevam <feste...@gmail.com>
Cc: Otavio Salvador <ota...@ossystems.com.br>
Cc: Stefano Babic <sba...@denx.de>
---
 drivers/spi/mxs_spi.c |   31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/mxs_spi.c b/drivers/spi/mxs_spi.c
index a037c13..fb6a167 100644
--- a/drivers/spi/mxs_spi.c
+++ b/drivers/spi/mxs_spi.c
@@ -287,9 +287,9 @@ static int mxs_spi_xfer_dma(struct mxs_spi_slave *slave,
 int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
                const void *dout, void *din, unsigned long flags)
 {
-       struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave);
-       struct mxs_ssp_regs *ssp_regs = mxs_slave->regs;
-       int len = bitlen / 8;
+       struct mxs_spi_slave *sslave = to_mxs_slave(slave);
+       struct mxs_ssp_regs *regs = sslave->regs;
+       int len = bitlen / 8, tl, ret;
        char dummy;
        int write = 0;
        char *data = NULL;
@@ -335,11 +335,24 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
                        dma = 0;
        }
 
-       if (!dma || (len < MXSSSP_SMALL_TRANSFER)) {
-               writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_clr);
-               return mxs_spi_xfer_pio(mxs_slave, data, len, write, flags);
-       } else {
-               writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_set);
-               return mxs_spi_xfer_dma(mxs_slave, data, len, write, flags);
+       while (len) {
+               if (!dma || (len < MXSSSP_SMALL_TRANSFER)) {
+                       tl = len;
+                       writel(SSP_CTRL1_DMA_ENABLE, &regs->hw_ssp_ctrl1_clr);
+                       ret = mxs_spi_xfer_pio(sslave, data, tl, write, flags);
+               } else {
+                       /* 0x4000 bytes is the limit for DMA burst. */
+                       tl = min(len, 0x4000);
+                       writel(SSP_CTRL1_DMA_ENABLE, &regs->hw_ssp_ctrl1_set);
+                       ret = mxs_spi_xfer_dma(sslave, data, tl, write, flags);
+               }
+
+               if (ret)
+                       return ret;
+
+               data += tl;
+               len -= tl;
        }
+
+       return ret;
 }
-- 
1.7.10.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to