Skip to content

Commit 9745d3a

Browse files
committed
drivers: mspi: Support MSPI driver for STM32
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]>
1 parent eb710ae commit 9745d3a

File tree

8 files changed

+5183
-1
lines changed

8 files changed

+5183
-1
lines changed

drivers/mspi/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ zephyr_library_sources_ifdef(CONFIG_MSPI_AMBIQ_AP5 mspi_ambiq_ap5.c)
1010
zephyr_library_sources_ifdef(CONFIG_MSPI_AMBIQ_TIMING_SCAN mspi_ambiq_timing_scan.c)
1111
zephyr_library_sources_ifdef(CONFIG_MSPI_DW mspi_dw.c)
1212
zephyr_library_sources_ifdef(CONFIG_MSPI_EMUL mspi_emul.c)
13+
zephyr_library_sources_ifdef(CONFIG_MSPI_STM32_OSPI mspi_stm32_ospi.c mspi_stm32_common.c)
14+
zephyr_library_sources_ifdef(CONFIG_MSPI_STM32_QSPI mspi_stm32_qspi.c mspi_stm32_common.c)
15+
zephyr_library_sources_ifdef(CONFIG_MSPI_STM32_XSPI mspi_stm32_xspi.c mspi_stm32_common.c)
1316
# zephyr-keep-sorted-stop

drivers/mspi/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,6 @@ source "subsys/logging/Kconfig.template.log_config"
6969
source "drivers/mspi/Kconfig.ambiq"
7070
source "drivers/mspi/Kconfig.dw"
7171
source "drivers/mspi/Kconfig.mspi_emul"
72+
source "drivers/mspi/Kconfig.stm32"
7273
# zephyr-keep-sorted-stop
73-
7474
endif # MSPI

drivers/mspi/Kconfig.stm32

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# STM32 MSPI flash driver configuration options
2+
3+
# Copyright (c) 2025 STMicroelectronics
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
config MSPI_STM32_XSPI
7+
bool "STM32 XSPI Controller driver"
8+
depends on DT_HAS_ST_STM32_XSPI_CONTROLLER_ENABLED
9+
default y
10+
select USE_STM32_HAL_XSPI
11+
select USE_STM32_LL_DLYB
12+
select DMA
13+
select USE_STM32_HAL_DMA
14+
select USE_STM32_HAL_DMA_EX
15+
help
16+
Enable XSPI driver for STM32 family of processors.
17+
18+
config MSPI_STM32_QSPI
19+
bool "STM32 QSPI Controller driver"
20+
depends on DT_HAS_ST_STM32_QSPI_CONTROLLER_ENABLED
21+
default y
22+
select USE_STM32_HAL_QSPI
23+
select DMA
24+
select USE_STM32_HAL_DMA
25+
select USE_STM32_HAL_DMA_EX
26+
select USE_STM32_HAL_MDMA
27+
help
28+
Enable QSPI driver for STM32 family of processors.
29+
30+
config MSPI_STM32_OSPI
31+
bool "STM32 OSPI Controller driver"
32+
depends on DT_HAS_ST_STM32_OSPI_CONTROLLER_ENABLED
33+
default y
34+
select USE_STM32_HAL_OSPI if !SOC_SERIES_STM32H5X
35+
select USE_STM32_LL_DLYB if (SOC_SERIES_STM32H5X || SOC_SERIES_STM32U5X)
36+
select USE_STM32_HAL_MDMA if SOC_SERIES_STM32H7X
37+
select DMA
38+
select USE_STM32_HAL_DMA
39+
select USE_STM32_HAL_DMA_EX
40+
help
41+
Enable OSPI driver for STM32 family of processors.
42+
43+
config MSPI_STM32_BUFFER_ALIGNMENT
44+
int
45+
default 32
46+
help
47+
Some MSPI host controllers require alignment of their data buffers
48+
in order for DMA to work correctly. This represents the alignment
49+
of buffers required in bytes.
50+
51+
config MSPI_STM32_ALLOW_WRITE_IN_MEMMAP
52+
bool "Allow write in MEMMAP mode"
53+
help
54+
Some MSPI host controllers allow to write in memory map mode.

