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