1 /* 2 * Copyright (c) 2023 Intel Corporation 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef _SEDI_DRIVER_IPC_H_ 8 #define _SEDI_DRIVER_IPC_H_ 9 10 #ifdef __cplusplus 11 extern "C" { 12 #endif 13 14 #include "sedi_driver_common.h" 15 16 /* 17 * struct sedi_ipc 18 * define IPC interface ID 19 * \ingroup sedi_driver_ipc 20 */ 21 typedef enum { 22 SEDI_IPC_HOST = 0, 23 SEDI_IPC_CSME, 24 SEDI_IPC_PMC, 25 SEDI_IPC_NUM 26 } sedi_ipc_t; 27 28 /****** IPC Event *****/ 29 30 /* 31 * SEDI_IPC_EVENT_MSG_IN 32 * Received an incoming ipc message 33 * \ingroup sedi_driver_ipc 34 */ 35 #define SEDI_IPC_EVENT_MSG_IN (1UL << 0) 36 37 /* 38 * SEDI_IPC_EVENT_MSG_PEER_ACKED 39 * An ipc busy bit is cleared by peer 40 * \ingroup sedi_driver_ipc 41 */ 42 #define SEDI_IPC_EVENT_MSG_PEER_ACKED (1UL << 1) 43 44 /* 45 * SEDI_IPC_EVENT_MSG_OUT 46 * An ipc message is received by peer 47 * \ingroup sedi_driver_ipc 48 */ 49 #define SEDI_IPC_EVENT_MSG_OUT (1UL << 2) 50 51 /* 52 * SEDI_IPC_EVENT_CSR_ACK 53 * Receive a CSR ack from peer after writing CSR 54 * \ingroup sedi_driver_ipc 55 */ 56 #define SEDI_IPC_EVENT_CSR_ACK (1UL << 3) 57 58 /****** IPC Capability *****/ 59 60 /* 61 * struct sedi_ipc_capabilities_t 62 * define IPC Driver Capabilities. 63 * \ingroup sedi_driver_ipc 64 */ 65 typedef struct { 66 uint32_t is_available : 1; 67 uint32_t reserved : 31; 68 } sedi_ipc_capabilities_t; 69 70 /****** IPC Driver helper definitions *****/ 71 72 #define IPC_PROTOCOL_BOOT 0 73 #define IPC_PROTOCOL_HECI 1 74 #define IPC_PROTOCOL_MCTP 2 75 #define IPC_PROTOCOL_MNG 3 76 77 #define IPC_DRBL_BUSY_BIT 31 78 #define IPC_DATA_LEN_MAX 128 79 80 #define IPC_HEADER_LENGTH_MASK (0x03FF) 81 #define IPC_HEADER_PROTOCOL_MASK (0x0F) 82 #define IPC_HEADER_MNG_CMD_MASK (0x0F) 83 84 #define IPC_HEADER_LENGTH_OFFSET 0 85 #define IPC_HEADER_PROTOCOL_OFFSET 10 86 #define IPC_HEADER_MNG_CMD_OFFSET 16 87 #define IPC_DRBL_BUSY_OFFS 31 88 89 #define IPC_HEADER_GET_LENGTH(drbl_reg) \ 90 (((drbl_reg) >> IPC_HEADER_LENGTH_OFFSET) & IPC_HEADER_LENGTH_MASK) 91 #define IPC_HEADER_GET_PROTOCOL(drbl_reg) \ 92 (((drbl_reg) >> IPC_HEADER_PROTOCOL_OFFSET) & IPC_HEADER_PROTOCOL_MASK) 93 #define IPC_HEADER_GET_MNG_CMD(drbl_reg) \ 94 (((drbl_reg) >> IPC_HEADER_MNG_CMD_OFFSET) & IPC_HEADER_MNG_CMD_MASK) 95 #define IPC_IS_BUSY(drbl) ((drbl) & BIT(IPC_DRBL_BUSY_OFFS)) 96 #define IPC_SET_BUSY(drbl) ((drbl) | BIT(IPC_DRBL_BUSY_OFFS)) 97 98 #define IPC_BUILD_DRBL(length, protocol) \ 99 ((1 << IPC_DRBL_BUSY_OFFS) \ 100 | ((protocol) << IPC_HEADER_PROTOCOL_OFFSET) \ 101 | ((length) << IPC_HEADER_LENGTH_OFFSET)) 102 103 #define IPC_BUILD_MNG_DRBL(cmd, length) \ 104 (((1) << IPC_DRBL_BUSY_OFFS) \ 105 | ((IPC_PROTOCOL_MNG) << IPC_HEADER_PROTOCOL_OFFSET) \ 106 | ((cmd) << IPC_HEADER_MNG_CMD_OFFSET) \ 107 | ((length) << IPC_HEADER_LENGTH_OFFSET)) 108 109 /* CSR bit definition */ 110 #define IPC_CSR_NO_MSG 0 111 #define IPC_CSR_RESET_ENTRY BIT(0) 112 #define IPC_CSR_RESET_EXIT BIT(1) 113 #define IPC_CSR_QUERY BIT(2) 114 #define IPC_CSR_ASSERT_VALID BIT(3) 115 #define IPC_CSR_ACKED_VALID BIT(4) 116 #define IPC_CSR_DEASSERT_VALID BIT(5) 117 #define IPC_CSR_SRAM_CLAIM BIT(31) 118 119 /****** IPC Driver API *****/ 120 121 /* 122 * ipc_event_handler IPC Event Handler Callback 123 * typedef sedi_ipc_event_cb_t 124 * Callback function type for signal ipc event. 125 * param[in] event: event type. 126 * return void 127 */ 128 typedef void (*sedi_ipc_event_cb_t)(IN sedi_ipc_t device, IN uint32_t event, 129 INOUT void *params); 130 131 /* 132 * Get the ipc driver's API version. 133 * return the version of current ipc driver's API 134 */ 135 sedi_driver_version_t sedi_ipc_get_version(void); 136 137 /* 138 * Get the device's capabilities. 139 * param[in] ipc_device: ipc device id 140 * param[inout] the capabilities of specific ipc device 141 * return return status 142 */ 143 int32_t sedi_ipc_get_capabilities(IN sedi_ipc_t ipc_device, 144 INOUT sedi_ipc_capabilities_t *cap); 145 /* 146 * write CSR message to peer. 147 * param[in] ipc_device: ipc device id 148 * param[in] csr: the csr content to sent 149 * return return status 150 */ 151 int32_t sedi_ipc_write_csr(IN sedi_ipc_t ipc_device, IN uint32_t csr); 152 153 /* 154 * read CSR message from peer. 155 * param[in] ipc_device: ipc device id 156 * param[out] csr: the pointer storing the csr msg 157 * return return status 158 */ 159 int32_t sedi_ipc_read_csr(IN sedi_ipc_t ipc_device, OUT uint32_t *csr); 160 161 /* 162 * Initialize the device 163 * param[in] ipc_device: ipc device id 164 * param[in] cb: the callback function which can receive device's events. 165 * param[in] user_params: user params, will be the last input of callback 166 * return return_status 167 */ 168 int32_t sedi_ipc_init(IN sedi_ipc_t ipc_device, IN sedi_ipc_event_cb_t cb, 169 INOUT void *user_params); 170 171 /* 172 * Uninitialize the device 173 * param[in] ipc_device: ipc device id 174 * return return_status 175 */ 176 int32_t sedi_ipc_uninit(IN sedi_ipc_t ipc_device); 177 178 /* 179 * Set the device's power 180 * param[in] ipc_device: ipc device id 181 * param[in] state: the power state to be set to the device 182 * return return_status 183 */ 184 int32_t sedi_ipc_set_power(IN sedi_ipc_t ipc_device, 185 IN sedi_power_state_t state); 186 187 /* 188 * Write data to IPC message fifo 189 * param[in] ipc_device: ipc device id 190 * param[in] msg: point to memory area where data is stored 191 * param[in] size: the length of data buffer 192 * return return_status 193 */ 194 int32_t sedi_ipc_write_msg(IN sedi_ipc_t ipc_device, IN uint8_t *msg, 195 IN int32_t size); 196 197 /* 198 * Write IPC doorbell register 199 * param[in] ipc_device: ipc device id 200 * param[in] doorbell: the value of doorbell 201 * return return_status 202 */ 203 int32_t sedi_ipc_write_dbl(IN sedi_ipc_t ipc_device, IN uint32_t doorbell); 204 205 /* 206 * Read data from IPC message fifo 207 * param[in] ipc_device: ipc device id 208 * param[out] msg: point to memory area where data will be stored 209 * param[in] size: the length of data buffer 210 * return return_status 211 */ 212 int32_t sedi_ipc_read_msg(IN sedi_ipc_t ipc_device, OUT uint8_t *msg, 213 IN int32_t size); 214 215 /* 216 * Read IPC doorbell register 217 * param[in] ipc_device: ipc device id 218 * param[out] doorbel: point to the value of doorbell 219 * return return_status 220 */ 221 int32_t sedi_ipc_read_dbl(IN sedi_ipc_t ipc_device, OUT uint32_t *doorbell); 222 223 /* 224 * send ack IPC message 225 * param[in] ipc_device: ipc device id 226 * param[in] msg: the ack msg 227 * param[in] size: the length of data buffer 228 * return return_status 229 */ 230 int32_t sedi_ipc_send_ack_msg(IN sedi_ipc_t ipc_device, IN uint8_t *msg, 231 IN int32_t size); 232 233 /* 234 * send ack IPC doorbell register 235 * param[in] ipc_device: ipc device id 236 * param[in] doorbell: the ack doorbell 237 * return return_status 238 */ 239 int32_t sedi_ipc_send_ack_drbl(IN sedi_ipc_t ipc_device, IN uint32_t ack); 240 241 /* 242 * read peer ack IPC message 243 * param[in] ipc_device: ipc device id 244 * param[out] doorbell: the buffer to store ack msg 245 * param[in] size: the length of data buffer 246 * return return_status 247 */ 248 int32_t sedi_ipc_read_ack_msg(IN sedi_ipc_t ipc_device, OUT uint8_t *msg, 249 IN int32_t size); 250 251 /* 252 * read peer ack IPC doorbell register 253 * param[in] ipc_device: ipc device id 254 * param[out] doorbell: the ack doorbell 255 * return return_status 256 */ 257 int32_t sedi_ipc_read_ack_drbl(IN sedi_ipc_t ipc_device, OUT uint32_t *ack); 258 259 #ifdef __cplusplus 260 } 261 #endif 262 263 #endif /* _SEDI_DRIVER_IPC_H_*/ 264