diff mbox series

[v6,1/2] dt-bindings: cpufreq: Document support for Airoha EN7581 CPUFreq

Message ID 20241204182323.15192-1-ansuelsmth@gmail.com
State New
Headers show
Series [v6,1/2] dt-bindings: cpufreq: Document support for Airoha EN7581 CPUFreq | expand

Commit Message

Christian Marangi Dec. 4, 2024, 6:23 p.m. UTC
Document required property for Airoha EN7581 CPUFreq .

On newer Airoha SoC, CPU Frequency is scaled indirectly with SMCCC commands
to ATF and no clocks are exposed to the OS.

The SoC have performance state described by ID for each OPP, for this a
Power Domain is used that sets the performance state ID according to the
required OPPs defined in the CPU OPP tables.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes v6:
- No changes
Changes v5:
- Add Reviewed-by tag
- Fix OPP node name error
- Rename cpufreq node name to power-domain
- Rename CPU node power domain name to perf
- Add model and compatible to example
Changes v4:
- Add this patch

 .../cpufreq/airoha,en7581-cpufreq.yaml        | 262 ++++++++++++++++++
 1 file changed, 262 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/cpufreq/airoha,en7581-cpufreq.yaml

Comments

Ulf Hansson Dec. 6, 2024, 8:13 a.m. UTC | #1
On Thu, 5 Dec 2024 at 19:01, Christian Marangi <ansuelsmth@gmail.com> wrote:
>
> On Thu, Dec 05, 2024 at 05:07:07PM +0100, Ulf Hansson wrote:
> > On Wed, 4 Dec 2024 at 19:24, Christian Marangi <ansuelsmth@gmail.com> wrote:
> > >
> > > Document required property for Airoha EN7581 CPUFreq .
> > >
> > > On newer Airoha SoC, CPU Frequency is scaled indirectly with SMCCC commands
> > > to ATF and no clocks are exposed to the OS.
> > >
> > > The SoC have performance state described by ID for each OPP, for this a
> > > Power Domain is used that sets the performance state ID according to the
> > > required OPPs defined in the CPU OPP tables.
> >
> > To clarify this, I would rather speak about a performance-domain with
> > performance-levels, where each level corresponds to a frequency that
> > is controlled by the FW/HW.
>
> (If Rob notice this and gets angry :P , v6 was posted 10 minutes before
> the review from Rob, big coincidence. No intention of ignoring the
> comments)
>
> I notice that power-domain schema also accepts node with
> performance-domain. My concern is that the API we would use
> (power-domain related) expect #power-domain-cells property and might
> reject init with #power-performance-cells.

You understood me wrong. I am not suggesting to use #power-performance-cells.

The more established way to model performance domains is using
"power-domain-cells" (a power-domain provider), which is capable of
performance scaling.

>
> I have to check this but I think it's better to have a clear idea of
> what the schema should be.
>
> >
> > >
> > > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> > > Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
> > > ---
> > > Changes v6:
> > > - No changes
> > > Changes v5:
> > > - Add Reviewed-by tag
> > > - Fix OPP node name error
> > > - Rename cpufreq node name to power-domain
> > > - Rename CPU node power domain name to perf
> > > - Add model and compatible to example
> > > Changes v4:
> > > - Add this patch
> > >
> > >  .../cpufreq/airoha,en7581-cpufreq.yaml        | 262 ++++++++++++++++++
> > >  1 file changed, 262 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/cpufreq/airoha,en7581-cpufreq.yaml
> > >
> > > diff --git a/Documentation/devicetree/bindings/cpufreq/airoha,en7581-cpufreq.yaml b/Documentation/devicetree/bindings/cpufreq/airoha,en7581-cpufreq.yaml
> > > new file mode 100644
> > > index 000000000000..7e36fa037e4b
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/cpufreq/airoha,en7581-cpufreq.yaml
> > > @@ -0,0 +1,262 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/cpufreq/airoha,en7581-cpufreq.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Airoha EN7581 CPUFreq
> > > +
> > > +maintainers:
> > > +  - Christian Marangi <ansuelsmth@gmail.com>
> > > +
> > > +description: |
> > > +  On newer Airoha SoC, CPU Frequency is scaled indirectly with SMCCC commands
> > > +  to ATF and no clocks are exposed to the OS.
> > > +
> > > +  The SoC have performance state described by ID for each OPP, for this a
> > > +  Power Domain is used that sets the performance state ID according to the
> > > +  required OPPs defined in the CPU OPP tables.
> > > +
> > > +properties:
> > > +  compatible:
> > > +    const: airoha,en7581-cpufreq
> > > +
> > > +  '#clock-cells':
> > > +    const: 0
> >
> > I think Rob questioned this too. Why do we need a clock provider here?
> >
> > If this is only to keep the CPUfreq DT driver happy, I think this
> > should be dropped. There is only a performance-domain here, right?
> >
>
> As said in v5, the API is fun.
> SMC have an OP to request the current frequency and that is provided in
> MHz.
>
> Then it does have a command to se the global frequency and that is in
> Index.
>
> Each index rapresent a particular frequency.
>
> For CPUFreq-DT a clock is mandatory, and is also good to provide one.

