Subrata Banik has uploaded this change for review.
flashrom: Check SPI Cycle In-Progress prior start HW Seq
As per EDS, SPI controller sets the HSFSTS.bit5 (SCIP) when software
sets the Flash Cycle Go (FGO) bit in the Hardware Sequencing Flash
Control register.
This bit remains set until the cycle completes on the SPI interface.
Hardware automatically sets and clears this bit so that software can
determine when read data is valid and/or when it is safe to begin
programming the next command.
Software must initiate the next SPI transaction when this bit is 0.
Added blocking mechanism without timeout to ensure previous SPI
transaction is complete before initiating newer command.
BUG=b:215255210
Signed-off-by: Subrata Banik <subratabanik@google.com>
Change-Id: Ib9265cc20513fd00f32f8fa22e28c312903ca484
---
M ichspi.c
1 file changed, 38 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/54/61854/1
diff --git a/ichspi.c b/ichspi.c
index 117ff8d..ac4e3eb 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -1366,6 +1366,35 @@
return 1;
}
+/*
+ * As per EDS, SPI controller sets the HSFSTS.bit5 (SCIP) when software
+ * sets the Flash Cycle Go (FGO) bit in the Hardware Sequencing Flash
+ * Control register.
+ *
+ * This bit remains set until the cycle completes on the SPI interface.
+ * Hardware automatically sets and clears this bit so that software can
+ * determine when read data is valid and/or when it is safe to begin
+ * programming the next command.
+ *
+ * Software must initiate the next SPI transaction when this bit is 0.
+ *
+ * Added blocking mechanism without timeout to ensure previous SPI transaction
+ * is complete before initiating newer command.
+ */
+static void ich_wait_for_hwseq_spi_cycle_complete(void)
+{
+ uint32_t hsfsts;
+
+ msg_pspew("SPI Transaction in progress ");
+ do {
+ hsfsts = REGREAD32(ICH9_REG_HSFS);
+ msg_pspew("..");
+ } while ((hsfsts & HSFS_SCIP) == HSFS_SCIP);
+
+ msg_pspew("\nSPI Transaction done!\n");
+ return;
+}
+
static int ich_hwseq_block_erase(struct flashctx *flash, unsigned int addr,
unsigned int len)
{
@@ -1396,6 +1425,9 @@
return -1;
}
+ /* Wait for previous SPI cycle to complete */
+ ich_wait_for_hwseq_spi_cycle_complete();
+
msg_pdbg("Erasing %d bytes starting at 0x%06x.\n", len, addr);
ich_hwseq_set_addr(addr);
@@ -1438,6 +1470,9 @@
/* as well as flash chip page borders as demanded in the Intel datasheets. */
block_len = min(block_len, 256 - (addr & 0xFF));
+ /* Wait for previous SPI cycle to complete */
+ ich_wait_for_hwseq_spi_cycle_complete();
+
ich_hwseq_set_addr(addr);
hsfc = REGREAD16(ICH9_REG_HSFC);
hsfc &= ~hwseq_data.hsfc_fcycle; /* set read operation */
@@ -1474,6 +1509,9 @@
REGWRITE16(ICH9_REG_HSFS, REGREAD16(ICH9_REG_HSFS));
while (len > 0) {
+ /* Wait for previous SPI cycle to complete */
+ ich_wait_for_hwseq_spi_cycle_complete();
+
ich_hwseq_set_addr(addr);
/* Obey programmer limit... */
block_len = min(len, flash->mst->opaque.max_data_write);
To view, visit change 61854. To unsubscribe, or for help writing mail filters, visit settings.