xref: /optee_os/core/include/drivers/scmi-msg.h (revision 48f04743e2e45bcccb7f6bedfc96b6b40aa0f9f2)
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 #ifdef CFG_SCMI_MSG_SMT
43 /*
44  * Initialize SMT memory buffer, called by platform at init for each
45  * agent channel using the SMT header format.
46  * This function depends on CFG_SCMI_MSG_SMT.
47  *
48  * @chan: Pointer to the channel shared memory to be initialized
49  */
50 void scmi_smt_init_agent_channel(struct scmi_msg_channel *channel);
51 
52 /*
53  * Set SMT shared buffer location
54  *
55  * @channel: SCMI channel reference
56  * @base: virtual address of the shared buffer or NULL to clear the reference
57  */
58 void scmi_smt_set_shared_buffer(struct scmi_msg_channel *channel, void *base);
59 #else
60 static inline
61 void scmi_smt_init_agent_channel(struct scmi_msg_channel *channel __unused)
62 {
63 	panic();
64 }
65 
66 static inline
67 void scmi_smt_set_shared_buffer(struct scmi_msg_channel *channel __unused,
68 				void *base __unused)
69 {
70 }
71 #endif /* CFG_SCMI_MSG_SMT */
72 
73 #ifdef CFG_SCMI_MSG_SMT_FASTCALL_ENTRY
74 /*
75  * Process SMT formatted message in a fastcall SMC execution context.
76  * Called by platform on SMC entry. When returning, output message is
77  * available in shared memory for agent to read the response.
78  * This function depends on CFG_SCMI_MSG_SMT_FASTCALL_ENTRY.
79  *
80  * @channel_id: SCMI channel ID the SMT belongs to
81  */
82 void scmi_smt_fastcall_smc_entry(unsigned int channel_id);
83 #else
84 static inline void scmi_smt_fastcall_smc_entry(unsigned int channel_id __unused)
85 {
86 }
87 #endif
88 
89 #ifdef CFG_SCMI_MSG_SMT_INTERRUPT_ENTRY
90 /*
91  * Process SMT formatted message in a secure interrupt execution context.
92  * Called by platform interrupt handler. When returning, output message is
93  * available in shared memory for agent to read the response.
94  * This function depends on CFG_SCMI_MSG_SMT_INTERRUPT_ENTRY.
95  *
96  * @channel_id: SCMI channel ID the SMT belongs to
97  */
98 void scmi_smt_interrupt_entry(unsigned int channel_id);
99 #else
100 static inline void scmi_smt_interrupt_entry(unsigned int channel_id __unused)
101 {
102 }
103 #endif
104 
105 #ifdef CFG_SCMI_MSG_SMT_THREAD_ENTRY
106 /*
107  * Process SMT formatted message in a TEE thread execution context.
108  * When returning, output message is available in shared memory for
109  * agent to read the response.
110  * This function depends on CFG_SCMI_MSG_SMT_THREAD_ENTRY.
111  *
112  * @channel_id: SCMI channel ID the SMT belongs to
113  */
114 void scmi_smt_threaded_entry(unsigned int channel_id);
115 #else
116 static inline void scmi_smt_threaded_entry(unsigned int channel_id __unused)
117 {
118 }
119 #endif
120 
121 /* Platform callback functions */
122 
123 /*
124  * Return the SCMI channel related to an agent
125  * @channel_id: SCMI channel ID
126  * Return a pointer to channel on success, NULL otherwise
127  */
128 struct scmi_msg_channel *plat_scmi_get_channel(unsigned int channel_id);
129 
130 /*
131  * Return how many SCMI protocols supported by the platform
132  * According to the SCMI specification, this function does not target
133  * a specific channel ID and shall return all platform known capabilities.
134  */
135 size_t plat_scmi_protocol_count(void);
136 
137 /*
138  * Get the count and list of SCMI protocols (but base) supported for an agent
139  *
140  * @channel_id: SCMI channel ID
141  * Return a pointer to a null terminated array supported protocol IDs.
142  */
143 const uint8_t *plat_scmi_protocol_list(unsigned int channel_id);
144 
145 /* Get the name of the SCMI vendor for the platform */
146 const char *plat_scmi_vendor_name(void);
147 
148 /* Get the name of the SCMI sub-vendor for the platform */
149 const char *plat_scmi_sub_vendor_name(void);
150 
151 /* Handlers for SCMI Clock protocol services */
152 
153 /*
154  * Return number of clock controllers for an agent
155  * @channel_id: SCMI channel ID
156  * Return number of clock controllers
157  */
158 size_t plat_scmi_clock_count(unsigned int channel_id);
159 
160 /*
161  * Get clock controller string ID (aka name)
162  * @channel_id: SCMI channel ID
163  * @scmi_id: SCMI clock ID
164  * Return pointer to name or NULL
165  */
166 const char *plat_scmi_clock_get_name(unsigned int channel_id,
167 				     unsigned int scmi_id);
168 
169 /*
170  * Get clock possible rate as an array of frequencies in Hertz.
171  *
172  * @channel_id: SCMI channel ID
173  * @scmi_id: SCMI clock ID
174  * @start_index: Requested start index for the exposed rates array
175  * @rates: If NULL, function returns, else output rates array
176  * @nb_elts: Array size of @rates.
177  * Return an SCMI compliant error code
178  */
179 int32_t plat_scmi_clock_rates_array(unsigned int channel_id,
180 				    unsigned int scmi_id, size_t start_index,
181 				    unsigned long *rates, size_t *nb_elts);
182 
183 /*
184  * Get clock possible rate as range with regular steps in Hertz
185  *
186  * @channel_id: SCMI channel ID
187  * @scmi_id: SCMI clock ID
188  * @min_max_step: 3 cell array for min, max and step rate data
189  * Return an SCMI compliant error code
190  */
191 int32_t plat_scmi_clock_rates_by_step(unsigned int channel_id,
192 				      unsigned int scmi_id,
193 				      unsigned long *min_max_step);
194 
195 /*
196  * Get clock rate in Hertz
197  * @channel_id: SCMI channel ID
198  * @scmi_id: SCMI clock ID
199  * Return clock rate or 0 if not supported
200  */
201 unsigned long plat_scmi_clock_get_rate(unsigned int channel_id,
202 				       unsigned int scmi_id);
203 
204 /*
205  * Set clock rate in Hertz
206  * @channel_id: SCMI channel ID
207  * @scmi_id: SCMI clock ID
208  * @rate: Target clock frequency in Hertz
209  * Return a compliant SCMI error code
210  */
211 int32_t plat_scmi_clock_set_rate(unsigned int channel_id, unsigned int scmi_id,
212 				 unsigned long rate);
213 
214 /*
215  * Get clock state (enabled or disabled)
216  * @channel_id: SCMI channel ID
217  * @scmi_id: SCMI clock ID
218  * Return 1 if clock is enabled, 0 if disables, or a negative SCMI error code
219  */
220 int32_t plat_scmi_clock_get_state(unsigned int channel_id,
221 				  unsigned int scmi_id);
222 
223 /*
224  * Get clock state (enabled or disabled)
225  * @channel_id: SCMI channel ID
226  * @scmi_id: SCMI clock ID
227  * @enable_not_disable: Enable clock if true, disable clock otherwise
228  * Return a compliant SCMI error code
229  */
230 int32_t plat_scmi_clock_set_state(unsigned int channel_id, unsigned int scmi_id,
231 				  bool enable_not_disable);
232 
233 /* Handlers for SCMI Reset Domain protocol services */
234 
235 /*
236  * Return number of reset domains for the agent
237  * @channel_id: SCMI channel ID
238  * Return number of reset domains
239  */
240 size_t plat_scmi_rd_count(unsigned int channel_id);
241 
242 /*
243  * Get reset domain string ID (aka name)
244  * @channel_id: SCMI channel ID
245  * @scmi_id: SCMI reset domain ID
246  * Return pointer to name or NULL
247  */
248 const char *plat_scmi_rd_get_name(unsigned int channel_id,
249 				  unsigned int scmi_id);
250 
251 /*
252  * Perform a reset cycle on a target reset domain
253  * @channel_id: SCMI channel ID
254  * @scmi_id: SCMI reset domain ID
255  * @state: Target reset state (see SCMI specification, 0 means context loss)
256  * Return a compliant SCMI error code
257  */
258 int32_t plat_scmi_rd_autonomous(unsigned int channel_id, unsigned int scmi_id,
259 				unsigned int state);
260 
261 /*
262  * Assert or deassert target reset domain
263  * @channel_id: SCMI channel ID
264  * @scmi_id: SCMI reset domain ID
265  * @assert_not_deassert: Assert domain if true, otherwise deassert domain
266  * Return a compliant SCMI error code
267  */
268 int32_t plat_scmi_rd_set_state(unsigned int channel_id, unsigned int scmi_id,
269 			       bool assert_not_deassert);
270 
271 /* Handlers for SCMI Voltage Domain protocol services */
272 
273 /*
274  * Return number of voltage domain for an agent
275  * @channel_id: SCMI channel ID
276  * Return number of voltage domains
277  */
278 size_t plat_scmi_voltd_count(unsigned int channel_id);
279 
280 /*
281  * Get clock controller string ID (aka name)
282  * @channel_id: SCMI channel ID
283  * @scmi_id: SCMI voltage domain ID
284  * Return pointer to name or NULL
285  */
286 const char *plat_scmi_voltd_get_name(unsigned int channel_id,
287 				     unsigned int scmi_id);
288 
289 /*
290  * Get voltage domain possible levels as an array of voltages in microvolt.
291  *
292  * @channel_id: SCMI channel ID
293  * @scmi_id: SCMI voltage domain ID
294  * @start_index: Level index to start from.
295  * @levels: If NULL, function returns, else output rates array
296  * @nb_elts: Array size of @levels.
297  * Return an SCMI compliant error code
298  */
299 int32_t plat_scmi_voltd_levels_array(unsigned int channel_id,
300 				     unsigned int scmi_id, size_t start_index,
301 				     long *levels, size_t *nb_elts);
302 
303 /*
304  * Get voltage domain possible levels as range with regular steps in microvolt
305  *
306  * @channel_id: SCMI channel ID
307  * @scmi_id: SCMI voltage domain ID
308  * @min_max_step: 3 cell array for min, max and step voltage data
309  * Return an SCMI compliant error code
310  */
311 int32_t plat_scmi_voltd_levels_by_step(unsigned int channel_id,
312 				       unsigned int scmi_id,
313 				       long *min_max_step);
314 
315 /*
316  * Get current voltage domain level in microvolt
317  * @channel_id: SCMI channel ID
318  * @scmi_id: SCMI voltage domain ID
319  * Return clock rate or 0 if not supported
320  */
321 long plat_scmi_voltd_get_level(unsigned int channel_id, unsigned int scmi_id);
322 
323 /*
324  * Set voltage domain level voltage domain
325  * @channel_id: SCMI channel ID
326  * @scmi_id: SCMI clock ID
327  * @level: Target voltage domain level in microvolt
328  * Return a compliant SCMI error code
329  */
330 int32_t plat_scmi_voltd_set_level(unsigned int channel_id, unsigned int scmi_id,
331 				  long level);
332 
333 /*
334  * Get voltage domain state configuration (enabled or disabled)
335  * @channel_id: SCMI channel ID
336  * @scmi_id: SCMI voltage domain ID
337  * @config: output state configuration value SCMI_VOLTAGE_DOMAIN_CONFIG_*
338  * Return a compliant SCMI error code
339  */
340 int32_t plat_scmi_voltd_get_config(unsigned int channel_id,
341 				   unsigned int scmi_id, uint32_t *config);
342 
343 /*
344  * Get voltage domain state configuration (enabled or disabled)
345  * @channel_id: SCMI channel ID
346  * @scmi_id: SCMI voltage domain ID
347  * @config: Target state configuration value SCMI_VOLTAGE_DOMAIN_CONFIG_*
348  * Return a compliant SCMI error code
349  */
350 int32_t plat_scmi_voltd_set_config(unsigned int channel_id,
351 				   unsigned int scmi_id, uint32_t config);
352 
353 #endif /* SCMI_MSG_H */
354