1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
4  */
5 
6 #include <assert.h>
7 #include <drivers/clk.h>
8 #include <drivers/clk_dt.h>
9 #include <drivers/stm32_iwdg.h>
10 #include <drivers/wdt.h>
11 #include <io.h>
12 #include <keep.h>
13 #include <kernel/boot.h>
14 #include <kernel/delay.h>
15 #include <kernel/dt.h>
16 #include <kernel/interrupt.h>
17 #include <kernel/misc.h>
18 #include <kernel/panic.h>
19 #include <kernel/pm.h>
20 #include <kernel/spinlock.h>
21 #include <libfdt.h>
22 #include <mm/core_memprot.h>
23 #include <sm/sm.h>
24 #include <stm32_util.h>
25 #include <string.h>
26 #include <trace.h>
27 
28 /* IWDG Compatibility */
29 #define IWDG_TIMEOUT_US		U(1000)
30 #define IWDG_CNT_MASK		GENMASK_32(11, 0)
31 
32 /* IWDG registers offsets */
33 #define IWDG_KR_OFFSET		U(0x00)
34 #define IWDG_PR_OFFSET		U(0x04)
35 #define IWDG_RLR_OFFSET		U(0x08)
36 #define IWDG_SR_OFFSET		U(0x0C)
37 #define IWDG_EWCR_OFFSET	U(0x14)
38 
39 #define IWDG_KR_ACCESS_KEY	U(0x5555)
40 #define IWDG_KR_RELOAD_KEY	U(0xAAAA)
41 #define IWDG_KR_START_KEY	U(0xCCCC)
42 
43 /* Use a fixed prescaler divider of 256 */
44 #define IWDG_PRESCALER_256	U(256)
45 #define IWDG_PR_DIV_256		U(0x06)
46 #define IWDG_PR_DIV_MASK	GENMASK_32(3, 0)
47 
48 #define IWDG_SR_PVU		BIT(0)
49 #define IWDG_SR_RVU		BIT(1)
50 #define IWDG_SR_WVU		BIT(2)
51 #define IWDG_SR_EWU		BIT(3)
52 #define IWDG_SR_UPDATE_MASK	(IWDG_SR_PVU | IWDG_SR_RVU | IWDG_SR_WVU | \
53 				 IWDG_SR_EWU)
54 
55 #define IWDG_EWCR_EWIE		BIT(15)
56 #define IWDG_EWCR_EWIC		BIT(14)
57 
58 /*
59  * Values for struct stm32_iwdg_device::flags
60  * IWDG_FLAGS_HW_ENABLED                Watchdog is enabled by BootROM
61  * IWDG_FLAGS_DISABLE_ON_STOP           Watchdog is freezed in SoC STOP mode
62  * IWDG_FLAGS_DISABLE_ON_STANDBY        Watchdog is freezed in SoC STANDBY mode
63  * IWDG_FLAGS_NON_SECURE                Instance is assigned to non-secure world
64  * IWDG_FLAGS_ENABLED			Watchdog has been enabled
65  */
66 #define IWDG_FLAGS_HW_ENABLED			BIT(0)
67 #define IWDG_FLAGS_DISABLE_ON_STOP		BIT(1)
68 #define IWDG_FLAGS_DISABLE_ON_STANDBY		BIT(2)
69 #define IWDG_FLAGS_NON_SECURE			BIT(3)
70 #define IWDG_FLAGS_ENABLED			BIT(4)
71 
72 /*
73  * IWDG watch instance data
74  * @base - IWDG interface IOMEM base address
75  * @clock - Bus clock
76  * @clk_lsi - IWDG source clock
77  * @flags - Property flags for the IWDG instance
78  * @timeout - Watchdog elaspure timeout
79  * @wdt_chip - Wathcdog chip instance
80  * @link - Link in registered watchdog instance list
81  */
82 struct stm32_iwdg_device {
83 	struct io_pa_va base;
84 	struct clk *clock;
85 	struct clk *clk_lsi;
86 	uint32_t flags;
87 	unsigned long timeout;
88 	struct wdt_chip wdt_chip;
89 	SLIST_ENTRY(stm32_iwdg_device) link;
90 };
91 
92 static unsigned int iwdg_lock = SPINLOCK_UNLOCK;
93 
94 static SLIST_HEAD(iwdg_dev_list_head, stm32_iwdg_device) iwdg_dev_list =
95 	SLIST_HEAD_INITIALIZER(iwdg_dev_list_head);
96 
get_base(struct stm32_iwdg_device * iwdg)97 static vaddr_t get_base(struct stm32_iwdg_device *iwdg)
98 {
99 	return io_pa_or_va(&iwdg->base, 1);
100 }
101 
is_assigned_to_nsec(struct stm32_iwdg_device * iwdg)102 static bool is_assigned_to_nsec(struct stm32_iwdg_device *iwdg)
103 {
104 	return iwdg->flags & IWDG_FLAGS_NON_SECURE;
105 }
106 
is_enable(struct stm32_iwdg_device * iwdg)107 static bool is_enable(struct stm32_iwdg_device *iwdg)
108 {
109 	return iwdg->flags & IWDG_FLAGS_ENABLED;
110 }
111 
112 /* Return counter value to related to input timeout in seconds, or 0 on error */
iwdg_timeout_cnt(struct stm32_iwdg_device * iwdg,unsigned long to_sec)113 static uint32_t iwdg_timeout_cnt(struct stm32_iwdg_device *iwdg,
114 				 unsigned long to_sec)
115 {
116 	uint64_t reload = (uint64_t)to_sec * clk_get_rate(iwdg->clk_lsi);
117 	uint64_t cnt = (reload / IWDG_PRESCALER_256) - 1;
118 
119 	/* Be safe and expect any counter to be above 2 */
120 	if (cnt > IWDG_CNT_MASK || cnt < 3)
121 		return 0;
122 
123 	return cnt;
124 }
125 
126 /* Wait IWDG programming completes */
iwdg_wait_sync(struct stm32_iwdg_device * iwdg)127 static TEE_Result iwdg_wait_sync(struct stm32_iwdg_device *iwdg)
128 {
129 	uint64_t timeout_ref = timeout_init_us(IWDG_TIMEOUT_US);
130 	vaddr_t iwdg_base = get_base(iwdg);
131 
132 	while (io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_UPDATE_MASK)
133 		if (timeout_elapsed(timeout_ref))
134 			break;
135 
136 	if (!(io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_UPDATE_MASK))
137 		return TEE_ERROR_GENERIC;
138 
139 	return TEE_SUCCESS;
140 }
141 
configure_timeout(struct stm32_iwdg_device * iwdg)142 static TEE_Result configure_timeout(struct stm32_iwdg_device *iwdg)
143 {
144 	TEE_Result res = TEE_ERROR_GENERIC;
145 	vaddr_t iwdg_base = get_base(iwdg);
146 	uint32_t rlr_value = 0;
147 
148 	assert(is_enable(iwdg));
149 
150 	rlr_value = iwdg_timeout_cnt(iwdg, iwdg->timeout);
151 	if (!rlr_value)
152 		return TEE_ERROR_GENERIC;
153 
154 	clk_enable(iwdg->clock);
155 
156 	io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_ACCESS_KEY);
157 	io_write32(iwdg_base + IWDG_PR_OFFSET, IWDG_PR_DIV_256);
158 	io_write32(iwdg_base + IWDG_RLR_OFFSET, rlr_value);
159 	io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_RELOAD_KEY);
160 
161 	res = iwdg_wait_sync(iwdg);
162 
163 	clk_disable(iwdg->clock);
164 
165 	return res;
166 }
167 
iwdg_start(struct stm32_iwdg_device * iwdg)168 static void iwdg_start(struct stm32_iwdg_device *iwdg)
169 {
170 	clk_enable(iwdg->clock);
171 	io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_START_KEY);
172 	clk_disable(iwdg->clock);
173 
174 	iwdg->flags |= IWDG_FLAGS_ENABLED;
175 }
176 
iwdg_refresh(struct stm32_iwdg_device * iwdg)177 static void iwdg_refresh(struct stm32_iwdg_device *iwdg)
178 {
179 	clk_enable(iwdg->clock);
180 	io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_RELOAD_KEY);
181 	clk_disable(iwdg->clock);
182 }
183 
184 /* Operators for watchdog OP-TEE interface */
wdt_chip_to_iwdg(struct wdt_chip * chip)185 static struct stm32_iwdg_device *wdt_chip_to_iwdg(struct wdt_chip *chip)
186 {
187 	return container_of(chip, struct stm32_iwdg_device, wdt_chip);
188 }
189 
iwdg_wdt_start(struct wdt_chip * chip)190 static void iwdg_wdt_start(struct wdt_chip *chip)
191 {
192 	struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip);
193 
194 	iwdg_start(iwdg);
195 
196 	if (configure_timeout(iwdg))
197 		panic();
198 }
199 
iwdg_wdt_refresh(struct wdt_chip * chip)200 static void iwdg_wdt_refresh(struct wdt_chip *chip)
201 {
202 	struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip);
203 
204 	iwdg_refresh(iwdg);
205 }
206 
iwdg_wdt_set_timeout(struct wdt_chip * chip,unsigned long timeout)207 static TEE_Result iwdg_wdt_set_timeout(struct wdt_chip *chip,
208 				       unsigned long timeout)
209 {
210 	struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip);
211 
212 	if (!iwdg_timeout_cnt(iwdg, timeout))
213 		return TEE_ERROR_BAD_PARAMETERS;
214 
215 	iwdg->timeout = timeout;
216 
217 	if (is_enable(iwdg)) {
218 		TEE_Result res = TEE_ERROR_GENERIC;
219 
220 		res = configure_timeout(iwdg);
221 		if (res)
222 			return res;
223 	}
224 
225 	return TEE_SUCCESS;
226 }
227 
228 static const struct wdt_ops stm32_iwdg_ops = {
229 	.start = iwdg_wdt_start,
230 	.ping = iwdg_wdt_refresh,
231 	.set_timeout = iwdg_wdt_set_timeout,
232 };
233 DECLARE_KEEP_PAGER(stm32_iwdg_ops);
234 
235 /* Refresh all registered watchdogs */
stm32_iwdg_refresh(void)236 void stm32_iwdg_refresh(void)
237 {
238 	struct stm32_iwdg_device *iwdg = NULL;
239 	uint32_t exceptions = cpu_spin_lock_xsave(&iwdg_lock);
240 
241 	SLIST_FOREACH(iwdg, &iwdg_dev_list, link)
242 		iwdg_refresh(iwdg);
243 
244 	cpu_spin_unlock_xrestore(&iwdg_lock, exceptions);
245 }
246 
247 /* Driver initialization */
stm32_iwdg_parse_fdt(struct stm32_iwdg_device * iwdg,const void * fdt,int node)248 static TEE_Result stm32_iwdg_parse_fdt(struct stm32_iwdg_device *iwdg,
249 				       const void *fdt, int node)
250 {
251 	TEE_Result res = TEE_ERROR_GENERIC;
252 	struct dt_node_info dt_info = { };
253 	const fdt32_t *cuint = NULL;
254 
255 	_fdt_fill_device_info(fdt, &dt_info, node);
256 
257 	if (dt_info.reg == DT_INFO_INVALID_REG ||
258 	    dt_info.reg_size == DT_INFO_INVALID_REG_SIZE)
259 		panic();
260 
261 	res = clk_dt_get_by_name(fdt, node, "pclk", &iwdg->clock);
262 	if (res)
263 		return res;
264 
265 	res = clk_dt_get_by_name(fdt, node, "lsi", &iwdg->clk_lsi);
266 	if (res)
267 		return res;
268 
269 	if (dt_info.status == DT_STATUS_OK_NSEC)
270 		iwdg->flags |= IWDG_FLAGS_NON_SECURE;
271 
272 	/* Get IOMEM address */
273 	iwdg->base.pa = dt_info.reg;
274 
275 	if (iwdg->flags & IWDG_FLAGS_NON_SECURE)
276 		io_pa_or_va_nsec(&iwdg->base, dt_info.reg_size);
277 	else
278 		io_pa_or_va_secure(&iwdg->base, dt_info.reg_size);
279 
280 	assert(iwdg->base.va);
281 
282 	/* Get and check timeout value */
283 	cuint = fdt_getprop(fdt, node, "timeout-sec", NULL);
284 	if (!cuint)
285 		return TEE_ERROR_BAD_PARAMETERS;
286 
287 	iwdg->timeout = (int)fdt32_to_cpu(*cuint);
288 	if (!iwdg->timeout)
289 		return TEE_ERROR_BAD_PARAMETERS;
290 
291 	if (!iwdg_timeout_cnt(iwdg, iwdg->timeout)) {
292 		EMSG("Timeout %lu not applicable", iwdg->timeout);
293 		return TEE_ERROR_BAD_PARAMETERS;
294 	}
295 
296 	/* DT can specify low power cases */
297 	if (!fdt_getprop(fdt, node, "stm32,enable-on-stop", NULL))
298 		iwdg->flags |= IWDG_FLAGS_DISABLE_ON_STOP;
299 
300 	if (!fdt_getprop(fdt, node, "stm32,enable-on-standby", NULL))
301 		iwdg->flags |= IWDG_FLAGS_DISABLE_ON_STANDBY;
302 
303 	return TEE_SUCCESS;
304 }
305 
306 /* Platform should override this function to provide IWDG fuses configuration */
stm32_get_iwdg_otp_config(paddr_t pbase __unused,struct stm32_iwdg_otp_data * otp_d)307 TEE_Result __weak stm32_get_iwdg_otp_config(paddr_t pbase __unused,
308 					    struct stm32_iwdg_otp_data *otp_d)
309 {
310 	otp_d->hw_enabled = false;
311 	otp_d->disable_on_stop = false;
312 	otp_d->disable_on_standby = false;
313 
314 	return TEE_SUCCESS;
315 }
316 
stm32_iwdg_setup(struct stm32_iwdg_device * iwdg,const void * fdt,int node)317 static TEE_Result stm32_iwdg_setup(struct stm32_iwdg_device *iwdg,
318 				   const void *fdt, int node)
319 {
320 	struct stm32_iwdg_otp_data otp_data = { };
321 	TEE_Result res = TEE_SUCCESS;
322 
323 	res = stm32_iwdg_parse_fdt(iwdg, fdt, node);
324 	if (res)
325 		return res;
326 
327 	res = stm32_get_iwdg_otp_config(iwdg->base.pa, &otp_data);
328 	if (res)
329 		return res;
330 
331 	if (otp_data.hw_enabled)
332 		iwdg->flags |= IWDG_FLAGS_HW_ENABLED;
333 	if (otp_data.disable_on_stop)
334 		iwdg->flags |= IWDG_FLAGS_DISABLE_ON_STOP;
335 	if (otp_data.disable_on_standby)
336 		iwdg->flags |= IWDG_FLAGS_DISABLE_ON_STANDBY;
337 
338 	/* Enable watchdog source clock once for all */
339 	clk_enable(iwdg->clk_lsi);
340 
341 	if (otp_data.hw_enabled) {
342 		iwdg->flags |= IWDG_FLAGS_ENABLED;
343 
344 		/* Configure timeout if watchdog is already enabled */
345 		res = configure_timeout(iwdg);
346 		if (res)
347 			return res;
348 
349 		iwdg_refresh(iwdg);
350 	}
351 
352 	return TEE_SUCCESS;
353 }
354 
stm32_iwdg_register(struct stm32_iwdg_device * iwdg)355 static TEE_Result stm32_iwdg_register(struct stm32_iwdg_device *iwdg)
356 {
357 	TEE_Result res = TEE_ERROR_GENERIC;
358 
359 	if (is_assigned_to_nsec(iwdg)) {
360 		stm32mp_register_non_secure_periph_iomem(iwdg->base.pa);
361 	} else {
362 		stm32mp_register_secure_periph_iomem(iwdg->base.pa);
363 
364 		/* Expose watchdog runtime service only to secure IWDG */
365 		iwdg->wdt_chip.ops = &stm32_iwdg_ops;
366 
367 		res = watchdog_register(&iwdg->wdt_chip);
368 		if (res)
369 			return res;
370 	}
371 
372 	SLIST_INSERT_HEAD(&iwdg_dev_list, iwdg, link);
373 
374 	return TEE_SUCCESS;
375 }
376 
stm32_iwdg_probe(const void * fdt,int node,const void * compat_data __unused)377 static TEE_Result stm32_iwdg_probe(const void *fdt, int node,
378 				   const void *compat_data __unused)
379 {
380 	struct stm32_iwdg_device *iwdg = NULL;
381 	TEE_Result res = TEE_SUCCESS;
382 
383 	iwdg = calloc(1, sizeof(*iwdg));
384 	if (!iwdg)
385 		return TEE_ERROR_OUT_OF_MEMORY;
386 
387 	res = stm32_iwdg_setup(iwdg, fdt, node);
388 	if (res)
389 		goto err;
390 
391 	res = stm32_iwdg_register(iwdg);
392 	if (res)
393 		goto err;
394 
395 	return TEE_SUCCESS;
396 
397 err:
398 	free(iwdg);
399 	return res;
400 }
401 
402 static const struct dt_device_match stm32_iwdg_match_table[] = {
403 	{ .compatible = "st,stm32mp1-iwdg" },
404 	{ }
405 };
406 
407 DEFINE_DT_DRIVER(stm32_iwdg_dt_driver) = {
408 	.name = "stm32-iwdg",
409 	.match_table = stm32_iwdg_match_table,
410 	.probe = stm32_iwdg_probe,
411 };
412