FILE
riscv-rpmi-message.h
File preview with syntax highlighting.
linux-6.19.14/include/linux/mailbox/riscv-rpmi-message.h
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* Copyright (C) 2025 Ventana Micro Systems Inc. */ 3 4#ifndef _LINUX_RISCV_RPMI_MESSAGE_H_ 5#define _LINUX_RISCV_RPMI_MESSAGE_H_ 6 7#include <linux/errno.h> 8#include <linux/mailbox_client.h> 9#include <linux/types.h> 10#include <linux/wordpart.h> 11 12/* RPMI version encode/decode macros */ 13#define RPMI_VER_MAJOR(__ver) upper_16_bits(__ver) 14#define RPMI_VER_MINOR(__ver) lower_16_bits(__ver) 15#define RPMI_MKVER(__maj, __min) (((u32)(__maj) << 16) | (u16)(__min)) 16 17/* RPMI message header */ 18struct rpmi_message_header { 19 __le16 servicegroup_id; 20 u8 service_id; 21 u8 flags; 22 __le16 datalen; 23 __le16 token; 24}; 25 26/* RPMI message */ 27struct rpmi_message { 28 struct rpmi_message_header header; 29 u8 data[]; 30}; 31 32/* RPMI notification event */ 33struct rpmi_notification_event { 34 __le16 event_datalen; 35 u8 event_id; 36 u8 reserved; 37 u8 event_data[]; 38}; 39 40/* RPMI error codes */ 41enum rpmi_error_codes { 42 RPMI_SUCCESS = 0, 43 RPMI_ERR_FAILED = -1, 44 RPMI_ERR_NOTSUPP = -2, 45 RPMI_ERR_INVALID_PARAM = -3, 46 RPMI_ERR_DENIED = -4, 47 RPMI_ERR_INVALID_ADDR = -5, 48 RPMI_ERR_ALREADY = -6, 49 RPMI_ERR_EXTENSION = -7, 50 RPMI_ERR_HW_FAULT = -8, 51 RPMI_ERR_BUSY = -9, 52 RPMI_ERR_INVALID_STATE = -10, 53 RPMI_ERR_BAD_RANGE = -11, 54 RPMI_ERR_TIMEOUT = -12, 55 RPMI_ERR_IO = -13, 56 RPMI_ERR_NO_DATA = -14, 57 RPMI_ERR_RESERVED_START = -15, 58 RPMI_ERR_RESERVED_END = -127, 59 RPMI_ERR_VENDOR_START = -128, 60}; 61 62static inline int rpmi_to_linux_error(int rpmi_error) 63{ 64 switch (rpmi_error) { 65 case RPMI_SUCCESS: 66 return 0; 67 case RPMI_ERR_INVALID_PARAM: 68 case RPMI_ERR_BAD_RANGE: 69 case RPMI_ERR_INVALID_STATE: 70 return -EINVAL; 71 case RPMI_ERR_DENIED: 72 return -EPERM; 73 case RPMI_ERR_INVALID_ADDR: 74 case RPMI_ERR_HW_FAULT: 75 return -EFAULT; 76 case RPMI_ERR_ALREADY: 77 return -EALREADY; 78 case RPMI_ERR_BUSY: 79 return -EBUSY; 80 case RPMI_ERR_TIMEOUT: 81 return -ETIMEDOUT; 82 case RPMI_ERR_IO: 83 return -ECOMM; 84 case RPMI_ERR_FAILED: 85 case RPMI_ERR_NOTSUPP: 86 case RPMI_ERR_NO_DATA: 87 case RPMI_ERR_EXTENSION: 88 default: 89 return -EOPNOTSUPP; 90 } 91} 92 93/* RPMI service group IDs */ 94#define RPMI_SRVGRP_SYSTEM_MSI 0x00002 95#define RPMI_SRVGRP_CLOCK 0x00008 96 97/* RPMI clock service IDs */ 98enum rpmi_clock_service_id { 99 RPMI_CLK_SRV_ENABLE_NOTIFICATION = 0x01, 100 RPMI_CLK_SRV_GET_NUM_CLOCKS = 0x02, 101 RPMI_CLK_SRV_GET_ATTRIBUTES = 0x03, 102 RPMI_CLK_SRV_GET_SUPPORTED_RATES = 0x04, 103 RPMI_CLK_SRV_SET_CONFIG = 0x05, 104 RPMI_CLK_SRV_GET_CONFIG = 0x06, 105 RPMI_CLK_SRV_SET_RATE = 0x07, 106 RPMI_CLK_SRV_GET_RATE = 0x08, 107 RPMI_CLK_SRV_ID_MAX_COUNT 108}; 109 110/* RPMI system MSI service IDs */ 111enum rpmi_sysmsi_service_id { 112 RPMI_SYSMSI_SRV_ENABLE_NOTIFICATION = 0x01, 113 RPMI_SYSMSI_SRV_GET_ATTRIBUTES = 0x02, 114 RPMI_SYSMSI_SRV_GET_MSI_ATTRIBUTES = 0x03, 115 RPMI_SYSMSI_SRV_SET_MSI_STATE = 0x04, 116 RPMI_SYSMSI_SRV_GET_MSI_STATE = 0x05, 117 RPMI_SYSMSI_SRV_SET_MSI_TARGET = 0x06, 118 RPMI_SYSMSI_SRV_GET_MSI_TARGET = 0x07, 119 RPMI_SYSMSI_SRV_ID_MAX_COUNT 120}; 121 122/* RPMI Linux mailbox attribute IDs */ 123enum rpmi_mbox_attribute_id { 124 RPMI_MBOX_ATTR_SPEC_VERSION, 125 RPMI_MBOX_ATTR_MAX_MSG_DATA_SIZE, 126 RPMI_MBOX_ATTR_SERVICEGROUP_ID, 127 RPMI_MBOX_ATTR_SERVICEGROUP_VERSION, 128 RPMI_MBOX_ATTR_IMPL_ID, 129 RPMI_MBOX_ATTR_IMPL_VERSION, 130 RPMI_MBOX_ATTR_MAX_ID 131}; 132 133/* RPMI Linux mailbox message types */ 134enum rpmi_mbox_message_type { 135 RPMI_MBOX_MSG_TYPE_GET_ATTRIBUTE, 136 RPMI_MBOX_MSG_TYPE_SET_ATTRIBUTE, 137 RPMI_MBOX_MSG_TYPE_SEND_WITH_RESPONSE, 138 RPMI_MBOX_MSG_TYPE_SEND_WITHOUT_RESPONSE, 139 RPMI_MBOX_MSG_TYPE_NOTIFICATION_EVENT, 140 RPMI_MBOX_MSG_MAX_TYPE 141}; 142 143/* RPMI Linux mailbox message instance */ 144struct rpmi_mbox_message { 145 enum rpmi_mbox_message_type type; 146 union { 147 struct { 148 enum rpmi_mbox_attribute_id id; 149 u32 value; 150 } attr; 151 152 struct { 153 u32 service_id; 154 void *request; 155 unsigned long request_len; 156 void *response; 157 unsigned long max_response_len; 158 unsigned long out_response_len; 159 } data; 160 161 struct { 162 u16 event_datalen; 163 u8 event_id; 164 u8 *event_data; 165 } notif; 166 }; 167 int error; 168}; 169 170/* RPMI Linux mailbox message helper routines */ 171static inline void rpmi_mbox_init_get_attribute(struct rpmi_mbox_message *msg, 172 enum rpmi_mbox_attribute_id id) 173{ 174 msg->type = RPMI_MBOX_MSG_TYPE_GET_ATTRIBUTE; 175 msg->attr.id = id; 176 msg->attr.value = 0; 177 msg->error = 0; 178} 179 180static inline void rpmi_mbox_init_set_attribute(struct rpmi_mbox_message *msg, 181 enum rpmi_mbox_attribute_id id, 182 u32 value) 183{ 184 msg->type = RPMI_MBOX_MSG_TYPE_SET_ATTRIBUTE; 185 msg->attr.id = id; 186 msg->attr.value = value; 187 msg->error = 0; 188} 189 190static inline void rpmi_mbox_init_send_with_response(struct rpmi_mbox_message *msg, 191 u32 service_id, 192 void *request, 193 unsigned long request_len, 194 void *response, 195 unsigned long max_response_len) 196{ 197 msg->type = RPMI_MBOX_MSG_TYPE_SEND_WITH_RESPONSE; 198 msg->data.service_id = service_id; 199 msg->data.request = request; 200 msg->data.request_len = request_len; 201 msg->data.response = response; 202 msg->data.max_response_len = max_response_len; 203 msg->data.out_response_len = 0; 204 msg->error = 0; 205} 206 207static inline void rpmi_mbox_init_send_without_response(struct rpmi_mbox_message *msg, 208 u32 service_id, 209 void *request, 210 unsigned long request_len) 211{ 212 msg->type = RPMI_MBOX_MSG_TYPE_SEND_WITHOUT_RESPONSE; 213 msg->data.service_id = service_id; 214 msg->data.request = request; 215 msg->data.request_len = request_len; 216 msg->data.response = NULL; 217 msg->data.max_response_len = 0; 218 msg->data.out_response_len = 0; 219 msg->error = 0; 220} 221 222static inline void *rpmi_mbox_get_msg_response(struct rpmi_mbox_message *msg) 223{ 224 return msg ? msg->data.response : NULL; 225} 226 227static inline int rpmi_mbox_send_message(struct mbox_chan *chan, 228 struct rpmi_mbox_message *msg) 229{ 230 int ret; 231 232 /* Send message for the underlying mailbox channel */ 233 ret = mbox_send_message(chan, msg); 234 if (ret < 0) 235 return ret; 236 237 /* Explicitly signal txdone for mailbox channel */ 238 ret = msg->error; 239 mbox_client_txdone(chan, ret); 240 return ret; 241} 242 243#endif /* _LINUX_RISCV_RPMI_MESSAGE_H_ */
~/
Read-only file preview.