1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT nordic_rram_controller
8
9 #include <string.h>
10 #include <zephyr/kernel.h>
11 #include <zephyr/device.h>
12 #include <zephyr/drivers/flash.h>
13 #include <zephyr/logging/log.h>
14 #include <zephyr/irq.h>
15 #include <zephyr/sys/barrier.h>
16 #include <hal/nrf_rramc.h>
17
18 #include <zephyr/../../drivers/flash/soc_flash_nrf.h>
19
20 /* Note that it is supported to compile this driver for both secure
21 * and non-secure images, but non-secure images cannot call
22 * nrf_rramc_config_set because NRF_RRAMC_NS does not exist.
23 *
24 * Instead, when TF-M boots, it will configure RRAMC with this static
25 * configuration:
26 *
27 * nrf_rramc_config_t config = {
28 * .mode_write = true,
29 * .write_buff_size = WRITE_BUFFER_SIZE
30 * };
31 *
32 * nrf_rramc_ready_next_timeout_t params = {
33 * .value = CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE,
34 * .enable = true,
35 * };
36 *
37 * For more details see NCSDK-26982.
38 */
39
40 LOG_MODULE_REGISTER(flash_nrf_rram, CONFIG_FLASH_LOG_LEVEL);
41
42 #define RRAM DT_INST(0, soc_nv_flash)
43
44 #if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
45 #define RRAM_START NRF_RRAM_BASE_ADDR
46 #else
47 #define RRAM_START DT_REG_ADDR(RRAM)
48 #endif
49 #define RRAM_SIZE DT_REG_SIZE(RRAM)
50
51 #define PAGE_SIZE DT_PROP(RRAM, erase_block_size)
52 #define PAGE_COUNT ((RRAM_SIZE) / (PAGE_SIZE))
53
54 #define WRITE_BLOCK_SIZE_FROM_DT DT_PROP(RRAM, write_block_size)
55 #define ERASE_VALUE 0xFF
56
57 #ifdef CONFIG_MULTITHREADING
58 static struct k_sem sem_lock;
59 #define SYNC_INIT() k_sem_init(&sem_lock, 1, 1)
60 #define SYNC_LOCK() k_sem_take(&sem_lock, K_FOREVER)
61 #define SYNC_UNLOCK() k_sem_give(&sem_lock)
62 #else
63 #define SYNC_INIT()
64 #define SYNC_LOCK()
65 #define SYNC_UNLOCK()
66 #endif /* CONFIG_MULTITHREADING */
67
68 #if CONFIG_NRF_RRAM_WRITE_BUFFER_SIZE > 0
69 #define WRITE_BUFFER_ENABLE 1
70 #define WRITE_BUFFER_SIZE CONFIG_NRF_RRAM_WRITE_BUFFER_SIZE
71 #define WRITE_LINE_SIZE 16 /* In bytes, one line is 128 bits. */
72 #define WRITE_BUFFER_MAX_SIZE (WRITE_BUFFER_SIZE * WRITE_LINE_SIZE)
73 BUILD_ASSERT((PAGE_SIZE % (WRITE_LINE_SIZE) == 0), "erase-block-size must be a multiple of 16");
74 BUILD_ASSERT((WRITE_BLOCK_SIZE_FROM_DT % (WRITE_LINE_SIZE) == 0),
75 "if NRF_RRAM_WRITE_BUFFER_SIZE > 0, then write-block-size must be a multiple of 16");
76 #else
77 #define WRITE_BUFFER_ENABLE 0
78 #define WRITE_BUFFER_SIZE 0
79 #define WRITE_LINE_SIZE WRITE_BLOCK_SIZE_FROM_DT
80 #define WRITE_BUFFER_MAX_SIZE 16 /* In bytes, one line is 128 bits. */
81 BUILD_ASSERT((PAGE_SIZE % (WRITE_LINE_SIZE) == 0),
82 "erase-block-size must be a multiple of write-block-size");
83 #endif
84
85 #ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
86
87 #if (WRITE_BUFFER_SIZE < 2)
88 #define FLASH_SLOT_WRITE 500
89 #elif (WRITE_BUFFER_SIZE < 4)
90 #define FLASH_SLOT_WRITE 1000
91 #elif (WRITE_BUFFER_SIZE < 9)
92 #define FLASH_SLOT_WRITE 2000
93 #elif (WRITE_BUFFER_SIZE < 17)
94 #define FLASH_SLOT_WRITE 4000
95 #else
96 #define FLASH_SLOT_WRITE 8000 /* longest write takes 7107 us */
97 #endif
98
99 static int write_op(void *context); /* instance of flash_op_handler_t */
100 static int write_synchronously(off_t addr, const void *data, size_t len);
101
102 #endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
103
is_within_bounds(off_t addr,size_t len,off_t boundary_start,size_t boundary_size)104 static inline bool is_within_bounds(off_t addr, size_t len, off_t boundary_start,
105 size_t boundary_size)
106 {
107 return (addr >= boundary_start && (addr < (boundary_start + boundary_size)) &&
108 (len <= (boundary_start + boundary_size - addr)));
109 }
110
111 #if WRITE_BUFFER_ENABLE
commit_changes(off_t addr,size_t len)112 static void commit_changes(off_t addr, size_t len)
113 {
114 #if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE)
115 if (nrf_rramc_empty_buffer_check(NRF_RRAMC)) {
116 /* The internal write-buffer has been committed to RRAM and is now empty. */
117 return;
118 }
119 #endif
120
121 if ((len % (WRITE_BUFFER_MAX_SIZE)) == 0) {
122 /* Our last operation was buffer size-aligned, so we're done. */
123 return;
124 }
125
126 #if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE)
127 ARG_UNUSED(addr);
128
129 nrf_rramc_task_trigger(NRF_RRAMC, NRF_RRAMC_TASK_COMMIT_WRITEBUF);
130 #else
131 /*
132 * When the commit task is unavailable we need to get creative to
133 * ensure this is committed.
134 *
135 * According to the PS the buffer is committed when "There is a
136 * read operation from a 128-bit word line in the buffer that has
137 * already been written to".
138 *
139 * So we read the last byte that has been written to trigger this
140 * commit.
141 *
142 * If this approach proves to be problematic, e.g. for writes to
143 * write-only memory, then one would have to rely on
144 * READYNEXTTIMEOUT to eventually commit the write.
145 */
146 volatile uint8_t dummy_read = *(volatile uint8_t *)(addr + len - 1);
147 ARG_UNUSED(dummy_read);
148 #endif
149
150 barrier_dmem_fence_full();
151 }
152 #endif
153
rram_write(off_t addr,const void * data,size_t len)154 static void rram_write(off_t addr, const void *data, size_t len)
155 {
156 #if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE)
157 nrf_rramc_config_t config = {.mode_write = true, .write_buff_size = WRITE_BUFFER_SIZE};
158
159 nrf_rramc_config_set(NRF_RRAMC, &config);
160 #endif
161
162 if (data) {
163 memcpy((void *)addr, data, len);
164 } else {
165 memset((void *)addr, ERASE_VALUE, len);
166 }
167
168 barrier_dmem_fence_full(); /* Barrier following our last write. */
169
170 #if WRITE_BUFFER_ENABLE
171 commit_changes(addr, len);
172 #endif
173
174 #if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE)
175 config.mode_write = false;
176 nrf_rramc_config_set(NRF_RRAMC, &config);
177 #endif
178 }
179
180 #ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
shift_write_context(uint32_t shift,struct flash_context * w_ctx)181 static void shift_write_context(uint32_t shift, struct flash_context *w_ctx)
182 {
183 w_ctx->flash_addr += shift;
184
185 /* NULL data_addr => erase emulation request*/
186 if (w_ctx->data_addr) {
187 w_ctx->data_addr += shift;
188 }
189
190 w_ctx->len -= shift;
191 }
192
write_op(void * context)193 static int write_op(void *context)
194 {
195 struct flash_context *w_ctx = context;
196 size_t len;
197
198 uint32_t i = 0U;
199
200 if (w_ctx->enable_time_limit) {
201 nrf_flash_sync_get_timestamp_begin();
202 }
203
204 while (w_ctx->len > 0) {
205 len = (WRITE_BUFFER_MAX_SIZE < w_ctx->len) ? WRITE_BUFFER_MAX_SIZE : w_ctx->len;
206
207 rram_write(w_ctx->flash_addr, (const void *)w_ctx->data_addr, len);
208
209 shift_write_context(len, w_ctx);
210
211 if (w_ctx->len > 0) {
212 i++;
213
214 if (w_ctx->enable_time_limit) {
215 if (nrf_flash_sync_check_time_limit(i)) {
216 return FLASH_OP_ONGOING;
217 }
218 }
219 }
220 }
221
222 return FLASH_OP_DONE;
223 }
224
write_synchronously(off_t addr,const void * data,size_t len)225 static int write_synchronously(off_t addr, const void *data, size_t len)
226 {
227 struct flash_context context = {
228 .data_addr = (uint32_t)data,
229 .flash_addr = addr,
230 .len = len,
231 .enable_time_limit = 1 /* enable time limit */
232 };
233
234 struct flash_op_desc flash_op_desc = {.handler = write_op, .context = &context};
235
236 nrf_flash_sync_set_context(FLASH_SLOT_WRITE);
237 return nrf_flash_sync_exe(&flash_op_desc);
238 }
239
240 #endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
241
nrf_write(off_t addr,const void * data,size_t len)242 static int nrf_write(off_t addr, const void *data, size_t len)
243 {
244 int ret = 0;
245
246 if (!is_within_bounds(addr, len, 0, RRAM_SIZE)) {
247 return -EINVAL;
248 }
249 addr += RRAM_START;
250
251 if (!len) {
252 return 0;
253 }
254
255 LOG_DBG("Write: %p:%zu", (void *)addr, len);
256
257 SYNC_LOCK();
258
259 #ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
260 if (nrf_flash_sync_is_required()) {
261 ret = write_synchronously(addr, data, len);
262 } else
263 #endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
264 {
265 rram_write(addr, data, len);
266 }
267
268 SYNC_UNLOCK();
269
270 return ret;
271 }
272
nrf_rram_read(const struct device * dev,off_t addr,void * data,size_t len)273 static int nrf_rram_read(const struct device *dev, off_t addr, void *data, size_t len)
274 {
275 ARG_UNUSED(dev);
276
277 if (!is_within_bounds(addr, len, 0, RRAM_SIZE)) {
278 return -EINVAL;
279 }
280 addr += RRAM_START;
281
282 memcpy(data, (void *)addr, len);
283
284 return 0;
285 }
286
nrf_rram_write(const struct device * dev,off_t addr,const void * data,size_t len)287 static int nrf_rram_write(const struct device *dev, off_t addr, const void *data, size_t len)
288 {
289 ARG_UNUSED(dev);
290
291 if (data == NULL) {
292 return -EINVAL;
293 }
294
295 return nrf_write(addr, data, len);
296 }
297
nrf_rram_erase(const struct device * dev,off_t addr,size_t len)298 static int nrf_rram_erase(const struct device *dev, off_t addr, size_t len)
299 {
300 ARG_UNUSED(dev);
301
302 return nrf_write(addr, NULL, len);
303 }
304
nrf_rram_get_parameters(const struct device * dev)305 static const struct flash_parameters *nrf_rram_get_parameters(const struct device *dev)
306 {
307 ARG_UNUSED(dev);
308
309 static const struct flash_parameters parameters = {
310 .write_block_size = WRITE_LINE_SIZE,
311 .erase_value = ERASE_VALUE,
312 .caps = {
313 .no_explicit_erase = true,
314 },
315 };
316
317 return ¶meters;
318 }
319
320 #if defined(CONFIG_FLASH_PAGE_LAYOUT)
nrf_rram_page_layout(const struct device * dev,const struct flash_pages_layout ** layout,size_t * layout_size)321 static void nrf_rram_page_layout(const struct device *dev, const struct flash_pages_layout **layout,
322 size_t *layout_size)
323 {
324 ARG_UNUSED(dev);
325
326 static const struct flash_pages_layout pages_layout = {
327 .pages_count = PAGE_COUNT,
328 .pages_size = PAGE_SIZE,
329 };
330
331 *layout = &pages_layout;
332 *layout_size = 1;
333 }
334 #endif
335
336 static const struct flash_driver_api nrf_rram_api = {
337 .read = nrf_rram_read,
338 .write = nrf_rram_write,
339 .erase = nrf_rram_erase,
340 .get_parameters = nrf_rram_get_parameters,
341 #if defined(CONFIG_FLASH_PAGE_LAYOUT)
342 .page_layout = nrf_rram_page_layout,
343 #endif
344 };
345
nrf_rram_init(const struct device * dev)346 static int nrf_rram_init(const struct device *dev)
347 {
348 ARG_UNUSED(dev);
349
350 SYNC_INIT();
351
352 #ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
353 nrf_flash_sync_init();
354 #endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
355
356 #if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) && CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE > 0
357 nrf_rramc_ready_next_timeout_t params = {
358 .value = CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE,
359 .enable = true,
360 };
361
362 nrf_rramc_ready_next_timeout_set(NRF_RRAMC, ¶ms);
363 #endif
364
365 return 0;
366 }
367
368 DEVICE_DT_INST_DEFINE(0, nrf_rram_init, NULL, NULL, NULL, POST_KERNEL, CONFIG_FLASH_INIT_PRIORITY,
369 &nrf_rram_api);
370