1 /*
2 * Copyright 2024 Microchip Technology Inc. and its subsidiaries.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stddef.h>
7 #include <stdint.h>
8
9 #include "mec_pcfg.h"
10 #include "mec_defs.h"
11 #include "mec_vbat_api.h"
12 #include "mec_retval.h"
13 #include "device_mec5.h"
14
15 /* -------- VBAT API -------- */
16
17 /* VBAT powered reset and status register */
mec_hal_vbat_pfrs(void)18 uint32_t mec_hal_vbat_pfrs(void)
19 {
20 return MEC_VBATR->PFRS;
21 }
22
mec_hal_vbat_pfrs_clear(uint32_t clrmsk)23 void mec_hal_vbat_pfrs_clear(uint32_t clrmsk)
24 {
25 MEC_VBATR->PFRS = clrmsk;
26 }
27
28 /* Lower word of 64-bit monotonic counter is read-only.
29 * A read causes it to increment by 1.
30 */
mec_hal_read_monotonic_counter32(void)31 uint32_t mec_hal_read_monotonic_counter32(void)
32 {
33 return MEC_VBATR->MCNTL;
34 }
35
mec_hal_read_monotonic_counter64(void)36 uint64_t mec_hal_read_monotonic_counter64(void)
37 {
38 uint64_t counter = MEC_VBATR->MCNTH;
39
40 counter <<= 32;
41 counter |= MEC_VBATR->MCNTL; /* increments on read */
42
43 return counter;
44 }
45
46 /* Upper word of 64-bit monotonic counter is read/write.
47 * Read/write does not cause it to increment.
48 */
mec_hal_set_monotonic_counter_msw(uint32_t msw)49 void mec_hal_set_monotonic_counter_msw(uint32_t msw)
50 {
51 MEC_VBATR->MCNTH = msw;
52 }
53
54 /* ---- VBAT Memory ---- */
mec_hal_bbram_size(void)55 uint32_t mec_hal_bbram_size(void)
56 {
57 uint32_t bbram_size = MEC_VBAT_MEM_SIZE;
58
59 #ifndef MEC5_FAM2_ID
60 if (MEC_ECS->FEAT_LOCK & MEC_BIT(MEC_ECS_FEAT_LOCK_BBRAM_SIZE_Pos)) {
61 bbram_size >>= 1u;
62 }
63 #endif
64
65 return bbram_size;
66 }
67
mec_hal_bbram_base_address(void)68 uintptr_t mec_hal_bbram_base_address(void)
69 {
70 return (uintptr_t)(MEC_VBATM_BASE);
71 }
72
mec_hal_bbram_rd8(uint16_t byte_ofs,uint8_t * val)73 int mec_hal_bbram_rd8(uint16_t byte_ofs, uint8_t *val)
74 {
75 if (!val || (byte_ofs >= MEC_VBAT_MEM_SIZE)) {
76 return MEC_RET_ERR_INVAL;
77 }
78
79 *val = MEC_VBATM->VBMEM[byte_ofs];
80
81 return MEC_RET_OK;
82 }
83
mec_hal_bbram_wr8(uint16_t byte_ofs,uint8_t val)84 int mec_hal_bbram_wr8(uint16_t byte_ofs, uint8_t val)
85 {
86 if (byte_ofs >= MEC_VBAT_MEM_SIZE) {
87 return MEC_RET_ERR_INVAL;
88 }
89
90 MEC_VBATM->VBMEM[byte_ofs] = val;
91
92 return MEC_RET_OK;
93 }
94
mec_hal_bbram_rd32(uint16_t byte_ofs,uint32_t * val)95 int mec_hal_bbram_rd32(uint16_t byte_ofs, uint32_t *val)
96 {
97 uint32_t r = 0;
98
99 if (!val || (byte_ofs >= MEC_VBAT_MEM_SIZE)) {
100 return MEC_RET_ERR_INVAL;
101 }
102
103 if (!(byte_ofs & 0x3u)) {
104 r = MEC_MMCR32(&MEC_VBATM->VBMEM[byte_ofs]);
105 } else {
106 for (uint16_t i = 0; i < 4u; i++) {
107 r <<= 8;
108 r |= MEC_VBATM->VBMEM[byte_ofs + 3 - i];
109 }
110 }
111
112 *val = r;
113
114 return MEC_RET_OK;
115 }
116
mec_hal_bbram_wr32(uint16_t byte_ofs,uint32_t val)117 int mec_hal_bbram_wr32(uint16_t byte_ofs, uint32_t val)
118 {
119 if (byte_ofs >= MEC_VBAT_MEM_SIZE) {
120 return MEC_RET_ERR_INVAL;
121 }
122
123 if (!(byte_ofs & 0x3u)) {
124 MEC_MMCR32(&MEC_VBATM->VBMEM[byte_ofs]) = val;
125 } else {
126 for (uint16_t i = 0; i < 4u; i++) {
127 MEC_VBATM->VBMEM[byte_ofs + i] = val & 0xffu;
128 val >>= 8;
129 }
130 }
131
132 return MEC_RET_OK;
133 }
134
mec_hal_bbram_rd(uint16_t byte_ofs,uint8_t * data,size_t datasz,size_t * nread)135 int mec_hal_bbram_rd(uint16_t byte_ofs, uint8_t *data, size_t datasz, size_t *nread)
136 {
137 if (!data || (byte_ofs >= MEC_VBAT_MEM_SIZE)) {
138 return MEC_RET_ERR_INVAL;
139 }
140
141 for (uint16_t idx = byte_ofs; idx < (uint16_t)MEC_VBAT_MEM_SIZE; idx++) {
142 if ((size_t)idx >= datasz) {
143 break;
144 }
145
146 *data++ = MEC_VBATM->VBMEM[idx];
147 if (nread) {
148 *nread += 1u;
149 }
150 }
151
152 return 0;
153 }
154
mec_hal_bbram_wr(uint16_t byte_ofs,uint8_t * data,size_t datasz,size_t * nwritten)155 int mec_hal_bbram_wr(uint16_t byte_ofs, uint8_t *data, size_t datasz, size_t *nwritten)
156 {
157 if (!data || (byte_ofs >= MEC_VBAT_MEM_SIZE)) {
158 return MEC_RET_ERR_INVAL;
159 }
160
161 for (uint16_t idx = byte_ofs; idx < (uint16_t)MEC_VBAT_MEM_SIZE; idx++) {
162 if ((size_t)idx >= datasz) {
163 break;
164 }
165
166 MEC_VBATM->VBMEM[idx] = *data++;
167 if (nwritten) {
168 *nwritten += 1u;
169 }
170 }
171
172 return 0;
173 }
174
175 /* end mec_vbat.c */
176