aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Bondarenko <anton.bondarenko.sama@gmail.com>2016-02-17 08:28:47 -0500
committerMark Brown <broonie@kernel.org>2016-02-17 09:22:29 -0500
commit390f0ffe92aea878b763c7fd8afd1dff62e0d20b (patch)
treec99e20a15697ad74d1da61b425204b504f12c102
parent92e963f50fc74041b5e9e744c330dca48e04f08d (diff)
spi: imx: allow only WML aligned transfers to use DMA
RX DMA tail data handling doesn't work correctly in many cases with current implementation. It happens because SPI core was setup to generates both RX and RX TAIL events. And RX TAIL event does not work correctly. This can be easily verified by sending SPI transaction with size modulus WML(32 in our case) not equal 0. Also removing change introduced in f6ee9b582d2db652497b73c1f117591dfb6d3a90 since this change only fix usecases with transfer size from 33 to 128 bytes and doesn't fix 129 bytes and bigger. This is output from transaction with len 138 bytes in loopback mode at 10Mhz: TX0000: a3 97 a2 55 53 be f1 fc f9 79 6b 52 14 13 e9 e2 TX0010: 2d 51 8e 1f 56 08 57 27 a7 05 d4 d0 52 82 77 75 TX0020: 1b 99 4a ed 58 3d 6a 52 36 d5 24 4a 68 8e ad 95 TX0030: 5f 3c 35 b5 c4 8c dd 6c 11 32 3d e2 b4 b4 59 cf TX0040: ce 23 3d 27 df a7 f9 96 fc 1e e0 66 2c 0e 7b 8c TX0050: ca 30 42 8f bc 9f 7b ce d1 b8 b1 87 ec 8a d6 bb TX0060: 2e 15 63 0e 3c dc a4 3a 7a 06 20 a7 93 1b 34 dd TX0070: 4c f5 ec 88 96 68 d6 68 a0 09 6f 8e 93 47 c9 41 TX0080: db ac cf 97 89 f3 51 05 79 71 RX0000: a3 97 a2 55 53 be f1 fc f9 79 6b 52 14 13 e9 e2 RX0010: 2d 51 8e 1f 56 08 57 27 a7 05 d4 d0 52 82 77 75 RX0020: 1b 99 4a ed 58 3d 6a 52 36 d5 24 4a 68 8e ad 95 RX0030: 5f 3c 35 00 00 b5 00 00 00 c4 00 00 8c 00 00 dd RX0040: 6c 11 32 3d e2 b4 b4 59 cf ce 23 3d 27 df a7 f9 RX0050: 96 fc 1e e0 66 2c 0e 7b 8c ca 30 42 8f 1f 1f bc RX0060: 9f 7b ce d1 b8 b1 87 ec 8a d6 bb 2e 15 63 0e ed RX0070: ed 3c 58 58 58 dc 3d 3d a4 6a 6a 3a 52 52 7a 36 RX0080: 06 20 a7 93 1b 34 dd 4c f5 ec Zeros at offset 33 and 34 caused by reading empty RX FIFO which not possible if DMA RX read was triggered by RX event. This mean DMA was triggered by RX TAIL event. Signed-off-by: Anton Bondarenko <anton.bondarenko.sama@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/spi-imx.c17
1 files changed, 2 insertions, 15 deletions
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index d98c33cb64f9..08492d6faa0d 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -204,8 +204,8 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
204{ 204{
205 struct spi_imx_data *spi_imx = spi_master_get_devdata(master); 205 struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
206 206
207 if (spi_imx->dma_is_inited && 207 if (spi_imx->dma_is_inited && transfer->len >= spi_imx->wml &&
208 transfer->len > spi_imx->wml * sizeof(u32)) 208 (transfer->len % spi_imx->wml) == 0)
209 return true; 209 return true;
210 return false; 210 return false;
211} 211}
@@ -919,8 +919,6 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
919 struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL; 919 struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL;
920 int ret; 920 int ret;
921 unsigned long timeout; 921 unsigned long timeout;
922 u32 dma;
923 int left;
924 struct spi_master *master = spi_imx->bitbang.master; 922 struct spi_master *master = spi_imx->bitbang.master;
925 struct sg_table *tx = &transfer->tx_sg, *rx = &transfer->rx_sg; 923 struct sg_table *tx = &transfer->tx_sg, *rx = &transfer->rx_sg;
926 924
@@ -954,13 +952,6 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
954 /* Trigger the cspi module. */ 952 /* Trigger the cspi module. */
955 spi_imx->dma_finished = 0; 953 spi_imx->dma_finished = 0;
956 954
957 dma = readl(spi_imx->base + MX51_ECSPI_DMA);
958 dma = dma & (~MX51_ECSPI_DMA_RXT_WML_MASK);
959 /* Change RX_DMA_LENGTH trigger dma fetch tail data */
960 left = transfer->len % spi_imx->wml;
961 if (left)
962 writel(dma | (left << MX51_ECSPI_DMA_RXT_WML_OFFSET),
963 spi_imx->base + MX51_ECSPI_DMA);
964 /* 955 /*
965 * Set these order to avoid potential RX overflow. The overflow may 956 * Set these order to avoid potential RX overflow. The overflow may
966 * happen if we enable SPI HW before starting RX DMA due to rescheduling 957 * happen if we enable SPI HW before starting RX DMA due to rescheduling
@@ -992,10 +983,6 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
992 spi_imx->devtype_data->reset(spi_imx); 983 spi_imx->devtype_data->reset(spi_imx);
993 dmaengine_terminate_all(master->dma_rx); 984 dmaengine_terminate_all(master->dma_rx);
994 } 985 }
995 dma &= ~MX51_ECSPI_DMA_RXT_WML_MASK;
996 writel(dma |
997 spi_imx->wml << MX51_ECSPI_DMA_RXT_WML_OFFSET,
998 spi_imx->base + MX51_ECSPI_DMA);
999 } 986 }
1000 987
1001 spi_imx->dma_finished = 1; 988 spi_imx->dma_finished = 1;