[PATCH V5 1/3] OPP: Redefine bindings to overcome shortcomings

Rob Herring robherring2 at gmail.com
Wed May 20 06:27:59 PDT 2015


On Tue, May 19, 2015 at 10:41 PM, Viresh Kumar <viresh.kumar at linaro.org> wrote:
> Current OPP (Operating performance point) DT bindings are proven to be
> insufficient at multiple instances.
>
> The shortcomings we are trying to solve here:
>
> - Getting clock/voltage/current rails sharing information between CPUs.
>   Shared by all cores vs independent clock per core vs shared clock per
>   cluster.
>
> - Support for specifying current levels along with voltages.
>
> - Support for multiple regulators.
>
> - Support for turbo modes.
>
> - Other per OPP settings: transition latencies, disabled status, etc.?
>
> - Expandability of OPPs in future.
>
> This patch introduces new bindings "operating-points-v2" to get these problems
> solved. Refer to the bindings for more details.
>
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>

This looks good to me:

Reviewed-by: Rob Herring <robh at kernel.org>

As I've mentioned before, I would like to see some users' acks on this as well.

Rob

> ---
>  Documentation/devicetree/bindings/power/opp.txt | 379 +++++++++++++++++++++++-
>  1 file changed, 375 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/power/opp.txt b/Documentation/devicetree/bindings/power/opp.txt
> index 74499e5033fc..d132e2927b21 100644
> --- a/Documentation/devicetree/bindings/power/opp.txt
> +++ b/Documentation/devicetree/bindings/power/opp.txt
> @@ -1,8 +1,19 @@
> -* Generic OPP Interface
> +Generic OPP (Operating Performance Points) Bindings
> +----------------------------------------------------
>
> -SoCs have a standard set of tuples consisting of frequency and
> -voltage pairs that the device will support per voltage domain. These
> -are called Operating Performance Points or OPPs.
> +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
> @@ -23,3 +34,363 @@ cpu at 0 {
>                 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 descriptor in their DT node. The OPP core will use this phandle
> +to find the operating points for the device.
> +
> +
> +* OPP Descriptor 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 descriptor'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.
> +
> +
> +* 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.
> +
> +- 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 at 0 {
> +                       compatible = "arm,cortex-a9";
> +                       reg = <0>;
> +                       next-level-cache = <&L2>;
> +                       clocks = <&clk_controller 0>;
> +                       clock-names = "cpu";
> +                       opp-supply = <&cpu_supply0>;
> +                       operating-points-v2 = <&cpu0_opp>;
> +               };
> +
> +               cpu at 1 {
> +                       compatible = "arm,cortex-a9";
> +                       reg = <1>;
> +                       next-level-cache = <&L2>;
> +                       clocks = <&clk_controller 0>;
> +                       clock-names = "cpu";
> +                       opp-supply = <&cpu_supply0>;
> +                       operating-points-v2 = <&cpu0_opp>;
> +               };
> +       };
> +
> +       cpu0_opp: opp0 {
> +               compatible = "operating-points-v2";
> +               opp-shared;
> +
> +               entry00 {
> +                       opp-hz = <1000000000>;
> +                       opp-microvolt = <970000 975000 985000>;
> +                       opp-microamp = <70000>;
> +                       clock-latency-ns = <300000>;
> +               };
> +               entry01 {
> +                       opp-hz = <1100000000>;
> +                       opp-microvolt = <980000 1000000 1010000>;
> +                       opp-microamp = <80000>;
> +                       clock-latency-ns = <310000>;
> +               };
> +               entry02 {
> +                       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 at 0 {
> +                       compatible = "qcom,krait";
> +                       reg = <0>;
> +                       next-level-cache = <&L2>;
> +                       clocks = <&clk_controller 0>;
> +                       clock-names = "cpu";
> +                       opp-supply = <&cpu_supply0>;
> +                       operating-points-v2 = <&cpu0_opp>;
> +               };
> +
> +               cpu at 1 {
> +                       compatible = "qcom,krait";
> +                       reg = <1>;
> +                       next-level-cache = <&L2>;
> +                       clocks = <&clk_controller 1>;
> +                       clock-names = "cpu";
> +                       opp-supply = <&cpu_supply1>;
> +                       operating-points-v2 = <&cpu0_opp>;
> +               };
> +
> +               cpu at 2 {
> +                       compatible = "qcom,krait";
> +                       reg = <2>;
> +                       next-level-cache = <&L2>;
> +                       clocks = <&clk_controller 2>;
> +                       clock-names = "cpu";
> +                       opp-supply = <&cpu_supply2>;
> +                       operating-points-v2 = <&cpu0_opp>;
> +               };
> +
> +               cpu at 3 {
> +                       compatible = "qcom,krait";
> +                       reg = <3>;
> +                       next-level-cache = <&L2>;
> +                       clocks = <&clk_controller 3>;
> +                       clock-names = "cpu";
> +                       opp-supply = <&cpu_supply3>;
> +                       operating-points-v2 = <&cpu0_opp>;
> +               };
> +       };
> +
> +       cpu0_opp: opp0 {
> +               compatible = "operating-points-v2";
> +
> +               /*
> +                * Missing opp-shared property means CPUs switch DVFS states
> +                * independently.
> +                */
> +
> +               entry00 {
> +                       opp-hz = <1000000000>;
> +                       opp-microvolt = <970000 975000 985000>;
> +                       opp-microamp = <70000>;
> +                       clock-latency-ns = <300000>;
> +               };
> +               entry01 {
> +                       opp-hz = <1100000000>;
> +                       opp-microvolt = <980000 1000000 1010000>;
> +                       opp-microamp = <80000>;
> +                       clock-latency-ns = <310000>;
> +               };
> +               entry02 {
> +                       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 at 0 {
> +                       compatible = "arm,cortex-a7";
> +                       reg = <0>;
> +                       next-level-cache = <&L2>;
> +                       clocks = <&clk_controller 0>;
> +                       clock-names = "cpu";
> +                       opp-supply = <&cpu_supply0>;
> +                       operating-points-v2 = <&cluster0_opp>;
> +               };
> +
> +               cpu at 1 {
> +                       compatible = "arm,cortex-a7";
> +                       reg = <1>;
> +                       next-level-cache = <&L2>;
> +                       clocks = <&clk_controller 0>;
> +                       clock-names = "cpu";
> +                       opp-supply = <&cpu_supply0>;
> +                       operating-points-v2 = <&cluster0_opp>;
> +               };
> +
> +               cpu at 100 {
> +                       compatible = "arm,cortex-a15";
> +                       reg = <100>;
> +                       next-level-cache = <&L2>;
> +                       clocks = <&clk_controller 1>;
> +                       clock-names = "cpu";
> +                       opp-supply = <&cpu_supply1>;
> +                       operating-points-v2 = <&cluster1_opp>;
> +               };
> +
> +               cpu at 101 {
> +                       compatible = "arm,cortex-a15";
> +                       reg = <101>;
> +                       next-level-cache = <&L2>;
> +                       clocks = <&clk_controller 1>;
> +                       clock-names = "cpu";
> +                       opp-supply = <&cpu_supply1>;
> +                       operating-points-v2 = <&cluster1_opp>;
> +               };
> +       };
> +
> +       cluster0_opp: opp0 {
> +               compatible = "operating-points-v2";
> +               opp-shared;
> +
> +               entry00 {
> +                       opp-hz = <1000000000>;
> +                       opp-microvolt = <970000 975000 985000>;
> +                       opp-microamp = <70000>;
> +                       clock-latency-ns = <300000>;
> +               };
> +               entry01 {
> +                       opp-hz = <1100000000>;
> +                       opp-microvolt = <980000 1000000 1010000>;
> +                       opp-microamp = <80000>;
> +                       clock-latency-ns = <310000>;
> +               };
> +               entry02 {
> +                       opp-hz = <1200000000>;
> +                       opp-microvolt = <1025000>;
> +                       opp-microamp = <90000>;
> +                       clock-latency-ns = <290000>;
> +                       turbo-mode;
> +               };
> +       };
> +
> +       cluster1_opp: opp1 {
> +               compatible = "operating-points-v2";
> +               opp-shared;
> +
> +               entry10 {
> +                       opp-hz = <1300000000>;
> +                       opp-microvolt = <1045000 1050000 1055000>;
> +                       opp-microamp = <95000>;
> +                       clock-latency-ns = <400000>;
> +               };
> +               entry11 {
> +                       opp-hz = <1400000000>;
> +                       opp-microvolt = <1075000>;
> +                       opp-microamp = <100000>;
> +                       clock-latency-ns = <400000>;
> +               };
> +               entry12 {
> +                       opp-hz = <1500000000>;
> +                       opp-microvolt = <1010000 1100000 1110000>;
> +                       opp-microamp = <95000>;
> +                       clock-latency-ns = <400000>;
> +                       turbo-mode;
> +               };
> +       };
> +};
> +
> +Example 4: Handling multiple regulators
> +
> +/ {
> +       cpus {
> +               cpu at 0 {
> +                       compatible = "arm,cortex-a7";
> +                       ...
> +
> +                       opp-supply = <&cpu_supply0>, <&cpu_supply1>, <&cpu_supply2>;
> +                       operating-points-v2 = <&cpu0_opp>;
> +               };
> +       };
> +
> +       cpu0_opp: opp0 {
> +               compatible = "operating-points-v2";
> +               opp-shared;
> +
> +               entry00 {
> +                       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 */
> +
> +               entry00 {
> +                       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 */
> +
> +               entry00 {
> +                       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>;
> +               };
> +       };
> +};
> --
> 2.4.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the linux-arm-kernel mailing list