1 /*
2  * Copyright (c) 2021 Sun Amar
3  * Copyright (c) 2021 Yonatan Schachter
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <em_system.h>
9 #include <em_rmu.h>
10 #include <drivers/hwinfo.h>
11 #include <string.h>
12 #include <sys/byteorder.h>
13 
14 #if defined(RMU_RSTCAUSE_BODUNREGRST) || defined(RMU_RSTCAUSE_BODREGRST) || \
15     defined(RMU_RSTCAUSE_AVDDBOD) || defined(RMU_RSTCAUSE_DVDDBOD) || \
16     defined(RMU_RSTCAUSE_DECBOD) || defined(RMU_RSTCAUSE_BODAVDD0) || \
17     defined(RMU_RSTCAUSE_BODAVDD1) || \
18     (defined(BU_PRESENT) && defined(_SILICON_LABS_32B_SERIES_0))
19 #define HAS_BROWNOUT 1
20 #endif
21 
z_impl_hwinfo_get_device_id(uint8_t * buffer,size_t length)22 ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length)
23 {
24 	uint64_t unique_id = sys_cpu_to_be64(SYSTEM_GetUnique());
25 
26 	if (length > sizeof(unique_id)) {
27 		length = sizeof(unique_id);
28 	}
29 
30 	memcpy(buffer, &unique_id, length);
31 
32 	return length;
33 }
34 
z_impl_hwinfo_get_reset_cause(uint32_t * cause)35 int z_impl_hwinfo_get_reset_cause(uint32_t *cause)
36 {
37 	uint32_t flags = 0;
38 	uint32_t rmu_flags = RMU_ResetCauseGet();
39 
40 	if (rmu_flags & RMU_RSTCAUSE_PORST) {
41 		flags |= RESET_POR;
42 	}
43 
44 	if (rmu_flags & RMU_RSTCAUSE_EXTRST) {
45 		flags |= RESET_PIN;
46 	}
47 
48 	if (rmu_flags & RMU_RSTCAUSE_SYSREQRST) {
49 		flags |= RESET_SOFTWARE;
50 	}
51 
52 	if (rmu_flags & RMU_RSTCAUSE_LOCKUPRST) {
53 		flags |= RESET_CPU_LOCKUP;
54 	}
55 
56 	if (rmu_flags & RMU_RSTCAUSE_WDOGRST) {
57 		flags |= RESET_WATCHDOG;
58 	}
59 
60 #ifdef RMU_RSTCAUSE_EM4WURST
61 	if (rmu_flags & RMU_RSTCAUSE_EM4WURST) {
62 		flags |= RESET_LOW_POWER_WAKE;
63 	}
64 #endif /* RMU_RSTCAUSE_EM4WURST */
65 
66 #ifdef RMU_RSTCAUSE_EM4RST
67 	if (rmu_flags & RMU_RSTCAUSE_EM4RST) {
68 		flags |= RESET_LOW_POWER_WAKE;
69 	}
70 #endif /* RMU_RSTCAUSE_EM4RST */
71 
72 #ifdef RMU_RSTCAUSE_BODUNREGRST
73 	if (rmu_flags & RMU_RSTCAUSE_BODUNREGRST) {
74 		flags |= RESET_BROWNOUT;
75 	}
76 #endif /* RMU_RSTCAUSE_BODUNREGRST */
77 
78 #ifdef RMU_RSTCAUSE_BODREGRST
79 	if (rmu_flags & RMU_RSTCAUSE_BODREGRST) {
80 		flags |= RESET_BROWNOUT;
81 	}
82 #endif /* RMU_RSTCAUSE_BODREGRST */
83 
84 #ifdef RMU_RSTCAUSE_AVDDBOD
85 	if (rmu_flags & RMU_RSTCAUSE_AVDDBOD) {
86 		flags |= RESET_BROWNOUT;
87 	}
88 #endif /* RMU_RSTCAUSE_AVDDBOD */
89 
90 #ifdef RMU_RSTCAUSE_DVDDBOD
91 	if (rmu_flags & RMU_RSTCAUSE_DVDDBOD) {
92 		flags |= RESET_BROWNOUT;
93 	}
94 #endif /* RMU_RSTCAUSE_DVDDBOD */
95 
96 #ifdef RMU_RSTCAUSE_DECBOD
97 	if (rmu_flags & RMU_RSTCAUSE_DECBOD) {
98 		flags |= RESET_BROWNOUT;
99 	}
100 #endif /* RMU_RSTCAUSE_DECBOD */
101 
102 #ifdef RMU_RSTCAUSE_BODAVDD0
103 	if (rmu_flags & RMU_RSTCAUSE_BODAVDD0) {
104 		flags |= RESET_BROWNOUT;
105 	}
106 #endif /* RMU_RSTCAUSE_BODAVDD0 */
107 
108 #ifdef RMU_RSTCAUSE_BODAVDD1
109 	if (rmu_flags & RMU_RSTCAUSE_BODAVDD1) {
110 		flags |= RESET_BROWNOUT;
111 	}
112 #endif /* RMU_RSTCAUSE_BODAVDD1 */
113 
114 #if defined(BU_PRESENT) && defined(_SILICON_LABS_32B_SERIES_0)
115 	if (rmu_flags & RMU_RSTCAUSE_BUBODVDDDREG) {
116 		flags |= RESET_BROWNOUT;
117 	}
118 
119 	if (rmu_flags & RMU_RSTCAUSE_BUBODBUVIN) {
120 		flags |= RESET_BROWNOUT;
121 	}
122 
123 	if (rmu_flags & RMU_RSTCAUSE_BUBODUNREG) {
124 		flags |= RESET_BROWNOUT;
125 	}
126 
127 	if (rmu_flags & RMU_RSTCAUSE_BUBODREG) {
128 		flags |= RESET_BROWNOUT;
129 	}
130 
131 	if (rmu_flags & RMU_RSTCAUSE_BUMODERST) {
132 		flags |= RESET_BROWNOUT;
133 	}
134 
135 #elif defined(RMU_RSTCAUSE_BUMODERST)
136 	if (rmu_flags & RMU_RSTCAUSE_BUMODERST) {
137 		flags |= RESET_BROWNOUT;
138 	}
139 
140 #endif /* defined(BU_PRESENT) && defined(_SILICON_LABS_32B_SERIES_0) */
141 
142 	*cause = flags;
143 	return 0;
144 }
145 
z_impl_hwinfo_clear_reset_cause(void)146 int z_impl_hwinfo_clear_reset_cause(void)
147 {
148 	RMU_ResetCauseClear();
149 
150 	return 0;
151 }
152 
z_impl_hwinfo_get_supported_reset_cause(uint32_t * supported)153 int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported)
154 {
155 	*supported = RESET_PIN
156 			| RESET_SOFTWARE
157 			| RESET_POR
158 			| RESET_WATCHDOG
159 			| RESET_CPU_LOCKUP
160 #if defined(RMU_RSTCAUSE_EM4WURST) || defined(RMU_RSTCAUSE_EM4RST)
161 			| RESET_LOW_POWER_WAKE
162 #endif /* defined(RMU_RSTCAUSE_EM4WURST) || defined(RMU_RSTCAUSE_EM4RST) */
163 #if HAS_BROWNOUT
164 			| RESET_BROWNOUT
165 #endif /* HAS_BROWNOUT */
166 			;
167 	return 0;
168 }
169