Skip to content

Commit cdb0141

Browse files
ExaltZephyrExaltZephyr
authored andcommitted
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 b621364 commit cdb0141

File tree

7 files changed

+5026
-0
lines changed

7 files changed

+5026
-0
lines changed

drivers/mspi/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,8 @@ zephyr_library_sources_ifdef(CONFIG_MSPI_AMBIQ_AP5 mspi_ambiq_ap5.c)
88
zephyr_library_sources_ifdef(CONFIG_MSPI_AMBIQ_TIMING_SCAN mspi_ambiq_timing_scan.c)
99
zephyr_library_sources_ifdef(CONFIG_MSPI_DW mspi_dw.c)
1010
zephyr_library_sources_ifdef(CONFIG_MSPI_EMUL mspi_emul.c)
11+
zephyr_library_sources_ifdef(CONFIG_MSPI_STM32_OSPI mspi_stm32_ospi.c)
12+
zephyr_library_sources_ifdef(CONFIG_MSPI_STM32_QSPI mspi_stm32_qspi.c)
13+
zephyr_library_sources_ifdef(CONFIG_MSPI_STM32_XSPI mspi_stm32_xspi.c)
14+
15+
zephyr_include_directories(${ZEPHYR_BASE}/drivers/flash)

drivers/mspi/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,6 @@ source "subsys/logging/Kconfig.template.log_config"
6262
source "drivers/mspi/Kconfig.ambiq"
6363
source "drivers/mspi/Kconfig.dw"
6464
source "drivers/mspi/Kconfig.mspi_emul"
65+
source "drivers/mspi/Kconfig.stm32"
6566

6667
endif # MSPI

drivers/mspi/Kconfig.stm32

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
select USE_STM32_HAL_XSPI
10+
select USE_STM32_LL_DLYB
11+
select DMA
12+
select USE_STM32_HAL_DMA
13+
select USE_STM32_HAL_DMA_EX
14+
imply MSPI_XIP
15+
default y
16+
help
17+
Enable driver for STM32 family of processors.
18+
19+
config MSPI_STM32_QSPI
20+
bool "STM32 QSPI Controller driver"
21+
default y
22+
depends on DT_HAS_ST_STM32_QSPI_CONTROLLER_ENABLED
23+
select USE_STM32_HAL_QSPI
24+
select DMA
25+
select USE_STM32_HAL_DMA
26+
select USE_STM32_HAL_DMA_EX
27+
select USE_STM32_HAL_MDMA
28+
imply MSPI_XIP
29+
help
30+
Enable QSPI driver for STM32 family of processors.
31+
32+
#DT_STM32_OCTOSPI_HAS_DMA := $(dt_compat_any_has_prop,$(DT_COMPAT_ST_STM32_OSPI),dmas)
33+
34+
config MSPI_STM32_OSPI
35+
bool "STM32 OSPI Controller driver"
36+
default y
37+
depends on DT_HAS_ST_STM32_OSPI_CONTROLLER_ENABLED
38+
select USE_STM32_HAL_OSPI if !SOC_SERIES_STM32H5X
39+
select USE_STM32_LL_DLYB if (SOC_SERIES_STM32H5X || SOC_SERIES_STM32U5X)
40+
select USE_STM32_HAL_MDMA if SOC_SERIES_STM32H7X
41+
select DMA
42+
select USE_STM32_HAL_DMA
43+
select USE_STM32_HAL_DMA_EX
44+
help
45+
Enable OSPI driver for STM32 family of processors.
46+
47+
config MSPI_BUFFER_ALIGNMENT
48+
int
49+
default 32
50+
help
51+
Some MSPI host controllers require alignment of their data buffers
52+
in order for DMA to work correctly. This represents the alignment
53+
of buffers required in bytes.
54+
55+
config MSPI_STM32_ALLOW_WRITE_IN_MEMMAP
56+
bool "Allow write in MEMMAP mode"
57+
default n
58+
help
59+
Some MSPI host controllers allow to write in memory map mode.

