aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonas Gorski <jogo@openwrt.org>2015-08-23 16:49:32 -0400
committerMark Brown <broonie@kernel.org>2015-08-25 12:33:49 -0400
commitf4d86223771533c68f1a6692d499f7ef0025f733 (patch)
treea420afd5d0a03ba0231282940cf2820ceda2b669
parentbc0195aad0daa2ad5b0d76cce22b167bc3435590 (diff)
spi/bcm63xx-hsspi: add support for dual spi read/write
Add support for dual read/writes on spi-bcm63xx-hsspi. This has been tested with a s25fl129p1 dual read capable spi flash, with a nice speed improvement: serial read: root@OpenWrt:/# time dd if=/dev/mtd4 of=/dev/null bs=8192 2032+0 records in 2032+0 records out real 0m 4.39s user 0m 0.00s sys 0m 1.55s dual read: root@OpenWrt:/# time dd if=/dev/mtd4 of=/dev/null bs=8192 2032+0 records in 2032+0 records out real 0m 3.09s user 0m 0.00s sys 0m 1.56s Signed-off-by: Jonas Gorski <jogo@openwrt.org> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/spi-bcm63xx-hsspi.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c
index f5ca6dc3a157..55789f7cda92 100644
--- a/drivers/spi/spi-bcm63xx-hsspi.c
+++ b/drivers/spi/spi-bcm63xx-hsspi.c
@@ -76,6 +76,7 @@
76#define HSSPI_FIFO_REG(x) (0x200 + (x) * 0x200) 76#define HSSPI_FIFO_REG(x) (0x200 + (x) * 0x200)
77 77
78 78
79#define HSSPI_OP_MULTIBIT BIT(11)
79#define HSSPI_OP_CODE_SHIFT 13 80#define HSSPI_OP_CODE_SHIFT 13
80#define HSSPI_OP_SLEEP (0 << HSSPI_OP_CODE_SHIFT) 81#define HSSPI_OP_SLEEP (0 << HSSPI_OP_CODE_SHIFT)
81#define HSSPI_OP_READ_WRITE (1 << HSSPI_OP_CODE_SHIFT) 82#define HSSPI_OP_READ_WRITE (1 << HSSPI_OP_CODE_SHIFT)
@@ -171,9 +172,12 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t)
171 if (opcode != HSSPI_OP_READ) 172 if (opcode != HSSPI_OP_READ)
172 step_size -= HSSPI_OPCODE_LEN; 173 step_size -= HSSPI_OPCODE_LEN;
173 174
174 __raw_writel(0 << MODE_CTRL_PREPENDBYTE_CNT_SHIFT | 175 if ((opcode == HSSPI_OP_READ && t->rx_nbits == SPI_NBITS_DUAL) ||
175 2 << MODE_CTRL_MULTIDATA_WR_STRT_SHIFT | 176 (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL))
176 2 << MODE_CTRL_MULTIDATA_RD_STRT_SHIFT | 0xff, 177 opcode |= HSSPI_OP_MULTIBIT;
178
179 __raw_writel(1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT |
180 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT | 0xff,
177 bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select)); 181 bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select));
178 182
179 while (pending > 0) { 183 while (pending > 0) {
@@ -374,7 +378,8 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
374 master->num_chipselect = 8; 378 master->num_chipselect = 8;
375 master->setup = bcm63xx_hsspi_setup; 379 master->setup = bcm63xx_hsspi_setup;
376 master->transfer_one_message = bcm63xx_hsspi_transfer_one; 380 master->transfer_one_message = bcm63xx_hsspi_transfer_one;
377 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; 381 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH |
382 SPI_RX_DUAL | SPI_TX_DUAL;
378 master->bits_per_word_mask = SPI_BPW_MASK(8); 383 master->bits_per_word_mask = SPI_BPW_MASK(8);
379 master->auto_runtime_pm = true; 384 master->auto_runtime_pm = true;
380 385