/* * 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; }