1be40ebc1e69120e60210b0c6bc870520c65f351
[librecmc/librecmc.git] /
1 From 61dc388f577b6f984797949f32c30021d9ea73dc Mon Sep 17 00:00:00 2001
2 From: Jonas Gorski <jogo@openwrt.org>
3 Date: Sun, 23 Aug 2015 12:16:02 +0200
4 Subject: [PATCH V2] spi/bcm63xx-hsspi: add support for dual spi read/write
5
6 Add support for dual read/writes on spi-bcm63xx-hsspi. This has been
7 tested with a s25fl129p1 dual read capable spi flash, with a nice speed
8 improvement:
9
10 serial read:
11
12 root@OpenWrt:/# time dd if=/dev/mtd4 of=/dev/null bs=8192
13 2032+0 records in
14 2032+0 records out
15 real    0m 4.39s
16 user    0m 0.00s
17 sys     0m 1.55s
18
19 dual read:
20
21 root@OpenWrt:/# time dd if=/dev/mtd4 of=/dev/null bs=8192
22 2032+0 records in
23 2032+0 records out
24 real    0m 3.09s
25 user    0m 0.00s
26 sys     0m 1.56s
27
28 Signed-off-by: Jonas Gorski <jogo@openwrt.org>
29 ---
30  drivers/spi/spi-bcm63xx-hsspi.c | 13 +++++++++----
31  1 file changed, 9 insertions(+), 4 deletions(-)
32
33 --- a/drivers/spi/spi-bcm63xx-hsspi.c
34 +++ b/drivers/spi/spi-bcm63xx-hsspi.c
35 @@ -76,6 +76,7 @@
36  #define HSSPI_FIFO_REG(x)                      (0x200 + (x) * 0x200)
37  
38  
39 +#define HSSPI_OP_MULTIBIT                      BIT(11)
40  #define HSSPI_OP_CODE_SHIFT                    13
41  #define HSSPI_OP_SLEEP                         (0 << HSSPI_OP_CODE_SHIFT)
42  #define HSSPI_OP_READ_WRITE                    (1 << HSSPI_OP_CODE_SHIFT)
43 @@ -171,9 +172,12 @@ static int bcm63xx_hsspi_do_txrx(struct
44         if (opcode != HSSPI_OP_READ)
45                 step_size -= HSSPI_OPCODE_LEN;
46  
47 -       __raw_writel(0 << MODE_CTRL_PREPENDBYTE_CNT_SHIFT |
48 -                    2 << MODE_CTRL_MULTIDATA_WR_STRT_SHIFT |
49 -                    2 << MODE_CTRL_MULTIDATA_RD_STRT_SHIFT | 0xff,
50 +       if ((opcode == HSSPI_OP_READ && t->rx_nbits == SPI_NBITS_DUAL) ||
51 +           (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL))
52 +               opcode |= HSSPI_OP_MULTIBIT;
53 +
54 +       __raw_writel(1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT |
55 +                    1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT | 0xff,
56                      bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select));
57  
58         while (pending > 0) {
59 @@ -374,7 +378,8 @@ static int bcm63xx_hsspi_probe(struct pl
60         master->num_chipselect = 8;
61         master->setup = bcm63xx_hsspi_setup;
62         master->transfer_one_message = bcm63xx_hsspi_transfer_one;
63 -       master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
64 +       master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH |
65 +                           SPI_RX_DUAL | SPI_TX_DUAL;
66         master->bits_per_word_mask = SPI_BPW_MASK(8);
67         master->auto_runtime_pm = true;
68