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