• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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