summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Felice <tony.felice@timesys.com>2013-11-07 11:57:41 -0500
committerAnthony Felice <tony.felice@timesys.com>2013-11-07 11:57:41 -0500
commitbbe3c57f4489c859ccad49a82567aa44d4637087 (patch)
tree175e57bf41ec321500f75c90b632d40a3aa26cfc
parent8dbbf996897e1d5878f3f5fd5fff5adedb04f3b8 (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.c4
-rw-r--r--drivers/mtd/devices/m25p80.c3
-rw-r--r--drivers/spi/spi_mvf_qspi.c65
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;
}
}