xref: /optee_os/core/drivers/atmel_rstc.c (revision 9f34db38245c9b3a4e6e7e63eb78a75e23ab2da3)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2021, Microchip
4  */
5 
6 #include <drivers/atmel_rstc.h>
7 #include <io.h>
8 #include <kernel/dt.h>
9 #include <kernel/dt_driver.h>
10 #include <matrix.h>
11 #include <platform_config.h>
12 #include <tee_api_defines.h>
13 #include <tee_api_types.h>
14 #include <types_ext.h>
15 
16 #define AT91_RSTC_CR		0x0
17 #define AT91_RSTC_CR_KEY	SHIFT_U32(0xA5, 24)
18 #define AT91_RSTC_CR_PROCRST	BIT32(0)
19 #define AT91_RSTC_CR_PERRST	BIT32(2)
20 
21 #define AT91_RSTC_GRSTR		0xE4
22 #define AT91_RSTC_GRSTR_USB(x)	SHIFT_U32(1, 4 + (x))
23 
24 static vaddr_t rstc_base;
25 
26 bool atmel_rstc_available(void)
27 {
28 	return rstc_base != 0;
29 }
30 
31 void __noreturn atmel_rstc_reset(void)
32 {
33 	uint32_t val = AT91_RSTC_CR_KEY | AT91_RSTC_CR_PROCRST |
34 		       AT91_RSTC_CR_PERRST;
35 
36 	io_write32(rstc_base + AT91_RSTC_CR, val);
37 
38 	/*
39 	 * After the previous write, the CPU will reset so we will never hit
40 	 * this loop.
41 	 */
42 	while (true)
43 		;
44 }
45 
46 void sam_rstc_usb_por(unsigned char id, bool enable)
47 {
48 	if (!atmel_rstc_available())
49 		panic();
50 
51 	if (enable)
52 		io_setbits32(rstc_base + AT91_RSTC_GRSTR,
53 			     AT91_RSTC_GRSTR_USB(id));
54 	else
55 		io_clrbits32(rstc_base + AT91_RSTC_GRSTR,
56 			     AT91_RSTC_GRSTR_USB(id));
57 }
58 
59 /* Non-null reference for compat data */
60 static const uint8_t rstc_always_secure;
61 
62 static TEE_Result atmel_rstc_probe(const void *fdt, int node,
63 				   const void *compat_data)
64 
65 {
66 	size_t size = 0;
67 
68 	if (fdt_get_status(fdt, node) != DT_STATUS_OK_SEC)
69 		return TEE_ERROR_BAD_PARAMETERS;
70 
71 	if (compat_data != &rstc_always_secure)
72 		matrix_configure_periph_secure(AT91C_ID_SYS);
73 
74 	if (dt_map_dev(fdt, node, &rstc_base, &size, DT_MAP_AUTO) < 0)
75 		return TEE_ERROR_GENERIC;
76 
77 	return TEE_SUCCESS;
78 }
79 
80 static const struct dt_device_match atmel_rstc_match_table[] = {
81 	{ .compatible = "atmel,sama5d3-rstc" },
82 	{
83 		.compatible = "microchip,sama7g5-rstc",
84 		.compat_data = &rstc_always_secure,
85 	},
86 	{ }
87 };
88 
89 DEFINE_DT_DRIVER(atmel_rstc_dt_driver) = {
90 	.name = "atmel_rstc",
91 	.type = DT_DRIVER_NOTYPE,
92 	.match_table = atmel_rstc_match_table,
93 	.probe = atmel_rstc_probe,
94 };
95