mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 04:42:12 +00:00
9f20d6815c
On few platforms, for power efficiency, we want the device to be configured for a specific OPP while we put the device in suspend state. Add an optional property in operating-points-v2 bindings for that. Suggested-by: Nishanth Menon <nm@ti.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Acked-by: Nishanth Menon <nm@ti.com> Acked-by: Rob Herring <robh@kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
466 lines
11 KiB
Plaintext
466 lines
11 KiB
Plaintext
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
|
|
|
|
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 = <1000000000>;
|
|
opp-microvolt = <970000 975000 985000>;
|
|
opp-microamp = <70000>;
|
|
clock-latency-ns = <300000>;
|
|
opp-suspend;
|
|
};
|
|
opp01 {
|
|
opp-hz = <1100000000>;
|
|
opp-microvolt = <980000 1000000 1010000>;
|
|
opp-microamp = <80000>;
|
|
clock-latency-ns = <310000>;
|
|
};
|
|
opp02 {
|
|
opp-hz = <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 = <1000000000>;
|
|
opp-microvolt = <970000 975000 985000>;
|
|
opp-microamp = <70000>;
|
|
clock-latency-ns = <300000>;
|
|
opp-suspend;
|
|
};
|
|
opp01 {
|
|
opp-hz = <1100000000>;
|
|
opp-microvolt = <980000 1000000 1010000>;
|
|
opp-microamp = <80000>;
|
|
clock-latency-ns = <310000>;
|
|
};
|
|
opp02 {
|
|
opp-hz = <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 = <1000000000>;
|
|
opp-microvolt = <970000 975000 985000>;
|
|
opp-microamp = <70000>;
|
|
clock-latency-ns = <300000>;
|
|
opp-suspend;
|
|
};
|
|
opp01 {
|
|
opp-hz = <1100000000>;
|
|
opp-microvolt = <980000 1000000 1010000>;
|
|
opp-microamp = <80000>;
|
|
clock-latency-ns = <310000>;
|
|
};
|
|
opp02 {
|
|
opp-hz = <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 = <1300000000>;
|
|
opp-microvolt = <1045000 1050000 1055000>;
|
|
opp-microamp = <95000>;
|
|
clock-latency-ns = <400000>;
|
|
opp-suspend;
|
|
};
|
|
opp11 {
|
|
opp-hz = <1400000000>;
|
|
opp-microvolt = <1075000>;
|
|
opp-microamp = <100000>;
|
|
clock-latency-ns = <400000>;
|
|
};
|
|
opp12 {
|
|
opp-hz = <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 = <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 = <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 = <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 = <600000000>;
|
|
...
|
|
};
|
|
|
|
opp01 {
|
|
opp-hz = <800000000>;
|
|
...
|
|
};
|
|
};
|
|
|
|
cpu0_opp_table_fast: opp_table_fast {
|
|
compatible = "operating-points-v2";
|
|
status = "okay";
|
|
opp-shared;
|
|
|
|
opp10 {
|
|
opp-hz = <1000000000>;
|
|
...
|
|
};
|
|
|
|
opp11 {
|
|
opp-hz = <1100000000>;
|
|
...
|
|
};
|
|
};
|
|
};
|