1 /**
2 ******************************************************************************
3 * @file bl808_ef_cfg.c
4 * @version V1.0
5 * @date
6 * @brief This file is the standard driver c file
7 ******************************************************************************
8 * @attention
9 *
10 * <h2><center>© COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
11 *
12 * Redistribution and use in source and binary forms, with or without modification,
13 * are permitted provided that the following conditions are met:
14 * 1. Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * 3. Neither the name of Bouffalo Lab nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 ******************************************************************************
35 */
36 #include "bl808_ef_cfg.h"
37 #include "hardware/ef_data_0_reg.h"
38 #include "hardware/ef_data_1_reg.h"
39
40 extern int bflb_efuse_read_mac_address_opt(uint8_t slot, uint8_t mac[6], uint8_t reload);
41
42 static const bflb_ef_ctrl_com_trim_cfg_t trim_list[] = {
43 {
44 .name = "rc32m",
45 .en_addr = 0x78 * 8 + 1,
46 .parity_addr = 0x78 * 8 + 0,
47 .value_addr = 0x7C * 8 + 4,
48 .value_len = 8,
49 },
50 {
51 .name = "rc32k",
52 .en_addr = 0xEC * 8 + 19,
53 .parity_addr = 0xEC * 8 + 18,
54 .value_addr = 0xEC * 8 + 8,
55 .value_len = 10,
56 },
57 {
58 .name = "gpadc_gain",
59 .en_addr = 0xF0 * 8 + 27,
60 .parity_addr = 0xF0 * 8 + 26,
61 .value_addr = 0xF0 * 8 + 14,
62 .value_len = 12,
63 },
64 {
65 .name = "tsen",
66 .en_addr = 0xF0 * 8 + 13,
67 .parity_addr = 0xF0 * 8 + 12,
68 .value_addr = 0xF0 * 8 + 0,
69 .value_len = 12,
70 },
71 {
72 .name = "usb20",
73 .en_addr = 0xF8 * 8 + 15,
74 .parity_addr = 0xF8 * 8 + 14,
75 .value_addr = 0xF8 * 8 + 8,
76 .value_len = 6,
77 },
78 {
79 .name = "dcdc11_trim",
80 .en_addr = 0x78 * 8 + 31,
81 .parity_addr = 0x78 * 8 + 30,
82 .value_addr = 0x78 * 8 + 26,
83 .value_len = 4,
84 },
85 {
86 .name = "dcdc18_trim",
87 .en_addr = 0x78 * 8 + 25,
88 .parity_addr = 0x78 * 8 + 24,
89 .value_addr = 0x78 * 8 + 20,
90 .value_len = 4,
91 },
92 {
93 .name = "ldo28cis_trim",
94 .en_addr = 0x78 * 8 + 13,
95 .parity_addr = 0x78 * 8 + 12,
96 .value_addr = 0x78 * 8 + 8,
97 .value_len = 4,
98 },
99 {
100 .name = "ldo15cis_trim",
101 .en_addr = 0x78 * 8 + 13,
102 .parity_addr = 0x78 * 8 + 12,
103 .value_addr = 0x78 * 8 + 8,
104 .value_len = 4,
105 },
106 {
107 .name = "ldo18flash_trim",
108 .en_addr = 0xEC * 8 + 31,
109 .parity_addr = 0xEC * 8 + 30,
110 .value_addr = 0xEC * 8 + 26,
111 .value_len = 4,
112 },
113 {
114 .name = "ldo12uhs_trim",
115 .en_addr = 0xEC * 8 + 25,
116 .parity_addr = 0xEC * 8 + 24,
117 .value_addr = 0xEC * 8 + 20,
118 .value_len = 4,
119 },
120 };
121
122 /****************************************************************************/ /**
123 * @brief Efuse get trim list
124 *
125 * @param trim_list: Trim list pointer
126 *
127 * @return Trim list count
128 *
129 *******************************************************************************/
bflb_ef_ctrl_get_common_trim_list(const bflb_ef_ctrl_com_trim_cfg_t ** ptrim_list)130 uint32_t bflb_ef_ctrl_get_common_trim_list(const bflb_ef_ctrl_com_trim_cfg_t **ptrim_list)
131 {
132 *ptrim_list = &trim_list[0];
133 return sizeof(trim_list) / sizeof(trim_list[0]);
134 }
135
136 /****************************************************************************/ /**
137 * @brief Efuse read device info
138 *
139 * @param deviceInfo: info pointer
140 *
141 * @return None
142 *
143 *******************************************************************************/
bflb_ef_ctrl_get_device_info(bflb_efuse_device_info_type * deviceInfo)144 void bflb_ef_ctrl_get_device_info(bflb_efuse_device_info_type *deviceInfo)
145 {
146 uint32_t tmpval;
147
148 //tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH);
149 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_WIFI_MAC_HIGH_OFFSET, &tmpval, 1, 1);
150
151 deviceInfo->chipInfo = (tmpval >> 29) & 0x7;
152 deviceInfo->memoryInfo = (tmpval >> 27) & 0x3;
153 deviceInfo->psramInfo = (tmpval >> 25) & 0x3;
154 deviceInfo->deviceInfo = (tmpval >> 22) & 0x7;
155
156 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_CFG_0_OFFSET, &tmpval, 1, 1);
157
158 deviceInfo->psramInfo |= ((tmpval >> 20) & 0x1) << 2;
159 }
160
bflb_efuse_get_chipid(uint8_t chipid[8])161 void bflb_efuse_get_chipid(uint8_t chipid[8])
162 {
163 bflb_efuse_read_mac_address_opt(0, chipid, 1);
164 chipid[6] = 0;
165 chipid[7] = 0;
166 }
167
168 /****************************************************************************/ /**
169 * @brief Whether MAC address slot is empty
170 *
171 * @param slot: MAC address slot
172 * @param reload: whether reload to check
173 *
174 * @return 0 for all slots full,1 for others
175 *
176 *******************************************************************************/
bflb_efuse_is_mac_address_slot_empty(uint8_t slot,uint8_t reload)177 uint8_t bflb_efuse_is_mac_address_slot_empty(uint8_t slot, uint8_t reload)
178 {
179 uint32_t tmp1 = 0xffffffff, tmp2 = 0xffffffff;
180 uint32_t part1Empty = 0, part2Empty = 0;
181
182 if (slot == 0) {
183 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_WIFI_MAC_LOW_OFFSET, &tmp1, 1, reload);
184 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_WIFI_MAC_HIGH_OFFSET, &tmp2, 1, reload);
185 } else if (slot == 1) {
186 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_SW_USAGE_2_OFFSET, &tmp1, 1, reload);
187 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_SW_USAGE_3_OFFSET, &tmp2, 1, reload);
188 } else if (slot == 2) {
189 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_KEY_SLOT_11_W1_OFFSET, &tmp1, 1, reload);
190 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_KEY_SLOT_11_W2_OFFSET, &tmp2, 1, reload);
191 }
192
193 part1Empty = (bflb_ef_ctrl_is_all_bits_zero(tmp1, 0, 32));
194 part2Empty = (bflb_ef_ctrl_is_all_bits_zero(tmp2, 0, 22));
195
196 return (part1Empty && part2Empty);
197 }
198
199 /****************************************************************************/ /**
200 * @brief Efuse write optional MAC address
201 *
202 * @param slot: MAC address slot
203 * @param mac[6]: MAC address buffer
204 * @param program: Whether program
205 *
206 * @return 0 or -1
207 *
208 *******************************************************************************/
bflb_efuse_write_mac_address_opt(uint8_t slot,uint8_t mac[6],uint8_t program)209 int bflb_efuse_write_mac_address_opt(uint8_t slot, uint8_t mac[6], uint8_t program)
210 {
211 uint8_t *maclow = (uint8_t *)mac;
212 uint8_t *machigh = (uint8_t *)(mac + 4);
213 uint32_t tmpval;
214 uint32_t i = 0, cnt;
215
216 if (slot >= 3) {
217 return -1;
218 }
219
220 /* Change to local order */
221 for (i = 0; i < 3; i++) {
222 tmpval = mac[i];
223 mac[i] = mac[5 - i];
224 mac[5 - i] = tmpval;
225 }
226
227 /* The low 32 bits */
228 tmpval = BL_RDWD_FRM_BYTEP(maclow);
229
230 if (slot == 0) {
231 bflb_ef_ctrl_write_direct(NULL, EF_DATA_0_EF_WIFI_MAC_LOW_OFFSET, &tmpval, 1, program);
232 } else if (slot == 1) {
233 bflb_ef_ctrl_write_direct(NULL, EF_DATA_0_EF_SW_USAGE_2_OFFSET, &tmpval, 1, program);
234 } else if (slot == 2) {
235 bflb_ef_ctrl_write_direct(NULL, EF_DATA_0_EF_KEY_SLOT_11_W1_OFFSET, &tmpval, 1, program);
236 }
237
238 /* The high 16 bits */
239 tmpval = machigh[0] + (machigh[1] << 8);
240 cnt = 0;
241
242 for (i = 0; i < 6; i++) {
243 cnt += bflb_ef_ctrl_get_byte_zero_cnt(mac[i]);
244 }
245
246 tmpval |= ((cnt & 0x3f) << 16);
247
248 if (slot == 0) {
249 bflb_ef_ctrl_write_direct(NULL, EF_DATA_0_EF_WIFI_MAC_HIGH_OFFSET, &tmpval, 1, program);
250 } else if (slot == 1) {
251 bflb_ef_ctrl_write_direct(NULL, EF_DATA_0_EF_SW_USAGE_3_OFFSET, &tmpval, 1, program);
252 } else if (slot == 2) {
253 bflb_ef_ctrl_write_direct(NULL, EF_DATA_0_EF_KEY_SLOT_11_W2_OFFSET, &tmpval, 1, program);
254 }
255
256 return 0;
257 }
258
259 /****************************************************************************/ /**
260 * @brief Efuse read optional MAC address
261 *
262 * @param slot: MAC address slot
263 * @param mac[6]: MAC address buffer
264 * @param reload: Whether reload
265 *
266 * @return 0 or -1
267 *
268 *******************************************************************************/
bflb_efuse_read_mac_address_opt(uint8_t slot,uint8_t mac[6],uint8_t reload)269 int bflb_efuse_read_mac_address_opt(uint8_t slot, uint8_t mac[6], uint8_t reload)
270 {
271 uint8_t *maclow = (uint8_t *)mac;
272 uint8_t *machigh = (uint8_t *)(mac + 4);
273 uint32_t tmpval = 0;
274 uint32_t i = 0;
275 uint32_t cnt = 0;
276
277 if (slot >= 3) {
278 return -1;
279 }
280
281 if (slot == 0) {
282 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_WIFI_MAC_LOW_OFFSET, &tmpval, 1, reload);
283 } else if (slot == 1) {
284 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_SW_USAGE_2_OFFSET, &tmpval, 1, reload);
285 } else if (slot == 2) {
286 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_KEY_SLOT_11_W1_OFFSET, &tmpval, 1, reload);
287 }
288
289 BL_WRWD_TO_BYTEP(maclow, tmpval);
290
291 if (slot == 0) {
292 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_WIFI_MAC_HIGH_OFFSET, &tmpval, 1, reload);
293 } else if (slot == 1) {
294 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_SW_USAGE_3_OFFSET, &tmpval, 1, reload);
295 } else if (slot == 2) {
296 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_KEY_SLOT_11_W2_OFFSET, &tmpval, 1, reload);
297 }
298
299 machigh[0] = tmpval & 0xff;
300 machigh[1] = (tmpval >> 8) & 0xff;
301
302 /* Check parity */
303 for (i = 0; i < 6; i++) {
304 cnt += bflb_ef_ctrl_get_byte_zero_cnt(mac[i]);
305 }
306
307 if ((cnt & 0x3f) == ((tmpval >> 16) & 0x3f)) {
308 /* Change to network order */
309 for (i = 0; i < 3; i++) {
310 tmpval = mac[i];
311 mac[i] = mac[5 - i];
312 mac[5 - i] = tmpval;
313 }
314 return 0;
315 } else {
316 return -1;
317 }
318 }
319
bflb_efuse_get_adc_trim(void)320 float bflb_efuse_get_adc_trim(void)
321 {
322 bflb_ef_ctrl_com_trim_t trim;
323 uint32_t tmp;
324
325 float coe = 1.0;
326
327 bflb_ef_ctrl_read_common_trim(NULL, "gpadc_gain", &trim, 1);
328
329 if (trim.en) {
330 if (trim.parity == bflb_ef_ctrl_get_trim_parity(trim.value, trim.len)) {
331 tmp = trim.value;
332
333 if (tmp & 0x800) {
334 tmp = ~tmp;
335 tmp += 1;
336 tmp = tmp & 0xfff;
337 coe = (1.0 + ((float)tmp / 2048.0));
338 } else {
339 coe = (1.0 - ((float)tmp / 2048.0));
340 }
341 }
342 }
343
344 return coe;
345 }
346
bflb_efuse_get_adc_tsen_trim(void)347 uint32_t bflb_efuse_get_adc_tsen_trim(void)
348 {
349 bflb_ef_ctrl_com_trim_t trim;
350
351 bflb_ef_ctrl_read_common_trim(NULL, "tsen", &trim, 1);
352 if (trim.en) {
353 if (trim.parity == bflb_ef_ctrl_get_trim_parity(trim.value, trim.len)) {
354 return trim.value;
355 }
356 }
357
358 return 2042;
359 }
360
bflb_efuse_read_secure_boot(uint8_t * sign,uint8_t * aes)361 void bflb_efuse_read_secure_boot(uint8_t *sign, uint8_t *aes)
362 {
363 uint32_t tmpval = 0;
364
365 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_CFG_0_OFFSET, &tmpval, 1, 1);
366 *sign = ((tmpval & EF_DATA_0_EF_SBOOT_SIGN_MODE_MSK) >> EF_DATA_0_EF_SBOOT_SIGN_MODE_POS) & 0x01;
367 *aes = ((tmpval & EF_DATA_0_EF_SF_AES_MODE_MSK) >> EF_DATA_0_EF_SF_AES_MODE_POS);
368 }
369
bflb_efuse_write_aes_key(uint8_t index,uint8_t * data,uint32_t len)370 void bflb_efuse_write_aes_key(uint8_t index, uint8_t *data, uint32_t len)
371 {
372 if ((index <= 3) || (index == 11)) {
373 index = ((index == 11) ? 5 : index);
374 /* Every key is 4 words len*/
375 bflb_ef_ctrl_write_direct(NULL, 0x1C + index * 4, (uint32_t *)data, len, 1);
376 } else if ((index < 11) && (index > 3)) {
377 index = index - 4;
378 /* Every key is 4 words len*/
379 bflb_ef_ctrl_write_direct(NULL, 0x80 + index * 4, (uint32_t *)data, len, 1);
380 }
381 }
382
bflb_efuse_read_aes_key(uint8_t index,uint8_t * data,uint32_t len)383 void bflb_efuse_read_aes_key(uint8_t index, uint8_t *data, uint32_t len)
384 {
385 if ((index <= 3) || (index == 11)) {
386 index = ((index == 11) ? 5 : index);
387 /* Every key is 4 words len*/
388 bflb_ef_ctrl_read_direct(NULL, 0x1C + index * 4, (uint32_t *)data, len, 1);
389 } else if ((index < 11) && (index > 3)) {
390 index = index - 4;
391 /* Every key is 4 words len*/
392 bflb_ef_ctrl_read_direct(NULL, 0x80 + index * 4, (uint32_t *)data, len, 1);
393 }
394 }
395
bflb_efuse_lock_aes_key_write(uint8_t index)396 void bflb_efuse_lock_aes_key_write(uint8_t index)
397 {
398 uint32_t lock = 0;
399
400 if ((index <= 3) || (index == 11)) {
401 index = ((index == 11) ? 8 : index);
402 lock |= (1 << (index + 17));
403 bflb_ef_ctrl_write_direct(NULL, 0x7c, (uint32_t *)&lock, 1, 1);
404 } else if ((index < 11) && (index > 3)) {
405 index = index - 4;
406 lock |= (1 << (index + 15));
407 bflb_ef_ctrl_write_direct(NULL, 0xfc, (uint32_t *)&lock, 1, 1);
408 }
409 }
410
bflb_efuse_lock_aes_key_read(uint8_t index)411 void bflb_efuse_lock_aes_key_read(uint8_t index)
412 {
413 uint32_t lock = 0;
414
415 if ((index <= 3) || (index == 11)) {
416 index = ((index == 11) ? 4 : index);
417 lock |= (1 << (index + 27));
418 bflb_ef_ctrl_write_direct(NULL, 0x7c, (uint32_t *)lock, 1, 1);
419 } else if ((index < 11) && (index > 3)) {
420 index = index - 4;
421 lock |= (1 << (index + 25));
422 bflb_ef_ctrl_write_direct(NULL, 0xfc, (uint32_t *)lock, 1, 1);
423 }
424 }
425
bflb_efuse_write_sw_usage(uint32_t index,uint32_t usage,uint8_t program)426 void bflb_efuse_write_sw_usage(uint32_t index, uint32_t usage, uint8_t program)
427 {
428 bflb_ef_ctrl_write_direct(NULL, EF_DATA_0_EF_SW_USAGE_0_OFFSET + index * 4, &usage, 1, program);
429 }
430
bflb_efuse_read_sw_usage(uint32_t index,uint32_t * usage)431 void bflb_efuse_read_sw_usage(uint32_t index, uint32_t *usage)
432 {
433 bflb_ef_ctrl_read_direct(NULL, EF_DATA_0_EF_SW_USAGE_0_OFFSET + index * 4, (uint32_t *)usage, 1, 1);
434 }