[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