| From 50a8924674a937d8fc8f74bc7caf655c357d6913 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 9 Feb 2023 12:02:41 -0800 |
| Subject: spi: bcm63xx-hsspi: Fix multi-bit mode setting |
| |
| From: William Zhang <william.zhang@broadcom.com> |
| |
| [ 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 | 12 +++++++++--- |
| 1 file changed, 9 insertions(+), 3 deletions(-) |
| |
| diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c |
| index bc539010f2b98..6071756149ef4 100644 |
| --- a/drivers/spi/spi-bcm63xx-hsspi.c |
| +++ b/drivers/spi/spi-bcm63xx-hsspi.c |
| @@ -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) { |
| -- |
| 2.39.2 |
| |