File Index
Files and directories
Sign in
FILE

riscv-rpmi-message.h

File preview with syntax highlighting.

linux-6.19.14/include/linux/mailbox/riscv-rpmi-message.h C
  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.