Skip to content

Conversation

@ExaltZephyr
Copy link
Contributor

@ExaltZephyr ExaltZephyr commented Sep 28, 2025

This PR introduces support for MSPI driver on STM32, enabling functionality APIs for MSPI host controllers.

  1. mspi_stm32_xspi driver

    • support xspi
    • tested using stm32h573i_dk and stm32h7s78_dk boards
    • functionalities:
      • Indirect Mode (read, write and erase).
      • DTR support.
      • Memory map mode (read and write).
      • xip configuration.
      • DMA Mode
      • Zephyr Power Management Support
  2. ospi_stm32 driver

    • support octospi
    • tested using stm32h735g_disco and b_u585i_iot02a
    • functionalities:
      • Indirect mode (read, write and erase)
      • DTR support
      • Memory map mode (read b_u585i_iot02a board)
      • xip configuration
      • DMA transfer (b_u585i_iot02a board)
      • zephyr power management support
  3. mspi_stm32_qspi driver

    • support quadspi
    • tested using arduino_giga_r1/stm32h747xx/m7 and stm32l496g_disco
    • functionalities:
      • Indirect mode (read, write and erase) with MSPI_IO_MODE_SINGLE, MSPI_IO_MODE_QUAD_1_1_4, and MSPI_IO_MODE_QUAD_1_4_4
      • Memory map mode (read)
      • xip configuration
      • DMA transfer (stm32l496g_disco)
      • Zephyr Power Management Support

Notes:

  • This PR was tested with JEDEC flash drivers and has not been tested with PSRAM.
  • mspi_stm32_xspi driver - DMA mode here was tested using stm32h573i_dk board only since no zephyr dma support on stm32h7s78_dk

@ExaltZephyr ExaltZephyr force-pushed the stm32-mspi-support branch 8 times, most recently from 834dc73 to 7e8241c Compare September 29, 2025 11:59
@FRASTM FRASTM mentioned this pull request Sep 30, 2025
4 tasks
@ExaltZephyr ExaltZephyr force-pushed the stm32-mspi-support branch 6 times, most recently from ed327ea to a09a921 Compare October 2, 2025 14:03
Copy link
Member

Choose a reason for hiding this comment

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

Please rename to dts/bindings/mspi/st,stm32-xspi-controller.yaml MSPI is the subsytem api and XSPI is the ST IP name.
Apply everywhere (driver files, ....) on this PR..

For example
dma-names = "tx_rx";

ssht-enable:
Copy link
Member

@erwango erwango Oct 2, 2025

Choose a reason for hiding this comment

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

For the three IPs, these bindings will have to propose the same configuration options as the union of dts/bindings/memory-controllers/st,stm32-xspi-psram.yaml and dts/bindings/flash_controller/st,stm32-xspi-nor.yaml

Copy link
Member

Choose a reason for hiding this comment

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

Note that this may potentially be done as a follow up PR

@ExaltZephyr ExaltZephyr force-pushed the stm32-mspi-support branch 9 times, most recently from e0849ca to 806f0f8 Compare October 6, 2025 12:23
@erwango erwango requested a review from Copilot October 6, 2025 12:25
@ExaltZephyr ExaltZephyr force-pushed the stm32-mspi-support branch 3 times, most recently from fc323fc to 6cf8d2c Compare November 18, 2025 13:35
Comment on lines 6 to 19
Enabling a stm32 xspi node in a board
description would typically requires this: (pinning depends on the stm32 mcu)
&xspi {
pinctrl-0 = <&octospi_clk_pe9 &octospi_ncs_pe10 &octospi_dqs_pe11
&octospi_io0_pe12 &octospi_io1_pe13
&octospi_io2_pe14 &octospi_io3_pe15
&octospi_io4_pe16 &octospi_io5_pe17
&octospi_io6_pe18 &octospi_io7_pe19>;
pinctrl-names = "default";
status = "okay";
};
Copy link
Member

Choose a reason for hiding this comment

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

This is not fully correct as you omit the dtsi part of the node. Pinning doesn't depends on the mcu, but depends on the board, ....
I would fully remove this part to avoid discussions on that part which will be long to get agreed by everyone.

Comment on lines +26 to +28
reg:
required: true

interrupts:
required: true

pinctrl-0:
required: true

pinctrl-names:
required: true

clocks:
required: true

clock-names:
required: true
Copy link
Member

Choose a reason for hiding this comment

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

