| Generic OPP (Operating Performance Points) Bindings |
| ---------------------------------------------------- |
| |
| Devices work at voltage-current-frequency combinations and some implementations |
| have the liberty of choosing these. These combinations are called Operating |
| Performance Points aka OPPs. This document defines bindings for these OPPs |
| applicable across wide range of devices. For illustration purpose, this document |
| uses CPU as a device. |
| |
| This document contain multiple versions of OPP binding and only one of them |
| should be used per device. |
| |
| Binding 1: operating-points |
| ============================ |
| |
| This binding only supports voltage-frequency pairs. |
| |
| Properties: |
| - operating-points: An array of 2-tuples items, and each item consists |
| of frequency and voltage like <freq-kHz vol-uV>. |
| freq: clock frequency in kHz |
| vol: voltage in microvolt |
| |
| Examples: |
| |
| cpu@0 { |
| compatible = "arm,cortex-a9"; |
| reg = <0>; |
| next-level-cache = <&L2>; |
| operating-points = < |
| /* kHz uV */ |
| 792000 1100000 |
| 396000 950000 |
| 198000 850000 |
| >; |
| }; |
| |
| |
| Binding 2: operating-points-v2 |
| ============================ |
| |
| * Property: operating-points-v2 |
| |
| Devices supporting OPPs must set their "operating-points-v2" property with |
| phandle to a OPP table in their DT node. The OPP core will use this phandle to |
| find the operating points for the device. |
| |
| Devices may want to choose OPP tables at runtime and so can provide a list of |
| phandles here. But only *one* of them should be chosen at runtime. This must be |
| accompanied by a corresponding "operating-points-names" property, to uniquely |
| identify the OPP tables. |
| |
| If required, this can be extended for SoC vendor specfic bindings. Such bindings |
| should be documented as Documentation/devicetree/bindings/power/<vendor>-opp.txt |
| and should have a compatible description like: "operating-points-v2-<vendor>". |
| |
| Optional properties: |
| - operating-points-names: Names of OPP tables (required if multiple OPP |
| tables are present), to uniquely identify them. The same list must be present |
| for all the CPUs which are sharing clock/voltage rails and hence the OPP |
| tables. |
| |
| * OPP Table Node |
| |
| This describes the OPPs belonging to a device. This node can have following |
| properties: |
| |
| Required properties: |
| - compatible: Allow OPPs to express their compatibility. It should be: |
| "operating-points-v2". |
| |
| - OPP nodes: One or more OPP nodes describing voltage-current-frequency |
| combinations. Their name isn't significant but their phandle can be used to |
| reference an OPP. |
| |
| Optional properties: |
| - opp-shared: Indicates that device nodes using this OPP Table Node's phandle |
| switch their DVFS state together, i.e. they share clock/voltage/current lines. |
| Missing property means devices have independent clock/voltage/current lines, |
| but they share OPP tables. |
| |
| - status: Marks the OPP table enabled/disabled. |
| |
| |
| * OPP Node |
| |
| This defines voltage-current-frequency combinations along with other related |
| properties. |
| |
| Required properties: |
| - opp-hz: Frequency in Hz, expressed as a 64-bit big-endian integer. |
| |
| Optional properties: |
| - opp-microvolt: voltage in micro Volts. |
| |
| A single regulator's voltage is specified with an array of size one or three. |
| Single entry is for target voltage and three entries are for <target min max> |
| voltages. |
| |
| Entries for multiple regulators must be present in the same order as |
| regulators are specified in device's DT node. |
| |
| - opp-microamp: The maximum current drawn by the device in microamperes |
| considering system specific parameters (such as transients, process, aging, |
| maximum operating temperature range etc.) as necessary. This may be used to |
| set the most efficient regulator operating mode. |
| |
| Should only be set if opp-microvolt is set for the OPP. |
| |
| Entries for multiple regulators must be present in the same order as |
| regulators are specified in device's DT node. If this property isn't required |
| for few regulators, then this should be marked as zero for them. If it isn't |
| required for any regulator, then this property need not be present. |
| |
| - clock-latency-ns: Specifies the maximum possible transition latency (in |
| nanoseconds) for switching to this OPP from any other OPP. |
| |
| - turbo-mode: Marks the OPP to be used only for turbo modes. Turbo mode is |
| available on some platforms, where the device can run over its operating |
| frequency for a short duration of time limited by the device's power, current |
| and thermal limits. |
| |
| - opp-suspend: Marks the OPP to be used during device suspend. Only one OPP in |
| the table should have this. |
| |
| - status: Marks the node enabled/disabled. |
| |
| Example 1: Single cluster Dual-core ARM cortex A9, switch DVFS states together. |
| |
| / { |
| cpus { |
| #address-cells = <1>; |
| #size-cells = <0>; |
| |
| cpu@0 { |
| compatible = "arm,cortex-a9"; |
| reg = <0>; |
| next-level-cache = <&L2>; |
| clocks = <&clk_controller 0>; |
| clock-names = "cpu"; |
| cpu-supply = <&cpu_supply0>; |
| operating-points-v2 = <&cpu0_opp_table>; |
| }; |
| |
| cpu@1 { |
| compatible = "arm,cortex-a9"; |
| reg = <1>; |
| next-level-cache = <&L2>; |
| clocks = <&clk_controller 0>; |
| clock-names = "cpu"; |
| cpu-supply = <&cpu_supply0>; |
| operating-points-v2 = <&cpu0_opp_table>; |
| }; |
| }; |
| |
| cpu0_opp_table: opp_table0 { |
| compatible = "operating-points-v2"; |
| opp-shared; |
| |
| opp00 { |
| opp-hz = /bits/ 64 <1000000000>; |
| opp-microvolt = <970000 975000 985000>; |
| opp-microamp = <70000>; |
| clock-latency-ns = <300000>; |
| opp-suspend; |
| }; |
| opp01 { |
| opp-hz = /bits/ 64 <1100000000>; |
| opp-microvolt = <980000 1000000 1010000>; |
| opp-microamp = <80000>; |
| clock-latency-ns = <310000>; |
| }; |
| opp02 { |
| opp-hz = /bits/ 64 <1200000000>; |
| opp-microvolt = <1025000>; |
| clock-latency-ns = <290000>; |
| turbo-mode; |
| }; |
| }; |
| }; |
| |
| Example 2: Single cluster, Quad-core Qualcom-krait, switches DVFS states |
| independently. |
| |
| / { |
| cpus { |
| #address-cells = <1>; |
| #size-cells = <0>; |
| |
| cpu@0 { |
| compatible = "qcom,krait"; |
| reg = <0>; |
| next-level-cache = <&L2>; |
| clocks = <&clk_controller 0>; |
| clock-names = "cpu"; |
| cpu-supply = <&cpu_supply0>; |
| operating-points-v2 = <&cpu_opp_table>; |
| }; |
| |
| cpu@1 { |
| compatible = "qcom,krait"; |
| reg = <1>; |
| next-level-cache = <&L2>; |
| clocks = <&clk_controller 1>; |
| clock-names = "cpu"; |
| cpu-supply = <&cpu_supply1>; |
| operating-points-v2 = <&cpu_opp_table>; |
| }; |
| |
| cpu@2 { |
| compatible = "qcom,krait"; |
| reg = <2>; |
| next-level-cache = <&L2>; |
| clocks = <&clk_controller 2>; |
| clock-names = "cpu"; |
| cpu-supply = <&cpu_supply2>; |
| operating-points-v2 = <&cpu_opp_table>; |
| }; |
| |
| cpu@3 { |
| compatible = "qcom,krait"; |
| reg = <3>; |
| next-level-cache = <&L2>; |
| clocks = <&clk_controller 3>; |
| clock-names = "cpu"; |
| cpu-supply = <&cpu_supply3>; |
| operating-points-v2 = <&cpu_opp_table>; |
| }; |
| }; |
| |
| cpu_opp_table: opp_table { |
| compatible = "operating-points-v2"; |
| |
| /* |
| * Missing opp-shared property means CPUs switch DVFS states |
| * independently. |
| */ |
| |
| opp00 { |
| opp-hz = /bits/ 64 <1000000000>; |
| opp-microvolt = <970000 975000 985000>; |
| opp-microamp = <70000>; |
| clock-latency-ns = <300000>; |
| opp-suspend; |
| }; |
| opp01 { |
| opp-hz = /bits/ 64 <1100000000>; |
| opp-microvolt = <980000 1000000 1010000>; |
| opp-microamp = <80000>; |
| clock-latency-ns = <310000>; |
| }; |
| opp02 { |
| opp-hz = /bits/ 64 <1200000000>; |
| opp-microvolt = <1025000>; |
| opp-microamp = <90000; |
| lock-latency-ns = <290000>; |
| turbo-mode; |
| }; |
| }; |
| }; |
| |
| Example 3: Dual-cluster, Dual-core per cluster. CPUs within a cluster switch |
| DVFS state together. |
| |
| / { |
| cpus { |
| #address-cells = <1>; |
| #size-cells = <0>; |
| |
| cpu@0 { |
| compatible = "arm,cortex-a7"; |
| reg = <0>; |
| next-level-cache = <&L2>; |
| clocks = <&clk_controller 0>; |
| clock-names = "cpu"; |
| cpu-supply = <&cpu_supply0>; |
| operating-points-v2 = <&cluster0_opp>; |
| }; |
| |
| cpu@1 { |
| compatible = "arm,cortex-a7"; |
| reg = <1>; |
| next-level-cache = <&L2>; |
| clocks = <&clk_controller 0>; |
| clock-names = "cpu"; |
| cpu-supply = <&cpu_supply0>; |
| operating-points-v2 = <&cluster0_opp>; |
| }; |
| |
| cpu@100 { |
| compatible = "arm,cortex-a15"; |
| reg = <100>; |
| next-level-cache = <&L2>; |
| clocks = <&clk_controller 1>; |
| clock-names = "cpu"; |
| cpu-supply = <&cpu_supply1>; |
| operating-points-v2 = <&cluster1_opp>; |
| }; |
| |
| cpu@101 { |
| compatible = "arm,cortex-a15"; |
| reg = <101>; |
| next-level-cache = <&L2>; |
| clocks = <&clk_controller 1>; |
| clock-names = "cpu"; |
| cpu-supply = <&cpu_supply1>; |
| operating-points-v2 = <&cluster1_opp>; |
| }; |
| }; |
| |
| cluster0_opp: opp_table0 { |
| compatible = "operating-points-v2"; |
| opp-shared; |
| |
| opp00 { |
| opp-hz = /bits/ 64 <1000000000>; |
| opp-microvolt = <970000 975000 985000>; |
| opp-microamp = <70000>; |
| clock-latency-ns = <300000>; |
| opp-suspend; |
| }; |
| opp01 { |
| opp-hz = /bits/ 64 <1100000000>; |
| opp-microvolt = <980000 1000000 1010000>; |
| opp-microamp = <80000>; |
| clock-latency-ns = <310000>; |
| }; |
| opp02 { |
| opp-hz = /bits/ 64 <1200000000>; |
| opp-microvolt = <1025000>; |
| opp-microamp = <90000>; |
| clock-latency-ns = <290000>; |
| turbo-mode; |
| }; |
| }; |
| |
| cluster1_opp: opp_table1 { |
| compatible = "operating-points-v2"; |
| opp-shared; |
| |
| opp10 { |
| opp-hz = /bits/ 64 <1300000000>; |
| opp-microvolt = <1045000 1050000 1055000>; |
| opp-microamp = <95000>; |
| clock-latency-ns = <400000>; |
| opp-suspend; |
| }; |
| opp11 { |
| opp-hz = /bits/ 64 <1400000000>; |
| opp-microvolt = <1075000>; |
| opp-microamp = <100000>; |
| clock-latency-ns = <400000>; |
| }; |
| opp12 { |
| opp-hz = /bits/ 64 <1500000000>; |
| opp-microvolt = <1010000 1100000 1110000>; |
| opp-microamp = <95000>; |
| clock-latency-ns = <400000>; |
| turbo-mode; |
| }; |
| }; |
| }; |
| |
| Example 4: Handling multiple regulators |
| |
| / { |
| cpus { |
| cpu@0 { |
| compatible = "arm,cortex-a7"; |
| ... |
| |
| cpu-supply = <&cpu_supply0>, <&cpu_supply1>, <&cpu_supply2>; |
| operating-points-v2 = <&cpu0_opp_table>; |
| }; |
| }; |
| |
| cpu0_opp_table: opp_table0 { |
| compatible = "operating-points-v2"; |
| opp-shared; |
| |
| opp00 { |
| opp-hz = /bits/ 64 <1000000000>; |
| opp-microvolt = <970000>, /* Supply 0 */ |
| <960000>, /* Supply 1 */ |
| <960000>; /* Supply 2 */ |
| opp-microamp = <70000>, /* Supply 0 */ |
| <70000>, /* Supply 1 */ |
| <70000>; /* Supply 2 */ |
| clock-latency-ns = <300000>; |
| }; |
| |
| /* OR */ |
| |
| opp00 { |
| opp-hz = /bits/ 64 <1000000000>; |
| opp-microvolt = <970000 975000 985000>, /* Supply 0 */ |
| <960000 965000 975000>, /* Supply 1 */ |
| <960000 965000 975000>; /* Supply 2 */ |
| opp-microamp = <70000>, /* Supply 0 */ |
| <70000>, /* Supply 1 */ |
| <70000>; /* Supply 2 */ |
| clock-latency-ns = <300000>; |
| }; |
| |
| /* OR */ |
| |
| opp00 { |
| opp-hz = /bits/ 64 <1000000000>; |
| opp-microvolt = <970000 975000 985000>, /* Supply 0 */ |
| <960000 965000 975000>, /* Supply 1 */ |
| <960000 965000 975000>; /* Supply 2 */ |
| opp-microamp = <70000>, /* Supply 0 */ |
| <0>, /* Supply 1 doesn't need this */ |
| <70000>; /* Supply 2 */ |
| clock-latency-ns = <300000>; |
| }; |
| }; |
| }; |
| |
| Example 5: Multiple OPP tables |
| |
| / { |
| cpus { |
| cpu@0 { |
| compatible = "arm,cortex-a7"; |
| ... |
| |
| cpu-supply = <&cpu_supply> |
| operating-points-v2 = <&cpu0_opp_table_slow>, <&cpu0_opp_table_fast>; |
| operating-points-names = "slow", "fast"; |
| }; |
| }; |
| |
| cpu0_opp_table_slow: opp_table_slow { |
| compatible = "operating-points-v2"; |
| status = "okay"; |
| opp-shared; |
| |
| opp00 { |
| opp-hz = /bits/ 64 <600000000>; |
| ... |
| }; |
| |
| opp01 { |
| opp-hz = /bits/ 64 <800000000>; |
| ... |
| }; |
| }; |
| |
| cpu0_opp_table_fast: opp_table_fast { |
| compatible = "operating-points-v2"; |
| status = "okay"; |
| opp-shared; |
| |
| opp10 { |
| opp-hz = /bits/ 64 <1000000000>; |
| ... |
| }; |
| |
| opp11 { |
| opp-hz = /bits/ 64 <1100000000>; |
| ... |
| }; |
| }; |
| }; |