Skip to content

Commit ae8eeda

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 ae8eeda

File tree

7 files changed

+4669
-0
lines changed

7 files changed

+4669
-0
lines changed

drivers/mspi/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ 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)

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: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/*
2+
* Copyright (c) 2025 EXALT Technologies.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_DRIVERS_MSPI_STM32_H_
8+
#define ZEPHYR_DRIVERS_MSPI_STM32_H_
9+
/* Macro to check if any xspi device has a domain clock or more */
10+
#define MSPI_STM32_DOMAIN_CLOCK_INST_SUPPORT(inst) DT_CLOCKS_HAS_IDX(DT_INST_PARENT(inst), 1) ||
11+
#define MSPI_STM32_INST_DEV_DOMAIN_CLOCK_SUPPORT \
12+
(DT_INST_FOREACH_STATUS_OKAY(MSPI_STM32_DOMAIN_CLOCK_INST_SUPPORT) 0)
13+
14+
/* This symbol takes the value 1 if device instance has a domain clock in its dts */
15+
#if MSPI_STM32_INST_DEV_DOMAIN_CLOCK_SUPPORT
16+
#define MSPI_STM32_DOMAIN_CLOCK_SUPPORT 1
17+
#else
18+
#define MSPI_STM32_DOMAIN_CLOCK_SUPPORT 0
19+
#endif
20+
21+
#define MSPI_STM32_FIFO_THRESHOLD 4U
22+
#define MSPI_MAX_FREQ 250000000
23+
#define MSPI_MAX_DEVICE 2
24+
25+
#if defined(CONFIG_SOC_SERIES_STM32U5X)
26+
/* Valid range is [1, 256] */
27+
#define MSPI_STM32_CLOCK_PRESCALER_MIN 1U
28+
#define MSPI_STM32_CLOCK_PRESCALER_MAX 256U
29+
#define MSPI_STM32_CLOCK_COMPUTE(bus_freq, prescaler) ((bus_freq) / (prescaler))
30+
#else
31+
/* Valid range is [0, 255] */
32+
#define MSPI_STM32_CLOCK_PRESCALER_MIN 0U
33+
#define MSPI_STM32_CLOCK_PRESCALER_MAX 255U
34+
#define MSPI_STM32_CLOCK_COMPUTE(bus_freq, prescaler) ((bus_freq) / ((prescaler) + 1U))
35+
#endif
36+
37+
#define MSPI_STM32_WRITE_REG_MAX_TIME 40U
38+
#define MSPI_STM32_MAX_FREQ 48000000
39+
40+
#define MSPI_STM32_CMD_WRSR 0x01 /* Write status register */
41+
#define MSPI_STM32_CMD_RDSR 0x05 /* Read status register */
42+
#define MSPI_STM32_CMD_READ 0x03 /* Read data */
43+
#define MSPI_STM32_CMD_READ_FAST 0x0B /* Read data */
44+
#define MSPI_STM32_CMD_PP 0x02 /* Page program */
45+
#define MSPI_STM32_CMD_READ_4B 0x13 /* Read data 4 Byte Address */
46+
#define MSPI_STM32_CMD_READ_FAST_4B 0x0C /* Fast Read 4 Byte Address */
47+
#define MSPI_STM32_CMD_PP_4B 0x12 /* Page Program 4 Byte Address */
48+
#define MSPI_STM32_CMD_WREN 0x06 /* Write enable */
49+
#define MSPI_STM32_CMD_RDPD 0xAB /* Release from Deep Power Down */
50+
#define MSPI_STM32_CMD_RD_CFGREG2 0x71 /* Read config register 2 */
51+
#define MSPI_STM32_CMD_WR_CFGREG2 0x72 /* Write config register 2 */
52+
#define MSPI_STM32_CMD_SE 0x20 /* Sector erase */
53+
#define MSPI_STM32_CMD_SE_4B 0x21 /* Sector erase 4 byte address*/
54+
55+
#define MSPI_STM32_OCMD_RDSR 0x05FA /* Octal Read status register */
56+
#define MSPI_STM32_OCMD_RD 0xEC13 /* Octal IO read command */
57+
#define MSPI_STM32_OCMD_PAGE_PRG 0x12ED /* Octal Page Prog */
58+
#define MSPI_STM32_OCMD_WREN 0x06F9 /* Octal Write enable */
59+
#define MSPI_STM32_OCMD_DTR_RD 0xEE11 /* Octal IO DTR read command */
60+
#define MSPI_STM32_OCMD_WR_CFGREG2 0x728D /* Octal Write configuration Register2 */
61+
#define MSPI_STM32_OCMD_RD_CFGREG2 0x718E /* Octal Read configuration Register2 */
62+
#define MSPI_STM32_OCMD_SE 0x21DE /* Octal Sector erase */
63+
64+
/* Flash Auto-polling values */
65+
#define MSPI_STM32_WREN_MATCH 0x02
66+
#define MSPI_STM32_WREN_MASK 0x02
67+
#define MSPI_STM32_WEL_MATCH 0x00
68+
#define MSPI_STM32_WEL_MASK 0x02
69+
#define MSPI_STM32_MEM_RDY_MATCH 0x00
70+
#define MSPI_STM32_MEM_RDY_MASK 0x01
71+
#define MSPI_STM32_AUTO_POLLING_INTERVAL 0x10
72+
73+
/* Flash Dummy Cycles values */
74+
#define MSPI_STM32_DUMMY_REG_OCTAL 4U
75+
#define MSPI_STM32_DUMMY_REG_OCTAL_DTR 5U
76+
77+
/* Memory registers address */
78+
#define MSPI_STM32_REG2_ADDR1 0x0000000
79+
#define MSPI_STM32_CR2_STR_OPI_EN 0x01
80+
#define MSPI_STM32_CR2_DTR_OPI_EN 0x02
81+
#define MSPI_STM32_REG2_ADDR3 0x00000300
82+
#define MSPI_STM32_CR2_DUMMY_CYCLES_66MHZ 0x07
83+
84+
typedef void (*irq_config_func_t)(void);
85+
86+
#ifndef DMA_LOW_PRIORITY_LOW_WEIGHT
87+
#define DMA_LOW_PRIORITY_LOW_WEIGHT DMA_PRIORITY_LOW
88+
#endif
89+
90+
#ifndef DMA_LOW_PRIORITY_MID_WEIGHT
91+
#define DMA_LOW_PRIORITY_MID_WEIGHT DMA_PRIORITY_MEDIUM
92+
#endif
93+
94+
#ifndef DMA_LOW_PRIORITY_HIGH_WEIGHT
95+
#define DMA_LOW_PRIORITY_HIGH_WEIGHT DMA_PRIORITY_HIGH
96+
#endif
97+
98+
#ifndef DMA_HIGH_PRIORITY
99+
#define DMA_HIGH_PRIORITY DMA_PRIORITY_VERY_HIGH
100+
#endif
101+
102+
enum mspi_access_mode {
103+
MSPI_ACCESS_ASYNC = 1,
104+
MSPI_ACCESS_SYNC = 2,
105+
MSPI_ACCESS_DMA = 3
106+
};
107+
108+
struct mspi_context {
109+
struct mspi_xfer xfer;
110+
int packets_left;
111+
struct k_sem lock;
112+
};
113+
114+
struct mspi_stm32_conf {
115+
bool use_dma;
116+
size_t pclk_len;
117+
irq_config_func_t irq_config;
118+
struct mspi_cfg mspicfg;
119+
const struct stm32_pclken *pclken;
120+
const struct pinctrl_dev_config *pcfg;
121+
};
122+
123+
/* Lookup table to set dma priority from the DTS */
124+
static const uint32_t table_priority[] = {
125+
DMA_LOW_PRIORITY_LOW_WEIGHT,
126+
DMA_LOW_PRIORITY_MID_WEIGHT,
127+
DMA_LOW_PRIORITY_HIGH_WEIGHT,
128+
DMA_HIGH_PRIORITY,
129+
};
130+
131+
/* Lookup table to set dma channel direction from the DTS */
132+
static const uint32_t table_direction[] = {
133+
DMA_MEMORY_TO_MEMORY,
134+
DMA_MEMORY_TO_PERIPH,
135+
DMA_PERIPH_TO_MEMORY,
136+
};
137+
138+
#if CONFIG_DMA_STM32U5
139+
static const uint32_t table_src_size[] = {
140+
LL_DMA_SRC_DATAWIDTH_BYTE,
141+
LL_DMA_SRC_DATAWIDTH_HALFWORD,
142+
LL_DMA_SRC_DATAWIDTH_WORD,
143+
};
144+
145+
static const uint32_t table_dest_size[] = {
146+
LL_DMA_DEST_DATAWIDTH_BYTE,
147+
LL_DMA_DEST_DATAWIDTH_HALFWORD,
148+
LL_DMA_DEST_DATAWIDTH_WORD,
149+
};
150+
#else
151+
static const uint32_t table_m_size[] = {
152+
LL_DMA_MDATAALIGN_BYTE,
153+
LL_DMA_MDATAALIGN_HALFWORD,
154+
LL_DMA_MDATAALIGN_WORD,
155+
};
156+
157+
static const uint32_t table_p_size[] = {
158+
LL_DMA_PDATAALIGN_BYTE,
159+
LL_DMA_PDATAALIGN_HALFWORD,
160+
LL_DMA_PDATAALIGN_WORD,
161+
};
162+
#endif /* CONFIG_DMA_STM32U5 */
163+
164+
struct stream {
165+
DMA_TypeDef *reg;
166+
const struct device *dev;
167+
uint32_t channel;
168+
struct dma_config cfg;
169+
uint8_t priority;
170+
bool src_addr_increment;
171+
bool dst_addr_increment;
172+
};
173+
174+
union hmspi_handle {
175+
#ifdef CONFIG_MSPI_STM32_XSPI
176+
XSPI_HandleTypeDef xspi;
177+
#endif
178+
#ifdef CONFIG_MSPI_STM32_OSPI
179+
OSPI_HandleTypeDef ospi;
180+
#endif
181+
#ifdef CONFIG_MSPI_STM32_QSPI
182+
QSPI_HandleTypeDef qspi;
183+
#endif
184+
};
185+
186+
/* mspi data includes the controller specific config variable */
187+
struct mspi_stm32_data {
188+
union hmspi_handle hmspi;
189+
uint32_t memmap_base_addr;
190+
struct mspi_context ctx;
191+
struct mspi_dev_id *dev_id;
192+
struct k_mutex lock;
193+
struct k_sem sync;
194+
struct mspi_dev_cfg dev_cfg;
195+
struct mspi_xip_cfg xip_cfg;
196+
struct stream dma_tx;
197+
struct stream dma_rx;
198+
struct stream dma;
199+
};
200+
201+
#endif /* ZEPHYR_DRIVERS_MSPI_STM32_H_ */

0 commit comments

Comments
 (0)