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 * @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 * @channel_id: SCMI channel ID the SMT belongs to 60 */ 61 void scmi_smt_fastcall_smc_entry(unsigned int channel_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 * @channel_id: SCMI channel ID the SMT belongs to 70 */ 71 void scmi_smt_interrupt_entry(unsigned int channel_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 * @channel_id: SCMI channel ID the SMT belongs to 80 */ 81 void scmi_smt_threaded_entry(unsigned int channel_id); 82 83 /* Platform callback functions */ 84 85 /* 86 * Return the SCMI channel related to an agent 87 * @channel_id: SCMI channel ID 88 * Return a pointer to channel on success, NULL otherwise 89 */ 90 struct scmi_msg_channel *plat_scmi_get_channel(unsigned int channel_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 channel 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 * @channel_id: SCMI channel ID 103 * Return a pointer to a null terminated array supported protocol IDs. 104 */ 105 const uint8_t *plat_scmi_protocol_list(unsigned int channel_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 * @channel_id: SCMI channel ID 118 * Return number of clock controllers 119 */ 120 size_t plat_scmi_clock_count(unsigned int channel_id); 121 122 /* 123 * Get clock controller string ID (aka name) 124 * @channel_id: SCMI channel 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 channel_id, 129 unsigned int scmi_id); 130 131 /* 132 * Get clock possible rate as an array of frequencies in Hertz. 133 * 134 * @channel_id: SCMI channel ID 135 * @scmi_id: SCMI clock ID 136 * @start_index: Requested start index for the exposed rates array 137 * @rates: If NULL, function returns, else output 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 channel_id, 142 unsigned int scmi_id, size_t start_index, 143 unsigned long *rates, size_t *nb_elts); 144 145 /* 146 * Get clock possible rate as range with regular steps in Hertz 147 * 148 * @channel_id: SCMI channel 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 channel_id, 154 unsigned int scmi_id, 155 unsigned long *min_max_step); 156 157 /* 158 * Get clock rate in Hertz 159 * @channel_id: SCMI channel 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 channel_id, 164 unsigned int scmi_id); 165 166 /* 167 * Set clock rate in Hertz 168 * @channel_id: SCMI channel 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 channel_id, unsigned int scmi_id, 174 unsigned long rate); 175 176 /* 177 * Get clock state (enabled or disabled) 178 * @channel_id: SCMI channel 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 channel_id, 183 unsigned int scmi_id); 184 185 /* 186 * Get clock state (enabled or disabled) 187 * @channel_id: SCMI channel ID 188 * @scmi_id: SCMI clock ID 189 * @enable_not_disable: Enable clock if true, disable clock otherwise 190 * Return a compliant SCMI error code 191 */ 192 int32_t plat_scmi_clock_set_state(unsigned int channel_id, unsigned int scmi_id, 193 bool enable_not_disable); 194 195 /* Handlers for SCMI Reset Domain protocol services */ 196 197 /* 198 * Return number of reset domains for the agent 199 * @channel_id: SCMI channel ID 200 * Return number of reset domains 201 */ 202 size_t plat_scmi_rd_count(unsigned int channel_id); 203 204 /* 205 * Get reset domain string ID (aka name) 206 * @channel_id: SCMI channel ID 207 * @scmi_id: SCMI reset domain ID 208 * Return pointer to name or NULL 209 */ 210 const char *plat_scmi_rd_get_name(unsigned int channel_id, 211 unsigned int scmi_id); 212 213 /* 214 * Perform a reset cycle on a target reset domain 215 * @channel_id: SCMI channel ID 216 * @scmi_id: SCMI reset domain ID 217 * @state: Target reset state (see SCMI specification, 0 means context loss) 218 * Return a compliant SCMI error code 219 */ 220 int32_t plat_scmi_rd_autonomous(unsigned int channel_id, unsigned int scmi_id, 221 unsigned int state); 222 223 /* 224 * Assert or deassert target reset domain 225 * @channel_id: SCMI channel ID 226 * @scmi_id: SCMI reset domain ID 227 * @assert_not_deassert: Assert domain if true, otherwise deassert domain 228 * Return a compliant SCMI error code 229 */ 230 int32_t plat_scmi_rd_set_state(unsigned int channel_id, unsigned int scmi_id, 231 bool assert_not_deassert); 232 233 /* Handlers for SCMI Voltage Domain protocol services */ 234 235 /* 236 * Return number of voltage domain for an agent 237 * @channel_id: SCMI channel ID 238 * Return number of voltage domains 239 */ 240 size_t plat_scmi_voltd_count(unsigned int channel_id); 241 242 /* 243 * Get clock controller string ID (aka name) 244 * @channel_id: SCMI channel ID 245 * @scmi_id: SCMI voltage domain ID 246 * Return pointer to name or NULL 247 */ 248 const char *plat_scmi_voltd_get_name(unsigned int channel_id, 249 unsigned int scmi_id); 250 251 /* 252 * Get voltage domain possible levels as an array of voltages in microvolt. 253 * 254 * @channel_id: SCMI channel ID 255 * @scmi_id: SCMI voltage domain ID 256 * @start_index: Level index to start from. 257 * @levels: If NULL, function returns, else output rates array 258 * @nb_elts: Array size of @levels. 259 * Return an SCMI compliant error code 260 */ 261 int32_t plat_scmi_voltd_levels_array(unsigned int channel_id, 262 unsigned int scmi_id, size_t start_index, 263 long *levels, size_t *nb_elts); 264 265 /* 266 * Get voltage domain possible levels as range with regular steps in microvolt 267 * 268 * @channel_id: SCMI channel ID 269 * @scmi_id: SCMI voltage domain ID 270 * @min_max_step: 3 cell array for min, max and step voltage data 271 * Return an SCMI compliant error code 272 */ 273 int32_t plat_scmi_voltd_levels_by_step(unsigned int channel_id, 274 unsigned int scmi_id, 275 long *min_max_step); 276 277 /* 278 * Get current voltage domain level in microvolt 279 * @channel_id: SCMI channel ID 280 * @scmi_id: SCMI voltage domain ID 281 * Return clock rate or 0 if not supported 282 */ 283 long plat_scmi_voltd_get_level(unsigned int channel_id, unsigned int scmi_id); 284 285 /* 286 * Set voltage domain level voltage domain 287 * @channel_id: SCMI channel ID 288 * @scmi_id: SCMI clock ID 289 * @level: Target voltage domain level in microvolt 290 * Return a compliant SCMI error code 291 */ 292 int32_t plat_scmi_voltd_set_level(unsigned int channel_id, unsigned int scmi_id, 293 long level); 294 295 /* 296 * Get voltage domain state configuration (enabled or disabled) 297 * @channel_id: SCMI channel ID 298 * @scmi_id: SCMI voltage domain ID 299 * @config: output state configuration value SCMI_VOLTAGE_DOMAIN_CONFIG_* 300 * Return a compliant SCMI error code 301 */ 302 int32_t plat_scmi_voltd_get_config(unsigned int channel_id, 303 unsigned int scmi_id, uint32_t *config); 304 305 /* 306 * Get voltage domain state configuration (enabled or disabled) 307 * @channel_id: SCMI channel ID 308 * @scmi_id: SCMI voltage domain ID 309 * @config: Target state configuration value SCMI_VOLTAGE_DOMAIN_CONFIG_* 310 * Return a compliant SCMI error code 311 */ 312 int32_t plat_scmi_voltd_set_config(unsigned int channel_id, 313 unsigned int scmi_id, uint32_t config); 314 315 #endif /* SCMI_MSG_H */ 316