drivers/mspi/mspi_stm32.h

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
* Copyright (c) 2025 EXALT Technologies.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "spi_nor.h"
8+
9+
#ifndef ZEPHYR_DRIVERS_MSPI_STM32_H_
10+
#define ZEPHYR_DRIVERS_MSPI_STM32_H_
11+
/* Macro to check if any xspi device has a domain clock or more */
12+
#define MSPI_STM32_DOMAIN_CLOCK_INST_SUPPORT(inst) DT_CLOCKS_HAS_IDX(DT_INST_PARENT(inst), 1) ||
13+
#define MSPI_STM32_INST_DEV_DOMAIN_CLOCK_SUPPORT \
14+
(DT_INST_FOREACH_STATUS_OKAY(MSPI_STM32_DOMAIN_CLOCK_INST_SUPPORT) 0)
15+
16+
/* This symbol takes the value 1 if device instance has a domain clock in its dts */
17+
#if MSPI_STM32_INST_DEV_DOMAIN_CLOCK_SUPPORT
18+
#define MSPI_STM32_DOMAIN_CLOCK_SUPPORT 1
19+
#else
20+
#define MSPI_STM32_DOMAIN_CLOCK_SUPPORT 0
21+
#endif
22+
23+
#define MSPI_STM32_FIFO_THRESHOLD 4U
24+
#define MSPI_MAX_FREQ 250000000
25+
#define MSPI_MAX_DEVICE 2
26+
27+
#if defined(CONFIG_SOC_SERIES_STM32U5X)
28+
/* Valid range is [1, 256] */
29+
#define MSPI_STM32_CLOCK_PRESCALER_MIN 1U
30+
#define MSPI_STM32_CLOCK_PRESCALER_MAX 256U
31+
#define MSPI_STM32_CLOCK_COMPUTE(bus_freq, prescaler) ((bus_freq) / (prescaler))
32+
#else
33+
/* Valid range is [0, 255] */
34+
#define MSPI_STM32_CLOCK_PRESCALER_MIN 0U
35+
#define MSPI_STM32_CLOCK_PRESCALER_MAX 255U
36+
#define MSPI_STM32_CLOCK_COMPUTE(bus_freq, prescaler) ((bus_freq) / ((prescaler) + 1U))
37+
#endif
38+
39+
#define MSPI_STM32_WRITE_REG_MAX_TIME 40U
40+
#define MSPI_STM32_MAX_FREQ 48000000
41+
42+
43+
typedef void (*irq_config_func_t)(void);
44+
45+
#ifndef DMA_LOW_PRIORITY_LOW_WEIGHT
46+
#define DMA_LOW_PRIORITY_LOW_WEIGHT DMA_PRIORITY_LOW
47+
#endif
48+
49+
#ifndef DMA_LOW_PRIORITY_MID_WEIGHT
50+
#define DMA_LOW_PRIORITY_MID_WEIGHT DMA_PRIORITY_MEDIUM
51+
#endif
52+
53+
#ifndef DMA_LOW_PRIORITY_HIGH_WEIGHT
54+
#define DMA_LOW_PRIORITY_HIGH_WEIGHT DMA_PRIORITY_HIGH
55+
#endif
56+
57+
#ifndef DMA_HIGH_PRIORITY
58+
#define DMA_HIGH_PRIORITY DMA_PRIORITY_VERY_HIGH
59+
#endif
60+
61+
enum mspi_access_mode {
62+
MSPI_ACCESS_ASYNC = 1,
63+
MSPI_ACCESS_SYNC = 2,
64+
MSPI_ACCESS_DMA = 3
65+
};
66+
67+
struct mspi_context {
68+
struct mspi_xfer xfer;
69+
int packets_left;
70+
struct k_sem lock;
71+
};
72+
73+
struct mspi_stm32_conf {
74+
bool use_dma;
75+
size_t pclk_len;
76+
irq_config_func_t irq_config;
77+
struct mspi_cfg mspicfg;
78+
const struct stm32_pclken *pclken;
79+
const struct pinctrl_dev_config *pcfg;
80+
};
81+
82+
/* Lookup table to set dma priority from the DTS */
83+
static const uint32_t table_priority[] = {
84+
DMA_LOW_PRIORITY_LOW_WEIGHT,
85+
DMA_LOW_PRIORITY_MID_WEIGHT,
86+
DMA_LOW_PRIORITY_HIGH_WEIGHT,
87+
DMA_HIGH_PRIORITY,
88+
};
89+
90+
/* Lookup table to set dma channel direction from the DTS */
91+
static const uint32_t table_direction[] = {
92+
DMA_MEMORY_TO_MEMORY,
93+
DMA_MEMORY_TO_PERIPH,
94+
DMA_PERIPH_TO_MEMORY,
95+
};
96+
97+
static const uint32_t table_src_size[] = {
98+
#ifndef LL_DMA_SRC_DATAWIDTH_BYTE
99+
#define LL_DMA_SRC_DATAWIDTH_BYTE LL_DMA_MDATAALIGN_BYTE
100+
#endif
101+
#ifndef LL_DMA_SRC_DATAWIDTH_HALFWORD
102+
#define LL_DMA_SRC_DATAWIDTH_HALFWORD LL_DMA_MDATAALIGN_HALFWORD
103+
#endif
104+
#ifndef LL_DMA_SRC_DATAWIDTH_WORD
105+
#define LL_DMA_SRC_DATAWIDTH_WORD LL_DMA_MDATAALIGN_WORD
106+
#endif
107+
};
108+
109+
static const uint32_t table_dest_size[] = {
110+
#ifndef LL_DMA_DEST_DATAWIDTH_BYTE
111+
#define LL_DMA_DEST_DATAWIDTH_BYTE LL_DMA_PDATAALIGN_BYTE
112+
#endif
113+
#ifndef LL_DMA_DEST_DATAWIDTH_HALFWORD
114+
#define LL_DMA_DEST_DATAWIDTH_HALFWORD LL_DMA_PDATAALIGN_HALFWORD
115+
#endif
116+
#ifndef LL_DMA_DEST_DATAWIDTH_WORD
117+
#define LL_DMA_DEST_DATAWIDTH_WORD LL_DMA_PDATAALIGN_WORD
118+
#endif
119+
};
120+
121+
struct stream {
122+
DMA_TypeDef *reg;
123+
const struct device *dev;
124+
uint32_t channel;
125+
struct dma_config cfg;
126+
uint8_t priority;
127+
bool src_addr_increment;
128+
bool dst_addr_increment;
129+
};
130+
131+
union hmspi_handle {
132+
#ifdef CONFIG_MSPI_STM32_XSPI
133+
XSPI_HandleTypeDef xspi;
134+
#endif
135+
#ifdef CONFIG_MSPI_STM32_OSPI
136+
OSPI_HandleTypeDef ospi;
137+
#endif
138+
#ifdef CONFIG_MSPI_STM32_QSPI
139+
QSPI_HandleTypeDef qspi;
140+
#endif
141+
};
142+
143+
/* mspi data includes the controller specific config variable */
144+
struct mspi_stm32_data {
145+
union hmspi_handle hmspi;
146+
uint32_t memmap_base_addr;
147+
struct mspi_context ctx;
148+
struct mspi_dev_id *dev_id;
149+
struct k_mutex lock;
150+
struct k_sem sync;
151+
struct mspi_dev_cfg dev_cfg;
152+
struct mspi_xip_cfg xip_cfg;
153+
struct stream dma_tx;
154+
struct stream dma_rx;
155+
struct stream dma;
156+
};
157+
158+
#endif /* ZEPHYR_DRIVERS_MSPI_STM32_H_ */

0 commit comments

Comments
 (0)