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