diff options
author | Anthony Felice <tony.felice@timesys.com> | 2013-11-07 11:57:41 -0500 |
---|---|---|
committer | Anthony Felice <tony.felice@timesys.com> | 2013-11-07 11:57:41 -0500 |
commit | bbe3c57f4489c859ccad49a82567aa44d4637087 (patch) | |
tree | 175e57bf41ec321500f75c90b632d40a3aa26cfc | |
parent | 8dbbf996897e1d5878f3f5fd5fff5adedb04f3b8 (diff) |
Fix FAST_READ for QSPI nor flash support.
This patch was submitted by Roshni Shah <roshni.shah@timesys.com>
for ticket #52067
-rw-r--r-- | arch/arm/mach-mvf/board-twr-vf700.c | 4 | ||||
-rw-r--r-- | drivers/mtd/devices/m25p80.c | 3 | ||||
-rw-r--r-- | drivers/spi/spi_mvf_qspi.c | 65 |
3 files changed, 63 insertions, 9 deletions
diff --git a/arch/arm/mach-mvf/board-twr-vf700.c b/arch/arm/mach-mvf/board-twr-vf700.c index becf814e3a11..5e5fec968711 100644 --- a/arch/arm/mach-mvf/board-twr-vf700.c +++ b/arch/arm/mach-mvf/board-twr-vf700.c @@ -322,7 +322,7 @@ static struct spi_mvf_chip at26df081a_chip_info = { static struct mtd_partition s25fl256s_partitions[] = { { - .name = "s25fl256s", + .name = "Flash_JFFS2", .size = (1024 * 64 * 256), .offset = 0x00000000, .mask_flags = 0, @@ -333,7 +333,7 @@ static struct flash_platform_data s25fl256s_spi_flash_data = { .name = "Spansion s25fl128s SPI Flash chip", .parts = s25fl256s_partitions, .nr_parts = ARRAY_SIZE(s25fl256s_partitions), - .type = "s25fl128s", + .type = "s25fl128s1", }; #endif 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; } } |