提交 747e1f60 编写于 作者: M Miquel Raynal 提交者: 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: NKen Ma <make@marvell.com>
Signed-off-by: NMiquel Raynal <miquel.raynal@free-electrons.com>
Signed-off-by: NMark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
上级 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% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册