s32 bsp_ipc_int_send(IPC_INT_CORE_E enDstCore, IPC_INT_LEV_E ulLvl) { unsigned long flags = 0,ret = 0; /*如果是modem处于复位状态,则调用AP侧IPC*/ /*ap receive mabx 0,send mbx 13*/ rproc_msg_t msg[2] ; /*发送标志,用于LPM3上接收时解析*/ msg[0]=(0<<24|9<<16|3<<8|14); if(!bsp_reset_ccpu_status_get()) { if(enDstCore!=IPC_CORE_MCORE) { bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC," only can send to mcore\n"); return ERROR; } msg[1]=(rproc_msg_t)(1<<(u32)ulLvl); ret = RPROC_ASYNC_SEND(HISI_RPROC_LPM3 , msg ,2,ASYNC_MSG, NULL, NULL); } else { IPC_CHECK_PARA(ulLvl,IPC_INT_BUTTOM); IPC_CHECK_PARA(enDstCore,IPC_CORE_BUTTOM); /*写原始中断寄存器,产生中断*/ spin_lock_irqsave(&ipc_ctrl.lock,flags); writel((u32)1 << ulLvl,(volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_CPU_RAW_INT(enDstCore))); spin_unlock_irqrestore(&ipc_ctrl.lock,flags); ipc_debug.u32RecvIntCore = enDstCore; ipc_debug.u32IntSendTimes[enDstCore][ulLvl]++; } return OK; }
s32 bsp_ipc_spin_lock_timeout(u32 u32SignalNum, u32 TimeoutMs) { u32 u32HsCtrl = 0; u32 start_time = 0, end_time = 0, elapsed = 0; IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); start_time = bsp_get_slice_value(); elapsed = TimeoutMs * bsp_get_slice_freq() / 1000; /*lint !e647 */ /* coverity[no_escape] */ for(;;) { u32HsCtrl = readl(ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); if (0 == u32HsCtrl) { ipc_debug.u32SemTakeTimes[u32SignalNum]++; ipc_debug.u32SemId = u32SignalNum; break; } end_time = bsp_get_slice_value(); if(get_timer_slice_delta(start_time, end_time) > elapsed) { ipc_debug.u32SemCore = readl(ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_STAT(ipc_ctrl.core_num, u32SignalNum)); return MDRV_ERROR; } } return MDRV_OK; }
s32 bsp_ipc_spin_unlock (u32 u32SignalNum) { IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); writel(0,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); ipc_debug.u32SemGiveTimes[u32SignalNum]++; return MDRV_OK; }
s32 bsp_ipc_sem_give(u32 u32SignalNum) { IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); ipc_debug.u32SemGiveTimes[u32SignalNum]++; /*向信号量请求寄存器写0*/ writel(0,(volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum))); return OK; }
s32 bsp_ipc_sem_give(u32 u32SignalNum) { IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); ipc_debug.u32SemGiveTimes[u32SignalNum]++; /*向信号量请求寄存器写0*/ writel(0,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); return MDRV_OK; }
s32 bsp_ipc_int_disconnect(IPC_INT_LEV_E ulLvl,voidfuncptr routine, u32 parameter) { unsigned int flags; IPC_CHECK_PARA(ulLvl,IPC_INT_BUTTOM); local_irq_save(flags); ipc_ctrl.ipc_int_table[ulLvl].routine = NULL; ipc_ctrl.ipc_int_table[ulLvl].arg = 0; local_irq_restore(flags); return OK; }
s32 bsp_ipc_int_disconnect(IPC_INT_LEV_E ulLvl,voidfuncptr routine, u32 parameter) { unsigned long flags = 0; IPC_CHECK_PARA(ulLvl,(INTSRC_NUM*IPCM_NUM)); spin_lock_irqsave(&ipc_ctrl.lock,flags); ipc_ctrl.ipc_int_table[ulLvl].routine = NULL; ipc_ctrl.ipc_int_table[ulLvl].arg = 0; spin_unlock_irqrestore(&ipc_ctrl.lock,flags); return MDRV_OK; }
s32 bsp_ipc_int_connect(IPC_INT_LEV_E ulLvl, voidfuncptr routine, u32 parameter) { unsigned long flags=0; IPC_CHECK_PARA(ulLvl,IPC_INT_BUTTOM); spin_lock_irqsave(&ipc_ctrl.lock,flags); ipc_ctrl.ipc_int_table[ulLvl].routine = routine; ipc_ctrl.ipc_int_table[ulLvl].arg = parameter; spin_unlock_irqrestore(&ipc_ctrl.lock,flags); return OK; }
s32 bsp_ipc_spin_unlock (u32 u32SignalNum) { IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); if(ipc_modem_reset_flag) { return OK; } writel(0,ipc_ctrl.ipc_base + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); return OK; }
s32 bsp_ipc_int_send(IPC_INT_CORE_E enDstCore, IPC_INT_LEV_E ulLvl) { unsigned int flags=0; IPC_CHECK_PARA(ulLvl,IPC_INT_BUTTOM); IPC_CHECK_PARA(enDstCore,IPC_CORE_BUTTOM); if(ipc_modem_reset_flag) /* 核间信息不可以交互 */ { return IPC_ERR_MODEM_RESETING; } /*写原始中断寄存器,产生中断*/ local_irq_save(flags); writel((u32)1 << (u32)ulLvl,ipc_ctrl.ipc_base + BSP_IPC_CPU_RAW_INT(enDstCore)); local_irq_restore(flags); #ifdef IPC_DEBUG_FEATURE ipc_debug.u32RecvIntCore = enDstCore; ipc_debug.u32IntSendTimes[enDstCore][ulLvl]++; #endif return OK; }
s32 bsp_ipc_int_send(IPC_INT_CORE_E enDstCore, IPC_INT_LEV_E ulLvl) { unsigned long flags = 0; unsigned int n = ulLvl/INTSRC_NUM; IPC_CHECK_PARA(ulLvl,(INTSRC_NUM*IPCM_NUM)); IPC_CHECK_PARA(enDstCore,IPC_CORE_BUTTOM); /*写原始中断寄存器,产生中断*/ spin_lock_irqsave(&ipc_ctrl.lock,flags); #ifdef CONFIG_IPCM_USE_FPGA_VIC if (IPC_CORE_MCORE == enDstCore) { writel((u32)1 << (ulLvl%INTSRC_NUM), g_p532_asic_ipcm_virt_addr + BSP_IPC_CPU_RAW_INT(enDstCore)); } else { writel((u32)1 << (ulLvl%INTSRC_NUM),ipc_ctrl.ipc_base[n] + BSP_IPC_CPU_RAW_INT(enDstCore)); } #else writel((u32)1 << (ulLvl%INTSRC_NUM),ipc_ctrl.ipc_base[n] + BSP_IPC_CPU_RAW_INT(enDstCore)); #endif #ifdef CONFIG_P531_DRX_IPC switch(ulLvl) { case IPC_INT_DICC_RELDATA: case IPC_ACPU_INT_SRC_CCPU_MSG: case IPC_ACPU_INT_SRC_CCPU_NVIM: case IPC_INT_DICC_USRDATA: case IPC_ACPU_INT_SRC_CCPU_ICC: case IPC_ACPU_INT_SRC_ICC_PRIVATE: case IPC_ACPU_SRC_CCPU_DUMP: writel(1<<IPC_MCU_INT_SRC_CCPU_DRX,ipc_ctrl.ipc_base[n] + BSP_IPC_CPU_RAW_INT(IPC_CORE_MCORE)); break; default: break; } #endif spin_unlock_irqrestore(&ipc_ctrl.lock,flags); ipc_debug.u32RecvIntCore = enDstCore; ipc_debug.u32IntSendTimes[enDstCore][ulLvl]++; return MDRV_OK; }
s32 bsp_ipc_int_disable(IPC_INT_LEV_E ulLvl) { u32 u32IntMask = 0,flags=0; IPC_CHECK_PARA(ulLvl,IPC_INT_BUTTOM); /*写中断屏蔽寄存器*/ local_irq_save(flags); u32IntMask = readl(ipc_ctrl.ipc_base + BSP_IPC_CPU_INT_MASK(ipc_ctrl.core_num)); u32IntMask = u32IntMask & (~((u32)1 << (u32)ulLvl)); writel(u32IntMask, ipc_ctrl.ipc_base + BSP_IPC_CPU_INT_MASK(ipc_ctrl.core_num)); local_irq_restore(flags); return OK; }
/*lint -save -e550*/ s32 bsp_ipc_int_enable (IPC_INT_LEV_E ulLvl) { u32 u32IntMask = 0; unsigned long flags=0; IPC_CHECK_PARA(ulLvl,IPC_INT_BUTTOM); /*写中断屏蔽寄存器*/ spin_lock_irqsave(&ipc_ctrl.lock,flags); u32IntMask = readl((const volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_CPU_INT_MASK(ipc_ctrl.core_num))); u32IntMask |= (u32)1 << ulLvl;/* [false alarm]:误报 */ writel(u32IntMask,(volatile void *)(ipc_ctrl.ipc_base+BSP_IPC_CPU_INT_MASK(ipc_ctrl.core_num))); spin_unlock_irqrestore(&ipc_ctrl.lock,flags); return OK; }
s32 bsp_ipc_spin_trylock(u32 u32SignalNum) { u32 u32HsCtrl = 0; IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); u32HsCtrl = readl(ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); if (0 == u32HsCtrl) { ipc_debug.u32SemTakeTimes[u32SignalNum]++; ipc_debug.u32SemId = u32SignalNum; return MDRV_OK; } else return MDRV_ERROR; }
s32 bsp_ipc_sem_take(u32 u32SignalNum,s32 s32timeout) { u32 u32IntMask = 0,ret = 0; /*参数检查*/ IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); /*将申请的信号量对应的释放中断清零*/ writel((u32)1<<u32SignalNum, ipc_ctrl.ipc_base[IPCM_NS]+BSP_IPC_SEM_INT_CLR(ipc_ctrl.core_num)); ret = readl(ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); if(0 == ret) { mask_int(u32SignalNum); ipc_debug.u32SemTakeTimes[u32SignalNum]++; ipc_debug.u32SemId = u32SignalNum; return MDRV_OK; } else { if(false == ipc_ctrl.sem_exist[u32SignalNum]) { bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"need call ipc_sem_create to create this sem before call ipc_sem_take!\n"); return MDRV_ERROR; } if(0 != s32timeout) { /*使能信号量释放中断*/ u32IntMask = readl(ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_SEM_INT_MASK(ipc_ctrl.core_num)); u32IntMask = u32IntMask | ((u32)1 << u32SignalNum); writel(u32IntMask,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_SEM_INT_MASK(ipc_ctrl.core_num)); if (MDRV_OK != osl_sem_downtimeout(&(ipc_ctrl.sem_ipc_task[u32SignalNum]), s32timeout)) { mask_int(u32SignalNum); bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"semTake timeout!\n"); ipc_debug.u32SemTakeFailTimes[u32SignalNum]++; return MDRV_ERROR; } else { /*lint !e525*/ mask_int(u32SignalNum); ipc_debug.u32SemTakeTimes[u32SignalNum]++; ipc_debug.u32SemId = u32SignalNum; return MDRV_OK; } } else { return MDRV_ERROR; } } }
s32 bsp_ipc_int_disable(IPC_INT_LEV_E ulLvl) { u32 u32IntMask = 0; unsigned long flags=0; unsigned int n = ulLvl/INTSRC_NUM; IPC_CHECK_PARA(ulLvl,(INTSRC_NUM*IPCM_NUM)); /*写中断屏蔽寄存器*/ spin_lock_irqsave(&ipc_ctrl.lock,flags); u32IntMask = readl(ipc_ctrl.ipc_base[n] + BSP_IPC_CPU_INT_MASK(ipc_ctrl.core_num)); u32IntMask = u32IntMask & (~((u32)1 << (ulLvl%INTSRC_NUM))); writel(u32IntMask, ipc_ctrl.ipc_base[n] + BSP_IPC_CPU_INT_MASK(ipc_ctrl.core_num)); spin_unlock_irqrestore(&ipc_ctrl.lock,flags); return MDRV_OK; }
s32 bsp_ipc_sem_create(u32 u32SignalNum) { IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); if(true != ipc_ctrl.sem_exist[u32SignalNum])/*避免同一个信号量在没有删除的情况下创建多次*/ { osl_sem_init(SEM_EMPTY,&(ipc_ctrl.sem_ipc_task[u32SignalNum])); ipc_ctrl.sem_exist[u32SignalNum] = true; return MDRV_OK; } else { return MDRV_OK; } }
s32 bsp_ipc_spin_lock(u32 u32SignalNum) { u32 u32HsCtrl = 0; IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); for(;;) { u32HsCtrl = readl((const volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum))); if (0 == u32HsCtrl) { ipc_debug.u32SemTakeTimes[u32SignalNum]++; ipc_debug.u32SemId = u32SignalNum; break; } } return OK; }
s32 bsp_ipc_spin_lock(u32 u32SignalNum) { u32 u32HsCtrl = 0; IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); if(ipc_modem_reset_flag) { return OK; } for(;;) { u32HsCtrl = readl(ipc_ctrl.ipc_base + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); if (0 == u32HsCtrl) { break; } } return OK; }
s32 bsp_ipc_sem_delete(u32 u32SignalNum) { IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); if(false == ipc_ctrl.sem_exist[u32SignalNum] ) { bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"semphore not exists,may be deleted already.\n"); return MDRV_ERROR; } else { if (osl_sema_delete(&(ipc_ctrl.sem_ipc_task[u32SignalNum]))) { bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"Delete semphore failed.\n"); return MDRV_ERROR; } ipc_ctrl.sem_exist[u32SignalNum] = false; return MDRV_OK; } }
s32 bsp_ipc_spin_unlock (u32 u32SignalNum) { IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); writel(0,(volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum))); return OK; }