diff options
author | Tom Rini <trini@konsulko.com> | 2016-05-24 13:42:03 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2016-05-24 13:42:03 -0400 |
commit | fc15b9beed05dec6cc092c265042381a0eadb0e9 (patch) | |
tree | 2b256906815661689177279d7cd23e30827c377b /drivers/mtd | |
parent | 2ee490a0245b65826a8ce8e42e34c9bf805d3656 (diff) | |
parent | bc323b3fa7cbf1008f02d342c0505231961b5fa6 (diff) | |
download | u-boot-imx-fc15b9beed05dec6cc092c265042381a0eadb0e9.zip u-boot-imx-fc15b9beed05dec6cc092c265042381a0eadb0e9.tar.gz u-boot-imx-fc15b9beed05dec6cc092c265042381a0eadb0e9.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-fsl-qoriq
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/spi/sf_internal.h | 5 | ||||
-rw-r--r-- | drivers/mtd/spi/spi_flash.c | 72 |
2 files changed, 77 insertions, 0 deletions
diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 007a5a0..da2bb7b 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -127,6 +127,11 @@ int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, const void *buf); #endif +#ifdef CONFIG_SPI_FLASH_SPANSION +/* Used for Spansion S25FS-S family flash only. */ +#define CMD_SPANSION_RDAR 0x65 /* Read any device register */ +#define CMD_SPANSION_WRAR 0x71 /* Write any device register */ +#endif /** * struct spi_flash_params - SPI/QSPI flash device params structure * diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 5451725..fa0e799 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -971,6 +971,43 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) } #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ +#ifdef CONFIG_SPI_FLASH_SPANSION +static int spansion_s25fss_disable_4KB_erase(struct spi_slave *spi) +{ + u8 cmd[4]; + u32 offset = 0x800004; /* CR3V register offset */ + u8 cr3v; + int ret; + + cmd[0] = CMD_SPANSION_RDAR; + cmd[1] = offset >> 16; + cmd[2] = offset >> 8; + cmd[3] = offset >> 0; + + ret = spi_flash_cmd_read(spi, cmd, 4, &cr3v, 1); + if (ret) + return -EIO; + /* CR3V bit3: 4-KB Erase */ + if (cr3v & 0x8) + return 0; + + cmd[0] = CMD_SPANSION_WRAR; + cr3v |= 0x8; + ret = spi_flash_cmd_write(spi, cmd, 4, &cr3v, 1); + if (ret) + return -EIO; + + cmd[0] = CMD_SPANSION_RDAR; + ret = spi_flash_cmd_read(spi, cmd, 4, &cr3v, 1); + if (ret) + return -EIO; + if (!(cr3v & 0x8)) + return -EFAULT; + + return 0; +} +#endif + int spi_flash_scan(struct spi_flash *flash) { struct spi_slave *spi = flash->spi; @@ -1021,6 +1058,41 @@ int spi_flash_scan(struct spi_flash *flash) return -EPROTONOSUPPORT; } +#ifdef CONFIG_SPI_FLASH_SPANSION + /* + * The S25FS-S family physical sectors may be configured as a + * hybrid combination of eight 4-kB parameter sectors + * at the top or bottom of the address space with all + * but one of the remaining sectors being uniform size. + * The Parameter Sector Erase commands (20h or 21h) must + * be used to erase the 4-kB parameter sectors individually. + * The Sector (uniform sector) Erase commands (D8h or DCh) + * must be used to erase any of the remaining + * sectors, including the portion of highest or lowest address + * sector that is not overlaid by the parameter sectors. + * The uniform sector erase command has no effect on parameter sectors. + */ + if (jedec == 0x0219 && (ext_jedec & 0xff00) == 0x4d00) { + int ret; + u8 id[6]; + + /* Read the ID codes again, 6 bytes */ + ret = spi_flash_cmd(flash->spi, CMD_READ_ID, id, sizeof(id)); + if (ret) + return -EIO; + + ret = memcmp(id, idcode, 5); + if (ret) + return -EIO; + + /* 0x81: S25FS-S family 0x80: S25FL-S family */ + if (id[5] == 0x81) { + ret = spansion_s25fss_disable_4KB_erase(spi); + if (ret) + return ret; + } + } +#endif /* Flash powers up read-only, so clear BP# bits */ if (idcode[0] == SPI_FLASH_CFI_MFR_ATMEL || idcode[0] == SPI_FLASH_CFI_MFR_MACRONIX || |