[U-Boot] [PATCH] spi: tegra20: fix mode selection logic
Stephen Warren
swarren at wwwdotorg.org
Fri Aug 12 23:06:10 CEST 2016
From: Stephen Warren <swarren at nvidia.com>
When the set_mode() function runs, the SPI bus is not active, and hence
the clocks to the SPI controller are not running. Any register read/write
at this time will hang the CPU. Remove the code from set_mode() that does
this, and move it to the correct place in claim_bus().
This essentially reverts and re-implements the patch mentioned in the
fixes tag below. I'm not sure how the original could ever have worked on
any Tegra platform; it certainly breaks the only Tegra board I have that
uses SPI.
Fixes: 5cb1b7b395c0 ("spi: tegra20: Add support for mode selection")
Cc: Mirza Krak <mirza.krak at hostmobility.com>
Signed-off-by: Stephen Warren <swarren at nvidia.com>
---
As far as I can tell, the fixed patch was never CC'd to any Tegra
maintainer:-(
---
drivers/spi/tegra20_slink.c | 24 ++++++++----------------
1 file changed, 8 insertions(+), 16 deletions(-)
diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c
index 238edec23ba5..0e167ccac053 100644
--- a/drivers/spi/tegra20_slink.c
+++ b/drivers/spi/tegra20_slink.c
@@ -151,6 +151,14 @@ static int tegra30_spi_claim_bus(struct udevice *dev)
/* Set master mode and sw controlled CS */
reg = readl(®s->command);
reg |= SLINK_CMD_M_S | SLINK_CMD_CS_SOFT;
+ /* Set CPOL and CPHA */
+ reg &= ~(SLINK_CMD_IDLE_SCLK_MASK | SLINK_CMD_CK_SDA);
+ if (priv->mode & SPI_CPHA)
+ reg |= SLINK_CMD_CK_SDA;
+ if (priv->mode & SPI_CPOL)
+ reg |= SLINK_CMD_IDLE_SCLK_DRIVE_HIGH;
+ else
+ reg |= SLINK_CMD_IDLE_SCLK_DRIVE_LOW;
writel(reg, ®s->command);
debug("%s: COMMAND = %08x\n", __func__, readl(®s->command));
@@ -321,22 +329,6 @@ static int tegra30_spi_set_speed(struct udevice *bus, uint speed)
static int tegra30_spi_set_mode(struct udevice *bus, uint mode)
{
struct tegra30_spi_priv *priv = dev_get_priv(bus);
- struct spi_regs *regs = priv->regs;
- u32 reg;
-
- reg = readl(®s->command);
-
- /* Set CPOL and CPHA */
- reg &= ~(SLINK_CMD_IDLE_SCLK_MASK | SLINK_CMD_CK_SDA);
- if (mode & SPI_CPHA)
- reg |= SLINK_CMD_CK_SDA;
-
- if (mode & SPI_CPOL)
- reg |= SLINK_CMD_IDLE_SCLK_DRIVE_HIGH;
- else
- reg |= SLINK_CMD_IDLE_SCLK_DRIVE_LOW;
-
- writel(reg, ®s->command);
priv->mode = mode;
debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
--
2.9.2
More information about the U-Boot
mailing list