aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorWilliam Zhang <william.zhang@broadcom.com>2023-06-07 16:37:02 -0700
committerJagan Teki <jagan@edgeble.ai>2023-07-13 13:59:57 +0530
commit27c4d550aaf45a9ffdd6ffe00aee854867943f29 (patch)
treef5d0de0e0f1d2a3bc429ea93e17123710ccc7aa1 /drivers
parent937b49e90abe8dcb095d324dc4d48ae1542b563d (diff)
downloadu-boot-27c4d550aaf45a9ffdd6ffe00aee854867943f29.zip
u-boot-27c4d550aaf45a9ffdd6ffe00aee854867943f29.tar.gz
u-boot-27c4d550aaf45a9ffdd6ffe00aee854867943f29.tar.bz2
spi: bcm63xx-hsspi: Fix multi-bit mode setting
Currently the driver always sets the controller to dual data bit mode for both tx and rx data in the profile mode control register even for single data bit transfer. Luckily the opcode is set correctly according to SPI transfer data bit width so it does not actually cause issues. This change fixes the problem by setting tx and rx data bit mode field correctly according to the actual SPI transfer tx and rx data bit width. Fixes: 29cc4368ad4b ("dm: spi: add BCM63xx HSSPI driver") Port from linux patch: Link: https://lore.kernel.org/r/20230209200246.141520-11-william.zhang@broadcom.com Signed-off-by: William Zhang <william.zhang@broadcom.com> Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/bcm63xx_hsspi.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/spi/bcm63xx_hsspi.c b/drivers/spi/bcm63xx_hsspi.c
index 4d714ad..ea34da2 100644
--- a/drivers/spi/bcm63xx_hsspi.c
+++ b/drivers/spi/bcm63xx_hsspi.c
@@ -221,7 +221,7 @@ static int bcm63xx_hsspi_xfer(struct udevice *dev, unsigned int bitlen,
size_t data_bytes = bitlen / 8;
size_t step_size = HSSPI_FIFO_SIZE;
uint16_t opcode = 0;
- uint32_t val;
+ uint32_t val = SPI_PFL_MODE_FILL_MASK;
const uint8_t *tx = dout;
uint8_t *rx = din;
@@ -240,14 +240,17 @@ static int bcm63xx_hsspi_xfer(struct udevice *dev, unsigned int bitlen,
step_size -= HSSPI_FIFO_OP_SIZE;
/* dual mode */
- if ((opcode == HSSPI_FIFO_OP_CODE_R && plat->mode == SPI_RX_DUAL) ||
- (opcode == HSSPI_FIFO_OP_CODE_W && plat->mode == SPI_TX_DUAL))
+ if ((opcode == HSSPI_FIFO_OP_CODE_R && (plat->mode & SPI_RX_DUAL)) ||
+ (opcode == HSSPI_FIFO_OP_CODE_W && (plat->mode & SPI_TX_DUAL))) {
opcode |= HSSPI_FIFO_OP_MBIT_MASK;
- /* profile mode */
- val = SPI_PFL_MODE_FILL_MASK |
- SPI_PFL_MODE_MDRDSZ_MASK |
- SPI_PFL_MODE_MDWRSZ_MASK;
+ /* profile mode */
+ if (plat->mode & SPI_RX_DUAL)
+ val |= SPI_PFL_MODE_MDRDSZ_MASK;
+ if (plat->mode & SPI_TX_DUAL)
+ val |= SPI_PFL_MODE_MDWRSZ_MASK;
+ }
+
if (plat->mode & SPI_3WIRE)
val |= SPI_PFL_MODE_3WIRE_MASK;
writel(val, priv->regs + SPI_PFL_MODE_REG(plat->cs));