drivers/mspi/mspi_stm32.h

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright (c) 2025 EXALT Technologies.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_DRIVERS_MSPI_MSPI_STM32_H_
8+
#define ZEPHYR_DRIVERS_MSPI_MSPI_STM32_H_
9+
10+
#include <zephyr/drivers/spi/spi_nor.h>
11+
12+
/* Macro to check if any xspi device has a domain clock or more */
13+
#define MSPI_STM32_DOMAIN_CLOCK_INST_SUPPORT(inst) DT_CLOCKS_HAS_IDX(DT_INST_PARENT(inst), 1) ||
14+
#define MSPI_STM32_INST_DEV_DOMAIN_CLOCK_SUPPORT \
15+
(DT_INST_FOREACH_STATUS_OKAY(MSPI_STM32_DOMAIN_CLOCK_INST_SUPPORT) 0)
16+
17+
/* This symbol takes the value 1 if device instance has a domain clock in its dts */
18+
#if MSPI_STM32_INST_DEV_DOMAIN_CLOCK_SUPPORT
19+
#define MSPI_STM32_DOMAIN_CLOCK_SUPPORT 1
20+
#else
21+
#define MSPI_STM32_DOMAIN_CLOCK_SUPPORT 0
22+
#endif
23+
24+
#define MSPI_STM32_FIFO_THRESHOLD 4U
25+
#define MSPI_MAX_FREQ 250000000
26+
#define MSPI_MAX_DEVICE 2
27+
28+
#if defined(CONFIG_SOC_SERIES_STM32U5X)
29+
/* Valid range is [1, 256] */
30+
#define MSPI_STM32_CLOCK_PRESCALER_MIN 1U
31+
#define MSPI_STM32_CLOCK_PRESCALER_MAX 256U
32+
#define MSPI_STM32_CLOCK_COMPUTE(bus_freq, prescaler) ((bus_freq) / (prescaler))
33+
#else
34+
/* Valid range is [0, 255] */
35+
#define MSPI_STM32_CLOCK_PRESCALER_MIN 0U
36+
#define MSPI_STM32_CLOCK_PRESCALER_MAX 255U
37+
#define MSPI_STM32_CLOCK_COMPUTE(bus_freq, prescaler) ((bus_freq) / ((prescaler) + 1U))
38+
#endif
39+
40+
#define MSPI_STM32_WRITE_REG_MAX_TIME 40U
41+
#define MSPI_STM32_MAX_FREQ 48000000
42+
43+
typedef void (*irq_config_func_t)(void);
44+
45+
enum mspi_stm32_access_mode {
46+
MSPI_ACCESS_ASYNC = 1,
47+
MSPI_ACCESS_SYNC = 2,
48+
MSPI_ACCESS_DMA = 3
49+
};
50+
51+
struct mspi_stm32_context {
52+
struct mspi_xfer xfer;
53+
int packets_left;
54+
struct k_sem lock;
55+
};
56+
57+
struct mspi_stm32_conf {
58+
bool dma_specified;
59+
size_t pclk_len;
60+
irq_config_func_t irq_config;
61+
struct mspi_cfg mspicfg;
62+
const struct stm32_pclken *pclken;
63+
const struct pinctrl_dev_config *pcfg;
64+
};
65+
66+
struct stm32_stream {
67+
DMA_TypeDef *reg;
68+
const struct device *dev;
69+
uint32_t channel;
70+
struct dma_config cfg;
71+
uint8_t priority;
72+
bool src_addr_increment;
73+
bool dst_addr_increment;
74+
};
75+
76+
union mspi_stm32_handle {
77+
#ifdef CONFIG_MSPI_STM32_XSPI
78+
XSPI_HandleTypeDef xspi;
79+
#endif
80+
#ifdef CONFIG_MSPI_STM32_OSPI
81+
OSPI_HandleTypeDef ospi;
82+
#endif
83+
#ifdef CONFIG_MSPI_STM32_QSPI
84+
QSPI_HandleTypeDef qspi;
85+
#endif
86+
};
87+
88+
/* mspi data includes the controller specific config variable */
89+
struct mspi_stm32_data {
90+
union mspi_stm32_handle hmspi;
91+
uint32_t memmap_base_addr;
92+
struct mspi_stm32_context ctx;
93+
struct mspi_dev_id *dev_id;
94+
struct k_mutex lock;
95+
struct k_sem sync;
96+
struct mspi_dev_cfg dev_cfg;
97+
struct mspi_xip_cfg xip_cfg;
98+
struct stm32_stream dma_tx;
99+
struct stm32_stream dma_rx;
100+
struct stm32_stream dma;
101+
#ifdef CONFIG_MSPI_STM32_XSPI
102+
DMA_HandleTypeDef hdma_tx;
103+
DMA_HandleTypeDef hdma_rx;
104+
#endif
105+
#ifdef CONFIG_MSPI_STM32_OSPI
106+
DMA_HandleTypeDef hdma;
107+
#endif
108+
};
109+
110+
extern const uint32_t mspi_stm32_table_priority[];
111+
extern const uint32_t mspi_stm32_table_direction[];
112+
extern const uint32_t mspi_stm32_table_src_size[];
113+
extern const uint32_t mspi_stm32_table_dest_size[];
114+
115+
#endif /* ZEPHYR_DRIVERS_MSPI_MSPI_STM32_H_ */

