• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Generic OPP (Operating Performance Points) Bindings
2----------------------------------------------------
3
4Devices work at voltage-current-frequency combinations and some implementations
5have the liberty of choosing these. These combinations are called Operating
6Performance Points aka OPPs. This document defines bindings for these OPPs
7applicable across wide range of devices. For illustration purpose, this document
8uses CPU as a device.
9
10This document contain multiple versions of OPP binding and only one of them
11should be used per device.
12
13Binding 1: operating-points
14============================
15
16This binding only supports voltage-frequency pairs.
17
18Properties:
19- operating-points: An array of 2-tuples items, and each item consists
20  of frequency and voltage like <freq-kHz vol-uV>.
21	freq: clock frequency in kHz
22	vol: voltage in microvolt
23
24Examples:
25
26cpu@0 {
27	compatible = "arm,cortex-a9";
28	reg = <0>;
29	next-level-cache = <&L2>;
30	operating-points = <
31		/* kHz    uV */
32		792000  1100000
33		396000  950000
34		198000  850000
35	>;
36};
37
38
39Binding 2: operating-points-v2
40============================
41
42* Property: operating-points-v2
43
44Devices supporting OPPs must set their "operating-points-v2" property with
45phandle to a OPP table in their DT node. The OPP core will use this phandle to
46find the operating points for the device.
47
48This can contain more than one phandle for power domain providers that provide
49multiple power domains. That is, one phandle for each power domain. If only one
50phandle is available, then the same OPP table will be used for all power domains
51provided by the power domain provider.
52
53If required, this can be extended for SoC vendor specific bindings. Such bindings
54should be documented as Documentation/devicetree/bindings/power/<vendor>-opp.txt
55and should have a compatible description like: "operating-points-v2-<vendor>".
56
57* OPP Table Node
58
59This describes the OPPs belonging to a device. This node can have following
60properties:
61
62Required properties:
63- compatible: Allow OPPs to express their compatibility. It should be:
64  "operating-points-v2".
65
66- OPP nodes: One or more OPP nodes describing voltage-current-frequency
67  combinations. Their name isn't significant but their phandle can be used to
68  reference an OPP.
69
70Optional properties:
71- opp-shared: Indicates that device nodes using this OPP Table Node's phandle
72  switch their DVFS state together, i.e. they share clock/voltage/current lines.
73  Missing property means devices have independent clock/voltage/current lines,
74  but they share OPP tables.
75
76- status: Marks the OPP table enabled/disabled.
77
78
79* OPP Node
80
81This defines voltage-current-frequency combinations along with other related
82properties.
83
84Required properties:
85- opp-hz: Frequency in Hz, expressed as a 64-bit big-endian integer. This is a
86  required property for all device nodes but devices like power domains. The
87  power domain nodes must have another (implementation dependent) property which
88  uniquely identifies the OPP nodes.
89
90Optional properties:
91- opp-microvolt: voltage in micro Volts.
92
93  A single regulator's voltage is specified with an array of size one or three.
94  Single entry is for target voltage and three entries are for <target min max>
95  voltages.
96
97  Entries for multiple regulators shall be provided in the same field separated
98  by angular brackets <>. The OPP binding doesn't provide any provisions to
99  relate the values to their power supplies or the order in which the supplies
100  need to be configured and that is left for the implementation specific
101  binding.
102
103  Entries for all regulators shall be of the same size, i.e. either all use a
104  single value or triplets.
105
106- opp-microvolt-<name>: Named opp-microvolt property. This is exactly similar to
107  the above opp-microvolt property, but allows multiple voltage ranges to be
108  provided for the same OPP. At runtime, the platform can pick a <name> and
109  matching opp-microvolt-<name> property will be enabled for all OPPs. If the
110  platform doesn't pick a specific <name> or the <name> doesn't match with any
111  opp-microvolt-<name> properties, then opp-microvolt property shall be used, if
112  present.
113
114- opp-microamp: The maximum current drawn by the device in microamperes
115  considering system specific parameters (such as transients, process, aging,
116  maximum operating temperature range etc.) as necessary. This may be used to
117  set the most efficient regulator operating mode.
118
119  Should only be set if opp-microvolt is set for the OPP.
120
121  Entries for multiple regulators shall be provided in the same field separated
122  by angular brackets <>. If current values aren't required for a regulator,
123  then it shall be filled with 0. If current values aren't required for any of
124  the regulators, then this field is not required. The OPP binding doesn't
125  provide any provisions to relate the values to their power supplies or the
126  order in which the supplies need to be configured and that is left for the
127  implementation specific binding.
128
129- opp-microamp-<name>: Named opp-microamp property. Similar to
130  opp-microvolt-<name> property, but for microamp instead.
131
132- clock-latency-ns: Specifies the maximum possible transition latency (in
133  nanoseconds) for switching to this OPP from any other OPP.
134
135- turbo-mode: Marks the OPP to be used only for turbo modes. Turbo mode is
136  available on some platforms, where the device can run over its operating
137  frequency for a short duration of time limited by the device's power, current
138  and thermal limits.
139
140- opp-suspend: Marks the OPP to be used during device suspend. Only one OPP in
141  the table should have this.
142
143- opp-supported-hw: This enables us to select only a subset of OPPs from the
144  larger OPP table, based on what version of the hardware we are running on. We
145  still can't have multiple nodes with the same opp-hz value in OPP table.
146
147  It's a user defined array containing a hierarchy of hardware version numbers,
148  supported by the OPP. For example: a platform with hierarchy of three levels
149  of versions (A, B and C), this field should be like <X Y Z>, where X
150  corresponds to Version hierarchy A, Y corresponds to version hierarchy B and Z
151  corresponds to version hierarchy C.
152
153  Each level of hierarchy is represented by a 32 bit value, and so there can be
154  only 32 different supported version per hierarchy. i.e. 1 bit per version. A
155  value of 0xFFFFFFFF will enable the OPP for all versions for that hierarchy
156  level. And a value of 0x00000000 will disable the OPP completely, and so we
157  never want that to happen.
158
159  If 32 values aren't sufficient for a version hierarchy, than that version
160  hierarchy can be contained in multiple 32 bit values. i.e. <X Y Z1 Z2> in the
161  above example, Z1 & Z2 refer to the version hierarchy Z.
162
163- status: Marks the node enabled/disabled.
164
165- required-opps: This contains phandle to an OPP node in another device's OPP
166  table. It may contain an array of phandles, where each phandle points to an
167  OPP of a different device. It should not contain multiple phandles to the OPP
168  nodes in the same OPP table. This specifies the minimum required OPP of the
169  device(s), whose OPP's phandle is present in this property, for the
170  functioning of the current device at the current OPP (where this property is
171  present).
172
173Example 1: Single cluster Dual-core ARM cortex A9, switch DVFS states together.
174
175/ {
176	cpus {
177		#address-cells = <1>;
178		#size-cells = <0>;
179
180		cpu@0 {
181			compatible = "arm,cortex-a9";
182			reg = <0>;
183			next-level-cache = <&L2>;
184			clocks = <&clk_controller 0>;
185			clock-names = "cpu";
186			cpu-supply = <&cpu_supply0>;
187			operating-points-v2 = <&cpu0_opp_table>;
188		};
189
190		cpu@1 {
191			compatible = "arm,cortex-a9";
192			reg = <1>;
193			next-level-cache = <&L2>;
194			clocks = <&clk_controller 0>;
195			clock-names = "cpu";
196			cpu-supply = <&cpu_supply0>;
197			operating-points-v2 = <&cpu0_opp_table>;
198		};
199	};
200
201	cpu0_opp_table: opp_table0 {
202		compatible = "operating-points-v2";
203		opp-shared;
204
205		opp-1000000000 {
206			opp-hz = /bits/ 64 <1000000000>;
207			opp-microvolt = <975000 970000 985000>;
208			opp-microamp = <70000>;
209			clock-latency-ns = <300000>;
210			opp-suspend;
211		};
212		opp-1100000000 {
213			opp-hz = /bits/ 64 <1100000000>;
214			opp-microvolt = <1000000 980000 1010000>;
215			opp-microamp = <80000>;
216			clock-latency-ns = <310000>;
217		};
218		opp-1200000000 {
219			opp-hz = /bits/ 64 <1200000000>;
220			opp-microvolt = <1025000>;
221			clock-latency-ns = <290000>;
222			turbo-mode;
223		};
224	};
225};
226
227Example 2: Single cluster, Quad-core Qualcom-krait, switches DVFS states
228independently.
229
230/ {
231	cpus {
232		#address-cells = <1>;
233		#size-cells = <0>;
234
235		cpu@0 {
236			compatible = "qcom,krait";
237			reg = <0>;
238			next-level-cache = <&L2>;
239			clocks = <&clk_controller 0>;
240			clock-names = "cpu";
241			cpu-supply = <&cpu_supply0>;
242			operating-points-v2 = <&cpu_opp_table>;
243		};
244
245		cpu@1 {
246			compatible = "qcom,krait";
247			reg = <1>;
248			next-level-cache = <&L2>;
249			clocks = <&clk_controller 1>;
250			clock-names = "cpu";
251			cpu-supply = <&cpu_supply1>;
252			operating-points-v2 = <&cpu_opp_table>;
253		};
254
255		cpu@2 {
256			compatible = "qcom,krait";
257			reg = <2>;
258			next-level-cache = <&L2>;
259			clocks = <&clk_controller 2>;
260			clock-names = "cpu";
261			cpu-supply = <&cpu_supply2>;
262			operating-points-v2 = <&cpu_opp_table>;
263		};
264
265		cpu@3 {
266			compatible = "qcom,krait";
267			reg = <3>;
268			next-level-cache = <&L2>;
269			clocks = <&clk_controller 3>;
270			clock-names = "cpu";
271			cpu-supply = <&cpu_supply3>;
272			operating-points-v2 = <&cpu_opp_table>;
273		};
274	};
275
276	cpu_opp_table: opp_table {
277		compatible = "operating-points-v2";
278
279		/*
280		 * Missing opp-shared property means CPUs switch DVFS states
281		 * independently.
282		 */
283
284		opp-1000000000 {
285			opp-hz = /bits/ 64 <1000000000>;
286			opp-microvolt = <975000 970000 985000>;
287			opp-microamp = <70000>;
288			clock-latency-ns = <300000>;
289			opp-suspend;
290		};
291		opp-1100000000 {
292			opp-hz = /bits/ 64 <1100000000>;
293			opp-microvolt = <1000000 980000 1010000>;
294			opp-microamp = <80000>;
295			clock-latency-ns = <310000>;
296		};
297		opp-1200000000 {
298			opp-hz = /bits/ 64 <1200000000>;
299			opp-microvolt = <1025000>;
300			opp-microamp = <90000;
301			lock-latency-ns = <290000>;
302			turbo-mode;
303		};
304	};
305};
306
307Example 3: Dual-cluster, Dual-core per cluster. CPUs within a cluster switch
308DVFS state together.
309
310/ {
311	cpus {
312		#address-cells = <1>;
313		#size-cells = <0>;
314
315		cpu@0 {
316			compatible = "arm,cortex-a7";
317			reg = <0>;
318			next-level-cache = <&L2>;
319			clocks = <&clk_controller 0>;
320			clock-names = "cpu";
321			cpu-supply = <&cpu_supply0>;
322			operating-points-v2 = <&cluster0_opp>;
323		};
324
325		cpu@1 {
326			compatible = "arm,cortex-a7";
327			reg = <1>;
328			next-level-cache = <&L2>;
329			clocks = <&clk_controller 0>;
330			clock-names = "cpu";
331			cpu-supply = <&cpu_supply0>;
332			operating-points-v2 = <&cluster0_opp>;
333		};
334
335		cpu@100 {
336			compatible = "arm,cortex-a15";
337			reg = <100>;
338			next-level-cache = <&L2>;
339			clocks = <&clk_controller 1>;
340			clock-names = "cpu";
341			cpu-supply = <&cpu_supply1>;
342			operating-points-v2 = <&cluster1_opp>;
343		};
344
345		cpu@101 {
346			compatible = "arm,cortex-a15";
347			reg = <101>;
348			next-level-cache = <&L2>;
349			clocks = <&clk_controller 1>;
350			clock-names = "cpu";
351			cpu-supply = <&cpu_supply1>;
352			operating-points-v2 = <&cluster1_opp>;
353		};
354	};
355
356	cluster0_opp: opp_table0 {
357		compatible = "operating-points-v2";
358		opp-shared;
359
360		opp-1000000000 {
361			opp-hz = /bits/ 64 <1000000000>;
362			opp-microvolt = <975000 970000 985000>;
363			opp-microamp = <70000>;
364			clock-latency-ns = <300000>;
365			opp-suspend;
366		};
367		opp-1100000000 {
368			opp-hz = /bits/ 64 <1100000000>;
369			opp-microvolt = <1000000 980000 1010000>;
370			opp-microamp = <80000>;
371			clock-latency-ns = <310000>;
372		};
373		opp-1200000000 {
374			opp-hz = /bits/ 64 <1200000000>;
375			opp-microvolt = <1025000>;
376			opp-microamp = <90000>;
377			clock-latency-ns = <290000>;
378			turbo-mode;
379		};
380	};
381
382	cluster1_opp: opp_table1 {
383		compatible = "operating-points-v2";
384		opp-shared;
385
386		opp-1300000000 {
387			opp-hz = /bits/ 64 <1300000000>;
388			opp-microvolt = <1050000 1045000 1055000>;
389			opp-microamp = <95000>;
390			clock-latency-ns = <400000>;
391			opp-suspend;
392		};
393		opp-1400000000 {
394			opp-hz = /bits/ 64 <1400000000>;
395			opp-microvolt = <1075000>;
396			opp-microamp = <100000>;
397			clock-latency-ns = <400000>;
398		};
399		opp-1500000000 {
400			opp-hz = /bits/ 64 <1500000000>;
401			opp-microvolt = <1100000 1010000 1110000>;
402			opp-microamp = <95000>;
403			clock-latency-ns = <400000>;
404			turbo-mode;
405		};
406	};
407};
408
409Example 4: Handling multiple regulators
410
411/ {
412	cpus {
413		cpu@0 {
414			compatible = "vendor,cpu-type";
415			...
416
417			vcc0-supply = <&cpu_supply0>;
418			vcc1-supply = <&cpu_supply1>;
419			vcc2-supply = <&cpu_supply2>;
420			operating-points-v2 = <&cpu0_opp_table>;
421		};
422	};
423
424	cpu0_opp_table: opp_table0 {
425		compatible = "operating-points-v2";
426		opp-shared;
427
428		opp-1000000000 {
429			opp-hz = /bits/ 64 <1000000000>;
430			opp-microvolt = <970000>, /* Supply 0 */
431					<960000>, /* Supply 1 */
432					<960000>; /* Supply 2 */
433			opp-microamp =  <70000>,  /* Supply 0 */
434					<70000>,  /* Supply 1 */
435					<70000>;  /* Supply 2 */
436			clock-latency-ns = <300000>;
437		};
438
439		/* OR */
440
441		opp-1000000000 {
442			opp-hz = /bits/ 64 <1000000000>;
443			opp-microvolt = <975000 970000 985000>, /* Supply 0 */
444					<965000 960000 975000>, /* Supply 1 */
445					<965000 960000 975000>; /* Supply 2 */
446			opp-microamp =  <70000>,		/* Supply 0 */
447					<70000>,		/* Supply 1 */
448					<70000>;		/* Supply 2 */
449			clock-latency-ns = <300000>;
450		};
451
452		/* OR */
453
454		opp-1000000000 {
455			opp-hz = /bits/ 64 <1000000000>;
456			opp-microvolt = <975000 970000 985000>, /* Supply 0 */
457					<965000 960000 975000>, /* Supply 1 */
458					<965000 960000 975000>; /* Supply 2 */
459			opp-microamp =  <70000>,		/* Supply 0 */
460					<0>,			/* Supply 1 doesn't need this */
461					<70000>;		/* Supply 2 */
462			clock-latency-ns = <300000>;
463		};
464	};
465};
466
467Example 5: opp-supported-hw
468(example: three level hierarchy of versions: cuts, substrate and process)
469
470/ {
471	cpus {
472		cpu@0 {
473			compatible = "arm,cortex-a7";
474			...
475
476			cpu-supply = <&cpu_supply>
477			operating-points-v2 = <&cpu0_opp_table_slow>;
478		};
479	};
480
481	opp_table {
482		compatible = "operating-points-v2";
483		opp-shared;
484
485		opp-600000000 {
486			/*
487			 * Supports all substrate and process versions for 0xF
488			 * cuts, i.e. only first four cuts.
489			 */
490			opp-supported-hw = <0xF 0xFFFFFFFF 0xFFFFFFFF>
491			opp-hz = /bits/ 64 <600000000>;
492			opp-microvolt = <915000 900000 925000>;
493			...
494		};
495
496		opp-800000000 {
497			/*
498			 * Supports:
499			 * - cuts: only one, 6th cut (represented by 6th bit).
500			 * - substrate: supports 16 different substrate versions
501			 * - process: supports 9 different process versions
502			 */
503			opp-supported-hw = <0x20 0xff0000ff 0x0000f4f0>
504			opp-hz = /bits/ 64 <800000000>;
505			opp-microvolt = <915000 900000 925000>;
506			...
507		};
508	};
509};
510
511Example 6: opp-microvolt-<name>, opp-microamp-<name>:
512(example: device with two possible microvolt ranges: slow and fast)
513
514/ {
515	cpus {
516		cpu@0 {
517			compatible = "arm,cortex-a7";
518			...
519
520			operating-points-v2 = <&cpu0_opp_table>;
521		};
522	};
523
524	cpu0_opp_table: opp_table0 {
525		compatible = "operating-points-v2";
526		opp-shared;
527
528		opp-1000000000 {
529			opp-hz = /bits/ 64 <1000000000>;
530			opp-microvolt-slow = <915000 900000 925000>;
531			opp-microvolt-fast = <975000 970000 985000>;
532			opp-microamp-slow =  <70000>;
533			opp-microamp-fast =  <71000>;
534		};
535
536		opp-1200000000 {
537			opp-hz = /bits/ 64 <1200000000>;
538			opp-microvolt-slow = <915000 900000 925000>, /* Supply vcc0 */
539					      <925000 910000 935000>; /* Supply vcc1 */
540			opp-microvolt-fast = <975000 970000 985000>, /* Supply vcc0 */
541					     <965000 960000 975000>; /* Supply vcc1 */
542			opp-microamp =  <70000>; /* Will be used for both slow/fast */
543		};
544	};
545};
546