diff options
author | Peng Fan <Peng.Fan@freescale.com> | 2014-10-09 11:02:22 +0800 |
---|---|---|
committer | Peng Fan <Peng.Fan@freescale.com> | 2014-10-09 11:02:22 +0800 |
commit | 2100a53919eec7f9a76bc67204cd89e20afa2924 (patch) | |
tree | 9448c2072ed534237f0acf99f46629af84ed528c /drivers/spi | |
parent | 7c174401a2607924bbe186d2b62bf1f325cbf24d (diff) | |
download | u-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>
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/fsl_qspi.c | 51 |
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; } |