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