xref: /linux/Documentation/power/opp.rst (revision 27a84f76738cc4a9509ec9234a7021de34a88e58)
1151f4e2bSMauro Carvalho Chehab==========================================
2151f4e2bSMauro Carvalho ChehabOperating Performance Points (OPP) Library
3151f4e2bSMauro Carvalho Chehab==========================================
4151f4e2bSMauro Carvalho Chehab
5151f4e2bSMauro Carvalho Chehab(C) 2009-2010 Nishanth Menon <nm@ti.com>, Texas Instruments Incorporated
6151f4e2bSMauro Carvalho Chehab
7151f4e2bSMauro Carvalho Chehab.. Contents
8151f4e2bSMauro Carvalho Chehab
9151f4e2bSMauro Carvalho Chehab  1. Introduction
10151f4e2bSMauro Carvalho Chehab  2. Initial OPP List Registration
11151f4e2bSMauro Carvalho Chehab  3. OPP Search Functions
12151f4e2bSMauro Carvalho Chehab  4. OPP Availability Control Functions
13151f4e2bSMauro Carvalho Chehab  5. OPP Data Retrieval Functions
14151f4e2bSMauro Carvalho Chehab  6. Data Structures
15151f4e2bSMauro Carvalho Chehab
16151f4e2bSMauro Carvalho Chehab1. Introduction
17151f4e2bSMauro Carvalho Chehab===============
18151f4e2bSMauro Carvalho Chehab
19151f4e2bSMauro Carvalho Chehab1.1 What is an Operating Performance Point (OPP)?
20151f4e2bSMauro Carvalho Chehab-------------------------------------------------
21151f4e2bSMauro Carvalho Chehab
22151f4e2bSMauro Carvalho ChehabComplex SoCs of today consists of a multiple sub-modules working in conjunction.
23151f4e2bSMauro Carvalho ChehabIn an operational system executing varied use cases, not all modules in the SoC
24151f4e2bSMauro Carvalho Chehabneed to function at their highest performing frequency all the time. To
25151f4e2bSMauro Carvalho Chehabfacilitate this, sub-modules in a SoC are grouped into domains, allowing some
26151f4e2bSMauro Carvalho Chehabdomains to run at lower voltage and frequency while other domains run at
27151f4e2bSMauro Carvalho Chehabvoltage/frequency pairs that are higher.
28151f4e2bSMauro Carvalho Chehab
29151f4e2bSMauro Carvalho ChehabThe set of discrete tuples consisting of frequency and voltage pairs that
30151f4e2bSMauro Carvalho Chehabthe device will support per domain are called Operating Performance Points or
31151f4e2bSMauro Carvalho ChehabOPPs.
32151f4e2bSMauro Carvalho Chehab
33151f4e2bSMauro Carvalho ChehabAs an example:
34151f4e2bSMauro Carvalho Chehab
35151f4e2bSMauro Carvalho ChehabLet us consider an MPU device which supports the following:
36151f4e2bSMauro Carvalho Chehab{300MHz at minimum voltage of 1V}, {800MHz at minimum voltage of 1.2V},
37151f4e2bSMauro Carvalho Chehab{1GHz at minimum voltage of 1.3V}
38151f4e2bSMauro Carvalho Chehab
39151f4e2bSMauro Carvalho ChehabWe can represent these as three OPPs as the following {Hz, uV} tuples:
40151f4e2bSMauro Carvalho Chehab
41151f4e2bSMauro Carvalho Chehab- {300000000, 1000000}
42151f4e2bSMauro Carvalho Chehab- {800000000, 1200000}
43151f4e2bSMauro Carvalho Chehab- {1000000000, 1300000}
44151f4e2bSMauro Carvalho Chehab
45151f4e2bSMauro Carvalho Chehab1.2 Operating Performance Points Library
46151f4e2bSMauro Carvalho Chehab----------------------------------------
47151f4e2bSMauro Carvalho Chehab
48151f4e2bSMauro Carvalho ChehabOPP library provides a set of helper functions to organize and query the OPP
49*27a84f76SYue Huinformation. The library is located in drivers/opp/ directory and the header
50151f4e2bSMauro Carvalho Chehabis located in include/linux/pm_opp.h. OPP library can be enabled by enabling
51151f4e2bSMauro Carvalho ChehabCONFIG_PM_OPP from power management menuconfig menu. OPP library depends on
52151f4e2bSMauro Carvalho ChehabCONFIG_PM as certain SoCs such as Texas Instrument's OMAP framework allows to
53151f4e2bSMauro Carvalho Chehaboptionally boot at a certain OPP without needing cpufreq.
54151f4e2bSMauro Carvalho Chehab
55151f4e2bSMauro Carvalho ChehabTypical usage of the OPP library is as follows::
56151f4e2bSMauro Carvalho Chehab
57151f4e2bSMauro Carvalho Chehab (users)	-> registers a set of default OPPs		-> (library)
58151f4e2bSMauro Carvalho Chehab SoC framework	-> modifies on required cases certain OPPs	-> OPP layer
59151f4e2bSMauro Carvalho Chehab		-> queries to search/retrieve information	->
60151f4e2bSMauro Carvalho Chehab
61151f4e2bSMauro Carvalho ChehabOPP layer expects each domain to be represented by a unique device pointer. SoC
62151f4e2bSMauro Carvalho Chehabframework registers a set of initial OPPs per device with the OPP layer. This
63151f4e2bSMauro Carvalho Chehablist is expected to be an optimally small number typically around 5 per device.
64151f4e2bSMauro Carvalho ChehabThis initial list contains a set of OPPs that the framework expects to be safely
65151f4e2bSMauro Carvalho Chehabenabled by default in the system.
66151f4e2bSMauro Carvalho Chehab
67151f4e2bSMauro Carvalho ChehabNote on OPP Availability
68151f4e2bSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^
69151f4e2bSMauro Carvalho Chehab
70151f4e2bSMauro Carvalho ChehabAs the system proceeds to operate, SoC framework may choose to make certain
71151f4e2bSMauro Carvalho ChehabOPPs available or not available on each device based on various external
72151f4e2bSMauro Carvalho Chehabfactors. Example usage: Thermal management or other exceptional situations where
73151f4e2bSMauro Carvalho ChehabSoC framework might choose to disable a higher frequency OPP to safely continue
74151f4e2bSMauro Carvalho Chehaboperations until that OPP could be re-enabled if possible.
75151f4e2bSMauro Carvalho Chehab
76151f4e2bSMauro Carvalho ChehabOPP library facilitates this concept in it's implementation. The following
77151f4e2bSMauro Carvalho Chehaboperational functions operate only on available opps:
78151f4e2bSMauro Carvalho Chehabopp_find_freq_{ceil, floor}, dev_pm_opp_get_voltage, dev_pm_opp_get_freq, dev_pm_opp_get_opp_count
79151f4e2bSMauro Carvalho Chehab
80151f4e2bSMauro Carvalho Chehabdev_pm_opp_find_freq_exact is meant to be used to find the opp pointer which can then
81151f4e2bSMauro Carvalho Chehabbe used for dev_pm_opp_enable/disable functions to make an opp available as required.
82151f4e2bSMauro Carvalho Chehab
83151f4e2bSMauro Carvalho ChehabWARNING: Users of OPP library should refresh their availability count using
84151f4e2bSMauro Carvalho Chehabget_opp_count if dev_pm_opp_enable/disable functions are invoked for a device, the
85151f4e2bSMauro Carvalho Chehabexact mechanism to trigger these or the notification mechanism to other
86151f4e2bSMauro Carvalho Chehabdependent subsystems such as cpufreq are left to the discretion of the SoC
87151f4e2bSMauro Carvalho Chehabspecific framework which uses the OPP library. Similar care needs to be taken
88151f4e2bSMauro Carvalho Chehabcare to refresh the cpufreq table in cases of these operations.
89151f4e2bSMauro Carvalho Chehab
90151f4e2bSMauro Carvalho Chehab2. Initial OPP List Registration
91151f4e2bSMauro Carvalho Chehab================================
92151f4e2bSMauro Carvalho ChehabThe SoC implementation calls dev_pm_opp_add function iteratively to add OPPs per
93151f4e2bSMauro Carvalho Chehabdevice. It is expected that the SoC framework will register the OPP entries
94151f4e2bSMauro Carvalho Chehaboptimally- typical numbers range to be less than 5. The list generated by
95151f4e2bSMauro Carvalho Chehabregistering the OPPs is maintained by OPP library throughout the device
96151f4e2bSMauro Carvalho Chehaboperation. The SoC framework can subsequently control the availability of the
97151f4e2bSMauro Carvalho ChehabOPPs dynamically using the dev_pm_opp_enable / disable functions.
98151f4e2bSMauro Carvalho Chehab
99151f4e2bSMauro Carvalho Chehabdev_pm_opp_add
100151f4e2bSMauro Carvalho Chehab	Add a new OPP for a specific domain represented by the device pointer.
101151f4e2bSMauro Carvalho Chehab	The OPP is defined using the frequency and voltage. Once added, the OPP
102151f4e2bSMauro Carvalho Chehab	is assumed to be available and control of it's availability can be done
103151f4e2bSMauro Carvalho Chehab	with the dev_pm_opp_enable/disable functions. OPP library internally stores
104151f4e2bSMauro Carvalho Chehab	and manages this information in the opp struct. This function may be
105151f4e2bSMauro Carvalho Chehab	used by SoC framework to define a optimal list as per the demands of
106151f4e2bSMauro Carvalho Chehab	SoC usage environment.
107151f4e2bSMauro Carvalho Chehab
108151f4e2bSMauro Carvalho Chehab	WARNING:
109151f4e2bSMauro Carvalho Chehab		Do not use this function in interrupt context.
110151f4e2bSMauro Carvalho Chehab
111151f4e2bSMauro Carvalho Chehab	Example::
112151f4e2bSMauro Carvalho Chehab
113151f4e2bSMauro Carvalho Chehab	 soc_pm_init()
114151f4e2bSMauro Carvalho Chehab	 {
115151f4e2bSMauro Carvalho Chehab		/* Do things */
116151f4e2bSMauro Carvalho Chehab		r = dev_pm_opp_add(mpu_dev, 1000000, 900000);
117151f4e2bSMauro Carvalho Chehab		if (!r) {
118151f4e2bSMauro Carvalho Chehab			pr_err("%s: unable to register mpu opp(%d)\n", r);
119151f4e2bSMauro Carvalho Chehab			goto no_cpufreq;
120151f4e2bSMauro Carvalho Chehab		}
121151f4e2bSMauro Carvalho Chehab		/* Do cpufreq things */
122151f4e2bSMauro Carvalho Chehab	 no_cpufreq:
123151f4e2bSMauro Carvalho Chehab		/* Do remaining things */
124151f4e2bSMauro Carvalho Chehab	 }
125151f4e2bSMauro Carvalho Chehab
126151f4e2bSMauro Carvalho Chehab3. OPP Search Functions
127151f4e2bSMauro Carvalho Chehab=======================
128151f4e2bSMauro Carvalho ChehabHigh level framework such as cpufreq operates on frequencies. To map the
129151f4e2bSMauro Carvalho Chehabfrequency back to the corresponding OPP, OPP library provides handy functions
130151f4e2bSMauro Carvalho Chehabto search the OPP list that OPP library internally manages. These search
131151f4e2bSMauro Carvalho Chehabfunctions return the matching pointer representing the opp if a match is
132151f4e2bSMauro Carvalho Chehabfound, else returns error. These errors are expected to be handled by standard
133151f4e2bSMauro Carvalho Chehaberror checks such as IS_ERR() and appropriate actions taken by the caller.
134151f4e2bSMauro Carvalho Chehab
135151f4e2bSMauro Carvalho ChehabCallers of these functions shall call dev_pm_opp_put() after they have used the
136151f4e2bSMauro Carvalho ChehabOPP. Otherwise the memory for the OPP will never get freed and result in
137151f4e2bSMauro Carvalho Chehabmemleak.
138151f4e2bSMauro Carvalho Chehab
139151f4e2bSMauro Carvalho Chehabdev_pm_opp_find_freq_exact
140151f4e2bSMauro Carvalho Chehab	Search for an OPP based on an *exact* frequency and
141151f4e2bSMauro Carvalho Chehab	availability. This function is especially useful to enable an OPP which
142151f4e2bSMauro Carvalho Chehab	is not available by default.
143151f4e2bSMauro Carvalho Chehab	Example: In a case when SoC framework detects a situation where a
144151f4e2bSMauro Carvalho Chehab	higher frequency could be made available, it can use this function to
145151f4e2bSMauro Carvalho Chehab	find the OPP prior to call the dev_pm_opp_enable to actually make
146151f4e2bSMauro Carvalho Chehab	it available::
147151f4e2bSMauro Carvalho Chehab
148151f4e2bSMauro Carvalho Chehab	 opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false);
149151f4e2bSMauro Carvalho Chehab	 dev_pm_opp_put(opp);
150151f4e2bSMauro Carvalho Chehab	 /* dont operate on the pointer.. just do a sanity check.. */
151151f4e2bSMauro Carvalho Chehab	 if (IS_ERR(opp)) {
152151f4e2bSMauro Carvalho Chehab		pr_err("frequency not disabled!\n");
153151f4e2bSMauro Carvalho Chehab		/* trigger appropriate actions.. */
154151f4e2bSMauro Carvalho Chehab	 } else {
155151f4e2bSMauro Carvalho Chehab		dev_pm_opp_enable(dev,1000000000);
156151f4e2bSMauro Carvalho Chehab	 }
157151f4e2bSMauro Carvalho Chehab
158151f4e2bSMauro Carvalho Chehab	NOTE:
159151f4e2bSMauro Carvalho Chehab	  This is the only search function that operates on OPPs which are
160151f4e2bSMauro Carvalho Chehab	  not available.
161151f4e2bSMauro Carvalho Chehab
162151f4e2bSMauro Carvalho Chehabdev_pm_opp_find_freq_floor
163151f4e2bSMauro Carvalho Chehab	Search for an available OPP which is *at most* the
164151f4e2bSMauro Carvalho Chehab	provided frequency. This function is useful while searching for a lesser
165151f4e2bSMauro Carvalho Chehab	match OR operating on OPP information in the order of decreasing
166151f4e2bSMauro Carvalho Chehab	frequency.
167151f4e2bSMauro Carvalho Chehab	Example: To find the highest opp for a device::
168151f4e2bSMauro Carvalho Chehab
169151f4e2bSMauro Carvalho Chehab	 freq = ULONG_MAX;
170151f4e2bSMauro Carvalho Chehab	 opp = dev_pm_opp_find_freq_floor(dev, &freq);
171151f4e2bSMauro Carvalho Chehab	 dev_pm_opp_put(opp);
172151f4e2bSMauro Carvalho Chehab
173151f4e2bSMauro Carvalho Chehabdev_pm_opp_find_freq_ceil
174151f4e2bSMauro Carvalho Chehab	Search for an available OPP which is *at least* the
175151f4e2bSMauro Carvalho Chehab	provided frequency. This function is useful while searching for a
176151f4e2bSMauro Carvalho Chehab	higher match OR operating on OPP information in the order of increasing
177151f4e2bSMauro Carvalho Chehab	frequency.
178151f4e2bSMauro Carvalho Chehab	Example 1: To find the lowest opp for a device::
179151f4e2bSMauro Carvalho Chehab
180151f4e2bSMauro Carvalho Chehab	 freq = 0;
181151f4e2bSMauro Carvalho Chehab	 opp = dev_pm_opp_find_freq_ceil(dev, &freq);
182151f4e2bSMauro Carvalho Chehab	 dev_pm_opp_put(opp);
183151f4e2bSMauro Carvalho Chehab
184151f4e2bSMauro Carvalho Chehab	Example 2: A simplified implementation of a SoC cpufreq_driver->target::
185151f4e2bSMauro Carvalho Chehab
186151f4e2bSMauro Carvalho Chehab	 soc_cpufreq_target(..)
187151f4e2bSMauro Carvalho Chehab	 {
188151f4e2bSMauro Carvalho Chehab		/* Do stuff like policy checks etc. */
189151f4e2bSMauro Carvalho Chehab		/* Find the best frequency match for the req */
190151f4e2bSMauro Carvalho Chehab		opp = dev_pm_opp_find_freq_ceil(dev, &freq);
191151f4e2bSMauro Carvalho Chehab		dev_pm_opp_put(opp);
192151f4e2bSMauro Carvalho Chehab		if (!IS_ERR(opp))
193151f4e2bSMauro Carvalho Chehab			soc_switch_to_freq_voltage(freq);
194151f4e2bSMauro Carvalho Chehab		else
195151f4e2bSMauro Carvalho Chehab			/* do something when we can't satisfy the req */
196151f4e2bSMauro Carvalho Chehab		/* do other stuff */
197151f4e2bSMauro Carvalho Chehab	 }
198151f4e2bSMauro Carvalho Chehab
199151f4e2bSMauro Carvalho Chehab4. OPP Availability Control Functions
200151f4e2bSMauro Carvalho Chehab=====================================
201151f4e2bSMauro Carvalho ChehabA default OPP list registered with the OPP library may not cater to all possible
202151f4e2bSMauro Carvalho Chehabsituation. The OPP library provides a set of functions to modify the
203151f4e2bSMauro Carvalho Chehabavailability of a OPP within the OPP list. This allows SoC frameworks to have
204151f4e2bSMauro Carvalho Chehabfine grained dynamic control of which sets of OPPs are operationally available.
205151f4e2bSMauro Carvalho ChehabThese functions are intended to *temporarily* remove an OPP in conditions such
206151f4e2bSMauro Carvalho Chehabas thermal considerations (e.g. don't use OPPx until the temperature drops).
207151f4e2bSMauro Carvalho Chehab
208151f4e2bSMauro Carvalho ChehabWARNING:
209151f4e2bSMauro Carvalho Chehab	Do not use these functions in interrupt context.
210151f4e2bSMauro Carvalho Chehab
211151f4e2bSMauro Carvalho Chehabdev_pm_opp_enable
212151f4e2bSMauro Carvalho Chehab	Make a OPP available for operation.
213151f4e2bSMauro Carvalho Chehab	Example: Lets say that 1GHz OPP is to be made available only if the
214151f4e2bSMauro Carvalho Chehab	SoC temperature is lower than a certain threshold. The SoC framework
215151f4e2bSMauro Carvalho Chehab	implementation might choose to do something as follows::
216151f4e2bSMauro Carvalho Chehab
217151f4e2bSMauro Carvalho Chehab	 if (cur_temp < temp_low_thresh) {
218151f4e2bSMauro Carvalho Chehab		/* Enable 1GHz if it was disabled */
219151f4e2bSMauro Carvalho Chehab		opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false);
220151f4e2bSMauro Carvalho Chehab		dev_pm_opp_put(opp);
221151f4e2bSMauro Carvalho Chehab		/* just error check */
222151f4e2bSMauro Carvalho Chehab		if (!IS_ERR(opp))
223151f4e2bSMauro Carvalho Chehab			ret = dev_pm_opp_enable(dev, 1000000000);
224151f4e2bSMauro Carvalho Chehab		else
225151f4e2bSMauro Carvalho Chehab			goto try_something_else;
226151f4e2bSMauro Carvalho Chehab	 }
227151f4e2bSMauro Carvalho Chehab
228151f4e2bSMauro Carvalho Chehabdev_pm_opp_disable
229151f4e2bSMauro Carvalho Chehab	Make an OPP to be not available for operation
230151f4e2bSMauro Carvalho Chehab	Example: Lets say that 1GHz OPP is to be disabled if the temperature
231151f4e2bSMauro Carvalho Chehab	exceeds a threshold value. The SoC framework implementation might
232151f4e2bSMauro Carvalho Chehab	choose to do something as follows::
233151f4e2bSMauro Carvalho Chehab
234151f4e2bSMauro Carvalho Chehab	 if (cur_temp > temp_high_thresh) {
235151f4e2bSMauro Carvalho Chehab		/* Disable 1GHz if it was enabled */
236151f4e2bSMauro Carvalho Chehab		opp = dev_pm_opp_find_freq_exact(dev, 1000000000, true);
237151f4e2bSMauro Carvalho Chehab		dev_pm_opp_put(opp);
238151f4e2bSMauro Carvalho Chehab		/* just error check */
239151f4e2bSMauro Carvalho Chehab		if (!IS_ERR(opp))
240151f4e2bSMauro Carvalho Chehab			ret = dev_pm_opp_disable(dev, 1000000000);
241151f4e2bSMauro Carvalho Chehab		else
242151f4e2bSMauro Carvalho Chehab			goto try_something_else;
243151f4e2bSMauro Carvalho Chehab	 }
244151f4e2bSMauro Carvalho Chehab
245151f4e2bSMauro Carvalho Chehab5. OPP Data Retrieval Functions
246151f4e2bSMauro Carvalho Chehab===============================
247151f4e2bSMauro Carvalho ChehabSince OPP library abstracts away the OPP information, a set of functions to pull
248151f4e2bSMauro Carvalho Chehabinformation from the OPP structure is necessary. Once an OPP pointer is
249151f4e2bSMauro Carvalho Chehabretrieved using the search functions, the following functions can be used by SoC
250151f4e2bSMauro Carvalho Chehabframework to retrieve the information represented inside the OPP layer.
251151f4e2bSMauro Carvalho Chehab
252151f4e2bSMauro Carvalho Chehabdev_pm_opp_get_voltage
253151f4e2bSMauro Carvalho Chehab	Retrieve the voltage represented by the opp pointer.
254151f4e2bSMauro Carvalho Chehab	Example: At a cpufreq transition to a different frequency, SoC
255151f4e2bSMauro Carvalho Chehab	framework requires to set the voltage represented by the OPP using
256151f4e2bSMauro Carvalho Chehab	the regulator framework to the Power Management chip providing the
257151f4e2bSMauro Carvalho Chehab	voltage::
258151f4e2bSMauro Carvalho Chehab
259151f4e2bSMauro Carvalho Chehab	 soc_switch_to_freq_voltage(freq)
260151f4e2bSMauro Carvalho Chehab	 {
261151f4e2bSMauro Carvalho Chehab		/* do things */
262151f4e2bSMauro Carvalho Chehab		opp = dev_pm_opp_find_freq_ceil(dev, &freq);
263151f4e2bSMauro Carvalho Chehab		v = dev_pm_opp_get_voltage(opp);
264151f4e2bSMauro Carvalho Chehab		dev_pm_opp_put(opp);
265151f4e2bSMauro Carvalho Chehab		if (v)
266151f4e2bSMauro Carvalho Chehab			regulator_set_voltage(.., v);
267151f4e2bSMauro Carvalho Chehab		/* do other things */
268151f4e2bSMauro Carvalho Chehab	 }
269151f4e2bSMauro Carvalho Chehab
270151f4e2bSMauro Carvalho Chehabdev_pm_opp_get_freq
271151f4e2bSMauro Carvalho Chehab	Retrieve the freq represented by the opp pointer.
272151f4e2bSMauro Carvalho Chehab	Example: Lets say the SoC framework uses a couple of helper functions
273151f4e2bSMauro Carvalho Chehab	we could pass opp pointers instead of doing additional parameters to
274151f4e2bSMauro Carvalho Chehab	handle quiet a bit of data parameters::
275151f4e2bSMauro Carvalho Chehab
276151f4e2bSMauro Carvalho Chehab	 soc_cpufreq_target(..)
277151f4e2bSMauro Carvalho Chehab	 {
278151f4e2bSMauro Carvalho Chehab		/* do things.. */
279151f4e2bSMauro Carvalho Chehab		 max_freq = ULONG_MAX;
280151f4e2bSMauro Carvalho Chehab		 max_opp = dev_pm_opp_find_freq_floor(dev,&max_freq);
281151f4e2bSMauro Carvalho Chehab		 requested_opp = dev_pm_opp_find_freq_ceil(dev,&freq);
282151f4e2bSMauro Carvalho Chehab		 if (!IS_ERR(max_opp) && !IS_ERR(requested_opp))
283151f4e2bSMauro Carvalho Chehab			r = soc_test_validity(max_opp, requested_opp);
284151f4e2bSMauro Carvalho Chehab		 dev_pm_opp_put(max_opp);
285151f4e2bSMauro Carvalho Chehab		 dev_pm_opp_put(requested_opp);
286151f4e2bSMauro Carvalho Chehab		/* do other things */
287151f4e2bSMauro Carvalho Chehab	 }
288151f4e2bSMauro Carvalho Chehab	 soc_test_validity(..)
289151f4e2bSMauro Carvalho Chehab	 {
290151f4e2bSMauro Carvalho Chehab		 if(dev_pm_opp_get_voltage(max_opp) < dev_pm_opp_get_voltage(requested_opp))
291151f4e2bSMauro Carvalho Chehab			 return -EINVAL;
292151f4e2bSMauro Carvalho Chehab		 if(dev_pm_opp_get_freq(max_opp) < dev_pm_opp_get_freq(requested_opp))
293151f4e2bSMauro Carvalho Chehab			 return -EINVAL;
294151f4e2bSMauro Carvalho Chehab		/* do things.. */
295151f4e2bSMauro Carvalho Chehab	 }
296151f4e2bSMauro Carvalho Chehab
297151f4e2bSMauro Carvalho Chehabdev_pm_opp_get_opp_count
298151f4e2bSMauro Carvalho Chehab	Retrieve the number of available opps for a device
299151f4e2bSMauro Carvalho Chehab	Example: Lets say a co-processor in the SoC needs to know the available
300151f4e2bSMauro Carvalho Chehab	frequencies in a table, the main processor can notify as following::
301151f4e2bSMauro Carvalho Chehab
302151f4e2bSMauro Carvalho Chehab	 soc_notify_coproc_available_frequencies()
303151f4e2bSMauro Carvalho Chehab	 {
304151f4e2bSMauro Carvalho Chehab		/* Do things */
305151f4e2bSMauro Carvalho Chehab		num_available = dev_pm_opp_get_opp_count(dev);
306151f4e2bSMauro Carvalho Chehab		speeds = kzalloc(sizeof(u32) * num_available, GFP_KERNEL);
307151f4e2bSMauro Carvalho Chehab		/* populate the table in increasing order */
308151f4e2bSMauro Carvalho Chehab		freq = 0;
309151f4e2bSMauro Carvalho Chehab		while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) {
310151f4e2bSMauro Carvalho Chehab			speeds[i] = freq;
311151f4e2bSMauro Carvalho Chehab			freq++;
312151f4e2bSMauro Carvalho Chehab			i++;
313151f4e2bSMauro Carvalho Chehab			dev_pm_opp_put(opp);
314151f4e2bSMauro Carvalho Chehab		}
315151f4e2bSMauro Carvalho Chehab
316151f4e2bSMauro Carvalho Chehab		soc_notify_coproc(AVAILABLE_FREQs, speeds, num_available);
317151f4e2bSMauro Carvalho Chehab		/* Do other things */
318151f4e2bSMauro Carvalho Chehab	 }
319151f4e2bSMauro Carvalho Chehab
320151f4e2bSMauro Carvalho Chehab6. Data Structures
321151f4e2bSMauro Carvalho Chehab==================
322151f4e2bSMauro Carvalho ChehabTypically an SoC contains multiple voltage domains which are variable. Each
323151f4e2bSMauro Carvalho Chehabdomain is represented by a device pointer. The relationship to OPP can be
324151f4e2bSMauro Carvalho Chehabrepresented as follows::
325151f4e2bSMauro Carvalho Chehab
326151f4e2bSMauro Carvalho Chehab  SoC
327151f4e2bSMauro Carvalho Chehab   |- device 1
328151f4e2bSMauro Carvalho Chehab   |	|- opp 1 (availability, freq, voltage)
329151f4e2bSMauro Carvalho Chehab   |	|- opp 2 ..
330151f4e2bSMauro Carvalho Chehab   ...	...
331151f4e2bSMauro Carvalho Chehab   |	`- opp n ..
332151f4e2bSMauro Carvalho Chehab   |- device 2
333151f4e2bSMauro Carvalho Chehab   ...
334151f4e2bSMauro Carvalho Chehab   `- device m
335151f4e2bSMauro Carvalho Chehab
336151f4e2bSMauro Carvalho ChehabOPP library maintains a internal list that the SoC framework populates and
337151f4e2bSMauro Carvalho Chehabaccessed by various functions as described above. However, the structures
338151f4e2bSMauro Carvalho Chehabrepresenting the actual OPPs and domains are internal to the OPP library itself
339151f4e2bSMauro Carvalho Chehabto allow for suitable abstraction reusable across systems.
340151f4e2bSMauro Carvalho Chehab
341151f4e2bSMauro Carvalho Chehabstruct dev_pm_opp
342151f4e2bSMauro Carvalho Chehab	The internal data structure of OPP library which is used to
343151f4e2bSMauro Carvalho Chehab	represent an OPP. In addition to the freq, voltage, availability
344151f4e2bSMauro Carvalho Chehab	information, it also contains internal book keeping information required
345151f4e2bSMauro Carvalho Chehab	for the OPP library to operate on.  Pointer to this structure is
346151f4e2bSMauro Carvalho Chehab	provided back to the users such as SoC framework to be used as a
347151f4e2bSMauro Carvalho Chehab	identifier for OPP in the interactions with OPP layer.
348151f4e2bSMauro Carvalho Chehab
349151f4e2bSMauro Carvalho Chehab	WARNING:
350151f4e2bSMauro Carvalho Chehab	  The struct dev_pm_opp pointer should not be parsed or modified by the
351151f4e2bSMauro Carvalho Chehab	  users. The defaults of for an instance is populated by
352151f4e2bSMauro Carvalho Chehab	  dev_pm_opp_add, but the availability of the OPP can be modified
353151f4e2bSMauro Carvalho Chehab	  by dev_pm_opp_enable/disable functions.
354151f4e2bSMauro Carvalho Chehab
355151f4e2bSMauro Carvalho Chehabstruct device
356151f4e2bSMauro Carvalho Chehab	This is used to identify a domain to the OPP layer. The
357151f4e2bSMauro Carvalho Chehab	nature of the device and it's implementation is left to the user of
358151f4e2bSMauro Carvalho Chehab	OPP library such as the SoC framework.
359151f4e2bSMauro Carvalho Chehab
360151f4e2bSMauro Carvalho ChehabOverall, in a simplistic view, the data structure operations is represented as
361151f4e2bSMauro Carvalho Chehabfollowing::
362151f4e2bSMauro Carvalho Chehab
363151f4e2bSMauro Carvalho Chehab  Initialization / modification:
364151f4e2bSMauro Carvalho Chehab              +-----+        /- dev_pm_opp_enable
365151f4e2bSMauro Carvalho Chehab  dev_pm_opp_add --> | opp | <-------
366151f4e2bSMauro Carvalho Chehab    |         +-----+        \- dev_pm_opp_disable
367151f4e2bSMauro Carvalho Chehab    \-------> domain_info(device)
368151f4e2bSMauro Carvalho Chehab
369151f4e2bSMauro Carvalho Chehab  Search functions:
370151f4e2bSMauro Carvalho Chehab               /-- dev_pm_opp_find_freq_ceil  ---\   +-----+
371151f4e2bSMauro Carvalho Chehab  domain_info<---- dev_pm_opp_find_freq_exact -----> | opp |
372151f4e2bSMauro Carvalho Chehab               \-- dev_pm_opp_find_freq_floor ---/   +-----+
373151f4e2bSMauro Carvalho Chehab
374151f4e2bSMauro Carvalho Chehab  Retrieval functions:
375151f4e2bSMauro Carvalho Chehab  +-----+     /- dev_pm_opp_get_voltage
376151f4e2bSMauro Carvalho Chehab  | opp | <---
377151f4e2bSMauro Carvalho Chehab  +-----+     \- dev_pm_opp_get_freq
378151f4e2bSMauro Carvalho Chehab
379151f4e2bSMauro Carvalho Chehab  domain_info <- dev_pm_opp_get_opp_count
380