erofs: reduntant assignment in __erofs_get_meta_page()
[linux/fpc-iii.git] / Documentation / power / opp.rst
blobb3cf1def9deec0e6eee02e26d5e3cf1bd660b1e8
1 ==========================================
2 Operating Performance Points (OPP) Library
3 ==========================================
5 (C) 2009-2010 Nishanth Menon <nm@ti.com>, Texas Instruments Incorporated
7 .. Contents
9   1. Introduction
10   2. Initial OPP List Registration
11   3. OPP Search Functions
12   4. OPP Availability Control Functions
13   5. OPP Data Retrieval Functions
14   6. Data Structures
16 1. Introduction
17 ===============
19 1.1 What is an Operating Performance Point (OPP)?
20 -------------------------------------------------
22 Complex SoCs of today consists of a multiple sub-modules working in conjunction.
23 In an operational system executing varied use cases, not all modules in the SoC
24 need to function at their highest performing frequency all the time. To
25 facilitate this, sub-modules in a SoC are grouped into domains, allowing some
26 domains to run at lower voltage and frequency while other domains run at
27 voltage/frequency pairs that are higher.
29 The set of discrete tuples consisting of frequency and voltage pairs that
30 the device will support per domain are called Operating Performance Points or
31 OPPs.
33 As an example:
35 Let us consider an MPU device which supports the following:
36 {300MHz at minimum voltage of 1V}, {800MHz at minimum voltage of 1.2V},
37 {1GHz at minimum voltage of 1.3V}
39 We can represent these as three OPPs as the following {Hz, uV} tuples:
41 - {300000000, 1000000}
42 - {800000000, 1200000}
43 - {1000000000, 1300000}
45 1.2 Operating Performance Points Library
46 ----------------------------------------
48 OPP library provides a set of helper functions to organize and query the OPP
49 information. The library is located in drivers/base/power/opp.c and the header
50 is located in include/linux/pm_opp.h. OPP library can be enabled by enabling
51 CONFIG_PM_OPP from power management menuconfig menu. OPP library depends on
52 CONFIG_PM as certain SoCs such as Texas Instrument's OMAP framework allows to
53 optionally boot at a certain OPP without needing cpufreq.
55 Typical usage of the OPP library is as follows::
57  (users)        -> registers a set of default OPPs              -> (library)
58  SoC framework  -> modifies on required cases certain OPPs      -> OPP layer
59                 -> queries to search/retrieve information       ->
61 OPP layer expects each domain to be represented by a unique device pointer. SoC
62 framework registers a set of initial OPPs per device with the OPP layer. This
63 list is expected to be an optimally small number typically around 5 per device.
64 This initial list contains a set of OPPs that the framework expects to be safely
65 enabled by default in the system.
67 Note on OPP Availability
68 ^^^^^^^^^^^^^^^^^^^^^^^^
70 As the system proceeds to operate, SoC framework may choose to make certain
71 OPPs available or not available on each device based on various external
72 factors. Example usage: Thermal management or other exceptional situations where
73 SoC framework might choose to disable a higher frequency OPP to safely continue
74 operations until that OPP could be re-enabled if possible.
76 OPP library facilitates this concept in it's implementation. The following
77 operational functions operate only on available opps:
78 opp_find_freq_{ceil, floor}, dev_pm_opp_get_voltage, dev_pm_opp_get_freq, dev_pm_opp_get_opp_count
80 dev_pm_opp_find_freq_exact is meant to be used to find the opp pointer which can then
81 be used for dev_pm_opp_enable/disable functions to make an opp available as required.
83 WARNING: Users of OPP library should refresh their availability count using
84 get_opp_count if dev_pm_opp_enable/disable functions are invoked for a device, the
85 exact mechanism to trigger these or the notification mechanism to other
86 dependent subsystems such as cpufreq are left to the discretion of the SoC
87 specific framework which uses the OPP library. Similar care needs to be taken
88 care to refresh the cpufreq table in cases of these operations.
90 2. Initial OPP List Registration
91 ================================
92 The SoC implementation calls dev_pm_opp_add function iteratively to add OPPs per
93 device. It is expected that the SoC framework will register the OPP entries
94 optimally- typical numbers range to be less than 5. The list generated by
95 registering the OPPs is maintained by OPP library throughout the device
96 operation. The SoC framework can subsequently control the availability of the
97 OPPs dynamically using the dev_pm_opp_enable / disable functions.
99 dev_pm_opp_add
100         Add a new OPP for a specific domain represented by the device pointer.
101         The OPP is defined using the frequency and voltage. Once added, the OPP
102         is assumed to be available and control of it's availability can be done
103         with the dev_pm_opp_enable/disable functions. OPP library internally stores
104         and manages this information in the opp struct. This function may be
105         used by SoC framework to define a optimal list as per the demands of
106         SoC usage environment.
108         WARNING:
109                 Do not use this function in interrupt context.
111         Example::
113          soc_pm_init()
114          {
115                 /* Do things */
116                 r = dev_pm_opp_add(mpu_dev, 1000000, 900000);
117                 if (!r) {
118                         pr_err("%s: unable to register mpu opp(%d)\n", r);
119                         goto no_cpufreq;
120                 }
121                 /* Do cpufreq things */
122          no_cpufreq:
123                 /* Do remaining things */
124          }
126 3. OPP Search Functions
127 =======================
128 High level framework such as cpufreq operates on frequencies. To map the
129 frequency back to the corresponding OPP, OPP library provides handy functions
130 to search the OPP list that OPP library internally manages. These search
131 functions return the matching pointer representing the opp if a match is
132 found, else returns error. These errors are expected to be handled by standard
133 error checks such as IS_ERR() and appropriate actions taken by the caller.
135 Callers of these functions shall call dev_pm_opp_put() after they have used the
136 OPP. Otherwise the memory for the OPP will never get freed and result in
137 memleak.
139 dev_pm_opp_find_freq_exact
140         Search for an OPP based on an *exact* frequency and
141         availability. This function is especially useful to enable an OPP which
142         is not available by default.
143         Example: In a case when SoC framework detects a situation where a
144         higher frequency could be made available, it can use this function to
145         find the OPP prior to call the dev_pm_opp_enable to actually make
146         it available::
148          opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false);
149          dev_pm_opp_put(opp);
150          /* dont operate on the pointer.. just do a sanity check.. */
151          if (IS_ERR(opp)) {
152                 pr_err("frequency not disabled!\n");
153                 /* trigger appropriate actions.. */
154          } else {
155                 dev_pm_opp_enable(dev,1000000000);
156          }
158         NOTE:
159           This is the only search function that operates on OPPs which are
160           not available.
162 dev_pm_opp_find_freq_floor
163         Search for an available OPP which is *at most* the
164         provided frequency. This function is useful while searching for a lesser
165         match OR operating on OPP information in the order of decreasing
166         frequency.
167         Example: To find the highest opp for a device::
169          freq = ULONG_MAX;
170          opp = dev_pm_opp_find_freq_floor(dev, &freq);
171          dev_pm_opp_put(opp);
173 dev_pm_opp_find_freq_ceil
174         Search for an available OPP which is *at least* the
175         provided frequency. This function is useful while searching for a
176         higher match OR operating on OPP information in the order of increasing
177         frequency.
178         Example 1: To find the lowest opp for a device::
180          freq = 0;
181          opp = dev_pm_opp_find_freq_ceil(dev, &freq);
182          dev_pm_opp_put(opp);
184         Example 2: A simplified implementation of a SoC cpufreq_driver->target::
186          soc_cpufreq_target(..)
187          {
188                 /* Do stuff like policy checks etc. */
189                 /* Find the best frequency match for the req */
190                 opp = dev_pm_opp_find_freq_ceil(dev, &freq);
191                 dev_pm_opp_put(opp);
192                 if (!IS_ERR(opp))
193                         soc_switch_to_freq_voltage(freq);
194                 else
195                         /* do something when we can't satisfy the req */
196                 /* do other stuff */
197          }
199 4. OPP Availability Control Functions
200 =====================================
201 A default OPP list registered with the OPP library may not cater to all possible
202 situation. The OPP library provides a set of functions to modify the
203 availability of a OPP within the OPP list. This allows SoC frameworks to have
204 fine grained dynamic control of which sets of OPPs are operationally available.
205 These functions are intended to *temporarily* remove an OPP in conditions such
206 as thermal considerations (e.g. don't use OPPx until the temperature drops).
208 WARNING:
209         Do not use these functions in interrupt context.
211 dev_pm_opp_enable
212         Make a OPP available for operation.
213         Example: Lets say that 1GHz OPP is to be made available only if the
214         SoC temperature is lower than a certain threshold. The SoC framework
215         implementation might choose to do something as follows::
217          if (cur_temp < temp_low_thresh) {
218                 /* Enable 1GHz if it was disabled */
219                 opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false);
220                 dev_pm_opp_put(opp);
221                 /* just error check */
222                 if (!IS_ERR(opp))
223                         ret = dev_pm_opp_enable(dev, 1000000000);
224                 else
225                         goto try_something_else;
226          }
228 dev_pm_opp_disable
229         Make an OPP to be not available for operation
230         Example: Lets say that 1GHz OPP is to be disabled if the temperature
231         exceeds a threshold value. The SoC framework implementation might
232         choose to do something as follows::
234          if (cur_temp > temp_high_thresh) {
235                 /* Disable 1GHz if it was enabled */
236                 opp = dev_pm_opp_find_freq_exact(dev, 1000000000, true);
237                 dev_pm_opp_put(opp);
238                 /* just error check */
239                 if (!IS_ERR(opp))
240                         ret = dev_pm_opp_disable(dev, 1000000000);
241                 else
242                         goto try_something_else;
243          }
245 5. OPP Data Retrieval Functions
246 ===============================
247 Since OPP library abstracts away the OPP information, a set of functions to pull
248 information from the OPP structure is necessary. Once an OPP pointer is
249 retrieved using the search functions, the following functions can be used by SoC
250 framework to retrieve the information represented inside the OPP layer.
252 dev_pm_opp_get_voltage
253         Retrieve the voltage represented by the opp pointer.
254         Example: At a cpufreq transition to a different frequency, SoC
255         framework requires to set the voltage represented by the OPP using
256         the regulator framework to the Power Management chip providing the
257         voltage::
259          soc_switch_to_freq_voltage(freq)
260          {
261                 /* do things */
262                 opp = dev_pm_opp_find_freq_ceil(dev, &freq);
263                 v = dev_pm_opp_get_voltage(opp);
264                 dev_pm_opp_put(opp);
265                 if (v)
266                         regulator_set_voltage(.., v);
267                 /* do other things */
268          }
270 dev_pm_opp_get_freq
271         Retrieve the freq represented by the opp pointer.
272         Example: Lets say the SoC framework uses a couple of helper functions
273         we could pass opp pointers instead of doing additional parameters to
274         handle quiet a bit of data parameters::
276          soc_cpufreq_target(..)
277          {
278                 /* do things.. */
279                  max_freq = ULONG_MAX;
280                  max_opp = dev_pm_opp_find_freq_floor(dev,&max_freq);
281                  requested_opp = dev_pm_opp_find_freq_ceil(dev,&freq);
282                  if (!IS_ERR(max_opp) && !IS_ERR(requested_opp))
283                         r = soc_test_validity(max_opp, requested_opp);
284                  dev_pm_opp_put(max_opp);
285                  dev_pm_opp_put(requested_opp);
286                 /* do other things */
287          }
288          soc_test_validity(..)
289          {
290                  if(dev_pm_opp_get_voltage(max_opp) < dev_pm_opp_get_voltage(requested_opp))
291                          return -EINVAL;
292                  if(dev_pm_opp_get_freq(max_opp) < dev_pm_opp_get_freq(requested_opp))
293                          return -EINVAL;
294                 /* do things.. */
295          }
297 dev_pm_opp_get_opp_count
298         Retrieve the number of available opps for a device
299         Example: Lets say a co-processor in the SoC needs to know the available
300         frequencies in a table, the main processor can notify as following::
302          soc_notify_coproc_available_frequencies()
303          {
304                 /* Do things */
305                 num_available = dev_pm_opp_get_opp_count(dev);
306                 speeds = kzalloc(sizeof(u32) * num_available, GFP_KERNEL);
307                 /* populate the table in increasing order */
308                 freq = 0;
309                 while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) {
310                         speeds[i] = freq;
311                         freq++;
312                         i++;
313                         dev_pm_opp_put(opp);
314                 }
316                 soc_notify_coproc(AVAILABLE_FREQs, speeds, num_available);
317                 /* Do other things */
318          }
320 6. Data Structures
321 ==================
322 Typically an SoC contains multiple voltage domains which are variable. Each
323 domain is represented by a device pointer. The relationship to OPP can be
324 represented as follows::
326   SoC
327    |- device 1
328    |    |- opp 1 (availability, freq, voltage)
329    |    |- opp 2 ..
330    ...  ...
331    |    `- opp n ..
332    |- device 2
333    ...
334    `- device m
336 OPP library maintains a internal list that the SoC framework populates and
337 accessed by various functions as described above. However, the structures
338 representing the actual OPPs and domains are internal to the OPP library itself
339 to allow for suitable abstraction reusable across systems.
341 struct dev_pm_opp
342         The internal data structure of OPP library which is used to
343         represent an OPP. In addition to the freq, voltage, availability
344         information, it also contains internal book keeping information required
345         for the OPP library to operate on.  Pointer to this structure is
346         provided back to the users such as SoC framework to be used as a
347         identifier for OPP in the interactions with OPP layer.
349         WARNING:
350           The struct dev_pm_opp pointer should not be parsed or modified by the
351           users. The defaults of for an instance is populated by
352           dev_pm_opp_add, but the availability of the OPP can be modified
353           by dev_pm_opp_enable/disable functions.
355 struct device
356         This is used to identify a domain to the OPP layer. The
357         nature of the device and it's implementation is left to the user of
358         OPP library such as the SoC framework.
360 Overall, in a simplistic view, the data structure operations is represented as
361 following::
363   Initialization / modification:
364               +-----+        /- dev_pm_opp_enable
365   dev_pm_opp_add --> | opp | <-------
366     |         +-----+        \- dev_pm_opp_disable
367     \-------> domain_info(device)
369   Search functions:
370                /-- dev_pm_opp_find_freq_ceil  ---\   +-----+
371   domain_info<---- dev_pm_opp_find_freq_exact -----> | opp |
372                \-- dev_pm_opp_find_freq_floor ---/   +-----+
374   Retrieval functions:
375   +-----+     /- dev_pm_opp_get_voltage
376   | opp | <---
377   +-----+     \- dev_pm_opp_get_freq
379   domain_info <- dev_pm_opp_get_opp_count