static void  mask_int(u32 u32SignalNum)
{
	u32 u32IntMask = 0;
	unsigned long flags=0;
	spin_lock_irqsave(&ipc_ctrl.lock,flags);
	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));
	spin_unlock_irqrestore(&ipc_ctrl.lock,flags);
}
예제 #2
0
static void  mask_int(u32 u32SignalNum)
{
	u32 u32IntMask = 0;
	unsigned long flags=0;
	spin_lock_irqsave(&ipc_ctrl.lock,flags);
	u32IntMask = readl((const volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_SEM_INT_MASK(ipc_ctrl.core_num)));
	u32IntMask = u32IntMask & (~((u32)1 << u32SignalNum)); /* [false alarm]:误报 */
	writel(u32IntMask,(volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_SEM_INT_MASK(ipc_ctrl.core_num)));
	spin_unlock_irqrestore(&ipc_ctrl.lock,flags);
}
 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;
		}
	}

}
void bsp_ipc_init(void)
{
	
	if(MODEM_ALREADY_INIT_MAGIC != get_modem_init_flag())
	{
		ipc_ctrl.core_num = IPC_CORE_MCORE;
		memset((void*)(ipc_ctrl.ipc_int_table),0x0,sizeof(struct ipc_entry) *INTSRC_NUM);
		ipc_ctrl.ipc_base = HI_IPCM_REGBASE_ADDR_VIRT;   
		ipc_ctrl.ipc_store_reg_table[0] = BSP_IPC_CPU_INT_MASK(0);       
		ipc_ctrl.ipc_store_reg_table[1] = BSP_IPC_CPU_INT_MASK(1);       
		ipc_ctrl.ipc_store_reg_table[2] = BSP_IPC_CPU_INT_MASK(3);       
		ipc_ctrl.ipc_store_reg_table[3] = BSP_IPC_CPU_INT_MASK(4); 
		ipc_ctrl.ipc_store_reg_table[4] = BSP_IPC_SEM_INT_MASK(0);       
		ipc_ctrl.ipc_store_reg_table[5] = BSP_IPC_SEM_INT_MASK(1);       
		ipc_ctrl.ipc_store_reg_table[6] = BSP_IPC_SEM_INT_MASK(3);       
		ipc_ctrl.ipc_store_reg_table[7] = BSP_IPC_SEM_INT_MASK(4);   
		ipc_ctrl.ipc_store_reg_table[8] = BSP_IPC_CPU_INT_MASK(2);       
		ipc_ctrl.ipc_store_reg_table[9] = BSP_IPC_SEM_INT_MASK(2);    
		writel(0x0,ipc_ctrl.ipc_base + BSP_IPC_CPU_INT_MASK(ipc_ctrl.core_num));
		writel(0x0,ipc_ctrl.ipc_base + BSP_IPC_SEM_INT_MASK(ipc_ctrl.core_num));
	}
	(void)request_irq(MCPU_IPC_INT, ipc_int_handler, 0, 0, 0);
	enable_irq(MCPU_IPC_INT); 
	ipc_bsp_trace("ipc ok\n");
	return;    
}
예제 #5
0
static s32  bsp_ipc_probe(struct platform_device *dev)
{
	s32 ret = 0,i = 0; /*lint !e34 */
	u32 array_size=0;
	k3_ipc_block.next = NULL;
	k3_ipc_block.notifier_call = hisi_k3_lpm2ap_ipc_handler;
	ret = RPROC_MONITOR_REGISTER(HISI_RPROC_LPM3, &k3_ipc_block);
	if (ret) {
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc monitor register Failed!\n");
		return ERROR;
	}
	ipc_ctrl.core_num = IPC_CORE_ACORE;
	for(i = 0;i< INTSRC_NUM;i++ )
	{
		ipc_ctrl.sem_exist[i] = false;
	}
	array_size = sizeof(struct ipc_entry)*INTSRC_NUM;
	memset((void*)(ipc_ctrl.ipc_int_table),0x0,array_size);
	ipc_ctrl.ipc_base = HI_IPCM_REGBASE_ADDR_VIRT;/*lint !e569 */
	writel(0x0,(volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_CPU_INT_MASK(ipc_ctrl.core_num)));
	writel(0x0,(volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_SEM_INT_MASK(ipc_ctrl.core_num)));
	spin_lock_init(&ipc_ctrl.lock);
	ret = request_irq(IPC_INT, ipc_int_handler, IRQF_NO_SUSPEND, "ipc_irq",(void*) NULL);
	if (ret )
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc int handler error,init failed\n");
		return ERROR;
	}
	ret = request_irq(IPC_SEM, ipc_sem_int_handler, IRQF_NO_SUSPEND, "ipc_sem",(void*) NULL);
	if (ret )
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc sem handler error,init failed\n");
		return ERROR;
	}
	bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc probe success\n");
	return OK;    /*lint !e438*/
}
void bsp_ipc_init(void)
{
	s32 ret = 0,i = 0;
    struct device_node *ptr_device_node = NULL;
	const char *compatible_name = "hisilicon,ipc_balong_mdm";
	char *ret_of_iomap = NULL;
	u32  irq_no_ipc_int = 0;
	u32  irq_no_ipc_sem = 0;
	
	ipc_ctrl.core_num = IPC_CORE_CCORE;
	for(i = 0;i< INTSRC_NUM;i++ )
	{
		ipc_ctrl.sem_exist[i] = false;
	}
	#ifdef CONFIG_CCORE_PM
	ret = bsp_device_pm_add(&ipc_dpm);
	if(ret)
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc init fail\n");
		return;
	}
	#endif

    /* 读取基地址并映射 */
	ptr_device_node = of_find_compatible_node(NULL, NULL, compatible_name);
	if (!ptr_device_node)  /* 找不到节点 */
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ccore ipc of_find_compatible_node fail\n");
		return;
	}

    ret_of_iomap = of_iomap(ptr_device_node, 0); 
	if (!ret_of_iomap)  /* 映射错误 */
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"of_iomap fail\n");
		return;
	}

