xref: /optee_os/core/drivers/rstctrl/stm32_rstctrl.c (revision f354a5d8f98eb3bc8f3360eccd7405144266b5b4)
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 
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 
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 
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 
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 
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 
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 
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 
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 static struct rstctrl *stm32_rstctrl_get_dev(struct dt_driver_phandle_args *arg,
182 					     void *priv_data __unused,
183 					     TEE_Result *res)
184 {
185 	struct stm32_rstline *stm32_rstline = NULL;
186 	uintptr_t control_id = 0;
187 
188 	if (arg->args_count != 1) {
189 		*res = TEE_ERROR_BAD_PARAMETERS;
190 		return NULL;
191 	}
192 	control_id = arg->args[0];
193 
194 	stm32_rstline = find_or_allocate_rstline(control_id);
195 	if (!stm32_rstline) {
196 		*res = TEE_ERROR_OUT_OF_MEMORY;
197 		return NULL;
198 	}
199 
200 	*res = TEE_SUCCESS;
201 	return &stm32_rstline->rstctrl;
202 }
203 
204 static TEE_Result stm32_rstctrl_provider_probe(const void *fdt, int offs,
205 					       const void *compat_data __unused)
206 {
207 	struct dt_node_info info = { };
208 
209 	assert(rstctrl_ops_is_valid(&stm32_rstctrl_ops));
210 
211 	fdt_fill_device_info(fdt, &info, offs);
212 
213 	assert(info.reg == RCC_BASE &&
214 	       info.reg_size != DT_INFO_INVALID_REG_SIZE);
215 
216 	return rstctrl_register_provider(fdt, offs, stm32_rstctrl_get_dev,
217 					 NULL);
218 }
219 
220 static const struct dt_device_match stm32_rstctrl_match_table[] = {
221 	{ .compatible = "st,stm32mp1-rcc" },
222 	{ .compatible = "st,stm32mp1-rcc-secure" },
223 	{ }
224 };
225 
226 DEFINE_DT_DRIVER(stm32_rstctrl_dt_driver) = {
227 	.name = "stm32_rstctrl",
228 	.type = DT_DRIVER_RSTCTRL,
229 	.match_table = stm32_rstctrl_match_table,
230 	.probe = stm32_rstctrl_provider_probe,
231 };
232