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.

762 lines
20 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* Description: asr driver
* Author: audio
* Create: 2020/9/11
* Notes:
* History: 2020/9/11 init.
*/
#include "reg_crg_ext.h"
#include "drv_sys_ext.h"
#include "td_type.h"
#include "drv_asr_elf.h"
#include "drv_asr_defines.h"
#include "drv_asr_ext.h"
#include "osal_ext.h"
#include "reg_asr_ext.h"
#include "drv_file_ext.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
static td_uchar* g_pc_elf_buf = TD_NULL;
static td_uchar* g_pc_overlay_buf = TD_NULL;
static osal_semaphore g_dsp_mutex = {0};
static osal_task *g_asr_thread = TD_NULL;
static volatile dsp_regs_type* g_reg_asr_secure = TD_NULL;
static volatile sysctrl_asr_cfg_0* g_reg_asr_sysctl = TD_NULL;
static volatile sc_crg_ctrl_0* g_reg_asr_sc_crg_ctrl = TD_NULL;
static volatile td_u32* g_reg_asr_sc_epll_crg_2 = TD_NULL;
static volatile U_PERI_CRG182* g_reg_asr_crg = TD_NULL;
static volatile reg_sys_ctl_asr_idle_mask* g_reg_sysctl_asr_int_mask = TD_NULL;
static volatile reg_sys_ctl_asr_idle_sta* g_reg_sysctl_asr_int_sta = TD_NULL;
static volatile reg_sys_ctl_asr_idle_mask_sta* g_reg_sysctl_asr_int_mask_sta = TD_NULL;
static volatile td_u32* g_overlay_start_entry = TD_NULL;
static volatile reg_asr_start_vec *g_reg_asr_start_vec = TD_NULL;
static td_void asr_reg_unmap(td_void);
#define DSP_OCRAM_SIZE 0x8000
#define REG_START 0
#define REG_END (0x10000000 - 0x4)
#define DDR_ADDR_START 0x10000000
/* ASR */
#define REG_ASR 0x00980000
#define DSP_SECUE_REG_ADDR 0x00982000
/* system ctrl reg */
#define ASR_CRG_CTRL_0_ADDR 0x00840050
#define ASR_CRG_0_ADDR 0x00840070
#define ASR_SC_EPLL_CRG_2_ADDR 0x00840088 /* SC_EPLL_CRG_2 */
#define ASR_PWRUP_CTRL_ADDR 0x00840190
#define ASR_START_VEC 0x009802f8
#define ASR_INT_MASK_ADDR 0x00840B80
#define ASR_INT_STATE_ADDR 0x00840B88
#define ASR_INT_MASK_STATE_ADDR 0x00840B8c
#define ASR_CRG182_REG_ADDR 0x00A002D8
#define ASR_OVERLAY_ENTRY_ADDR 0x02819000
static td_s32 asr_check_firmware_file(td_void)
{
td_s32 ret;
td_u32 i;
td_u32 path_num;
td_void *fp_fw = TD_NULL;
td_void *fp_overlay = TD_NULL;
td_u8 fw_name[128]; /* 128: len */
td_u8 overlay_name[128];
td_u8 *path[] = {
"/lib/firmware/",
"/vendor/firmware/"
};
path_num = sizeof(path) / sizeof(path[0]);
for (i = 0; i < path_num; i++) {
ret = snprintf_s(fw_name, sizeof(fw_name), sizeof(fw_name) - 1, "%s%s", path[i], ASR_BIN_PATH);
if (ret < 0) {
soc_err_print_call_fun_err(snprintf_s, ret);
return ret;
}
ret = snprintf_s(overlay_name, sizeof(overlay_name), sizeof(overlay_name) - 1, "%s%s",
path[i], ASR_OVERLAY_PATH);
if (ret < 0) {
soc_err_print_call_fun_err(snprintf_s, ret);
return ret;
}
fp_fw = osal_klib_fopen(fw_name, OSAL_O_RDONLY, 0);
fp_overlay = osal_klib_fopen(overlay_name, OSAL_O_RDONLY, 0);
if (fp_fw == TD_NULL || fp_overlay == TD_NULL) {
continue;
}
osal_klib_fclose(fp_fw);
osal_klib_fclose(fp_overlay);
return TD_SUCCESS;
}
return TD_FAILURE;
}
static td_s32 asr_load_asr_code(td_void)
{
td_s32 ret;
osal_firmware *fw = TD_NULL;
osal_firmware *overlay = TD_NULL;
ret = asr_check_firmware_file();
if (ret != TD_SUCCESS) {
return ret;
}
ret = osal_request_firmware_into_buf(&fw, ASR_BIN_PATH, g_pc_elf_buf, ELF_SIZE_MAX);
if (ret != 0) {
soc_err_print_call_fun_err(osal_request_firmware_into_buf, ret);
return ret;
}
ret = osal_request_firmware_into_buf(&overlay, ASR_OVERLAY_PATH, g_pc_overlay_buf, OVERLAY_SIZE_MAX);
if (ret != 0) {
soc_err_print_call_fun_err(osal_request_firmware_into_buf, ret);
return ret;
}
osal_release_firmware(fw);
osal_release_firmware(overlay);
return TD_SUCCESS;
}
static td_s32 asr_load_firmware_thread(td_void *data)
{
td_s32 ret;
while (!osal_kthread_should_stop()) {
osal_msleep(500); /* 500 ms */
ret = asr_load_asr_code();
if (ret != TD_SUCCESS) {
continue;
}
break;
}
return TD_SUCCESS;
}
static td_s32 asr_try_loading_firmware(td_void)
{
td_s32 ret;
ret = asr_load_asr_code();
if (ret == TD_SUCCESS) {
return TD_SUCCESS;
}
g_asr_thread = osal_kthread_create(asr_load_firmware_thread, TD_NULL, "asr_loading_thread", 0);
if (g_asr_thread == TD_NULL) {
soc_err_print_call_fun_err(osal_kthread_create, TD_FAILURE);
return TD_FAILURE;
}
return TD_SUCCESS;
}
static td_s32 asr_firmware_buf_init(td_void)
{
g_pc_elf_buf = osal_vmalloc(ELF_SIZE_MAX);
if (g_pc_elf_buf == TD_NULL) {
soc_log_err("g_pc_elf_buf SOC_VMALLOC fail\n");
return TD_FAILURE;
}
g_pc_overlay_buf = osal_vmalloc(OVERLAY_SIZE_MAX);
if (g_pc_overlay_buf == TD_NULL) {
soc_log_err("g_pc_elf_buf SOC_VMALLOC fail\n");
osal_vfree(g_pc_elf_buf);
g_pc_elf_buf = TD_NULL;
return TD_FAILURE;
}
memset_s(g_pc_elf_buf, ELF_SIZE_MAX, 0, ELF_SIZE_MAX); /* reset firmware area to all 0. */
memset_s(g_pc_overlay_buf, OVERLAY_SIZE_MAX, 0, OVERLAY_SIZE_MAX);
return TD_SUCCESS;
}
static td_void asr_firmware_buf_deinit(td_void)
{
if (g_pc_elf_buf != TD_NULL) {
osal_vfree(g_pc_elf_buf);
g_pc_elf_buf = TD_NULL;
}
asr_reg_unmap();
return;
}
td_s32 asr_firmware_init(td_void)
{
td_s32 ret;
ret = asr_firmware_buf_init();
if (ret != TD_SUCCESS) {
soc_log_err("asr_firmware_buf_init fail\n");
return TD_FAILURE;
}
ret = asr_try_loading_firmware();
if (ret != TD_SUCCESS) {
soc_log_err("asr_try_loading_firmware fail\n");
return TD_FAILURE;
}
return TD_SUCCESS;
}
td_void asr_firmware_deinit(td_void)
{
if (g_asr_thread != TD_NULL) {
osal_kthread_destroy(g_asr_thread, 1);
g_asr_thread = TD_NULL;
}
asr_firmware_buf_deinit();
return;
}
static td_s32 asr_load_elf(td_void)
{
td_s32 ret;
td_u32 start_entry;
if (g_pc_elf_buf == TD_NULL) {
soc_log_err("no asr firmware, load asr fail!\n");
return TD_FAILURE;
}
asr_copy_elf_section(g_pc_overlay_buf);
ret = asr_check_elf_paser(g_pc_overlay_buf);
if (ret != TD_SUCCESS) {
soc_log_err("call asr_check_elf_paser failed(0x%x)\n", ret);
osal_vfree(g_pc_overlay_buf);
g_pc_overlay_buf = TD_NULL;
return ret;
}
asr_get_elf_entry(g_pc_overlay_buf, &start_entry);
*g_overlay_start_entry = start_entry;
asr_copy_elf_section(g_pc_elf_buf);
ret = asr_check_elf_paser(g_pc_elf_buf);
if (ret != TD_SUCCESS) {
soc_log_err("call asr_check_elf_paser failed(0x%x)\n", ret);
return ret;
}
return ret;
}
td_s32 asr_sem_init(td_void)
{
td_s32 ret;
ret = osal_sem_init(&g_dsp_mutex, 1);
if (ret != TD_SUCCESS) {
soc_log_err("call osal_sem_init fail: 0x%x\n", ret);
return ret;
}
return TD_SUCCESS;
}
td_void asr_sem_deinit(td_void)
{
osal_sem_destroy(&g_dsp_mutex);
}
static td_void asr_reg_unmap1(td_void)
{
if (g_reg_asr_secure != TD_NULL) {
osal_iounmap((td_void *)g_reg_asr_secure, sizeof(dsp_regs_type));
g_reg_asr_secure = TD_NULL;
}
if (g_reg_asr_sysctl != TD_NULL) {
osal_iounmap((td_void *)g_reg_asr_sysctl, sizeof(sysctrl_asr_cfg_0));
g_reg_asr_sysctl = TD_NULL;
}
if (g_reg_asr_sc_crg_ctrl != TD_NULL) {
osal_iounmap((td_void *)g_reg_asr_sc_crg_ctrl, sizeof(sc_crg_ctrl_0));
g_reg_asr_sc_crg_ctrl = TD_NULL;
}
if (g_reg_asr_sc_epll_crg_2 != TD_NULL) {
osal_iounmap((td_void *)g_reg_asr_sc_epll_crg_2, sizeof(td_u32));
g_reg_asr_sc_epll_crg_2 = TD_NULL;
}
if (g_reg_asr_crg != TD_NULL) {
osal_iounmap((td_void *)g_reg_asr_crg, sizeof(U_PERI_CRG182));
g_reg_asr_crg = TD_NULL;
}
if (g_overlay_start_entry != TD_NULL) {
osal_iounmap((td_void *)g_overlay_start_entry, sizeof(td_u32));
g_overlay_start_entry = TD_NULL;
}
}
static td_void asr_reg_unmap2(td_void)
{
if (g_reg_sysctl_asr_int_mask != TD_NULL) {
osal_iounmap((td_void *)g_reg_sysctl_asr_int_mask, sizeof(reg_sys_ctl_asr_idle_mask));
g_reg_sysctl_asr_int_mask = TD_NULL;
}
if (g_reg_sysctl_asr_int_sta != TD_NULL) {
osal_iounmap((td_void *)g_reg_sysctl_asr_int_sta, sizeof(reg_sys_ctl_asr_idle_sta));
g_reg_sysctl_asr_int_sta = TD_NULL;
}
if (g_reg_sysctl_asr_int_mask_sta != TD_NULL) {
osal_iounmap((td_void *)g_reg_sysctl_asr_int_mask_sta, sizeof(reg_sys_ctl_asr_idle_mask_sta));
g_reg_sysctl_asr_int_mask_sta = TD_NULL;
}
if (g_reg_asr_start_vec != TD_NULL) {
osal_iounmap((td_void *)g_reg_asr_start_vec, sizeof(reg_asr_start_vec));
g_reg_asr_start_vec = TD_NULL;
}
}
static td_void asr_reg_unmap(td_void)
{
asr_reg_unmap1();
asr_reg_unmap2();
}
static td_void asr_reg_map1(td_void)
{
g_reg_asr_secure = (volatile dsp_regs_type*)osal_ioremap_nocache(DSP_SECUE_REG_ADDR, sizeof(dsp_regs_type));
if (g_reg_asr_secure == TD_NULL) {
soc_log_err("osal_ioremap_nocache dsp_regs_type failed!\n");
goto err;
}
g_reg_asr_sysctl = (volatile sysctrl_asr_cfg_0*)osal_ioremap_nocache(ASR_CRG_0_ADDR,
sizeof(sysctrl_asr_cfg_0));
if (g_reg_asr_sysctl == TD_NULL) {
soc_log_err("osal_ioremap_nocache sysctrl_asr_cfg_0 failed!\n");
goto err;
}
g_reg_asr_sc_crg_ctrl = (volatile sc_crg_ctrl_0*)osal_ioremap_nocache(ASR_CRG_CTRL_0_ADDR,
sizeof(sc_crg_ctrl_0));
if (g_reg_asr_sc_crg_ctrl == TD_NULL) {
soc_log_err("osal_ioremap_nocache sc_crg_ctrl_0 failed!\n");
goto err;
}
g_reg_asr_sc_epll_crg_2 = (volatile td_u32*)osal_ioremap_nocache(ASR_SC_EPLL_CRG_2_ADDR,
sizeof(td_u32));
if (g_reg_asr_sc_epll_crg_2 == TD_NULL) {
soc_log_err("osal_ioremap_nocache sc_crg_ctrl_0 failed!\n");
goto err;
}
g_reg_asr_crg = (volatile U_PERI_CRG182*)osal_ioremap_nocache(ASR_CRG182_REG_ADDR, sizeof(U_PERI_CRG182));
if (g_reg_asr_crg == TD_NULL) {
soc_log_err("osal_ioremap_nocache U_PERI_CRG182 failed!\n");
goto err;
}
g_overlay_start_entry = (volatile td_u32*)osal_ioremap_nocache(ASR_OVERLAY_ENTRY_ADDR, sizeof(td_u32));
if (g_overlay_start_entry == TD_NULL) {
soc_log_info("osal_ioremap_nocache sc_crg_ctrl_0 failed!\n");
goto err;
}
return;
err:
asr_reg_unmap1();
}
static td_void asr_reg_map2(td_void)
{
g_reg_sysctl_asr_int_mask = (volatile reg_sys_ctl_asr_idle_mask*)osal_ioremap_nocache(ASR_INT_MASK_ADDR,
sizeof(reg_sys_ctl_asr_idle_mask));
if (g_reg_sysctl_asr_int_mask == TD_NULL) {
soc_log_err("osal_ioremap_nocache reg_sys_ctl_asr_idle_maskfailed!\n");
goto err;
}
g_reg_sysctl_asr_int_sta = (volatile reg_sys_ctl_asr_idle_sta*)osal_ioremap_nocache(ASR_INT_STATE_ADDR,
sizeof(reg_sys_ctl_asr_idle_sta));
if (g_reg_sysctl_asr_int_sta == TD_NULL) {
soc_log_err("osal_ioremap_nocache reg_sys_ctl_asr_idle_sta!\n");
goto err;
}
g_reg_sysctl_asr_int_mask_sta = (volatile reg_sys_ctl_asr_idle_mask_sta*)
osal_ioremap_nocache(ASR_INT_MASK_STATE_ADDR, sizeof(reg_sys_ctl_asr_idle_mask_sta));
if (g_reg_sysctl_asr_int_mask_sta == TD_NULL) {
soc_log_err("osal_ioremap_nocache reg_sys_ctl_asr_idle_sta!\n");
goto err;
}
g_reg_asr_start_vec = (volatile reg_asr_start_vec *)osal_ioremap_nocache(ASR_START_VEC,
sizeof(reg_asr_start_vec));
if (g_reg_asr_start_vec == TD_NULL) {
soc_log_info("osal_ioremap_nocache g_reg_asr_start_vec failed!\n");
goto err;
}
return;
err:
asr_reg_unmap();
}
static td_void asr_reg_map(td_void)
{
asr_reg_map1();
asr_reg_map2();
}
static td_void asr_select_clk(td_void)
{
volatile U_PERI_CRG182 crg;
crg.u32 = g_reg_asr_crg->u32;
crg.bits.dsp0_cksel = 0x0; /* 0-12M, 1-600M, 2-784M, 3-392M, 4-50M ,5-25M, 7-710M */
g_reg_asr_crg->u32 = crg.u32;
}
static td_void asr_sc_crg_ctrl_init(td_void)
{
volatile sc_crg_ctrl_0 crg;
crg.u32 = g_reg_asr_sc_crg_ctrl->u32;
crg.bits.sys_aclk_asr_cken = 1; /* [20] */
g_reg_asr_sc_crg_ctrl->u32 = crg.u32;
}
static td_void asr_sc_epll_crg_2_init(td_void)
{
*g_reg_asr_sc_epll_crg_2 = 0x100000; /* EPLL enable */
}
static void asr_disable(td_void)
{
volatile dsp_ctrl_info dsp_ctrl;
dsp_ctrl.u32 = g_reg_asr_secure->dsp_ctrl.u32;
dsp_ctrl.bits.dsp_en = 0;
g_reg_asr_secure->dsp_ctrl.u32 = dsp_ctrl.u32;
osal_msleep(1);
}
static void asr_enable(td_void)
{
volatile dsp_ctrl_info dsp_ctrl;
dsp_ctrl.u32 = g_reg_asr_secure->dsp_ctrl.u32;
dsp_ctrl.bits.dsp_en = 1;
g_reg_asr_secure->dsp_ctrl.u32 = dsp_ctrl.u32;
osal_msleep(1);
}
static void asr_sysctrl_reset(td_void)
{
volatile sysctrl_asr_cfg_0 crg;
crg.u32 = g_reg_asr_sysctl->u32;
crg.bits.sys_dsp0_srst_req = 1;
crg.bits.sys_dsp0_debug_srst_req = 1;
g_reg_asr_sysctl->u32 = crg.u32;
osal_msleep(1);
}
static void asr_sysctrl_unreset(td_void)
{
volatile sysctrl_asr_cfg_0 crg;
crg.u32 = g_reg_asr_sysctl->u32;
crg.bits.sys_dsp0_srst_req = 0;
crg.bits.sys_dsp0_debug_srst_req = 0;
g_reg_asr_sysctl->u32 = crg.u32;
osal_msleep(1);
}
static void asr_start_addr_set(td_s32 val)
{
volatile reg_asr_start_vec start_vec;
start_vec.u32 = g_reg_asr_start_vec->u32;
start_vec.bits.statvectorsel = val;
g_reg_asr_start_vec->u32 = start_vec.u32;
osal_msleep(1); /* wait 1 ms */
}
static td_void asr_clk_set(td_void)
{
volatile sysctrl_asr_cfg_0 crg;
crg.u32 = g_reg_asr_sysctl->u32;
/*
* DSP0 work clk
* 00: crystal oscillator 24M
* 01: clk_dsp0_occ --> 600M
* 10: clk_12d288m_int --> 394M
* 11: clk_49d1m_int --> 524M
*/
crg.bits.sys_asr0_clk_sel = 2; /* 2: 349M */
/*
* DSP0 bus AXI clk
* 00: crystal oscillator 24M
* 01: aclk_asr_occ
* 10: clk_49d1m_ini --> 349M
* 11: clk_12d288m_ini --> 394M
*/
crg.bits.sys_asr0_axi_clk_sel = 2; /* 2: 349M */
g_reg_asr_sysctl->u32 = crg.u32;
osal_msleep(1);
/*
* ocram clk choice
* 0: crystal oscillator 24M
* 1: choice 394MHz occ clk
*/
crg.u32 = g_reg_asr_sysctl->u32;
crg.bits.sys_ocram_work_cksel = 1;
g_reg_asr_sysctl->u32 = crg.u32;
osal_msleep(1);
crg.u32 = g_reg_asr_sysctl->u32;
crg.bits.sys_ocram_cken = 1;
g_reg_asr_sysctl->u32 = crg.u32;
osal_msleep(1);
asr_select_clk();
crg.u32 = g_reg_asr_sysctl->u32;
crg.bits.sys_dsp0_cken = 1;
g_reg_asr_sysctl->u32 = crg.u32;
osal_msleep(1);
}
static td_void asr_clk_restore(td_void)
{
volatile sysctrl_asr_cfg_0 crg;
crg.u32 = g_reg_asr_sysctl->u32;
/*
* DSP0 work clk
* 00: crystal oscillator 24M
* 01: clk_dsp0_occ --> 600M
* 10: clk_12d288m_int --> 394M
* 11: clk_49d1m_int --> 524M
*/
crg.bits.sys_asr0_clk_sel = 0;
/*
* DSP0 bus AXI clk
* 00: crystal oscillator 24M
* 01: aclk_asr_occ
* 10: clk_49d1m_ini --> 349M
* 11: clk_12d288m_ini --> 394M
*/
crg.bits.sys_asr0_axi_clk_sel = 0;
g_reg_asr_sysctl->u32 = crg.u32;
osal_msleep(1);
/*
* ocram clk choice
* 0: crystal oscillator 24M
* 1: choice 394MHz occ clk
*/
crg.u32 = g_reg_asr_sysctl->u32;
crg.bits.sys_ocram_work_cksel = 0;
g_reg_asr_sysctl->u32 = crg.u32;
osal_msleep(1);
crg.u32 = g_reg_asr_sysctl->u32;
crg.bits.sys_ocram_cken = 1;
g_reg_asr_sysctl->u32 = crg.u32;
osal_msleep(1);
asr_select_clk();
crg.u32 = g_reg_asr_sysctl->u32;
crg.bits.sys_dsp0_cken = 1;
g_reg_asr_sysctl->u32 = crg.u32;
osal_msleep(1);
}
static td_s32 dsp_start(td_void)
{
td_u32 ret;
asr_sc_epll_crg_2_init();
asr_sc_crg_ctrl_init();
asr_disable();
asr_sysctrl_reset();
asr_start_addr_set(1);
asr_clk_set();
asr_reset_elf_section(ASR_IMG_START_ADDR, ASR_IMG_SIZE); /* Clear .text area before cancel reset. */
g_reg_asr_secure->dsp_work_on.bits.dsp_work_on = 0x0;
g_reg_sysctl_asr_int_sta->bits.sys_asr_idle_int = 0x0;
g_reg_sysctl_asr_int_mask_sta->bits.sys_asr_idle_mask_int = 0x0;
asr_sysctrl_unreset();
ret = asr_load_elf();
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(asr_load_elf, ret);
return ret;
}
osal_msleep(1);
ret = asr_flush_cache_area(ASR_IMG_START_ADDR, ASR_IMG_SIZE);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(asr_flush_cache_area, ret);
return ret;
}
asr_sysctrl_reset();
asr_start_addr_set(0);
asr_sysctrl_unreset();
asr_enable();
return TD_SUCCESS;
}
static td_s32 dsp_check_running(td_void)
{
td_u8 work_on;
td_u32 wait_ms = 0;
while (wait_ms++ < 30) { /* try 30 times */
work_on = g_reg_asr_secure->dsp_work_on.bits.dsp_work_on;
if (work_on == 1) {
g_reg_asr_secure->dsp_work_on.bits.dsp_work_on = 0x0;
return TD_SUCCESS;
}
osal_msleep(100); /* wait 100 ms */
if (wait_ms % 50 == 0) { /* 50 for not printf frequently */
soc_log_err("wait %d\n", (wait_ms / 10)); /* 10 means every 1s */
}
}
return TD_FAILURE;
}
td_s32 dsp_check_idle(td_void)
{
td_u32 cnt = 0;
while (cnt < 10) { /* try 10 times */
if (g_reg_sysctl_asr_int_sta->bits.sys_asr_idle_int == 1) {
return TD_SUCCESS;
}
if (g_reg_sysctl_asr_int_mask_sta->bits.sys_asr_idle_mask_int == 1) {
return TD_SUCCESS;
}
cnt++;
osal_msleep(100); /* wait 100 ms */
if (cnt % 10 == 0) { /* wait 10 is cnt */
soc_log_err("dsp_check_idle times : %d\n", cnt);
}
}
return TD_FAILURE;
}
static td_s32 dsp_wait_running(td_void)
{
td_s32 ret;
ret = dsp_check_running();
if (ret != TD_SUCCESS) {
soc_log_err("chk runnig fail\n");
return ret;
}
ret = dsp_check_idle();
if (ret != TD_SUCCESS) {
soc_log_err("dsp_check_idle fail\n");
return ret;
}
return TD_SUCCESS;
}
static td_s32 asr_reset_toboot(td_void)
{
td_s32 ret;
ret = dsp_start();
if (ret != TD_SUCCESS) {
soc_log_err("dsp start failed(ret:0x%x)\n", ret);
return ret;
}
return dsp_wait_running();
}
td_void asr_resume_reset(td_void)
{
asr_sc_crg_ctrl_init();
asr_clk_set();
}
td_void asr_restore_default_clk(td_void)
{
asr_sysctrl_reset();
asr_clk_restore();
}
td_s32 asr_reset(td_void)
{
td_s32 ret;
osal_sem_down_interruptible(&g_dsp_mutex);
asr_reg_map();
osal_sem_up(&g_dsp_mutex);
ret = asr_reset_toboot();
if (ret != TD_SUCCESS) {
soc_log_err("asr_reset_toboot failed\n");
asr_reg_unmap();
return ret;
}
osal_msleep(100); /* delay 100ms */
return TD_SUCCESS;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */