xref: /optee_os/core/include/drivers/scmi-msg.h (revision bbfe5da7daee2ab8efcb94fe11938d444b940384)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*
3  * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.
4  * Copyright (c) 2019-2021, Linaro Limited
5  */
6 
7 #ifndef SCMI_MSG_H
8 #define SCMI_MSG_H
9 
10 #include <compiler.h>
11 #include <kernel/panic.h>
12 #include <mm/core_memprot.h>
13 #include <stdbool.h>
14 #include <stddef.h>
15 #include <stdint.h>
16 
17 /* Minimum size expected for SMT based shared memory message buffers */
18 #define SMT_BUF_SLOT_SIZE	128
19 
20 /* Standard values for SCMI voltage domain protocol configuration state */
21 #define SCMI_VOLTAGE_DOMAIN_CONFIG_ARCH_ON	0x7
22 #define SCMI_VOLTAGE_DOMAIN_CONFIG_ARCH_OFF	0
23 
24 /* A channel abstract a communication path between agent and server */
25 struct scmi_msg_channel;
26 
27 /*
28  * struct scmi_msg_channel - Shared memory buffer for a agent-to-server channel
29  *
30  * @shm_addr: Address of the shared memory for the SCMI channel
31  * @shm_size: Byte size of the shared memory for the SCMI channel
32  * @busy: True when channel is busy, flase when channel is free
33  * @threaded: True is executed in a threaded context, false otherwise
34  */
35 struct scmi_msg_channel {
36 	struct io_pa_va shm_addr;
37 	size_t shm_size;
38 	bool busy;
39 	bool threaded;
40 };
41 
42 /*
43  * Initialize SMT memory buffer, called by platform at init for each
44  * agent channel using the SMT header format.
45  * This function depends on CFG_SCMI_MSG_SMT.
46  *
47  * @chan: Pointer to the channel shared memory to be initialized
48  */
49 void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan);
50 
51 /*
52  * Process SMT formatted message in a fastcall SMC execution context.
53  * Called by platform on SMC entry. When returning, output message is
54  * available in shared memory for agent to read the response.
55  * This function depends on CFG_SCMI_MSG_SMT_FASTCALL_ENTRY.
56  *
57  * @channel_id: SCMI channel ID the SMT belongs to
58  */
59 void scmi_smt_fastcall_smc_entry(unsigned int channel_id);
60 
61 /*
62  * Process SMT formatted message in a secure interrupt execution context.
63  * Called by platform interrupt handler. When returning, output message is
64  * available in shared memory for agent to read the response.
65  * This function depends on CFG_SCMI_MSG_SMT_INTERRUPT_ENTRY.
66  *
67  * @channel_id: SCMI channel ID the SMT belongs to
68  */
69 void scmi_smt_interrupt_entry(unsigned int channel_id);
70 
71 /*
72  * Process SMT formatted message in a TEE thread execution context.
73  * When returning, output message is available in shared memory for
74  * agent to read the response.
75  * This function depends on CFG_SCMI_MSG_SMT_THREAD_ENTRY.
76  *
77  * @channel_id: SCMI channel ID the SMT belongs to
78  */
79 void scmi_smt_threaded_entry(unsigned int channel_id);
80 
81 /* Platform callback functions */
82 
83 /*
84  * Return the SCMI channel related to an agent
85  * @channel_id: SCMI channel ID
86  * Return a pointer to channel on success, NULL otherwise
87  */
88 struct scmi_msg_channel *plat_scmi_get_channel(unsigned int channel_id);
89 
90 /*
91  * Return how many SCMI protocols supported by the platform
92  * According to the SCMI specification, this function does not target
93  * a specific channel ID and shall return all platform known capabilities.
94  */
95 size_t plat_scmi_protocol_count(void);
96 
97 /*
98  * Get the count and list of SCMI protocols (but base) supported for an agent
99  *
100  * @channel_id: SCMI channel ID
101  * Return a pointer to a null terminated array supported protocol IDs.
102  */
103 const uint8_t *plat_scmi_protocol_list(unsigned int channel_id);
104 
105 /* Get the name of the SCMI vendor for the platform */
106 const char *plat_scmi_vendor_name(void);
107 
108 /* Get the name of the SCMI sub-vendor for the platform */
109 const char *plat_scmi_sub_vendor_name(void);
110 
111 /* Handlers for SCMI Clock protocol services */
112 
113 /*
114  * Return number of clock controllers for an agent
115  * @channel_id: SCMI channel ID
116  * Return number of clock controllers
117  */
118 size_t plat_scmi_clock_count(unsigned int channel_id);
119 
120 /*
121  * Get clock controller string ID (aka name)
122  * @channel_id: SCMI channel ID
123  * @scmi_id: SCMI clock ID
124  * Return pointer to name or NULL
125  */
126 const char *plat_scmi_clock_get_name(unsigned int channel_id,
127 				     unsigned int scmi_id);
128 
129 /*
130  * Get clock possible rate as an array of frequencies in Hertz.
131  *
132  * @channel_id: SCMI channel ID
133  * @scmi_id: SCMI clock ID
134  * @start_index: Requested start index for the exposed rates array
135  * @rates: If NULL, function returns, else output rates array
136  * @nb_elts: Array size of @rates.
137  * Return an SCMI compliant error code
138  */
139 int32_t plat_scmi_clock_rates_array(unsigned int channel_id,
140 				    unsigned int scmi_id, size_t start_index,
141 				    unsigned long *rates, size_t *nb_elts);
142 
143 /*
144  * Get clock possible rate as range with regular steps in Hertz
145  *
146  * @channel_id: SCMI channel ID
147  * @scmi_id: SCMI clock ID
148  * @min_max_step: 3 cell array for min, max and step rate data
149  * Return an SCMI compliant error code
150  */
151 int32_t plat_scmi_clock_rates_by_step(unsigned int channel_id,
152 				      unsigned int scmi_id,
153 				      unsigned long *min_max_step);
154 
155 /*
156  * Get clock rate in Hertz
157  * @channel_id: SCMI channel ID
158  * @scmi_id: SCMI clock ID
159  * Return clock rate or 0 if not supported
160  */
161 unsigned long plat_scmi_clock_get_rate(unsigned int channel_id,
162 				       unsigned int scmi_id);
163 
164 /*
165  * Set clock rate in Hertz
166  * @channel_id: SCMI channel ID
167  * @scmi_id: SCMI clock ID
168  * @rate: Target clock frequency in Hertz
169  * Return a compliant SCMI error code
170  */
171 int32_t plat_scmi_clock_set_rate(unsigned int channel_id, unsigned int scmi_id,
172 				 unsigned long rate);
173 
174 /*
175  * Get clock state (enabled or disabled)
176  * @channel_id: SCMI channel ID
177  * @scmi_id: SCMI clock ID
178  * Return 1 if clock is enabled, 0 if disables, or a negative SCMI error code
179  */
180 int32_t plat_scmi_clock_get_state(unsigned int channel_id,
181 				  unsigned int scmi_id);
182 
183 /*
184  * Get clock state (enabled or disabled)
185  * @channel_id: SCMI channel ID
186  * @scmi_id: SCMI clock ID
187  * @enable_not_disable: Enable clock if true, disable clock otherwise
188  * Return a compliant SCMI error code
189  */
190 int32_t plat_scmi_clock_set_state(unsigned int channel_id, unsigned int scmi_id,
191 				  bool enable_not_disable);
192 
193 /* Handlers for SCMI Reset Domain protocol services */
194 
195 /*
196  * Return number of reset domains for the agent
197  * @channel_id: SCMI channel ID
198  * Return number of reset domains
199  */
200 size_t plat_scmi_rd_count(unsigned int channel_id);
201 
202 /*
203  * Get reset domain string ID (aka name)
204  * @channel_id: SCMI channel ID
205  * @scmi_id: SCMI reset domain ID
206  * Return pointer to name or NULL
207  */
208 const char *plat_scmi_rd_get_name(unsigned int channel_id,
209 				  unsigned int scmi_id);
210 
211 /*
212  * Perform a reset cycle on a target reset domain
213  * @channel_id: SCMI channel ID
214  * @scmi_id: SCMI reset domain ID
215  * @state: Target reset state (see SCMI specification, 0 means context loss)
216  * Return a compliant SCMI error code
217  */
218 int32_t plat_scmi_rd_autonomous(unsigned int channel_id, unsigned int scmi_id,
219 				unsigned int state);
220 
221 /*
222  * Assert or deassert target reset domain
223  * @channel_id: SCMI channel ID
224  * @scmi_id: SCMI reset domain ID
225  * @assert_not_deassert: Assert domain if true, otherwise deassert domain
226  * Return a compliant SCMI error code
227  */
228 int32_t plat_scmi_rd_set_state(unsigned int channel_id, unsigned int scmi_id,
229 			       bool assert_not_deassert);
230 
231 /* Handlers for SCMI Voltage Domain protocol services */
232 
233 /*
234  * Return number of voltage domain for an agent
235  * @channel_id: SCMI channel ID
236  * Return number of voltage domains
237  */
238 size_t plat_scmi_voltd_count(unsigned int channel_id);
239 
240 /*
241  * Get clock controller string ID (aka name)
242  * @channel_id: SCMI channel ID
243  * @scmi_id: SCMI voltage domain ID
244  * Return pointer to name or NULL
245  */
246 const char *plat_scmi_voltd_get_name(unsigned int channel_id,
247 				     unsigned int scmi_id);
248 
249 /*
250  * Get voltage domain possible levels as an array of voltages in microvolt.
251  *
252  * @channel_id: SCMI channel ID
253  * @scmi_id: SCMI voltage domain ID
254  * @start_index: Level index to start from.
255  * @levels: If NULL, function returns, else output rates array
256  * @nb_elts: Array size of @levels.
257  * Return an SCMI compliant error code
258  */
259 int32_t plat_scmi_voltd_levels_array(unsigned int channel_id,
260 				     unsigned int scmi_id, size_t start_index,
261 				     long *levels, size_t *nb_elts);
262 
263 /*
264  * Get voltage domain possible levels as range with regular steps in microvolt
265  *
266  * @channel_id: SCMI channel ID
267  * @scmi_id: SCMI voltage domain ID
268  * @min_max_step: 3 cell array for min, max and step voltage data
269  * Return an SCMI compliant error code
270  */
271 int32_t plat_scmi_voltd_levels_by_step(unsigned int channel_id,
272 				       unsigned int scmi_id,
273 				       long *min_max_step);
274 
275 /*
276  * Get current voltage domain level in microvolt
277  * @channel_id: SCMI channel ID
278  * @scmi_id: SCMI voltage domain ID
279  * Return clock rate or 0 if not supported
280  */
281 long plat_scmi_voltd_get_level(unsigned int channel_id, unsigned int scmi_id);
282 
283 /*
284  * Set voltage domain level voltage domain
285  * @channel_id: SCMI channel ID
286  * @scmi_id: SCMI clock ID
287  * @level: Target voltage domain level in microvolt
288  * Return a compliant SCMI error code
289  */
290 int32_t plat_scmi_voltd_set_level(unsigned int channel_id, unsigned int scmi_id,
291 				  long level);
292 
293 /*
294  * Get voltage domain state configuration (enabled or disabled)
295  * @channel_id: SCMI channel ID
296  * @scmi_id: SCMI voltage domain ID
297  * @config: output state configuration value SCMI_VOLTAGE_DOMAIN_CONFIG_*
298  * Return a compliant SCMI error code
299  */
300 int32_t plat_scmi_voltd_get_config(unsigned int channel_id,
301 				   unsigned int scmi_id, uint32_t *config);
302 
303 /*
304  * Get voltage domain state configuration (enabled or disabled)
305  * @channel_id: SCMI channel ID
306  * @scmi_id: SCMI voltage domain ID
307  * @config: Target state configuration value SCMI_VOLTAGE_DOMAIN_CONFIG_*
308  * Return a compliant SCMI error code
309  */
310 int32_t plat_scmi_voltd_set_config(unsigned int channel_id,
311 				   unsigned int scmi_id, uint32_t config);
312 
313 #endif /* SCMI_MSG_H */
314