mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-27 15:12:36 +02:00
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>
This commit is contained in:
parent
c880173472
commit
a3140d0b18
1
flash.h
1
flash.h
@ -369,6 +369,7 @@ struct spi_command {
|
||||
const unsigned char *writearr;
|
||||
unsigned char *readarr;
|
||||
};
|
||||
#define NULL_SPI_CMD { 0, 0, NULL, NULL, }
|
||||
int spi_send_command(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
|
||||
int spi_send_multicommand(struct flashctx *flash, struct spi_command *cmds);
|
||||
uint32_t spi_get_valid_read_addr(struct flashctx *flash);
|
||||
|
129
spi25.c
129
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,
|
||||
.writecnt = 1,
|
||||
.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 = 0,
|
||||
.writearr = NULL,
|
||||
.readcnt = 0,
|
||||
.readarr = NULL,
|
||||
}};
|
||||
.writecnt = 1,
|
||||
.writearr = (const unsigned char[]){ op },
|
||||
},
|
||||
NULL_SPI_CMD,
|
||||
};
|
||||
|
||||
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);
|
||||
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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user