Well, that's a separate discussion. Let's settle on the bindings first.

> But in v5 Rob was O.K. for the clock. The main complain is for the OPP
> table.

We need the OPP table, else how would we be able to describe the
available performance levels?

>
> > > +
> > > +  '#power-domain-cells':
> > > +    const: 0
> > > +
> > > +  operating-points-v2: true
> > > +
> > > +required:
> > > +  - compatible
> > > +  - '#clock-cells'
> > > +  - '#power-domain-cells'
> > > +  - operating-points-v2
> > > +
> > > +additionalProperties: false
> > > +
> > > +examples:
> > > +  - |
> > > +    / {
> > > +        model = "Airoha EN7581 Evaluation Board";
> > > +        compatible = "airoha,en7581-evb", "airoha,en7581";
> > > +
> > > +        #address-cells = <2>;
> > > +       #size-cells = <2>;
> > > +
> > > +        cpus {
> > > +            #address-cells = <1>;
> > > +            #size-cells = <0>;
> > > +
> > > +            cpu0: cpu@0 {
> > > +                device_type = "cpu";
> > > +                compatible = "arm,cortex-a53";
> > > +                reg = <0x0>;
> > > +                operating-points-v2 = <&cpu_opp_table>;
> > > +                enable-method = "psci";
> > > +                clocks = <&cpu_pd>;
> > > +                clock-names = "cpu";
> > > +                power-domains = <&cpu_pd>;
> > > +                power-domain-names = "perf";
> > > +                next-level-cache = <&l2>;
> > > +                #cooling-cells = <2>;
> > > +            };
> > > +
> > > +            cpu1: cpu@1 {
> > > +                device_type = "cpu";
> > > +                compatible = "arm,cortex-a53";
> > > +                reg = <0x1>;
> > > +                operating-points-v2 = <&cpu_opp_table>;
> > > +                enable-method = "psci";
> > > +                clocks = <&cpu_pd>;
> > > +                clock-names = "cpu";
> > > +                power-domains = <&cpu_pd>;
> > > +                power-domain-names = "perf";
> > > +                next-level-cache = <&l2>;
> > > +                #cooling-cells = <2>;
> > > +            };
> > > +
> > > +            cpu2: cpu@2 {
> > > +                device_type = "cpu";
> > > +                compatible = "arm,cortex-a53";
> > > +                reg = <0x2>;
> > > +                operating-points-v2 = <&cpu_opp_table>;
> > > +                enable-method = "psci";
> > > +                clocks = <&cpu_pd>;
> > > +                clock-names = "cpu";
> > > +                power-domains = <&cpu_pd>;
> > > +                power-domain-names = "perf";
> > > +                next-level-cache = <&l2>;
> > > +                #cooling-cells = <2>;
> > > +            };
> > > +
> > > +            cpu3: cpu@3 {
> > > +                device_type = "cpu";
> > > +                compatible = "arm,cortex-a53";
> > > +                reg = <0x3>;
> > > +                operating-points-v2 = <&cpu_opp_table>;
> > > +                enable-method = "psci";
> > > +                clocks = <&cpu_pd>;
> > > +                clock-names = "cpu";
> > > +                power-domains = <&cpu_pd>;
> > > +                power-domain-names = "perf";
> > > +                next-level-cache = <&l2>;
> > > +                #cooling-cells = <2>;
> > > +            };
> > > +        };
> > > +
> > > +        cpu_opp_table: opp-table-cpu {
> > > +            compatible = "operating-points-v2";
> > > +            opp-shared;
> > > +
> > > +            opp-500000000 {
> > > +                opp-hz = /bits/ 64 <500000000>;
> > > +                required-opps = <&smcc_opp0>;
> > > +            };
> > > +
> > > +            opp-550000000 {
> > > +                opp-hz = /bits/ 64 <550000000>;
> > > +                required-opps = <&smcc_opp1>;
> > > +            };
> > > +
> > > +            opp-600000000 {
> > > +                opp-hz = /bits/ 64 <600000000>;
> > > +                required-opps = <&smcc_opp2>;
> > > +            };
> > > +
> > > +            opp-650000000 {
> > > +                opp-hz = /bits/ 64 <650000000>;
> > > +                required-opps = <&smcc_opp3>;
> > > +            };
> > > +
> > > +            opp-7000000000 {
> > > +                opp-hz = /bits/ 64 <700000000>;
> > > +                required-opps = <&smcc_opp4>;
> > > +            };
> > > +
> > > +            opp-7500000000 {
> > > +                opp-hz = /bits/ 64 <750000000>;
> > > +                required-opps = <&smcc_opp5>;
> > > +            };
> > > +
> > > +            opp-8000000000 {
> > > +                opp-hz = /bits/ 64 <800000000>;
> > > +                required-opps = <&smcc_opp6>;
> > > +            };
> > > +
> > > +            opp-8500000000 {
> > > +                opp-hz = /bits/ 64 <850000000>;
> > > +                required-opps = <&smcc_opp7>;
> > > +            };
> > > +
> > > +            opp-9000000000 {
> > > +                opp-hz = /bits/ 64 <900000000>;
> > > +                required-opps = <&smcc_opp8>;
> > > +            };
> > > +
> > > +            opp-9500000000 {
> > > +                opp-hz = /bits/ 64 <950000000>;
> > > +                required-opps = <&smcc_opp9>;
> > > +            };
> > > +
> > > +            opp-10000000000 {
> > > +                opp-hz = /bits/ 64 <1000000000>;
> > > +                required-opps = <&smcc_opp10>;
> > > +            };
> > > +
> > > +            opp-10500000000 {
> > > +                opp-hz = /bits/ 64 <1050000000>;
> > > +                required-opps = <&smcc_opp11>;
> > > +            };
> > > +
> > > +            opp-11000000000 {
> > > +                opp-hz = /bits/ 64 <1100000000>;
> > > +                required-opps = <&smcc_opp12>;
> > > +            };
> > > +
> > > +            opp-11500000000 {
> > > +                opp-hz = /bits/ 64 <1150000000>;
> > > +                required-opps = <&smcc_opp13>;
> > > +            };
> > > +
> > > +            opp-12000000000 {
> > > +                opp-hz = /bits/ 64 <1200000000>;
> > > +                required-opps = <&smcc_opp14>;
> > > +            };
> > > +        };
> > > +
> > > +        cpu_smcc_opp_table: opp-table-smcc {
> > > +            compatible = "operating-points-v2";
> > > +
> > > +            smcc_opp0: opp-0 {
> > > +               opp-level = <0>;
> > > +            };
> > > +
> > > +            smcc_opp1: opp-1 {
> > > +                opp-level = <1>;
> > > +            };
> > > +
> > > +            smcc_opp2: opp-2 {
> > > +               opp-level = <2>;
> > > +            };
> > > +
> > > +            smcc_opp3: opp-3 {
> > > +               opp-level = <3>;
> > > +            };
> > > +
> > > +            smcc_opp4: opp-4 {
> > > +                opp-level = <4>;
> > > +            };
> > > +
> > > +            smcc_opp5: opp-5 {
> > > +                opp-level = <5>;
> > > +            };
> > > +
> > > +            smcc_opp6: opp-6 {
> > > +               opp-level = <6>;
> > > +            };
> > > +
> > > +            smcc_opp7: opp-7 {
> > > +               opp-level = <7>;
> > > +            };
> > > +
> > > +            smcc_opp8: opp-8 {
> > > +                opp-level = <8>;
> > > +            };
> > > +
> > > +            smcc_opp9: opp-9 {
> > > +               opp-level = <9>;
> > > +            };
> > > +
> > > +            smcc_opp10: opp-10 {
> > > +                opp-level = <10>;
> > > +            };
> > > +
> > > +            smcc_opp11: opp-11 {
> > > +                opp-level = <11>;
> > > +            };
> > > +
> > > +            smcc_opp12: opp-12 {
> > > +                opp-level = <12>;
> > > +            };
> > > +
> > > +            smcc_opp13: opp-13 {
> > > +                opp-level = <13>;
> > > +            };
> > > +
> > > +            smcc_opp14: opp-14 {
> > > +                opp-level = <14>;
> > > +            };
> > > +        };
> > > +
> > > +        cpu_pd: power-domain {
> >
> > Nitpick: We could use the name *performance-domain* here instead, that
> > would make it even more clear what this node describes.
> >
> > > +            compatible = "airoha,en7581-cpufreq";
> > > +
> > > +            operating-points-v2 = <&cpu_smcc_opp_table>;
> > > +
> > > +            #power-domain-cells = <0>;
> > > +            #clock-cells = <0>;
> > > +        };
> > > +    };
> > > --
> > > 2.45.2
> > >
> >
> > With those changes I am still happy with this approach, so feel free
> > to keep my Reviewed-by tag.
> >
>
> Thanks a lot for the hint. What I think should be understood and we need
> to agree on is the OPP table.
>
> Currently we have an implementation that is
>
> CPU-OPP-Table:
> - OPP Freq in MHz 1
>   - connection to OPP for performance-domain
>   ...
>
> Performance-Domain-OPP-Table:
> - OPP Level 1 (connected to OPP Freq)
>
> Is the double table the problem and we should find a way to unify it in
> something like
> CPU-OPP-Table:
> - OPP Freq in MHz 1
>   OPP Level 1
>
> - OPP Freq in MHz 2
>   OPP Level 2
>
> ...
>
> From what I notice this is problematic as the 2 subsystems require
> dedicated table for each other.
> In any case I think a table of freq is a MUST. Dropping that would
> result in not giving to the user an idea of the supported frequency and
> scaling stats.

