SF: Bulk Erase command support for spansion

Change-Id: Ida70d167cafc6af823f31c660d108cc25be6edff
Signed-off-by: Antony Arun T <antothom@codeaurora.org>
This commit is contained in:
Antony Arun T 2018-02-23 11:55:36 +05:30
parent d8c656785c
commit 4ca40fa90d
5 changed files with 78 additions and 2 deletions

View file

@ -347,6 +347,22 @@ static int do_spi_flash_erase(int argc, char * const argv[])
return ret == 0 ? 0 : 1; return ret == 0 ? 0 : 1;
} }
static int do_spi_flash_berase(int argc, char * const argv[])
{
switch (spi_flash_berase(flash)) {
case 0:
return 0;
case -ENOTSUPP:
printf("SPI flash %s not supported\n", argv[0]);
return 1;
default:
printf("SPI flash %s failed\n", argv[0]);
return 1;
}
return 1;
}
static int do_spi_protect(int argc, char * const argv[]) static int do_spi_protect(int argc, char * const argv[])
{ {
int ret = 0; int ret = 0;
@ -576,6 +592,8 @@ static int do_spi_flash(cmd_tbl_t *cmdtp, int flag, int argc,
else if (!strcmp(cmd, "test")) else if (!strcmp(cmd, "test"))
ret = do_spi_flash_test(argc, argv); ret = do_spi_flash_test(argc, argv);
#endif #endif
else if (strcmp(cmd, "bulkerase") == 0)
ret = do_spi_flash_berase(argc, argv);
else else
ret = -1; ret = -1;
@ -613,5 +631,7 @@ U_BOOT_CMD(
" or to start of mtd `partition'\n" " or to start of mtd `partition'\n"
"sf protect lock/unlock sector len - protect/unprotect 'len' bytes starting\n" "sf protect lock/unlock sector len - protect/unprotect 'len' bytes starting\n"
" at address 'sector'\n" " at address 'sector'\n"
"sf bulkerase - Erase entire flash chip\n"
" (Not supported on all devices)\n"
SF_TEST_HELP SF_TEST_HELP
); );

View file

@ -12,6 +12,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/compat.h>
/* Dual SPI flash memories - see SPI_COMM_DUAL_... */ /* Dual SPI flash memories - see SPI_COMM_DUAL_... */
enum spi_dual_flash { enum spi_dual_flash {
@ -115,6 +116,7 @@ enum spi_nor_option_flags {
#define SPI_FLASH_PROG_TIMEOUT (2 * CONFIG_SYS_HZ) #define SPI_FLASH_PROG_TIMEOUT (2 * CONFIG_SYS_HZ)
#define SPI_FLASH_PAGE_ERASE_TIMEOUT (5 * CONFIG_SYS_HZ) #define SPI_FLASH_PAGE_ERASE_TIMEOUT (5 * CONFIG_SYS_HZ)
#define SPI_FLASH_SECTOR_ERASE_TIMEOUT (10 * CONFIG_SYS_HZ) #define SPI_FLASH_SECTOR_ERASE_TIMEOUT (10 * CONFIG_SYS_HZ)
#define SPI_FLASH_BERASE_TIMEOUT(f) ((f)->berase_timeout * CONFIG_SYS_HZ)
/* SST specific */ /* SST specific */
#ifdef CONFIG_SPI_FLASH_SST #ifdef CONFIG_SPI_FLASH_SST
@ -147,6 +149,7 @@ struct spi_flash_params {
u32 nr_sectors; u32 nr_sectors;
u8 e_rd_cmd; u8 e_rd_cmd;
u16 flags; u16 flags;
u16 bulkerase_timeout; /* in seconds */
}; };
extern const struct spi_flash_params spi_flash_params_table[]; extern const struct spi_flash_params spi_flash_params_table[];

View file

@ -72,9 +72,9 @@ const struct spi_flash_params spi_flash_params_table[] = {
{"S25FL032P", 0x010215, 0x4d00, 64 * 1024, 64, RD_FULL, WR_QPP}, {"S25FL032P", 0x010215, 0x4d00, 64 * 1024, 64, RD_FULL, WR_QPP},
{"S25FL064P", 0x010216, 0x4d00, 64 * 1024, 128, RD_FULL, WR_QPP}, {"S25FL064P", 0x010216, 0x4d00, 64 * 1024, 128, RD_FULL, WR_QPP},
{"S25FL128S_256K", 0x012018, 0x4d00, 256 * 1024, 64, RD_FULL, WR_QPP}, {"S25FL128S_256K", 0x012018, 0x4d00, 256 * 1024, 64, RD_FULL, WR_QPP},
{"S25FL128S_64K", 0x012018, 0x4d01, 64 * 1024, 256, RD_FULL, WR_QPP}, {"S25FL128S_64K", 0x012018, 0x4d01, 64 * 1024, 256, RD_FULL, WR_QPP, 180},
{"S25FL256S_256K", 0x010219, 0x4d00, 256 * 1024, 128, RD_FULL, WR_QPP}, {"S25FL256S_256K", 0x010219, 0x4d00, 256 * 1024, 128, RD_FULL, WR_QPP},
{"S25FL256S_64K", 0x010219, 0x4d01, 64 * 1024, 512, RD_FULL, WR_QPP}, {"S25FL256S_64K", 0x010219, 0x4d01, 64 * 1024, 512, RD_FULL, WR_QPP, 360},
{"S25FL512S_256K", 0x010220, 0x4d00, 256 * 1024, 256, RD_FULL, WR_QPP}, {"S25FL512S_256K", 0x010220, 0x4d00, 256 * 1024, 256, RD_FULL, WR_QPP},
{"S25FL512S_64K", 0x010220, 0x4d01, 64 * 1024, 1024, RD_FULL, WR_QPP}, {"S25FL512S_64K", 0x010220, 0x4d01, 64 * 1024, 1024, RD_FULL, WR_QPP},
{"S25FL512S_512K", 0x010220, 0x4f00, 256 * 1024, 256, RD_FULL, WR_QPP}, {"S25FL512S_512K", 0x010220, 0x4f00, 256 * 1024, 256, RD_FULL, WR_QPP},

View file

@ -19,6 +19,10 @@
#include "sf_internal.h" #include "sf_internal.h"
#if defined CONFIG_SPI_FLASH_SPANSION
#define CMD_S25FSXX_BE 0x60
#endif
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
static void spi_flash_addr(struct spi_flash *flash, u32 addr, u8 *cmd) static void spi_flash_addr(struct spi_flash *flash, u32 addr, u8 *cmd)
@ -266,6 +270,37 @@ static int spi_flash_cmd_wait_ready(struct spi_flash *flash,
return -ETIMEDOUT; return -ETIMEDOUT;
} }
#if defined CONFIG_SPI_FLASH_SPANSION
int spi_flash_cmd_berase(struct spi_flash *flash, u8 erase_cmd)
{
int ret;
ret = spi_claim_bus(flash->spi);
if (ret) {
debug("SF: Unable to claim SPI bus\n");
return ret;
}
ret = spi_flash_cmd_write_enable(flash);
if (ret)
goto out;
ret = spi_flash_cmd_write(flash->spi, &erase_cmd, 1, NULL, 0);
if (ret)
goto out;
ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_BERASE_TIMEOUT(flash));
out:
spi_release_bus(flash->spi);
return ret;
}
static int bulk_erase(struct spi_flash *flash)
{
return spi_flash_cmd_berase(flash, CMD_S25FSXX_BE);
}
#endif
int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd, int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
size_t cmd_len, const void *buf, size_t buf_len) size_t cmd_len, const void *buf, size_t buf_len)
{ {
@ -1161,5 +1196,12 @@ print_sf_info:
} }
#endif #endif
#if defined CONFIG_SPI_FLASH_SPANSION
if (params->bulkerase_timeout) {
flash->berase = bulk_erase;
flash->berase_timeout = params->bulkerase_timeout;
}
#endif
return ret; return ret;
} }

View file

@ -114,6 +114,9 @@ struct spi_flash {
const void *buf); const void *buf);
int (*erase)(struct spi_flash *flash, u32 offset, size_t len); int (*erase)(struct spi_flash *flash, u32 offset, size_t len);
#endif #endif
u16 berase_timeout; /* Bulk erase timeout */
int (*berase)(struct spi_flash *flash); /* Bulk Erase */
}; };
struct dm_spi_flash_ops { struct dm_spi_flash_ops {
@ -249,6 +252,14 @@ static inline int spi_flash_protect(struct spi_flash *flash, u32 ofs, u32 len,
return flash->flash_unlock(flash, ofs, len); return flash->flash_unlock(flash, ofs, len);
} }
static inline int spi_flash_berase(struct spi_flash *flash)
{
if (!flash->berase)
return -ENOTSUPP;
return flash->berase(flash);
}
void spi_boot(void) __noreturn; void spi_boot(void) __noreturn;
void spi_spl_load_image(uint32_t offs, unsigned int size, void *vdst); void spi_spl_load_image(uint32_t offs, unsigned int size, void *vdst);