1 /* 2 * Arm SCP/MCP Software 3 * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 * 7 * Description: 8 * SCMI Clock Management Protocol Support. 9 */ 10 11 #ifndef MOD_SCMI_CLOCK_H 12 #define MOD_SCMI_CLOCK_H 13 14 #include <fwk_id.h> 15 16 #include <mod_clock.h> 17 18 #include <stddef.h> 19 #include <stdint.h> 20 21 /*! 22 * \ingroup GroupModules Modules 23 * \defgroup GroupSCMI_CLOCK SCMI Clock Management Protocol 24 * \{ 25 */ 26 27 /*! 28 * \brief Permission flags governing the ability to use certain SCMI commands to 29 * interact with a clock. 30 * 31 * \details Setting a permission flag for a clock enables the corresponding 32 * functionality for any agent that has visibilty of the clock 33 * through its clock device table. 34 */ 35 enum mod_scmi_clock_permissions { 36 /*! No permissions (at least one must be granted) */ 37 MOD_SCMI_CLOCK_PERM_INVALID = 0, 38 39 /*! The clock's attributes can be queried */ 40 MOD_SCMI_CLOCK_PERM_ATTRIBUTES = (1 << 0), 41 42 /*! The clock's supported rates can be queried */ 43 MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES = (1 << 1), 44 45 /*! The clock's current rate can be queried */ 46 MOD_SCMI_CLOCK_PERM_GET_RATE = (1 << 2), 47 48 /*! The clock can be set to a new rate */ 49 MOD_SCMI_CLOCK_PERM_SET_RATE = (1 << 3), 50 51 /*! The clock can be enabled and disabled */ 52 MOD_SCMI_CLOCK_PERM_SET_CONFIG = (1 << 4), 53 }; 54 55 /*! 56 * \brief Clock device. 57 * 58 * \details Clock device structures are used in per-agent clock device tables. 59 * Each contains an identifier of an element that will be bound to in order 60 * to use the clock device. The permission flags for the clock are applied 61 * to any agent that uses the device configuration in its clock device 62 * table. 63 */ 64 struct mod_scmi_clock_device { 65 /*! 66 * \brief Clock element identifier. 67 * 68 * \details The module that owns the element must implement the Clock API 69 * that is defined by the \c clock module. 70 */ 71 fwk_id_t element_id; 72 73 /*! \brief Startup clock status flag. 74 * 75 * \details State of the clock at startup. If set, it specifies that 76 * this clock starts running. This flag does not affect the actual 77 * state of the clock, but it provides an indication for the initial 78 * internal state map. 79 */ 80 bool starts_enabled; 81 }; 82 83 /*! 84 * \brief Agent descriptor. 85 * 86 * \details Describes an agent that uses the SCMI Clock Management protocol. 87 * Provides a pointer to the agent's clock device table and the number of 88 * devices within the table. 89 */ 90 struct mod_scmi_clock_agent { 91 /*! Pointer to a table of clock devices that are visible to the agent */ 92 const struct mod_scmi_clock_device *device_table; 93 94 /*! 95 * \brief The number of \c mod_scmi_clock_device structures in the table 96 * pointed to by \c device_table. 97 */ 98 uint8_t device_count; 99 }; 100 101 /*! 102 * \brief Module configuration. 103 */ 104 struct mod_scmi_clock_config { 105 /*! Maximum supported number of pending, asynchronous clock rate changes */ 106 uint8_t max_pending_transactions; 107 108 /*! 109 * \brief Pointer to the table of agent descriptors, used to provide 110 * per-agent views of clocks in the system. 111 */ 112 const struct mod_scmi_clock_agent *agent_table; 113 114 /*! Number of agents in ::mod_scmi_clock_config::agent_table */ 115 size_t agent_count; 116 }; 117 118 /*! 119 * \defgroup GroupScmiClockPolicyHandlers Policy Handlers 120 * 121 * \brief SCMI Clock Policy Handlers. 122 * 123 * \details The SCMI policy handlers are weak definitions to allow a platform 124 * to implement a policy appropriate to that platform. The SCMI 125 * clock policy functions may be overridden in the 126 * `product/<platform>/src` directory. 127 * 128 * \note The `rate`/`round_mode`/`state` values may be changed by the policy 129 * handlers. 130 * \note See `product/juno/src/juno_scmi_clock.c` for an example policy 131 * handler. 132 * 133 * \{ 134 */ 135 136 /*! 137 * \brief Policy handler policies. 138 * 139 * \details These values are returned to the message handler by the policy 140 * handlers to determine whether the message handler should continue 141 * processing the message, or whether the request has been rejected. 142 */ 143 enum mod_scmi_clock_policy_status { 144 /*! Do not execute the message handler */ 145 MOD_SCMI_CLOCK_SKIP_MESSAGE_HANDLER, 146 147 /*! Execute the message handler */ 148 MOD_SCMI_CLOCK_EXECUTE_MESSAGE_HANDLER, 149 }; 150 151 /*! 152 * \brief Directive for Policy handler. 153 * 154 * \details These values are passed to the policy handlers to indicate 155 * whether the policy handler is being invoked prior to the operation 156 * processing the message or on completion of the message. If the message 157 * handler has completed it is safe to commit any changes the policy 158 * handler may need to make to any internal state. 159 */ 160 enum mod_scmi_clock_policy_commit { 161 /*! The message handler has not run yet */ 162 MOD_SCMI_CLOCK_PRE_MESSAGE_HANDLER, 163 164 /*! The message handler has completed */ 165 MOD_SCMI_CLOCK_POST_MESSAGE_HANDLER, 166 }; 167 168 /*! 169 * \brief SCMI Clock Set Rate command policy. 170 * 171 * \details This function determines whether the SCMI message handler should 172 * allow or reject a given SCMI Clock Set Rate command. 173 * 174 * The SCMI policy handler is executed before the message handler is 175 * called. The SCMI protocol message handler will only continue if the 176 * policy handler both returns ::FWK_SUCCESS and sets the policy status to 177 * ::MOD_SCMI_CLOCK_EXECUTE_MESSAGE_HANDLER. 178 * 179 * The SCMI policy handlers have default weak implementations that allow a 180 * platform to implement a policy appropriate for that platform. 181 * 182 * \note See `product/juno/src/juno_scmi_clock.c` for an example policy 183 * handler. 184 * 185 * \param[out] policy_status Whether the command should be accepted or not. 186 * \param[in, out] round_mode Rounding operation to perform, if required, to 187 * achieve the given rate. 188 * \param[in, out] rate Desired frequency in hertz. 189 * \param[in] policy_commit Whether the message handler has completed or not. 190 * \param[in] service_id Identifier of the agent making the request. 191 * \param[in] clock_dev_id SCMI clock device identifier. 192 * 193 * \retval ::FWK_SUCCESS The operation succeeded. 194 * 195 * \return Status code representing the result of the operation. 196 */ 197 int mod_scmi_clock_rate_set_policy( 198 enum mod_scmi_clock_policy_status *policy_status, 199 enum mod_clock_round_mode *round_mode, 200 uint64_t *rate, 201 enum mod_scmi_clock_policy_commit policy_commit, 202 fwk_id_t service_id, 203 uint32_t clock_dev_id); 204 205 /*! 206 * \brief SCMI Clock Set Config command policy. 207 * 208 * \details This function determines whether the SCMI message handler should 209 * allow or reject a given SCMI Clock Set Config command. 210 * 211 * The SCMI policy handler is executed before the message handler is 212 * called. The SCMI protocol message handler will only continue if the 213 * policy handler both returns ::FWK_SUCCESS and sets the policy status to 214 * ::MOD_SCMI_CLOCK_EXECUTE_MESSAGE_HANDLER. 215 * 216 * \param[out] policy_status Whether the command should be accepted or not. 217 * \param[in, out] state Pointer to one of the valid clock states. 218 * \param[in] policy_commit Whether the message handler has completed or not. 219 * \param[in] service_id Identifier of the agent making the request. 220 * \param[in] clock_dev_id Identifier of the clock. 221 * 222 * \retval ::FWK_SUCCESS The operation succeeded. 223 * 224 * \return Status code representing the result of the operation. 225 */ 226 int mod_scmi_clock_config_set_policy( 227 enum mod_scmi_clock_policy_status *policy_status, 228 enum mod_clock_state *state, 229 enum mod_scmi_clock_policy_commit policy_commit, 230 fwk_id_t service_id, 231 uint32_t clock_dev_id); 232 233 /*! 234 * \} 235 */ 236 237 /*! 238 * \} 239 */ 240 241 #endif /* MOD_SCMI_CLOCK_H */ 242