Skip to content

drivers: flash: stm32_qspi: Fix configuration & erase in dual-flash mode #93234

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

taltenbach
Copy link
Contributor

@taltenbach taltenbach commented Jul 17, 2025

When dual-flash mode is enabled, two identical flash memories are connected to the QUADSPI peripheral and are accessed in parallel. This means in particular that:

  • Both flash memories must be configured the same way, so any write performed to the status register of a given flash memory must also be performed for the other flash memory.
  • When performing a program or erase operation, the flash driver must wait for the operation to complete on both flash memories by polling both status registers.
  • Page and erase size are doubled.

That was not properly handled by the QSPI flash driver, which might lead to errors when reading, erasing or programming data. In particular, this fixes #93153.

The changes were tested on a STM32H747I-DISCO board, in both single- and dual-flash configuration. It was ensured that the drivers/spi_flash sample runs without errors and that the status register can be properly read/written.

In multiple places, "#if DT_PROP(DT_NODELABEL(quadspi), dual_flash) &&
defined(QUADSPI_CR_DFM)" was used to guard sections specific to
the dual-flash feature. This is quite long and "#ifdef
STM32_QSPI_DOUBLE_FLASH" is now used instead.

Note the presence of QUADSPI_CR_DFM is no more checked. This is not
considered as an issue since when QUADSPI_CR_DFM is not available, the
QSPI hardware doesn't support dual-flash mode so this mode must not be
enabled in the devicetree. With that change, enabling dual-flash mode
when not available causes a compile-time error.

Signed-off-by: Thomas Altenbach <[email protected]>
@taltenbach
Copy link
Contributor Author

cc @erwango @FRASTM

Copy link
Contributor

@FRASTM FRASTM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for fixing
The samples/drivers/spi_flash passed in indirect or memory Mapped mode on a dual quad-SPI flash stm32 target

The 'qspi_read_status_register' routine implements the reading of a
flash memory's status register. This routine is used anytime reading a
status register is needed, except in 'qspi_wait_until_ready'. This
commit moves the read routine to be able to use it in
'qspi_wait_until_ready'. The 'qspi_write_status_register' is also moved
to keep it close to the read routine.

Signed-off-by: Thomas Altenbach <[email protected]>
@taltenbach taltenbach force-pushed the fix/stm32-qspi-dual-flash-erase branch from 85fc57d to e0ff9ed Compare July 17, 2025 11:11
@zephyrbot zephyrbot requested a review from etienne-lms July 17, 2025 11:12
@taltenbach
Copy link
Contributor Author

@FRASTM Thanks for reviewing and testing! I applied your suggestion :)

@taltenbach taltenbach force-pushed the fix/stm32-qspi-dual-flash-erase branch from e0ff9ed to 711add0 Compare July 18, 2025 01:21
@taltenbach
Copy link
Contributor Author

@etienne-lms @GeorgeCGV Suggested changes applied

@taltenbach taltenbach force-pushed the fix/stm32-qspi-dual-flash-erase branch from 711add0 to 677b2be Compare July 18, 2025 12:13
etienne-lms
etienne-lms previously approved these changes Jul 18, 2025
GeorgeCGV
GeorgeCGV previously approved these changes Jul 18, 2025
@taltenbach taltenbach dismissed stale reviews from GeorgeCGV and etienne-lms via 0bef2cb July 21, 2025 23:39
@taltenbach taltenbach force-pushed the fix/stm32-qspi-dual-flash-erase branch from 677b2be to 0bef2cb Compare July 21, 2025 23:39
When dual-flash mode is enabled, two identical flash memories are
connected to the QUADSPI peripheral, each having its own set of
registers. This means that when reading or writing a flash register,
this has to be made for both flash memories.

For example, when reading a status register (1 byte), the QUADSPI
peripheral must be configured to read two bytes of data, which
correspond respectively to the value of the register in the first and
second flash memory. Same thing when writing.

Before this commit, when dual-flash mode was enabled, only the register
of the first flash memory was considered, which means the second flash
memory could be incorrectly configured and that any write/erase
operation could be considered as completed too early, if the operation
takes more time to complete for the second flash memory.

Signed-off-by: Thomas Altenbach <[email protected]>
When dual-flash mode is enabled, even bytes are written to the first
flash memory and odd bytes to the second flash memory. This means, from
the flash driver's point of view, the size of a flash page is twice the
size of a single flash memory's page.

So if each flash memory has 256-byte pages, 512 bytes should be used as
page size by the flash driver. Using 256 bytes was working fine but is
suboptimal.

Signed-off-by: Thomas Altenbach <[email protected]>
When dual-flash mode is enabled, any erase operation is executed on both
flash memories in parallel. This means from the flash driver's point of
view, the size of a given sector/block is twice the size of a
sector/block on a single flash memory.

For example, assuming 4-KiB sectors for each flash memory, if the flash
driver is asked to erase at address 0x0000, the erase size must be a
multiple of 8 KiB since each sector erase operation will cause a 4-KiB
sector to erased in each flash memory.

Before this commit, the doubled erase size was only considered in
'setup_pages_layout'. Now, the actual sizes of the erase operations are
properly set in the flash driver's data and are used everywhere in the
driver.

Signed-off-by: Thomas Altenbach <[email protected]>
When a board contains two identical flash memories configured in
parallel dual-flash mode, the actual sector size is twice the sector
size of a single flash memory. So, assuming 4-KiB sectors for each flash
memory, any erase operation must be 8-KiB aligned.

This commit updates the start offset and sector size in the spi_flash
sample to be properly aligned when a dual-flash configuration is used.

At the moment, this is only supported for STM32-based boards and QSPI
flash memories.

Signed-off-by: Thomas Altenbach <[email protected]>
@taltenbach taltenbach force-pushed the fix/stm32-qspi-dual-flash-erase branch from 0bef2cb to 73ebf16 Compare July 21, 2025 23:44
Copy link

@JarmouniA JarmouniA added the backport v4.2-branch Request backport to the v4.2-branch label Jul 22, 2025
@erwango erwango removed the backport v4.2-branch Request backport to the v4.2-branch label Jul 23, 2025
@erwango
Copy link
Member

erwango commented Jul 23, 2025

Removing the backport tag. Eventhough it has been carefully and reviewed, I prefer to remain on the safe side and avoid disturbing v4.2.0 with this for now.
I'd be open to backport after a while, once we'll have evidence it has been used widely w/o trouble.

@erwango erwango assigned erwango and unassigned tbursztyka Jul 23, 2025
@kartben kartben merged commit b7967f7 into zephyrproject-rtos:main Jul 23, 2025
35 of 37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

stm32h747 dual quad-flash reading failure
8 participants