1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef MOD_DVFS_H
9 #define MOD_DVFS_H
10 
11 #include <fwk_id.h>
12 #include <fwk_macros.h>
13 #include <fwk_module_idx.h>
14 
15 #include <stddef.h>
16 #include <stdint.h>
17 
18 /*!
19  * \ingroup GroupModules
20  * \defgroup GroupDvfs Dynamic Voltage and Frequency Scaling (DVFS)
21  * \{
22  */
23 
24 /*!
25  * \defgroup GroupDvfsTypes Types
26  * \{
27  */
28 
29 /*!
30  * \brief Operating Performance Point (OPP).
31  */
32 struct mod_dvfs_opp {
33     uint32_t level; /*!< Level value of the OPP */
34     uint32_t voltage; /*!< Power supply voltage in millivolts (mV) */
35     uint32_t frequency; /*!< Clock rate in Hertz (Hz) */
36     uint32_t power; /*!< Power draw in milliwatts (mW) */
37 };
38 
39 /*!
40  * \}
41  */
42 
43 /*!
44  * \defgroup GroupDvfsConfig Configuration
45  * \{
46  */
47 
48 /*!
49  * \brief Domain configuration.
50  */
51 struct mod_dvfs_domain_config {
52     /*!
53      * \brief Power supply identifier.
54      *
55      * \warning This identifier must refer to an element of the \c psu module.
56      */
57     fwk_id_t psu_id;
58 
59     /*!
60      * \brief Clock identifier.
61      *
62      * \warning This identifier must refer to an element of the \c clock module.
63      */
64     fwk_id_t clock_id;
65 
66     /*!
67      * \brief Alarm identifier.
68      *
69      * \warning This identifier must refer to an alarm of the \c timer module.
70      */
71     fwk_id_t alarm_id;
72 
73     /*! Delay in milliseconds before retrying a request */
74     uint16_t retry_ms;
75 
76     /*! Worst-case transition latency in microseconds */
77     uint16_t latency;
78 
79     /*! Sustained operating point index */
80     size_t sustained_idx;
81 
82     /*!
83      * \brief Operating points.
84      *
85      * \note The frequencies and levels of these operating points must be in
86      *      ascending order.
87      */
88     struct mod_dvfs_opp *opps;
89 };
90 
91 /*!
92  * \}
93  */
94 
95 /*!
96  * \defgroup GroupDvfsApis APIs
97  * \{
98  */
99 
100 /*!
101  * \brief Domain API.
102  */
103 struct mod_dvfs_domain_api {
104     /*!
105      * \brief Get the current operating point of a domain.
106      *
107      * \param domain_id Element identifier of the domain.
108      * \param [out] opp Current operating point.
109      */
110     int (*get_current_opp)(fwk_id_t domain_id, struct mod_dvfs_opp *opp);
111 
112     /*!
113      * \brief Get the sustained operating point of a domain.
114      *
115      * \param domain_id Element identifier of the domain.
116      * \param [out] opp Sustained operating point.
117      */
118     int (*get_sustained_opp)(
119         fwk_id_t domain_id,
120         struct mod_dvfs_opp *opp);
121 
122     /*!
123      * \brief Get an operating point from its index.
124      *
125      * \param domain_id Element identifier of the domain.
126      * \param n Index of the operating point to retrieve.
127      * \param [out] opp Requested operating point.
128      */
129     int (*get_nth_opp)(
130         fwk_id_t domain_id,
131         size_t n,
132         struct mod_dvfs_opp *opp);
133 
134     /*!
135      * \brief Get the number of operating points of a domain.
136      *
137      * \param domain_id Element identifier of the domain.
138      * \param [out] opp_count Number of operating points.
139      */
140     int (*get_opp_count)(fwk_id_t domain_id, size_t *opp_count);
141 
142     /*!
143      * \brief Get the level id for the given level.
144      *
145      * \param domain_id Element identifier of the domain.
146      * \param level Requested level.
147      * \param [out] level id inside the OPP table.
148      */
149     int (*get_level_id)(fwk_id_t domain_id, uint32_t level, size_t *level_id);
150 
151     /*!
152      * \brief Get the worst-case transition latency of a domain.
153      *
154      * \param domain_id Element identifier of the domain.
155      * \param [out] latency Worst-case transition latency.
156      */
157     int (*get_latency)(fwk_id_t domain_id, uint16_t *latency);
158 
159     /*!
160      * \brief Set the level of a domain.
161      *
162      * \param domain_id Element identifier of the domain.
163      * \param cookie Context-specific value.
164      * \param level Requested level.
165      */
166     int (*set_level)(fwk_id_t domain_id, uintptr_t cookie, uint32_t level);
167 };
168 
169 /*!
170  * \}
171  */
172 
173 /*!
174  * \defgroup GroupDvfsEvents Events
175  * \{
176  */
177 
178 /*!
179  * \brief <tt>Get current OPP </tt> event response parameters.
180  */
181 struct mod_dvfs_params_response {
182     /*! Event response status */
183     int status;
184 
185     /*! Event response frequency */
186     uint32_t performance_level;
187 };
188 
189 /*!
190  * \}
191  */
192 /*!
193  * \defgroup GroupDvfsIds Identifiers
194  * \{
195  */
196 
197 /*!
198  * \brief API indices.
199  */
200 enum mod_dvfs_api_idx {
201     MOD_DVFS_API_IDX_DVFS, /*!< API index for mod_dvfs_api_id_dvfs() */
202     MOD_DVFS_API_IDX_COUNT /*!< Number of defined APIs */
203 };
204 
205 /*! Module API identifier */
206 static const fwk_id_t mod_dvfs_api_id_dvfs =
207     FWK_ID_API_INIT(FWK_MODULE_IDX_DVFS, MOD_DVFS_API_IDX_DVFS);
208 
209 /*!
210  * \brief Event indices.
211  */
212 enum mod_dvfs_event_idx {
213     MOD_DVFS_EVENT_IDX_SET, /*!< Set level/limits */
214     MOD_DVFS_EVENT_IDX_GET_OPP, /*!< Get Operating Performance Point */
215     MOD_DVFS_EVENT_IDX_COUNT, /*!< event count */
216 };
217 
218 /*! <tt>Set operating point/limits</tt> event identifier */
219 static const fwk_id_t mod_dvfs_event_id_set =
220     FWK_ID_EVENT_INIT(FWK_MODULE_IDX_DVFS, MOD_DVFS_EVENT_IDX_SET);
221 
222 /*! <tt>Get current OPP </tt> event identifier */
223 static const fwk_id_t mod_dvfs_event_id_get_opp =
224     FWK_ID_EVENT_INIT(FWK_MODULE_IDX_DVFS, MOD_DVFS_EVENT_IDX_GET_OPP);
225 
226 /*!
227  * \}
228  */
229 
230 /*!
231  * \}
232  */
233 
234 #endif /* MOD_DVFS_H */
235