I know of no supported SPI chip which would require delays for any operation. The delays in our SPI code are only there to reduce load on the SPI bus. As such, they might be a good idea for shared flash, but I'm not too convinced of that either. For all external programmers, delays between commands are 100% pointless unless required by the flash chip (and I don't know of any such requirements).
Michael, I'd like to hear your thoughts on the impact of reading the status register in a tight loop instead of sleeping in between for systems which use flash translation (e.g. by EC).
There are two options how we can handle this: - Remove the delays completely. - Mark the delays as optional, e.g. programmer_odelay() and let it default to a nop.
This patch removes the delays.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-spi_nodelay/spi25.c =================================================================== --- flashrom-spi_nodelay/spi25.c (Revision 1048) +++ flashrom-spi_nodelay/spi25.c (Arbeitskopie) @@ -455,11 +455,11 @@ return result; } /* Wait until the Write-In-Progress bit is cleared. - * This usually takes 1-85 s, so wait in 1 s steps. + * This usually takes 1-85 s. */ /* FIXME: We assume spi_read_status_register will never fail. */ while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) - programmer_delay(1000 * 1000); + /* do nothing */; if (check_erased_range(flash, 0, flash->total_size * 1024)) { msg_cerr("ERASE FAILED!\n"); return -1; @@ -500,11 +500,11 @@ return result; } /* Wait until the Write-In-Progress bit is cleared. - * This usually takes 1-85 s, so wait in 1 s steps. + * This usually takes 1-85 s. */ /* FIXME: We assume spi_read_status_register will never fail. */ while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) - programmer_delay(1000 * 1000); + /* do nothing */; if (check_erased_range(flash, 0, flash->total_size * 1024)) { msg_cerr("ERASE FAILED!\n"); return -1; @@ -545,10 +545,10 @@ return result; } /* Wait until the Write-In-Progress bit is cleared. - * This usually takes 100-4000 ms, so wait in 100 ms steps. + * This usually takes 100-4000 ms. */ while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) - programmer_delay(100 * 1000); + /* do nothing */; if (check_erased_range(flash, addr, blocklen)) { msg_cerr("ERASE FAILED!\n"); return -1; @@ -594,10 +594,10 @@ return result; } /* Wait until the Write-In-Progress bit is cleared. - * This usually takes 100-4000 ms, so wait in 100 ms steps. + * This usually takes 100-4000 ms. */ while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) - programmer_delay(100 * 1000); + /* do nothing */; if (check_erased_range(flash, addr, blocklen)) { msg_cerr("ERASE FAILED!\n"); return -1; @@ -641,10 +641,10 @@ return result; } /* Wait until the Write-In-Progress bit is cleared. - * This usually takes 100-4000 ms, so wait in 100 ms steps. + * This usually takes 100-4000 ms. */ while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) - programmer_delay(100 * 1000); + /* do nothing */; if (check_erased_range(flash, addr, blocklen)) { msg_cerr("ERASE FAILED!\n"); return -1; @@ -709,10 +709,10 @@ return result; } /* Wait until the Write-In-Progress bit is cleared. - * This usually takes 15-800 ms, so wait in 10 ms steps. + * This usually takes 15-800 ms. */ while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) - programmer_delay(10 * 1000); + /* do nothing */; if (check_erased_range(flash, addr, blocklen)) { msg_cerr("ERASE FAILED!\n"); return -1; @@ -977,7 +977,7 @@ if (rc) break; while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) - programmer_delay(10); + /* do nothing */; } if (rc) break; @@ -1010,7 +1010,7 @@ if (result) return 1; while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) - programmer_delay(10); + /* do nothing */; }
return 0; @@ -1044,13 +1044,13 @@ return result; spi_send_command(6, 0, w, NULL); while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) - programmer_delay(5); /* SST25VF040B Tbp is max 10us */ + /* do nothing */; while (pos < size) { w[1] = buf[pos++]; w[2] = buf[pos++]; spi_send_command(3, 0, w, NULL); while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) - programmer_delay(5); /* SST25VF040B Tbp is max 10us */ + /* do nothing */; } spi_write_disable(); return 0; Index: flashrom-spi_nodelay/it87spi.c =================================================================== --- flashrom-spi_nodelay/it87spi.c (Revision 1048) +++ flashrom-spi_nodelay/it87spi.c (Arbeitskopie) @@ -304,7 +304,7 @@ * This usually takes 1-10 ms, so wait in 1 ms steps. */ while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) - programmer_delay(1000); + /* do nothing */; return 0; }
Index: flashrom-spi_nodelay/wbsio_spi.c =================================================================== --- flashrom-spi_nodelay/wbsio_spi.c (Revision 1048) +++ flashrom-spi_nodelay/wbsio_spi.c (Arbeitskopie) @@ -163,7 +163,6 @@
OUTB(writearr[0], wbsio_spibase); OUTB(mode, wbsio_spibase + 1); - programmer_delay(10);
if (!readcnt) return 0;