diff --git a/drivers/hisi/Kconfig b/drivers/hisi/Kconfig index bd8019eec12f..b75cccc5a038 100644 --- a/drivers/hisi/Kconfig +++ b/drivers/hisi/Kconfig @@ -10,6 +10,7 @@ if HISILICON_PLATFORM source "drivers/hisi/mailbox/Kconfig" source "drivers/hisi/hifi_dsp/Kconfig" +source "drivers/hisi/hifi_mailbox/Kconfig" endif #HISILICON_PLATFORM diff --git a/drivers/hisi/Makefile b/drivers/hisi/Makefile index 79ef87e1b628..c2f75581457a 100644 --- a/drivers/hisi/Makefile +++ b/drivers/hisi/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_HISILICON_PLATFORM_MAILBOX) += mailbox/ obj-$(CONFIG_HIFI_DSP_ONE_TRACK) += hifi_dsp/ +obj-$(CONFIG_HIFI_MAILBOX) += hifi_mailbox/ diff --git a/drivers/hisi/hifi_mailbox/Kconfig b/drivers/hisi/hifi_mailbox/Kconfig new file mode 100644 index 000000000000..f588a8ec9acc --- /dev/null +++ b/drivers/hisi/hifi_mailbox/Kconfig @@ -0,0 +1 @@ +source "drivers/hisi/hifi_mailbox/ipcm/Kconfig" diff --git a/drivers/hisi/hifi_mailbox/Makefile b/drivers/hisi/hifi_mailbox/Makefile new file mode 100644 index 000000000000..8c6b5bb22519 --- /dev/null +++ b/drivers/hisi/hifi_mailbox/Makefile @@ -0,0 +1,2 @@ + +obj-$(CONFIG_HIFI_IPC) += ipcm/ diff --git a/drivers/hisi/hifi_mailbox/ipcm/Kconfig b/drivers/hisi/hifi_mailbox/ipcm/Kconfig new file mode 100644 index 000000000000..18408d3ba598 --- /dev/null +++ b/drivers/hisi/hifi_mailbox/ipcm/Kconfig @@ -0,0 +1,23 @@ +menu "Hifi mailbox driver" + +config HIFI_IPC + bool "k3 multicore ipc driver" + default n + help + k3 multicore ipc driver. +config HIFI_IPC_3650 + bool "hifi 3650 mailbox driver base on ipc" + default n + help + transplant 3650 mailbox driver. +config HIFI_IPC_3660 + bool "hifi 3660 mailbox driver base on ipc" + default n + help + transplant 3660 mailbox driver. +config HIFI_IPC_6250 + bool "hifi 6250 mailbox driver base on ipc" + default n + help + transplant 6250 mailbox driver. +endmenu diff --git a/drivers/hisi/hifi_mailbox/ipcm/Makefile b/drivers/hisi/hifi_mailbox/ipcm/Makefile new file mode 100644 index 000000000000..bda1d5986cdb --- /dev/null +++ b/drivers/hisi/hifi_mailbox/ipcm/Makefile @@ -0,0 +1,5 @@ +EXTRA_CFLAGS += -I$(srctree)/drivers/hisi/hifi_mailbox/mailbox/ + +obj-$(CONFIG_HIFI_IPC) := bsp_ipc.o + + diff --git a/drivers/hisi/hifi_mailbox/ipcm/bsp_drv_ipc.h b/drivers/hisi/hifi_mailbox/ipcm/bsp_drv_ipc.h new file mode 100644 index 000000000000..d7ee30431511 --- /dev/null +++ b/drivers/hisi/hifi_mailbox/ipcm/bsp_drv_ipc.h @@ -0,0 +1,116 @@ + +#ifndef _BSP_DRV_IPC_H_ +#define _BSP_DRV_IPC_H_ + +#include +#include "drv_comm.h" + +#include "../mailbox/mdrv_ipc_enum.h" + +#ifdef __cplusplus +extern "C" { +#endif + + extern void __iomem *ipc_base; + +#define SIZE_4K (4096) +#define BSP_IPC_BASE_ADDR (SOC_IPC_S_BASE_ADDR) +#define IPC_REG_SIZE (SIZE_4K) + +#define BSP_RegRd(uwAddr) (0) +#define BSP_RegWr(uwAddr, uwValue) + +#define SOC_IPC_CPU_INT_EN_ADDR(base, i) ((base) + (0x500+(0x10*(i)))) +#define SOC_IPC_SEM_INT_MASK_ADDR(base, j) ((base) + (0x604+(0x10*(j)))) +#define SOC_IPC_CPU_INT_CLR_ADDR(base, i) ((base) + (0x40C+(0x10*(i)))) +#define IRQ_IPC0_S (252) +#define IRQ_IPC1_S (253) +#define SOC_IPC_CPU_INT_EN_ADDR(base, i) ((base) + (0x500+(0x10*(i)))) +#define SOC_IPC_CPU_INT_DIS_ADDR(base, i) ((base) + (0x504+(0x10*(i)))) +#define SOC_IPC_CPU_INT_STAT_ADDR(base, i) ((base) + (0x408+(0x10*(i)))) +#define SOC_IPC_CPU_RAW_INT_ADDR(base, i) ((base) + (0x400+(0x10*(i)))) +#define SOC_IPC_CPU_INT_MASK_ADDR(base, i) ((base) + (0x404+(0x10*(i)))) +#define SOC_IPC_SEM_INT_CLR_ADDR(base, j) ((base) + (0x60C+(0x10*(j)))) +#define SOC_IPC_HS_CTRL_ADDR(base, j, k) ((base) + (0x800+(0x100*(j))+(0x8*(k)))) +#define SOC_IPC_SEM_INT_STAT_ADDR(base, j) ((base) + (0x608+(0x10*(j)))) +#define SOC_IPC_S_BASE_ADDR (0xe0475000) + +#define SOC_IPC_CPU_INT_MASK_DIS_ADDR(base, i) SOC_IPC_CPU_INT_EN_ADDR(base, i) +#define SOC_IPC_CPU_INT_MASK_EN_ADDR(base, i) SOC_IPC_CPU_INT_DIS_ADDR(base, i) + +#define BSP_IPC_CPU_RAW_INT(i) (SOC_IPC_CPU_RAW_INT_ADDR((BSP_U32)ipc_base, i)) +#define BSP_IPC_CPU_INT_MASK(i) (SOC_IPC_CPU_INT_MASK_ADDR((BSP_U32)ipc_base, i)) +#define BSP_IPC_CPU_INT_STAT(i) (SOC_IPC_CPU_INT_STAT_ADDR((BSP_U32)ipc_base, i)) +#define BSP_IPC_CPU_INT_CLR(i) (SOC_IPC_CPU_INT_CLR_ADDR((BSP_U32)ipc_base, i)) +#define BSP_IPC_INT_MASK_EN(i) (SOC_IPC_CPU_INT_MASK_EN_ADDR((BSP_U32)ipc_base, i)) +#define BSP_IPC_INT_MASK_DIS(i) (SOC_IPC_CPU_INT_MASK_DIS_ADDR((BSP_U32)ipc_base, i)) + +#define BSP_IPC_SEM_RAW_INT(j) (SOC_IPC_SEM_RAW_INT_ADDR((BSP_U32)ipc_base, j)) +#define BSP_IPC_SEM_INT_MASK(j) (SOC_IPC_SEM_INT_MASK_ADDR((BSP_U32)ipc_base, j)) +#define BSP_IPC_SEM_INT_STAT(j) (SOC_IPC_SEM_INT_STAT_ADDR((BSP_U32)ipc_base, j)) +#define BSP_IPC_SEM_INT_CLR(j) (SOC_IPC_SEM_INT_CLR_ADDR((BSP_U32)ipc_base, j)) +#define BSP_IPC_HS_CTRL(j, k) (SOC_IPC_HS_CTRL_ADDR((BSP_U32)ipc_base, j, k)) +#define BSP_IPC_HS_STAT(j, k) (SOC_IPC_HS_STAT_ADDR((BSP_U32)ipc_base, j, k)) + +#define BSP_IPC_CPU_RAW_INT_ACPU (BSP_IPC_CPU_RAW_INT((BSP_U32)IPC_CORE_ACPU)) +#define BSP_IPC_CPU_INT_MASK_ACPU (BSP_IPC_CPU_INT_MASK((BSP_U32)IPC_CORE_ACPU)) +#define BSP_IPC_CPU_INT_STAT_ACPU (BSP_IPC_CPU_INT_STAT((BSP_U32)IPC_CORE_ACPU)) +#define BSP_IPC_CPU_INT_CLR_ACPU (BSP_IPC_CPU_INT_CLR((BSP_U32)IPC_CORE_ACPU)) +#define BSP_IPC_CPU_INT_MASK_EN_ACPU (BSP_IPC_INT_MASK_EN((BSP_U32)IPC_CORE_ACPU)) +#define BSP_IPC_CPU_INT_MASK_DIS_ACPU (BSP_IPC_INT_MASK_DIS((BSP_U32)IPC_CORE_ACPU)) + +#define UCOM_COMM_UINT32_MAX (0xffffffff) +#define BSP_IPC_MAX_INT_NUM (32) +#define IPC_MASK 0xFFFFFF0F + +#define INT_LEV_IPC_CPU (IRQ_IPC0_S) +#define INT_LEV_IPC_SEM (IRQ_IPC1_S) + +#define INT_VEC_IPC_SEM IVEC_TO_INUM(INT_LEV_IPC_SEM) +#define INTSRC_NUM 32 + +#define INT_VEC_IPC_CPU IVEC_TO_INUM(INT_LEV_IPC_CPU) +#define IPC_CHECK_PARA(ulLvl) \ + do {\ + if (ulLvl >= INTSRC_NUM) {\ + pr_warn("Wrong para , line:%d\n", __LINE__);\ + return BSP_ERROR;\ + } \ + } while (0) + + typedef struct tagIPC_DEV_S { + BSP_BOOL bInit; + } IPC_DEV_S; + + typedef struct { + VOIDFUNCPTR routine; + BSP_U32 arg; + } BSP_IPC_ENTRY; + + typedef struct tagIPC_DEBUG_E { + BSP_U32 u32RecvIntCore; + BSP_U32 u32IntHandleTimes[INTSRC_NUM]; + BSP_U32 u32IntSendTimes[INTSRC_NUM]; + BSP_U32 u32SemId; + BSP_U32 u32SemTakeTimes[INTSRC_NUM]; + BSP_U32 u32SemGiveTimes[INTSRC_NUM]; + } IPC_DEBUG_E; + + BSP_S32 DRV_IPCIntInit(void); + + BSP_S32 IPC_IntEnable(IPC_INT_LEV_E ulLvl); + + BSP_S32 IPC_IntConnect(IPC_INT_LEV_E ulLvl, VOIDFUNCPTR routine, + BSP_U32 parameter); + + BSP_S32 IPC_IntSend(IPC_INT_CORE_E enDstCore, IPC_INT_LEV_E ulLvl); + + BSP_VOID IPC_SpinLock(BSP_U32 u32SignalNum); + + BSP_VOID IPC_SpinUnLock(BSP_U32 u32SignalNum); + BSP_VOID IPC_SemGive_Ccore_All(BSP_VOID); + +#ifdef __cplusplus +} +#endif +#endif /* end #define _BSP_IPC_H_ */ diff --git a/drivers/hisi/hifi_mailbox/ipcm/bsp_ipc.c b/drivers/hisi/hifi_mailbox/ipcm/bsp_ipc.c new file mode 100644 index 000000000000..be07c72b2a79 --- /dev/null +++ b/drivers/hisi/hifi_mailbox/ipcm/bsp_ipc.c @@ -0,0 +1,436 @@ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "bsp_drv_ipc.h" + +/*#define USE_HIFI_IPC*/ +BSP_IPC_ENTRY stIpcIntTable[INTSRC_NUM]; +static IPC_DEV_S g_stIpcDev = { 0 }; + +BSP_U32 g_CoreNum; + +struct semaphore g_semIpcTask[INTSRC_NUM]; +IPC_DEBUG_E g_stIpc_debug = { 0 }; + +/* base address of ipc registers */ +void __iomem *ipc_base; +spinlock_t g_ipc_int_lock = __SPIN_LOCK_UNLOCKED("ipc"); + +#define USE_HISI_MAILBOX + +/*************************************k3 ipc******************************************/ +#define BIT_ENABLE(n) (1 << (n)) +#define BYTE_REF(address) (*((unsigned char volatile *) (address))) +#define HALFWORD_REF(address) (*((unsigned short volatile *) (address))) +#define WORD_REF(address) (*((unsigned int volatile *) (address))) +#define WORD_PTR(address) (*((unsigned int volatile **) (address))) +#define BYTE(address) volatile unsigned char __attribute__((section(".ARM.__at_"address))) +#define HALFWORD(address) volatile unsigned short __attribute__((section(".ARM.__at_"address))) +#define WORD(address) volatile unsigned int __attribute__((section(".ARM.__at_"address))) + +#define K3_IPC_MODE_ACK (7) +#define K3_IPC_MODE_IDLE (4) +#define K3_IPC_MODE_AUTOACK (0) + +/*************************************hifiϵͳipc******************************************/ +#define K3_SYS_IPC_BASE_ADDR_S (unsigned long)(0xe896a000) +#define K3_SYS_IPC_BASE_ADDR_NS (unsigned long)(0xe896b000) +#define K3_SYS_IPC_REG_SIZE (0xA00) + +#define K3_IPC_LOCK(base) WORD_REF(base + 0xA00) +#define K3_IPC_SOURCE(base, box) WORD_REF(base + ((box) * 64)) +#define K3_IPC_DEST(base, box) WORD_REF(base + ((box) * 64) + 0x04) +#define K3_IPC_DCLR(base, box) WORD_REF(base + ((box) * 64) + 0x08) +#define K3_IPC_DSTATUS(base, box) WORD_REF(base + ((box) * 64) + 0x0c) +#define K3_IPC_MODE(base, box) WORD_REF(base + ((box) * 64) + 0x10) +#define K3_IPC_IMASK(base, box) WORD_REF(base + ((box) * 64) + 0x14) +#define K3_IPC_ICLR(base, box) WORD_REF(base + ((box) * 64) + 0x18) +#define K3_IPC_SEND(base, box) WORD_REF(base + ((box) * 64) + 0x1c) +#define K3_IPC_DATA(base, box, num) WORD_REF(base + ((box) * 64) + 0x20 + ((num) * 4)) +#define K3_IPC_CPUIMST(base, core) WORD_REF(base + 0x800 + ((core) * 8)) +#define K3_IPC_CPUIRST(base, core) WORD_REF(base + 0x804 + ((core) * 8)) + +#define K3_SYS_IPC_CORE_LIT (0) +#define K3_SYS_IPC_CORE_BIG (1) +#define K3_SYS_IPC_CORE_IOM3 (2) +#define K3_SYS_IPC_CORE_LPM3 (3) +#define K3_SYS_IPC_CORE_HIFI (4) + +#define K3_HIFI_IPC_BASE_ADDR (unsigned long)(0xE804C000) +#define K3_HIFI_IPC_REG_SIZE (0x1000) + +#define K3_ASP_CFG_CTRLDIS(base) WORD_REF(base + 0x04) +#define K3_ASP_CFG_GATE_EN(base) WORD_REF(base + 0x0c) + +enum { + K3_HIFI_IPC_CORE_AP_LPM3_IOM3 = 0, + K3_HIFI_IPC_CORE_MODEM_A9 = 1, + K3_HIFI_IPC_CORE_MODEM_BBE = 2, + K3_HIFI_IPC_CORE_HIFI = 3, + K3_HIFI_IPC_CORE_IOM3 = 5, + K3_HIFI_IPC_CORE_AP = 6, + K3_HIFI_IPC_CORE_LPM3 = 8, +}; + +typedef enum { + K3_SEC_SYS_IPC = 0, + K3_UNSEC_SYS_IPC, + K3_HIFI_IPC, +} K3_IPC; + +typedef struct { + K3_IPC ipcMode; + void __iomem *ipcBase; + int mailBoxNum; + int intNum; + int sourceCore; + int destCore; +} K3_IPC_CONFIG; + +enum { + K3_IPC_CORE_IS_SEND = 0, + K3_IPC_CORE_IS_RECEIVE, + K3_IPC_CORE_IS_UNKNOEN, +}; + +static K3_IPC_CONFIG k3IpcConfig[K3_IPC_CORE_IS_UNKNOEN] = { + { + K3_UNSEC_SYS_IPC, + NULL, + 18, + 220, + K3_SYS_IPC_CORE_LIT, + K3_SYS_IPC_CORE_HIFI}, + + { + K3_UNSEC_SYS_IPC, + NULL, + 2, + 227, + K3_SYS_IPC_CORE_HIFI, + K3_SYS_IPC_CORE_BIG} +}; + +static int DRV_k3IpcIntHandler_ipc(struct notifier_block *nb, unsigned long len, + void *msg); +struct hisi_mbox *hifi_tx_mbox; +struct notifier_block rx_nb; + +#ifdef USE_HISI_MAILBOX +#define MAX_SEND_IPC_TRY 3 + +static int hisi_hifi_mbox_init(void) +{ + int ret = 0, rproc_id = 0; + + rx_nb.next = NULL; + rx_nb.notifier_call = DRV_k3IpcIntHandler_ipc; + rproc_id = HISI_RPROC_HIFI_MBX2; + /* register the rx notify callback */ + ret = RPROC_MONITOR_REGISTER(rproc_id, &rx_nb); + if (ret) + pr_info("%s:RPROC_MONITOR_REGISTER failed", __func__); + + return ret; +} + +/* +static void hisi_hifi_mbox_exit(void) +{ + if (hifi_mbox) + hisi_mbox_put(&hifi_mbox); +} +*/ +#else +static irqreturn_t DRV_k3IpcIntHandler_ack(int irq, void *dev_id) +{ + BSP_S32 retval = IRQ_HANDLED; + BSP_U32 u32IntStat = 0; + + int myRole = K3_IPC_CORE_IS_SEND; + BSP_U32 mailBoxNum = k3IpcConfig[myRole].mailBoxNum; + BSP_U32 source = k3IpcConfig[myRole].sourceCore; + void __iomem *ipcBase = k3IpcConfig[myRole].ipcBase; + + u32IntStat = K3_IPC_CPUIMST(ipcBase, source); + + if (u32IntStat & BIT_ENABLE(mailBoxNum)) { + if (K3_IPC_MODE(ipcBase, mailBoxNum) & + BIT_ENABLE(K3_IPC_MODE_ACK)) { + pr_info("func:%s: Receive ack int\n", __func__); + + K3_IPC_SOURCE(ipcBase, mailBoxNum) = BIT_ENABLE(source); + } + K3_IPC_DCLR(ipcBase, mailBoxNum) = BIT_ENABLE(mailBoxNum); + } + + return (irqreturn_t) IRQ_RETVAL(retval); +} + +#endif + +BSP_S32 DRV_IPCIntInit(void) +{ + + int myRole = 0; + + printk(KERN_ERR "DRV_IPCIntInit begin.\n"); + + if (BSP_TRUE == g_stIpcDev.bInit) { + return BSP_OK; + } + + printk(KERN_ERR "DRV_IPCIntInit line = %d\n", __LINE__); + + g_CoreNum = IPC_CORE_ACPU; + + memset((void *)stIpcIntTable, 0x0, + (INTSRC_NUM * sizeof(BSP_IPC_ENTRY))); + + myRole = K3_IPC_CORE_IS_SEND; + if (K3_UNSEC_SYS_IPC == k3IpcConfig[myRole].ipcMode) { + k3IpcConfig[myRole].ipcBase = + ioremap(K3_SYS_IPC_BASE_ADDR_NS, K3_SYS_IPC_REG_SIZE); + if (!k3IpcConfig[myRole].ipcBase) { + printk(KERN_ERR + "line %d :k3 unsec sys ipc ioremap error.\n", + __LINE__); + return -1; + } + } else if (K3_SEC_SYS_IPC == k3IpcConfig[myRole].ipcMode) { + k3IpcConfig[myRole].ipcBase = + ioremap(K3_SYS_IPC_BASE_ADDR_S, K3_SYS_IPC_REG_SIZE); + if (!k3IpcConfig[myRole].ipcBase) { + printk(KERN_ERR + "line %d :k3 sec sys ipc ioremap error.\n", + __LINE__); + return -1; + } + } else { + k3IpcConfig[myRole].ipcBase = + ioremap(K3_HIFI_IPC_BASE_ADDR, K3_HIFI_IPC_REG_SIZE); + if (!k3IpcConfig[myRole].ipcBase) { + printk(KERN_ERR "line %d :k3 hifi ipc ioremap error.\n", + __LINE__); + return -1; + } + } + + K3_IPC_LOCK(k3IpcConfig[myRole].ipcBase) = 0x1ACCE551; + myRole = K3_IPC_CORE_IS_RECEIVE; + if (K3_UNSEC_SYS_IPC == k3IpcConfig[myRole].ipcMode) { + k3IpcConfig[myRole].ipcBase = + ioremap(K3_SYS_IPC_BASE_ADDR_NS, K3_SYS_IPC_REG_SIZE); + if (!k3IpcConfig[myRole].ipcBase) { + printk(KERN_ERR + "line %d :k3 unsec sys ipc ioremap error.\n", + __LINE__); + return -1; + } + } else if (K3_SEC_SYS_IPC == k3IpcConfig[myRole].ipcMode) { + k3IpcConfig[myRole].ipcBase = + ioremap(K3_SYS_IPC_BASE_ADDR_S, K3_SYS_IPC_REG_SIZE); + if (!k3IpcConfig[myRole].ipcBase) { + printk(KERN_ERR + "line %d :k3 sec sys ipc ioremap error.\n", + __LINE__); + return -1; + } + } else { + k3IpcConfig[myRole].ipcBase = + ioremap(K3_HIFI_IPC_BASE_ADDR, K3_HIFI_IPC_REG_SIZE); + if (!k3IpcConfig[myRole].ipcBase) { + printk(KERN_ERR "line %d :k3 hifi ipc ioremap error.\n", + __LINE__); + return -1; + } + } + K3_IPC_LOCK(k3IpcConfig[myRole].ipcBase) = 0x1ACCE551; +#ifdef USE_HISI_MAILBOX + hisi_hifi_mbox_init(); +#else + ret = request_irq(k3IpcConfig[K3_IPC_CORE_IS_SEND].intNum, + DRV_k3IpcIntHandler_ack, 0, "k3IpcIntHandler_ack", + NULL); + if (ret) { + printk(KERN_ERR + "BSP_DRV_IPCIntInit: Unable to register ipc irq ret=%d.\n", + ret); + return BSP_ERROR; + } + printk(KERN_ERR "BSP_DRV_IPCIntInit line = %d\n", __LINE__); +#endif + + g_stIpcDev.bInit = BSP_TRUE; + + printk(KERN_ERR "BSP_DRV_IPCIntInit end.\n"); + + return BSP_OK; +} + +BSP_S32 IPC_IntEnable(IPC_INT_LEV_E ulLvl) +{ + IPC_CHECK_PARA(ulLvl); + + return BSP_OK; +} + +BSP_S32 IPC_IntDisable(IPC_INT_LEV_E ulLvl) +{ + IPC_CHECK_PARA(ulLvl); + + return BSP_OK; +} + +BSP_S32 IPC_IntConnect(IPC_INT_LEV_E ulLvl, VOIDFUNCPTR routine, + BSP_U32 parameter) +{ + + unsigned long flag = 0; + + IPC_CHECK_PARA(ulLvl); + + spin_lock_irqsave(&g_ipc_int_lock, flag); + stIpcIntTable[ulLvl].routine = routine; + stIpcIntTable[ulLvl].arg = parameter; + spin_unlock_irqrestore(&g_ipc_int_lock, flag); + + return BSP_OK; +} + +BSP_S32 IPC_IntDisonnect(IPC_INT_LEV_E ulLvl, VOIDFUNCPTR routine, + BSP_U32 parameter) +{ + unsigned long flag = 0; + + IPC_CHECK_PARA(ulLvl); + + spin_lock_irqsave(&g_ipc_int_lock, flag); + stIpcIntTable[ulLvl].routine = NULL; + stIpcIntTable[ulLvl].arg = 0; + spin_unlock_irqrestore(&g_ipc_int_lock, flag); + + return BSP_OK; +} + +static int DRV_k3IpcIntHandler_ipc(struct notifier_block *nb, unsigned long len, + void *msg) +{ + BSP_U32 newLevel = 0; + mbox_msg_t *_msg = (mbox_msg_t *) msg; + + newLevel = _msg[0]; + + if (newLevel < INTSRC_NUM) { + g_stIpc_debug.u32IntHandleTimes[newLevel]++; + + if (NULL != stIpcIntTable[newLevel].routine) { + stIpcIntTable[newLevel].routine(stIpcIntTable[newLevel]. + arg); + } + } + + return 0; +} + +BSP_S32 IPC_IntSend(IPC_INT_CORE_E enDstCore, IPC_INT_LEV_E ulLvl) +{ + int myRole = K3_IPC_CORE_IS_SEND; + BSP_U32 source = k3IpcConfig[myRole].sourceCore; + +#ifdef USE_HISI_MAILBOX + BSP_U32 ipcMsg[2]; + int ret = 0, rproc_id = 0; +#else + BSP_U32 mailBoxNum = k3IpcConfig[myRole].mailBoxNum; + BSP_U32 dest = k3IpcConfig[myRole].destCore; + void __iomem *ipcBase = k3IpcConfig[myRole].ipcBase; +#endif + + IPC_CHECK_PARA(ulLvl); + + if (IPC_CORE_HiFi == enDstCore) { +#ifdef USE_HISI_MAILBOX + ipcMsg[0] = (source << 24) | (ulLvl << 8); + + rproc_id = HISI_RPROC_HIFI_MBX18; + ret = RPROC_ASYNC_SEND(rproc_id, (mbox_msg_t *) ipcMsg, 2); + if (ret) { + printk(" %s , line %d, send error\n", __func__, + __LINE__); + } +#else + while (0 == + (K3_IPC_MODE(ipcBase, mailBoxNum) & + BIT_ENABLE(K3_IPC_MODE_IDLE))) { + printk("func:%s: mailbox is busy mode = 0x%x\n", + __func__, K3_IPC_MODE(ipcBase, mailBoxNum)); + } + + K3_IPC_SOURCE(ipcBase, mailBoxNum) = BIT_ENABLE(source); + K3_IPC_DEST(ipcBase, mailBoxNum) = BIT_ENABLE(dest); + + K3_IPC_IMASK(ipcBase, mailBoxNum) = + ~(BIT_ENABLE(source) | BIT_ENABLE(dest)); + + K3_IPC_MODE(ipcBase, mailBoxNum) = + BIT_ENABLE(K3_IPC_MODE_AUTOACK); + + K3_IPC_DATA(ipcBase, mailBoxNum, 0) = source; + K3_IPC_DATA(ipcBase, mailBoxNum, 1) = ulLvl; + + K3_IPC_SEND(ipcBase, mailBoxNum) = BIT_ENABLE(source); + +#endif + } else { + BSP_RegWr(BSP_IPC_CPU_RAW_INT(enDstCore), 1 << ulLvl); + } + + g_stIpc_debug.u32RecvIntCore = enDstCore; + g_stIpc_debug.u32IntSendTimes[ulLvl]++; + + return BSP_OK; +} + +void BSP_IPC_SpinLock(unsigned int u32SignalNum) +{ + unsigned int u32HsCtrl; + + if (u32SignalNum >= INTSRC_NUM) { + printk("BSP_IPC_SpinLock Parameter error, line:%d\n", + __LINE__); + return; + } + for (;;) { + u32HsCtrl = BSP_RegRd(BSP_IPC_HS_CTRL(g_CoreNum, u32SignalNum)); + if (0 == u32HsCtrl) { + break; + } + } +} + +void BSP_IPC_SpinUnLock(unsigned int u32SignalNum) +{ + if (u32SignalNum >= INTSRC_NUM) { + printk("BSP_IPC_SpinUnLock Parameter error, line:%d\n", + __LINE__); + return; + } + BSP_RegWr(BSP_IPC_HS_CTRL(g_CoreNum, u32SignalNum), 0); +} + +EXPORT_SYMBOL(IPC_IntEnable); +EXPORT_SYMBOL(IPC_IntDisable); +EXPORT_SYMBOL(IPC_IntConnect); +EXPORT_SYMBOL(IPC_IntSend); diff --git a/drivers/hisi/hifi_mailbox/ipcm/drv_comm.h b/drivers/hisi/hifi_mailbox/ipcm/drv_comm.h new file mode 100644 index 000000000000..5a7f0a884773 --- /dev/null +++ b/drivers/hisi/hifi_mailbox/ipcm/drv_comm.h @@ -0,0 +1,188 @@ + +#ifndef __DRV_COMM_H__ +#define __DRV_COMM_H__ + +/*************************GLOBAL BEGIN*****************************/ +#ifndef _WIN32_COMPILE +typedef signed long long BSP_S64; +#else +typedef double BSP_S64; +#endif +typedef signed int BSP_S32; +typedef signed short BSP_S16; +typedef signed char BSP_S8; +typedef char BSP_CHAR; +typedef char BSP_CHAR_TL; + +#ifndef _WIN32_COMPILE +typedef unsigned long long BSP_U64; +#else +typedef double BSP_U64; +#endif +typedef unsigned int BSP_U32; +typedef unsigned short BSP_U16; +typedef unsigned char BSP_U8; + +typedef int BSP_BOOL; +typedef void BSP_VOID; +typedef int BSP_STATUS; + +#ifndef _WIN32_COMPILE +typedef signed long long *BSP_PS64; +#else +typedef double *BSP_PS64; +#endif +typedef signed int *BSP_PS32; +typedef signed short *BSP_PS16; +typedef signed char *BSP_PS8; + +#ifndef _WIN32_COMPILE +typedef unsigned long long *BSP_PU64; +#else +typedef double *BSP_PU64; +#endif +typedef unsigned int *BSP_PU32; +typedef unsigned short *BSP_PU16; +typedef unsigned char *BSP_PU8; + +#ifndef UINT8 +typedef unsigned char UINT8; +#endif +#ifndef UINT32 +typedef unsigned int UINT32; +#endif +typedef int *BSP_PBOOL; +typedef void *BSP_PVOID; +typedef int *BSP_PSTATUS; + +typedef void VOID; +typedef BSP_S32 STATUS; +typedef BSP_S32 UDI_HANDLE; + +#ifndef BSP_CONST +#define BSP_CONST const +#endif + +#ifndef OK +#define OK (0) +#endif + +#ifndef ERROR +#define ERROR (-1) +#endif + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef BSP_OK +#define BSP_OK (0) +#endif + +#ifndef BSP_ERROR +#define BSP_ERROR (-1) +#endif + +#ifndef BSP_TRUE +#define BSP_TRUE (1) +#endif + +#ifndef BSP_FALSE +#define BSP_FALSE (0) +#endif + +#ifndef BSP_NULL +#define BSP_NULL (void *)0 +#endif + +typedef BSP_S32(*FUNCPTR_1) (int); +typedef int (*PWRCTRLFUNCPTRVOID) (void); +typedef unsigned int (*PWRCTRLFUNCPTR) (unsigned int arg); /* ptr to function returning int */ + +#ifndef INLINE +#ifdef __KERNEL__ +#define INLINE inline +#else +#define INLINE __inline__ +#endif +#endif + +#if defined(BSP_CORE_MODEM) || defined(PRODUCT_CFG_CORE_TYPE_MODEM) +#ifndef _VOIDFUNCPTR_DEFINED +typedef BSP_VOID(*VOIDFUNCPTR) (); +#endif +#else +typedef BSP_VOID(*VOIDFUNCPTR) (BSP_U32); +#define SEM_FULL (1) +#define SEM_EMPTY (0) +#define LOCAL static +#define IVEC_TO_INUM(intVec) ((int)(intVec)) +#endif + +#define BSP_ERR_MODULE_OFFSET (0x1000) +#define BSP_DEF_ERR(mod, errid) \ + ((((BSP_U32) mod + BSP_ERR_MODULE_OFFSET) << 16) | (errid)) + +#define BSP_REG(base, reg) (*(volatile BSP_U32 *)((BSP_U32)base + (reg))) + +#if defined(BSP_CORE_MODEM) || defined(PRODUCT_CFG_CORE_TYPE_MODEM) || defined(__VXWORKS__) +#define BSP_REG_READ(base, reg, result) \ + ((result) = BSP_REG(base, reg)) + +#define BSP_REG_WRITE(base, reg, data) \ + (BSP_REG(base, reg) = (data)) + +#else +#define BSP_REG_READ(base, reg, resule) \ + (resule = readl(base + reg)) + +#define BSP_REG_WRITE(base, reg, data) \ + (writel(data, (base + reg))) +#endif + +#define BSP_REG_SETBITS(base, reg, pos, bits, val) (BSP_REG(base, reg) = (BSP_REG(base, reg) & (~((((u32)1 << (bits)) - 1) << (pos)))) \ + | ((u32)((val) & (((u32)1 << (bits)) - 1)) << (pos))) +#define BSP_REG_GETBITS(base, reg, pos, bits) ((BSP_REG(base, reg) >> (pos)) & (((u32)1 << (bits)) - 1)) + +#define DRV_OK (0) +#define DRV_ERROR (-1) +#define DRV_INTERFACE_RSLT_OK (0) + +typedef int (*pFUNCPTR) (void); + +typedef unsigned long (*pFUNCPTR2) (unsigned long ulPara1, + unsigned long ulPara2); + +typedef unsigned int tagUDI_DEVICE_ID_UINT32; + +typedef struct { + BSP_U32 ulblockCount; + BSP_U32 ulpageSize; + BSP_U32 ulpgCntPerBlk; +} DLOAD_FLASH_STRU; +typedef BSP_VOID(*UpLinkRxFunc) (BSP_U8 *buf, BSP_U32 len); + +typedef BSP_VOID(*FreePktEncap) (BSP_VOID *PktEncap); + +typedef enum tagGMAC_OWNER_E { + GMAC_OWNER_VXWORKS = 0, + GMAC_OWNER_PS, + GMAC_OWNER_MSP, + GMAC_OWNER_MAX +} GMAC_OWNER_E; + +typedef enum tagWDT_TIMEOUT_E { + WDT_TIMEOUT_1 = 0, /*0xFFFF000/WDT_CLK_FREQ, about 3657ms *//*WDT_CLK_FREQ = ARM_FREQ/6 = 70M */ + WDT_TIMEOUT_2, /*0x1FFFE000/WDT_CLK_FREQ, about 7314ms */ + WDT_TIMEOUT_3, /*0x3FFFC000/WDT_CLK_FREQ, about 14628ms */ + WDT_TIMEOUT_4, /*0x7FFF8000/WDT_CLK_FREQ, about 29257ms */ + WDT_TIMEOUT_BUTT +} WDT_TIMEOUT_E; + +/*************************GLOBAL END****************************/ + +#endif