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.

177 lines
5.0 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2019. All rights reserved.
* Description: decoder
* Author: Hisilicon
* Create: 2012-04-22
*/
#include "soc_osal.h"
#include "soc_log.h"
#include "td_type.h"
#include "proc.h"
#include "dmcu_comm.h"
#include "dmcu_pmp.h"
#include "dmcu_mem.h"
#include "dmcu_hal.h"
#include "dmcu_dbg.h"
#include "dmcu_adapt.h"
volatile td_u32 g_dmcu_boot_flag = 1;
volatile td_u32 g_status = 0;
td_s32 dmcu_liteos_suspend(td_void)
{
mcu_dmcu_status *mcu_status = get_mcu_status();
g_status = mcu_status->u32;
return TD_SUCCESS;
}
td_s32 dmcu_liteos_resume(td_void)
{
mcu_dmcu_status *mcu_status = get_mcu_status();
mcu_status->u32 = g_status;
dmcu_itcm_resume();
dmcu_mem_resume();
OsTickStart();
LOS_CpupReset();
return TD_SUCCESS;
}
static td_s32 dmcu_cmd_suspend_process(dmcu_ctrl_cmd cmd, td_void *args, td_u32 length)
{
g_dmcu_boot_flag = 1;
dmcu_liteos_suspend();
osal_irq_lock();
os_sr_save_register();
if (g_dmcu_boot_flag == 1) {
td_u32 *ack = TD_NULL;
g_dmcu_boot_flag = 0;
dmcu_flush_d_cache_by_all();
ack = (td_u32 *)DMCU_COM_START_ADDR;
dmcu_flush_d_cache_by_all();
osal_printk("dmcu_cmd_suspend_process suspend ok\n");
*(volatile td_u32 *)(ack) = 1;
while (1);
}
dmcu_liteos_resume();
osal_irq_unlock();
return TD_SUCCESS;
}
static td_s32 dmcu_cmd_resume_process(dmcu_ctrl_cmd cmd, td_void *args, td_u32 length)
{
osal_printk("dmcu_cmd_resume_process success\n");
return TD_SUCCESS;
}
static dmcu_recieve_cmd_function g_dmcu_recieve_cmd_function[] = {
dmcu_recieve_cmd_fn_def(DMCU_CMD_SUSPEND, dmcu_cmd_suspend_process),
dmcu_recieve_cmd_fn_def(DMCU_CMD_RESUME, dmcu_cmd_resume_process),
dmcu_recieve_cmd_fn_def(DMCU_CMD_PROC_WRITE, dmcu_proc_write_process),
dmcu_recieve_cmd_fn_def(DMCU_CMD_PROC_READ, dmcu_proc_read_process),
};
td_s32 dmcu_ctrl_server_process_task(dmcu_ctrl_cmd cmd, td_void *args, td_u32 length)
{
td_u32 i;
td_u32 cmd_num = sizeof(g_dmcu_recieve_cmd_function) / sizeof(dmcu_recieve_cmd_function);
for (i = 0; i < cmd_num; i++) {
if (cmd == g_dmcu_recieve_cmd_function[i].cmd) {
return g_dmcu_recieve_cmd_function[i].handler(cmd, args, length);
}
}
return TD_FAILURE;
}
td_s32 dmcu_ctrl_server_process(dmcu_ctrl_cmd cmd, td_void *args, td_u32 length)
{
return dmcu_ctrl_server_process_task(cmd, args, length);
}
static dmcu_server_ctx g_dmcu_server_ctx = { 0 };
static td_s32 dmcu_server_ctrl_thread(td_void *data)
{
td_s32 ret, i;
const td_u32 delay_time = 10; /* 10 is delay for ctrl_thread loop */
ipcm_msg *msg = TD_NULL;
td_u8 try_times = 5;
mcu_dmcu_status *mcu_status = get_mcu_status();
mcu_status->bit.ctrl_thread_status = READY;
osal_set_freezable();
while (!osal_kthread_should_stop()) {
if (osal_try_to_freeze() == TD_TRUE) {
mcu_status->bit.ctrl_thread_status = FREEZE;
continue;
}
mcu_status->bit.ctrl_thread_status = RUNNING;
i = 0;
while (i < try_times) {
ret = drv_ipcm_receive_msg(IPCM_CTRL, &msg);
if (ret == TD_SUCCESS) {
ret = dmcu_ctrl_server_process(msg->head.cmd, (td_void *)(td_uintptr_t)msg->data.para_data,
msg->data.data_len);
msg->head.ret_status = ret;
msg->head.option.ack_data_ok = TD_TRUE;
g_table_ctx_info->queue_info[IPCM_CTRL].read_pos += msg->data.data_len + sizeof(ipcm_msg);
}
i++;
}
osal_msleep_uninterruptible(delay_time);
}
mcu_status->bit.ctrl_thread_status = STOP;
return TD_SUCCESS;
}
td_s32 dmcu_server_ctrl_init(td_void)
{
osal_task *pthread;
mcu_dmcu_status *mcu_status = get_mcu_status();
mcu_status->bit.ctrl_thread_status = NO_READY;
pthread = osal_kthread_create(dmcu_server_ctrl_thread, &g_dmcu_server_ctx, DEF_DMCU_CTRL_THREAD_NAME, STACK_4096);
if (pthread == TD_NULL) {
osal_printk("create dmcu server kthread failed\r\n");
return TD_FAILURE;
}
osal_kthread_set_priority(pthread, OSAL_TASK_PRIORITY_HIGH);
g_dmcu_server_ctx.thread_handle = pthread;
return TD_SUCCESS;
}
td_s32 dmcu_server_ctrl_deinit(td_void)
{
osal_kthread_destroy(g_dmcu_server_ctx.thread_handle, 1);
return TD_SUCCESS;
}
td_s32 dmcu_comm_ctrl_init(td_void)
{
td_s32 ret;
mcu_dmcu_status *mcu_status = get_mcu_status();
dmcu_adapt_init();
ret = dmcu_server_ctrl_init();
if (ret != TD_SUCCESS) {
osal_printk("dmcu_server_ctrl_init fail\n");
return TD_FAILURE;
}
mcu_status->bit.dmcu_server_ctrl_init = 1;
osal_printk("open ctrl ipcm success. queue size:%d\n", DMCU_IPCM_CTRL_SIZE);
return TD_SUCCESS;
}
td_s32 dmcu_comm_ctrl_deinit(td_void)
{
dmcu_adapt_deinit();
dmcu_server_ctrl_deinit();
osal_printk("close ctrl ipcm success.\n");
return TD_SUCCESS;
}