/** * @file sdrv_mbox.h * @brief SemiDrive Mailbox driver header file. * * @copyright copyright description (c) 2022 Semidrive Semiconductor. * All rights reserved. * * Revision History: * ----------------- */ #ifndef SDRV_MBOX_H #define SDRV_MBOX_H #include #include #include #include /* config of sdrv mbox */ #define SDRV_MBOX_CHN_NUM 8U #define SDRV_MBOX_ANY_ADDR -1 #define SDRV_MBOX_SHORT_BUF_LEN 4U #define SDRV_MBOX_NO_WAIT 0U #define SDRV_MBOX_WAIT_FOREVER 0xffffffffU #ifndef ASSEMBLY __BEGIN_CDECLS /** * @brief mbox status error code. */ enum sdrv_mbox_error { /* Invalid mailbox master id. */ SDRV_MBOX_STATUS_INVALID_MASTERID = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_MBOX, 0), /* Invalid mailbox message Length. */ SDRV_MBOX_STATUS_LENGTH_ERROR = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_MBOX, 1), /* No mailbox channel. */ SDRV_MBOX_STATUS_NO_CHANNEL = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_MBOX, 2), /* No mailbox message buffer. */ SDRV_MBOX_STATUS_NO_MSG_BUFFER = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_MBOX, 3), /* mailbox timeout error. */ SDRV_MBOX_STATUS_TIMEOUT = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_MBOX, 4), }; /* sdrv mbox processor index */ typedef enum { MBOX_PROC_ID_SF = 0U, /* SF */ MBOX_PROC_ID_SP0 = 1U, /* SP0 */ MBOX_PROC_ID_SP1 = 2U, /* SP1 */ MBOX_PROC_ID_SX0 = 3U, /* SX0 */ MBOX_PROC_ID_SX1 = 4U, /* SX1 */ MBOX_PROC_ID_NUM = 5U, /* mbox processor index number */ } sdrv_mbox_proc_id_t; /** * @brief sdrv mbox remote processor bitmap * * Multi remote processors can be combined by the symbol '|', * for example, MBOX_RPROC_SF | MBOX_RPROC_SP0. * */ typedef enum { MBOX_RPROC_SF = (1U << MBOX_PROC_ID_SF), MBOX_RPROC_SP0 = (1U << MBOX_PROC_ID_SP0), MBOX_RPROC_SP1 = (1U << MBOX_PROC_ID_SP1), MBOX_RPROC_SX0 = (1U << MBOX_PROC_ID_SX0), MBOX_RPROC_SX1 = (1U << MBOX_PROC_ID_SX1), } sdrv_mbox_rproc_t; /** * @brief sdrv mbox address id * * Mbox address id is used to define different mbox message types, * especially for the frequent used messages, such as rpmsg or power-manage. * Raw data (MBOX_ADDR_RAW) is usually chosen for the messages without any type. * */ typedef enum { MBOX_ADDR_INVALID = 0x0U, /* Invalid message */ MBOX_ADDR_RAW = 0x1U, /* Raw data */ MBOX_ADDR_IPCC = 0x2U, /* IPCC data */ MBOX_ADDR_RPMSG = 0x4U, /* RPMSG data */ MBOX_ADDR_PM = 0x8U, /* Power-manage data */ } sdrv_mbox_addr_t; /* mbox callback */ typedef int (*sdrv_mbox_rxcallback)(void *arg, uint8_t *data, uint32_t len); /* sdrv chan req priv data */ typedef struct sdrv_mbox_chan_req { uint32_t rproc; int16_t src_addr; /* -1: any addr */ int16_t dest_addr; /* -1: any addr */ } sdrv_mbox_chan_req_t; /* sdrv mbox device */ struct sdrv_mbox_dev; /* sdrv mbox configurations */ typedef struct sdrv_mbox_config { paddr_t base; /* mbox register base address */ paddr_t mem_base; /* mbox memory buffer base address */ int irq; /* mbox irq number */ uint8_t set_masterid_num; /* reserved */ } sdrv_mbox_config_t; /* sdrv mbox chan priv */ typedef struct sdrv_mbox_chan { struct sdrv_mbox_dev *dev; /* mbox device */ uint8_t used; /* mbox channel used flag */ uint8_t msg_id; /* mbox channel id */ uint8_t mb_mask; /* mbox message buffer mask */ uint32_t rproc; /* mbox remote processor */ int16_t src_addr; /* mbox message source address */ int16_t dest_addr; /* mbox message dest address */ sdrv_mbox_rxcallback callback; /* mbox channel callback function */ void *arg; /* mbox channel argument */ } sdrv_mbox_chan_t; /* sdrv mbox device */ typedef struct sdrv_mbox_dev { paddr_t base; /* mbox register base address */ paddr_t mem_base; /* mbox memory buffer base address */ int irq; /* mbox irq number */ uint8_t set_masterid_num; /* reserved */ uint8_t chan_num; /* mbox max channel number */ sdrv_mbox_chan_t chan[SDRV_MBOX_CHN_NUM]; /* mbox channel */ uint32_t msg_bitmap; /* mbox channel used flag */ uint32_t mb_bitmap; /* mbox message buffer used flag */ uint32_t mtu; /* mbox maximum transmission unit */ } sdrv_mbox_t; /** * @brief sdrv mbox receive message * * This function receives mailbox message data. * It should be called before other core send mailbox data. * * @param[in] chan sdrv mbox channel * @param[in] data msg data * @param[in] msg len * @return receive result */ int sdrv_mbox_received(sdrv_mbox_chan_t *chan, uint8_t *data, uint32_t len); /** * @brief sdrv mbox channel send short data * * This function is used to send mailbox data without buffers. * The data length is not more than 4 bytes. * The mailbox data will be saved in registers and send directly. * * @param[in] chan mbox channel * @param[in] data data ptr * @param[in] len data length, unit: 2 bytes * @param[in] timeout wait timeout(millisecond), timeout should not be too small. * return send result */ status_t sdrv_mbox_send_nobuf(sdrv_mbox_chan_t *sdrv_chan, uint8_t *data, uint32_t len, uint32_t timeout); /** * @brief sdrv mbox channel send data use message buf * * This function is used to send mailbox data in standard flow: * 1. allocate data buffers * 2. copy data to the buffers * 3. send data from the buffers * * @param[in] chan mbox channel * @param[in] data data ptr * @param[in] len data length, unit: 2 bytes * @param[in] timeout wait timeout(millisecond), timeout should not be too small. * return send result */ status_t sdrv_mbox_send(sdrv_mbox_chan_t *sdrv_chan, uint8_t *data, uint32_t len, uint32_t timeout); /** * @brief sdrv mbox channel allocate buffer * * This function allocates data buffers, and copy mailbox data to the buffers first. * And then, another function (sdrv_mbox_send_nocopy) is called to send mailbox data. * * @param[in] chan mbox channel * @param[in] len data length, unit: 2 bytes * return buffer address */ uint8_t *sdrv_mbox_alloc_buffer(sdrv_mbox_chan_t *sdrv_chan, uint32_t len); /** * @brief sdrv mbox channel send data no copy * * This function is used to send mailbox data without repeating to copy data. * This function is combined with the function sdrv_mbox_alloc_buffer, * sending the data which have been stored in the buffer. * * @param[in] chan mbox channel * @param[in] data data ptr * @param[in] len data length, unit: 2 bytes * @param[in] timeout wait timeout(millisecond), timeout should not be too small. * @return send result */ status_t sdrv_mbox_send_nocopy(sdrv_mbox_chan_t *chan, uint8_t *data, uint32_t len, uint32_t timeout); /** * @brief sdrv mbox client request channel * * @param[in] dev mbox dev * @param[in] chan_req mbox channel request param * @return mbox channel */ sdrv_mbox_chan_t *sdrv_mbox_request_channel(sdrv_mbox_t *dev, sdrv_mbox_chan_req_t *chan_req); /** * @brief sdrv mbox release channel * * @param[in] chan sdrv mbox chan * @return SDRV_STATUS_OK or error code */ status_t sdrv_mbox_release_channel(sdrv_mbox_chan_t *chan); /** * @brief sdrv mbox set callback * * This function sets mailbox callback function. * * @param[in] chan sdrv mbox channel * @param[in] callback callback function * @param[in] arg callback argument * @return SDRV_STATUS_OK or error code */ status_t sdrv_mbox_set_callback(sdrv_mbox_chan_t *chan, sdrv_mbox_rxcallback callback, void *arg); /** * @brief sdrv mbox get mtu * * This function gets maximum transmission unit. * * @param[in] dev sdrv mbox dev * @return mtu */ uint32_t sdrv_mbox_mtu(sdrv_mbox_t *dev); /** * @brief sdrv mbox init * * This function initializes mailbox device. * * @param[in] dev sdrv mbox device * @param[in] cfg sdrv mbox configuration */ status_t sdrv_mbox_init(sdrv_mbox_t *dev, const sdrv_mbox_config_t *cfg); __END_CDECLS #endif #endif