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>&copy; 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 }