Most of those are already part of the includes above. Please clean up.

Copy link
Contributor Author

@ExaltZephyr ExaltZephyr Nov 19, 2025

Choose a reason for hiding this comment

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

@erwango
yes correct but here I just marked them as required since in include files they are not marked as required
what do you think ?

# Copyright (c) 2025 STMicroelectronics
# SPDX-License-Identifier: Apache-2.0

config MSPI_STM32_XSPI
Copy link
Member

Choose a reason for hiding this comment

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

Please sort alphabetically whenvener it is possible.

Comment on lines 77 to 84
#ifdef CONFIG_MSPI_STM32_XSPI
XSPI_HandleTypeDef xspi;
#endif
#ifdef CONFIG_MSPI_STM32_OSPI
OSPI_HandleTypeDef ospi;
#endif
#ifdef CONFIG_MSPI_STM32_QSPI
QSPI_HandleTypeDef qspi;
Copy link
Member

Choose a reason for hiding this comment

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

Ditto on alphabetical sorting

Comment on lines 26 to 48
#ifndef LL_DMA_SRC_DATAWIDTH_BYTE
#define LL_DMA_SRC_DATAWIDTH_BYTE LL_DMA_MDATAALIGN_BYTE
#endif

#ifndef LL_DMA_SRC_DATAWIDTH_HALFWORD
#define LL_DMA_SRC_DATAWIDTH_HALFWORD LL_DMA_MDATAALIGN_HALFWORD
#endif

#ifndef LL_DMA_SRC_DATAWIDTH_WORD
#define LL_DMA_SRC_DATAWIDTH_WORD LL_DMA_MDATAALIGN_WORD
#endif

#ifndef LL_DMA_DEST_DATAWIDTH_BYTE
#define LL_DMA_DEST_DATAWIDTH_BYTE LL_DMA_PDATAALIGN_BYTE
#endif

#ifndef LL_DMA_DEST_DATAWIDTH_HALFWORD
#define LL_DMA_DEST_DATAWIDTH_HALFWORD LL_DMA_PDATAALIGN_HALFWORD
#endif

#ifndef LL_DMA_DEST_DATAWIDTH_WORD
#define LL_DMA_DEST_DATAWIDTH_WORD LL_DMA_PDATAALIGN_WORD
#endif
Copy link
Member

Choose a reason for hiding this comment

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

Please avoid redefining LL symbols, but use new symbols instead.

Copy link
Member

Choose a reason for hiding this comment

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

Is this file really useful vs already available mspi_stm32.h ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ys, it's needed to define global arrays mspi_stm32_table_...[].

return ret;
}

if (IS_ENABLED(MSPI_STM32_DOMAIN_CLOCK_SUPPORT) && (config->pclk_len > 1)) {
Copy link
Member

Choose a reason for hiding this comment

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

Let's remove use of MSPI_STM32_DOMAIN_CLOCK_SUPPORT in the driver. It's bringing confusion and saving implied is neglectible vs the size of the driver.

*/

#ifndef __SPI_NOR_H__
#define __SPI_NOR_H__
Copy link
Contributor

Choose a reason for hiding this comment

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

#ifndef ZEPHYR_INCLUDE_DRIVERS_SPI_SPI_NOR_H_
#define ZEPHYR_INCLUDE_DRIVERS_SPI_SPI_NOR_H_

#define SPI_NOR_IS_32K_ALIGNED(_ofs) SPI_NOR_IS_ALIGNED(_ofs, 15)
#define SPI_NOR_IS_64K_ALIGNED(_ofs) SPI_NOR_IS_ALIGNED(_ofs, 16)

#define CMD_RDCR 0x15 /* Read the configuration register. */
Copy link
Contributor

Choose a reason for hiding this comment

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

For consistency, this macro should be renamed SPI_NOR_CMD_RDCR.

For that purpose, I think you can squash commits "include: spi: Move spi_nor.h to include folder"
and "drivers: flash: Adjust include paths for spi_nor.h".

Copy link
Contributor

Choose a reason for hiding this comment

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

Ys, it's needed to define global arrays mspi_stm32_table_...[].

return ret;
}

OSPI_RegularCmdTypeDef s_command = mspi_stm32_ospi_prepare_cmd(cfg_mode, cfg_rate);
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add an empty line below this local variable definition?