#ifdef CONFIG_IPCM_USE_FPGA_VIC
    g_p532_asic_ipcm_virt_addr = (unsigned long)ret_of_iomap;

	/* 读取基地址并映射 */
	ptr_device_node = of_find_compatible_node(NULL, NULL, "hisilicon,ipc_balong_mdm_fpga");
	if (!ptr_device_node)  /* 找不到节点 */
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ccore ipc of_find_compatible_node fail\n");
		return;
	}

	ret_of_iomap = of_iomap(ptr_device_node, 0); 
	if (!ret_of_iomap)	/* 映射错误 */
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"of_iomap fail\n");
		return;
	}

#endif
	
	(void)memset_s((void*)(ipc_ctrl.ipc_int_table), sizeof(struct ipc_entry) * INTSRC_NUM, 
		                                   0x0, sizeof(struct ipc_entry) * INTSRC_NUM);
	ipc_ctrl.ipc_base[IPCM_NS] = (u32)ret_of_iomap; //HI_IPCM_REGBASE_ADDR_VIRT
	writel(0x0,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_CPU_INT_MASK(ipc_ctrl.core_num));
	writel(0x0,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_SEM_INT_MASK(ipc_ctrl.core_num));
	writel(0xffffffff,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_CPU_INT_CLR(ipc_ctrl.core_num));/*清所有32个中断*/
	writel(0xffffffff,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_SEM_INT_CLR(ipc_ctrl.core_num));/*清所有32个中断*/
	ipc_free_sem_taked((u32)IPC_CORE_CCORE);
	ipc_free_sem_taked((u32)IPC_CORE_LDSP);
	spin_lock_init(&ipc_ctrl.lock);
#ifdef CONFIG_IPCM_USE_FPGA_VIC
	/* 获取中断号 */
	irq_no_ipc_int = irq_of_parse_and_map(ptr_device_node, 0);
	ret = bsp_vic_connect(irq_no_ipc_int, (vicfuncptr)ipc_int_handler, 0);
	ret |= bsp_vic_enable(irq_no_ipc_int);
	if (ret )
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc int handler error,init failed\n");
		return;
	}

	/* 获取中断号 */
	irq_no_ipc_sem = irq_of_parse_and_map(ptr_device_node, 1);
	ret = bsp_vic_connect(irq_no_ipc_sem, (vicfuncptr)ipc_sem_int_handler, 0);
	ret |= bsp_vic_enable(irq_no_ipc_sem);
	if (ret )
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc sem handler error,init failed\n");
		return;
	}

#else
    /* 获取中断号 */
	irq_no_ipc_int = irq_of_parse_and_map(ptr_device_node, 0);
	ret = request_irq(irq_no_ipc_int,(irq_handler_t) ipc_int_handler, 0, "ipc_irq",(void*)IPCM_NS);  //IPC_INT
	if (ret )
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc int handler error,init failed\n");
		return;
	}

    /* 获取中断号 */
	irq_no_ipc_sem = irq_of_parse_and_map(ptr_device_node, 1);
	ret = request_irq(irq_no_ipc_sem, (irq_handler_t) ipc_sem_int_handler, 0, "ipc_sem",(void*) NULL);  //IPC_SEM
	if (ret )
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc sem handler error,init failed\n");
		return;
	}
#endif
	
	#ifdef ENABLE_TEST_CODE
	ret = bsp_ipc_test_init();
	if (ret )
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"bsp_ipc_test_init failed\n");
		return;
	}
	#endif
	bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ccore ipc_ns init success\n");
	bsp_ipc_s_init();
	return;
}