If the controller supports enhanced SPI modes then update the register or reset the register if the transfer is not using dual/quad/octal mode. Signed-off-by: Sudip Mukherjee <sudip.mukherjee@xxxxxxxxxx> --- drivers/spi/spi-dw-core.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 8e624620864f..9d499bdf2ce6 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -676,6 +676,32 @@ static void dw_spi_stop_mem_op(struct dw_spi *dws, struct spi_device *spi) dw_spi_enable_chip(dws, 1); } +static void update_spi_ctrl0(struct dw_spi *dws, const struct spi_mem_op *op, bool enable) +{ + u32 spi_ctrlr0; + + spi_ctrlr0 = dw_readl(dws, DW_HSSI_SPI_CTRLR0); + if (enable) { + spi_ctrlr0 |= FIELD_PREP(DW_HSSI_SPI_CTRLR0_WAIT_CYCLE_MASK, + op->dummy.nbytes * BITS_PER_BYTE); + /* 8 bit instruction length */ + spi_ctrlr0 |= FIELD_PREP(DW_HSSI_SPI_CTRLR0_INST_L_MASK, + DW_HSSI_SPI_CTRLR0_INST_L8); + /* 32 bit address length */ + spi_ctrlr0 |= FIELD_PREP(DW_HSSI_SPI_CTRLR0_ADDR_L_MASK, + DW_HSSI_SPI_CTRLR0_ADDR_L32); + /* Enable clock stretching */ + spi_ctrlr0 |= DW_HSSI_SPI_CTRLR0_CLK_STRETCH_EN; + } else { + spi_ctrlr0 &= ~DW_HSSI_SPI_CTRLR0_WAIT_CYCLE_MASK; + spi_ctrlr0 &= ~DW_HSSI_SPI_CTRLR0_INST_L_MASK; + spi_ctrlr0 &= ~DW_HSSI_SPI_CTRLR0_ADDR_L_MASK; + spi_ctrlr0 &= ~DW_HSSI_SPI_CTRLR0_CLK_STRETCH_EN; + } + + dw_writel(dws, DW_HSSI_SPI_CTRLR0, spi_ctrlr0); +} + /* * The SPI memory operation implementation below is the best choice for the * devices, which are selected by the native chip-select lane. It's @@ -738,6 +764,9 @@ static int dw_spi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) dw_spi_enable_chip(dws, 0); + if (dws->caps & DW_SPI_CAP_EXT_SPI) + update_spi_ctrl0(dws, op, enhanced_spi); + dw_spi_update_config(dws, mem->spi, &cfg); dw_spi_mask_intr(dws, 0xff); -- 2.30.2