diff options
-rw-r--r-- | flashchips.c | 286 | ||||
-rw-r--r-- | flashchips.h | 15 | ||||
-rw-r--r-- | spi25.c | 14 |
3 files changed, 309 insertions, 6 deletions
diff --git a/flashchips.c b/flashchips.c index 3842170..902f956 100644 --- a/flashchips.c +++ b/flashchips.c @@ -1169,14 +1169,207 @@ struct flashchip flashchips[] = { .read = read_memmapped, }, - /* The next two chip definitions have top/bottom boot blocks, but has no - device differentiation between the two */ + { + .vendor = "AMIC", + .name = "A25L05PT", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID, + .model_id = AMIC_A25L05PT, + .total_size = 64, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid4, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {32 * 1024, 1}, + {16 * 1024, 1}, + {8 * 1024, 1}, + {4 * 1024, 2}, + }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {64 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = spi_disable_blockprotect, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + { + .vendor = "AMIC", + .name = "A25L05PU", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID, + .model_id = AMIC_A25L05PU, + .total_size = 64, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid4, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {4 * 1024, 2}, + {8 * 1024, 1}, + {16 * 1024, 1}, + {32 * 1024, 1}, + }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {64 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = spi_disable_blockprotect, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + { + .vendor = "AMIC", + .name = "A25L10PT", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID, + .model_id = AMIC_A25L10PT, + .total_size = 128, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid4, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {64 * 1024, 1}, + {32 * 1024, 1}, + {16 * 1024, 1}, + {8 * 1024, 1}, + {4 * 1024, 2}, + }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {128 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = spi_disable_blockprotect, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + { + .vendor = "AMIC", + .name = "A25L10PU", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID, + .model_id = AMIC_A25L10PU, + .total_size = 128, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid4, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {4 * 1024, 2}, + {8 * 1024, 1}, + {16 * 1024, 1}, + {32 * 1024, 1}, + {64 * 1024, 1}, + }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {128 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = spi_disable_blockprotect, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + { + .vendor = "AMIC", + .name = "A25L20PT", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID, + .model_id = AMIC_A25L20PT, + .total_size = 256, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid4, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {64 * 1024, 3}, + {32 * 1024, 1}, + {16 * 1024, 1}, + {8 * 1024, 1}, + {4 * 1024, 2}, + }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {256 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = spi_disable_blockprotect, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + { + .vendor = "AMIC", + .name = "A25L20PU", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID, + .model_id = AMIC_A25L20PU, + .total_size = 256, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid4, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {4 * 1024, 2}, + {8 * 1024, 1}, + {16 * 1024, 1}, + {32 * 1024, 1}, + {64 * 1024, 3}, + }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {256 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = spi_disable_blockprotect, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + /* The A25L40P{T,U} chips are distinguished by their + * erase block layouts, but without any distinction in RDID. + * This inexplicable quirk was verified by Rudolf Marek + * and discussed on the flashrom mailing list on 2010-07-12. + */ { .vendor = "AMIC", .name = "A25L40PT", .bustype = CHIP_BUSTYPE_SPI, .manufacture_id = AMIC_ID, - .model_id = AMIC_A25L40P, + .model_id = AMIC_A25L40PT, .total_size = 512, .page_size = 256, .tested = TEST_OK_PRW, @@ -1208,7 +1401,7 @@ struct flashchip flashchips[] = { .name = "A25L40PU", .bustype = CHIP_BUSTYPE_SPI, .manufacture_id = AMIC_ID, - .model_id = AMIC_A25L40P, + .model_id = AMIC_A25L40PU, .total_size = 512, .page_size = 256, .tested = TEST_OK_PRW, @@ -1269,6 +1462,76 @@ struct flashchip flashchips[] = { { .vendor = "AMIC", + .name = "A25L16PT", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID, + .model_id = AMIC_A25L16PT, + .total_size = 2048, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid4, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {64 * 1024, 31}, + {32 * 1024, 1}, + {16 * 1024, 1}, + {8 * 1024, 1}, + {4 * 1024, 2}, + }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {2048 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { {2048 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = spi_disable_blockprotect, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + { + .vendor = "AMIC", + .name = "A25L16PU", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID, + .model_id = AMIC_A25L16PU, + .total_size = 2048, + .page_size = 256, + .tested = TEST_OK_PRW, + .probe = probe_spi_rdid4, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {4 * 1024, 2}, + {8 * 1024, 1}, + {16 * 1024, 1}, + {32 * 1024, 1}, + {64 * 1024, 31}, + }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {2048 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { {2048 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = spi_disable_blockprotect, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + { + .vendor = "AMIC", .name = "A29002B", .bustype = CHIP_BUSTYPE_PARALLEL, .manufacture_id = AMIC_ID_NOPREFIX, @@ -6678,6 +6941,21 @@ struct flashchip flashchips[] = { }, { + .vendor = "AMIC", + .name = "unknown AMIC SPI chip", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID, + .model_id = GENERIC_DEVICE_ID, + .total_size = 0, + .page_size = 256, + .tested = TEST_BAD_PREW, + .probe = probe_spi_rdid4, + .probe_timing = TIMING_ZERO, + .write = NULL, + .read = NULL, + }, + + { .vendor = "Atmel", .name = "unknown Atmel SPI chip", .bustype = CHIP_BUSTYPE_SPI, diff --git a/flashchips.h b/flashchips.h index 63cba1e..3157b68 100644 --- a/flashchips.h +++ b/flashchips.h @@ -75,8 +75,19 @@ #define AMIC_ID 0x7F37 /* AMIC */ #define AMIC_ID_NOPREFIX 0x37 /* AMIC */ -#define AMIC_A25L40P 0x2013 -#define AMIC_A25L80P 0x2014 +#define AMIC_A25L05PT 0x2020 +#define AMIC_A25L05PU 0x2010 +#define AMIC_A25L10PT 0x2021 +#define AMIC_A25L10PU 0x2011 +#define AMIC_A25L20PT 0x2022 +#define AMIC_A25L20PU 0x2012 +#define AMIC_A25L40PT 0x2013 /* Datasheet says T and U have + same device ID. Confirmed by + hardware testing. */ +#define AMIC_A25L40PU 0x2013 +#define AMIC_A25L80P 0x2014 /* Seems that no A25L80PT exists */ +#define AMIC_A25L16PT 0x2025 +#define AMIC_A25L16PU 0x2015 #define AMIC_A29002B 0x0d #define AMIC_A29002T 0x8C /* Same as A290021T */ #define AMIC_A29040B 0x86 @@ -328,6 +328,16 @@ void spi_prettyprint_status_register_common(uint8_t status) } /* Prettyprint the status register. Works for + * AMIC A25L series + */ +void spi_prettyprint_status_register_amic_a25l(uint8_t status) +{ + msg_cdbg("Chip status register: Status Register Write Disable " + "(SRWD) is %sset\n", (status & (1 << 7)) ? "" : "not "); + spi_prettyprint_status_register_common(status); +} + +/* Prettyprint the status register. Works for * ST M25P series * MX MX25L series */ @@ -389,6 +399,10 @@ void spi_prettyprint_status_register(struct flashchip *flash) status = spi_read_status_register(); msg_cdbg("Chip status register is %02x\n", status); switch (flash->manufacture_id) { + case AMIC_ID: + if ((flash->model_id & 0xff00) == 0x2000) + spi_prettyprint_status_register_amic_a25l(status); + break; case ST_ID: if (((flash->model_id & 0xff00) == 0x2000) || ((flash->model_id & 0xff00) == 0x2500)) |