
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@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;