Why do we need to invent something new here to describe this HW?
Doesn't the existing OPP v2 DT bindings with the required-opps
property, along with the power-domains bindings work as is?

Kind regards
Uffe
diff mbox series

Patch

diff --git a/Documentation/devicetree/bindings/cpufreq/airoha,en7581-cpufreq.yaml b/Documentation/devicetree/bindings/cpufreq/airoha,en7581-cpufreq.yaml
new file mode 100644
index 000000000000..7e36fa037e4b
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/airoha,en7581-cpufreq.yaml
@@ -0,0 +1,262 @@ 
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/airoha,en7581-cpufreq.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha EN7581 CPUFreq
+
+maintainers:
+  - Christian Marangi <ansuelsmth@gmail.com>
+
+description: |
+  On newer Airoha SoC, CPU Frequency is scaled indirectly with SMCCC commands
+  to ATF and no clocks are exposed to the OS.
+
+  The SoC have performance state described by ID for each OPP, for this a
+  Power Domain is used that sets the performance state ID according to the
+  required OPPs defined in the CPU OPP tables.
+
+properties:
+  compatible:
+    const: airoha,en7581-cpufreq
+
+  '#clock-cells':
+    const: 0
+
+  '#power-domain-cells':
+    const: 0
+
+  operating-points-v2: true
+
+required:
+  - compatible
+  - '#clock-cells'
+  - '#power-domain-cells'
+  - operating-points-v2
+
+additionalProperties: false
+
+examples:
+  - |
+    / {
+        model = "Airoha EN7581 Evaluation Board";
+        compatible = "airoha,en7581-evb", "airoha,en7581";
+
+        #address-cells = <2>;
+      	#size-cells = <2>;
+
+        cpus {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            cpu0: cpu@0 {
+                device_type = "cpu";
+                compatible = "arm,cortex-a53";
+                reg = <0x0>;
+                operating-points-v2 = <&cpu_opp_table>;
+                enable-method = "psci";
+                clocks = <&cpu_pd>;
+                clock-names = "cpu";
+                power-domains = <&cpu_pd>;
+                power-domain-names = "perf";
+                next-level-cache = <&l2>;
+                #cooling-cells = <2>;
+            };
+
+            cpu1: cpu@1 {
+                device_type = "cpu";
+                compatible = "arm,cortex-a53";
+                reg = <0x1>;
+                operating-points-v2 = <&cpu_opp_table>;
+                enable-method = "psci";
+                clocks = <&cpu_pd>;
+                clock-names = "cpu";
+                power-domains = <&cpu_pd>;
+                power-domain-names = "perf";
+                next-level-cache = <&l2>;
+                #cooling-cells = <2>;
+            };
+
+            cpu2: cpu@2 {
+                device_type = "cpu";
+                compatible = "arm,cortex-a53";
+                reg = <0x2>;
+                operating-points-v2 = <&cpu_opp_table>;
+                enable-method = "psci";
+                clocks = <&cpu_pd>;
+                clock-names = "cpu";
+                power-domains = <&cpu_pd>;
+                power-domain-names = "perf";
+                next-level-cache = <&l2>;
+                #cooling-cells = <2>;
+            };
+
+            cpu3: cpu@3 {
+                device_type = "cpu";
+                compatible = "arm,cortex-a53";
+                reg = <0x3>;
+                operating-points-v2 = <&cpu_opp_table>;
+                enable-method = "psci";
+                clocks = <&cpu_pd>;
+                clock-names = "cpu";
+                power-domains = <&cpu_pd>;
+                power-domain-names = "perf";
+                next-level-cache = <&l2>;
+                #cooling-cells = <2>;
+            };
+        };
+
+        cpu_opp_table: opp-table-cpu {
+            compatible = "operating-points-v2";
+            opp-shared;
+
+            opp-500000000 {
+                opp-hz = /bits/ 64 <500000000>;
+                required-opps = <&smcc_opp0>;
+            };
+
+            opp-550000000 {
+                opp-hz = /bits/ 64 <550000000>;
+                required-opps = <&smcc_opp1>;
+            };
+
+            opp-600000000 {
+                opp-hz = /bits/ 64 <600000000>;
+                required-opps = <&smcc_opp2>;
+            };
+
+            opp-650000000 {
+                opp-hz = /bits/ 64 <650000000>;
+                required-opps = <&smcc_opp3>;
+            };
+
+            opp-7000000000 {
+                opp-hz = /bits/ 64 <700000000>;
+                required-opps = <&smcc_opp4>;
+            };
+
+            opp-7500000000 {
+                opp-hz = /bits/ 64 <750000000>;
+                required-opps = <&smcc_opp5>;
+            };
+
+            opp-8000000000 {
+                opp-hz = /bits/ 64 <800000000>;
+                required-opps = <&smcc_opp6>;
+            };
+
+            opp-8500000000 {
+                opp-hz = /bits/ 64 <850000000>;
+                required-opps = <&smcc_opp7>;
+            };
+
+            opp-9000000000 {
+                opp-hz = /bits/ 64 <900000000>;
+                required-opps = <&smcc_opp8>;
+            };
+
+            opp-9500000000 {
+                opp-hz = /bits/ 64 <950000000>;
+                required-opps = <&smcc_opp9>;
+            };
+
+            opp-10000000000 {
+                opp-hz = /bits/ 64 <1000000000>;
+                required-opps = <&smcc_opp10>;
+            };
+
+            opp-10500000000 {
+                opp-hz = /bits/ 64 <1050000000>;
+                required-opps = <&smcc_opp11>;
+            };
+
+            opp-11000000000 {
+                opp-hz = /bits/ 64 <1100000000>;
+                required-opps = <&smcc_opp12>;
+            };
+
+            opp-11500000000 {
+                opp-hz = /bits/ 64 <1150000000>;
+                required-opps = <&smcc_opp13>;
+            };
+
+            opp-12000000000 {
+                opp-hz = /bits/ 64 <1200000000>;
+                required-opps = <&smcc_opp14>;
+            };
+        };
+
+        cpu_smcc_opp_table: opp-table-smcc {
+            compatible = "operating-points-v2";
+
+            smcc_opp0: opp-0 {
+               opp-level = <0>;
+            };
+
+            smcc_opp1: opp-1 {
+                opp-level = <1>;
+            };
+
+            smcc_opp2: opp-2 {
+               opp-level = <2>;
+            };
+
+            smcc_opp3: opp-3 {
+               opp-level = <3>;
+            };
+
+            smcc_opp4: opp-4 {
+                opp-level = <4>;
+            };
+
+            smcc_opp5: opp-5 {
+                opp-level = <5>;
+            };
+
+            smcc_opp6: opp-6 {
+               opp-level = <6>;
+            };
+
+            smcc_opp7: opp-7 {
+               opp-level = <7>;
+            };
+
+            smcc_opp8: opp-8 {
+                opp-level = <8>;
+            };
+
+            smcc_opp9: opp-9 {
+               opp-level = <9>;
+            };
+
+            smcc_opp10: opp-10 {
+                opp-level = <10>;
+            };
+
+            smcc_opp11: opp-11 {
+                opp-level = <11>;
+            };
+
+            smcc_opp12: opp-12 {
+                opp-level = <12>;
+            };
+
+            smcc_opp13: opp-13 {
+                opp-level = <13>;
+            };
+
+            smcc_opp14: opp-14 {
+                opp-level = <14>;
+            };
+        };
+
+        cpu_pd: power-domain {
+            compatible = "airoha,en7581-cpufreq";
+
+            operating-points-v2 = <&cpu_smcc_opp_table>;
+
+            #power-domain-cells = <0>;
+            #clock-cells = <0>;
+        };
+    };