• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2022 Beken Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "efuse_hal.h"
16 #include "efuse_ll.h"
17 #include <driver/hal/hal_efuse_types.h>
18 
efuse_hal_check_can_write(uint8_t old_byte,uint8_t new_byte)19 static int efuse_hal_check_can_write(uint8_t old_byte, uint8_t new_byte)
20 {
21 	if (new_byte == old_byte) {
22 		/* no need to read */
23 		return -1;
24 	}
25 
26 	for (int i = 0; i < 8; i++) {
27 		uint8_t old_bit = ((old_byte >> i) & 0x01);
28 		uint8_t new_bit = ((new_byte >> i) & 0x01);
29 
30 		if ((old_bit) && (!new_bit)) {
31 			/* can not change old from 1 to 0 */
32 			HAL_LOGW("[efuse] cannot change bit[%d] from 1 to 0\r\n", i);
33 			return -2;
34 		}
35 	}
36 
37 	return 0;
38 }
39 
efuse_hal_init(efuse_hal_t * hal)40 bk_err_t efuse_hal_init(efuse_hal_t *hal)
41 {
42 	hal->hw = (efuse_hw_t *)EFUSE_LL_REG_BASE(hal->id);
43 	efuse_ll_init(hal->hw);
44 	return BK_OK;
45 }
46 
47 /* 1. check if can write
48  * 2. enable efuse vdd2.5v
49  * 3. set dir, addr, data, enable
50  * 4. wait for operate finished
51  * 5. disable efuse vdd2.5v
52  * 6. check if write success
53  */
efuse_hal_write(efuse_hal_t * hal,uint8_t addr,uint8_t wr_data)54 bk_err_t efuse_hal_write(efuse_hal_t *hal, uint8_t addr, uint8_t wr_data)
55 {
56 	/* read before write, ensure this byte and this bit no wrote */
57 	uint8_t read_data = efuse_hal_read(hal, addr);
58 	int ret = efuse_hal_check_can_write(read_data, wr_data);
59 	if (ret == -1) {
60 		return BK_OK;
61 	}
62 	if (ret == -2) {
63 		return BK_ERR_EFUSE_CANNOT_WRTIE;
64 	}
65 
66 	efuse_ll_enable_vdd25(hal->hw);
67 
68 	efuse_ll_set_direction_write(hal->hw);
69 	efuse_ll_set_addr(hal->hw, addr);
70 	efuse_ll_set_wr_data(hal->hw, wr_data);
71 	efuse_ll_enable(hal->hw);
72 
73 	BK_WHILE (!efuse_ll_is_operate_finished(hal->hw));
74 
75 	efuse_ll_disable_vdd25(hal->hw);
76 
77 	read_data = efuse_hal_read(hal, addr);
78 	if (read_data != wr_data) {
79 		return BK_ERR_EFUSE_WRTIE_NOT_EQUAL;
80 	}
81 
82 	return BK_OK;
83 }
84 
85 /* 1. set addr & direction=read
86  * 2. enable efuse
87  * 3. wait for efuse operate finished
88  * 4. if rd_data valid, read data
89  */
efuse_hal_read(efuse_hal_t * hal,uint8_t addr)90 uint8_t efuse_hal_read(efuse_hal_t *hal, uint8_t addr)
91 {
92 	efuse_ll_set_direction_read(hal->hw);
93 	efuse_ll_set_addr(hal->hw, addr);
94 	efuse_ll_enable(hal->hw);
95 
96 	/* wait for efuse operate finished */
97 	BK_WHILE (!efuse_ll_is_operate_finished(hal->hw));
98 
99 	if (efuse_ll_is_rd_data_valid(hal->hw)) {
100 		return efuse_ll_get_rd_data(hal->hw);
101 	} else {
102 		return 0xFF;
103 	}
104 }
105 
106