[U-Boot Patch v1 5/7] spi: fu540: fix: use spi xfer bitlen for spi transfer

Sagar Shrikant Kadam sagar.kadam at sifive.com
Thu Jan 23 21:16:04 CET 2020


Use bitlen passed by dm_spi_ops rather than using spi-tx/
rx-bus-width from the device tree, to set the mode bits in
format register of spi controller present in FU540-C000 SoC
on HiFive Unleashed board.

This patch handles a case where controller mode in format
register (0x40) is configured as per the width specified
in the dt-node of the slave device. For instance if spi-tx-
bus-width and spi-rx-bus-width in the flash device node in
dt is set to 4 bit mode, the controller gets configured in
QUAD mode, whereas the spi nor scan tries to read the JEDEC
ID with the reg_proto set to SNOR_PROTO_1_1_1 and fails.

Signed-off-by: Sagar Shrikant Kadam <sagar.kadam at sifive.com>
---
 drivers/spi/spi-sifive.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi-sifive.c b/drivers/spi/spi-sifive.c
index f990ad6..038fdb7 100644
--- a/drivers/spi/spi-sifive.c
+++ b/drivers/spi/spi-sifive.c
@@ -85,6 +85,10 @@
 #define SIFIVE_SPI_IP_TXWM               BIT(0)
 #define SIFIVE_SPI_IP_RXWM               BIT(1)
 
+#define SPI_NBITS_SINGLE		BIT(0)
+#define SPI_NBITS_DUAL			BIT(1)
+#define SPI_NBITS_QUAD			BIT(2)
+
 struct sifive_spi {
 	void		*regs;		/* base address of the registers */
 	u32		fifo_depth;
@@ -127,7 +131,7 @@ static void sifive_spi_clear_cs(struct sifive_spi *spi)
 }
 
 static void sifive_spi_prep_transfer(struct sifive_spi *spi,
-				     bool is_rx_xfer,
+				     unsigned int bitlen, bool is_rx_xfer,
 				     struct dm_spi_slave_platdata *slave)
 {
 	u32 cr;
@@ -146,12 +150,17 @@ static void sifive_spi_prep_transfer(struct sifive_spi *spi,
 
 	/* Number of wires ? */
 	cr &= ~SIFIVE_SPI_FMT_PROTO_MASK;
-	if ((slave->mode & SPI_TX_QUAD) || (slave->mode & SPI_RX_QUAD))
+	switch (bitlen) {
+	case SPI_NBITS_QUAD:
 		cr |= SIFIVE_SPI_FMT_PROTO_QUAD;
-	else if ((slave->mode & SPI_TX_DUAL) || (slave->mode & SPI_RX_DUAL))
+		break;
+	case SPI_NBITS_DUAL:
 		cr |= SIFIVE_SPI_FMT_PROTO_DUAL;
-	else
+		break;
+	default:
 		cr |= SIFIVE_SPI_FMT_PROTO_SINGLE;
+		break;
+	}
 
 	/* SPI direction in/out ? */
 	cr &= ~SIFIVE_SPI_FMT_DIR;
@@ -235,7 +244,7 @@ static int sifive_spi_xfer(struct udevice *dev, unsigned int bitlen,
 			return ret;
 	}
 
-	sifive_spi_prep_transfer(spi, true, slave);
+	sifive_spi_prep_transfer(spi, bitlen, true, slave);
 
 	remaining_len = bitlen / 8;
 
-- 
2.7.4



More information about the U-Boot mailing list