summaryrefslogtreecommitdiffstats
path: root/spi25.c
diff options
context:
space:
mode:
authorStefan Tauner <stefan.tauner@alumni.tuwien.ac.at>2012-10-27 00:06:02 +0000
committerStefan Tauner <stefan.tauner@alumni.tuwien.ac.at>2012-10-27 00:06:02 +0000
commit94b39b47e475d3d8f153acea4a3fdcd6bbc81ea7 (patch)
tree42a78390b7e92346efe9c97c93e458eb91a75d86 /spi25.c
parentd956f822490e10be505355a59fc2498800d33c1d (diff)
downloadast2050-flashrom-94b39b47e475d3d8f153acea4a3fdcd6bbc81ea7.zip
ast2050-flashrom-94b39b47e475d3d8f153acea4a3fdcd6bbc81ea7.tar.gz
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>
Diffstat (limited to 'spi25.c')
-rw-r--r--spi25.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/spi25.c b/spi25.c
index a65f548..10c5a4a 100644
--- a/spi25.c
+++ b/spi25.c
@@ -741,6 +741,86 @@ int spi_block_erase_20(struct flashctx *flash, unsigned int addr,
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,
unsigned int blocklen)
{
OpenPOWER on IntegriCloud