[PATCH 0/3 v2] qspi: t210: fix claim_bus and clock/tap delays

From: Tom Warren twarren@nvidia.com
These patches fix a couple of problems encountered in the T210 QSPI driver discovered during Jetson Nano bringup, and adapt the driver to upstream DM norms.
Tom Warren (3): qspi: t210: Fix claim_bus's use of the wrong bus/device qspi: t210: Fix QSPI clock and tap delays qspi: t210: Use dev_read calls to get FDT data like base, freq
drivers/spi/tegra210_qspi.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-)

From: Tom Warren twarren@nvidia.com
claim_bus() is passed a udevice *dev, which is the bus device's parent. In this driver, claim_bus assumed it was the bus, which caused the 'priv' info pointer to be wrong, and periph_id was incorrect. This in turn caused the periph clock call to assign the wrong clock (PLLM instead of PLLP0), which caused a kernel warning. I only saw the 'bad' periph_id when enabling DEBUG due to an assert. Not sure how QSPI was working w/this errant clock, but it was moot as QSPI wasn't active unless you probed it, and that wasn't happening until I posted a patch to enable env save to QSPI for Nano (coming soon).
Signed-off-by: Tom Warren twarren@nvidia.com --- Changes in v2: - None
drivers/spi/tegra210_qspi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/tegra210_qspi.c b/drivers/spi/tegra210_qspi.c index d82ecaa..2a77126 100644 --- a/drivers/spi/tegra210_qspi.c +++ b/drivers/spi/tegra210_qspi.c @@ -2,7 +2,8 @@ /* * NVIDIA Tegra210 QSPI controller driver * - * (C) Copyright 2015 NVIDIA Corporation <www.nvidia.com> + * (C) Copyright 2015-2019 NVIDIA Corporation <www.nvidia.com> + * */
#include <common.h> @@ -137,8 +138,9 @@ static int tegra210_qspi_probe(struct udevice *bus) return 0; }
-static int tegra210_qspi_claim_bus(struct udevice *bus) +static int tegra210_qspi_claim_bus(struct udevice *dev) { + struct udevice *bus = dev->parent; struct tegra210_qspi_priv *priv = dev_get_priv(bus); struct qspi_regs *regs = priv->regs;

From: Tom Warren twarren@nvidia.com
When claim_bus was setting the clock, it reset the QSPI controller, which wipes out any tap delays set by previous bootloaders (nvtboot, CBoot for example on Nano). Instead of doing that in claim_bus, which gets called a lot, moved clock setting to probe(), and set tap delays there, too. Also updated clock to 80MHz to match CBoot. Now QSPI env save works reliably again.
Signed-off-by: Tom Warren twarren@nvidia.com --- Changes in v2: - None
drivers/spi/tegra210_qspi.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/spi/tegra210_qspi.c b/drivers/spi/tegra210_qspi.c index 2a77126..4284ea9 100644 --- a/drivers/spi/tegra210_qspi.c +++ b/drivers/spi/tegra210_qspi.c @@ -42,10 +42,10 @@ DECLARE_GLOBAL_DATA_PTR; #define QSPI_CMD1_BITLEN_SHIFT 0
/* COMMAND2 */ -#define QSPI_CMD2_TX_CLK_TAP_DELAY BIT(6) -#define QSPI_CMD2_TX_CLK_TAP_DELAY_MASK GENMASK(11,6) -#define QSPI_CMD2_RX_CLK_TAP_DELAY BIT(0) -#define QSPI_CMD2_RX_CLK_TAP_DELAY_MASK GENMASK(5,0) +#define QSPI_CMD2_TX_CLK_TAP_DELAY_SHIFT 10 +#define QSPI_CMD2_TX_CLK_TAP_DELAY_MASK GENMASK(14,10) +#define QSPI_CMD2_RX_CLK_TAP_DELAY_SHIFT 0 +#define QSPI_CMD2_RX_CLK_TAP_DELAY_MASK GENMASK(7,0)
/* TRANSFER STATUS */ #define QSPI_XFER_STS_RDY BIT(30) @@ -127,14 +127,22 @@ static int tegra210_qspi_probe(struct udevice *bus) struct tegra210_qspi_priv *priv = dev_get_priv(bus);
priv->regs = (struct qspi_regs *)plat->base; + struct qspi_regs *regs = priv->regs;
priv->last_transaction_us = timer_get_us(); priv->freq = plat->frequency; priv->periph_id = plat->periph_id;
+ debug("%s: Freq = %u, id = %d\n", __func__, priv->freq, priv->periph_id); /* Change SPI clock to correct frequency, PLLP_OUT0 source */ clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH, priv->freq);
+ /* Set tap delays here, clock change above resets QSPI controller */ + u32 reg = (0x09 << QSPI_CMD2_TX_CLK_TAP_DELAY_SHIFT) | + (0x0C << QSPI_CMD2_RX_CLK_TAP_DELAY_SHIFT); + writel(reg, ®s->command2); + debug("%s: COMMAND2 = %08x\n", __func__, readl(®s->command2)); + return 0; }
@@ -144,9 +152,6 @@ static int tegra210_qspi_claim_bus(struct udevice *dev) struct tegra210_qspi_priv *priv = dev_get_priv(bus); struct qspi_regs *regs = priv->regs;
- /* Change SPI clock to correct frequency, PLLP_OUT0 source */ - clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH, priv->freq); - debug("%s: FIFO STATUS = %08x\n", __func__, readl(®s->fifo_status));
/* Set master mode and sw controlled CS */

From: Tom Warren twarren@nvidia.com
This Tegra QSPI driver hadn't been brought up to date with how DM drivers are fetching data from the FDT now, and was pulling in bogus data for base, max freq, etc. Fixed ofdata_to_platdata to work the same way it does in the tegra114 SPI driver, using dev_read_ functions.
Signed-off-by: Tom Warren twarren@nvidia.com --- Changes in v2: - New
drivers/spi/tegra210_qspi.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/tegra210_qspi.c b/drivers/spi/tegra210_qspi.c index 4284ea9..466d572 100644 --- a/drivers/spi/tegra210_qspi.c +++ b/drivers/spi/tegra210_qspi.c @@ -2,7 +2,7 @@ /* * NVIDIA Tegra210 QSPI controller driver * - * (C) Copyright 2015-2019 NVIDIA Corporation <www.nvidia.com> + * (C) Copyright 2015-2020 NVIDIA Corporation <www.nvidia.com> * */
@@ -97,10 +97,8 @@ struct tegra210_qspi_priv { static int tegra210_qspi_ofdata_to_platdata(struct udevice *bus) { struct tegra_spi_platdata *plat = bus->platdata; - const void *blob = gd->fdt_blob; - int node = dev_of_offset(bus);
- plat->base = devfdt_get_addr(bus); + plat->base = dev_read_addr(bus); plat->periph_id = clock_decode_periph_id(bus);
if (plat->periph_id == PERIPH_ID_NONE) { @@ -110,9 +108,9 @@ static int tegra210_qspi_ofdata_to_platdata(struct udevice *bus) }
/* Use 500KHz as a suitable default */ - plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency", + plat->frequency = dev_read_u32_default(bus, "spi-max-frequency", 500000); - plat->deactivate_delay_us = fdtdec_get_int(blob, node, + plat->deactivate_delay_us = dev_read_u32_default(bus, "spi-deactivate-delay", 0); debug("%s: base=%#08lx, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n", __func__, plat->base, plat->periph_id, plat->frequency,
participants (1)
-
tomcwarren3959@gmail.com