1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2021-2022, Linaro Limited
4 * Copyright (c) 2018-2022, STMicroelectronics
5 */
6
7 #include <drivers/rstctrl.h>
8 #include <drivers/stm32mp1_rcc.h>
9 #include <dt-bindings/reset/stm32mp1-resets.h>
10 #include <io.h>
11 #include <kernel/delay.h>
12 #include <kernel/dt.h>
13 #include <kernel/panic.h>
14 #include <mm/core_memprot.h>
15 #include <stm32_util.h>
16
17 #define RESET_ID_MASK GENMASK_32(31, 5)
18 #define RESET_ID_SHIFT 5
19 #define RESET_BIT_POS_MASK GENMASK_32(4, 0)
20 #define RESET_OFFSET_MAX 1024
21
22 /* Exposed rstctrl instance */
23 struct stm32_rstline {
24 unsigned int id;
25 struct rstctrl rstctrl;
26 SLIST_ENTRY(stm32_rstline) link;
27 };
28
29 static SLIST_HEAD(, stm32_rstline) stm32_rst_list =
30 SLIST_HEAD_INITIALIZER(stm32_rst_list);
31
reset_id2reg_offset(unsigned int id)32 static size_t reset_id2reg_offset(unsigned int id)
33 {
34 size_t offset = (id & RESET_ID_MASK) >> RESET_ID_SHIFT;
35
36 assert(offset < RESET_OFFSET_MAX);
37 return offset * sizeof(uint32_t);
38 }
39
reset_id2reg_bit_pos(unsigned int reset_id)40 static uint8_t reset_id2reg_bit_pos(unsigned int reset_id)
41 {
42 uint8_t pos = reset_id & RESET_BIT_POS_MASK;
43
44 assert(pos < 32);
45 return pos;
46 }
47
to_rstline(struct rstctrl * rstctrl)48 static struct stm32_rstline *to_rstline(struct rstctrl *rstctrl)
49 {
50 assert(rstctrl);
51
52 return container_of(rstctrl, struct stm32_rstline, rstctrl);
53 }
54
reset_assert(struct rstctrl * rstctrl,unsigned int to_us)55 static TEE_Result reset_assert(struct rstctrl *rstctrl, unsigned int to_us)
56 {
57 unsigned int id = to_rstline(rstctrl)->id;
58 vaddr_t rcc_base = stm32_rcc_base();
59 uint32_t bit_mask = 0;
60 size_t offset = 0;
61
62 switch (id) {
63 case MCU_HOLD_BOOT_R:
64 /*
65 * The RCC_MP_GCR is a read/write register.
66 * Assert the MCU HOLD_BOOT means clear the BOOT_MCU bit
67 */
68 io_clrbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU);
69
70 return TEE_SUCCESS;
71 case MCU_R:
72 /* MCU reset can only be written */
73 to_us = 0;
74 break;
75 default:
76 break;
77 }
78
79 offset = reset_id2reg_offset(id);
80 bit_mask = BIT(reset_id2reg_bit_pos(id));
81
82 io_write32(rcc_base + offset, bit_mask);
83
84 if (to_us) {
85 uint64_t timeout_ref = timeout_init_us(to_us);
86
87 while (!(io_read32(rcc_base + offset) & bit_mask))
88 if (timeout_elapsed(timeout_ref))
89 break;
90
91 if (!(io_read32(rcc_base + offset) & bit_mask))
92 return TEE_ERROR_SECURITY;
93 }
94
95 return TEE_SUCCESS;
96 }
97
reset_deassert(struct rstctrl * rstctrl,unsigned int to_us)98 static TEE_Result reset_deassert(struct rstctrl *rstctrl, unsigned int to_us)
99 {
100 unsigned int id = to_rstline(rstctrl)->id;
101 vaddr_t rcc_base = stm32_rcc_base();
102 uint32_t bit_mask = 0;
103 size_t offset = 0;
104
105 switch (id) {
106 case MCU_HOLD_BOOT_R:
107 /*
108 * The RCC_MP_GCR is a read/write register.
109 * Deassert the MCU HOLD_BOOT means set the BOOT_MCU the bit
110 */
111 io_setbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU);
112
113 return TEE_SUCCESS;
114 case MCU_R:
115 /* MCU reset deasserts by its own */
116 return TEE_SUCCESS;
117 default:
118 break;
119 }
120
121 offset = reset_id2reg_offset(id) + RCC_MP_RSTCLRR_OFFSET;
122 bit_mask = BIT(reset_id2reg_bit_pos(id));
123
124 io_write32(rcc_base + offset, bit_mask);
125
126 if (to_us) {
127 uint64_t timeout_ref = timeout_init_us(to_us);
128
129 while ((io_read32(rcc_base + offset) & bit_mask))
130 if (timeout_elapsed(timeout_ref))
131 break;
132
133 if (io_read32(rcc_base + offset) & bit_mask)
134 return TEE_ERROR_SECURITY;
135 }
136
137 return TEE_SUCCESS;
138 }
139
140 static struct rstctrl_ops stm32_rstctrl_ops = {
141 .assert_level = reset_assert,
142 .deassert_level = reset_deassert,
143 };
144
find_rstctrl_device(unsigned int control_id)145 static struct stm32_rstline *find_rstctrl_device(unsigned int control_id)
146 {
147 struct stm32_rstline *stm32_rstline = NULL;
148
149 SLIST_FOREACH(stm32_rstline, &stm32_rst_list, link)
150 if (stm32_rstline->id == control_id)
151 break;
152
153 return stm32_rstline;
154 }
155
find_or_allocate_rstline(unsigned int binding_id)156 static struct stm32_rstline *find_or_allocate_rstline(unsigned int binding_id)
157 {
158 struct stm32_rstline *stm32_rstline = find_rstctrl_device(binding_id);
159
160 if (stm32_rstline)
161 return stm32_rstline;
162
163 stm32_rstline = calloc(1, sizeof(*stm32_rstline));
164 if (stm32_rstline) {
165 stm32_rstline->rstctrl.ops = &stm32_rstctrl_ops;
166 stm32_rstline->id = binding_id;
167 SLIST_INSERT_HEAD(&stm32_rst_list, stm32_rstline, link);
168 }
169
170 return stm32_rstline;
171 }
172
stm32mp_rcc_reset_id_to_rstctrl(unsigned int binding_id)173 struct rstctrl *stm32mp_rcc_reset_id_to_rstctrl(unsigned int binding_id)
174 {
175 struct stm32_rstline *rstline = find_or_allocate_rstline(binding_id);
176
177 assert(rstline);
178 return &rstline->rstctrl;
179 }
180
181 #ifdef CFG_EMBED_DTB
stm32_rstctrl_get_dev(struct dt_driver_phandle_args * arg,void * priv_data __unused,TEE_Result * res)182 static struct rstctrl *stm32_rstctrl_get_dev(struct dt_driver_phandle_args *arg,
183 void *priv_data __unused,
184 TEE_Result *res)
185 {
186 struct stm32_rstline *stm32_rstline = NULL;
187 uintptr_t control_id = 0;
188
189 if (arg->args_count != 1) {
190 *res = TEE_ERROR_BAD_PARAMETERS;
191 return NULL;
192 }
193 control_id = arg->args[0];
194
195 stm32_rstline = find_or_allocate_rstline(control_id);
196 if (!stm32_rstline) {
197 *res = TEE_ERROR_OUT_OF_MEMORY;
198 return NULL;
199 }
200
201 *res = TEE_SUCCESS;
202 return &stm32_rstline->rstctrl;
203 }
204
stm32_rstctrl_provider_probe(const void * fdt,int offs,const void * compat_data __unused)205 static TEE_Result stm32_rstctrl_provider_probe(const void *fdt, int offs,
206 const void *compat_data __unused)
207 {
208 struct dt_node_info info = { };
209
210 assert(rstctrl_ops_is_valid(&stm32_rstctrl_ops));
211
212 _fdt_fill_device_info(fdt, &info, offs);
213
214 assert(info.reg == RCC_BASE &&
215 info.reg_size != DT_INFO_INVALID_REG_SIZE);
216
217 return rstctrl_register_provider(fdt, offs, stm32_rstctrl_get_dev,
218 NULL);
219 }
220
221 static const struct dt_device_match stm32_rstctrl_match_table[] = {
222 { .compatible = "st,stm32mp1-rcc" },
223 { .compatible = "st,stm32mp1-rcc-secure" },
224 { }
225 };
226
227 DEFINE_DT_DRIVER(stm32_rstctrl_dt_driver) = {
228 .name = "stm32_rstctrl",
229 .type = DT_DRIVER_RSTCTRL,
230 .match_table = stm32_rstctrl_match_table,
231 .probe = stm32_rstctrl_provider_probe,
232 };
233 #endif /*CFG_EMBED_DTB*/
234