1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2021-2022, Linaro Limited
4 * Copyright (c) 2018-2024, STMicroelectronics
5 */
6
7 #include <arm.h>
8 #include <drivers/rstctrl.h>
9 #include <drivers/stm32mp1_rcc.h>
10 #include <drivers/stm32mp_dt_bindings.h>
11 #include <io.h>
12 #include <keep.h>
13 #include <kernel/dt.h>
14 #include <kernel/dt_driver.h>
15 #include <stm32_util.h>
16
17 #include "stm32_rstctrl.h"
18
19 #define RESET_ID_MASK GENMASK_32(31, 5)
20 #define RESET_ID_SHIFT U(5)
21 #define RESET_BIT_POS_MASK GENMASK_32(4, 0)
22 #define RESET_OFFSET_MAX U(1024)
23
reset_id2reg_offset(unsigned int id)24 static size_t reset_id2reg_offset(unsigned int id)
25 {
26 size_t offset = (id & RESET_ID_MASK) >> RESET_ID_SHIFT;
27
28 assert(offset < RESET_OFFSET_MAX);
29 return offset * sizeof(uint32_t);
30 }
31
reset_id2reg_bit_pos(unsigned int reset_id)32 static uint32_t reset_id2reg_bit_pos(unsigned int reset_id)
33 {
34 uint32_t pos = reset_id & RESET_BIT_POS_MASK;
35
36 assert(pos < 32);
37 return pos;
38 }
39
reset_assert(struct rstctrl * rstctrl,unsigned int to_us)40 static TEE_Result reset_assert(struct rstctrl *rstctrl, unsigned int to_us)
41 {
42 unsigned int id = to_stm32_rstline(rstctrl)->id;
43 vaddr_t rcc_base = stm32_rcc_base();
44 uint32_t bit_mask = 0;
45 size_t offset = 0;
46
47 #ifdef CFG_STM32MP15
48 switch (id) {
49 case MCU_HOLD_BOOT_R:
50 /*
51 * The RCC_MP_GCR is a read/write register.
52 * Assert the MCU HOLD_BOOT means clear the BOOT_MCU bit
53 */
54 io_clrbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU);
55
56 return TEE_SUCCESS;
57 case MCU_R:
58 /* MCU reset can only be written */
59 to_us = 0;
60 break;
61 default:
62 break;
63 }
64 #endif
65
66 offset = reset_id2reg_offset(id);
67 bit_mask = BIT(reset_id2reg_bit_pos(id));
68
69 io_write32(rcc_base + offset, bit_mask);
70
71 if (to_us) {
72 uint32_t value = 0;
73
74 if (IO_READ32_POLL_TIMEOUT(rcc_base + offset, value,
75 value & bit_mask, 0, to_us))
76 return TEE_ERROR_GENERIC;
77 } else {
78 /* Make sure the above write is performed */
79 dsb();
80 }
81
82 return TEE_SUCCESS;
83 }
84
reset_deassert(struct rstctrl * rstctrl,unsigned int to_us)85 static TEE_Result reset_deassert(struct rstctrl *rstctrl, unsigned int to_us)
86 {
87 unsigned int id = to_stm32_rstline(rstctrl)->id;
88 vaddr_t rcc_base = stm32_rcc_base();
89 uint32_t bit_mask = 0;
90 size_t offset = 0;
91
92 #ifdef CFG_STM32MP15
93 switch (id) {
94 case MCU_HOLD_BOOT_R:
95 /*
96 * The RCC_MP_GCR is a read/write register.
97 * Deassert the MCU HOLD_BOOT means set the BOOT_MCU the bit
98 */
99 io_setbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU);
100
101 return TEE_SUCCESS;
102 case MCU_R:
103 /* MCU reset deasserts by its own */
104 return TEE_SUCCESS;
105 default:
106 break;
107 }
108 #endif
109
110 offset = reset_id2reg_offset(id) + RCC_MP_RSTCLRR_OFFSET;
111 bit_mask = BIT(reset_id2reg_bit_pos(id));
112
113 io_write32(rcc_base + offset, bit_mask);
114
115 if (to_us) {
116 uint32_t value = 0;
117
118 if (IO_READ32_POLL_TIMEOUT(rcc_base + offset, value,
119 !(value & bit_mask), 0, to_us))
120 return TEE_ERROR_GENERIC;
121 } else {
122 /* Make sure the above write is performed */
123 dsb();
124 }
125
126 return TEE_SUCCESS;
127 }
128
129 static const struct rstctrl_ops stm32_rstctrl_ops = {
130 .assert_level = reset_assert,
131 .deassert_level = reset_deassert,
132 };
133 DECLARE_KEEP_PAGER(stm32_rstctrl_ops);
134
stm32_reset_get_ops(unsigned int id __unused)135 static const struct rstctrl_ops *stm32_reset_get_ops(unsigned int id __unused)
136 {
137 return &stm32_rstctrl_ops;
138 }
139
140 static const struct stm32_reset_data stm32mp1_reset_data = {
141 .get_rstctrl_ops = stm32_reset_get_ops
142 };
143 DECLARE_KEEP_PAGER(stm32mp1_reset_data);
144
145 static const struct dt_device_match stm32_rstctrl_match_table[] = {
146 {
147 .compatible = "st,stm32mp1-rcc",
148 .compat_data = &stm32mp1_reset_data,
149 },
150 {
151 .compatible = "st,stm32mp1-rcc-secure",
152 .compat_data = &stm32mp1_reset_data,
153 },
154 {
155 .compatible = "st,stm32mp13-rcc",
156 .compat_data = &stm32mp1_reset_data,
157 },
158 { }
159 };
160
161 DEFINE_DT_DRIVER(stm32_rstctrl_dt_driver) = {
162 .name = "stm32_rstctrl",
163 .type = DT_DRIVER_RSTCTRL,
164 .match_table = stm32_rstctrl_match_table,
165 .probe = stm32_rstctrl_provider_probe,
166 };
167