Commit 747e1f60 authored by Miquel Raynal's avatar Miquel Raynal Committed by Mark Brown

spi: armada-3700: Fix failing commands with quad-SPI

A3700 SPI controller datasheet states that only the first line (IO0) is
used to receive and send instructions, addresses and dummy bytes,
unless for addresses during an RX operation in a quad SPI configuration
(see p.821 of the Armada-3720-DB datasheet). Otherwise, some commands
such as SPI NOR commands like READ_FROM_CACHE_DUAL_IO(0xeb) and
READ_FROM_CACHE_DUAL_IO(0xbb) will fail because these commands must send
address bytes through the four pins. Data transfer always use the four
bytes with this setup.

Thus, in quad SPI configuration, the A3700_SPI_ADDR_PIN bit must be set
only in this case to inform the controller that it must use the number
of pins indicated in the {A3700_SPI_DATA_PIN1,A3700_SPI_DATA_PIN0} field
during the address cycles of an RX operation.
Suggested-by: default avatarKen Ma <make@marvell.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@free-electrons.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
parent ecb478bf
...@@ -161,7 +161,7 @@ static void a3700_spi_deactivate_cs(struct a3700_spi *a3700_spi, ...@@ -161,7 +161,7 @@ static void a3700_spi_deactivate_cs(struct a3700_spi *a3700_spi,
} }
static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi, static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi,
unsigned int pin_mode) unsigned int pin_mode, bool receiving)
{ {
u32 val; u32 val;
...@@ -177,6 +177,9 @@ static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi, ...@@ -177,6 +177,9 @@ static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi,
break; break;
case SPI_NBITS_QUAD: case SPI_NBITS_QUAD:
val |= A3700_SPI_DATA_PIN1; val |= A3700_SPI_DATA_PIN1;
/* RX during address reception uses 4-pin */
if (receiving)
val |= A3700_SPI_ADDR_PIN;
break; break;
default: default:
dev_err(&a3700_spi->master->dev, "wrong pin mode %u", pin_mode); dev_err(&a3700_spi->master->dev, "wrong pin mode %u", pin_mode);
...@@ -653,7 +656,7 @@ static int a3700_spi_transfer_one(struct spi_master *master, ...@@ -653,7 +656,7 @@ static int a3700_spi_transfer_one(struct spi_master *master,
else if (xfer->rx_buf) else if (xfer->rx_buf)
nbits = xfer->rx_nbits; nbits = xfer->rx_nbits;
a3700_spi_pin_mode_set(a3700_spi, nbits); a3700_spi_pin_mode_set(a3700_spi, nbits, xfer->rx_buf ? true : false);
if (xfer->rx_buf) { if (xfer->rx_buf) {
/* Set read data length */ /* Set read data length */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment