Skip to content

Commit cf66b0c

Browse files
khoa-nguyen-18cfriedt
authored andcommitted
drivers: flash: Add support Renesas MRAM driver
Add support Renesas MRAM driver for RA devices Signed-off-by: Khoa Nguyen <khoa.nguyen.xh@renesas.com>
1 parent 87a6d5b commit cf66b0c

File tree

6 files changed

+292
-0
lines changed

6 files changed

+292
-0
lines changed

drivers/flash/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NRF_MRAMC soc_flash_nrf_mramc.c)
6363
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NRF_RRAM soc_flash_nrf_rram.c)
6464
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NUMAKER soc_flash_numaker.c)
6565
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NUMAKER_RMC soc_flash_numaker_rmc.c)
66+
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_RENESAS_RA_MRAM soc_flash_renesas_ra_mram.c)
6667
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_RENESAS_RX soc_flash_renesas_rx.c)
6768
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_RTS5912 flash_realtek_rts5912.c)
6869
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_RV32M1 soc_flash_rv32m1.c)

drivers/flash/Kconfig.renesas_ra

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,15 @@ config FLASH_RENESAS_RA_HP_CHECK_BEFORE_READING
4141
are undefined.
4242

4343
endif # SOC_FLASH_RENESAS_RA_HP
44+
45+
config SOC_FLASH_RENESAS_RA_MRAM
46+
bool "RA Flash MRAM driver"
47+
depends on DT_HAS_RENESAS_RA_MRAM_CONTROLLER_ENABLED
48+
default y
49+
select FLASH_HAS_DRIVER_ENABLED
50+
select FLASH_PAGE_LAYOUT
51+
select FLASH_HAS_PAGE_LAYOUT
52+
select FLASH_HAS_NO_EXPLICIT_ERASE
53+
select USE_RA_FSP_MRAM
54+
help
55+
Enable Flash MRAM driver for RA series
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
/*
2+
* Copyright (c) 2025 Renesas Electronics Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL
8+
#include <zephyr/logging/log.h>
9+
#include <zephyr/kernel.h>
10+
#include <zephyr/device.h>
11+
#include <zephyr/devicetree.h>
12+
#include <zephyr/drivers/flash.h>
13+
14+
#include <r_flash_api.h>
15+
#include <r_mram.h>
16+
#include <soc.h>
17+
18+
#define DT_DRV_COMPAT renesas_ra_mram_controller
19+
20+
LOG_MODULE_REGISTER(flash_renesas_ra_mram, CONFIG_FLASH_LOG_LEVEL);
21+
22+
struct mram_renesas_ra_controller_data {
23+
mram_instance_ctrl_t mram_controller;
24+
struct st_flash_cfg f_config;
25+
struct k_mutex code_mram_mtx;
26+
};
27+
28+
struct mram_renesas_ra_config {
29+
struct flash_parameters mram_parameters;
30+
size_t erase_block_size;
31+
#ifdef CONFIG_FLASH_PAGE_LAYOUT
32+
struct flash_pages_layout device_page_layout;
33+
#endif
34+
};
35+
36+
struct mram_renesas_ra_data {
37+
struct mram_renesas_ra_controller_data *controller_data;
38+
uint32_t area_address;
39+
uint32_t area_size;
40+
};
41+
42+
static struct mram_renesas_ra_controller_data mram_controller_data = {
43+
.f_config = {
44+
.data_flash_bgo = false,
45+
.irq = FSP_INVALID_VECTOR,
46+
.err_irq = FSP_INVALID_VECTOR,
47+
.ipl = BSP_IRQ_DISABLED,
48+
.err_ipl = BSP_IRQ_DISABLED,
49+
.p_callback = NULL,
50+
},
51+
};
52+
53+
static bool mram_renesas_ra_valid_range(struct mram_renesas_ra_data *mram_data, off_t offset,
54+
size_t len)
55+
{
56+
if ((offset < 0) || (offset >= mram_data->area_size) ||
57+
(mram_data->area_size - offset < len) || (len > UINT32_MAX - offset)) {
58+
return false;
59+
}
60+
61+
return true;
62+
}
63+
64+
static int mram_renesas_ra_read(const struct device *dev, off_t offset, void *data, size_t len)
65+
{
66+
struct mram_renesas_ra_data *mram_data = dev->data;
67+
struct mram_renesas_ra_controller_data *ctrl_data = mram_data->controller_data;
68+
69+
if (!len) {
70+
return 0;
71+
}
72+
73+
if (!mram_renesas_ra_valid_range(mram_data, offset, len)) {
74+
return -EINVAL;
75+
}
76+
77+
LOG_DBG("mram: read 0x%lx, len: %u", (long)(offset), len);
78+
79+
k_mutex_lock(&ctrl_data->code_mram_mtx, K_FOREVER);
80+
81+
memcpy(data, (uint8_t *)(offset + mram_data->area_address), len);
82+
83+
k_mutex_unlock(&ctrl_data->code_mram_mtx);
84+
85+
return 0;
86+
}
87+
88+
static int mram_renesas_ra_write(const struct device *dev, off_t offset, const void *data,
89+
size_t len)
90+
{
91+
struct mram_renesas_ra_data *mram_data = dev->data;
92+
struct mram_renesas_ra_controller_data *ctrl_data = mram_data->controller_data;
93+
fsp_err_t err;
94+
95+
if (!len) {
96+
return 0;
97+
}
98+
99+
if (!mram_renesas_ra_valid_range(mram_data, offset, len)) {
100+
return -EINVAL;
101+
}
102+
103+
k_mutex_lock(&ctrl_data->code_mram_mtx, K_FOREVER);
104+
105+
err = R_MRAM_Write(ctrl_data, (uint32_t)data, (uint32_t)(offset + mram_data->area_address),
106+
len);
107+
108+
k_mutex_unlock(&ctrl_data->code_mram_mtx);
109+
110+
if (err != FSP_SUCCESS) {
111+
return -EIO;
112+
}
113+
114+
return 0;
115+
}
116+
117+
static int mram_renesas_ra_erase(const struct device *dev, off_t offset, size_t size)
118+
{
119+
const struct mram_renesas_ra_config *mram_config = dev->config;
120+
struct mram_renesas_ra_data *mram_data = dev->data;
121+
struct mram_renesas_ra_controller_data *ctrl_data = mram_data->controller_data;
122+
fsp_err_t err;
123+
uint32_t block_num;
124+
125+
if (!size) {
126+
return 0;
127+
}
128+
129+
if (!mram_renesas_ra_valid_range(mram_data, offset, size)) {
130+
return -EINVAL;
131+
}
132+
133+
block_num = DIV_ROUND_UP(size, mram_config->erase_block_size);
134+
135+
k_mutex_lock(&ctrl_data->code_mram_mtx, K_FOREVER);
136+
137+
err = R_MRAM_Erase(ctrl_data, (uint32_t)(offset + mram_data->area_address), block_num);
138+
139+
k_mutex_unlock(&ctrl_data->code_mram_mtx);
140+
141+
if (err != FSP_SUCCESS) {
142+
return -EIO;
143+
}
144+
145+
return 0;
146+
}
147+
148+
static const struct flash_parameters *mram_renesas_ra_get_parameters(const struct device *dev)
149+
{
150+
const struct mram_renesas_ra_config *mram_config = dev->config;
151+
152+
return &mram_config->mram_parameters;
153+
}
154+
155+
static int mram_renesas_ra_get_size(const struct device *dev, uint64_t *size)
156+
{
157+
struct mram_renesas_ra_data *mram_data = dev->data;
158+
159+
*size = (uint64_t)mram_data->area_size;
160+
return 0;
161+
}
162+
163+
#ifdef CONFIG_FLASH_PAGE_LAYOUT
164+
165+
void mram_renesas_ra_page_layout(const struct device *dev, const struct flash_pages_layout **layout,
166+
size_t *layout_size)
167+
{
168+
const struct mram_renesas_ra_config *mram_config = dev->config;
169+
170+
*layout = &(mram_config->device_page_layout);
171+
*layout_size = 1;
172+
}
173+
174+
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
175+
176+
static int mram_renesas_ra_controller_init(const struct device *dev)
177+
{
178+
fsp_err_t err;
179+
struct mram_renesas_ra_controller_data *data = dev->data;
180+
181+
k_mutex_init(&data->code_mram_mtx);
182+
183+
err = R_MRAM_Open(&data->mram_controller, &data->f_config);
184+
185+
if (err != FSP_SUCCESS) {
186+
LOG_DBG("flash: open error=%d", (int)err);
187+
return -EIO;
188+
}
189+
190+
return 0;
191+
}
192+
193+
static int mram_renesas_ra_init(const struct device *dev)
194+
{
195+
const struct device *dev_ctrl = DEVICE_DT_INST_GET(0);
196+
struct mram_renesas_ra_data *mram_data = dev->data;
197+
198+
if (!device_is_ready(dev_ctrl)) {
199+
return -ENODEV;
200+
}
201+
202+
mram_data->controller_data = dev_ctrl->data;
203+
204+
return 0;
205+
}
206+
207+
static DEVICE_API(flash, mram_renesas_ra_api) = {
208+
.erase = mram_renesas_ra_erase,
209+
.write = mram_renesas_ra_write,
210+
.read = mram_renesas_ra_read,
211+
.get_parameters = mram_renesas_ra_get_parameters,
212+
.get_size = mram_renesas_ra_get_size,
213+
#ifdef CONFIG_FLASH_PAGE_LAYOUT
214+
.page_layout = mram_renesas_ra_page_layout,
215+
#endif
216+
};
217+
218+
#ifdef CONFIG_FLASH_PAGE_LAYOUT
219+
#define MRAM_RENESAS_RA_INIT_DEVICE_PAGE_LAYOUT(index) \
220+
.device_page_layout = { \
221+
.pages_count = (DT_REG_SIZE(index) / DT_PROP(index, erase_block_size)), \
222+
.pages_size = DT_PROP(index, erase_block_size), \
223+
}
224+
#else
225+
#define MRAM_RENESAS_RA_INIT_DEVICE_PAGE_LAYOUT(index)
226+
#endif
227+
228+
#define MRAM_RENESAS_RA_INIT(index) \
229+
static struct mram_renesas_ra_data mram_renesas_ra_data_##index = { \
230+
.area_address = DT_REG_ADDR(index), \
231+
.area_size = DT_REG_SIZE(index), \
232+
}; \
233+
static const struct mram_renesas_ra_config mram_renesas_ra_config_##index = { \
234+
.mram_parameters = \
235+
{ \
236+
.write_block_size = DT_PROP(index, write_block_size), \
237+
.erase_value = 0xff, \
238+
.caps = \
239+
{ \
240+
.no_explicit_erase = true, \
241+
}, \
242+
}, \
243+
.erase_block_size = DT_PROP(index, erase_block_size), \
244+
MRAM_RENESAS_RA_INIT_DEVICE_PAGE_LAYOUT(index), \
245+
}; \
246+
\
247+
DEVICE_DT_DEFINE(index, mram_renesas_ra_init, NULL, &mram_renesas_ra_data_##index, \
248+
&mram_renesas_ra_config_##index, POST_KERNEL, CONFIG_FLASH_INIT_PRIORITY, \
249+
&mram_renesas_ra_api);
250+
251+
DT_FOREACH_CHILD_STATUS_OKAY(DT_DRV_INST(0), MRAM_RENESAS_RA_INIT);
252+
253+
DEVICE_DT_DEFINE(DT_DRV_INST(0), mram_renesas_ra_controller_init, NULL, &mram_controller_data, NULL,
254+
PRE_KERNEL_1, CONFIG_FLASH_INIT_PRIORITY, NULL);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2025 Renesas Electronics Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Renesas RA flash MRAM controller
5+
6+
compatible: "renesas,ra-mram-controller"
7+
8+
include: flash-controller.yaml
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (c) 2025 Renesas Electronics Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: MRAM memory of Renesas RA family
5+
6+
include: [soc-nv-flash.yaml]
7+
8+
compatible: "renesas,ra-nv-mram"
9+
10+
properties:
11+
reg:
12+
required: true

modules/Kconfig.renesas

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ config USE_RA_FSP_SCE
6565
help
6666
Enable RA FSP SCE driver
6767

68+
config USE_RA_FSP_MRAM
69+
bool
70+
help
71+
Enable RA FSP MRAM driver
72+
6873
if USE_RA_FSP_SCE
6974

7075
config HAS_RENESAS_RA_RSIP_E51A

0 commit comments

Comments
 (0)