Files
base/drivers/include/sdrv_mbox.h
2025-11-07 09:57:14 +08:00

264 lines
8.4 KiB
C

/**
* @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 <types.h>
#include <compiler.h>
#include <sdrv_common.h>
#include <mbox_proc.h>
/* 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