You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
5.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2013-2020. All rights reserved.
* Description: reg drv
* Author: Hisilicon
* Create: 2013/08/26
*/
#include "soc_log.h"
#include "td_type.h"
#include "osal_ext.h"
#include "drv_reg.h"
#include "reg_common_ext.h"
#include "drv_mem_ext.h"
#include "linux/huanglong/securec.h"
#define SYS_OTP_LEN 0x800
#define SYS_OTP_BUF_LEN 0x1000
volatile ext_reg_sys_ctrl *g_reg_sys_ctrl = TD_NULL;
volatile ext_reg_peri *g_reg_peri = TD_NULL;
volatile ext_reg_io *g_reg_io = TD_NULL;
volatile ext_reg_crg *g_reg_crg = TD_NULL;
volatile ext_reg_aon_crg *g_reg_aon_crg = TD_NULL;
td_u8 *g_otp_base_vir_addr = TD_NULL;
static td_s32 drv_reg_otp_aon_init(td_void)
{
td_u8 *otp_addr = TD_NULL;
td_s32 ret;
/* 此处定义为0是因为 reserved9/reserved13 没有这块寄存器基地址,用于区分 reserved5 */
if (EXT_REG_AON_CRG_BASE_ADDR != 0x0) {
g_reg_aon_crg = (ext_reg_aon_crg *)osal_ioremap_nocache(EXT_REG_AON_CRG_BASE_ADDR, sizeof(ext_reg_aon_crg));
if (g_reg_aon_crg == TD_NULL) {
soc_print("EXT_REG_AON_CRG_BASE_ADDR ioremap error!\n");
return TD_FAILURE;
}
}
otp_addr = (td_u8 *)osal_ioremap_nocache(EXT_REG_OTP_BASE_ADDR, 0x1000);
if (otp_addr == TD_NULL) {
soc_print("EXT_REG_OTP_BASE_ADDR ioremap error!\n");
goto err1;
}
g_otp_base_vir_addr = SOC_KZALLOC(SOC_ID_SYS, 0x1000, GFP_KERNEL);
if (g_otp_base_vir_addr == TD_NULL) {
soc_print("g_otp_base_vir_addr kmalloc error!\n");
goto err0;
}
ret = memcpy_s(g_otp_base_vir_addr, SYS_OTP_BUF_LEN, otp_addr, SYS_OTP_LEN);
if (ret != EOK) {
soc_print("memcpy_s error!\n");
SOC_KFREE(SOC_ID_SYS, g_otp_base_vir_addr);
goto err0;
}
osal_iounmap((td_void *)otp_addr, OSAL_IOUNMAP_SIZE);
otp_addr = TD_NULL;
return TD_SUCCESS;
err0:
osal_iounmap((td_void *)otp_addr, OSAL_IOUNMAP_SIZE);
otp_addr = TD_NULL;
err1:
/* 此处定义为0是因为 reserved9/reserved13 没有这块寄存器基地址,用于区分 reserved5 */
if (EXT_REG_AON_CRG_BASE_ADDR != 0x0) {
osal_iounmap((td_void *)g_reg_aon_crg, OSAL_IOUNMAP_SIZE);
g_reg_aon_crg = TD_NULL;
}
return TD_FAILURE;
}
td_s32 drv_reg_init(td_void)
{
td_s32 ret;
g_reg_sys_ctrl = (ext_reg_sys_ctrl *)osal_ioremap_nocache(EXT_REG_SYS_BASE_ADDR, sizeof(ext_reg_sys_ctrl));
if (g_reg_sys_ctrl == TD_NULL) {
soc_print("EXT_REG_SYS_BASE_ADDR ioremap error!\n");
goto err4;
}
g_reg_peri = (ext_reg_peri *)osal_ioremap_nocache(EXT_REG_PERI_BASE_ADDR, sizeof(ext_reg_peri));
if (g_reg_peri == TD_NULL) {
soc_print("EXT_REG_PERI_BASE_ADDR ioremap error!\n");
goto err3;
}
g_reg_io = (ext_reg_io *)osal_ioremap_nocache(EXT_REG_IO_BASE_ADDR, sizeof(ext_reg_io));
if (g_reg_io == TD_NULL) {
soc_print("EXT_REG_IO_BASE_ADDR ioremap error!\n");
goto err2;
}
g_reg_crg = (ext_reg_crg *)osal_ioremap_nocache(EXT_REG_CRG_BASE_ADDR, sizeof(ext_reg_crg));
if (g_reg_crg == TD_NULL) {
soc_print("EXT_REG_CRG_BASE_ADDR ioremap error!\n");
goto err1;
}
ret = drv_reg_otp_aon_init();
if (ret != TD_SUCCESS) {
soc_print("EXT_REG_CRG_BASE_ADDR ioremap error!\n");
goto err0;
}
return TD_SUCCESS;
err0:
osal_iounmap((td_void *)g_reg_crg, OSAL_IOUNMAP_SIZE);
g_reg_crg = TD_NULL;
err1:
osal_iounmap((td_void *)g_reg_io, OSAL_IOUNMAP_SIZE);
g_reg_io = TD_NULL;
err2:
osal_iounmap((td_void *)g_reg_peri, OSAL_IOUNMAP_SIZE);
g_reg_peri = TD_NULL;
err3:
osal_iounmap((td_void *)g_reg_sys_ctrl, OSAL_IOUNMAP_SIZE);
g_reg_sys_ctrl = TD_NULL;
err4:
return TD_FAILURE;
}
td_void drv_reg_exit(td_void)
{
if (g_otp_base_vir_addr != TD_NULL) {
SOC_KFREE(SOC_ID_SYS, g_otp_base_vir_addr);
g_otp_base_vir_addr = TD_NULL;
}
if (g_reg_sys_ctrl != TD_NULL) {
osal_iounmap((td_void *)g_reg_sys_ctrl, OSAL_IOUNMAP_SIZE);
g_reg_sys_ctrl = TD_NULL;
}
if (g_reg_peri != TD_NULL) {
osal_iounmap((td_void *)g_reg_peri, OSAL_IOUNMAP_SIZE);
g_reg_peri = TD_NULL;
}
if (g_reg_io != TD_NULL) {
osal_iounmap((td_void *)g_reg_io, OSAL_IOUNMAP_SIZE);
g_reg_io = TD_NULL;
}
if (g_reg_crg != TD_NULL) {
osal_iounmap((td_void *)g_reg_crg, OSAL_IOUNMAP_SIZE);
g_reg_crg = TD_NULL;
}
if (g_reg_aon_crg != TD_NULL) {
osal_iounmap((td_void *)g_reg_aon_crg, OSAL_IOUNMAP_SIZE);
g_reg_aon_crg = TD_NULL;
}
return;
}
volatile ext_reg_sys_ctrl *drv_sys_get_ctrl_reg_ptr(td_void)
{
return g_reg_sys_ctrl;
}
volatile ext_reg_peri *drv_sys_get_peri_reg_ptr(td_void)
{
return g_reg_peri;
}
volatile ext_reg_io *drv_sys_get_io_reg_ptr(td_void)
{
return g_reg_io;
}
volatile ext_reg_crg *drv_sys_get_crg_reg_ptr(td_void)
{
return g_reg_crg;
}
volatile ext_reg_aon_crg *drv_sys_get_aon_crg_reg_ptr(td_void)
{
return g_reg_aon_crg;
}
td_u8 *drv_sys_get_otp_base_vir_addr(td_void)
{
return g_otp_base_vir_addr;
}