]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
spi: bcm63xx-hsspi: Fix multi-bit mode setting
authorWilliam Zhang <william.zhang@broadcom.com>
Thu, 9 Feb 2023 20:02:41 +0000 (12:02 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 11 Mar 2023 15:26:43 +0000 (16:26 +0100)
[ Upstream commit 811ff802aaf878ebbbaeac0307a0164fa21e7d40 ]

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: 142168eba9dc ("spi: bcm63xx-hsspi: add bcm63xx HSSPI driver")
Signed-off-by: William Zhang <william.zhang@broadcom.com>
Link: https://lore.kernel.org/r/20230209200246.141520-11-william.zhang@broadcom.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/spi/spi-bcm63xx-hsspi.c

index cbcba614b253375d024cf45f03408fa53337d8f5..d2c23d5797c4b6daa51382f0376027c3a38e27e1 100644 (file)
@@ -160,6 +160,7 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t)
        int step_size = HSSPI_BUFFER_LEN;
        const u8 *tx = t->tx_buf;
        u8 *rx = t->rx_buf;
+       u32 val = 0;
 
        bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz);
        bcm63xx_hsspi_set_cs(bs, spi->chip_select, true);
@@ -175,11 +176,16 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t)
                step_size -= HSSPI_OPCODE_LEN;
 
        if ((opcode == HSSPI_OP_READ && t->rx_nbits == SPI_NBITS_DUAL) ||
-           (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL))
+           (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL)) {
                opcode |= HSSPI_OP_MULTIBIT;
 
-       __raw_writel(1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT |
-                    1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT | 0xff,
+               if (t->rx_nbits == SPI_NBITS_DUAL)
+                       val |= 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT;
+               if (t->tx_nbits == SPI_NBITS_DUAL)
+                       val |= 1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT;
+       }
+
+       __raw_writel(val | 0xff,
                     bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select));
 
        while (pending > 0) {