xref: /optee_os/core/include/drivers/scmi-msg.h (revision 064bf8dc50d06d72e0d220d811b2261ea5cdea95)
1ae8c8068SEtienne Carriere /* SPDX-License-Identifier: BSD-3-Clause */
2ae8c8068SEtienne Carriere /*
3ae8c8068SEtienne Carriere  * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.
4ae8c8068SEtienne Carriere  * Copyright (c) 2019, Linaro Limited
5ae8c8068SEtienne Carriere  */
6ae8c8068SEtienne Carriere 
7ae8c8068SEtienne Carriere #ifndef SCMI_MSG_H
8ae8c8068SEtienne Carriere #define SCMI_MSG_H
9ae8c8068SEtienne Carriere 
10ae8c8068SEtienne Carriere #include <compiler.h>
11ae8c8068SEtienne Carriere #include <kernel/panic.h>
12ae8c8068SEtienne Carriere #include <mm/core_memprot.h>
13ae8c8068SEtienne Carriere #include <stdbool.h>
14ae8c8068SEtienne Carriere #include <stddef.h>
15ae8c8068SEtienne Carriere #include <stdint.h>
16ae8c8068SEtienne Carriere 
17ae8c8068SEtienne Carriere /* Minimum size expected for SMT based shared memory message buffers */
18ae8c8068SEtienne Carriere #define SMT_BUF_SLOT_SIZE	128
19ae8c8068SEtienne Carriere 
20ae8c8068SEtienne Carriere /* A channel abstract a communication path between agent and server */
21ae8c8068SEtienne Carriere struct scmi_msg_channel;
22ae8c8068SEtienne Carriere 
23ae8c8068SEtienne Carriere /*
24ae8c8068SEtienne Carriere  * struct scmi_msg_channel - Shared memory buffer for a agent-to-server channel
25ae8c8068SEtienne Carriere  *
26ae8c8068SEtienne Carriere  * @shm_addr: Address of the shared memory for the SCMI channel
27ae8c8068SEtienne Carriere  * @shm_size: Byte size of the shared memory for the SCMI channel
28ae8c8068SEtienne Carriere  * @busy: True when channel is busy, flase when channel is free
29ae8c8068SEtienne Carriere  * @threaded: True is executed in a threaded context, false otherwise
30*064bf8dcSEtienne Carriere  * @agent_name: Agent name, SCMI protocol exposes 16 bytes max, or NULL
31ae8c8068SEtienne Carriere  */
32ae8c8068SEtienne Carriere struct scmi_msg_channel {
33ae8c8068SEtienne Carriere 	struct io_pa_va shm_addr;
34ae8c8068SEtienne Carriere 	size_t shm_size;
35ae8c8068SEtienne Carriere 	bool busy;
36ae8c8068SEtienne Carriere 	bool threaded;
37ae8c8068SEtienne Carriere 	const char *agent_name;
38ae8c8068SEtienne Carriere };
39ae8c8068SEtienne Carriere 
40a58c4d70SEtienne Carriere /*
41a58c4d70SEtienne Carriere  * Initialize SMT memory buffer, called by platform at init for each
42a58c4d70SEtienne Carriere  * agent channel using the SMT header format.
43a58c4d70SEtienne Carriere  * This function depends on CFG_SCMI_MSG_SMT.
44a58c4d70SEtienne Carriere  *
45a58c4d70SEtienne Carriere  * @chan: Pointer to the channel shared memory to be initialized
46a58c4d70SEtienne Carriere  */
47a58c4d70SEtienne Carriere void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan);
48a58c4d70SEtienne Carriere 
49a58c4d70SEtienne Carriere /*
50*064bf8dcSEtienne Carriere  * Process SMT formatted message in a fastcall SMC execution context.
51a58c4d70SEtienne Carriere  * Called by platform on SMC entry. When returning, output message is
52a58c4d70SEtienne Carriere  * available in shared memory for agent to read the response.
53a58c4d70SEtienne Carriere  * This function depends on CFG_SCMI_MSG_SMT_FASTCALL_ENTRY.
54a58c4d70SEtienne Carriere  *
55a58c4d70SEtienne Carriere  * @agent_id: SCMI agent ID the SMT belongs to
56a58c4d70SEtienne Carriere  */
57a58c4d70SEtienne Carriere void scmi_smt_fastcall_smc_entry(unsigned int agent_id);
58a58c4d70SEtienne Carriere 
59a58c4d70SEtienne Carriere /*
60a58c4d70SEtienne Carriere  * Process SMT formatted message in a secure interrupt execution context.
61a58c4d70SEtienne Carriere  * Called by platform interrupt handler. When returning, output message is
62a58c4d70SEtienne Carriere  * available in shared memory for agent to read the response.
63a58c4d70SEtienne Carriere  * This function depends on CFG_SCMI_MSG_SMT_INTERRUPT_ENTRY.
64a58c4d70SEtienne Carriere  *
65a58c4d70SEtienne Carriere  * @agent_id: SCMI agent ID the SMT belongs to
66a58c4d70SEtienne Carriere  */
67a58c4d70SEtienne Carriere void scmi_smt_interrupt_entry(unsigned int agent_id);
68a58c4d70SEtienne Carriere 
69a58c4d70SEtienne Carriere /*
70a58c4d70SEtienne Carriere  * Process SMT formatted message in a TEE thread execution context.
71a58c4d70SEtienne Carriere  * When returning, output message is available in shared memory for
72a58c4d70SEtienne Carriere  * agent to read the response.
73a58c4d70SEtienne Carriere  * This function depends on CFG_SCMI_MSG_SMT_THREAD_ENTRY.
74a58c4d70SEtienne Carriere  *
75a58c4d70SEtienne Carriere  * @agent_id: SCMI agent ID the SMT belongs to
76a58c4d70SEtienne Carriere  */
77a58c4d70SEtienne Carriere void scmi_smt_threaded_entry(unsigned int agent_id);
78a58c4d70SEtienne Carriere 
79ae8c8068SEtienne Carriere /* Platform callback functions */
80ae8c8068SEtienne Carriere 
81ae8c8068SEtienne Carriere /*
82ae8c8068SEtienne Carriere  * Return the SCMI channel related to an agent
83ae8c8068SEtienne Carriere  * @agent_id: SCMI agent ID
84ae8c8068SEtienne Carriere  * Return a pointer to channel on success, NULL otherwise
85ae8c8068SEtienne Carriere  */
86ae8c8068SEtienne Carriere struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id);
87ae8c8068SEtienne Carriere 
88ae8c8068SEtienne Carriere /*
89ae8c8068SEtienne Carriere  * Return how many SCMI protocols supported by the platform
90ae8c8068SEtienne Carriere  * According to the SCMI specification, this function does not target
91ae8c8068SEtienne Carriere  * a specific agent ID and shall return all platform known capabilities.
92ae8c8068SEtienne Carriere  */
93ae8c8068SEtienne Carriere size_t plat_scmi_protocol_count(void);
94ae8c8068SEtienne Carriere 
95ae8c8068SEtienne Carriere /*
96ae8c8068SEtienne Carriere  * Get the count and list of SCMI protocols (but base) supported for an agent
97ae8c8068SEtienne Carriere  *
98ae8c8068SEtienne Carriere  * @agent_id: SCMI agent ID
99ae8c8068SEtienne Carriere  * Return a pointer to a null terminated array supported protocol IDs.
100ae8c8068SEtienne Carriere  */
101ae8c8068SEtienne Carriere const uint8_t *plat_scmi_protocol_list(unsigned int agent_id);
102ae8c8068SEtienne Carriere 
103ae8c8068SEtienne Carriere /* Get the name of the SCMI vendor for the platform */
104ae8c8068SEtienne Carriere const char *plat_scmi_vendor_name(void);
105ae8c8068SEtienne Carriere 
106ae8c8068SEtienne Carriere /* Get the name of the SCMI sub-vendor for the platform */
107ae8c8068SEtienne Carriere const char *plat_scmi_sub_vendor_name(void);
108ae8c8068SEtienne Carriere 
109a7a9e3baSEtienne Carriere /* Handlers for SCMI Clock protocol services */
110a7a9e3baSEtienne Carriere 
111a7a9e3baSEtienne Carriere /*
112a7a9e3baSEtienne Carriere  * Return number of clock controllers for an agent
113a7a9e3baSEtienne Carriere  * @agent_id: SCMI agent ID
114a7a9e3baSEtienne Carriere  * Return number of clock controllers
115a7a9e3baSEtienne Carriere  */
116a7a9e3baSEtienne Carriere size_t plat_scmi_clock_count(unsigned int agent_id);
117a7a9e3baSEtienne Carriere 
118a7a9e3baSEtienne Carriere /*
119a7a9e3baSEtienne Carriere  * Get clock controller string ID (aka name)
120a7a9e3baSEtienne Carriere  * @agent_id: SCMI agent ID
121a7a9e3baSEtienne Carriere  * @scmi_id: SCMI clock ID
122a7a9e3baSEtienne Carriere  * Return pointer to name or NULL
123a7a9e3baSEtienne Carriere  */
124a7a9e3baSEtienne Carriere const char *plat_scmi_clock_get_name(unsigned int agent_id,
125a7a9e3baSEtienne Carriere 				     unsigned int scmi_id);
126a7a9e3baSEtienne Carriere 
127a7a9e3baSEtienne Carriere /*
128a7a9e3baSEtienne Carriere  * Get clock possible rate as an array of frequencies in Hertz.
129a7a9e3baSEtienne Carriere  *
130a7a9e3baSEtienne Carriere  * @agent_id: SCMI agent ID
131a7a9e3baSEtienne Carriere  * @scmi_id: SCMI clock ID
132a7a9e3baSEtienne Carriere  * @rates: If NULL, function returns, else output rates array
133a7a9e3baSEtienne Carriere  * @nb_elts: Array size of @rates.
134a7a9e3baSEtienne Carriere  * Return an SCMI compliant error code
135a7a9e3baSEtienne Carriere  */
136a7a9e3baSEtienne Carriere int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
137a7a9e3baSEtienne Carriere 				    unsigned long *rates, size_t *nb_elts);
138a7a9e3baSEtienne Carriere 
139a7a9e3baSEtienne Carriere /*
140a7a9e3baSEtienne Carriere  * Get clock possible rate as range with regular steps in Hertz
141a7a9e3baSEtienne Carriere  *
142a7a9e3baSEtienne Carriere  * @agent_id: SCMI agent ID
143a7a9e3baSEtienne Carriere  * @scmi_id: SCMI clock ID
144a7a9e3baSEtienne Carriere  * @min_max_step: 3 cell array for min, max and step rate data
145a7a9e3baSEtienne Carriere  * Return an SCMI compliant error code
146a7a9e3baSEtienne Carriere  */
147a7a9e3baSEtienne Carriere int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id,
148a7a9e3baSEtienne Carriere 				      unsigned int scmi_id,
149a7a9e3baSEtienne Carriere 				      unsigned long *min_max_step);
150a7a9e3baSEtienne Carriere 
151a7a9e3baSEtienne Carriere /*
152a7a9e3baSEtienne Carriere  * Get clock rate in Hertz
153a7a9e3baSEtienne Carriere  * @agent_id: SCMI agent ID
154a7a9e3baSEtienne Carriere  * @scmi_id: SCMI clock ID
155a7a9e3baSEtienne Carriere  * Return clock rate or 0 if not supported
156a7a9e3baSEtienne Carriere  */
157a7a9e3baSEtienne Carriere unsigned long plat_scmi_clock_get_rate(unsigned int agent_id,
158a7a9e3baSEtienne Carriere 				       unsigned int scmi_id);
159a7a9e3baSEtienne Carriere 
160a7a9e3baSEtienne Carriere /*
161a7a9e3baSEtienne Carriere  * Set clock rate in Hertz
162a7a9e3baSEtienne Carriere  * @agent_id: SCMI agent ID
163a7a9e3baSEtienne Carriere  * @scmi_id: SCMI clock ID
164a7a9e3baSEtienne Carriere  * @rate: Target clock frequency in Hertz
165a7a9e3baSEtienne Carriere  * Return a compliant SCMI error code
166a7a9e3baSEtienne Carriere  */
167a7a9e3baSEtienne Carriere int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id,
168a7a9e3baSEtienne Carriere 				 unsigned long rate);
169a7a9e3baSEtienne Carriere 
170a7a9e3baSEtienne Carriere /*
171a7a9e3baSEtienne Carriere  * Get clock state (enabled or disabled)
172a7a9e3baSEtienne Carriere  * @agent_id: SCMI agent ID
173a7a9e3baSEtienne Carriere  * @scmi_id: SCMI clock ID
174a7a9e3baSEtienne Carriere  * Return 1 if clock is enabled, 0 if disables, or a negative SCMI error code
175a7a9e3baSEtienne Carriere  */
176a7a9e3baSEtienne Carriere int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id);
177a7a9e3baSEtienne Carriere 
178a7a9e3baSEtienne Carriere /*
179a7a9e3baSEtienne Carriere  * Get clock state (enabled or disabled)
180a7a9e3baSEtienne Carriere  * @agent_id: SCMI agent ID
181a7a9e3baSEtienne Carriere  * @scmi_id: SCMI clock ID
182a7a9e3baSEtienne Carriere  * @enable_not_disable: Enable clock if true, disable clock otherwise
183a7a9e3baSEtienne Carriere  * Return a compliant SCMI error code
184a7a9e3baSEtienne Carriere  */
185a7a9e3baSEtienne Carriere int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id,
186a7a9e3baSEtienne Carriere 				  bool enable_not_disable);
18756a1f10eSEtienne Carriere 
18856a1f10eSEtienne Carriere /* Handlers for SCMI Reset Domain protocol services */
18956a1f10eSEtienne Carriere 
19056a1f10eSEtienne Carriere /*
19156a1f10eSEtienne Carriere  * Return number of reset domains for the agent
19256a1f10eSEtienne Carriere  * @agent_id: SCMI agent ID
19356a1f10eSEtienne Carriere  * Return number of reset domains
19456a1f10eSEtienne Carriere  */
19556a1f10eSEtienne Carriere size_t plat_scmi_rd_count(unsigned int agent_id);
19656a1f10eSEtienne Carriere 
19756a1f10eSEtienne Carriere /*
19856a1f10eSEtienne Carriere  * Get reset domain string ID (aka name)
19956a1f10eSEtienne Carriere  * @agent_id: SCMI agent ID
20056a1f10eSEtienne Carriere  * @scmi_id: SCMI reset domain ID
20156a1f10eSEtienne Carriere  * Return pointer to name or NULL
20256a1f10eSEtienne Carriere  */
20356a1f10eSEtienne Carriere const char *plat_scmi_rd_get_name(unsigned int agent_id, unsigned int scmi_id);
20456a1f10eSEtienne Carriere 
20556a1f10eSEtienne Carriere /*
20656a1f10eSEtienne Carriere  * Perform a reset cycle on a target reset domain
20756a1f10eSEtienne Carriere  * @agent_id: SCMI agent ID
20856a1f10eSEtienne Carriere  * @scmi_id: SCMI reset domain ID
20956a1f10eSEtienne Carriere  * @state: Target reset state (see SCMI specification, 0 means context loss)
21056a1f10eSEtienne Carriere  * Return a compliant SCMI error code
21156a1f10eSEtienne Carriere  */
21256a1f10eSEtienne Carriere int32_t plat_scmi_rd_autonomous(unsigned int agent_id, unsigned int scmi_id,
21356a1f10eSEtienne Carriere 				unsigned int state);
21456a1f10eSEtienne Carriere 
21556a1f10eSEtienne Carriere /*
21656a1f10eSEtienne Carriere  * Assert or deassert target reset domain
21756a1f10eSEtienne Carriere  * @agent_id: SCMI agent ID
21856a1f10eSEtienne Carriere  * @scmi_id: SCMI reset domain ID
21956a1f10eSEtienne Carriere  * @assert_not_deassert: Assert domain if true, otherwise deassert domain
22056a1f10eSEtienne Carriere  * Return a compliant SCMI error code
22156a1f10eSEtienne Carriere  */
22256a1f10eSEtienne Carriere int32_t plat_scmi_rd_set_state(unsigned int agent_id, unsigned int scmi_id,
22356a1f10eSEtienne Carriere 			       bool assert_not_deassert);
22456a1f10eSEtienne Carriere 
225ae8c8068SEtienne Carriere #endif /* SCMI_MSG_H */
226