mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-27 23:22:37 +02:00
Fix timing of SPI status register writes (WRSR)
SPI write status register (WRSR) may take longer than 100 ms, and it makes sense to poll for completion in 10 ms steps until 5 s are over. This patch complements r1115. Corresponding to flashrom svn r1201. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Joshua Roys <roysjosh@gmail.com>
This commit is contained in:
parent
ef69783a83
commit
174f55bdec
3
flash.h
3
flash.h
@ -35,6 +35,9 @@
|
|||||||
|
|
||||||
#define ERROR_PTR ((void*)-1)
|
#define ERROR_PTR ((void*)-1)
|
||||||
|
|
||||||
|
/* Error codes */
|
||||||
|
#define TIMEOUT_ERROR -101
|
||||||
|
|
||||||
typedef unsigned long chipaddr;
|
typedef unsigned long chipaddr;
|
||||||
|
|
||||||
int register_shutdown(void (*function) (void *data), void *data);
|
int register_shutdown(void (*function) (void *data), void *data);
|
||||||
|
40
spi25.c
40
spi25.c
@ -856,6 +856,7 @@ int spi_write_status_enable(void)
|
|||||||
static int spi_write_status_register_ewsr(struct flashchip *flash, int status)
|
static int spi_write_status_register_ewsr(struct flashchip *flash, int status)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
int i = 0;
|
||||||
struct spi_command cmds[] = {
|
struct spi_command cmds[] = {
|
||||||
{
|
{
|
||||||
/* WRSR requires either EWSR or WREN depending on chip type. */
|
/* WRSR requires either EWSR or WREN depending on chip type. */
|
||||||
@ -879,15 +880,31 @@ static int spi_write_status_register_ewsr(struct flashchip *flash, int status)
|
|||||||
if (result) {
|
if (result) {
|
||||||
msg_cerr("%s failed during command execution\n",
|
msg_cerr("%s failed during command execution\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
/* No point in waiting for the command to complete if execution
|
||||||
|
* failed.
|
||||||
|
*/
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
/* WRSR performs a self-timed erase before the changes take effect. */
|
/* WRSR performs a self-timed erase before the changes take effect.
|
||||||
|
* This may take 50-85 ms in most cases, and some chips apparently
|
||||||
|
* allow running RDSR only once. Therefore pick an initial delay of
|
||||||
|
* 100 ms, then wait in 10 ms steps until a total of 5 s have elapsed.
|
||||||
|
*/
|
||||||
programmer_delay(100 * 1000);
|
programmer_delay(100 * 1000);
|
||||||
return result;
|
while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) {
|
||||||
|
if (++i > 490) {
|
||||||
|
msg_cerr("Error: WIP bit after WRSR never cleared\n");
|
||||||
|
return TIMEOUT_ERROR;
|
||||||
|
}
|
||||||
|
programmer_delay(10 * 1000);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spi_write_status_register_wren(struct flashchip *flash, int status)
|
static int spi_write_status_register_wren(struct flashchip *flash, int status)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
int i = 0;
|
||||||
struct spi_command cmds[] = {
|
struct spi_command cmds[] = {
|
||||||
{
|
{
|
||||||
/* WRSR requires either EWSR or WREN depending on chip type. */
|
/* WRSR requires either EWSR or WREN depending on chip type. */
|
||||||
@ -911,10 +928,25 @@ static int spi_write_status_register_wren(struct flashchip *flash, int status)
|
|||||||
if (result) {
|
if (result) {
|
||||||
msg_cerr("%s failed during command execution\n",
|
msg_cerr("%s failed during command execution\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
/* No point in waiting for the command to complete if execution
|
||||||
|
* failed.
|
||||||
|
*/
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
/* WRSR performs a self-timed erase before the changes take effect. */
|
/* WRSR performs a self-timed erase before the changes take effect.
|
||||||
|
* This may take 50-85 ms in most cases, and some chips apparently
|
||||||
|
* allow running RDSR only once. Therefore pick an initial delay of
|
||||||
|
* 100 ms, then wait in 10 ms steps until a total of 5 s have elapsed.
|
||||||
|
*/
|
||||||
programmer_delay(100 * 1000);
|
programmer_delay(100 * 1000);
|
||||||
return result;
|
while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) {
|
||||||
|
if (++i > 490) {
|
||||||
|
msg_cerr("Error: WIP bit after WRSR never cleared\n");
|
||||||
|
return TIMEOUT_ERROR;
|
||||||
|
}
|
||||||
|
programmer_delay(10 * 1000);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spi_write_status_register(struct flashchip *flash, int status)
|
static int spi_write_status_register(struct flashchip *flash, int status)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user