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 &parameters;
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, &params);
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