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