1 /*
2  * Copyright (c) 2024 Ambiq
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <am_mcu_apollo.h>
8 #include <zephyr/drivers/hwinfo.h>
9 #include <string.h>
10 #include <zephyr/sys/byteorder.h>
11 
z_impl_hwinfo_get_device_id(uint8_t * buffer,size_t length)12 ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length)
13 {
14 
15 	struct ambiq_hwinfo {
16 		/* Ambiq Chip ID0 */
17 		uint32_t chip_id_0;
18 		/* Ambiq Chip ID1 */
19 		uint32_t chip_id_1;
20 		/* Ambiq Factory Trim Revision */
21 		/* Can be used in Ambiq HAL for additional code support  */
22 		uint32_t factory_trim_version;
23 	};
24 
25 	struct ambiq_hwinfo dev_hw_info = {0};
26 
27 	/* Contains the HAL hardware information about the device. */
28 	am_hal_mcuctrl_device_t mcu_ctrl_device;
29 
30 	am_hal_mram_info_read(1, AM_REG_INFO1_TRIM_REV_O / 4, 1, &dev_hw_info.factory_trim_version);
31 	am_hal_mcuctrl_info_get(AM_HAL_MCUCTRL_INFO_DEVICEID, &mcu_ctrl_device);
32 
33 	dev_hw_info.chip_id_0 = mcu_ctrl_device.ui32ChipID0;
34 	dev_hw_info.chip_id_1 = mcu_ctrl_device.ui32ChipID1;
35 
36 	if (length > sizeof(dev_hw_info)) {
37 		length = sizeof(dev_hw_info);
38 	}
39 
40 	dev_hw_info.chip_id_0 = BSWAP_32(dev_hw_info.chip_id_0);
41 	dev_hw_info.chip_id_1 = BSWAP_32(dev_hw_info.chip_id_1);
42 	dev_hw_info.factory_trim_version = BSWAP_32(dev_hw_info.factory_trim_version);
43 	memcpy(buffer, &dev_hw_info, length);
44 
45 	return length;
46 }
47 
z_impl_hwinfo_get_reset_cause(uint32_t * cause)48 int z_impl_hwinfo_get_reset_cause(uint32_t *cause)
49 {
50 	uint32_t flags = 0;
51 	uint32_t reset_status = 0;
52 	am_hal_reset_status_t status = {0};
53 
54 	/* Print out reset status register upon entry */
55 	am_hal_reset_status_get(&status);
56 	reset_status = status.eStatus;
57 
58 	/* EXTERNAL PIN */
59 	if (reset_status & AM_HAL_RESET_STATUS_EXTERNAL) {
60 		flags |= RESET_PIN;
61 	}
62 
63 	/* POWER CYCLE */
64 	if (reset_status & AM_HAL_RESET_STATUS_POR) {
65 		flags |= RESET_POR;
66 	}
67 
68 	/* BROWNOUT DETECTOR */
69 	if (reset_status & AM_HAL_RESET_STATUS_BOD) {
70 		flags |= RESET_BROWNOUT;
71 	}
72 
73 	/* SOFTWARE POR */
74 	if (reset_status & AM_HAL_RESET_STATUS_SWPOR) {
75 		flags |= RESET_SOFTWARE;
76 	}
77 
78 	/* SOFTWARE POI */
79 	if (reset_status & AM_HAL_RESET_STATUS_SWPOI) {
80 		flags |= RESET_SOFTWARE;
81 	}
82 
83 	/* DEBUGGER */
84 	if (reset_status & AM_HAL_RESET_STATUS_DEBUGGER) {
85 		flags |= RESET_DEBUG;
86 	}
87 
88 	/* WATCHDOG */
89 	if (reset_status & AM_HAL_RESET_STATUS_WDT) {
90 		flags |= RESET_WATCHDOG;
91 	}
92 
93 	/* BOUNREG */
94 	if (reset_status & AM_HAL_RESET_STATUS_BOUNREG) {
95 		flags |= RESET_HARDWARE;
96 	}
97 
98 	/* BOCORE */
99 	if (reset_status & AM_HAL_RESET_STATUS_BOCORE) {
100 		flags |= RESET_HARDWARE;
101 	}
102 
103 	/* BOMEM */
104 	if (reset_status & AM_HAL_RESET_STATUS_BOMEM) {
105 		flags |= RESET_HARDWARE;
106 	}
107 
108 	/* BOHPMEM */
109 	if (reset_status & AM_HAL_RESET_STATUS_BOHPMEM) {
110 		flags |= RESET_HARDWARE;
111 	}
112 
113 	*cause = flags;
114 	return 0;
115 }
116 
z_impl_hwinfo_clear_reset_cause(void)117 int z_impl_hwinfo_clear_reset_cause(void)
118 {
119 	/* SBL maintains the RSTGEN->STAT register in
120 	 * INFO1 space even upon clearing RSTGEN->STAT
121 	 * register.
122 	 * - INFO1_RESETSTATUS
123 	 */
124 
125 	return -ENOSYS;
126 }
127 
z_impl_hwinfo_get_supported_reset_cause(uint32_t * supported)128 int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported)
129 {
130 	*supported = RESET_PIN
131 			| RESET_SOFTWARE
132 			| RESET_POR
133 			| RESET_WATCHDOG
134 			| RESET_HARDWARE
135 			| RESET_BROWNOUT;
136 	return 0;
137 }
138