1 /*
2  * Copyright (c) 2020 Vossloh Cogifer
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT st_stm32h7_flash_controller
8 
9 #include <zephyr/sys/util.h>
10 #include <zephyr/kernel.h>
11 #include <zephyr/device.h>
12 #include <string.h>
13 #include <zephyr/drivers/flash.h>
14 #include <zephyr/init.h>
15 #include <zephyr/sys/barrier.h>
16 #include <soc.h>
17 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
18 #include <stm32h7rsxx_ll_bus.h>
19 #include <stm32h7rsxx_ll_utils.h>
20 #else
21 #include <stm32h7xx_ll_bus.h>
22 #include <stm32h7xx_ll_utils.h>
23 #endif /* CONFIG_SOC_SERIES_STM32H7RSX */
24 
25 #include "flash_stm32.h"
26 #include "stm32_hsem.h"
27 
28 #define LOG_DOMAIN flash_stm32h7
29 #define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL
30 #include <zephyr/logging/log.h>
31 LOG_MODULE_REGISTER(LOG_DOMAIN);
32 
33 /* Let's wait for double the max erase time to be sure that the operation is
34  * completed.
35  */
36 #define STM32H7_FLASH_TIMEOUT	\
37 	(2 * DT_PROP(DT_INST(0, st_stm32_nv_flash), max_erase_time))
38 
39 #define STM32H7_M4_FLASH_SIZE DT_PROP_OR(DT_INST(0, st_stm32_nv_flash), bank2_flash_size, 0)
40 #ifdef CONFIG_CPU_CORTEX_M4
41 #if STM32H7_M4_FLASH_SIZE == 0
42 #error Flash driver on M4 requires the DT property bank2-flash-size
43 #else
44 #define REAL_FLASH_SIZE_KB (KB(STM32H7_M4_FLASH_SIZE * 2))
45 #endif
46 #else
47 #define REAL_FLASH_SIZE_KB KB(LL_GetFlashSize())
48 #endif
49 #define SECTOR_PER_BANK		((REAL_FLASH_SIZE_KB / FLASH_SECTOR_SIZE) / 2)
50 #if defined(DUAL_BANK)
51 #define STM32H7_SERIES_MAX_FLASH_KB	KB(2048)
52 #define BANK2_OFFSET	(STM32H7_SERIES_MAX_FLASH_KB / 2)
53 /* When flash is dual bank and flash size is smaller than Max flash size of
54  * the serie, there is a discontinuty between bank1 and bank2.
55  */
56 #define DISCONTINUOUS_BANKS (REAL_FLASH_SIZE_KB < STM32H7_SERIES_MAX_FLASH_KB)
57 #endif
58 
59 struct flash_stm32_sector_t {
60 	int sector_index;
61 	int bank;
62 	volatile uint32_t *cr;
63 	volatile uint32_t *sr;
64 };
65 
66 #if defined(CONFIG_MULTITHREADING) || defined(CONFIG_STM32H7_DUAL_CORE)
67 /*
68  * This is named flash_stm32_sem_take instead of flash_stm32_lock (and
69  * similarly for flash_stm32_sem_give) to avoid confusion with locking
70  * actual flash sectors.
71  */
_flash_stm32_sem_take(const struct device * dev)72 static inline void _flash_stm32_sem_take(const struct device *dev)
73 {
74 	k_sem_take(&FLASH_STM32_PRIV(dev)->sem, K_FOREVER);
75 	z_stm32_hsem_lock(CFG_HW_FLASH_SEMID, HSEM_LOCK_WAIT_FOREVER);
76 }
77 
_flash_stm32_sem_give(const struct device * dev)78 static inline void _flash_stm32_sem_give(const struct device *dev)
79 {
80 	z_stm32_hsem_unlock(CFG_HW_FLASH_SEMID);
81 	k_sem_give(&FLASH_STM32_PRIV(dev)->sem);
82 }
83 
84 #define flash_stm32_sem_init(dev) k_sem_init(&FLASH_STM32_PRIV(dev)->sem, 1, 1)
85 #define flash_stm32_sem_take(dev) _flash_stm32_sem_take(dev)
86 #define flash_stm32_sem_give(dev) _flash_stm32_sem_give(dev)
87 #else
88 #define flash_stm32_sem_init(dev)
89 #define flash_stm32_sem_take(dev)
90 #define flash_stm32_sem_give(dev)
91 #endif
92 
flash_stm32_valid_range(const struct device * dev,off_t offset,uint32_t len,bool write)93 bool flash_stm32_valid_range(const struct device *dev, off_t offset,
94 			     uint32_t len,
95 			     bool write)
96 {
97 #if defined(DUAL_BANK)
98 	if (DISCONTINUOUS_BANKS) {
99 		/*
100 		 * In case of bank1/2 discontinuity, the range should not
101 		 * start before bank2 and end beyond bank1 at the same time.
102 		 * Locations beyond bank2 are caught by flash_stm32_range_exists
103 		 */
104 		if ((offset < BANK2_OFFSET)
105 		    && (offset + len > REAL_FLASH_SIZE_KB / 2)) {
106 			LOG_ERR("Range ovelaps flash bank discontinuity");
107 			return false;
108 		}
109 	}
110 #endif
111 
112 	if (write) {
113 		if ((offset % (FLASH_NB_32BITWORD_IN_FLASHWORD * 4)) != 0) {
114 			LOG_ERR("Write offset not aligned on flashword length. "
115 				"Offset: 0x%lx, flashword length: %d",
116 				(unsigned long) offset, FLASH_NB_32BITWORD_IN_FLASHWORD * 4);
117 			return false;
118 		}
119 	}
120 	return flash_stm32_range_exists(dev, offset, len);
121 }
122 
flash_stm32_check_status(const struct device * dev)123 static int flash_stm32_check_status(const struct device *dev)
124 {
125 	FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
126 	/* The hardware corrects single ECC errors and detects double
127 	 * ECC errors. Corrected data is returned for single ECC
128 	 * errors, so in this case we just log a warning.
129 	 */
130 #ifdef DUAL_BANK
131 	uint32_t const error_bank2 = (FLASH_FLAG_ALL_ERRORS_BANK2
132 				      & ~FLASH_FLAG_SNECCERR_BANK2);
133 #endif
134 	uint32_t sr;
135 
136 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
137 	uint32_t const error_bank = (FLASH_FLAG_ECC_ERRORS
138 				      & ~FLASH_FLAG_SNECCERR
139 				      & ~FLASH_FLAG_DBECCERR);
140 
141 
142 	/* Read the Interrupt status flags. */
143 	sr = regs->ISR;
144 	if (sr & (FLASH_FLAG_SNECCERR)) {
145 		uint32_t word = regs->ECCSFADDR & FLASH_ECCSFADDR_SEC_FADD;
146 
147 		LOG_WRN("Bank%d ECC error at 0x%08x", 1,
148 			word * 4 * FLASH_NB_32BITWORD_IN_FLASHWORD);
149 	}
150 
151 	if (sr & (FLASH_FLAG_DBECCERR)) {
152 		uint32_t word = regs->ECCDFADDR & FLASH_ECCDFADDR_DED_FADD;
153 
154 		LOG_WRN("Bank%d ECC error at 0x%08x", 1,
155 			word * 4 * FLASH_NB_32BITWORD_IN_FLASHWORD);
156 	}
157 
158 	/* Clear the ECC flags (including FA) */
159 	regs->ICR = FLASH_FLAG_ECC_ERRORS;
160 	if (sr & error_bank) {
161 #else
162 	uint32_t const error_bank1 = (FLASH_FLAG_ALL_ERRORS_BANK1
163 				      & ~FLASH_FLAG_SNECCERR_BANK1);
164 
165 	/* Read the status flags. */
166 	sr = regs->SR1;
167 	if (sr & (FLASH_FLAG_SNECCERR_BANK1|FLASH_FLAG_DBECCERR_BANK1)) {
168 		uint32_t word = regs->ECC_FA1 & FLASH_ECC_FA_FAIL_ECC_ADDR;
169 
170 		LOG_WRN("Bank%d ECC error at 0x%08x", 1,
171 			word * 4 * FLASH_NB_32BITWORD_IN_FLASHWORD);
172 	}
173 	/* Clear the flags (including FA1R) */
174 	regs->CCR1 = FLASH_FLAG_ALL_BANK1;
175 
176 	if (sr & error_bank1) {
177 #endif /* CONFIG_SOC_SERIES_STM32H7RSX */
178 		LOG_ERR("Status Bank%d: 0x%08x", 1, sr);
179 		return -EIO;
180 	}
181 
182 #ifdef DUAL_BANK
183 	sr = regs->SR2;
184 	if (sr & (FLASH_FLAG_SNECCERR_BANK1|FLASH_FLAG_DBECCERR_BANK1)) {
185 		uint32_t word = regs->ECC_FA2 & FLASH_ECC_FA_FAIL_ECC_ADDR;
186 
187 		LOG_WRN("Bank%d ECC error at 0x%08x", 2,
188 			word * 4 * FLASH_NB_32BITWORD_IN_FLASHWORD);
189 	}
190 	regs->CCR2 = FLASH_FLAG_ALL_BANK2;
191 	if (sr & error_bank2) {
192 		LOG_ERR("Status Bank%d: 0x%08x", 2, sr);
193 		return -EIO;
194 	}
195 #endif
196 
197 	return 0;
198 }
199 
200 
201 int flash_stm32_wait_flash_idle(const struct device *dev)
202 {
203 	int64_t timeout_time = k_uptime_get() + STM32H7_FLASH_TIMEOUT;
204 	int rc;
205 
206 	rc = flash_stm32_check_status(dev);
207 	if (rc < 0) {
208 		return -EIO;
209 	}
210 #ifdef DUAL_BANK
211 	while ((FLASH_STM32_REGS(dev)->SR1 & FLASH_SR_QW)
212 	       || (FLASH_STM32_REGS(dev)->SR2 & FLASH_SR_QW))
213 #else
214 	while (FLASH_STM32_REGS(dev)->SR1 & FLASH_SR_QW)
215 #endif
216 	{
217 		if (k_uptime_get() > timeout_time) {
218 			LOG_ERR("Timeout! val: %d", STM32H7_FLASH_TIMEOUT);
219 			return -EIO;
220 		}
221 	}
222 
223 	return 0;
224 }
225 
226 static struct flash_stm32_sector_t get_sector(const struct device *dev,
227 					      off_t offset)
228 {
229 	struct flash_stm32_sector_t sector;
230 	FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
231 
232 #ifdef DUAL_BANK
233 	off_t temp_offset = offset + (CONFIG_FLASH_BASE_ADDRESS & 0xffffff);
234 
235 	bool bank_swap;
236 	/* Check whether bank1/2 are swapped */
237 	bank_swap = (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_SWAP_BANK)
238 			== FLASH_OPTCR_SWAP_BANK);
239 	sector.sector_index = offset / FLASH_SECTOR_SIZE;
240 	if ((temp_offset < (REAL_FLASH_SIZE_KB / 2)) && !bank_swap) {
241 		sector.bank = 1;
242 		sector.cr = &regs->CR1;
243 		sector.sr = &regs->SR1;
244 	} else if ((temp_offset >= BANK2_OFFSET) && bank_swap) {
245 		sector.sector_index -= BANK2_OFFSET / FLASH_SECTOR_SIZE;
246 		sector.bank = 1;
247 		sector.cr = &regs->CR2;
248 		sector.sr = &regs->SR2;
249 	} else if ((temp_offset < (REAL_FLASH_SIZE_KB / 2)) && bank_swap) {
250 		sector.bank = 2;
251 		sector.cr = &regs->CR1;
252 		sector.sr = &regs->SR1;
253 	} else if ((temp_offset >= BANK2_OFFSET) && !bank_swap) {
254 		sector.sector_index -= BANK2_OFFSET / FLASH_SECTOR_SIZE;
255 		sector.bank = 2;
256 		sector.cr = &regs->CR2;
257 		sector.sr = &regs->SR2;
258 	} else {
259 		sector.sector_index = 0;
260 		sector.bank = 0;
261 		sector.cr = NULL;
262 		sector.sr = NULL;
263 	}
264 #else
265 	if (offset < REAL_FLASH_SIZE_KB) {
266 		sector.sector_index = offset / FLASH_SECTOR_SIZE;
267 		sector.bank = 1;
268 		sector.cr = &regs->CR1;
269 		sector.sr = &regs->SR1;
270 	} else {
271 		sector.sector_index = 0;
272 		sector.bank = 0;
273 		sector.cr = NULL;
274 		sector.sr = NULL;
275 	}
276 #endif
277 
278 	return sector;
279 }
280 
281 static int erase_sector(const struct device *dev, int offset)
282 {
283 	int rc;
284 	struct flash_stm32_sector_t sector = get_sector(dev, offset);
285 
286 	if (sector.bank == 0) {
287 
288 		LOG_ERR("Offset %ld does not exist", (long) offset);
289 		return -EINVAL;
290 	}
291 
292 	/* if the control register is locked, do not fail silently */
293 	if (*(sector.cr) & FLASH_CR_LOCK) {
294 		return -EIO;
295 	}
296 
297 	rc = flash_stm32_wait_flash_idle(dev);
298 	if (rc < 0) {
299 		return rc;
300 	}
301 
302 	*(sector.cr) &= ~FLASH_CR_SNB;
303 	*(sector.cr) |= (FLASH_CR_SER
304 		| ((sector.sector_index << FLASH_CR_SNB_Pos) & FLASH_CR_SNB));
305 	*(sector.cr) |= FLASH_CR_START;
306 	/* flush the register write */
307 	barrier_dsync_fence_full();
308 
309 	rc = flash_stm32_wait_flash_idle(dev);
310 	*(sector.cr) &= ~(FLASH_CR_SER | FLASH_CR_SNB);
311 
312 	return rc;
313 }
314 
315 
316 int flash_stm32_block_erase_loop(const struct device *dev,
317 				 unsigned int offset,
318 				 unsigned int len)
319 {
320 	unsigned int address = offset;
321 	int rc = 0;
322 
323 	for (; address <= offset + len - 1 ; address += FLASH_SECTOR_SIZE) {
324 		rc = erase_sector(dev, address);
325 		if (rc < 0) {
326 			break;
327 		}
328 	}
329 	return rc;
330 }
331 
332 static int wait_write_queue(const struct flash_stm32_sector_t *sector)
333 {
334 	int64_t timeout_time = k_uptime_get() + 100;
335 
336 	while (*(sector->sr) & FLASH_SR_QW) {
337 		if (k_uptime_get() > timeout_time) {
338 			LOG_ERR("Timeout! val: %d", 100);
339 			return -EIO;
340 		}
341 	}
342 
343 	return 0;
344 }
345 
346 static int write_ndwords(const struct device *dev,
347 			 off_t offset, const uint64_t *data,
348 			 uint8_t n)
349 {
350 	volatile uint64_t *flash = (uint64_t *)(offset
351 						+ FLASH_STM32_BASE_ADDRESS);
352 	int rc;
353 	int i;
354 	struct flash_stm32_sector_t sector = get_sector(dev, offset);
355 
356 	if (sector.bank == 0) {
357 		LOG_ERR("Offset %ld does not exist", (long) offset);
358 		return -EINVAL;
359 	}
360 
361 	/* if the control register is locked, do not fail silently */
362 	if (*(sector.cr) & FLASH_CR_LOCK) {
363 		return -EIO;
364 	}
365 
366 	/* Check that no Flash main memory operation is ongoing */
367 	rc = flash_stm32_wait_flash_idle(dev);
368 	if (rc < 0) {
369 		return rc;
370 	}
371 
372 	/* Check if 256 bits location is erased */
373 	for (i = 0; i < n; ++i) {
374 		if (flash[i] != 0xFFFFFFFFFFFFFFFFUL) {
375 			return -EIO;
376 		}
377 	}
378 
379 	/* Set the PG bit */
380 	*(sector.cr) |= FLASH_CR_PG;
381 
382 	/* Flush the register write */
383 	barrier_dsync_fence_full();
384 
385 	/* Perform the data write operation at the desired memory address */
386 	for (i = 0; i < n; ++i) {
387 		/* Source dword may be unaligned, so take extra care when dereferencing it */
388 		flash[i] = UNALIGNED_GET(data + i);
389 
390 		/* Flush the data write */
391 		barrier_dsync_fence_full();
392 
393 		wait_write_queue(&sector);
394 	}
395 
396 	/* Wait until the BSY bit is cleared */
397 	rc = flash_stm32_wait_flash_idle(dev);
398 
399 	/* Clear the PG bit */
400 	*(sector.cr) &= (~FLASH_CR_PG);
401 
402 	return rc;
403 }
404 
405 int flash_stm32_write_range(const struct device *dev, unsigned int offset,
406 			    const void *data, unsigned int len)
407 {
408 	int rc = 0;
409 	int i, j;
410 	const uint8_t ndwords = FLASH_NB_32BITWORD_IN_FLASHWORD / 2;
411 	const uint8_t nbytes = FLASH_NB_32BITWORD_IN_FLASHWORD * 4;
412 	uint8_t unaligned_datas[nbytes];
413 
414 	for (i = 0; i < len && i + nbytes <= len; i += nbytes, offset += nbytes) {
415 		rc = write_ndwords(dev, offset,
416 				   (const uint64_t *) data + (i >> 3),
417 				   ndwords);
418 		if (rc < 0) {
419 			return rc;
420 		}
421 	}
422 
423 	/* Handle the remaining bytes if length is not aligned on
424 	 * FLASH_NB_32BITWORD_IN_FLASHWORD
425 	 */
426 	if (i < len) {
427 		memset(unaligned_datas, 0xff, sizeof(unaligned_datas));
428 		for (j = 0; j < len - i; ++j) {
429 			unaligned_datas[j] = ((uint8_t *)data)[i + j];
430 		}
431 		rc = write_ndwords(dev, offset,
432 				   (const uint64_t *)unaligned_datas,
433 				   ndwords);
434 		if (rc < 0) {
435 			return rc;
436 		}
437 	}
438 
439 	return rc;
440 }
441 
442 static int flash_stm32h7_write_protection(const struct device *dev, bool enable)
443 {
444 	FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
445 
446 	int rc = 0;
447 
448 	if (enable) {
449 		rc = flash_stm32_wait_flash_idle(dev);
450 		if (rc) {
451 			return rc;
452 		}
453 	}
454 
455 	/* Bank 1 */
456 	if (enable) {
457 		regs->CR1 |= FLASH_CR_LOCK;
458 	} else {
459 		if (regs->CR1 & FLASH_CR_LOCK) {
460 			regs->KEYR1 = FLASH_KEY1;
461 			regs->KEYR1 = FLASH_KEY2;
462 		}
463 	}
464 #ifdef DUAL_BANK
465 	/* Bank 2 */
466 	if (enable) {
467 		regs->CR2 |= FLASH_CR_LOCK;
468 	} else {
469 		if (regs->CR2 & FLASH_CR_LOCK) {
470 			regs->KEYR2 = FLASH_KEY1;
471 			regs->KEYR2 = FLASH_KEY2;
472 		}
473 	}
474 #endif
475 
476 	if (enable) {
477 		LOG_DBG("Enable write protection");
478 	} else {
479 		LOG_DBG("Disable write protection");
480 	}
481 
482 	return rc;
483 }
484 
485 #ifdef CONFIG_CPU_CORTEX_M7
486 static void flash_stm32h7_flush_caches(const struct device *dev,
487 				       off_t offset, size_t len)
488 {
489 	ARG_UNUSED(dev);
490 
491 	if (!(SCB->CCR & SCB_CCR_DC_Msk)) {
492 		return; /* Cache not enabled */
493 	}
494 
495 	SCB_InvalidateDCache_by_Addr((uint32_t *)(FLASH_STM32_BASE_ADDRESS
496 						  + offset), len);
497 }
498 #endif /* CONFIG_CPU_CORTEX_M7 */
499 
500 static int flash_stm32h7_erase(const struct device *dev, off_t offset,
501 			       size_t len)
502 {
503 	int rc, rc2;
504 
505 #ifdef CONFIG_CPU_CORTEX_M7
506 	/* Flush whole sectors */
507 	off_t flush_offset = ROUND_DOWN(offset, FLASH_SECTOR_SIZE);
508 	size_t flush_len = ROUND_UP(offset + len - 1, FLASH_SECTOR_SIZE)
509 		 - flush_offset;
510 #endif /* CONFIG_CPU_CORTEX_M7 */
511 
512 	if (!flash_stm32_valid_range(dev, offset, len, true)) {
513 		LOG_ERR("Erase range invalid. Offset: %ld, len: %zu",
514 			(long) offset, len);
515 		return -EINVAL;
516 	}
517 
518 	if (!len) {
519 		return 0;
520 	}
521 
522 	flash_stm32_sem_take(dev);
523 
524 	LOG_DBG("Erase offset: %ld, len: %zu", (long) offset, len);
525 
526 	rc = flash_stm32h7_write_protection(dev, false);
527 	if (rc) {
528 		goto done;
529 	}
530 
531 	rc = flash_stm32_block_erase_loop(dev, offset, len);
532 
533 #ifdef CONFIG_CPU_CORTEX_M7
534 	/* Flush cache on all sectors affected by the erase */
535 	flash_stm32h7_flush_caches(dev, flush_offset, flush_len);
536 #elif CONFIG_CPU_CORTEX_M4
537 	if (LL_AHB1_GRP1_IsEnabledClock(LL_AHB1_GRP1_PERIPH_ART)
538 		&& LL_ART_IsEnabled()) {
539 		LOG_ERR("Cortex M4: ART enabled not supported by flash driver");
540 	}
541 #endif /* CONFIG_CPU_CORTEX_M7 */
542 done:
543 	rc2 = flash_stm32h7_write_protection(dev, true);
544 
545 	if (!rc) {
546 		rc = rc2;
547 	}
548 
549 	flash_stm32_sem_give(dev);
550 
551 	return rc;
552 }
553 
554 
555 static int flash_stm32h7_write(const struct device *dev, off_t offset,
556 			       const void *data, size_t len)
557 {
558 	int rc;
559 
560 	if (!flash_stm32_valid_range(dev, offset, len, true)) {
561 		LOG_ERR("Write range invalid. Offset: %ld, len: %zu",
562 			(long) offset, len);
563 		return -EINVAL;
564 	}
565 
566 	if (!len) {
567 		return 0;
568 	}
569 
570 	flash_stm32_sem_take(dev);
571 
572 	LOG_DBG("Write offset: %ld, len: %zu", (long) offset, len);
573 
574 	rc = flash_stm32h7_write_protection(dev, false);
575 	if (!rc) {
576 		rc = flash_stm32_write_range(dev, offset, data, len);
577 	}
578 
579 	int rc2 = flash_stm32h7_write_protection(dev, true);
580 
581 	if (!rc) {
582 		rc = rc2;
583 	}
584 
585 	flash_stm32_sem_give(dev);
586 
587 	return rc;
588 }
589 
590 static int flash_stm32h7_read(const struct device *dev, off_t offset,
591 			      void *data,
592 			      size_t len)
593 {
594 	if (!flash_stm32_valid_range(dev, offset, len, false)) {
595 		LOG_ERR("Read range invalid. Offset: %ld, len: %zu",
596 			(long) offset, len);
597 		return -EINVAL;
598 	}
599 
600 	if (!len) {
601 		return 0;
602 	}
603 
604 	LOG_DBG("Read offset: %ld, len: %zu", (long) offset, len);
605 
606 	/* During the read we mask bus errors and only allow NMI.
607 	 *
608 	 * If the flash has a double ECC error then there is normally
609 	 * a bus fault, but we want to return an error code instead.
610 	 */
611 	unsigned int irq_lock_key = irq_lock();
612 
613 	__set_FAULTMASK(1);
614 	SCB->CCR |= SCB_CCR_BFHFNMIGN_Msk;
615 	barrier_dsync_fence_full();
616 	barrier_isync_fence_full();
617 
618 	memcpy(data, (uint8_t *) FLASH_STM32_BASE_ADDRESS + offset, len);
619 
620 	__set_FAULTMASK(0);
621 	SCB->CCR &= ~SCB_CCR_BFHFNMIGN_Msk;
622 	barrier_dsync_fence_full();
623 	barrier_isync_fence_full();
624 	irq_unlock(irq_lock_key);
625 
626 	return flash_stm32_check_status(dev);
627 }
628 
629 
630 static const struct flash_parameters flash_stm32h7_parameters = {
631 	.write_block_size = FLASH_STM32_WRITE_BLOCK_SIZE,
632 	.erase_value = 0xff,
633 };
634 
635 static const struct flash_parameters *
636 flash_stm32h7_get_parameters(const struct device *dev)
637 {
638 	ARG_UNUSED(dev);
639 
640 	return &flash_stm32h7_parameters;
641 }
642 
643 
644 void flash_stm32_page_layout(const struct device *dev,
645 			     const struct flash_pages_layout **layout,
646 			     size_t *layout_size)
647 {
648 	ARG_UNUSED(dev);
649 
650 #if defined(DUAL_BANK)
651 	static struct flash_pages_layout stm32h7_flash_layout[3];
652 
653 	if (DISCONTINUOUS_BANKS) {
654 		if (stm32h7_flash_layout[0].pages_count == 0) {
655 			/* Bank1 */
656 			stm32h7_flash_layout[0].pages_count = SECTOR_PER_BANK;
657 			stm32h7_flash_layout[0].pages_size = FLASH_SECTOR_SIZE;
658 			/*
659 			 * Dummy page corresponding to discontinuity
660 			 * between bank1/2
661 			 */
662 			stm32h7_flash_layout[1].pages_count = 1;
663 			stm32h7_flash_layout[1].pages_size = BANK2_OFFSET
664 					- (SECTOR_PER_BANK * FLASH_SECTOR_SIZE);
665 			/* Bank2 */
666 			stm32h7_flash_layout[2].pages_count = SECTOR_PER_BANK;
667 			stm32h7_flash_layout[2].pages_size = FLASH_SECTOR_SIZE;
668 		}
669 		*layout_size = ARRAY_SIZE(stm32h7_flash_layout);
670 	} else {
671 		if (stm32h7_flash_layout[0].pages_count == 0) {
672 			stm32h7_flash_layout[0].pages_count =
673 				REAL_FLASH_SIZE_KB / FLASH_SECTOR_SIZE;
674 			stm32h7_flash_layout[0].pages_size = FLASH_SECTOR_SIZE;
675 		}
676 		*layout_size = 1;
677 	}
678 #else
679 	static struct flash_pages_layout stm32h7_flash_layout[1];
680 
681 	if (stm32h7_flash_layout[0].pages_count == 0) {
682 		stm32h7_flash_layout[0].pages_count =
683 				REAL_FLASH_SIZE_KB / FLASH_SECTOR_SIZE;
684 		stm32h7_flash_layout[0].pages_size = FLASH_SECTOR_SIZE;
685 	}
686 	*layout_size = ARRAY_SIZE(stm32h7_flash_layout);
687 #endif
688 	*layout = stm32h7_flash_layout;
689 }
690 
691 static struct flash_stm32_priv flash_data = {
692 	.regs = (FLASH_TypeDef *) DT_INST_REG_ADDR(0),
693 	.pclken = { .bus = DT_INST_CLOCKS_CELL(0, bus),
694 		    .enr = DT_INST_CLOCKS_CELL(0, bits)},
695 };
696 
697 static const struct flash_driver_api flash_stm32h7_api = {
698 	.erase = flash_stm32h7_erase,
699 	.write = flash_stm32h7_write,
700 	.read = flash_stm32h7_read,
701 	.get_parameters = flash_stm32h7_get_parameters,
702 #ifdef CONFIG_FLASH_PAGE_LAYOUT
703 	.page_layout = flash_stm32_page_layout,
704 #endif
705 };
706 
707 static int stm32h7_flash_init(const struct device *dev)
708 {
709 	struct flash_stm32_priv *p = FLASH_STM32_PRIV(dev);
710 	const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
711 
712 	if (!device_is_ready(clk)) {
713 		LOG_ERR("clock control device not ready");
714 		return -ENODEV;
715 	}
716 
717 	/* enable clock */
718 	if (clock_control_on(clk, (clock_control_subsys_t)&p->pclken) != 0) {
719 		LOG_ERR("Failed to enable clock");
720 		return -EIO;
721 	}
722 
723 	flash_stm32_sem_init(dev);
724 
725 	LOG_DBG("Flash initialized. BS: %zu",
726 		flash_stm32h7_parameters.write_block_size);
727 
728 #if ((CONFIG_FLASH_LOG_LEVEL >= LOG_LEVEL_DBG) && CONFIG_FLASH_PAGE_LAYOUT)
729 	const struct flash_pages_layout *layout;
730 	size_t layout_size;
731 
732 	flash_stm32_page_layout(dev, &layout, &layout_size);
733 	for (size_t i = 0; i < layout_size; i++) {
734 		LOG_DBG("Block %zu: bs: %zu count: %zu", i,
735 			layout[i].pages_size, layout[i].pages_count);
736 	}
737 #endif
738 
739 	return flash_stm32h7_write_protection(dev, false);
740 }
741 
742 
743 DEVICE_DT_INST_DEFINE(0, stm32h7_flash_init, NULL,
744 		    &flash_data, NULL, POST_KERNEL,
745 		    CONFIG_FLASH_INIT_PRIORITY, &flash_stm32h7_api);
746