drivers/mspi/mspi_stm32_common.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2025 EXALT Technologies.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/types.h>
8+
#include <stm32_ll_dma.h>
9+
10+
#ifndef DMA_LOW_PRIORITY_LOW_WEIGHT
11+
#define DMA_LOW_PRIORITY_LOW_WEIGHT DMA_PRIORITY_LOW
12+
#endif
13+
14+
#ifndef DMA_LOW_PRIORITY_MID_WEIGHT
15+
#define DMA_LOW_PRIORITY_MID_WEIGHT DMA_PRIORITY_MEDIUM
16+
#endif
17+
18+
#ifndef DMA_LOW_PRIORITY_HIGH_WEIGHT
19+
#define DMA_LOW_PRIORITY_HIGH_WEIGHT DMA_PRIORITY_HIGH
20+
#endif
21+
22+
#ifndef DMA_HIGH_PRIORITY
23+
#define DMA_HIGH_PRIORITY DMA_PRIORITY_VERY_HIGH
24+
#endif
25+
26+
#ifndef LL_DMA_SRC_DATAWIDTH_BYTE
27+
#define LL_DMA_SRC_DATAWIDTH_BYTE LL_DMA_MDATAALIGN_BYTE
28+
#endif
29+
30+
#ifndef LL_DMA_SRC_DATAWIDTH_HALFWORD
31+
#define LL_DMA_SRC_DATAWIDTH_HALFWORD LL_DMA_MDATAALIGN_HALFWORD
32+
#endif
33+
34+
#ifndef LL_DMA_SRC_DATAWIDTH_WORD
35+
#define LL_DMA_SRC_DATAWIDTH_WORD LL_DMA_MDATAALIGN_WORD
36+
#endif
37+
38+
#ifndef LL_DMA_DEST_DATAWIDTH_BYTE
39+
#define LL_DMA_DEST_DATAWIDTH_BYTE LL_DMA_PDATAALIGN_BYTE
40+
#endif
41+
42+
#ifndef LL_DMA_DEST_DATAWIDTH_HALFWORD
43+
#define LL_DMA_DEST_DATAWIDTH_HALFWORD LL_DMA_PDATAALIGN_HALFWORD
44+
#endif
45+
46+
#ifndef LL_DMA_DEST_DATAWIDTH_WORD
47+
#define LL_DMA_DEST_DATAWIDTH_WORD LL_DMA_PDATAALIGN_WORD
48+
#endif
49+
50+
/* Lookup table to set dma priority from the DTS */
51+
const uint32_t mspi_stm32_table_priority[] = {
52+
DMA_LOW_PRIORITY_LOW_WEIGHT,
53+
DMA_LOW_PRIORITY_MID_WEIGHT,
54+
DMA_LOW_PRIORITY_HIGH_WEIGHT,
55+
DMA_HIGH_PRIORITY,
56+
};
57+
58+
/* Lookup table to set dma channel direction from the DTS */
59+
const uint32_t mspi_stm32_table_direction[] = {
60+
DMA_MEMORY_TO_MEMORY,
61+
DMA_MEMORY_TO_PERIPH,
62+
DMA_PERIPH_TO_MEMORY,
63+
};
64+
65+
const uint32_t mspi_stm32_table_src_size[] = {
66+
LL_DMA_SRC_DATAWIDTH_BYTE,
67+
LL_DMA_SRC_DATAWIDTH_HALFWORD,
68+
LL_DMA_SRC_DATAWIDTH_WORD
69+
};
70+
71+
const uint32_t mspi_stm32_table_dest_size[] = {
72+
LL_DMA_DEST_DATAWIDTH_BYTE,
73+
LL_DMA_DEST_DATAWIDTH_HALFWORD,
74+
LL_DMA_DEST_DATAWIDTH_WORD
75+
};

0 commit comments

Comments
 (0)