xref: /openbmc/linux/Documentation/power/opp.rst (revision 3dc4b6fb)
1==========================================
2Operating Performance Points (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. Data Structures
15
161. Introduction
17===============
18
191.1 What is an Operating Performance Point (OPP)?
20-------------------------------------------------
21
22Complex SoCs of today consists of a multiple sub-modules working in conjunction.
23In an operational system executing varied use cases, not all modules in the SoC
24need to function at their highest performing frequency all the time. To
25facilitate this, sub-modules in a SoC are grouped into domains, allowing some
26domains to run at lower voltage and frequency while other domains run at
27voltage/frequency pairs that are higher.
28
29The set of discrete tuples consisting of frequency and voltage pairs that
30the device will support per domain are called Operating Performance Points or
31OPPs.
32
33As an example:
34
35Let 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}
38
39We can represent these as three OPPs as the following {Hz, uV} tuples:
40
41- {300000000, 1000000}
42- {800000000, 1200000}
43- {1000000000, 1300000}
44
451.2 Operating Performance Points Library
46----------------------------------------
47
48OPP library provides a set of helper functions to organize and query the OPP
49information. The library is located in drivers/opp/ directory and the header
50is located in include/linux/pm_opp.h. OPP library can be enabled by enabling
51CONFIG_PM_OPP from power management menuconfig menu. OPP library depends on
52CONFIG_PM as certain SoCs such as Texas Instrument's OMAP framework allows to
53optionally boot at a certain OPP without needing cpufreq.
54
55Typical usage of the OPP library is as follows::
56
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	->
60
61OPP layer expects each domain to be represented by a unique device pointer. SoC
62framework registers a set of initial OPPs per device with the OPP layer. This
63list is expected to be an optimally small number typically around 5 per device.
64This initial list contains a set of OPPs that the framework expects to be safely
65enabled by default in the system.
66
67Note on OPP Availability
68^^^^^^^^^^^^^^^^^^^^^^^^
69
70As the system proceeds to operate, SoC framework may choose to make certain
71OPPs available or not available on each device based on various external
72factors. Example usage: Thermal management or other exceptional situations where
73SoC framework might choose to disable a higher frequency OPP to safely continue
74operations until that OPP could be re-enabled if possible.
75
76OPP library facilitates this concept in it's implementation. The following
77operational functions operate only on available opps:
78opp_find_freq_{ceil, floor}, dev_pm_opp_get_voltage, dev_pm_opp_get_freq, dev_pm_opp_get_opp_count
79
80dev_pm_opp_find_freq_exact is meant to be used to find the opp pointer which can then
81be used for dev_pm_opp_enable/disable functions to make an opp available as required.
82
83WARNING: Users of OPP library should refresh their availability count using
84get_opp_count if dev_pm_opp_enable/disable functions are invoked for a device, the
85exact mechanism to trigger these or the notification mechanism to other
86dependent subsystems such as cpufreq are left to the discretion of the SoC
87specific framework which uses the OPP library. Similar care needs to be taken
88care to refresh the cpufreq table in cases of these operations.
89
902. Initial OPP List Registration
91================================
92The SoC implementation calls dev_pm_opp_add function iteratively to add OPPs per
93device. It is expected that the SoC framework will register the OPP entries
94optimally- typical numbers range to be less than 5. The list generated by
95registering the OPPs is maintained by OPP library throughout the device
96operation. The SoC framework can subsequently control the availability of the
97OPPs dynamically using the dev_pm_opp_enable / disable functions.
98
99dev_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.
107
108	WARNING:
109		Do not use this function in interrupt context.
110
111	Example::
112
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	 }
125
1263. OPP Search Functions
127=======================
128High level framework such as cpufreq operates on frequencies. To map the
129frequency back to the corresponding OPP, OPP library provides handy functions
130to search the OPP list that OPP library internally manages. These search
131functions return the matching pointer representing the opp if a match is
132found, else returns error. These errors are expected to be handled by standard
133error checks such as IS_ERR() and appropriate actions taken by the caller.
134
135Callers of these functions shall call dev_pm_opp_put() after they have used the
136OPP. Otherwise the memory for the OPP will never get freed and result in
137memleak.
138
139dev_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::
147
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	 }
157
158	NOTE:
159	  This is the only search function that operates on OPPs which are
160	  not available.
161
162dev_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::
168
169	 freq = ULONG_MAX;
170	 opp = dev_pm_opp_find_freq_floor(dev, &freq);
171	 dev_pm_opp_put(opp);
172
173dev_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::
179
180	 freq = 0;
181	 opp = dev_pm_opp_find_freq_ceil(dev, &freq);
182	 dev_pm_opp_put(opp);
183
184	Example 2: A simplified implementation of a SoC cpufreq_driver->target::
185
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	 }
198
1994. OPP Availability Control Functions
200=====================================
201A default OPP list registered with the OPP library may not cater to all possible
202situation. The OPP library provides a set of functions to modify the
203availability of a OPP within the OPP list. This allows SoC frameworks to have
204fine grained dynamic control of which sets of OPPs are operationally available.
205These functions are intended to *temporarily* remove an OPP in conditions such
206as thermal considerations (e.g. don't use OPPx until the temperature drops).
207
208WARNING:
209	Do not use these functions in interrupt context.
210
211dev_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::
216
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	 }
227
228dev_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::
233
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	 }
244
2455. OPP Data Retrieval Functions
246===============================
247Since OPP library abstracts away the OPP information, a set of functions to pull
248information from the OPP structure is necessary. Once an OPP pointer is
249retrieved using the search functions, the following functions can be used by SoC
250framework to retrieve the information represented inside the OPP layer.
251
252dev_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::
258
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	 }
269
270dev_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::
275
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	 }
296
297dev_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::
301
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		}
315
316		soc_notify_coproc(AVAILABLE_FREQs, speeds, num_available);
317		/* Do other things */
318	 }
319
3206. Data Structures
321==================
322Typically an SoC contains multiple voltage domains which are variable. Each
323domain is represented by a device pointer. The relationship to OPP can be
324represented as follows::
325
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
336OPP library maintains a internal list that the SoC framework populates and
337accessed by various functions as described above. However, the structures
338representing the actual OPPs and domains are internal to the OPP library itself
339to allow for suitable abstraction reusable across systems.
340
341struct 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.
348
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.
354
355struct 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.
359
360Overall, in a simplistic view, the data structure operations is represented as
361following::
362
363  Initialization / modification:
364              +-----+        /- dev_pm_opp_enable
365  dev_pm_opp_add --> | opp | <-------
366    |         +-----+        \- dev_pm_opp_disable
367    \-------> domain_info(device)
368
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 ---/   +-----+
373
374  Retrieval functions:
375  +-----+     /- dev_pm_opp_get_voltage
376  | opp | <---
377  +-----+     \- dev_pm_opp_get_freq
378
379  domain_info <- dev_pm_opp_get_opp_count
380