summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeng Fan <Peng.Fan@freescale.com>2014-10-09 11:02:22 +0800
committerPeng Fan <Peng.Fan@freescale.com>2014-10-09 11:02:22 +0800
commit2100a53919eec7f9a76bc67204cd89e20afa2924 (patch)
tree9448c2072ed534237f0acf99f46629af84ed528c
parent7c174401a2607924bbe186d2b62bf1f325cbf24d (diff)
downloadu-boot-imx-2100a53919eec7f9a76bc67204cd89e20afa2924.zip
u-boot-imx-2100a53919eec7f9a76bc67204cd89e20afa2924.tar.gz
u-boot-imx-2100a53919eec7f9a76bc67204cd89e20afa2924.tar.bz2
MLK-9665-1 QuadSPI: Support flash bigger than 16MB
By introducing CONFIG_SPI_FLASH_BAR and add related command in LUT to enable fsl_qspi.c can handle flash size bigger that 16M. Because uboot does not support 32bits address access, this means bank address should be used to access bigger flash. It is hard to let qspi driver dynamically set LUT, so BRRD BRWR RDEAR and WREAR are all supported. Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
-rw-r--r--drivers/spi/fsl_qspi.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index 07374df..8439dbd 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -180,6 +180,12 @@
#define SEQID_RDCR 9
#define SEQID_DDR_QUAD_READ 10
#define SEQID_BE_4K 11
+#ifdef CONFIG_SPI_FLASH_BAR
+#define SEQID_BRRD 12
+#define SEQID_BRWR 13
+#define SEQID_RDEAR 14
+#define SEQID_WREAR 15
+#endif
/* Flash opcodes. */
#define OPCODE_WREN 0x06 /* Write enable */
@@ -214,7 +220,12 @@
#define OPCODE_EN4B 0xb7 /* Enter 4-byte mode */
#define OPCODE_EX4B 0xe9 /* Exit 4-byte mode */
+/* Used for Micron, winbond and Macronix flashes */
+#define OPCODE_WREAR 0xc5 /* EAR register write */
+#define OPCODE_RDEAR 0xc8 /* EAR reigster read */
+
/* Used for Spansion flashes only. */
+#define OPCODE_BRRD 0x16 /* Bank register read */
#define OPCODE_BRWR 0x17 /* Bank register write */
/* Status Register bits. */
@@ -377,6 +388,31 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
base + QUADSPI_LUT(lut_base));
+#ifdef CONFIG_SPI_FLASH_BAR
+ /*
+ * BRRD BRWR RDEAR WREAR are all supported, because it is hard to
+ * dynamically check whether to set BRRD BRWR or RDEAR WREAR.
+ */
+ lut_base = SEQID_BRRD * 4;
+ cmd = OPCODE_BRRD;
+ writel(LUT0(CMD, PAD1, cmd) | LUT1(READ, PAD1, 0x1),
+ base + QUADSPI_LUT(lut_base));
+
+ lut_base = SEQID_BRWR * 4;
+ cmd = OPCODE_BRWR;
+ writel(LUT0(CMD, PAD1, cmd) | LUT1(WRITE, PAD1, 0x1),
+ base + QUADSPI_LUT(lut_base));
+
+ lut_base = SEQID_RDEAR * 4;
+ cmd = OPCODE_RDEAR;
+ writel(LUT0(CMD, PAD1, cmd) | LUT1(READ, PAD1, 0x1),
+ base + QUADSPI_LUT(lut_base));
+
+ lut_base = SEQID_WREAR * 4;
+ cmd = OPCODE_WREAR;
+ writel(LUT0(CMD, PAD1, cmd) | LUT1(WRITE, PAD1, 0x1),
+ base + QUADSPI_LUT(lut_base));
+#endif
fsl_qspi_lock_lut(q);
}
@@ -589,6 +625,16 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
return SEQID_DDR_QUAD_READ;
case OPCODE_BE_4K:
return SEQID_BE_4K;
+#ifdef CONFIG_SPI_FLASH_BAR
+ case OPCODE_BRRD:
+ return SEQID_BRRD;
+ case OPCODE_BRWR:
+ return SEQID_BRWR;
+ case OPCODE_RDEAR:
+ return SEQID_RDEAR;
+ case OPCODE_WREAR:
+ return SEQID_WREAR;
+#endif
default:
break;
}
@@ -682,7 +728,10 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len)
/* restore the MCR */
writel(reg, base + QUADSPI_MCR);
- if ((OPCODE_SE == cmd) || (OPCODE_PP == cmd) || (OPCODE_BE_4K == cmd))
+ /* After switch BANK, AHB buffer should also be invalid. */
+ if ((OPCODE_SE == cmd) || (OPCODE_PP == cmd) ||
+ (OPCODE_BE_4K == cmd) || (OPCODE_WREAR == cmd) ||
+ (OPCODE_BRWR == cmd))
fsl_qspi_invalid(q);
return err;
}