1 /*
2  * Copyright (c) 2021 Vestas Wind Systems A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/hwinfo.h>
8 #include <zephyr/logging/log.h>
9 #include <fsl_rcm.h>
10 
11 LOG_MODULE_REGISTER(hwinfo_rcm, CONFIG_HWINFO_LOG_LEVEL);
12 
13 /**
14  * @brief Translate from RCM reset source mask to Zephyr hwinfo sources mask.
15  *
16  * Translate bitmask from MCUX RCM reset source bitmask to Zephyr
17  * hwinfo reset source bitmask.
18  *
19  * @param NXP MCUX RCM reset source mask.
20  * @retval Zephyr hwinfo reset source mask.
21  */
hwinfo_mcux_rcm_xlate_reset_sources(uint32_t sources)22 static uint32_t hwinfo_mcux_rcm_xlate_reset_sources(uint32_t sources)
23 {
24 	uint32_t mask = 0;
25 
26 #if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP)
27 	if (sources & kRCM_SourceWakeup) {
28 		mask |= RESET_LOW_POWER_WAKE;
29 	}
30 #endif /* (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP) */
31 
32 	if (sources & kRCM_SourceLvd) {
33 		mask |= RESET_BROWNOUT;
34 	}
35 
36 #if (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC)
37 	if (sources & kRCM_SourceLoc) {
38 		mask |= RESET_CLOCK;
39 	}
40 #endif /* (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC) */
41 
42 #if (defined(FSL_FEATURE_RCM_HAS_LOL) && FSL_FEATURE_RCM_HAS_LOL)
43 	if (sources & kRCM_SourceLol) {
44 		mask |= RESET_PLL;
45 	}
46 #endif /*  (defined(FSL_FEATURE_RCM_HAS_LOL) && FSL_FEATURE_RCM_HAS_LOL) */
47 
48 	if (sources & kRCM_SourceWdog) {
49 		mask |= RESET_WATCHDOG;
50 	}
51 
52 	if (sources & kRCM_SourcePin) {
53 		mask |= RESET_PIN;
54 	}
55 
56 	if (sources & kRCM_SourcePor) {
57 		mask |= RESET_POR;
58 	}
59 
60 #if (defined(FSL_FEATURE_RCM_HAS_JTAG) && FSL_FEATURE_RCM_HAS_JTAG)
61 	if (sources & kRCM_SourceJtag) {
62 		mask |= RESET_DEBUG;
63 	}
64 #endif /* (defined(FSL_FEATURE_RCM_HAS_JTAG) && FSL_FEATURE_RCM_HAS_JTAG) */
65 
66 	if (sources & kRCM_SourceLockup) {
67 		mask |= RESET_CPU_LOCKUP;
68 	}
69 
70 	if (sources & kRCM_SourceSw) {
71 		mask |= RESET_SOFTWARE;
72 	}
73 
74 #if (defined(FSL_FEATURE_RCM_HAS_MDM_AP) && FSL_FEATURE_RCM_HAS_MDM_AP)
75 	if (sources & kRCM_SourceMdmap) {
76 		mask |= RESET_DEBUG;
77 	}
78 #endif /* (defined(FSL_FEATURE_RCM_HAS_MDM_AP) && FSL_FEATURE_RCM_HAS_MDM_AP) */
79 
80 #if (defined(FSL_FEATURE_RCM_HAS_EZPORT) && FSL_FEATURE_RCM_HAS_EZPORT)
81 	if (sources & kRCM_SourceEzpt) {
82 		mask |= RESET_DEBUG;
83 	}
84 #endif /*  (defined(FSL_FEATURE_RCM_HAS_EZPORT) && FSL_FEATURE_RCM_HAS_EZPORT) */
85 
86 	return mask;
87 }
88 
z_impl_hwinfo_get_reset_cause(uint32_t * cause)89 int z_impl_hwinfo_get_reset_cause(uint32_t *cause)
90 {
91 	uint32_t sources;
92 
93 #if (defined(FSL_FEATURE_RCM_HAS_SSRS) && FSL_FEATURE_RCM_HAS_SSRS)
94 	sources = RCM_GetStickyResetSources(RCM) & kRCM_SourceAll;
95 #else /* (defined(FSL_FEATURE_RCM_HAS_SSRS) && FSL_FEATURE_RCM_HAS_SSRS) */
96 	sources = RCM_GetPreviousResetSources(RCM) & kRCM_SourceAll;
97 #endif /* !(defined(FSL_FEATURE_RCM_HAS_PARAM) && FSL_FEATURE_RCM_HAS_PARAM) */
98 
99 	*cause = hwinfo_mcux_rcm_xlate_reset_sources(sources);
100 
101 	LOG_DBG("sources = 0x%08x, cause = 0x%08x", sources, *cause);
102 
103 	return 0;
104 }
105 
106 #if (defined(FSL_FEATURE_RCM_HAS_SSRS) && FSL_FEATURE_RCM_HAS_SSRS)
z_impl_hwinfo_clear_reset_cause(void)107 int z_impl_hwinfo_clear_reset_cause(void)
108 {
109 	uint32_t sources;
110 
111 	sources = RCM_GetStickyResetSources(RCM) & kRCM_SourceAll;
112 	RCM_ClearStickyResetSources(RCM, sources);
113 
114 	LOG_DBG("sources = 0x%08x", sources);
115 
116 	return 0;
117 }
118 #endif /* (defined(FSL_FEATURE_RCM_HAS_SSRS) && FSL_FEATURE_RCM_HAS_SSRS) */
119 
120 #if (defined(FSL_FEATURE_RCM_HAS_PARAM) && FSL_FEATURE_RCM_HAS_PARAM)
z_impl_hwinfo_get_supported_reset_cause(uint32_t * supported)121 int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported)
122 {
123 	uint32_t sources;
124 
125 	sources = RCM_GetResetSourceImplementedStatus(RCM);
126 	*supported = hwinfo_mcux_rcm_xlate_reset_sources(sources);
127 
128 	LOG_DBG("sources = 0x%08x, supported = 0x%08x", sources, *supported);
129 
130 	return 0;
131 }
132 #endif /* (defined(FSL_FEATURE_RCM_HAS_PARAM) && FSL_FEATURE_RCM_HAS_PARAM) */
133