/* For ASYNC mode, wait for IRQ completion (PM locks released in ISR) */
if (k_sem_take(&dev_data->sync, K_FOREVER) < 0) {
LOG_ERR("Failed to complete async transfer");
Copy link
Contributor

Choose a reason for hiding this comment

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

		pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
		(void)pm_device_runtime_put(dev);


if (mspi_stm32_xspi_is_inp(controller)) {
ret = -EBUSY;
goto e_return;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can put PM ressource at this stage (as done at e_return branch label).

/* Lock with the expected timeout value = ctx->xfer.timeout */
ret = mspi_stm32_ospi_context_lock(ctx, dev_data->dev_id, xfer, true);
if (ret != 0) {
goto status_end;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should not call k_sem_give(&ctx->lock) at function exit.

Suggestion:

static int mspi_stm32_ospi_status_reg(const struct device *controller, const struct mspi_xfer *xfer)
{
	// here, return straight upon error

	(void)pm_device_runtime_get(controller);
	pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);

	// here `goto pm_put` upon error

	ret = mspi_stm32_ospi_context_lock(ctx, dev_data->dev_id, xfer, true);

	// here `goto ctx_unlock` upon error

ctx_unlock:
	k_sem_give(&ctx->lock);
pm_put:
	pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
	(void)pm_device_runtime_put(controller);

	return ret;
}

See also the QSPI and XSPI drivers for equivalent issues.

status_end:
pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
(void)pm_device_runtime_put(controller);
k_sem_give(&ctx->lock);
Copy link
Contributor

Choose a reason for hiding this comment

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

To here finding where context lock is locked/taken and unlocked/given, I think it would help to have a helper function that matches mspi_stm32_ospi_context_lock():

static inline void mspi_stm32_ospi_context_unlock(struct mspi_stm32_context *ctx)
{
	k_sem_give(&ctx->lock);
}

Ditto in QSPI and XSPI drivers.

@zephyrbot zephyrbot requested a review from erwango November 19, 2025 08:12
@ExaltZephyr ExaltZephyr force-pushed the stm32-mspi-support branch 2 times, most recently from a6d3767 to c1ceacb Compare November 19, 2025 10:03
This commit moves spi_nor.h from drivers/flash
to include/drivers/spi directory and updates
affected flash drivers with new include path

Signed-off-by: Sara Touqan <[email protected]>
Signed-off-by: Sarah Younis <[email protected]>
Signed-off-by: Mohammad Odeh <[email protected]>
Copy link
Contributor

@tpambor tpambor left a comment

Choose a reason for hiding this comment

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

We are looking to use this driver together with a PSRAM, which would require support for MSPI_DATA_RATE_S_D_D. Maybe you could also support these modes.

? HAL_XSPI_INSTRUCTION_DTR_ENABLE
: HAL_XSPI_INSTRUCTION_DTR_DISABLE;
cmd_tmp.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
cmd_tmp.AddressDTRMode = (cfg_rate == MSPI_DATA_RATE_DUAL) ? HAL_XSPI_ADDRESS_DTR_ENABLE
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
cmd_tmp.AddressDTRMode = (cfg_rate == MSPI_DATA_RATE_DUAL) ? HAL_XSPI_ADDRESS_DTR_ENABLE
cmd_tmp.AddressDTRMode = ((cfg_rate == MSPI_DATA_RATE_DUAL) || (cfg_rate == MSPI_DATA_RATE_S_D_D)) ? HAL_XSPI_ADDRESS_DTR_ENABLE

: HAL_XSPI_DATA_DTR_DISABLE;
/* AddressWidth must be set to 32bits for init and mem config phase */
cmd_tmp.AddressWidth = HAL_XSPI_ADDRESS_32_BITS;
cmd_tmp.DataDTRMode = (cfg_rate == MSPI_DATA_RATE_DUAL) ? HAL_XSPI_DATA_DTR_ENABLE
Copy link
Contributor

@tpambor tpambor Nov 19, 2025

Choose a reason for hiding this comment

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

Suggested change
cmd_tmp.DataDTRMode = (cfg_rate == MSPI_DATA_RATE_DUAL) ? HAL_XSPI_DATA_DTR_ENABLE
cmd_tmp.DataDTRMode = (cfg_rate != MSPI_DATA_RATE_SINGLE) ? HAL_XSPI_DATA_DTR_ENABLE

cmd_tmp.DataDTRMode = (cfg_rate == MSPI_DATA_RATE_DUAL) ? HAL_XSPI_DATA_DTR_ENABLE
: HAL_XSPI_DATA_DTR_DISABLE;
cmd_tmp.DQSMode =
(cfg_rate == MSPI_DATA_RATE_DUAL) ? HAL_XSPI_DQS_ENABLE : HAL_XSPI_DQS_DISABLE;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
(cfg_rate == MSPI_DATA_RATE_DUAL) ? HAL_XSPI_DQS_ENABLE : HAL_XSPI_DQS_DISABLE;
(cfg_rate != MSPI_DATA_RATE_SINGLE) ? HAL_XSPI_DQS_ENABLE : HAL_XSPI_DQS_DISABLE;

@erwango
Copy link
Member

erwango commented Nov 19, 2025

We are looking to use this driver together with a PSRAM, which would require support for MSPI_DATA_RATE_S_D_D. Maybe you could also support these modes.

This could also be added later. I prefer we get a more simple version soon, on which contributions could be made.

Comment on lines +12 to +22
/* Macro to check if any xspi device has a domain clock or more */
#define MSPI_STM32_DOMAIN_CLOCK_INST_SUPPORT(inst) DT_CLOCKS_HAS_IDX(DT_INST_PARENT(inst), 1) ||
#define MSPI_STM32_INST_DEV_DOMAIN_CLOCK_SUPPORT \
(DT_INST_FOREACH_STATUS_OKAY(MSPI_STM32_DOMAIN_CLOCK_INST_SUPPORT) 0)

/* This symbol takes the value 1 if device instance has a domain clock in its dts */
#if MSPI_STM32_INST_DEV_DOMAIN_CLOCK_SUPPORT
#define MSPI_STM32_DOMAIN_CLOCK_SUPPORT 1
#else
#define MSPI_STM32_DOMAIN_CLOCK_SUPPORT 0
#endif
Copy link
Member

Choose a reason for hiding this comment

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

Not required anymore (to be cleaned up from all O/Q/X drivers variants.

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.

Maybe moving this spi_nor.h header file could have its own PR ?

@ExaltZephyr
Copy link
Contributor Author

Maybe moving this spi_nor.h header file could have its own PR ?

@etienne-lms is it ok with you to revert the commit of moving spi_nor.h and then later another PR can be opened?

@erwango
Copy link
Member

erwango commented Nov 19, 2025

@etienne-lms is it ok with you to revert the commit of moving spi_nor.h and then later another PR can be opened?

I think that the point of @FRASTM was not to do it later, but before.
So request is to split it in another PR now and it will be merged before current PR.

@etienne-lms
Copy link
Contributor

I think that the point of @FRASTM was not to do it later, but before.
So request is to split it in another PR now and it will be merged before current PR.

I agree. It would allow the SPI maintainer (@swift-tk) to explicitly agree (or not) on this change.
Unless @swift-tk you're ok with such a change and agree it's reviewed and merged as part of the MSPI P-R.

This commit adds the main DTS configurations required
to enable MSPI/OSPI/QSPI support on STM32.

Signed-off-by: Sara Touqan <[email protected]>
Signed-off-by: Sarah Younis <[email protected]>
Signed-off-by: Mohammad Odeh <[email protected]>
This commit introduces support for the mspi and ospi drivers on STM32,
enabling functionality APIs for MSPI/OSPI/QSPI host controllers..

Signed-off-by: Sara Touqan <[email protected]>
Signed-off-by: Sarah Younis <[email protected]>
Signed-off-by: Mohammad Odeh <[email protected]>
@ExaltZephyr
Copy link
Contributor Author

I think that the point of @FRASTM was not to do it later, but before.
So request is to split it in another PR now and it will be merged before current PR.

I agree. It would allow the SPI maintainer (@swift-tk) to explicitly agree (or not) on this change. Unless @swift-tk you're ok with such a change and agree it's reviewed and merged as part of the MSPI P-R.

ok then we can open new PR for this header change.
@swift-tk ok with you ?

this commit enables building and running the sample on
stm32h573i_dk board,stm32h735g_disco board, arduino_giga_r1
board, and  b_u585i_iot02a board by providing the required overlay
and configuration updates.

Signed-off-by: Sara Touqan <[email protected]>
Signed-off-by: Sarah Younis <[email protected]>
Signed-off-by: Mohammad Odeh <[email protected]>
@ExaltZephyr
Copy link
Contributor Author

Updated PR description to add DMA support for QSPI driver. Tested on STM32L496G-DISCO.

@sonarqubecloud
Copy link

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.

8 participants