From: Ian Roberts <ian.robe...@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.morri...@timesys.com> Signed-off-by: Nathan Barrett-Morrison <nathan.morri...@timesys.com> Signed-off-by: Greg Malysa <greg.mal...@timesys.com> Signed-off-by: Ian Roberts <ian.robe...@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