1 /*
2  * Copyright (c) 2024 STMicroelectronics
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT st_stm32wb0_flash_controller
8 
9 #include <zephyr/init.h>
10 #include <zephyr/kernel.h>
11 #include <zephyr/device.h>
12 #include <zephyr/drivers/flash.h>
13 #include <zephyr/sys/byteorder.h>
14 #include <zephyr/sys/math_extras.h>
15 
16 /* <soc.h> also brings "stm32wb0x_hal_flash.h"
17  * and "system_stm32wb0x.h", which provide macros
18  * used by the driver, such as FLASH_PAGE_SIZE or
19  * _MEMORY_FLASH_SIZE_ respectively.
20  */
21 #include <soc.h>
22 #include <stm32_ll_bus.h>
23 #include <stm32_ll_rcc.h>
24 #include <stm32_ll_system.h>
25 
26 #include <zephyr/logging/log.h>
27 LOG_MODULE_REGISTER(flash_stm32wb0x, CONFIG_FLASH_LOG_LEVEL);
28 
29 /**
30  * Driver private definitions & assertions
31  */
32 #define SYSTEM_FLASH_SIZE	_MEMORY_FLASH_SIZE_
33 #define PAGES_IN_FLASH		(SYSTEM_FLASH_SIZE / FLASH_PAGE_SIZE)
34 
35 #define WRITE_BLOCK_SIZE \
36 	DT_PROP(DT_INST(0, soc_nv_flash), write_block_size)
37 
38 /* Size of flash words, in bytes (equal to write block size) */
39 #define WORD_SIZE	WRITE_BLOCK_SIZE
40 
41 #define ERASE_BLOCK_SIZE \
42 	DT_PROP(DT_INST(0, soc_nv_flash), erase_block_size)
43 
44 /**
45  * Driver private structures
46  */
47 struct flash_wb0x_data {
48 	/** Used to serialize write/erase operations */
49 	struct k_sem write_lock;
50 
51 	/** Flash size, in bytes */
52 	size_t flash_size;
53 };
54 
55 /**
56  * Driver private utility functions
57  */
read_mem_u32(const uint32_t * ptr)58 static inline uint32_t read_mem_u32(const uint32_t *ptr)
59 {
60 	/**
61 	 * Fetch word using sys_get_le32, which performs byte-sized
62 	 * reads instead of word-sized. This is important as ptr may
63 	 * be unaligned. We also want to use le32 because the data is
64 	 * stored in little-endian inside the flash.
65 	 */
66 	return sys_get_le32((const uint8_t *)ptr);
67 }
68 
get_flash_size_in_bytes(void)69 static inline size_t get_flash_size_in_bytes(void)
70 {
71 	/* FLASH.SIZE contains the highest flash address supported
72 	 * on this MCU, which is also the number of words in flash
73 	 * minus one.
74 	 */
75 	const uint32_t words_in_flash =
76 		READ_BIT(FLASH->SIZE, FLASH_FLASH_SIZE_FLASH_SIZE) + 1;
77 
78 	return words_in_flash * WORD_SIZE;
79 }
80 
81 /**
82  * @brief Returns the associated error to IRQ flags.
83  *
84  * @returns a negative error value
85  */
error_from_irq_flags(uint32_t flags)86 static int error_from_irq_flags(uint32_t flags)
87 {
88 	/**
89 	 * Only two errors are expected:
90 	 *  - illegal command
91 	 *  - command error
92 	 */
93 	if (flags & FLASH_FLAG_ILLCMD) {
94 		return -EINVAL;
95 	}
96 
97 	if (flags & FLASH_FLAG_CMDERR) {
98 		return -EIO;
99 	}
100 
101 	/*
102 	 * Unexpected error flag -> "out of domain"
103 	 * In practice, this should never be reached.
104 	 */
105 	return -EDOM;
106 }
107 
is_valid_flash_range(const struct device * dev,off_t offset,uint32_t len)108 static bool is_valid_flash_range(const struct device *dev,
109 				off_t offset, uint32_t len)
110 {
111 	const struct flash_wb0x_data *data = dev->data;
112 	uint32_t offset_plus_len;
113 
114 		/* (offset + len) must not overflow */
115 	return !u32_add_overflow(offset, len, &offset_plus_len)
116 		/* offset must be a valid offset in flash */
117 		&& IN_RANGE(offset, 0, data->flash_size - 1)
118 		/* (offset + len) must be in [0; flash size]
119 		 * because it is equal to the last accessed
120 		 * byte in flash plus one (an access of `len`
121 		 * bytes starting at `offset` touches bytes
122 		 * `offset` to `offset + len` EXCLUDED)
123 		 */
124 		&& IN_RANGE(offset_plus_len, 0, data->flash_size);
125 }
126 
is_writeable_flash_range(const struct device * dev,off_t offset,uint32_t len)127 static bool is_writeable_flash_range(const struct device *dev,
128 				off_t offset, uint32_t len)
129 {
130 	if ((offset % WRITE_BLOCK_SIZE) != 0
131 		|| (len % WRITE_BLOCK_SIZE) != 0) {
132 		return false;
133 	}
134 
135 	return is_valid_flash_range(dev, offset, len);
136 }
137 
is_erasable_flash_range(const struct device * dev,off_t offset,uint32_t len)138 static bool is_erasable_flash_range(const struct device *dev,
139 				off_t offset, uint32_t len)
140 {
141 	if ((offset % ERASE_BLOCK_SIZE) != 0
142 		|| (len % ERASE_BLOCK_SIZE) != 0) {
143 		return false;
144 	}
145 
146 	return is_valid_flash_range(dev, offset, len);
147 }
148 
149 /**
150  * Driver private functions
151  */
152 
poll_flash_controller(void)153 static uint32_t poll_flash_controller(void)
154 {
155 	uint32_t flags;
156 
157 	/* Poll until an interrupt flag is raised */
158 	do {
159 		flags = FLASH->IRQRAW;
160 	} while (flags == 0);
161 
162 	/* Acknowledge the flag(s) we have seen */
163 	FLASH->IRQRAW = flags;
164 
165 	return flags;
166 }
167 
execute_flash_command(uint8_t cmd)168 static int execute_flash_command(uint8_t cmd)
169 {
170 	uint32_t irq_flags;
171 
172 	/* Clear all pending interrupt bits */
173 	FLASH->IRQRAW = FLASH->IRQRAW;
174 
175 	/* Start command */
176 	FLASH->COMMAND = cmd;
177 
178 	/* Wait for CMDSTART */
179 	irq_flags = poll_flash_controller();
180 
181 	/* If command didn't start, an error occurred */
182 	if (!(irq_flags & FLASH_IT_CMDSTART)) {
183 		return error_from_irq_flags(irq_flags);
184 	}
185 
186 	/**
187 	 * Both CMDSTART and CMDDONE may be set if the command was
188 	 * executed fast enough. In this case, we're already done.
189 	 * Otherwise, we need to poll again until CMDDONE/error occurs.
190 	 */
191 	if (!(irq_flags & FLASH_IT_CMDDONE)) {
192 		irq_flags = poll_flash_controller();
193 	}
194 
195 	if (!(irq_flags & FLASH_IT_CMDDONE)) {
196 		return error_from_irq_flags(irq_flags);
197 	} else {
198 		return 0;
199 	}
200 }
201 
erase_page_range(uint32_t start_page,uint32_t page_count)202 int erase_page_range(uint32_t start_page, uint32_t page_count)
203 {
204 	int res = 0;
205 
206 	__ASSERT_NO_MSG(start_page < PAGES_IN_FLASH);
207 	__ASSERT_NO_MSG((start_page + page_count - 1) < PAGES_IN_FLASH);
208 
209 	for (uint32_t i = start_page;
210 		i < (start_page + page_count);
211 		i++) {
212 		/* ADDRESS[16:9] = XADR[10:3] (address of page to erase)
213 		 * ADDRESS[8:0]  = 0 (row & word address, must be 0)
214 		 */
215 		FLASH->ADDRESS = (i << 9);
216 
217 		res = execute_flash_command(FLASH_CMD_ERASE_PAGES);
218 		if (res < 0) {
219 			break;
220 		}
221 	}
222 
223 	return res;
224 }
225 
write_word_range(const void * buf,uint32_t start_word,uint32_t num_words)226 int write_word_range(const void *buf, uint32_t start_word, uint32_t num_words)
227 {
228 	/* Special value to load in DATAx registers to skip
229 	 * writing corresponding word with BURSTWRITE command.
230 	 */
231 	const uint32_t BURST_IGNORE_VALUE = 0xFFFFFFFF;
232 	const size_t WORDS_IN_BURST = 4;
233 	uint32_t dst_addr = start_word;
234 	uint32_t remaining = num_words;
235 	/**
236 	 * Note that @p buf may not be aligned to 32-bit boundary.
237 	 * However, declaring src_ptr as uint32_t* makes the address
238 	 * increment by 4 every time we do src_ptr++, which makes it
239 	 * behave like the other counters in this function.
240 	 */
241 	const uint32_t *src_ptr = buf;
242 	int res = 0;
243 
244 	/**
245 	 * Write to flash is performed as a 3 step process:
246 	 *  - write single words using WRITE commands until the write
247 	 *    write address is aligned to flash quadword boundary
248 	 *
249 	 *  - after write address is aligned to quadword, we can use
250 	 *    the BURSTWRITE commands to write 4 words at a time
251 	 *
252 	 *  - once less than 4 words remain to write, a last BURSTWRITE
253 	 *    is used with unneeded DATAx registers filled with 0xFFFFFFFF
254 	 *    (this makes BURSTWRITE ignore write to these addresses)
255 	 */
256 
257 	/* (1) Align to quadword boundary with WRITE commands */
258 	while (remaining > 0 && (dst_addr % WORDS_IN_BURST) != 0) {
259 		FLASH->ADDRESS = dst_addr;
260 		FLASH->DATA0 = read_mem_u32(src_ptr);
261 
262 		res = execute_flash_command(FLASH_CMD_WRITE);
263 		if (res < 0) {
264 			return res;
265 		}
266 
267 		src_ptr++;
268 		dst_addr++;
269 		remaining--;
270 	}
271 
272 	/* (2) Write bursts of quadwords */
273 	while (remaining >= WORDS_IN_BURST) {
274 		__ASSERT_NO_MSG((dst_addr % WORDS_IN_BURST) == 0);
275 
276 		FLASH->ADDRESS = dst_addr;
277 		FLASH->DATA0 = read_mem_u32(src_ptr + 0);
278 		FLASH->DATA1 = read_mem_u32(src_ptr + 1);
279 		FLASH->DATA2 = read_mem_u32(src_ptr + 2);
280 		FLASH->DATA3 = read_mem_u32(src_ptr + 3);
281 
282 		res = execute_flash_command(FLASH_CMD_BURSTWRITE);
283 		if (res < 0) {
284 			return res;
285 		}
286 
287 		src_ptr += WORDS_IN_BURST;
288 		dst_addr += WORDS_IN_BURST;
289 		remaining -= WORDS_IN_BURST;
290 	}
291 
292 	/* (3) Write trailing (between 1 and 3 words) */
293 	if (remaining > 0) {
294 		__ASSERT_NO_MSG(remaining < WORDS_IN_BURST);
295 		__ASSERT_NO_MSG((dst_addr % WORDS_IN_BURST) == 0);
296 
297 		FLASH->ADDRESS = dst_addr;
298 		FLASH->DATA0 = read_mem_u32(src_ptr + 0);
299 
300 		FLASH->DATA1 = (remaining >= 2)
301 			? read_mem_u32(src_ptr + 1)
302 			: BURST_IGNORE_VALUE;
303 
304 		FLASH->DATA2 = (remaining == 3)
305 			? read_mem_u32(src_ptr + 2)
306 			: BURST_IGNORE_VALUE;
307 
308 		FLASH->DATA3 = BURST_IGNORE_VALUE;
309 
310 		remaining = 0;
311 
312 		res = execute_flash_command(FLASH_CMD_BURSTWRITE);
313 	}
314 
315 	return res;
316 }
317 
318 /**
319  * Driver subsystem API implementation
320  */
flash_wb0x_read(const struct device * dev,off_t offset,void * buffer,size_t len)321 int flash_wb0x_read(const struct device *dev, off_t offset,
322 			void *buffer, size_t len)
323 {
324 	if (!len) {
325 		return 0;
326 	}
327 
328 	if (!is_valid_flash_range(dev, offset, len)) {
329 		return -EINVAL;
330 	}
331 
332 	const uint8_t *flash_base = ((void *)DT_REG_ADDR(DT_INST(0, st_stm32_nv_flash)));
333 
334 	memcpy(buffer, flash_base + (uint32_t)offset, len);
335 
336 	return 0;
337 }
338 
flash_wb0x_write(const struct device * dev,off_t offset,const void * buffer,size_t len)339 int flash_wb0x_write(const struct device *dev, off_t offset,
340 			const void *buffer, size_t len)
341 {
342 	struct flash_wb0x_data *data = dev->data;
343 	int res;
344 
345 	if (!len) {
346 		return 0;
347 	}
348 
349 	if (!is_writeable_flash_range(dev, offset, len)) {
350 		return -EINVAL;
351 	}
352 
353 	/* Acquire driver lock */
354 	res = k_sem_take(&data->write_lock, K_NO_WAIT);
355 	if (res < 0) {
356 		return res;
357 	}
358 
359 	const uint32_t start_word = (uint32_t)offset / WORD_SIZE;
360 	const uint32_t num_words = len / WORD_SIZE;
361 
362 	res = write_word_range(buffer, start_word, num_words);
363 
364 	/* Release driver lock */
365 	k_sem_give(&data->write_lock);
366 
367 	return res;
368 }
369 
flash_wb0x_erase(const struct device * dev,off_t offset,size_t size)370 int flash_wb0x_erase(const struct device *dev, off_t offset, size_t size)
371 {
372 	struct flash_wb0x_data *data = dev->data;
373 	int res;
374 
375 	if (!size) {
376 		return 0;
377 	}
378 
379 	if (!is_erasable_flash_range(dev, offset, size)) {
380 		return -EINVAL;
381 	}
382 
383 	/* Acquire driver lock */
384 	res = k_sem_take(&data->write_lock, K_NO_WAIT);
385 	if (res < 0) {
386 		return res;
387 	}
388 
389 	const uint32_t start_page = (uint32_t)offset / ERASE_BLOCK_SIZE;
390 	const uint32_t page_count = size / ERASE_BLOCK_SIZE;
391 
392 	res = erase_page_range(start_page, page_count);
393 
394 	/* Release driver lock */
395 	k_sem_give(&data->write_lock);
396 
397 	return res;
398 }
399 
flash_wb0x_get_parameters(const struct device * dev)400 const struct flash_parameters *flash_wb0x_get_parameters(
401 					const struct device *dev)
402 {
403 	static const struct flash_parameters fp = {
404 		.write_block_size = WRITE_BLOCK_SIZE,
405 		.erase_value = 0xff,
406 	};
407 
408 	return &fp;
409 }
410 
411 #if defined(CONFIG_FLASH_PAGE_LAYOUT)
flash_wb0x_pages_layout(const struct device * dev,const struct flash_pages_layout ** layout,size_t * layout_size)412 void flash_wb0x_pages_layout(const struct device *dev,
413 				const struct flash_pages_layout **layout,
414 				size_t *layout_size)
415 {
416 	/**
417 	 * STM32WB0 flash: single bank, 2KiB pages
418 	 * (the number of pages depends on MCU)
419 	 */
420 	static const struct flash_pages_layout fpl[] = {{
421 		.pages_count = PAGES_IN_FLASH,
422 		.pages_size = FLASH_PAGE_SIZE
423 	}};
424 
425 	*layout = fpl;
426 	*layout_size = ARRAY_SIZE(fpl);
427 }
428 #endif /* CONFIG_FLASH_PAGE_LAYOUT */
429 
430 static DEVICE_API(flash, flash_wb0x_api) = {
431 	.erase = flash_wb0x_erase,
432 	.write = flash_wb0x_write,
433 	.read = flash_wb0x_read,
434 	.get_parameters = flash_wb0x_get_parameters,
435 #ifdef CONFIG_FLASH_PAGE_LAYOUT
436 	.page_layout = flash_wb0x_pages_layout,
437 #endif
438 	/* extended operations not supported */
439 };
440 
stm32wb0x_flash_init(const struct device * dev)441 int stm32wb0x_flash_init(const struct device *dev)
442 {
443 	struct flash_wb0x_data *data = dev->data;
444 
445 	k_sem_init(&data->write_lock, 1, 1);
446 
447 	data->flash_size = get_flash_size_in_bytes();
448 
449 	return 0;
450 }
451 
452 /**
453  * Driver device instantiation
454  */
455 static struct flash_wb0x_data wb0x_flash_drv_data;
456 
457 DEVICE_DT_INST_DEFINE(0, stm32wb0x_flash_init, NULL,
458 		    &wb0x_flash_drv_data, NULL, POST_KERNEL,
459 		    CONFIG_FLASH_INIT_PRIORITY, &flash_wb0x_api);
460