From 5643c0782e5cd8ef19010ed9bba7286386b2b584 Mon Sep 17 00:00:00 2001 From: Sean Nelson Date: Tue, 19 Jan 2010 03:23:07 +0000 Subject: Block eraser conversions and support for Eon EN25B series Convert chips to block_erasers: ST_M25PE10 ST_M25PE20 ST_M25PE40 ST_M25PE80 ST_M25PE16 PMC_25LV010 PMC_25LV016B PMC_25LV020 PMC_25LV040 PMC_25LV080B PMC_25LV512 PMC_39F010 PMC_49FL002 PMC_49FL004 SANYO_LE25FW203A SPANSION_S25FL016A Added spi_block_erase_d7 for PMC chips. Corresponding to flashrom svn r867. Signed-off-by: Sean Nelson Acked-by: Carl-Daniel Hailfinger --- chipdrivers.h | 1 + flashchips.c | 256 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- spi.c | 42 ++++++++++ spi.h | 5 ++ 4 files changed, 283 insertions(+), 21 deletions(-) diff --git a/chipdrivers.h b/chipdrivers.h index e7261e0..496aa7e 100644 --- a/chipdrivers.h +++ b/chipdrivers.h @@ -38,6 +38,7 @@ int spi_chip_erase_60_c7(struct flashchip *flash); int spi_chip_erase_d8(struct flashchip *flash); int spi_block_erase_20(struct flashchip *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_52(struct flashchip *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_d7(struct flashchip *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_d8(struct flashchip *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_60(struct flashchip *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_c7(struct flashchip *flash, unsigned int addr, unsigned int blocklen); diff --git a/flashchips.c b/flashchips.c index 933682d..465950b 100644 --- a/flashchips.c +++ b/flashchips.c @@ -2959,7 +2959,20 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, - .erase = spi_chip_erase_d8, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 32} }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { {64 * 1024, 2} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {128 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, .write = spi_chip_write_256, .read = spi_chip_read, }, @@ -2975,7 +2988,20 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, - .erase = spi_chip_erase_d8, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 64} }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { {64 * 1024, 4} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {256 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, .write = spi_chip_write_256, .read = spi_chip_read, }, @@ -2986,12 +3012,25 @@ struct flashchip flashchips[] = { .bustype = CHIP_BUSTYPE_SPI, .manufacture_id = ST_ID, .model_id = ST_M25PE40, - .total_size = 256, + .total_size = 512, .page_size = 256, .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, - .erase = spi_chip_erase_d8, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 128} }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { {64 * 1024, 8} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {512 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, .write = spi_chip_write_256, .read = spi_chip_read, }, @@ -3007,7 +3046,20 @@ struct flashchip flashchips[] = { .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, - .erase = spi_chip_erase_d8, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 256} }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { {64 * 1024, 16} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {1024 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, .write = spi_chip_write_256, .read = spi_chip_read, }, @@ -3023,7 +3075,20 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, - .erase = spi_chip_erase_d8, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 512} }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { {64 * 1024, 32} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {2 * 1024 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, .write = spi_chip_write_256, .read = spi_chip_read, }, @@ -3039,7 +3104,20 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, - .erase = spi_chip_erase_c7, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 32} }, + .block_erase = spi_block_erase_d7, + }, { + .eraseblocks = { {32 * 1024, 4} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {128 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, .write = spi_chip_write_256, .read = spi_chip_read, }, @@ -3055,7 +3133,26 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, - .erase = spi_chip_erase_c7, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 512} }, + .block_erase = spi_block_erase_d7, + }, { + .eraseblocks = { {4 * 1024, 512} }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { {64 * 1024, 32} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {2 * 1024 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { {2 * 1024 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, .write = spi_chip_write_256, .read = spi_chip_read, }, @@ -3071,7 +3168,20 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, - .erase = spi_chip_erase_c7, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 64} }, + .block_erase = spi_block_erase_d7, + }, { + .eraseblocks = { {64 * 1024, 4} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {256 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, .write = spi_chip_write_256, .read = spi_chip_read, }, @@ -3087,7 +3197,20 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, - .erase = spi_chip_erase_c7, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 128} }, + .block_erase = spi_block_erase_d7, + }, { + .eraseblocks = { {64 * 1024, 8} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {512 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, .write = spi_chip_write_256, .read = spi_chip_read, }, @@ -3103,7 +3226,26 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, - .erase = spi_chip_erase_c7, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 256} }, + .block_erase = spi_block_erase_d7, + }, { + .eraseblocks = { {4 * 1024, 256} }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { {64 * 1024, 16} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {1024 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { {1024 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, .write = spi_chip_write_256, .read = spi_chip_read, }, @@ -3119,7 +3261,20 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, - .erase = spi_chip_erase_c7, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 16} }, + .block_erase = spi_block_erase_d7, + }, { + .eraseblocks = { {32 * 1024, 2} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {64 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, .write = spi_chip_write_256, .read = spi_chip_read, }, @@ -3194,10 +3349,23 @@ struct flashchip flashchips[] = { .model_id = PMC_39F010, .total_size = 128, .page_size = 4096, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRW, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ - .erase = erase_chip_jedec, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 32} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {64 * 1024, 2} }, + .block_erase = erase_block_jedec, + }, { + .eraseblocks = { {128 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + } + }, .write = write_49f002, .read = read_memmapped, }, @@ -3211,10 +3379,23 @@ struct flashchip flashchips[] = { .total_size = 256, .page_size = 16 * 1024, .feature_bits = FEATURE_REGISTERMAP, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRW, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */ - .erase = erase_49fl00x, + .erase = NULL, /* Was: erase_49fl00x */ + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 64} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {16 * 1024, 16} }, + .block_erase = erase_block_jedec, + }, { + .eraseblocks = { {256 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + } + }, .write = write_49fl00x, .read = read_memmapped, }, @@ -3228,10 +3409,23 @@ struct flashchip flashchips[] = { .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRW, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */ - .erase = erase_49fl00x, + .erase = NULL, /* Was: erase_49fl00x */ + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 128} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {64 * 1024, 8} }, + .block_erase = erase_block_jedec, + }, { + .eraseblocks = { {512 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + } + }, .write = write_49fl00x, .read = read_memmapped, }, @@ -3247,7 +3441,17 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, - .erase = spi_chip_erase_c7, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 32} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {2 * 1024 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, .write = spi_chip_write_256, .read = spi_chip_read, }, @@ -3317,10 +3521,20 @@ struct flashchip flashchips[] = { .model_id = SPANSION_S25FL016A, .total_size = 2048, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, - .erase = spi_chip_erase_c7, + .erase = NULL, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 32} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {2 * 1024 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, .write = spi_chip_write_256, .read = spi_chip_read, }, diff --git a/spi.c b/spi.c index 952952f..685c917 100644 --- a/spi.c +++ b/spi.c @@ -701,6 +701,48 @@ int spi_block_erase_d8(struct flashchip *flash, unsigned int addr, unsigned int return 0; } +/* Block size is usually + * 4k for PMC + */ +int spi_block_erase_d7(struct flashchip *flash, unsigned int addr, unsigned int blocklen) +{ + int result; + struct spi_command cmds[] = { + { + .writecnt = JEDEC_WREN_OUTSIZE, + .writearr = (const unsigned char[]){ JEDEC_WREN }, + .readcnt = 0, + .readarr = NULL, + }, { + .writecnt = JEDEC_BE_D7_OUTSIZE, + .writearr = (const unsigned char[]){ JEDEC_BE_D7, (addr >> 16) & 0xff, (addr >> 8) & 0xff, (addr & 0xff) }, + .readcnt = 0, + .readarr = NULL, + }, { + .writecnt = 0, + .writearr = NULL, + .readcnt = 0, + .readarr = NULL, + }}; + + result = spi_send_multicommand(cmds); + if (result) { + fprintf(stderr, "%s failed during command execution at address 0x%x\n", + __func__, addr); + return result; + } + /* Wait until the Write-In-Progress bit is cleared. + * This usually takes 100-4000 ms, so wait in 100 ms steps. + */ + while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) + programmer_delay(100 * 1000); + if (check_erased_range(flash, addr, blocklen)) { + fprintf(stderr, "ERASE FAILED!\n"); + return -1; + } + return 0; +} + int spi_chip_erase_d8(struct flashchip *flash) { int i, rc = 0; diff --git a/spi.h b/spi.h index 2fa7dcd..1b49d59 100644 --- a/spi.h +++ b/spi.h @@ -74,6 +74,11 @@ #define JEDEC_BE_D8_OUTSIZE 0x04 #define JEDEC_BE_D8_INSIZE 0x00 +/* Block Erase 0xd7 is supported by PMC chips. */ +#define JEDEC_BE_D7 0xd7 +#define JEDEC_BE_D7_OUTSIZE 0x04 +#define JEDEC_BE_D7_INSIZE 0x00 + /* Sector Erase 0x20 is supported by Macronix/SST chips. */ #define JEDEC_SE 0x20 #define JEDEC_SE_OUTSIZE 0x04 -- cgit v1.1