aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndrew Bresticker <abrestic@chromium.org>2014-12-22 14:35:16 -0500
committerMark Brown <broonie@kernel.org>2014-12-24 07:20:22 -0500
commit549858ce76e31d5e2139e5588df976ee42607a0d (patch)
treef467c9287a20c9b74fe3328963cb2456f45bc1f4 /drivers
parent76fe5e95fac3c93bdff9102480e5ba823ba656c3 (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.c49
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
175static unsigned int spfi_pio_write8(struct img_spfi *spfi, const u8 *buf, 175static 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
212static unsigned int spfi_pio_read8(struct img_spfi *spfi, u8 *buf, 212static 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)
508static bool img_spfi_can_dma(struct spi_master *master, struct spi_device *spi, 499static 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}