Port these commits: - v6.11-rc5-90-g329ca3eed4a9a ("spi: atmel-quadspi: Avoid overwriting delay register settings") - v6.12-rc1-1-g162d9b5d2308c ("spi: atmel-quadspi: Fix wrong register value written to MR"). - v6.13-rc2-27-gf663898d047a7 ("spi: atmel-quadspi: Factor out switching to Serial Memory Mode to function")
Cc: Csókás Bence <csokas.be...@prolan.hu> Signed-off-by: Alexander Dahl <a...@thorsis.com> --- drivers/spi/atmel-quadspi.c | 96 ++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c index ea045acab65..9e596b7448c 100644 --- a/drivers/spi/atmel-quadspi.c +++ b/drivers/spi/atmel-quadspi.c @@ -395,6 +395,26 @@ static void atmel_qspi_write(u32 value, struct atmel_qspi *aq, u32 offset) writel(value, aq->regs + offset); } +static int atmel_qspi_reg_sync(struct atmel_qspi *aq) +{ + u32 val; + + return readl_poll_timeout(aq->regs + QSPI_SR2, val, + !(val & QSPI_SR2_SYNCBSY), + ATMEL_QSPI_SYNC_TIMEOUT); +} + +static int atmel_qspi_update_config(struct atmel_qspi *aq) +{ + int ret; + + ret = atmel_qspi_reg_sync(aq); + if (ret) + return ret; + atmel_qspi_write(QSPI_CR_UPDCFG, aq, QSPI_CR); + return atmel_qspi_reg_sync(aq); +} + static inline bool atmel_qspi_is_compatible(const struct spi_mem_op *op, const struct atmel_qspi_mode *mode) { @@ -458,6 +478,25 @@ static bool atmel_qspi_supports_op(struct spi_slave *slave, return true; } +/* + * If the QSPI controller is set in regular SPI mode, set it in + * Serial Memory Mode (SMM). + */ +static int atmel_qspi_set_serial_memory_mode(struct atmel_qspi *aq) +{ + int ret = 0; + + if (!(aq->mr & QSPI_MR_SMM)) { + aq->mr |= QSPI_MR_SMM; + atmel_qspi_write(aq->mr, aq, QSPI_MR); + + if (aq->caps->has_gclk) + ret = atmel_qspi_update_config(aq); + } + + return ret; +} + static int atmel_qspi_set_cfg(struct atmel_qspi *aq, const struct spi_mem_op *op, u32 *offset) { @@ -537,14 +576,9 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq, ifr |= QSPI_IFR_TFRTYP_MEM; } - /* - * If the QSPI controller is set in regular SPI mode, set it in - * Serial Memory Mode (SMM). - */ - if (aq->mr != QSPI_MR_SMM) { - atmel_qspi_write(QSPI_MR_SMM, aq, QSPI_MR); - aq->mr = QSPI_MR_SMM; - } + mode = atmel_qspi_set_serial_memory_mode(aq); + if (mode < 0) + return mode; /* Clear pending interrupts */ (void)atmel_qspi_read(aq, QSPI_SR); @@ -598,26 +632,6 @@ static int atmel_qspi_transfer(struct atmel_qspi *aq, ATMEL_QSPI_TIMEOUT); } -static int atmel_qspi_reg_sync(struct atmel_qspi *aq) -{ - u32 val; - - return readl_poll_timeout(aq->regs + QSPI_SR2, val, - !(val & QSPI_SR2_SYNCBSY), - ATMEL_QSPI_SYNC_TIMEOUT); -} - -static int atmel_qspi_update_config(struct atmel_qspi *aq) -{ - int ret; - - ret = atmel_qspi_reg_sync(aq); - if (ret) - return ret; - atmel_qspi_write(QSPI_CR_UPDCFG, aq, QSPI_CR); - return atmel_qspi_reg_sync(aq); -} - static int atmel_qspi_sama7g5_set_cfg(struct atmel_qspi *aq, const struct spi_mem_op *op, u32 *offset) { @@ -669,17 +683,9 @@ static int atmel_qspi_sama7g5_set_cfg(struct atmel_qspi *aq, ifr |= QSPI_IFR_TFRTYP_MEM; } - /* - * If the QSPI controller is set in regular SPI mode, set it in - * Serial Memory Mode (SMM). - */ - if (aq->mr != QSPI_MR_SMM) { - atmel_qspi_write(QSPI_MR_SMM | QSPI_MR_DQSDLYEN, aq, QSPI_MR); - ret = atmel_qspi_update_config(aq); - if (ret) - return ret; - aq->mr = QSPI_MR_SMM; - } + ret = atmel_qspi_set_serial_memory_mode(aq); + if (ret < 0) + return ret; /* Clear pending interrupts */ (void)atmel_qspi_read(aq, QSPI_SR); @@ -903,11 +909,10 @@ static int atmel_qspi_sama7g5_set_speed(struct udevice *bus, uint hz) } /* Set the QSPI controller by default in Serial Memory Mode */ - atmel_qspi_write(QSPI_MR_SMM | QSPI_MR_DQSDLYEN, aq, QSPI_MR); - ret = atmel_qspi_update_config(aq); - if (ret) + aq->mr |= QSPI_MR_DQSDLYEN; + ret = atmel_qspi_set_serial_memory_mode(aq); + if (ret < 0) return ret; - aq->mr = QSPI_MR_SMM; /* Enable the QSPI controller. */ ret = atmel_qspi_reg_sync(aq); @@ -1048,8 +1053,9 @@ static int atmel_qspi_init(struct atmel_qspi *aq) atmel_qspi_write(QSPI_CR_SWRST, aq, QSPI_CR); /* Set the QSPI controller by default in Serial Memory Mode */ - atmel_qspi_write(QSPI_MR_SMM, aq, QSPI_MR); - aq->mr = QSPI_MR_SMM; + ret = atmel_qspi_set_serial_memory_mode(aq); + if (ret < 0) + return ret; /* Enable the QSPI controller */ atmel_qspi_write(QSPI_CR_QSPIEN, aq, QSPI_CR); -- 2.39.5