aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2011-01-21 10:56:42 -0500
committerGrant Likely <grant.likely@secretlab.ca>2011-01-21 12:02:35 -0500
commit9dabb3f3269d042908bf1f4e685413c39cc8c373 (patch)
treea6913470397af37729670966b9683aec48edb525 /drivers/spi
parente2dbf5ebcc983b0349ab507bf7dd5562cf88dd24 (diff)
spi/spi_sh_msiof: consolidate data in 8-bit mode into 32-bit words
Instead of sending data 8 bits at a time in 8-bit SPI mode, swap bytes and send and receive them 32 bits at a time. Tested with an SD-card, with which this patch reduced the number of interrupts by 50%, when reading 5MiB of data (there are also small service packets, the number of interrupts, produced by 512-byte sectors should, of course, drop by 75%), and improved throughput by more than 40%. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi_sh_msiof.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/spi/spi_sh_msiof.c b/drivers/spi/spi_sh_msiof.c
index d220cb287874..da6e42ec856e 100644
--- a/drivers/spi/spi_sh_msiof.c
+++ b/drivers/spi/spi_sh_msiof.c
@@ -267,6 +267,26 @@ static void sh_msiof_spi_write_fifo_32u(struct sh_msiof_spi_priv *p,
267 sh_msiof_write(p, TFDR, get_unaligned(&buf_32[k]) << fs); 267 sh_msiof_write(p, TFDR, get_unaligned(&buf_32[k]) << fs);
268} 268}
269 269
270static void sh_msiof_spi_write_fifo_s32(struct sh_msiof_spi_priv *p,
271 const void *tx_buf, int words, int fs)
272{
273 const u32 *buf_32 = tx_buf;
274 int k;
275
276 for (k = 0; k < words; k++)
277 sh_msiof_write(p, TFDR, swab32(buf_32[k] << fs));
278}
279
280static void sh_msiof_spi_write_fifo_s32u(struct sh_msiof_spi_priv *p,
281 const void *tx_buf, int words, int fs)
282{
283 const u32 *buf_32 = tx_buf;
284 int k;
285
286 for (k = 0; k < words; k++)
287 sh_msiof_write(p, TFDR, swab32(get_unaligned(&buf_32[k]) << fs));
288}
289
270static void sh_msiof_spi_read_fifo_8(struct sh_msiof_spi_priv *p, 290static void sh_msiof_spi_read_fifo_8(struct sh_msiof_spi_priv *p,
271 void *rx_buf, int words, int fs) 291 void *rx_buf, int words, int fs)
272{ 292{
@@ -317,6 +337,26 @@ static void sh_msiof_spi_read_fifo_32u(struct sh_msiof_spi_priv *p,
317 put_unaligned(sh_msiof_read(p, RFDR) >> fs, &buf_32[k]); 337 put_unaligned(sh_msiof_read(p, RFDR) >> fs, &buf_32[k]);
318} 338}
319 339
340static void sh_msiof_spi_read_fifo_s32(struct sh_msiof_spi_priv *p,
341 void *rx_buf, int words, int fs)
342{
343 u32 *buf_32 = rx_buf;
344 int k;
345
346 for (k = 0; k < words; k++)
347 buf_32[k] = swab32(sh_msiof_read(p, RFDR) >> fs);
348}
349
350static void sh_msiof_spi_read_fifo_s32u(struct sh_msiof_spi_priv *p,
351 void *rx_buf, int words, int fs)
352{
353 u32 *buf_32 = rx_buf;
354 int k;
355
356 for (k = 0; k < words; k++)
357 put_unaligned(swab32(sh_msiof_read(p, RFDR) >> fs), &buf_32[k]);
358}
359
320static int sh_msiof_spi_bits(struct spi_device *spi, struct spi_transfer *t) 360static int sh_msiof_spi_bits(struct spi_device *spi, struct spi_transfer *t)
321{ 361{
322 int bits; 362 int bits;
@@ -468,9 +508,17 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
468 int bytes_done; 508 int bytes_done;
469 int words; 509 int words;
470 int n; 510 int n;
511 bool swab;
471 512
472 bits = sh_msiof_spi_bits(spi, t); 513 bits = sh_msiof_spi_bits(spi, t);
473 514
515 if (bits <= 8 && t->len > 15 && !(t->len & 3)) {
516 bits = 32;
517 swab = true;
518 } else {
519 swab = false;
520 }
521
474 /* setup bytes per word and fifo read/write functions */ 522 /* setup bytes per word and fifo read/write functions */
475 if (bits <= 8) { 523 if (bits <= 8) {
476 bytes_per_word = 1; 524 bytes_per_word = 1;
@@ -487,6 +535,17 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
487 rx_fifo = sh_msiof_spi_read_fifo_16u; 535 rx_fifo = sh_msiof_spi_read_fifo_16u;
488 else 536 else
489 rx_fifo = sh_msiof_spi_read_fifo_16; 537 rx_fifo = sh_msiof_spi_read_fifo_16;
538 } else if (swab) {
539 bytes_per_word = 4;
540 if ((unsigned long)t->tx_buf & 0x03)
541 tx_fifo = sh_msiof_spi_write_fifo_s32u;
542 else
543 tx_fifo = sh_msiof_spi_write_fifo_s32;
544
545 if ((unsigned long)t->rx_buf & 0x03)
546 rx_fifo = sh_msiof_spi_read_fifo_s32u;
547 else
548 rx_fifo = sh_msiof_spi_read_fifo_s32;
490 } else { 549 } else {
491 bytes_per_word = 4; 550 bytes_per_word = 4;
492 if ((unsigned long)t->tx_buf & 0x03) 551 if ((unsigned long)t->tx_buf & 0x03)