diff options
Diffstat (limited to 'Documentation/power')
-rw-r--r-- | Documentation/power/00-INDEX | 2 | ||||
-rw-r--r-- | Documentation/power/opp.txt | 375 |
2 files changed, 377 insertions, 0 deletions
diff --git a/Documentation/power/00-INDEX b/Documentation/power/00-INDEX index fb742c213c9e..45e9d4a91284 100644 --- a/Documentation/power/00-INDEX +++ b/Documentation/power/00-INDEX | |||
@@ -14,6 +14,8 @@ interface.txt | |||
14 | - Power management user interface in /sys/power | 14 | - Power management user interface in /sys/power |
15 | notifiers.txt | 15 | notifiers.txt |
16 | - Registering suspend notifiers in device drivers | 16 | - Registering suspend notifiers in device drivers |
17 | opp.txt | ||
18 | - Operating Performance Point library | ||
17 | pci.txt | 19 | pci.txt |
18 | - How the PCI Subsystem Does Power Management | 20 | - How the PCI Subsystem Does Power Management |
19 | pm_qos_interface.txt | 21 | pm_qos_interface.txt |
diff --git a/Documentation/power/opp.txt b/Documentation/power/opp.txt new file mode 100644 index 000000000000..44d87ad3cea9 --- /dev/null +++ b/Documentation/power/opp.txt | |||
@@ -0,0 +1,375 @@ | |||
1 | *=============* | ||
2 | * OPP Library * | ||
3 | *=============* | ||
4 | |||
5 | (C) 2009-2010 Nishanth Menon <nm@ti.com>, Texas Instruments Incorporated | ||
6 | |||
7 | Contents | ||
8 | -------- | ||
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. Cpufreq Table Generation | ||
15 | 7. Data Structures | ||
16 | |||
17 | 1. Introduction | ||
18 | =============== | ||
19 | Complex SoCs of today consists of a multiple sub-modules working in conjunction. | ||
20 | In an operational system executing varied use cases, not all modules in the SoC | ||
21 | need to function at their highest performing frequency all the time. To | ||
22 | facilitate this, sub-modules in a SoC are grouped into domains, allowing some | ||
23 | domains to run at lower voltage and frequency while other domains are loaded | ||
24 | more. The set of discrete tuples consisting of frequency and voltage pairs that | ||
25 | the device will support per domain are called Operating Performance Points or | ||
26 | OPPs. | ||
27 | |||
28 | OPP library provides a set of helper functions to organize and query the OPP | ||
29 | information. The library is located in drivers/base/power/opp.c and the header | ||
30 | is located in include/linux/opp.h. OPP library can be enabled by enabling | ||
31 | CONFIG_PM_OPP from power management menuconfig menu. OPP library depends on | ||
32 | CONFIG_PM as certain SoCs such as Texas Instrument's OMAP framework allows to | ||
33 | optionally boot at a certain OPP without needing cpufreq. | ||
34 | |||
35 | Typical usage of the OPP library is as follows: | ||
36 | (users) -> registers a set of default OPPs -> (library) | ||
37 | SoC framework -> modifies on required cases certain OPPs -> OPP layer | ||
38 | -> queries to search/retrieve information -> | ||
39 | |||
40 | OPP layer expects each domain to be represented by a unique device pointer. SoC | ||
41 | framework registers a set of initial OPPs per device with the OPP layer. This | ||
42 | list is expected to be an optimally small number typically around 5 per device. | ||
43 | This initial list contains a set of OPPs that the framework expects to be safely | ||
44 | enabled by default in the system. | ||
45 | |||
46 | Note on OPP Availability: | ||
47 | ------------------------ | ||
48 | As the system proceeds to operate, SoC framework may choose to make certain | ||
49 | OPPs available or not available on each device based on various external | ||
50 | factors. Example usage: Thermal management or other exceptional situations where | ||
51 | SoC framework might choose to disable a higher frequency OPP to safely continue | ||
52 | operations until that OPP could be re-enabled if possible. | ||
53 | |||
54 | OPP library facilitates this concept in it's implementation. The following | ||
55 | operational functions operate only on available opps: | ||
56 | opp_find_freq_{ceil, floor}, opp_get_voltage, opp_get_freq, opp_get_opp_count | ||
57 | and opp_init_cpufreq_table | ||
58 | |||
59 | opp_find_freq_exact is meant to be used to find the opp pointer which can then | ||
60 | be used for opp_enable/disable functions to make an opp available as required. | ||
61 | |||
62 | WARNING: Users of OPP library should refresh their availability count using | ||
63 | get_opp_count if opp_enable/disable functions are invoked for a device, the | ||
64 | exact mechanism to trigger these or the notification mechanism to other | ||
65 | dependent subsystems such as cpufreq are left to the discretion of the SoC | ||
66 | specific framework which uses the OPP library. Similar care needs to be taken | ||
67 | care to refresh the cpufreq table in cases of these operations. | ||
68 | |||
69 | WARNING on OPP List locking mechanism: | ||
70 | ------------------------------------------------- | ||
71 | OPP library uses RCU for exclusivity. RCU allows the query functions to operate | ||
72 | in multiple contexts and this synchronization mechanism is optimal for a read | ||
73 | intensive operations on data structure as the OPP library caters to. | ||
74 | |||
75 | To ensure that the data retrieved are sane, the users such as SoC framework | ||
76 | should ensure that the section of code operating on OPP queries are locked | ||
77 | using RCU read locks. The opp_find_freq_{exact,ceil,floor}, | ||
78 | opp_get_{voltage, freq, opp_count} fall into this category. | ||
79 | |||
80 | opp_{add,enable,disable} are updaters which use mutex and implement it's own | ||
81 | RCU locking mechanisms. opp_init_cpufreq_table acts as an updater and uses | ||
82 | mutex to implment RCU updater strategy. These functions should *NOT* be called | ||
83 | under RCU locks and other contexts that prevent blocking functions in RCU or | ||
84 | mutex operations from working. | ||
85 | |||
86 | 2. Initial OPP List Registration | ||
87 | ================================ | ||
88 | The SoC implementation calls opp_add function iteratively to add OPPs per | ||
89 | device. It is expected that the SoC framework will register the OPP entries | ||
90 | optimally- typical numbers range to be less than 5. The list generated by | ||
91 | registering the OPPs is maintained by OPP library throughout the device | ||
92 | operation. The SoC framework can subsequently control the availability of the | ||
93 | OPPs dynamically using the opp_enable / disable functions. | ||
94 | |||
95 | opp_add - Add a new OPP for a specific domain represented by the device pointer. | ||
96 | The OPP is defined using the frequency and voltage. Once added, the OPP | ||
97 | is assumed to be available and control of it's availability can be done | ||
98 | with the opp_enable/disable functions. OPP library internally stores | ||
99 | and manages this information in the opp struct. This function may be | ||
100 | used by SoC framework to define a optimal list as per the demands of | ||
101 | SoC usage environment. | ||
102 | |||
103 | WARNING: Do not use this function in interrupt context. | ||
104 | |||
105 | Example: | ||
106 | soc_pm_init() | ||
107 | { | ||
108 | /* Do things */ | ||
109 | r = opp_add(mpu_dev, 1000000, 900000); | ||
110 | if (!r) { | ||
111 | pr_err("%s: unable to register mpu opp(%d)\n", r); | ||
112 | goto no_cpufreq; | ||
113 | } | ||
114 | /* Do cpufreq things */ | ||
115 | no_cpufreq: | ||
116 | /* Do remaining things */ | ||
117 | } | ||
118 | |||
119 | 3. OPP Search Functions | ||
120 | ======================= | ||
121 | High level framework such as cpufreq operates on frequencies. To map the | ||
122 | frequency back to the corresponding OPP, OPP library provides handy functions | ||
123 | to search the OPP list that OPP library internally manages. These search | ||
124 | functions return the matching pointer representing the opp if a match is | ||
125 | found, else returns error. These errors are expected to be handled by standard | ||
126 | error checks such as IS_ERR() and appropriate actions taken by the caller. | ||
127 | |||
128 | opp_find_freq_exact - Search for an OPP based on an *exact* frequency and | ||
129 | availability. This function is especially useful to enable an OPP which | ||
130 | is not available by default. | ||
131 | Example: In a case when SoC framework detects a situation where a | ||
132 | higher frequency could be made available, it can use this function to | ||
133 | find the OPP prior to call the opp_enable to actually make it available. | ||
134 | rcu_read_lock(); | ||
135 | opp = opp_find_freq_exact(dev, 1000000000, false); | ||
136 | rcu_read_unlock(); | ||
137 | /* dont operate on the pointer.. just do a sanity check.. */ | ||
138 | if (IS_ERR(opp)) { | ||
139 | pr_err("frequency not disabled!\n"); | ||
140 | /* trigger appropriate actions.. */ | ||
141 | } else { | ||
142 | opp_enable(dev,1000000000); | ||
143 | } | ||
144 | |||
145 | NOTE: This is the only search function that operates on OPPs which are | ||
146 | not available. | ||
147 | |||
148 | opp_find_freq_floor - Search for an available OPP which is *at most* the | ||
149 | provided frequency. This function is useful while searching for a lesser | ||
150 | match OR operating on OPP information in the order of decreasing | ||
151 | frequency. | ||
152 | Example: To find the highest opp for a device: | ||
153 | freq = ULONG_MAX; | ||
154 | rcu_read_lock(); | ||
155 | opp_find_freq_floor(dev, &freq); | ||
156 | rcu_read_unlock(); | ||
157 | |||
158 | opp_find_freq_ceil - Search for an available OPP which is *at least* the | ||
159 | provided frequency. This function is useful while searching for a | ||
160 | higher match OR operating on OPP information in the order of increasing | ||
161 | frequency. | ||
162 | Example 1: To find the lowest opp for a device: | ||
163 | freq = 0; | ||
164 | rcu_read_lock(); | ||
165 | opp_find_freq_ceil(dev, &freq); | ||
166 | rcu_read_unlock(); | ||
167 | Example 2: A simplified implementation of a SoC cpufreq_driver->target: | ||
168 | soc_cpufreq_target(..) | ||
169 | { | ||
170 | /* Do stuff like policy checks etc. */ | ||
171 | /* Find the best frequency match for the req */ | ||
172 | rcu_read_lock(); | ||
173 | opp = opp_find_freq_ceil(dev, &freq); | ||
174 | rcu_read_unlock(); | ||
175 | if (!IS_ERR(opp)) | ||
176 | soc_switch_to_freq_voltage(freq); | ||
177 | else | ||
178 | /* do something when we cant satisfy the req */ | ||
179 | /* do other stuff */ | ||
180 | } | ||
181 | |||
182 | 4. OPP Availability Control Functions | ||
183 | ===================================== | ||
184 | A default OPP list registered with the OPP library may not cater to all possible | ||
185 | situation. The OPP library provides a set of functions to modify the | ||
186 | availability of a OPP within the OPP list. This allows SoC frameworks to have | ||
187 | fine grained dynamic control of which sets of OPPs are operationally available. | ||
188 | These functions are intended to *temporarily* remove an OPP in conditions such | ||
189 | as thermal considerations (e.g. don't use OPPx until the temperature drops). | ||
190 | |||
191 | WARNING: Do not use these functions in interrupt context. | ||
192 | |||
193 | opp_enable - Make a OPP available for operation. | ||
194 | Example: Lets say that 1GHz OPP is to be made available only if the | ||
195 | SoC temperature is lower than a certain threshold. The SoC framework | ||
196 | implementation might choose to do something as follows: | ||
197 | if (cur_temp < temp_low_thresh) { | ||
198 | /* Enable 1GHz if it was disabled */ | ||
199 | rcu_read_lock(); | ||
200 | opp = opp_find_freq_exact(dev, 1000000000, false); | ||
201 | rcu_read_unlock(); | ||
202 | /* just error check */ | ||
203 | if (!IS_ERR(opp)) | ||
204 | ret = opp_enable(dev, 1000000000); | ||
205 | else | ||
206 | goto try_something_else; | ||
207 | } | ||
208 | |||
209 | opp_disable - Make an OPP to be not available for operation | ||
210 | Example: Lets say that 1GHz OPP is to be disabled if the temperature | ||
211 | exceeds a threshold value. The SoC framework implementation might | ||
212 | choose to do something as follows: | ||
213 | if (cur_temp > temp_high_thresh) { | ||
214 | /* Disable 1GHz if it was enabled */ | ||
215 | rcu_read_lock(); | ||
216 | opp = opp_find_freq_exact(dev, 1000000000, true); | ||
217 | rcu_read_unlock(); | ||
218 | /* just error check */ | ||
219 | if (!IS_ERR(opp)) | ||
220 | ret = opp_disable(dev, 1000000000); | ||
221 | else | ||
222 | goto try_something_else; | ||
223 | } | ||
224 | |||
225 | 5. OPP Data Retrieval Functions | ||
226 | =============================== | ||
227 | Since OPP library abstracts away the OPP information, a set of functions to pull | ||
228 | information from the OPP structure is necessary. Once an OPP pointer is | ||
229 | retrieved using the search functions, the following functions can be used by SoC | ||
230 | framework to retrieve the information represented inside the OPP layer. | ||
231 | |||
232 | opp_get_voltage - Retrieve the voltage represented by the opp pointer. | ||
233 | Example: At a cpufreq transition to a different frequency, SoC | ||
234 | framework requires to set the voltage represented by the OPP using | ||
235 | the regulator framework to the Power Management chip providing the | ||
236 | voltage. | ||
237 | soc_switch_to_freq_voltage(freq) | ||
238 | { | ||
239 | /* do things */ | ||
240 | rcu_read_lock(); | ||
241 | opp = opp_find_freq_ceil(dev, &freq); | ||
242 | v = opp_get_voltage(opp); | ||
243 | rcu_read_unlock(); | ||
244 | if (v) | ||
245 | regulator_set_voltage(.., v); | ||
246 | /* do other things */ | ||
247 | } | ||
248 | |||
249 | opp_get_freq - Retrieve the freq represented by the opp pointer. | ||
250 | Example: Lets say the SoC framework uses a couple of helper functions | ||
251 | we could pass opp pointers instead of doing additional parameters to | ||
252 | handle quiet a bit of data parameters. | ||
253 | soc_cpufreq_target(..) | ||
254 | { | ||
255 | /* do things.. */ | ||
256 | max_freq = ULONG_MAX; | ||
257 | rcu_read_lock(); | ||
258 | max_opp = opp_find_freq_floor(dev,&max_freq); | ||
259 | requested_opp = opp_find_freq_ceil(dev,&freq); | ||
260 | if (!IS_ERR(max_opp) && !IS_ERR(requested_opp)) | ||
261 | r = soc_test_validity(max_opp, requested_opp); | ||
262 | rcu_read_unlock(); | ||
263 | /* do other things */ | ||
264 | } | ||
265 | soc_test_validity(..) | ||
266 | { | ||
267 | if(opp_get_voltage(max_opp) < opp_get_voltage(requested_opp)) | ||
268 | return -EINVAL; | ||
269 | if(opp_get_freq(max_opp) < opp_get_freq(requested_opp)) | ||
270 | return -EINVAL; | ||
271 | /* do things.. */ | ||
272 | } | ||
273 | |||
274 | opp_get_opp_count - Retrieve the number of available opps for a device | ||
275 | Example: Lets say a co-processor in the SoC needs to know the available | ||
276 | frequencies in a table, the main processor can notify as following: | ||
277 | soc_notify_coproc_available_frequencies() | ||
278 | { | ||
279 | /* Do things */ | ||
280 | rcu_read_lock(); | ||
281 | num_available = opp_get_opp_count(dev); | ||
282 | speeds = kzalloc(sizeof(u32) * num_available, GFP_KERNEL); | ||
283 | /* populate the table in increasing order */ | ||
284 | freq = 0; | ||
285 | while (!IS_ERR(opp = opp_find_freq_ceil(dev, &freq))) { | ||
286 | speeds[i] = freq; | ||
287 | freq++; | ||
288 | i++; | ||
289 | } | ||
290 | rcu_read_unlock(); | ||
291 | |||
292 | soc_notify_coproc(AVAILABLE_FREQs, speeds, num_available); | ||
293 | /* Do other things */ | ||
294 | } | ||
295 | |||
296 | 6. Cpufreq Table Generation | ||
297 | =========================== | ||
298 | opp_init_cpufreq_table - cpufreq framework typically is initialized with | ||
299 | cpufreq_frequency_table_cpuinfo which is provided with the list of | ||
300 | frequencies that are available for operation. This function provides | ||
301 | a ready to use conversion routine to translate the OPP layer's internal | ||
302 | information about the available frequencies into a format readily | ||
303 | providable to cpufreq. | ||
304 | |||
305 | WARNING: Do not use this function in interrupt context. | ||
306 | |||
307 | Example: | ||
308 | soc_pm_init() | ||
309 | { | ||
310 | /* Do things */ | ||
311 | r = opp_init_cpufreq_table(dev, &freq_table); | ||
312 | if (!r) | ||
313 | cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
314 | /* Do other things */ | ||
315 | } | ||
316 | |||
317 | NOTE: This function is available only if CONFIG_CPU_FREQ is enabled in | ||
318 | addition to CONFIG_PM as power management feature is required to | ||
319 | dynamically scale voltage and frequency in a system. | ||
320 | |||
321 | 7. Data Structures | ||
322 | ================== | ||
323 | Typically an SoC contains multiple voltage domains which are variable. Each | ||
324 | domain is represented by a device pointer. The relationship to OPP can be | ||
325 | 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 | ||
335 | |||
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. | ||
340 | |||
341 | struct opp - The internal data structure of OPP library which is used to | ||
342 | represent an OPP. In addition to the freq, voltage, availability | ||
343 | information, it also contains internal book keeping information required | ||
344 | for the OPP library to operate on. Pointer to this structure is | ||
345 | provided back to the users such as SoC framework to be used as a | ||
346 | identifier for OPP in the interactions with OPP layer. | ||
347 | |||
348 | WARNING: The struct opp pointer should not be parsed or modified by the | ||
349 | users. The defaults of for an instance is populated by opp_add, but the | ||
350 | availability of the OPP can be modified by opp_enable/disable functions. | ||
351 | |||
352 | struct device - This is used to identify a domain to the OPP layer. The | ||
353 | nature of the device and it's implementation is left to the user of | ||
354 | OPP library such as the SoC framework. | ||
355 | |||
356 | Overall, in a simplistic view, the data structure operations is represented as | ||
357 | following: | ||
358 | |||
359 | Initialization / modification: | ||
360 | +-----+ /- opp_enable | ||
361 | opp_add --> | opp | <------- | ||
362 | | +-----+ \- opp_disable | ||
363 | \-------> domain_info(device) | ||
364 | |||
365 | Search functions: | ||
366 | /-- opp_find_freq_ceil ---\ +-----+ | ||
367 | domain_info<---- opp_find_freq_exact -----> | opp | | ||
368 | \-- opp_find_freq_floor ---/ +-----+ | ||
369 | |||
370 | Retrieval functions: | ||
371 | +-----+ /- opp_get_voltage | ||
372 | | opp | <--- | ||
373 | +-----+ \- opp_get_freq | ||
374 | |||
375 | domain_info <- opp_get_opp_count | ||