[PATCH linux dev-5.7 3/6] spi: fsi: Fix use of the bneq+ sequencer instruction
Joel Stanley
joel at jms.id.au
Thu Jul 30 09:27:14 AEST 2020
On Wed, 29 Jul 2020 at 20:45, Eddie James <eajames at linux.ibm.com> wrote:
>
> From: Brad Bishop <bradleyb at fuzziesquirrel.com>
>
> All of the switches in N2_count_control in the counter configuration are
> required to make the branch if not equal and increment command work.
> Set them when using bneq+.
>
> A side effect of this mode requires a dummy write to TDR when both
> transmitting and receiving otherwise the controller won't start shifting
> receive data.
>
> It is likely not possible to avoid TDR underrun errors in this mode and
> they are harmless, so do not check for them.
>
> Signed-off-by: Eddie James <eajames at linux.ibm.com>
> Signed-off-by: Brad Bishop <bradleyb at fuzziesquirrel.com>
Fixes: bbb6b2f9865b ("spi: Add FSI-attached SPI controller driver")
Reviewed-by: Joel Stanley <joel at jms.id.au>
> ---
> drivers/spi/spi-fsi.c | 28 +++++++++++++++++++++++++---
> 1 file changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/spi/spi-fsi.c b/drivers/spi/spi-fsi.c
> index 559d0ff981f3..c31a852b6a3e 100644
> --- a/drivers/spi/spi-fsi.c
> +++ b/drivers/spi/spi-fsi.c
> @@ -29,6 +29,10 @@
> #define SPI_FSI_ERROR 0x0
> #define SPI_FSI_COUNTER_CFG 0x1
> #define SPI_FSI_COUNTER_CFG_LOOPS(x) (((u64)(x) & 0xffULL) << 32)
> +#define SPI_FSI_COUNTER_CFG_N2_RX BIT_ULL(8)
> +#define SPI_FSI_COUNTER_CFG_N2_TX BIT_ULL(9)
> +#define SPI_FSI_COUNTER_CFG_N2_IMPLICIT BIT_ULL(10)
> +#define SPI_FSI_COUNTER_CFG_N2_RELOAD BIT_ULL(11)
> #define SPI_FSI_CFG1 0x2
> #define SPI_FSI_CLOCK_CFG 0x3
> #define SPI_FSI_CLOCK_CFG_MM_ENABLE BIT_ULL(32)
> @@ -61,7 +65,7 @@
> #define SPI_FSI_STATUS_RDR_OVERRUN BIT_ULL(62)
> #define SPI_FSI_STATUS_RDR_FULL BIT_ULL(63)
> #define SPI_FSI_STATUS_ANY_ERROR \
> - (SPI_FSI_STATUS_ERROR | SPI_FSI_STATUS_TDR_UNDERRUN | \
> + (SPI_FSI_STATUS_ERROR | \
> SPI_FSI_STATUS_TDR_OVERRUN | SPI_FSI_STATUS_RDR_UNDERRUN | \
> SPI_FSI_STATUS_RDR_OVERRUN)
> #define SPI_FSI_PORT_CTRL 0x9
> @@ -238,6 +242,7 @@ static int fsi_spi_sequence_transfer(struct fsi_spi *ctx,
> int rc;
> u8 len = min(transfer->len, 8U);
> u8 rem = transfer->len % len;
> + u64 cfg = 0ULL;
>
> loops = transfer->len / len;
>
> @@ -258,8 +263,14 @@ static int fsi_spi_sequence_transfer(struct fsi_spi *ctx,
> if (loops > 1) {
> fsi_spi_sequence_add(seq, SPI_FSI_SEQUENCE_BRANCH(idx));
>
> - rc = fsi_spi_write_reg(ctx, SPI_FSI_COUNTER_CFG,
> - SPI_FSI_COUNTER_CFG_LOOPS(loops - 1));
> + cfg = SPI_FSI_COUNTER_CFG_LOOPS(loops - 1);
> + if (transfer->rx_buf)
> + cfg |= SPI_FSI_COUNTER_CFG_N2_RX |
> + SPI_FSI_COUNTER_CFG_N2_TX |
> + SPI_FSI_COUNTER_CFG_N2_IMPLICIT |
> + SPI_FSI_COUNTER_CFG_N2_RELOAD;
> +
> + rc = fsi_spi_write_reg(ctx, SPI_FSI_COUNTER_CFG, cfg);
> if (rc)
> return rc;
> }
> @@ -275,6 +286,7 @@ static int fsi_spi_transfer_data(struct fsi_spi *ctx,
> {
> int rc = 0;
> u64 status = 0ULL;
> + u64 cfg = 0ULL;
>
> if (transfer->tx_buf) {
> int nb;
> @@ -312,6 +324,16 @@ static int fsi_spi_transfer_data(struct fsi_spi *ctx,
> u64 in = 0ULL;
> u8 *rx = transfer->rx_buf;
>
> + rc = fsi_spi_read_reg(ctx, SPI_FSI_COUNTER_CFG, &cfg);
> + if (rc)
> + return rc;
> +
> + if (cfg & SPI_FSI_COUNTER_CFG_N2_IMPLICIT) {
> + rc = fsi_spi_write_reg(ctx, SPI_FSI_DATA_TX, 0);
> + if (rc)
> + return rc;
> + }
> +
> while (transfer->len > recv) {
> do {
> rc = fsi_spi_read_reg(ctx, SPI_FSI_STATUS,
> --
> 2.24.0
>
More information about the openbmc
mailing list