1 /**
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 * Description: Provides efuse driver source \n
16 *
17 * History: \n
18 * 2023-3-4, Create file. \n
19 */
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <stdbool.h>
23 #include "securec.h"
24 #include "common_def.h"
25 #include "hal_efuse.h"
26 #include "hal_efuse_v151_reg_op.h"
27 #include "efuse_porting.h"
28 #include "tcxo.h"
29
30 #define HAL_EFUSE_WRITE_MODE 0xa5a5
31 #define HAL_EFUSE_READ_MODE 0x5a5a
32 #define HAL_EFUSE_CLEAR_RESULT 0x0
33 #define HAL_EFUSE_REG_WIDTH 1U
34 #define HAL_EFUSE_REG_SHIFT 2U
35 #define HAL_EFUSE_REG_LENGTH 4U
36 #define HAL_EFUSE_REG_DATA_SHIFT 8U
37 #define HAL_EFUSE_REG_DATA_LENGTH 16
38 #define HAL_EFUSE_REG_VALID_DATA 0x1
39 #define HAL_EFUSE_REG_BYTE_OFFSET 1
40 #define HAL_EFUSE_BYTES_PRE_REG 2
41 #define HAL_EFUSE_BYTE_MASK 0xFF
42 #define HAL_EFUSE_REG_H_MASK 0xFF00
43 #define HAL_EFUSE_REG_L_MASK 0x00FF
44
45 #define HAL_EFUSE_POWER_ON_DELAY_US 120ULL
46 #define HAL_EFUSE_DELAY_US 100
47 #define HAL_EFUSE_CLOCK_PERIOD 0x1f
48 #if defined(CONFIG_EFUSE_SWITCH_EN)
49 #define HAL_EFUSE_SWITCH_ON_DELAY 200
50 #define HAL_EFUSE_SWITCH_OFF_DELAY 200
51 #define HAL_EFUSE_SWITCH_EN 0xa5a5
52 #define HAL_EFUSE_SWITCH_OFF 0x0
53 #endif
54
55 #define HAL_EFUSE0_BOOT_DONE 0x4
56
57 static uint32_t g_efuse_clock_period = HAL_EFUSE_CLOCK_PERIOD;
58 static bool g_efuse_is_init = false;
59
hal_efuse_set_clock_period(uint32_t clock_period)60 void hal_efuse_set_clock_period(uint32_t clock_period)
61 {
62 g_efuse_clock_period = clock_period;
63 }
64
hal_efuse_init(void)65 static errcode_t hal_efuse_init(void)
66 {
67 hal_efuse_regs_init(0);
68 hal_efuse_clock_period_set(0, g_efuse_clock_period);
69 #if CONFIG_EFUSE_REGION_NUM > EFUSE_REGION_INDEX1
70 hal_efuse_regs_init(EFUSE_REGION_INDEX1);
71 hal_efuse_clock_period_set(EFUSE_REGION_INDEX1, g_efuse_clock_period);
72 #endif
73 #if CONFIG_EFUSE_REGION_NUM > EFUSE_REGION_INDEX2
74 hal_efuse_regs_init(EFUSE_REGION_INDEX2);
75 hal_efuse_clock_period_set(EFUSE_REGION_INDEX2, g_efuse_clock_period);
76 #endif
77 g_efuse_is_init = true;
78 return ERRCODE_SUCC;
79 }
80
hal_efuse_deinit(void)81 static void hal_efuse_deinit(void)
82 {
83 g_efuse_is_init = false;
84 return ;
85 }
86
hal_efuse_get_writeread_addr(uint32_t byte_addr)87 static uint32_t hal_efuse_get_writeread_addr(uint32_t byte_addr)
88 {
89 hal_efuse_region_t region = hal_efuse_get_region(byte_addr);
90 uint16_t offset = hal_efuse_get_byte_offset(byte_addr);
91 return g_efuse_region_read_address[region] + ((offset >> 1U) << HAL_EFUSE_REG_SHIFT);
92 }
93
hal_efuse_read_byte(uint32_t byte_address,uint8_t * value)94 static errcode_t hal_efuse_read_byte(uint32_t byte_address, uint8_t *value)
95 {
96 if (g_efuse_is_init == false) {
97 return ERRCODE_EFUSE_NOT_INIT;
98 }
99
100 if ((byte_address >= EFUSE_MAX_BYTES) || (value == NULL)) {
101 return ERRCODE_INVALID_PARAM;
102 }
103 volatile uint32_t *efuse_byte = (volatile uint32_t *)((uintptr_t)hal_efuse_get_writeread_addr(byte_address));
104 hal_efuse_ctl_set(hal_efuse_get_region(byte_address), HAL_EFUSE_READ_MODE);
105 if ((byte_address % HAL_EFUSE_BYTES_PRE_REG) != 0) {
106 *value = (uint8_t)((*efuse_byte >> HAL_EFUSE_REG_DATA_SHIFT) & HAL_EFUSE_BYTE_MASK);
107 } else {
108 *value = (uint8_t)(*efuse_byte & HAL_EFUSE_BYTE_MASK);
109 }
110 return ERRCODE_SUCC;
111 }
112
hal_efuse_write_operation(uint32_t address,uint8_t value,hal_efuse_region_t region)113 static errcode_t hal_efuse_write_operation(uint32_t address, uint8_t value, hal_efuse_region_t region)
114 {
115 unused(region);
116 if (g_efuse_is_init == false) {
117 return ERRCODE_EFUSE_NOT_INIT;
118 }
119
120 if (address >= EFUSE_MAX_BYTES) {
121 return ERRCODE_INVALID_PARAM;
122 }
123 #if defined(CONFIG_EFUSE_SWITCH_EN)
124 hal_efuse_switch_en_set(HAL_EFUSE_SWITCH_EN);
125 uapi_tcxo_delay_us(HAL_EFUSE_SWITCH_ON_DELAY);
126 #endif
127
128 hal_efuse_ctl_set(hal_efuse_get_region(address), HAL_EFUSE_WRITE_MODE);
129 hal_efuse_avdd_ctl_set(hal_efuse_get_region(address), 1);
130 uapi_tcxo_delay_us(HAL_EFUSE_DELAY_US);
131 volatile uint32_t *efuse_byte = (volatile uint32_t *)((uintptr_t)hal_efuse_get_writeread_addr(address));
132 if ((address % HAL_EFUSE_BYTES_PRE_REG) != 0) {
133 *efuse_byte = (uint16_t)(value) << HAL_EFUSE_REG_DATA_SHIFT;
134 } else {
135 *efuse_byte = (uint32_t)(value);
136 }
137 hal_efuse_avdd_ctl_set(hal_efuse_get_region(address), 0);
138 uapi_tcxo_delay_us(HAL_EFUSE_DELAY_US);
139
140 #if defined(CONFIG_EFUSE_SWITCH_EN)
141 uapi_tcxo_delay_us(HAL_EFUSE_SWITCH_OFF_DELAY);
142 hal_efuse_switch_en_set(0);
143 #endif
144 return ERRCODE_SUCC;
145 }
146
hal_efuse_write_buffer_operation(uint32_t address,const uint8_t * buffer,uint16_t length)147 static errcode_t hal_efuse_write_buffer_operation(uint32_t address, const uint8_t *buffer, uint16_t length)
148 {
149 if (g_efuse_is_init == false) {
150 return ERRCODE_EFUSE_NOT_INIT;
151 }
152
153 for (uint32_t i = 0; i < length; i++) {
154 if (hal_efuse_write_operation(address + i, buffer[i], 0) != ERRCODE_SUCC) {
155 return ERRCODE_FAIL;
156 }
157 }
158
159 return ERRCODE_SUCC;
160 }
161
hal_efuse_get_die_id(uint8_t * buffer,uint16_t length)162 static errcode_t hal_efuse_get_die_id(uint8_t *buffer, uint16_t length)
163 {
164 if (g_efuse_is_init == false) {
165 return ERRCODE_EFUSE_NOT_INIT;
166 }
167 for (uint32_t i = 0; i < length; i++) {
168 if (hal_efuse_read_byte(EFUSE_DIE_ID_BASE_BYTE_ADDR + i, &buffer[i]) != ERRCODE_SUCC) {
169 return ERRCODE_FAIL;
170 }
171 }
172 return ERRCODE_SUCC;
173 }
174
175 hal_efuse_funcs_t g_hal_efuse_funcs = {
176 .init = hal_efuse_init,
177 .deinit = hal_efuse_deinit,
178 .flush_write = NULL,
179 .refresh_read = NULL,
180 .read_byte = hal_efuse_read_byte,
181 .write_byte = NULL,
182 .clear = NULL,
183 .write_op = hal_efuse_write_operation,
184 .write_buffer_op = hal_efuse_write_buffer_operation,
185 .get_die_id = hal_efuse_get_die_id,
186 .get_chip_id = NULL
187 };
188
hal_efuse_funcs_get(void)189 hal_efuse_funcs_t *hal_efuse_funcs_get(void)
190 {
191 return &g_hal_efuse_funcs;
192 }
193