[coreboot-gerrit] New patch to review for coreboot: soc/apollolake/spi.c: Add timeout for HW sequencer transfers

Alexandru Gagniuc (alexandrux.gagniuc@intel.com) gerrit at coreboot.org
Tue Jun 21 23:47:00 CEST 2016


Alexandru Gagniuc (alexandrux.gagniuc at intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15310

-gerrit

commit 755011be32ba774ce0518f71a68bb3ec42ea7f79
Author: Alexandru Gagniuc <alexandrux.gagniuc at intel.com>
Date:   Tue Jun 21 14:38:05 2016 -0700

    soc/apollolake/spi.c: Add timeout for HW sequencer transfers
    
    Add a timeout to the loop which waits for SPI transactions to complete
    via the hardware sequencer (wait_for_hwseq_xfer). This should provide
    an indication if the hardware sequencer becomes unresponsive.
    
    Change-Id: I48ab8642ea2578e3afcc6eef45733919e4b0e79d
    Signed-off-by: Alexandru Gagniuc <alexandrux.gagniuc at intel.com>
---
 src/soc/intel/apollolake/spi.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/soc/intel/apollolake/spi.c b/src/soc/intel/apollolake/spi.c
index 282ed01..01272e0 100644
--- a/src/soc/intel/apollolake/spi.c
+++ b/src/soc/intel/apollolake/spi.c
@@ -25,6 +25,7 @@
 #include <spi_flash.h>
 #include <stdlib.h>
 #include <string.h>
+#include <timer.h>
 
 /* Helper to create a SPI context on API entry. */
 #define BOILERPLATE_CREATE_CTX(ctx)		\
@@ -145,9 +146,21 @@ static void print_xfer_error(struct spi_ctx *ctx, const char *failure_reason,
 	       failure_reason, flash_addr, ctx->hsfsts_on_last_error);
 }
 
+/*
+ * The timeouts are arbitrarily chosen. Since we're working with 64 byte
+ * transfers, we can assume writes should complete in way under 100 ms. We make
+ * the same assumption about erase. Then anything that is not finished within
+ * one second is most likely an error.
+ */
 static int wait_for_hwseq_xfer(struct spi_ctx *ctx)
 {
 	uint32_t hsfsts;
+	bool warning_printed = false;
+	struct stopwatch warn_timeout, error_timeout;
+
+	stopwatch_init_msecs_expire(&warn_timeout, 100);
+	stopwatch_init_msecs_expire(&error_timeout, 1000);
+
 	do {
 		hsfsts = _spi_ctrlr_reg_read(ctx, SPIBAR_HSFSTS_CTL);
 
@@ -155,7 +168,14 @@ static int wait_for_hwseq_xfer(struct spi_ctx *ctx)
 			ctx->hsfsts_on_last_error = hsfsts;
 			return E_HW_ERROR;
 		}
-	/* TODO: set up timer and abort on timeout */
+
+		if (stopwatch_expired(&warn_timeout) && !warning_printed) {
+			printk(BIOS_WARNING, "SPI transaction appears stuck\n");
+			warning_printed = true;
+		}
+		if (stopwatch_expired(&error_timeout)) {
+			return E_TIMEOUT;
+		}
 	} while (!(hsfsts & SPIBAR_HSFSTS_FDONE));
 
 	return SUCCESS;



More information about the coreboot-gerrit mailing list