Add 4-byte address supports, so-that SPI-NOR chips has > 16MiB should accessible.
Signed-off-by: Jagan Teki <jt...@openedev.com> --- drivers/mtd/spi-nor/m25p80.c | 1 + drivers/mtd/spi-nor/spi-nor.c | 36 ++++++++++++++++++++++++++++++++++++ include/linux/mtd/spi-nor.h | 6 +++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/m25p80.c b/drivers/mtd/spi-nor/m25p80.c index 3393bed..42df9ef 100644 --- a/drivers/mtd/spi-nor/m25p80.c +++ b/drivers/mtd/spi-nor/m25p80.c @@ -31,6 +31,7 @@ static void m25p_addr2cmd(struct spi_nor *nor, unsigned int addr, u8 *cmd) cmd[1] = addr >> (nor->addr_width * 8 - 8); cmd[2] = addr >> (nor->addr_width * 8 - 16); cmd[3] = addr >> (nor->addr_width * 8 - 24); + cmd[4] = addr >> (nor->addr_width * 8 - 32); } static int m25p_cmdsz(struct spi_nor *nor) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index c280287..f49a70c 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -379,6 +379,36 @@ static int sst_write_bp(struct udevice *dev, loff_t to, size_t len, } #endif +/* Enable/disable 4-byte addressing mode. */ +static int set_4byte(struct spi_nor *nor, const struct spi_nor_info *info, + int enable) +{ + int status; + bool need_wren = false; + u8 cmd; + + switch (JEDEC_MFR(info)) { + case SNOR_MFR_MICRON: + /* Some Micron need WREN command; all will accept it */ + need_wren = true; + case SNOR_MFR_MACRONIX: + case SNOR_MFR_WINBOND: + if (need_wren) + write_enable(nor); + + cmd = enable ? SNOR_OP_EN4B : SNOR_OP_EX4B; + status = nor->write_reg(nor, cmd, NULL, 0); + if (need_wren) + write_disable(nor); + + return status; + default: + /* Spansion style */ + nor->cmd_buf[0] = enable << 7; + return nor->write_reg(nor, SNOR_OP_BRWR, nor->cmd_buf, 1); + } +} + #ifdef CONFIG_SPI_NOR_MACRONIX static int macronix_quad_enable(struct spi_nor *nor) { @@ -614,6 +644,12 @@ int spi_nor_scan(struct udevice *dev) } nor->addr_width = 3; + if (mtd->size > SNOR_16MB_BOUN) { + nor->addr_width = 4; + ret = set_4byte(nor, info, true); + if (ret) + return ret; + } /* Dummy cycles for read */ switch (nor->read_opcode) { diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index e2e225a..8f7db7f 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -62,6 +62,10 @@ #define SNOR_OP_BP 0x02 /* Byte program */ #define SNOR_OP_AAI_WP 0xad /* Auto addr increment word program */ +/* Used for Macronix and Winbond flashes. */ +#define SNOR_OP_EN4B 0xb7 /* Enter 4-byte mode */ +#define SNOR_OP_EX4B 0xe9 /* Exit 4-byte mode */ + /* Status Register bits. */ #define SR_WIP BIT(0) /* Write in progress */ #define SR_WEL BIT(1) /* Write enable latch */ @@ -83,7 +87,7 @@ /* Flash timeout values */ #define SNOR_READY_WAIT_PROG (2 * CONFIG_SYS_HZ) #define SNOR_READY_WAIT_ERASE (5 * CONFIG_SYS_HZ) -#define SNOR_MAX_CMD_SIZE 4 +#define SNOR_MAX_CMD_SIZE 6 #define SNOR_16MB_BOUN 0x1000000 enum snor_option_flags { -- 2.7.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot