This patch adds the following chips, all untested, based on the AMIC datasheets: http://www.amictechnology.com/pdf/A25L20P.pdf covers: AMIC A25L05PT AMIC A25L05PU AMIC A25L10PT AMIC A25L10PU AMIC A25L20PT AMIC A25L20PU http://www.amictechnology.com/pdf/A25L16P.pdf covers: AMIC A25L16PT AMIC A25L16PU
In comments, it also clarifies the situation surrounding the A25L40PT and A25L40PU chips, which share the same RDID values, despite the fact that their erase block layouts are different. Rudolf Marek tested and confirmed the distinct erase block layouts of these chips, so I also marked them as TEST_OK_PREW.
Finally, it adds a pretty-printer for the AMIC SPI chips, and a generic AMIC chip type.
Signed-off-by: Daniel Lenski dlenski@gmail.com
On Mon, 2010-07-12 at 16:46 -0400, Daniel Lenski wrote:
This patch adds the following chips, all untested, based on the AMIC datasheets: http://www.amictechnology.com/pdf/A25L20P.pdf covers: AMIC A25L05PT AMIC A25L05PU AMIC A25L10PT AMIC A25L10PU AMIC A25L20PT AMIC A25L20PU http://www.amictechnology.com/pdf/A25L16P.pdf covers: AMIC A25L16PT AMIC A25L16PU
In comments, it also clarifies the situation surrounding the A25L40PT and A25L40PU chips, which share the same RDID values, despite the fact that their erase block layouts are different. Rudolf Marek tested and confirmed the distinct erase block layouts of these chips, so I also marked them as TEST_OK_PREW.
Finally, it adds a pretty-printer for the AMIC SPI chips, and a generic AMIC chip type.
Signed-off-by: Daniel Lenski dlenski@gmail.com
Did this patch get forgotten?
It added the AMIC SPI chips requested by Carl-Daniel Hailfinger. Pretty straightforward stuff. Please let me know if there are any changes needed.
Dan
Hi Daniel,
thanks a lot for your patch.
On 12.07.2010 22:46, Daniel Lenski wrote:
This patch adds the following chips, all untested, based on the AMIC datasheets: http://www.amictechnology.com/pdf/A25L20P.pdf covers: AMIC A25L05PT AMIC A25L05PU AMIC A25L10PT AMIC A25L10PU AMIC A25L20PT AMIC A25L20PU http://www.amictechnology.com/pdf/A25L16P.pdf covers: AMIC A25L16PT AMIC A25L16PU
In comments, it also clarifies the situation surrounding the A25L40PT and A25L40PU chips, which share the same RDID values, despite the fact that their erase block layouts are different. Rudolf Marek tested and confirmed the distinct erase block layouts of these chips, so I also marked them as TEST_OK_PREW.
Finally, it adds a pretty-printer for the AMIC SPI chips, and a generic AMIC chip type.
Signed-off-by: Daniel Lenski dlenski@gmail.com
I have changed the whitespace in a few places, added the .unlock function to the chip definitions and added the 0x60 chip erase command to the A25L16P* family chips.
Acked-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net and committed in r1096.
Side note: If anyone is looking for the datasheet for the not-yet-supported A25L032 family, here it is: http://www.amictechnology.com/pdf/A25L032.pdf
Regards, Carl-Daniel
On Thu, Jul 22, 2010 at 7:58 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Side note: If anyone is looking for the datasheet for the not-yet-supported A25L032 family, here it is: http://www.amictechnology.com/pdf/A25L032.pdf
I took a look at this. Similar to the others from AMIC but...
Incredibly, the data sheet states two different device ID values on page 31 (it's either 0x3016 or 0x4016). Does anyone know which is right?
This device has *two* status registers, with separate RDSR-1 and RDSR-2 commands, but a combined WRSR command. The first has the standard block protect bits BP0-2, while the second has an "All protect" (APT) bit which overrides the BP bits. I think the unlock procedure would have to be modified to account for this APT bit.
Dan
On 22.07.2010 15:35, Daniel Lenski wrote:
On Thu, Jul 22, 2010 at 7:58 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Side note: If anyone is looking for the datasheet for the not-yet-supported A25L032 family, here it is: http://www.amictechnology.com/pdf/A25L032.pdf
I took a look at this. Similar to the others from AMIC but...
Incredibly, the data sheet states two different device ID values on page 31 (it's either 0x3016 or 0x4016). Does anyone know which is right?
According to my datsheets, the following is true: 0x7f37 0x2025 is A25L16PT (top) 0x7f37 0x2015 is A25L16PU (bottom) The chips above are already supported.
The chips below are all unsupported: http://www.amictechnology.com/pdf/A25L512.pdf http://www.amictechnology.com/pdf/A25L010.pdf http://www.amictechnology.com/pdf/A25L020.pdf http://www.amictechnology.com/pdf/A25L040.pdf http://www.amictechnology.com/pdf/A25L080.pdf http://www.amictechnology.com/pdf/A25L016.pdf http://www.amictechnology.com/pdf/A25L032.pdf http://www.amictechnology.com/pdf/A25LQ032.pdf IDs: 0x37 0x3010 is A25L512 (uniform 4k sectors) 0x37 0x3011 is A25L010 (uniform 4k sectors) 0x37 0x3012 is A25L020 (uniform 4k sectors) 0x37 0x3013 is A25L040 (uniform 4k sectors) 0x37 0x3014 is A25L080 (uniform 4k sectors) 0x37 0x3015 is A25L016 (uniform 4k sectors) 0x37 0x3016 is A25L032 (uniform 4k sectors) 0x37 0x4016 is A25LQ032 (uniform 4k sectors) Please note that the IDs of the newer chips all use AMIC_ID_NOPREFIX instead of AMIC_ID, and that means they use probe_spi_rdid instead of probe_spi_rdid4.
This device has *two* status registers, with separate RDSR-1 and RDSR-2 commands, but a combined WRSR command. The first has the standard block protect bits BP0-2, while the second has an "All protect" (APT) bit which overrides the BP bits. I think the unlock procedure would have to be modified to account for this APT bit.
You can either set .unlock=NULL or write a new unlock function. If you decide to write a new unlock function, please note that you'll need an audit of all SPI programmer drivers to check whether they can deal with such writes. I can help with such an audit, but I'd be happy if I could postpone that work a bit because my TODO list is huge. OTOH, drivers without unlock should be mergeable quickly.
Side note: Right now we have the AMIC chips after the Atmel chips in flashchips.c instead of placing them directly after the AMD chips. Not sure if a move makes sense (good for consistency, but it will mess up svn blame).
Regards, Carl-Daniel
This patch should enable read/write/erase support for these chips, but does *not* implement unlock functionality for them yet, because they have more complex protection features than simply BPx block-protect bits.
Datasheets: http://www.amictechnology.com/pdf/A25L512.pdf http://www.amictechnology.com/pdf/A25L010.pdf http://www.amictechnology.com/pdf/A25L020.pdf http://www.amictechnology.com/pdf/A25L040.pdf http://www.amictechnology.com/pdf/A25L080.pdf http://www.amictechnology.com/pdf/A25L016.pdf http://www.amictechnology.com/pdf/A25L032.pdf http://www.amictechnology.com/pdf/A25LQ032.pdf
IDs: 0x37 0x3010 is A25L512 (uniform 4k sectors) 0x37 0x3011 is A25L010 (uniform 4k sectors) 0x37 0x3012 is A25L020 (uniform 4k sectors) 0x37 0x3013 is A25L040 (uniform 4k sectors) 0x37 0x3014 is A25L080 (uniform 4k sectors) 0x37 0x3015 is A25L016 (uniform 4k sectors) 0x37 0x3016 is A25L032 (uniform 4k sectors) 0x37 0x4016 is A25LQ032 (uniform 4k sectors, has quad-rate read)
Please note that the IDs of the newer chips all use AMIC_ID_NOPREFIX instead of AMIC_ID, and that means they use probe_spi_rdid instead of probe_spi_rdid4.
Signed-off-by: Dan Lenski dlenski@gmail.com
diff --git a/flashchips.c b/flashchips.c index c6d265e..29dad48 100644 --- a/flashchips.c +++ b/flashchips.c @@ -1532,6 +1532,292 @@ struct flashchip flashchips[] = {
{ .vendor = "AMIC", + .name = "A25L512", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID_NOPREFIX, + .model_id = AMIC_A25L512, + .total_size = 64, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { { 64 * 1024, 1 } }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { { 64 * 1024, 1 } }, + .block_erase = spi_block_erase_52, + }, { + .eraseblocks = { { 4 * 1024, 16 } }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { { 64 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { { 64 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = NULL, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + + { + .vendor = "AMIC", + .name = "A25L010", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID_NOPREFIX, + .model_id = AMIC_A25L010, + .total_size = 128, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { { 64 * 1024, 2 } }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { { 64 * 1024, 2 } }, + .block_erase = spi_block_erase_52, + }, { + .eraseblocks = { { 4 * 1024, 32 } }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { { 128 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { { 128 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = NULL, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + + { + .vendor = "AMIC", + .name = "A25L020", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID_NOPREFIX, + .model_id = AMIC_A25L020, + .total_size = 256, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { { 64 * 1024, 4 } }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { { 64 * 1024, 4 } }, + .block_erase = spi_block_erase_52, + }, { + .eraseblocks = { { 4 * 1024, 64 } }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { { 256 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { { 256 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = NULL, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + + { + .vendor = "AMIC", + .name = "A25L040", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID_NOPREFIX, + .model_id = AMIC_A25L040, + .total_size = 512, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { { 64 * 1024, 8 } }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { { 64 * 1024, 8 } }, + .block_erase = spi_block_erase_52, + }, { + .eraseblocks = { { 4 * 1024, 128 } }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { { 512 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { { 512 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = NULL, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + + { + .vendor = "AMIC", + .name = "A25L080", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID_NOPREFIX, + .model_id = AMIC_A25L080, + .total_size = 1024, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { { 64 * 1024, 16 } }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { { 64 * 1024, 16 } }, + .block_erase = spi_block_erase_52, + }, { + .eraseblocks = { { 4 * 1024, 256 } }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { { 1024 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { { 1024 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = NULL, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + + { + .vendor = "AMIC", + .name = "A25L016", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID_NOPREFIX, + .model_id = AMIC_A25L016, + .total_size = 2048, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { { 64 * 1024, 32 } }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { { 64 * 1024, 32 } }, + .block_erase = spi_block_erase_52, + }, { + .eraseblocks = { { 4 * 1024, 512 } }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { { 2048 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { { 2048 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = NULL, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + + { + .vendor = "AMIC", + .name = "A25L032", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID_NOPREFIX, + .model_id = AMIC_A25L032, + .total_size = 4096, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { { 64 * 1024, 64 } }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { { 64 * 1024, 64 } }, + .block_erase = spi_block_erase_52, + }, { + .eraseblocks = { { 4 * 1024, 1024 } }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { { 4096 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { { 4096 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = NULL, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + { + .vendor = "AMIC", + .name = "A25LQ032", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = AMIC_ID_NOPREFIX, + .model_id = AMIC_A25LQ032, + .total_size = 4096, + .page_size = 256, + .tested = TEST_UNTESTED, + .probe = probe_spi_rdid, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { { 64 * 1024, 64 } }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { { 64 * 1024, 64 } }, + .block_erase = spi_block_erase_52, + }, { + .eraseblocks = { { 4 * 1024, 1024 } }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { { 4096 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { { 4096 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .unlock = NULL, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + { + .vendor = "AMIC", .name = "A29002B", .bustype = CHIP_BUSTYPE_PARALLEL, .manufacture_id = AMIC_ID_NOPREFIX, diff --git a/flashchips.h b/flashchips.h index 3e2befa..0b16e3b 100644 --- a/flashchips.h +++ b/flashchips.h @@ -88,6 +88,14 @@ #define AMIC_A25L80P 0x2014 /* Seems that no A25L80PT exists */ #define AMIC_A25L16PT 0x2025 #define AMIC_A25L16PU 0x2015 +#define AMIC_A25L512 0x3010 +#define AMIC_A25L010 0x3011 +#define AMIC_A25L020 0x3012 +#define AMIC_A25L040 0x3013 +#define AMIC_A25L080 0x3014 +#define AMIC_A25L016 0x3015 +#define AMIC_A25L032 0x3016 +#define AMIC_A25LQ032 0x4016 #define AMIC_A29002B 0x0d #define AMIC_A29002T 0x8C /* Same as A290021T */ #define AMIC_A29040B 0x86
On 24.07.2010 00:26, Daniel Lenski wrote:
This patch should enable read/write/erase support for these chips, but does *not* implement unlock functionality for them yet, because they have more complex protection features than simply BPx block-protect bits.
Datasheets: http://www.amictechnology.com/pdf/A25L512.pdf http://www.amictechnology.com/pdf/A25L010.pdf http://www.amictechnology.com/pdf/A25L020.pdf http://www.amictechnology.com/pdf/A25L040.pdf http://www.amictechnology.com/pdf/A25L080.pdf http://www.amictechnology.com/pdf/A25L016.pdf http://www.amictechnology.com/pdf/A25L032.pdf http://www.amictechnology.com/pdf/A25LQ032.pdf
IDs: 0x37 0x3010 is A25L512 (uniform 4k sectors) 0x37 0x3011 is A25L010 (uniform 4k sectors) 0x37 0x3012 is A25L020 (uniform 4k sectors) 0x37 0x3013 is A25L040 (uniform 4k sectors) 0x37 0x3014 is A25L080 (uniform 4k sectors) 0x37 0x3015 is A25L016 (uniform 4k sectors) 0x37 0x3016 is A25L032 (uniform 4k sectors) 0x37 0x4016 is A25LQ032 (uniform 4k sectors, has quad-rate read)
Please note that the IDs of the newer chips all use AMIC_ID_NOPREFIX instead of AMIC_ID, and that means they use probe_spi_rdid instead of probe_spi_rdid4.
Signed-off-by: Dan Lenski dlenski@gmail.com
Thanks for your patch! Review follows.
General remark: Can you order the eraseblock definitions by eraseblock size (smallest one first)? This allows us to use a better reflashing granularity in the first write/erase attempt, and reserves bigger granularities for the case where smaller granularities fail.
diff --git a/flashchips.c b/flashchips.c index c6d265e..29dad48 100644 --- a/flashchips.c +++ b/flashchips.c @@ -1532,6 +1532,292 @@ struct flashchip flashchips[] = {
{ .vendor = "AMIC",
.name = "A25L512",
.bustype = CHIP_BUSTYPE_SPI,
.manufacture_id = AMIC_ID_NOPREFIX,
.model_id = AMIC_A25L512,
.total_size = 64,
.page_size = 256,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
.eraseblocks = { { 64 * 1024, 1 } },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { { 64 * 1024, 1 } },
.block_erase = spi_block_erase_52,
I can't find the 52h SPI opcode in the datasheet.
}, {
.eraseblocks = { { 4 * 1024, 16 } },
.block_erase = spi_block_erase_20,
}, {
.eraseblocks = { { 64 * 1024, 1} },
.block_erase = spi_block_erase_60,
I can't find the 60h SPI opcode in the datasheet.
}, {
.eraseblocks = { { 64 * 1024, 1} },
.block_erase = spi_block_erase_c7,
}
},
.unlock = NULL,
Can you add a comment so it looks like this:
.unlock = NULL, /* Two-byte status reg */
.write = spi_chip_write_256,
.read = spi_chip_read,
- },
- {
.vendor = "AMIC",
.name = "A25L010",
.bustype = CHIP_BUSTYPE_SPI,
.manufacture_id = AMIC_ID_NOPREFIX,
.model_id = AMIC_A25L010,
.total_size = 128,
.page_size = 256,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
.eraseblocks = { { 64 * 1024, 2 } },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { { 64 * 1024, 2 } },
.block_erase = spi_block_erase_52,
I can't find 52h.
}, {
.eraseblocks = { { 4 * 1024, 32 } },
.block_erase = spi_block_erase_20,
}, {
.eraseblocks = { { 128 * 1024, 1} },
.block_erase = spi_block_erase_60,
I can't find 60h.
}, {
.eraseblocks = { { 128 * 1024, 1} },
.block_erase = spi_block_erase_c7,
}
},
.unlock = NULL,
.write = spi_chip_write_256,
.read = spi_chip_read,
- },
- {
.vendor = "AMIC",
.name = "A25L020",
.bustype = CHIP_BUSTYPE_SPI,
.manufacture_id = AMIC_ID_NOPREFIX,
.model_id = AMIC_A25L020,
.total_size = 256,
.page_size = 256,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
.eraseblocks = { { 64 * 1024, 4 } },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { { 64 * 1024, 4 } },
.block_erase = spi_block_erase_52,
I can't find 52h.
}, {
.eraseblocks = { { 4 * 1024, 64 } },
.block_erase = spi_block_erase_20,
}, {
.eraseblocks = { { 256 * 1024, 1} },
.block_erase = spi_block_erase_60,
I can't find 60h.
}, {
.eraseblocks = { { 256 * 1024, 1} },
.block_erase = spi_block_erase_c7,
}
},
.unlock = NULL,
.write = spi_chip_write_256,
.read = spi_chip_read,
- },
- {
.vendor = "AMIC",
.name = "A25L040",
.bustype = CHIP_BUSTYPE_SPI,
.manufacture_id = AMIC_ID_NOPREFIX,
.model_id = AMIC_A25L040,
.total_size = 512,
.page_size = 256,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
.eraseblocks = { { 64 * 1024, 8 } },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { { 64 * 1024, 8 } },
.block_erase = spi_block_erase_52,
I can't find 52h.
}, {
.eraseblocks = { { 4 * 1024, 128 } },
.block_erase = spi_block_erase_20,
}, {
.eraseblocks = { { 512 * 1024, 1} },
.block_erase = spi_block_erase_60,
I can't find 60h.
}, {
.eraseblocks = { { 512 * 1024, 1} },
.block_erase = spi_block_erase_c7,
}
},
.unlock = NULL,
.write = spi_chip_write_256,
.read = spi_chip_read,
- },
- {
.vendor = "AMIC",
.name = "A25L080",
.bustype = CHIP_BUSTYPE_SPI,
.manufacture_id = AMIC_ID_NOPREFIX,
.model_id = AMIC_A25L080,
.total_size = 1024,
.page_size = 256,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
.eraseblocks = { { 64 * 1024, 16 } },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { { 64 * 1024, 16 } },
.block_erase = spi_block_erase_52,
I can't find 52h.
}, {
.eraseblocks = { { 4 * 1024, 256 } },
.block_erase = spi_block_erase_20,
}, {
.eraseblocks = { { 1024 * 1024, 1} },
.block_erase = spi_block_erase_60,
I can't find 60h.
}, {
.eraseblocks = { { 1024 * 1024, 1} },
.block_erase = spi_block_erase_c7,
}
},
.unlock = NULL,
.write = spi_chip_write_256,
.read = spi_chip_read,
- },
- {
.vendor = "AMIC",
.name = "A25L016",
.bustype = CHIP_BUSTYPE_SPI,
.manufacture_id = AMIC_ID_NOPREFIX,
.model_id = AMIC_A25L016,
.total_size = 2048,
.page_size = 256,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
.eraseblocks = { { 64 * 1024, 32 } },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { { 64 * 1024, 32 } },
.block_erase = spi_block_erase_52,
I can't find 52h.
}, {
.eraseblocks = { { 4 * 1024, 512 } },
.block_erase = spi_block_erase_20,
}, {
.eraseblocks = { { 2048 * 1024, 1} },
.block_erase = spi_block_erase_60,
I can't find 60h.
}, {
.eraseblocks = { { 2048 * 1024, 1} },
.block_erase = spi_block_erase_c7,
}
},
.unlock = NULL,
.write = spi_chip_write_256,
.read = spi_chip_read,
- },
- {
.vendor = "AMIC",
.name = "A25L032",
.bustype = CHIP_BUSTYPE_SPI,
.manufacture_id = AMIC_ID_NOPREFIX,
.model_id = AMIC_A25L032,
.total_size = 4096,
.page_size = 256,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
.eraseblocks = { { 64 * 1024, 64 } },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { { 64 * 1024, 64 } },
.block_erase = spi_block_erase_52,
}, {
.eraseblocks = { { 4 * 1024, 1024 } },
.block_erase = spi_block_erase_20,
}, {
.eraseblocks = { { 4096 * 1024, 1} },
.block_erase = spi_block_erase_60,
}, {
.eraseblocks = { { 4096 * 1024, 1} },
.block_erase = spi_block_erase_c7,
Can you use the order 20, 52, d8, 60, c7 here?
}
},
.unlock = NULL,
.write = spi_chip_write_256,
.read = spi_chip_read,
- },
- {
.vendor = "AMIC",
.name = "A25LQ032",
.bustype = CHIP_BUSTYPE_SPI,
.manufacture_id = AMIC_ID_NOPREFIX,
.model_id = AMIC_A25LQ032,
.total_size = 4096,
.page_size = 256,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
.eraseblocks = { { 64 * 1024, 64 } },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { { 64 * 1024, 64 } },
.block_erase = spi_block_erase_52,
}, {
.eraseblocks = { { 4 * 1024, 1024 } },
.block_erase = spi_block_erase_20,
}, {
.eraseblocks = { { 4096 * 1024, 1} },
.block_erase = spi_block_erase_60,
}, {
.eraseblocks = { { 4096 * 1024, 1} },
.block_erase = spi_block_erase_c7,
Can you use the order 20, 52, d8, 60, c7 here?
}
},
.unlock = NULL,
.write = spi_chip_write_256,
.read = spi_chip_read,
- },
- {
.name = "A29002B", .bustype = CHIP_BUSTYPE_PARALLEL, .manufacture_id = AMIC_ID_NOPREFIX,.vendor = "AMIC",
diff --git a/flashchips.h b/flashchips.h index 3e2befa..0b16e3b 100644 --- a/flashchips.h +++ b/flashchips.h @@ -88,6 +88,14 @@ #define AMIC_A25L80P 0x2014 /* Seems that no A25L80PT exists */ #define AMIC_A25L16PT 0x2025 #define AMIC_A25L16PU 0x2015 +#define AMIC_A25L512 0x3010 +#define AMIC_A25L010 0x3011 +#define AMIC_A25L020 0x3012 +#define AMIC_A25L040 0x3013 +#define AMIC_A25L080 0x3014 +#define AMIC_A25L016 0x3015 +#define AMIC_A25L032 0x3016 +#define AMIC_A25LQ032 0x4016 #define AMIC_A29002B 0x0d #define AMIC_A29002T 0x8C /* Same as A290021T */ #define AMIC_A29040B 0x86
Looks good otherwise.
Regards, Carl-Daniel
On Sat, 2010-07-24 at 10:16 +0200, Carl-Daniel Hailfinger wrote:
General remark: Can you order the eraseblock definitions by eraseblock size (smallest one first)? This allows us to use a better reflashing granularity in the first write/erase attempt, and reserves bigger granularities for the case where smaller granularities fail.
Got it, done.
I can't find the 52h SPI opcode in the datasheet. I can't find the 60h SPI opcode in the datasheet. (etc.)
Changed these. I found other versions of the datasheets that suggested these were valid and had been inadvertently omitted... but I think I'm probably erring on the wrong side of caution by doing that.
Can you add a comment so it looks like this:
.unlock = NULL, /* Two-byte status reg */
Done. I made a careless mistake, which is that only the 032 and Q032 chips have the two-byte status reg and more complex protection features. The smaller-capacity ones can still use the standard spi_disable_blockprotect unlock function. I have corrected this in the patch.
One other feature of the A25L032 and A25LQ032 chips which Flashrom may want to be aware of: they have 64 bytes of one-time-programmable memory on them. Is reading/writing this outside the scope of Flashrom? I assume they'd be used for serial numbers or crypto keys... and it might be misleading to assume Flashrom was completely backing up/restoring a BIOS image if it can't read and write this OTP region.
Revised patch is attached, with revised description.
Dan
On 24.07.2010 23:22, Daniel Lenski wrote:
On Sat, 2010-07-24 at 10:16 +0200, Carl-Daniel Hailfinger wrote:
General remark: Can you order the eraseblock definitions by eraseblock size (smallest one first)? This allows us to use a better reflashing granularity in the first write/erase attempt, and reserves bigger granularities for the case where smaller granularities fail.
Got it, done.
I can't find the 52h SPI opcode in the datasheet. I can't find the 60h SPI opcode in the datasheet. (etc.)
Changed these. I found other versions of the datasheets that suggested these were valid and had been inadvertently omitted... but I think I'm probably erring on the wrong side of caution by doing that.
flashrom can deal fine with failing erase, so if you can dig up those datasheets again, please send a followup patch which adds those SPI erase opcodes again. I had assumed you were extrapolating, but having solid data is an entirely different thing. And yes, datasheets often contradict each other.
Can you add a comment so it looks like this:
.unlock = NULL, /* Two-byte status reg */
Done. I made a careless mistake, which is that only the 032 and Q032 chips have the two-byte status reg and more complex protection features. The smaller-capacity ones can still use the standard spi_disable_blockprotect unlock function. I have corrected this in the patch.
OK. I have added support for some Atmel chips which need a more complicated unlocking, and maybe that can serve as a template for you. In the interest of full disclosure I should say that the structure of my unlock functions for AT25* is suboptimal, and probably would benefit from some generalization and/or refactoring.
One other feature of the A25L032 and A25LQ032 chips which Flashrom may want to be aware of: they have 64 bytes of one-time-programmable memory on them. Is reading/writing this outside the scope of Flashrom? I assume they'd be used for serial numbers or crypto keys... and it might be misleading to assume Flashrom was completely backing up/restoring a BIOS image if it can't read and write this OTP region.
Good point. Given that those are accessible with special commands only, and are not "normal" flash contents per se, I feel it is OK to ignore them for now. Future flashrom versions will have an interface which allows running arbitrary commands, and that interface could be used for OTP and security regions.
Revised patch is attached, with revised description.
Acked-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Thanks for your patch, committed in r1118.
Regards, Carl-Daniel
On Thu, 2010-07-29 at 17:05 +0200, Carl-Daniel Hailfinger wrote:
I can't find the 52h SPI opcode in the datasheet. I can't find the 60h SPI opcode in the datasheet. (etc.)
Changed these. I found other versions of the datasheets that suggested these were valid and had been inadvertently omitted... but I think I'm probably erring on the wrong side of caution by doing that.
flashrom can deal fine with failing erase, so if you can dig up those datasheets again, please send a followup patch which adds those SPI erase opcodes again. I had assumed you were extrapolating, but having solid data is an entirely different thing. And yes, datasheets often contradict each other.
I had found an early (version number <1.0) version of the A25L020/A25L010/A25L512 datasheet that listed these, but I'm unfortunately not finding it now. It doesn't appear in any of the versions >=1.0, so it's probably wrong.
OK. I have added support for some Atmel chips which need a more complicated unlocking, and maybe that can serve as a template for you. In the interest of full disclosure I should say that the structure of my unlock functions for AT25* is suboptimal, and probably would benefit from some generalization and/or refactoring.
I took a look at the at25f* unlock functions. If I understand correctly, they involve various manipulations of the standard 1-byte status register.
The A25L032/Q032 will require new functions to read and write the 2-byte status register. The good thing is that the standard commands can be used except when manipulating the second byte, AFAICT. Would you prefer one big ugly function to do the whole thing, or factor things out into separate functions to read/write the 2-byte SR?
One other feature of the A25L032 and A25LQ032 chips which Flashrom may want to be aware of: they have 64 bytes of one-time-programmable memory on them. Is reading/writing this outside the scope of Flashrom? I assume they'd be used for serial numbers or crypto keys... and it might be misleading to assume Flashrom was completely backing up/restoring a BIOS image if it can't read and write this OTP region.
Good point. Given that those are accessible with special commands only, and are not "normal" flash contents per se, I feel it is OK to ignore them for now. Future flashrom versions will have an interface which allows running arbitrary commands, and that interface could be used for OTP and security regions.
Perhaps a FEATURE_UNHANDLED_OTP bit (or something more concise to that effect) could be designed, which would just give a warning prior to read/write/erase? Something like the FEATURE_EVIL_TWIN bit that you proposed to warn about pairs like the A25L40P{T,U}.
I've coded up a small patch for that, to follow.
Dan