[U-Boot] [PATCH 7/8] rockchip: spi: add driver-data and a 'rxonly_manages_fifo' flag

Philipp Tomsich philipp.tomsich at theobroma-systems.com
Sun Feb 3 15:17:32 UTC 2019


The SPI controller's documentation (I only had access to the RK3399,
RK3368 and PX30 TRMs) specifies that, when operating in master-mode,
the controller will stop the SCLK to avoid RXFIFO overruns and TXFIFO
underruns.  Looks like my worries that we'd need to support DMA-330
(aka PL330) to make any further progress were unfounded.

This adds a driver-data structure to capture hardware-specific
settings of individual controller instances (after all, we don't know
if all versions are well-behaved) and adds a 'master_manages_fifo'
flag to it.  The first use of said flag is in the optimised
receive-only transfer-handler, which can now request 64Kframe
(i.e. 128KByte) bursts of data on each reprogramming of CTRLR1
(i.e. every time through the loop).

This improves throughput to 46.85MBit/s (a 94.65% bus-utilisation).

Signed-off-by: Philipp Tomsich <philipp.tomsich at theobroma-systems.com>
---

 drivers/spi/rk_spi.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/rk_spi.c b/drivers/spi/rk_spi.c
index fec41a4..7b39d1c 100644
--- a/drivers/spi/rk_spi.c
+++ b/drivers/spi/rk_spi.c
@@ -26,6 +26,11 @@
 /* Change to 1 to output registers at the start of each transaction */
 #define DEBUG_RK_SPI	0
 
+struct rockchip_spi_params {
+	/* RXFIFO overruns and TXFIFO underruns stop the master clock */
+	bool master_manages_fifo;
+};
+
 struct rockchip_spi_platdata {
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
 	struct dtd_rockchip_rk3288_spi of_plat;
@@ -364,6 +369,15 @@ static inline int rockchip_spi_16bit_reader(struct udevice *dev,
 		return 0;
 	}
 
+	/*
+	 * If we know that the hardware will manage RXFIFO overruns
+	 * (i.e. stop the SPI clock until there's space in the FIFO),
+	 * we the allow largest possible chunk size that can be
+	 * represented in CTRLR1.
+	 */
+	if (data && data->master_manages_fifo)
+		max_chunk_size = 0x10000;
+
 	// rockchip_spi_configure(dev, mode, size)
 	rkspi_enable_chip(regs, false);
 	clrsetbits_le32(&regs->ctrlr0,
@@ -524,10 +538,16 @@ static const struct dm_spi_ops rockchip_spi_ops = {
 	 */
 };
 
+const  struct rockchip_spi_params rk3399_spi_params = {
+	.master_manages_fifo = true,
+};
+
 static const struct udevice_id rockchip_spi_ids[] = {
 	{ .compatible = "rockchip,rk3288-spi" },
-	{ .compatible = "rockchip,rk3368-spi" },
-	{ .compatible = "rockchip,rk3399-spi" },
+	{ .compatible = "rockchip,rk3368-spi",
+	  .data = (ulong)&rk3399_spi_params },
+	{ .compatible = "rockchip,rk3399-spi",
+	  .data = (ulong)&rk3399_spi_params },
 	{ }
 };
 
-- 
2.1.4



More information about the U-Boot mailing list