summaryrefslogtreecommitdiffstats
path: root/spi25.c
diff options
context:
space:
mode:
authorCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>2010-05-21 23:09:42 +0000
committerCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>2010-05-21 23:09:42 +0000
commit5824fbff010076cc0d2a4387c1b2f54644ae5785 (patch)
tree73c903182e7400386453acfbd7c738b3361849ff /spi25.c
parentd175e06ac305274d8e1a8a4658f7f5518c89b801 (diff)
downloadast2050-flashrom-5824fbff010076cc0d2a4387c1b2f54644ae5785.zip
ast2050-flashrom-5824fbff010076cc0d2a4387c1b2f54644ae5785.tar.gz
Introduce a generic SPI read function: spi_write_chunked()
Every SPI programmer driver had its own completely different chip write implementation, and all of them were insufficiently commented. Create spi_write_chunked as a copy of spi_read_chunked and convert all SPI programmers to use it. No functional changes except: - Bus Pirate uses 12 Byte writes instead of 8 Byte writes - SB600 uses 5 Byte writes instead of 1 Byte writes Corresponding to flashrom svn r1005. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Michael Karcher <flashrom@mkarcher.dialup.fu-berlin.de> Acked-by: David Hendricks <dhendrix@google.com>
Diffstat (limited to 'spi25.c')
-rw-r--r--spi25.c50
1 files changed, 48 insertions, 2 deletions
diff --git a/spi25.c b/spi25.c
index c6d1b65..5a52f28 100644
--- a/spi25.c
+++ b/spi25.c
@@ -1,7 +1,7 @@
/*
* This file is part of the flashrom project.
*
- * Copyright (C) 2007, 2008, 2009 Carl-Daniel Hailfinger
+ * Copyright (C) 2007, 2008, 2009, 2010 Carl-Daniel Hailfinger
* Copyright (C) 2008 coresystems GmbH
*
* This program is free software; you can redistribute it and/or modify
@@ -874,7 +874,7 @@ int spi_nbyte_read(int address, uint8_t *bytes, int len)
}
/*
- * Read a complete flash chip.
+ * Read a part of the flash chip.
* Each page is read separately in chunks with a maximum size of chunksize.
*/
int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize)
@@ -913,6 +913,52 @@ int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len,
}
/*
+ * Write a part of the flash chip.
+ * Each page is written separately in chunks with a maximum size of chunksize.
+ */
+int spi_write_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize)
+{
+ int rc = 0;
+ int i, j, starthere, lenhere;
+ /* FIXME: page_size is the wrong variable. We need max_writechunk_size
+ * in struct flashchip to do this properly. All chips using
+ * spi_chip_write_256 have page_size set to max_writechunk_size, so
+ * we're OK for now.
+ */
+ int page_size = flash->page_size;
+ int towrite;
+
+ /* Warning: This loop has a very unusual condition and body.
+ * The loop needs to go through each page with at least one affected
+ * byte. The lowest page number is (start / page_size) since that
+ * division rounds down. The highest page number we want is the page
+ * where the last byte of the range lives. That last byte has the
+ * address (start + len - 1), thus the highest page number is
+ * (start + len - 1) / page_size. Since we want to include that last
+ * page as well, the loop condition uses <=.
+ */
+ for (i = start / page_size; i <= (start + len - 1) / page_size; i++) {
+ /* Byte position of the first byte in the range in this page. */
+ /* starthere is an offset to the base address of the chip. */
+ starthere = max(start, i * page_size);
+ /* Length of bytes in the range in this page. */
+ lenhere = min(start + len, (i + 1) * page_size) - starthere;
+ for (j = 0; j < lenhere; j += chunksize) {
+ towrite = min(chunksize, lenhere - j);
+ rc = spi_nbyte_program(starthere + j, buf + starthere - start + j, towrite);
+ if (rc)
+ break;
+ while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+ programmer_delay(10);
+ }
+ if (rc)
+ break;
+ }
+
+ return rc;
+}
+
+/*
* Program chip using byte programming. (SLOW!)
* This is for chips which can only handle one byte writes
* and for chips where memory mapped programming is impossible
OpenPOWER on IntegriCloud