summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2016-08-27 15:10:30 -0600
committerPatrick Georgi <pgeorgi@google.com>2016-09-20 21:51:42 +0200
commit03cd118025e0f7aab139254e07f9d1dca3c242e5 (patch)
treeb4464c6400e113a12a093123bdc827c4f11233e4
parent2b7a6019f26aaaa1d01a2a69adfbf58cde919679 (diff)
downloadcoreboot-03cd118025e0f7aab139254e07f9d1dca3c242e5.tar.xz
rockchip: spi: Improve SPI read efficiency
The SPI driver is quite slow at reading data. For example, with a 24MHz clock on gru it achieves a read speed of only 13.9Mbps. We can correct this by reading the status registers once, then reading as many bytes as are available before checking the status registers again. It seems likely that a status register read requires synchronizing with the SPI FIFO clock domain, which takes a while. BUG=chrome-os-partner:56556 BRANCH=none TEST=run on gru and see the speed increase from 13.920 Mbps to 24.712 Mbps Change-Id: I24aed0c9c6c5445634c4e056922afaee4e9a7b33 Signed-off-by: Martin Roth <martinroth@chromium.org> Original-Commit-Id: 49c2fc20d7d7d703763e9b0a6f68313a349a84b9 Original-Change-Id: I42745f01f0fe069f6ae26d866004d36bb257e6b2 Original-Signed-off-by: Simon Glass <sjg@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/376945 Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/16582 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
-rw-r--r--src/soc/rockchip/common/include/soc/spi.h7
-rw-r--r--src/soc/rockchip/common/spi.c15
2 files changed, 18 insertions, 4 deletions
diff --git a/src/soc/rockchip/common/include/soc/spi.h b/src/soc/rockchip/common/include/soc/spi.h
index 7e9e568e6d..dcaa4711d2 100644
--- a/src/soc/rockchip/common/include/soc/spi.h
+++ b/src/soc/rockchip/common/include/soc/spi.h
@@ -165,6 +165,13 @@ check_member(rockchip_spi, rxdr, 0x800);
#define SPI_OMOD_SLAVE 0x01
/* --------Bit fields in CTRLR0--------end */
+
+/* TXFLR bits */
+#define TXFLR_LEVEL_MASK 0x3f
+
+/* RXFLR bits */
+#define RXFLR_LEVEL_MASK 0x3f
+
/* Bit fields in SR, 7 bits */
#define SR_MASK 0x7f
#define SR_BUSY (1 << 0)
diff --git a/src/soc/rockchip/common/spi.c b/src/soc/rockchip/common/spi.c
index 6784f5b975..f35f91589f 100644
--- a/src/soc/rockchip/common/spi.c
+++ b/src/soc/rockchip/common/spi.c
@@ -235,11 +235,18 @@ static int do_xfer(struct rockchip_spi *regs, const void *dout,
xferred = 1;
}
+ /*
+ * Try to read as many bytes as are available in one go.
+ * Reading the status registers probably requires
+ * sychronizing with the SPI clock which is pretty slow.
+ */
if (*bytes_in && !(sr & SR_RF_EMPT)) {
- *in_buf = read32(&regs->rxdr) & 0xff;
- in_buf++;
- *bytes_in -= 1;
- xferred = 1;
+ int todo = read32(&regs->rxflr) & RXFLR_LEVEL_MASK;
+
+ *bytes_in -= todo;
+ xferred = todo;
+ while (todo-- > 0)
+ *in_buf++ = read32(&regs->rxdr) & 0xff;
}
min_xfer -= xferred;