diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2014-02-04 13:58:08 +0100 |
---|---|---|
committer | Stefan Agner <stefan.agner@toradex.com> | 2014-02-04 13:58:08 +0100 |
commit | c52df3630a69f07dbe6fec453924c0f08d98561b (patch) | |
tree | 7bc67111ed63bbba9546a1c6eb76c9b17c4829c3 /drivers | |
parent | cba73bf21464f5e6be6c9b52302e868654eda0d7 (diff) | |
parent | 211c76becc528becec01e1efb23db84b2ebdf5ea (diff) |
Merge tag '3.0-vybrid-ts2.10' into vybrid-latest-merge
3.0-vybrid-ts2.10
Conflicts:
arch/arm/mach-mvf/clock.c
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/devices/m25p80.c | 3 | ||||
-rw-r--r-- | drivers/spi/spi_mvf_qspi.c | 65 |
2 files changed, 61 insertions, 7 deletions
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 2e416b6ec0d0..4c6b4f68239c 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -698,7 +698,8 @@ static const struct spi_device_id m25p_ids[] = { { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SECT_4K) }, { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, - { "s25fl128s", INFO(0x012018, 0x4d00, 64 * 1024, 256, 0) }, + { "s25fl128s0", INFO(0x012018, 0x4d00, 64 * 1024, 256, 0) }, + { "s25fl128s1", INFO(0x012018, 0x4d01, 64 * 1024, 256, 0) }, { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, 0) }, { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) }, diff --git a/drivers/spi/spi_mvf_qspi.c b/drivers/spi/spi_mvf_qspi.c index a15425827a27..dd5cfe408d46 100644 --- a/drivers/spi/spi_mvf_qspi.c +++ b/drivers/spi/spi_mvf_qspi.c @@ -313,6 +313,16 @@ static void set_lut(struct mvfqspi *mvfqspi) writel(0x0, mvfqspi->iobase + QUADSPI_LUT(54)); writel(0x0, mvfqspi->iobase + QUADSPI_LUT(55)); + /* SEQID 14 - Fast READ */ +#ifdef QUADSPI_ENABLE_32BITS_ADDR + writel(0x0820040C, mvfqspi->iobase + QUADSPI_LUT(56)); +#else + writel(0x0818040B, mvfqspi->iobase + QUADSPI_LUT(56)); +#endif + writel(0x1c800c08, mvfqspi->iobase + QUADSPI_LUT(57)); + writel(0x0, mvfqspi->iobase + QUADSPI_LUT(58)); + writel(0x0, mvfqspi->iobase + QUADSPI_LUT(59)); + /* Lock the LUT */ writel(0x5af05af0, mvfqspi->iobase + QUADSPI_LUTKEY); writel(0x1, mvfqspi->iobase + QUADSPI_LCKCR); @@ -434,6 +444,35 @@ static void mvfqspi_transfer_msg(unsigned int opr, unsigned int to_or_from, mvfqspi->iobase + QUADSPI_MCR); } break; + case OPCODE_FAST_READ: + to_or_from += PSP_QSPI0_MEMMAP_BASE; + + while (count > 0) { + writel(to_or_from, mvfqspi->iobase + QUADSPI_SFAR); + size = (count > RX_BUFFER_SIZE) ? + RX_BUFFER_SIZE : count; + writel(14 << QSPI_IPCR_SEQID_SHIFT | size, + mvfqspi->iobase + QUADSPI_IPCR); + do {} while (readl(mvfqspi->iobase + QUADSPI_SR) & + QSPI_SR_BUSY_MASK); + + to_or_from += size; + count -= size; + + i = 0; + while ((RX_BUFFER_SIZE >= size) && (size > 0)) { + tmp = readl(mvfqspi->iobase + QUADSPI_RBDR + + i * 4); + *rxbuf = endian_change_32bit(tmp); + rxbuf++; + size -= 4; + i++; + } + writel(readl(mvfqspi->iobase + QUADSPI_MCR) | + QSPI_MCR_CLR_RXF_MASK, + mvfqspi->iobase + QUADSPI_MCR); + } + break; case OPCODE_SE: to_or_from += PSP_QSPI0_MEMMAP_BASE; writel(to_or_from, mvfqspi->iobase + QUADSPI_SFAR); @@ -517,14 +556,23 @@ static void mvfqspi_transfer_msg(unsigned int opr, unsigned int to_or_from, reg = readl(mvfqspi->iobase + QUADSPI_RBSR); if (reg & QSPI_RBSR_RDBFL_MASK) { - tmp = readl(mvfqspi->iobase + QUADSPI_RBDR); - *rxbuf = endian_change_32bit(tmp); - rxbuf += 4; - count -= 4; + i = 0; + while (count >= 4) { + tmp = readl(mvfqspi->iobase + QUADSPI_RBDR + i); + *rxbuf = endian_change_32bit(tmp); + rxbuf += 1; + count -= 4; + i += 4; + } + if (count) { + tmp = readl(mvfqspi->iobase + QUADSPI_RBDR + i); + tmp = endian_change_32bit(tmp); + memcpy(rxbuf, &tmp, count); + } } break; default: - printk(KERN_ERR "cannot support this opcode\n"); + printk(KERN_ERR "cannot support %x opcode\n", opr); break; } @@ -565,6 +613,11 @@ static void mvfqspi_work(struct work_struct *work) to_or_from = tx_buf & 0xffffff00; msg->actual_length += xfer->len; continue; + case OPCODE_FAST_READ: + opr = OPCODE_FAST_READ; + to_or_from = tx_buf & 0xffffff00; + msg->actual_length += xfer->len; + continue; case OPCODE_PP: opr = OPCODE_PP; to_or_from = tx_buf & 0xffffff00; @@ -592,7 +645,7 @@ static void mvfqspi_work(struct work_struct *work) break; default: printk(KERN_ERR "cannot support" - " this opcode\n"); + " %x opcode\n", temp_tx_buf); break; } } |