mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-26 22:52:34 +02:00
Add support for Atmel AT26DF041
Wicked chip: No WRSR, no write enable command (but swallows our default one without a problem), supports an auto-erasing page write (but even without that page writes are recommended to write the whole page i.e. operate on a completely erased page), mad requirements on block refreshments if only partly written. Found on my Intel D946GZIS and tested with my serprog in situ. Using the page write by setting JEDEC_BYTE_PROGRAM to 0x11 and using the spi_chip_write_256 command greatly improves performance and works flawlessly. Corresponding to flashrom svn r1616. Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at> Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
This commit is contained in:
parent
d956f82249
commit
94b39b47e4
@ -41,7 +41,9 @@ int probe_spi_res2(struct flashctx *flash);
|
|||||||
int spi_write_enable(struct flashctx *flash);
|
int spi_write_enable(struct flashctx *flash);
|
||||||
int spi_write_disable(struct flashctx *flash);
|
int spi_write_disable(struct flashctx *flash);
|
||||||
int spi_block_erase_20(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
|
int spi_block_erase_20(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
|
||||||
|
int spi_block_erase_50(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
|
||||||
int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
|
int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
|
||||||
|
int spi_block_erase_81(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
|
||||||
int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
|
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_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_60(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
|
||||||
|
14
flashchips.c
14
flashchips.c
@ -1795,18 +1795,24 @@ const struct flashchip flashchips[] = {
|
|||||||
.total_size = 512,
|
.total_size = 512,
|
||||||
.page_size = 256,
|
.page_size = 256,
|
||||||
/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
|
/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
|
||||||
.tested = TEST_UNTESTED,
|
.tested = TEST_OK_PREW,
|
||||||
.probe = probe_spi_rdid,
|
.probe = probe_spi_rdid,
|
||||||
.probe_timing = TIMING_ZERO,
|
.probe_timing = TIMING_ZERO,
|
||||||
.block_erasers =
|
.block_erasers =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
.eraseblocks = { {256, 2048} },
|
||||||
|
.block_erase = spi_block_erase_81,
|
||||||
|
}, {
|
||||||
|
.eraseblocks = { {2 * 1024, 256} },
|
||||||
|
.block_erase = spi_block_erase_50,
|
||||||
|
}, {
|
||||||
.eraseblocks = { {4 * 1024, 128} },
|
.eraseblocks = { {4 * 1024, 128} },
|
||||||
.block_erase = spi_block_erase_20,
|
.block_erase = spi_block_erase_20,
|
||||||
}
|
}
|
||||||
},
|
}, /* Supports also an incompatible page write (of exactly 256 B) and an auto-erasing write. */
|
||||||
.write = NULL /* Incompatible Page write */,
|
.write = spi_chip_write_1,
|
||||||
.read = spi_chip_read,
|
.read = spi_chip_read, /* Fast read (0x0B) supported */
|
||||||
.voltage = {2700, 3600}, /* 3.0-3.6V for higher speed, 2.7-3.6V normal */
|
.voltage = {2700, 3600}, /* 3.0-3.6V for higher speed, 2.7-3.6V normal */
|
||||||
},
|
},
|
||||||
|
|
||||||
|
10
spi.h
10
spi.h
@ -76,11 +76,21 @@
|
|||||||
#define JEDEC_CE_C7_OUTSIZE 0x01
|
#define JEDEC_CE_C7_OUTSIZE 0x01
|
||||||
#define JEDEC_CE_C7_INSIZE 0x00
|
#define JEDEC_CE_C7_INSIZE 0x00
|
||||||
|
|
||||||
|
/* Block Erase 0x50 is supported by Atmel AT26DF chips. */
|
||||||
|
#define JEDEC_BE_50 0x50
|
||||||
|
#define JEDEC_BE_50_OUTSIZE 0x04
|
||||||
|
#define JEDEC_BE_50_INSIZE 0x00
|
||||||
|
|
||||||
/* Block Erase 0x52 is supported by SST and old Atmel chips. */
|
/* Block Erase 0x52 is supported by SST and old Atmel chips. */
|
||||||
#define JEDEC_BE_52 0x52
|
#define JEDEC_BE_52 0x52
|
||||||
#define JEDEC_BE_52_OUTSIZE 0x04
|
#define JEDEC_BE_52_OUTSIZE 0x04
|
||||||
#define JEDEC_BE_52_INSIZE 0x00
|
#define JEDEC_BE_52_INSIZE 0x00
|
||||||
|
|
||||||
|
/* Block Erase 0x81 is supported by Atmel AT26DF chips. */
|
||||||
|
#define JEDEC_BE_81 0x81
|
||||||
|
#define JEDEC_BE_81_OUTSIZE 0x04
|
||||||
|
#define JEDEC_BE_81_INSIZE 0x00
|
||||||
|
|
||||||
/* Block Erase 0xd8 is supported by EON/Macronix chips. */
|
/* Block Erase 0xd8 is supported by EON/Macronix chips. */
|
||||||
#define JEDEC_BE_D8 0xd8
|
#define JEDEC_BE_D8 0xd8
|
||||||
#define JEDEC_BE_D8_OUTSIZE 0x04
|
#define JEDEC_BE_D8_OUTSIZE 0x04
|
||||||
|
80
spi25.c
80
spi25.c
@ -741,6 +741,86 @@ int spi_block_erase_20(struct flashctx *flash, unsigned int addr,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int spi_block_erase_50(struct flashctx *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_50_OUTSIZE,
|
||||||
|
.writearr = (const unsigned char[]){
|
||||||
|
JEDEC_BE_50,
|
||||||
|
(addr >> 16) & 0xff,
|
||||||
|
(addr >> 8) & 0xff,
|
||||||
|
(addr & 0xff)
|
||||||
|
},
|
||||||
|
.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 at address 0x%x\n", __func__, addr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/* Wait until the Write-In-Progress bit is cleared.
|
||||||
|
* This usually takes 10 ms, so wait in 1 ms steps.
|
||||||
|
*/
|
||||||
|
while (spi_read_status_register(flash) & SPI_SR_WIP)
|
||||||
|
programmer_delay(1 * 1000);
|
||||||
|
/* FIXME: Check the status register for errors. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spi_block_erase_81(struct flashctx *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_81_OUTSIZE,
|
||||||
|
.writearr = (const unsigned char[]){
|
||||||
|
JEDEC_BE_81,
|
||||||
|
(addr >> 16) & 0xff,
|
||||||
|
(addr >> 8) & 0xff,
|
||||||
|
(addr & 0xff)
|
||||||
|
},
|
||||||
|
.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 at address 0x%x\n", __func__, addr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/* Wait until the Write-In-Progress bit is cleared.
|
||||||
|
* This usually takes 8 ms, so wait in 1 ms steps.
|
||||||
|
*/
|
||||||
|
while (spi_read_status_register(flash) & SPI_SR_WIP)
|
||||||
|
programmer_delay(1 * 1000);
|
||||||
|
/* FIXME: Check the status register for errors. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int spi_block_erase_60(struct flashctx *flash, unsigned int addr,
|
int spi_block_erase_60(struct flashctx *flash, unsigned int addr,
|
||||||
unsigned int blocklen)
|
unsigned int blocklen)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user