diff options
-rw-r--r-- | chipdrivers.h | 1 | ||||
-rw-r--r-- | flashchips.c | 3 | ||||
-rw-r--r-- | spi.h | 5 | ||||
-rw-r--r-- | spi25.c | 47 |
4 files changed, 56 insertions, 0 deletions
diff --git a/chipdrivers.h b/chipdrivers.h index b43e16e..b8af62a 100644 --- a/chipdrivers.h +++ b/chipdrivers.h @@ -40,6 +40,7 @@ int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int b int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_60(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_62(struct flashctx *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_c7(struct flashctx *flash, unsigned int addr, unsigned int blocklen); erasefunc_t *spi_get_erasefn_from_opcode(uint8_t opcode); int spi_chip_write_1(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); diff --git a/flashchips.c b/flashchips.c index 1175333..c794afc 100644 --- a/flashchips.c +++ b/flashchips.c @@ -1695,6 +1695,9 @@ const struct flashchip flashchips[] = { }, { .eraseblocks = { {64 * 1024, 1} }, .block_erase = spi_block_erase_c7, + }, { + .eraseblocks = { {64 * 1024, 1} }, + .block_erase = spi_block_erase_62, } }, .printlock = spi_prettyprint_status_register_at25f512b, @@ -66,6 +66,11 @@ #define JEDEC_CE_60_OUTSIZE 0x01 #define JEDEC_CE_60_INSIZE 0x00 +/* Chip Erase 0x62 is supported by Atmel AT25F chips. */ +#define JEDEC_CE_62 0x62 +#define JEDEC_CE_62_OUTSIZE 0x01 +#define JEDEC_CE_62_INSIZE 0x00 + /* Chip Erase 0xc7 is supported by SST/ST/EON/Macronix chips. */ #define JEDEC_CE_C7 0xc7 #define JEDEC_CE_C7_OUTSIZE 0x01 @@ -487,6 +487,43 @@ int spi_chip_erase_60(struct flashctx *flash) return 0; } +int spi_chip_erase_62(struct flashctx *flash) +{ + int result; + struct spi_command cmds[] = { + { + .writecnt = JEDEC_WREN_OUTSIZE, + .writearr = (const unsigned char[]){ JEDEC_WREN }, + .readcnt = 0, + .readarr = NULL, + }, { + .writecnt = JEDEC_CE_62_OUTSIZE, + .writearr = (const unsigned char[]){ JEDEC_CE_62 }, + .readcnt = 0, + .readarr = NULL, + }, { + .writecnt = 0, + .writearr = NULL, + .readcnt = 0, + .readarr = NULL, + }}; + + result = spi_send_multicommand(flash, cmds); + if (result) { + msg_cerr("%s failed during command execution\n", + __func__); + return result; + } + /* Wait until the Write-In-Progress bit is cleared. + * This usually takes 2-5 s, so wait in 100 ms steps. + */ + /* FIXME: We assume spi_read_status_register will never fail. */ + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(100 * 1000); + /* FIXME: Check the status register for errors. */ + return 0; +} + int spi_chip_erase_c7(struct flashctx *flash) { int result; @@ -711,6 +748,16 @@ int spi_block_erase_60(struct flashctx *flash, unsigned int addr, return spi_chip_erase_60(flash); } +int spi_block_erase_62(struct flashctx *flash, unsigned int addr, unsigned int blocklen) +{ + if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) { + msg_cerr("%s called with incorrect arguments\n", + __func__); + return -1; + } + return spi_chip_erase_62(flash); +} + int spi_block_erase_c7(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { |