From 6aeb12d558fd10f3a5dcc518bdfe6f67d14c652f Mon Sep 17 00:00:00 2001 From: Thomas Altenbach Date: Sun, 6 Jul 2025 03:45:01 +0200 Subject: [PATCH] drivers: flash: stm32_qspi: Fix flash not reset when in QPI mode The reset commands were sent only in SPI mode, causing the device not to be properly reset when in QPI mode. On the STM32H747I-DISCO boards, this was causing the driver initialization to fail due to a bad SFDP magic after flashing the external memory using STM32CubeProgrammer since the external loader is configuring the flash memory in QPI mode. The commands are sent in QPI mode first, then in SPI mode: - If the flash memory was in QPI mode, the two first reset commands are processed and after reset, the flash memory is in SPI mode and correctly handles the SPI mode reset commands. - If the flash memory was in SPI mode, for each QPI command the chip select signal will be released before the flash memory had the opportunity to receive a whole command (1 byte), so the partially received commands will be ignored and won't cause any harm. Then, the chip is reset by the commands sent in SPI mode. Signed-off-by: Thomas Altenbach --- drivers/flash/flash_stm32_qspi.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/flash/flash_stm32_qspi.c b/drivers/flash/flash_stm32_qspi.c index 1f5c398a6d4..c955fc9e86c 100644 --- a/drivers/flash/flash_stm32_qspi.c +++ b/drivers/flash/flash_stm32_qspi.c @@ -1402,10 +1402,29 @@ static int flash_stm32_qspi_send_reset(const struct device *dev) { QSPI_CommandTypeDef cmd = { .Instruction = SPI_NOR_CMD_RESET_EN, - .InstructionMode = QSPI_INSTRUCTION_1_LINE, + .InstructionMode = QSPI_INSTRUCTION_4_LINES }; int ret; + /* + * The device might be in SPI or QPI mode, so to ensure the device is properly reset send + * the reset commands in both QPI and SPI modes. + */ + ret = qspi_send_cmd(dev, &cmd); + if (ret != 0) { + LOG_ERR("%d: Failed to send RESET_EN", ret); + return ret; + } + + cmd.Instruction = SPI_NOR_CMD_RESET_MEM; + ret = qspi_send_cmd(dev, &cmd); + if (ret != 0) { + LOG_ERR("%d: Failed to send RESET_MEM", ret); + return ret; + } + + cmd.Instruction = SPI_NOR_CMD_RESET_EN; + cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE; ret = qspi_send_cmd(dev, &cmd); if (ret != 0) { LOG_ERR("%d: Failed to send RESET_EN", ret);