/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved. * Description: mailbox driver for liteos */ #ifndef _DRV_MAILBOX_H_ #define _DRV_MAILBOX_H_ #include "los_mbx.h" #ifdef CONFIG_DRIVERS_MBX_DMCU #include #include #include "delay.h" #else #include "los_list.h" #include "los_mux.h" #include "los_delay.h" #endif #ifdef __cplusplus #if __cplusplus extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ #define SUPPORT_MBX_INTERRUPT #define MAILBOX_VERSION_OFFSET 0x0 /* acpu to vmcu0 */ #ifdef CHIP_TYPE_RESERVED23 #define MBX_VMCU0_BASE_ADDR 0x00dfb000 #else #define MBX_VMCU0_BASE_ADDR 0x0129b000 #endif #define MBX_VMCU1_BASE_ADDR 0x012bb000 #define ACPU_TO_VMCU_HEAD_OFFSET (0x0020 / 4) #define ACPU_TO_VMCU_ARGS_OFFSET (0x0040 / 4) #define ACPU_TO_VMCU_ARGS_NUM (16 * 4) #define ACPU_TO_VMCU_SEND_OFFSET (0x0400 / 4) #define ACPU_INTR_FROM_VMCU_OFFSET (0x0418 / 4) /* vmcu0 to acpu */ #define VMCU_TO_ACPU_HEAD_OFFSET (0x0100 / 4) #define VMCU_TO_ACPU_ARGS_OFFSET (0x0420 / 4) #define VMCU_TO_ACPU_ARGS_V2_OFFSET (0x0110 / 4) #define VMCU_TO_ACPU_ARGS_NUM (12 * 4) #define VMCU_TO_ACPU_ARGS_V2_NUM (16 * 4) #define VMCU_TO_ACPU_SEND_OFFSET (0x0410 / 4) #define VMCU_INTR_FROM_ACPU_OFFSET (0x0408 / 4) /* tcpu to vmcu0 */ #define TCPU_TO_VMCU_HEAD_OFFSET (0x0200 / 4) #define TCPU_TO_VMCU_ARGS_OFFSET (0x0240 / 4) #define TCPU_TO_VMCU_ARGS_NUM (16 * 4) #define TCPU_TO_VMCU_SEND_OFFSET (0x0404 / 4) #define TCPU_INTR_FROM_VMCU_OFFSET (0x041C / 4) /* vmcu0 to tcpu */ #define VMCU_TO_TCPU_HEAD_OFFSET (0x0300 / 4) #define VMCU_TO_TCPU_ARGS_OFFSET (0x0310 / 4) #define VMCU_TO_TCPU_ARGS_NUM (4 * 4) #define VMCU_TO_TCPU_SEND_OFFSET (0x0414 / 4) #define VMCU_INTR_FROM_TCPU_OFFSET (0x040C / 4) #define MBX_IRQ_ACPU2VMCU (26 + 13) #define ACPU2VMCU_IRQ_NAME "ACPU2VMCU_IRQ" #define MBX_IRQ_TCPU2VMCU (26 + 12) #define TCPU2VMCU_IRQ_NAME "TCPU2VMCU_IRQ" /* acpu to dmcu0 */ #ifndef CONFIG_MBX_BASE_ADDR_DMCU #define CONFIG_MBX_BASE_ADDR_DMCU 0x117B000 #endif #define MBX_ACPU_DMCU0_BASE_ADDR CONFIG_MBX_BASE_ADDR_DMCU #define ACPU_TO_DMCU_HEAD_OFFSET (0x0020 / 4) #define ACPU_TO_DMCU_ARGS_OFFSET (0x0040 / 4) #define ACPU_TO_DMCU_ARGS_NUM (16 * 4) #define ACPU_TO_DMCU_SEND_OFFSET (0x0400 / 4) #define ACPU_INTR_FROM_DMCU_OFFSET (0x0418 / 4) /* dmcu0 to acpu */ #define DMCU_TO_ACPU_HEAD_OFFSET (0x0100 / 4) #define DMCU_TO_ACPU_ARGS_V2_OFFSET (0x0110 / 4) #define DMCU_TO_ACPU_ARGS_OFFSET (0x0420 / 4) #define DMCU_TO_ACPU_ARGS_V2_NUM (16 * 4) #define DMCU_TO_ACPU_ARGS_NUM (12 * 4) #define DMCU_TO_ACPU_SEND_OFFSET (0x0410 / 4) #define DMCU_INTR_FROM_ACPU_OFFSET (0x0408 / 4) #define MBX_IRQ_ACPU2DMCU (26 + 12) #define DMCU2ACPU_IRQ_NAME "ACPU2DMCU_IRQ" #define SOC_ERRCODE_DEF(moduleid, errid) (td_u32)(0x80000000 | ((moduleid) << 16) | (errid)) #define SOC_MAILBOX_ID 0x6D #define SOC_MBX_SUCCESS 0 #define SOC_MBX_FAILURE (-1) #define MBX_DELAY_TIME 10 #define MBX_RX_BUFF_SIZE 4100 #define MBX_TX_BUFF_SIZE 0 #define SOC_ERR_MAILBOX_NOT_INIT SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x0001) #define SOC_ERR_MAILBOX_INVALID_HANDLE SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x0002) #define SOC_ERR_MAILBOX_INVALID_PTR SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x0003) #define SOC_ERR_MAILBOX_INVALID_PARA SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x0004) #define SOC_ERR_MAILBOX_INVALID_FLAG SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x0005) #define SOC_ERR_MAILBOX_INVALID_RECEIVER SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x0006) #define SOC_ERR_MAILBOX_NO_MEMORY SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x0007) #define SOC_ERR_MAILBOX_NOT_SUPPORT SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x0008) #define SOC_ERR_MAILBOX_ERR_RECEIVE SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x0009) #define SOC_ERR_MAILBOX_UNEXPECTED_RECEIVE_LEN SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x000A) #define SOC_ERR_MAILBOX_CRC_CHECK_ERROR SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x000B) #define SOC_ERR_MAILBOX_UNKNOWN_CMD SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x000C) #define SOC_ERR_MAILBOX_NO_SESSION SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x000D) #define SOC_ERR_MAILBOX_TIMEOUT SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x000E) #define SOC_ERR_MAILBOX_UNKNOWN SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x000F) #define SOC_ERR_MAILBOX_PENDING SOC_ERRCODE_DEF(SOC_MAILBOX_ID, 0x0010) #define SESSION_BUSY (1 << 0) #define SESSION_ID_SIDE0(session_id) (((session_id) >> 4) & 0xF) #define SESSION_ID_SIDE1(session_id) ((session_id) & 0xF) #define SESSION_ID_NUM(session_id) (((session_id) >> 8) & 0xFF) #define SESSION_ID_PORT(session_id) (((session_id) >> 16) & 0x7F) #define SESSION_ID_HANDLE(session_id) (((session_id) >> 8) & 0x7FFF) #define GEN_SESSION_HANDLE(num, port) (((num) & 0xFF) | ((port) & 0x7F) << 8) #define SESSION_HANDLE_NUM(handle) ((handle) & 0xFF) #define SESSION_HANDLE_PORT(handle) (((handle) >> 8) & 0x7F) struct buffer { td_u8 *addr; td_u32 size; td_u32 rd_idx; td_u32 wr_idx; }; struct reg { td_u32 *version; td_u32 *head; td_u32 *argv; td_u32 argv_size; td_u32 *trigger_rx; td_u32 *pending; td_u32 *lock; }; struct session { td_u32 num; td_u32 port; td_u32 rx_status; td_s32 tx_status; struct buffer rx_buf; struct buffer tx_buf; struct reg *rx_reg; struct reg *tx_reg; session_callback func; const td_void *data; LOS_DL_LIST node; }; union msg_head { struct { td_u32 reserved : 9; /* [8:0] */ td_u32 port : 7; /* [15:9] */ td_u32 num : 8; /* [23:16] */ td_u32 msg_len : 7; /* [30:24] */ td_u32 ongoing : 1; /* [31] */ } bits; td_u32 head; }; struct addr_info { td_u32 *base_addr; td_u32 *rx_head_addr; }; struct mailbox { enum cpu_id local_cpu; td_u32 initalized; td_u32 list_lock; LOS_DL_LIST list_head; struct addr_info acpu_vmcu0; struct addr_info tcpu_vmcu0; td_u32 tx_acpu_lock; td_u32 tx_tcpu_lock; struct addr_info acpu_dmcu0; td_u32 tx_dmcu0_lock; td_u32 dmcu0_irq; }; static inline void mutex_lock(td_u32 *lock) { LOS_MuxPend(*lock, LOS_WAIT_FOREVER); return; } static inline void mutex_unlock(td_u32 *lock) { LOS_MuxPost(*lock); return; } static inline void spin_lock_irqsave(td_u32 *lock, td_ulong *flag) { *flag = LOS_IntLock(); LOS_TaskLock(); return; } static inline void spin_unlock_irqrestore(td_u32 *lock, td_ulong *flag) { LOS_TaskUnlock(); LOS_IntRestore(*flag); return; } static inline td_u32 readl(const td_u32 *addr) { if (addr == NULL) { return SOC_ERR_MAILBOX_INVALID_PTR; } __asm__ __volatile__("fence"); return GET_UINT32(addr); } static inline void writel(td_u32 value, const td_u32 *addr) { if (addr == NULL) { return; } WRITE_UINT32(value, addr); __asm__ __volatile__("fence"); } #define MBX_ERR_PRINT printf #define MBX_WARN_PRINT printf #define MBX_INFO_PRINT printf #define MBX_DBG_PRINT printf #define MBX_WRITEL writel #define MBX_READL readl #define MBX_UDELAY LOS_Udelay #define MBX_MSLEEP LOS_Msleep #define MBX_MALLOC(size) LOS_MemAlloc(m_aucSysMem0, size) #define MBX_FREE(addr) LOS_MemFree(m_aucSysMem0, addr) #define MBX_MUTEX_INIT LOS_MuxCreate #define MBX_LIST_ADD(node, head) LOS_ListAdd(head, node) #define MBX_LIST_DEL(node) LOS_ListDelete(node) #define MBX_INIT_LIST_HEAD LOS_ListInit #define MBX_IRQ_RET td_void #define MBX_IRQ_HANDLED #define MBX_LIST_FOR_EACH_ENTRY(pos, n, head, member) \ LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(pos, n, head, struct session, member) void init_mailbox_reg(struct session *session, td_u32 session_id, const struct mailbox *mailbox); void mbx_polling_rx(void); #ifdef __cplusplus #if __cplusplus } #endif /* __cplusplus */ #endif /* __cplusplus */ #endif /* _DRV_MAILBOX_H_ */