summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;