xref: /optee_os/core/include/drivers/scmi-msg.h (revision 9fc2442cc66c279cb962c90c4375746fc9b28bb9)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*
3  * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.
4  * Copyright (c) 2019, 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  * @agent_name: Agent name, SCMI protocol exposes 16 bytes max, or NULL
35  */
36 struct scmi_msg_channel {
37 	struct io_pa_va shm_addr;
38 	size_t shm_size;
39 	bool busy;
40 	bool threaded;
41 	const char *agent_name;
42 };
43 
44 /*
45  * Initialize SMT memory buffer, called by platform at init for each
46  * agent channel using the SMT header format.
47  * This function depends on CFG_SCMI_MSG_SMT.
48  *
49  * @chan: Pointer to the channel shared memory to be initialized
50  */
51 void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan);
52 
53 /*
54  * Process SMT formatted message in a fastcall SMC execution context.
55  * Called by platform on SMC entry. When returning, output message is
56  * available in shared memory for agent to read the response.
57  * This function depends on CFG_SCMI_MSG_SMT_FASTCALL_ENTRY.
58  *
59  * @agent_id: SCMI agent ID the SMT belongs to
60  */
61 void scmi_smt_fastcall_smc_entry(unsigned int agent_id);
62 
63 /*
64  * Process SMT formatted message in a secure interrupt execution context.
65  * Called by platform interrupt handler. When returning, output message is
66  * available in shared memory for agent to read the response.
67  * This function depends on CFG_SCMI_MSG_SMT_INTERRUPT_ENTRY.
68  *
69  * @agent_id: SCMI agent ID the SMT belongs to
70  */
71 void scmi_smt_interrupt_entry(unsigned int agent_id);
72 
73 /*
74  * Process SMT formatted message in a TEE thread execution context.
75  * When returning, output message is available in shared memory for
76  * agent to read the response.
77  * This function depends on CFG_SCMI_MSG_SMT_THREAD_ENTRY.
78  *
79  * @agent_id: SCMI agent ID the SMT belongs to
80  */
81 void scmi_smt_threaded_entry(unsigned int agent_id);
82 
83 /* Platform callback functions */
84 
85 /*
86  * Return the SCMI channel related to an agent
87  * @agent_id: SCMI agent ID
88  * Return a pointer to channel on success, NULL otherwise
89  */
90 struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id);
91 
92 /*
93  * Return how many SCMI protocols supported by the platform
94  * According to the SCMI specification, this function does not target
95  * a specific agent ID and shall return all platform known capabilities.
96  */
97 size_t plat_scmi_protocol_count(void);
98 
99 /*
100  * Get the count and list of SCMI protocols (but base) supported for an agent
101  *
102  * @agent_id: SCMI agent ID
103  * Return a pointer to a null terminated array supported protocol IDs.
104  */
105 const uint8_t *plat_scmi_protocol_list(unsigned int agent_id);
106 
107 /* Get the name of the SCMI vendor for the platform */
108 const char *plat_scmi_vendor_name(void);
109 
110 /* Get the name of the SCMI sub-vendor for the platform */
111 const char *plat_scmi_sub_vendor_name(void);
112 
113 /* Handlers for SCMI Clock protocol services */
114 
115 /*
116  * Return number of clock controllers for an agent
117  * @agent_id: SCMI agent ID
118  * Return number of clock controllers
119  */
120 size_t plat_scmi_clock_count(unsigned int agent_id);
121 
122 /*
123  * Get clock controller string ID (aka name)
124  * @agent_id: SCMI agent ID
125  * @scmi_id: SCMI clock ID
126  * Return pointer to name or NULL
127  */
128 const char *plat_scmi_clock_get_name(unsigned int agent_id,
129 				     unsigned int scmi_id);
130 
131 /*
132  * Get clock possible rate as an array of frequencies in Hertz.
133  *
134  * @agent_id: SCMI agent ID
135  * @scmi_id: SCMI clock ID
136  * @rates: If NULL, function returns, else output rates array
137  * @start_index: Requested start index for the exposed rates array
138  * @nb_elts: Array size of @rates.
139  * Return an SCMI compliant error code
140  */
141 int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
142 				    size_t start_index, unsigned long *rates,
143 				    size_t *nb_elts);
144 
145 /*
146  * Get clock possible rate as range with regular steps in Hertz
147  *
148  * @agent_id: SCMI agent ID
149  * @scmi_id: SCMI clock ID
150  * @min_max_step: 3 cell array for min, max and step rate data
151  * Return an SCMI compliant error code
152  */
153 int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id,
154 				      unsigned int scmi_id,
155 				      unsigned long *min_max_step);
156 
157 /*
158  * Get clock rate in Hertz
159  * @agent_id: SCMI agent ID
160  * @scmi_id: SCMI clock ID
161  * Return clock rate or 0 if not supported
162  */
163 unsigned long plat_scmi_clock_get_rate(unsigned int agent_id,
164 				       unsigned int scmi_id);
165 
166 /*
167  * Set clock rate in Hertz
168  * @agent_id: SCMI agent ID
169  * @scmi_id: SCMI clock ID
170  * @rate: Target clock frequency in Hertz
171  * Return a compliant SCMI error code
172  */
173 int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id,
174 				 unsigned long rate);
175 
176 /*
177  * Get clock state (enabled or disabled)
178  * @agent_id: SCMI agent ID
179  * @scmi_id: SCMI clock ID
180  * Return 1 if clock is enabled, 0 if disables, or a negative SCMI error code
181  */
182 int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id);
183 
184 /*
185  * Get clock state (enabled or disabled)
186  * @agent_id: SCMI agent ID
187  * @scmi_id: SCMI clock ID
188  * @enable_not_disable: Enable clock if true, disable clock otherwise
189  * Return a compliant SCMI error code
190  */
191 int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id,
192 				  bool enable_not_disable);
193 
194 /* Handlers for SCMI Reset Domain protocol services */
195 
196 /*
197  * Return number of reset domains for the agent
198  * @agent_id: SCMI agent ID
199  * Return number of reset domains
200  */
201 size_t plat_scmi_rd_count(unsigned int agent_id);
202 
203 /*
204  * Get reset domain string ID (aka name)
205  * @agent_id: SCMI agent ID
206  * @scmi_id: SCMI reset domain ID
207  * Return pointer to name or NULL
208  */
209 const char *plat_scmi_rd_get_name(unsigned int agent_id, unsigned int scmi_id);
210 
211 /*
212  * Perform a reset cycle on a target reset domain
213  * @agent_id: SCMI agent 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 agent_id, unsigned int scmi_id,
219 				unsigned int state);
220 
221 /*
222  * Assert or deassert target reset domain
223  * @agent_id: SCMI agent 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 agent_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  * @agent_id: SCMI agent ID
236  * Return number of voltage domains
237  */
238 size_t plat_scmi_voltd_count(unsigned int agent_id);
239 
240 /*
241  * Get clock controller string ID (aka name)
242  * @agent_id: SCMI agent 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 agent_id,
247 				     unsigned int scmi_id);
248 
249 /*
250  * Get voltage domain possible levels as an array of voltages in microvolt.
251  *
252  * @agent_id: SCMI agent ID
253  * @scmi_id: SCMI voltage domain ID
254  * @levels: If NULL, function returns, else output rates array
255  * @start_index: Level index to start from.
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 agent_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  * @agent_id: SCMI agent 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 agent_id,
272 				       unsigned int scmi_id,
273 				       long *min_max_step);
274 
275 /*
276  * Get current voltage domain level in microvolt
277  * @agent_id: SCMI agent 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 agent_id, unsigned int scmi_id);
282 
283 /*
284  * Set voltage domain level voltage domain
285  * @agent_id: SCMI agent 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 agent_id, unsigned int scmi_id,
291 				  long level);
292 
293 /*
294  * Get voltage domain state configuration (enabled or disabled)
295  * @agent_id: SCMI agent ID
296  * @scmi_id: SCMI voltage domain ID
297  * @config: output state configuration value
298  * Return a compliant SCMI error code
299  */
300 int32_t plat_scmi_voltd_get_config(unsigned int agent_id, unsigned int scmi_id,
301 				   uint32_t *config);
302 
303 /*
304  * Get voltage domain state configuration (enabled or disabled)
305  * @agent_id: SCMI agent ID
306  * @scmi_id: SCMI clock ID
307  * @enable_not_disable: Enable clock if true, disable clock otherwise
308  * Return a compliant SCMI error code
309  */
310 int32_t plat_scmi_voltd_set_config(unsigned int agent_id, unsigned int scmi_id,
311 				   uint32_t config);
312 
313 #endif /* SCMI_MSG_H */
314