[PATCH 10/11] spi: cadence-quadspi: Add DT control of max Read Delay Capture value

Greg Malysa greg.malysa at timesys.com
Fri Apr 12 00:36:54 CEST 2024


From: Ian Roberts <ian.roberts at timesys.com>

On some SOCs (eg sc59x), attempting to use too high of a Read
Delay Capture value can cause the controller DMA to lock up. Thus,
add a device tree configuration property to allow controlling
the max Read Delay Capture value.

Co-developed-by: Nathan Barrett-Morrison <nathan.morrison at timesys.com>
Signed-off-by: Nathan Barrett-Morrison <nathan.morrison at timesys.com>
Signed-off-by: Greg Malysa <greg.malysa at timesys.com>
Signed-off-by: Ian Roberts <ian.roberts at timesys.com>
---

 doc/device-tree-bindings/spi/spi-cadence.txt | 2 ++
 drivers/spi/cadence_qspi.c                   | 9 ++++++++-
 drivers/spi/cadence_qspi.h                   | 2 ++
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/doc/device-tree-bindings/spi/spi-cadence.txt b/doc/device-tree-bindings/spi/spi-cadence.txt
index 69e02c1c4b..9bd7ef8bed 100644
--- a/doc/device-tree-bindings/spi/spi-cadence.txt
+++ b/doc/device-tree-bindings/spi/spi-cadence.txt
@@ -29,3 +29,5 @@ connected flash properties
 			  select (n_ss_out).
 - cdns,tslch-ns		: Delay in master reference clocks between setting
 			  n_ss_out low and first bit transfer
+- cdns,max-read-delay	: Max safe value to use for the read capture delay
+			  during auto calibration.
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index a5e921cae7..3778a469d4 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -104,7 +104,7 @@ static int spi_calibration(struct udevice *bus, uint hz)
 
 	/* use back the intended clock and find low range */
 	cadence_spi_write_speed(bus, hz);
-	for (i = 0; i < CQSPI_READ_CAPTURE_MAX_DELAY; i++) {
+	for (i = 0; i < priv->max_read_delay; i++) {
 		/* Disable QSPI */
 		cadence_qspi_apb_controller_disable(base);
 
@@ -246,6 +246,7 @@ static int cadence_spi_probe(struct udevice *bus)
 	priv->fifo_depth	= plat->fifo_depth;
 	priv->fifo_width	= plat->fifo_width;
 	priv->trigger_address	= plat->trigger_address;
+	priv->max_read_delay	= plat->max_read_delay;
 	priv->read_delay	= plat->read_delay;
 	priv->ahbsize		= plat->ahbsize;
 	priv->max_hz		= plat->max_hz;
@@ -456,6 +457,10 @@ static int cadence_spi_of_to_plat(struct udevice *bus)
 
 	plat->is_dma = dev_read_bool(bus, "cdns,is-dma");
 
+	plat->max_read_delay = dev_read_u32_default(bus,
+						    "cdns,max-read-delay",
+						    CQSPI_READ_CAPTURE_MAX_DELAY);
+
 	/* All other parameters are embedded in the child node */
 	subnode = cadence_qspi_get_subnode(bus);
 	if (!ofnode_valid(subnode)) {
@@ -484,6 +489,8 @@ static int cadence_spi_of_to_plat(struct udevice *bus)
 	 */
 	plat->read_delay = ofnode_read_s32_default(subnode, "cdns,read-delay",
 						   -1);
+	if (plat->read_delay > plat->max_read_delay)
+		plat->read_delay = plat->max_read_delay;
 
 	debug("%s: regbase=%p ahbbase=%p max-frequency=%d page-size=%d\n",
 	      __func__, plat->regbase, plat->ahbbase, plat->max_hz,
diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h
index 9c15d3c6df..d7a02f0870 100644
--- a/drivers/spi/cadence_qspi.h
+++ b/drivers/spi/cadence_qspi.h
@@ -214,6 +214,7 @@ struct cadence_spi_plat {
 	fdt_addr_t	ahbsize;
 	bool		use_dac_mode;
 	int		read_delay;
+	int		max_read_delay;
 
 	/* Flash parameters */
 	u32		page_size;
@@ -260,6 +261,7 @@ struct cadence_spi_priv {
 	unsigned int	previous_hz;
 	u32		wr_delay;
 	int		read_delay;
+	int		max_read_delay;
 
 	struct reset_ctl_bulk *resets;
 	u32		page_size;
-- 
2.43.2



More information about the U-Boot mailing list