From patchwork Fri Jun 5 12:44:42 2020
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Pratyush Yadav
X-Patchwork-Id: 241812
List-Id: U-Boot discussion
From: p.yadav at ti.com (Pratyush Yadav)
Date: Fri, 5 Jun 2020 18:14:42 +0530
Subject: [PATCH v6 03/21] spi: cadence-qspi: Do not calibrate when device
tree sets read delay
In-Reply-To: <20200605124500.17867-1-p.yadav@ti.com>
References: <20200605124500.17867-1-p.yadav@ti.com>
Message-ID: <20200605124500.17867-4-p.yadav@ti.com>
If the device tree provides a read delay value, use that directly and do
not perform the calibration procedure.
This allows the device tree to over-ride the read delay value in cases
where the read delay value obtained via calibration is incorrect. One
such example is the Cypress Semper flash. It needs a read delay of 4 in
octal DTR mode. But since the calibration procedure is run before the
flash is switched in octal DTR mode, it yields a read delay of 2. A
value of 4 works for both octal DTR and legacy modes.
Signed-off-by: Pratyush Yadav
---
drivers/spi/cadence_qspi.c | 26 +++++++++++++++++++++-----
drivers/spi/cadence_qspi.h | 1 +
2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index 1e85749209..305f2ec0df 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -141,12 +141,20 @@ static int cadence_spi_set_speed(struct udevice *bus, uint hz)
cadence_qspi_apb_controller_disable(priv->regbase);
/*
- * Calibration required for different current SCLK speed, requested
- * SCLK speed or chip select
+ * If the device tree already provides a read delay value, use that
+ * instead of calibrating.
*/
- if (priv->previous_hz != hz ||
- priv->qspi_calibrated_hz != hz ||
- priv->qspi_calibrated_cs != spi_chip_select(bus)) {
+ if (plat->read_delay >= 0) {
+ cadence_spi_write_speed(bus, hz);
+ cadence_qspi_apb_readdata_capture(priv->regbase, 1,
+ plat->read_delay);
+ } else if (priv->previous_hz != hz ||
+ priv->qspi_calibrated_hz != hz ||
+ priv->qspi_calibrated_cs != spi_chip_select(bus)) {
+ /*
+ * Calibration required for different current SCLK speed,
+ * requested SCLK speed or chip select
+ */
err = spi_calibration(bus, hz);
if (err)
return err;
@@ -320,6 +328,14 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus)
255);
plat->tchsh_ns = ofnode_read_u32_default(subnode, "cdns,tchsh-ns", 20);
plat->tslch_ns = ofnode_read_u32_default(subnode, "cdns,tslch-ns", 20);
+ /*
+ * Read delay should be an unsigned value but we use a signed integer
+ * so that negative values can indicate that the device tree did not
+ * specify any signed values and we need to perform the calibration
+ * sequence to find it out.
+ */
+ plat->read_delay = ofnode_read_s32_default(subnode, "cdns,read-delay",
+ -1);
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 ae459c74a1..9dff2fdced 100644
--- a/drivers/spi/cadence_qspi.h
+++ b/drivers/spi/cadence_qspi.h
@@ -26,6 +26,7 @@ struct cadence_spi_platdata {
u32 trigger_address;
fdt_addr_t ahbsize;
bool use_dac_mode;
+ int read_delay;
/* Flash parameters */
u32 page_size;