diff options
author | Andrew Bresticker <abrestic@chromium.org> | 2014-12-22 14:35:16 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2014-12-24 07:20:22 -0500 |
commit | 549858ce76e31d5e2139e5588df976ee42607a0d (patch) | |
tree | f467c9287a20c9b74fe3328963cb2456f45bc1f4 /drivers | |
parent | 76fe5e95fac3c93bdff9102480e5ba823ba656c3 (diff) |
spi: img-spfi: Select FIFO based on transfer length
Since the 32-bit FIFO is deeper (64 bytes) than the 8-bit FIFO (16 bytes),
use the 32-bit FIFO when there are at least 32 bits remaining to be
transferred in PIO mode or when the transfer length is 32-bit aligned
in DMA mode.
Signed-off-by: Andrew Bresticker <abrestic@chromium.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/spi/spi-img-spfi.c | 49 |
1 files changed, 19 insertions, 30 deletions
diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index aad6683db81b..c01567d53581 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c | |||
@@ -160,16 +160,16 @@ static unsigned int spfi_pio_write32(struct img_spfi *spfi, const u32 *buf, | |||
160 | unsigned int count = 0; | 160 | unsigned int count = 0; |
161 | u32 status; | 161 | u32 status; |
162 | 162 | ||
163 | while (count < max) { | 163 | while (count < max / 4) { |
164 | spfi_writel(spfi, SPFI_INTERRUPT_SDFUL, SPFI_INTERRUPT_CLEAR); | 164 | spfi_writel(spfi, SPFI_INTERRUPT_SDFUL, SPFI_INTERRUPT_CLEAR); |
165 | status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); | 165 | status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); |
166 | if (status & SPFI_INTERRUPT_SDFUL) | 166 | if (status & SPFI_INTERRUPT_SDFUL) |
167 | break; | 167 | break; |
168 | spfi_writel(spfi, buf[count / 4], SPFI_TX_32BIT_VALID_DATA); | 168 | spfi_writel(spfi, buf[count], SPFI_TX_32BIT_VALID_DATA); |
169 | count += 4; | 169 | count++; |
170 | } | 170 | } |
171 | 171 | ||
172 | return count; | 172 | return count * 4; |
173 | } | 173 | } |
174 | 174 | ||
175 | static unsigned int spfi_pio_write8(struct img_spfi *spfi, const u8 *buf, | 175 | static unsigned int spfi_pio_write8(struct img_spfi *spfi, const u8 *buf, |
@@ -196,17 +196,17 @@ static unsigned int spfi_pio_read32(struct img_spfi *spfi, u32 *buf, | |||
196 | unsigned int count = 0; | 196 | unsigned int count = 0; |
197 | u32 status; | 197 | u32 status; |
198 | 198 | ||
199 | while (count < max) { | 199 | while (count < max / 4) { |
200 | spfi_writel(spfi, SPFI_INTERRUPT_GDEX32BIT, | 200 | spfi_writel(spfi, SPFI_INTERRUPT_GDEX32BIT, |
201 | SPFI_INTERRUPT_CLEAR); | 201 | SPFI_INTERRUPT_CLEAR); |
202 | status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); | 202 | status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); |
203 | if (!(status & SPFI_INTERRUPT_GDEX32BIT)) | 203 | if (!(status & SPFI_INTERRUPT_GDEX32BIT)) |
204 | break; | 204 | break; |
205 | buf[count / 4] = spfi_readl(spfi, SPFI_RX_32BIT_VALID_DATA); | 205 | buf[count] = spfi_readl(spfi, SPFI_RX_32BIT_VALID_DATA); |
206 | count += 4; | 206 | count++; |
207 | } | 207 | } |
208 | 208 | ||
209 | return count; | 209 | return count * 4; |
210 | } | 210 | } |
211 | 211 | ||
212 | static unsigned int spfi_pio_read8(struct img_spfi *spfi, u8 *buf, | 212 | static unsigned int spfi_pio_read8(struct img_spfi *spfi, u8 *buf, |
@@ -251,17 +251,15 @@ static int img_spfi_start_pio(struct spi_master *master, | |||
251 | time_before(jiffies, timeout)) { | 251 | time_before(jiffies, timeout)) { |
252 | unsigned int tx_count, rx_count; | 252 | unsigned int tx_count, rx_count; |
253 | 253 | ||
254 | switch (xfer->bits_per_word) { | 254 | if (tx_bytes >= 4) |
255 | case 32: | ||
256 | tx_count = spfi_pio_write32(spfi, tx_buf, tx_bytes); | 255 | tx_count = spfi_pio_write32(spfi, tx_buf, tx_bytes); |
257 | rx_count = spfi_pio_read32(spfi, rx_buf, rx_bytes); | 256 | else |
258 | break; | ||
259 | case 8: | ||
260 | default: | ||
261 | tx_count = spfi_pio_write8(spfi, tx_buf, tx_bytes); | 257 | tx_count = spfi_pio_write8(spfi, tx_buf, tx_bytes); |
258 | |||
259 | if (rx_bytes >= 4) | ||
260 | rx_count = spfi_pio_read32(spfi, rx_buf, rx_bytes); | ||
261 | else | ||
262 | rx_count = spfi_pio_read8(spfi, rx_buf, rx_bytes); | 262 | rx_count = spfi_pio_read8(spfi, rx_buf, rx_bytes); |
263 | break; | ||
264 | } | ||
265 | 263 | ||
266 | tx_buf += tx_count; | 264 | tx_buf += tx_count; |
267 | rx_buf += rx_count; | 265 | rx_buf += rx_count; |
@@ -331,14 +329,11 @@ static int img_spfi_start_dma(struct spi_master *master, | |||
331 | 329 | ||
332 | if (xfer->rx_buf) { | 330 | if (xfer->rx_buf) { |
333 | rxconf.direction = DMA_DEV_TO_MEM; | 331 | rxconf.direction = DMA_DEV_TO_MEM; |
334 | switch (xfer->bits_per_word) { | 332 | if (xfer->len % 4 == 0) { |
335 | case 32: | ||
336 | rxconf.src_addr = spfi->phys + SPFI_RX_32BIT_VALID_DATA; | 333 | rxconf.src_addr = spfi->phys + SPFI_RX_32BIT_VALID_DATA; |
337 | rxconf.src_addr_width = 4; | 334 | rxconf.src_addr_width = 4; |
338 | rxconf.src_maxburst = 4; | 335 | rxconf.src_maxburst = 4; |
339 | break; | 336 | } else { |
340 | case 8: | ||
341 | default: | ||
342 | rxconf.src_addr = spfi->phys + SPFI_RX_8BIT_VALID_DATA; | 337 | rxconf.src_addr = spfi->phys + SPFI_RX_8BIT_VALID_DATA; |
343 | rxconf.src_addr_width = 1; | 338 | rxconf.src_addr_width = 1; |
344 | rxconf.src_maxburst = 4; | 339 | rxconf.src_maxburst = 4; |
@@ -358,18 +353,14 @@ static int img_spfi_start_dma(struct spi_master *master, | |||
358 | 353 | ||
359 | if (xfer->tx_buf) { | 354 | if (xfer->tx_buf) { |
360 | txconf.direction = DMA_MEM_TO_DEV; | 355 | txconf.direction = DMA_MEM_TO_DEV; |
361 | switch (xfer->bits_per_word) { | 356 | if (xfer->len % 4 == 0) { |
362 | case 32: | ||
363 | txconf.dst_addr = spfi->phys + SPFI_TX_32BIT_VALID_DATA; | 357 | txconf.dst_addr = spfi->phys + SPFI_TX_32BIT_VALID_DATA; |
364 | txconf.dst_addr_width = 4; | 358 | txconf.dst_addr_width = 4; |
365 | txconf.dst_maxburst = 4; | 359 | txconf.dst_maxburst = 4; |
366 | break; | 360 | } else { |
367 | case 8: | ||
368 | default: | ||
369 | txconf.dst_addr = spfi->phys + SPFI_TX_8BIT_VALID_DATA; | 361 | txconf.dst_addr = spfi->phys + SPFI_TX_8BIT_VALID_DATA; |
370 | txconf.dst_addr_width = 1; | 362 | txconf.dst_addr_width = 1; |
371 | txconf.dst_maxburst = 4; | 363 | txconf.dst_maxburst = 4; |
372 | break; | ||
373 | } | 364 | } |
374 | dmaengine_slave_config(spfi->tx_ch, &txconf); | 365 | dmaengine_slave_config(spfi->tx_ch, &txconf); |
375 | 366 | ||
@@ -508,9 +499,7 @@ static void img_spfi_set_cs(struct spi_device *spi, bool enable) | |||
508 | static bool img_spfi_can_dma(struct spi_master *master, struct spi_device *spi, | 499 | static bool img_spfi_can_dma(struct spi_master *master, struct spi_device *spi, |
509 | struct spi_transfer *xfer) | 500 | struct spi_transfer *xfer) |
510 | { | 501 | { |
511 | if (xfer->bits_per_word == 8 && xfer->len > SPFI_8BIT_FIFO_SIZE) | 502 | if (xfer->len > SPFI_32BIT_FIFO_SIZE) |
512 | return true; | ||
513 | if (xfer->bits_per_word == 32 && xfer->len > SPFI_32BIT_FIFO_SIZE) | ||
514 | return true; | 503 | return true; |
515 | return false; | 504 | return false; |
516 | } | 505 | } |