1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2018-2019, STMicroelectronics
4  */
5 
6 #include <drivers/stm32mp1_rcc.h>
7 #include <io.h>
8 #include <kernel/delay.h>
9 #include <kernel/panic.h>
10 #include <mm/core_memprot.h>
11 #include <platform_config.h>
12 #include <stm32_util.h>
13 #include <tee_api_defines.h>
14 
15 #define RESET_ID_MASK		GENMASK_32(31, 5)
16 #define RESET_ID_SHIFT		5
17 #define RESET_BIT_POS_MASK	GENMASK_32(4, 0)
18 
stm32_rcc_base(void)19 vaddr_t stm32_rcc_base(void)
20 {
21 	static struct io_pa_va base = { .pa = RCC_BASE };
22 
23 	return io_pa_or_va_secure(&base, 1);
24 }
25 
reset_id2reg_offset(unsigned int id)26 static size_t reset_id2reg_offset(unsigned int id)
27 {
28 	return ((id & RESET_ID_MASK) >> RESET_ID_SHIFT) * sizeof(uint32_t);
29 }
30 
reset_id2reg_bit_pos(unsigned int reset_id)31 static uint8_t reset_id2reg_bit_pos(unsigned int reset_id)
32 {
33 	return reset_id & RESET_BIT_POS_MASK;
34 }
35 
stm32_reset_assert(unsigned int id,unsigned int to_us)36 TEE_Result stm32_reset_assert(unsigned int id, unsigned int to_us)
37 {
38 	size_t offset = reset_id2reg_offset(id);
39 	uint32_t bitmsk = BIT(reset_id2reg_bit_pos(id));
40 	vaddr_t rcc_base = stm32_rcc_base();
41 
42 	io_write32(rcc_base + offset, bitmsk);
43 
44 	if (to_us) {
45 		uint64_t timeout_ref = timeout_init_us(to_us);
46 
47 		while (!(io_read32(rcc_base + offset) & bitmsk))
48 			if (timeout_elapsed(timeout_ref))
49 				break;
50 
51 		if (!(io_read32(rcc_base + offset) & bitmsk))
52 			return TEE_ERROR_SECURITY;
53 	}
54 
55 	return TEE_SUCCESS;
56 }
57 
stm32_reset_deassert(unsigned int id,unsigned int to_us)58 TEE_Result stm32_reset_deassert(unsigned int id, unsigned int to_us)
59 {
60 	size_t offset = reset_id2reg_offset(id) + RCC_MP_RSTCLRR_OFFSET;
61 	uint32_t bitmsk = BIT(reset_id2reg_bit_pos(id));
62 	vaddr_t rcc_base = stm32_rcc_base();
63 
64 	io_write32(rcc_base + offset, bitmsk);
65 
66 	if (to_us) {
67 		uint64_t timeout_ref = timeout_init_us(to_us);
68 
69 		while ((io_read32(rcc_base + offset) & bitmsk))
70 			if (timeout_elapsed(timeout_ref))
71 				break;
72 
73 		if (io_read32(rcc_base + offset) & bitmsk)
74 			return TEE_ERROR_SECURITY;
75 	}
76 
77 	return TEE_SUCCESS;
78 }
79 
stm32_reset_assert_deassert_mcu(bool assert_not_deassert)80 void stm32_reset_assert_deassert_mcu(bool assert_not_deassert)
81 {
82 	vaddr_t rcc_base = stm32_rcc_base();
83 
84 	/*
85 	 * The RCC_MP_GCR is a read/write register.
86 	 * Assert the MCU HOLD_BOOT means clear the BOOT_MCU bit
87 	 * Deassert the MCU HOLD_BOOT means set the BOOT_MCU the bit
88 	 */
89 	if (assert_not_deassert)
90 		io_clrbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU);
91 	else
92 		io_setbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU);
93 }
94