summaryrefslogtreecommitdiffstats
path: root/spi25.c
diff options
context:
space:
mode:
authorNico Huber <nico.h@gmx.de>2017-10-15 11:20:58 +0200
committerNico Huber <nico.h@gmx.de>2017-12-28 10:41:38 +0000
commita3140d0b18058610a2694fc3592031a849b0c92a (patch)
tree194083a9889bb76a70cb447a14660d6ec449506c /spi25.c
parentc8801734727e1e510cbd99e305007b73f9f57e93 (diff)
downloadflashrom-a3140d0b18058610a2694fc3592031a849b0c92a.tar.gz
flashrom-a3140d0b18058610a2694fc3592031a849b0c92a.tar.bz2
flashrom-a3140d0b18058610a2694fc3592031a849b0c92a.zip
spi25: Introduce spi_simple_write_cmd()
spi_simple_write_cmd() executes WREN plus a single byte write and polls WIP afterwards. It's used to replace current spi_erase_chip_*() imple- mentations. Change-Id: Ib244356fa471e15863b52e6037899d19113cb4a9 Signed-off-by: Nico Huber <nico.h@gmx.de> Reviewed-on: https://review.coreboot.org/22382 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: David Hendricks <david.hendricks@gmail.com>
Diffstat (limited to 'spi25.c')
-rw-r--r--spi25.c133
1 files changed, 38 insertions, 95 deletions
diff --git a/spi25.c b/spi25.c
index 30b862f17..da04d2e94 100644
--- a/spi25.c
+++ b/spi25.c
@@ -22,6 +22,7 @@
* Contains the common SPI chip driver functions
*/
+#include <stddef.h>
#include <string.h>
#include "flash.h"
#include "flashchips.h"
@@ -322,114 +323,56 @@ int probe_spi_at25f(struct flashctx *flash)
return 0;
}
-int spi_chip_erase_60(struct flashctx *flash)
+/**
+ * Execute WREN plus another one byte `op`, optionally poll WIP afterwards.
+ *
+ * @param flash the flash chip's context
+ * @param op the operation to execute
+ * @param poll_delay interval in us for polling WIP, don't poll if zero
+ * @return 0 on success, non-zero otherwise
+ */
+static int spi_simple_write_cmd(struct flashctx *const flash, const uint8_t op, const unsigned int poll_delay)
{
- int result;
struct spi_command cmds[] = {
{
- .writecnt = JEDEC_WREN_OUTSIZE,
- .writearr = (const unsigned char[]){ JEDEC_WREN },
- .readcnt = 0,
- .readarr = NULL,
- }, {
- .writecnt = JEDEC_CE_60_OUTSIZE,
- .writearr = (const unsigned char[]){ JEDEC_CE_60 },
- .readcnt = 0,
- .readarr = NULL,
+ .writecnt = 1,
+ .writearr = (const unsigned char[]){ JEDEC_WREN },
}, {
- .writecnt = 0,
- .writearr = NULL,
- .readcnt = 0,
- .readarr = NULL,
- }};
-
- result = spi_send_multicommand(flash, cmds);
- if (result) {
- msg_cerr("%s failed during command execution\n",
- __func__);
- return result;
- }
- /* Wait until the Write-In-Progress bit is cleared.
- * This usually takes 1-85 s, so wait in 1 s steps.
- */
- /* FIXME: We assume spi_read_status_register will never fail. */
- while (spi_read_status_register(flash) & SPI_SR_WIP)
- programmer_delay(1000 * 1000);
+ .writecnt = 1,
+ .writearr = (const unsigned char[]){ op },
+ },
+ NULL_SPI_CMD,
+ };
+
+ const int result = spi_send_multicommand(flash, cmds);
+ if (result)
+ msg_cerr("%s failed during command execution\n", __func__);
+
+ /* FIXME: We can't tell if spi_read_status_register() failed. */
+ /* FIXME: We don't time out. */
+ while (poll_delay && spi_read_status_register(flash) & SPI_SR_WIP)
+ programmer_delay(poll_delay);
/* FIXME: Check the status register for errors. */
- return 0;
+
+ return result;
+}
+
+int spi_chip_erase_60(struct flashctx *flash)
+{
+ /* This usually takes 1-85s, so wait in 1s steps. */
+ return spi_simple_write_cmd(flash, 0x60, 1000 * 1000);
}
int spi_chip_erase_62(struct flashctx *flash)
{
- int result;
- struct spi_command cmds[] = {
- {
- .writecnt = JEDEC_WREN_OUTSIZE,
- .writearr = (const unsigned char[]){ JEDEC_WREN },
- .readcnt = 0,
- .readarr = NULL,
- }, {
- .writecnt = JEDEC_CE_62_OUTSIZE,
- .writearr = (const unsigned char[]){ JEDEC_CE_62 },
- .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\n",
- __func__);
- return result;
- }
- /* Wait until the Write-In-Progress bit is cleared.
- * This usually takes 2-5 s, so wait in 100 ms steps.
- */
- /* FIXME: We assume spi_read_status_register will never fail. */
- while (spi_read_status_register(flash) & SPI_SR_WIP)
- programmer_delay(100 * 1000);
- /* FIXME: Check the status register for errors. */
- return 0;
+ /* This usually takes 2-5s, so wait in 100ms steps. */
+ return spi_simple_write_cmd(flash, 0x62, 100 * 1000);
}
int spi_chip_erase_c7(struct flashctx *flash)
{
- int result;
- struct spi_command cmds[] = {
- {
- .writecnt = JEDEC_WREN_OUTSIZE,
- .writearr = (const unsigned char[]){ JEDEC_WREN },
- .readcnt = 0,
- .readarr = NULL,
- }, {
- .writecnt = JEDEC_CE_C7_OUTSIZE,
- .writearr = (const unsigned char[]){ JEDEC_CE_C7 },
- .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\n", __func__);
- return result;
- }
- /* Wait until the Write-In-Progress bit is cleared.
- * This usually takes 1-85 s, so wait in 1 s steps.
- */
- /* FIXME: We assume spi_read_status_register will never fail. */
- while (spi_read_status_register(flash) & SPI_SR_WIP)
- programmer_delay(1000 * 1000);
- /* FIXME: Check the status register for errors. */
- return 0;
+ /* This usually takes 1-85s, so wait in 1s steps. */
+ return spi_simple_write_cmd(flash, 0xc7, 1000 * 1000);
}
int spi_block_erase_52(struct flashctx *flash, unsigned int addr,