1 /*
2  * Copyright 2024 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/hwinfo.h>
8 
9 #include <fsl_ocotp.h>
10 #include <fsl_power.h>
11 
12 /* Because of the ROM clearing the reset register and using scratch register
13  * which cannot be cleared, we have to "fake" this to meet the hwinfo api.
14  * Technically all the reset causes are already cleared by the ROM, but we will
15  * still clear them ourselves on the first call to clear them by user.
16  */
17 static bool reset_cleared;
18 
z_impl_hwinfo_get_device_id(uint8_t * buffer,size_t length)19 ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length)
20 {
21 	uint32_t id_length = length;
22 
23 	if (OCOTP_ReadUniqueID(buffer, &id_length)) {
24 		return -EINVAL;
25 	}
26 
27 	return (ssize_t)id_length;
28 }
29 
z_impl_hwinfo_get_supported_reset_cause(uint32_t * supported)30 int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported)
31 {
32 	*supported = (
33 		RESET_SOFTWARE		|
34 		RESET_CPU_LOCKUP	|
35 		RESET_WATCHDOG		|
36 		RESET_SECURITY		|
37 		RESET_DEBUG		|
38 		RESET_HARDWARE
39 	);
40 
41 	return 0;
42 }
43 
z_impl_hwinfo_get_reset_cause(uint32_t * cause)44 int z_impl_hwinfo_get_reset_cause(uint32_t *cause)
45 {
46 	if (reset_cleared) {
47 		*cause = 0;
48 		return 0;
49 	}
50 
51 	uint32_t reset_cause = POWER_GetResetCause();
52 
53 	switch (reset_cause) {
54 	case kPOWER_ResetCauseSysResetReq:
55 		*cause = RESET_SOFTWARE;
56 		break;
57 	case kPOWER_ResetCauseLockup:
58 		*cause = RESET_CPU_LOCKUP;
59 		break;
60 	case kPOWER_ResetCauseWdt:
61 		*cause = RESET_WATCHDOG;
62 		break;
63 	case kPOWER_ResetCauseApResetReq:
64 		*cause = RESET_DEBUG;
65 		break;
66 	case kPOWER_ResetCauseCodeWdt:
67 	case kPOWER_ResetCauseItrc:
68 		*cause = RESET_SECURITY;
69 		break;
70 	case kPOWER_ResetCauseResetB:
71 		*cause = RESET_HARDWARE;
72 		break;
73 	default:
74 		*cause = 0;
75 		break;
76 	}
77 
78 	return 0;
79 }
80 
z_impl_hwinfo_clear_reset_cause(void)81 int z_impl_hwinfo_clear_reset_cause(void)
82 {
83 	POWER_ClearResetCause(kPOWER_ResetCauseAll);
84 
85 	reset_cleared = true;
86 
87 	return 0;
88 }
89