171 lines
3.7 KiB
C
Executable File
171 lines
3.7 KiB
C
Executable File
/*
|
|
* Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved.
|
|
*/
|
|
|
|
#include "hal_otp.h"
|
|
#include "cipher_adapt.h"
|
|
|
|
#ifdef OTP_SUPPORT
|
|
|
|
typedef enum {
|
|
OTP_USER_LOCK_STA0_TYPE,
|
|
OTP_USER_LOCK_STA1_TYPE,
|
|
OTP_USER_LOCK_UNKNOWN_STA,
|
|
} opt_lock_sta_type_e;
|
|
|
|
typedef enum {
|
|
OTP_READ_LOCK_STA_MODE,
|
|
OTP_LOCK_CIPHER_KEY_MODE,
|
|
OTP_WRITE_KEY_ID_OR_PASSWD_MODE,
|
|
OTP_KEY_ID_OR_PASSWD_CRC_MODE,
|
|
OTP_SET_FLAG_ENABLE_MODE,
|
|
OTP_WRITE_USER_ROOM_MODE,
|
|
OTP_READ_USER_ROOM_MODE,
|
|
OTP_UNKOOWN_MODE,
|
|
} otp_user_work_mode_e;
|
|
|
|
typedef enum {
|
|
OTP_USER_KEY0,
|
|
OTP_USER_KEY1,
|
|
OTP_USER_KEY2,
|
|
OTP_USER_KEY3,
|
|
OTP_USER_KEY_JTAG_PW_ID,
|
|
OTP_USER_KEY_JTAG_PW,
|
|
OTP_USER_KEY_ROOTKEY,
|
|
OTP_USER_KEY_UNKNOWN,
|
|
} otp_user_key_index_e;
|
|
|
|
typedef enum {
|
|
OTP_KEY_LENGTH_64BIT,
|
|
OTP_KEY_LENGTH_128BIT,
|
|
OTP_KEY_LENGTH_256BIT,
|
|
OTP_KEY_LENGTH_UNSUPPORT,
|
|
} otp_user_key_length_e;
|
|
|
|
gk_void *g_efuse_otp_reg_base = GK_NULL;
|
|
|
|
/* OTP init */
|
|
gk_s32 hal_efuse_otp_init(gk_void)
|
|
{
|
|
gk_u32 crg_value = 0;
|
|
gk_u32 *sys_addr = GK_NULL;
|
|
|
|
sys_addr = cipher_ioremap_nocache(REG_SYS_OTP_CLK_ADDR_PHY, 0x100);
|
|
if (sys_addr == GK_NULL) {
|
|
gk_err_cipher("ERROR: sys_addr ioremap with nocache failed!!\n");
|
|
return GK_FAILURE;
|
|
}
|
|
|
|
hal_cipher_read_reg(sys_addr, &crg_value);
|
|
#ifdef OTP_CRG_RESET_SUPPORT
|
|
crg_value |= OTP_CRG_RESET_BIT; /* reset */
|
|
crg_value |= OTP_CRG_CLOCK_BIT; /* set the bit 0, clock opened */
|
|
hal_cipher_write_reg(sys_addr, crg_value);
|
|
|
|
/* clock select and cancel reset 0x30100 */
|
|
crg_value &= (~OTP_CRG_RESET_BIT); /* cancel reset */
|
|
#endif
|
|
crg_value |= OTP_CRG_CLOCK_BIT; /* set the bit 0, clock opened */
|
|
hal_cipher_write_reg(sys_addr, crg_value);
|
|
|
|
cipher_iounmap(sys_addr);
|
|
sys_addr = GK_NULL;
|
|
|
|
g_efuse_otp_reg_base = cipher_ioremap_nocache(CIPHER_OTP_REG_BASE_ADDR_PHY, 0x100);
|
|
if (g_efuse_otp_reg_base == GK_NULL) {
|
|
gk_err_cipher("ERROR: osal_ioremap_nocache for OTP failed!!\n");
|
|
return GK_FAILURE;
|
|
}
|
|
|
|
return GK_SUCCESS;
|
|
}
|
|
|
|
static gk_s32 hal_otp_wait_free(gk_void)
|
|
{
|
|
gk_u32 timeout_cnt = 0;
|
|
gk_u32 reg_value = 0;
|
|
|
|
while (1) {
|
|
hal_cipher_read_reg(OTP_USER_CTRL_STA, ®_value);
|
|
if ((reg_value & 0x1) == 0) /* bit0:otp_op_busy 0:idle, 1:busy */
|
|
return GK_SUCCESS;
|
|
|
|
timeout_cnt++;
|
|
if (timeout_cnt >= 10000) { /* 10000 count */
|
|
gk_err_cipher("OTP_WaitFree TimeOut!\n");
|
|
break;
|
|
}
|
|
}
|
|
return GK_FAILURE;
|
|
}
|
|
|
|
static gk_s32 hal_otp_set_mode(otp_user_work_mode_e otp_mode)
|
|
{
|
|
gk_u32 reg_value = otp_mode;
|
|
|
|
if (otp_mode >= OTP_UNKOOWN_MODE) {
|
|
gk_err_cipher("Mode Unknown!\n");
|
|
return GK_FAILURE;
|
|
}
|
|
|
|
(gk_void)hal_cipher_write_reg(OTP_USER_WORK_MODE, reg_value);
|
|
return GK_SUCCESS;
|
|
}
|
|
|
|
static gk_void hal_otp_op_start(gk_void)
|
|
{
|
|
gk_u32 reg_value = 0x1acce551;
|
|
(gk_void)hal_cipher_write_reg(OTP_USER_OP_START, reg_value);
|
|
}
|
|
|
|
static gk_s32 hal_otp_wait_op_done(gk_void)
|
|
{
|
|
gk_u32 timeout_cnt = 0;
|
|
gk_u32 reg_value = 0;
|
|
|
|
while (1) {
|
|
hal_cipher_read_reg(OTP_USER_CTRL_STA, ®_value);
|
|
if (reg_value & 0x2) {
|
|
return GK_SUCCESS;
|
|
}
|
|
|
|
timeout_cnt++;
|
|
if (timeout_cnt >= 10000) { /* 10000 count */
|
|
gk_err_cipher("OTP_Wait_OP_done TimeOut!\n");
|
|
break;
|
|
}
|
|
}
|
|
return GK_FAILURE;
|
|
}
|
|
|
|
static gk_void hal_choose_otp_key(otp_user_key_index_e which_key)
|
|
{
|
|
gk_u32 reg_value;
|
|
|
|
reg_value = which_key;
|
|
(gk_void)hal_cipher_write_reg(OTP_USER_KEY_INDEX, reg_value);
|
|
}
|
|
|
|
/* set otp key to klad */
|
|
gk_s32 hal_efuse_otp_load_cipher_key(gk_u32 chn_id, gk_u32 opt_id)
|
|
{
|
|
if (opt_id > OTP_USER_KEY3)
|
|
opt_id = OTP_USER_KEY0;
|
|
|
|
if (GK_FAILURE == hal_otp_wait_free())
|
|
return GK_FAILURE;
|
|
hal_choose_otp_key(opt_id);
|
|
|
|
if (hal_otp_set_mode(OTP_LOCK_CIPHER_KEY_MODE))
|
|
return GK_FAILURE;
|
|
|
|
hal_otp_op_start();
|
|
|
|
if (GK_FAILURE == hal_otp_wait_op_done())
|
|
return GK_FAILURE;
|
|
|
|
return GK_SUCCESS;
|
|
}
|
|
#endif
|
|
|