opp: Allow opp-supported-hw to contain multiple versions
cover opp: Allow opp-supported-hw to contain multiple versions
Stephan and Dmitry,
Here is an attempt to solve the problem you guys faced, I have tested it locally and works with my expectations. Please see if they solve your problems.
Dmitry: I sent another message for you in patch 3's comments section.
--
viresh
Viresh Kumar (3):
dt-bindings: opp: Allow opp-supported-hw to contain multiple versions
opp: Allow opp-supported-hw to contain multiple versions
ARM: tegra: Pass multiple versions in opp-supported-hw property
Documentation/devicetree/bindings/opp/opp.txt | 53 +- .../boot/dts/tegra20-cpu-opp-microvolt.dtsi | 36 - arch/arm/boot/dts/tegra20-cpu-opp.dtsi | 67 +- .../boot/dts/tegra30-cpu-opp-microvolt.dtsi | 512 --------- arch/arm/boot/dts/tegra30-cpu-opp.dtsi | 986 +++--------------- drivers/opp/of.c | 47 +- 6 files changed, 214 insertions(+), 1487 deletions(-)
Signature · 1 line
2.25.0.rc1.19.g042ed3e048af
PATCH 1/3 dt-bindings: opp: Allow opp-supported-hw to contain multiple versions
A single list of versions for a hierarchy of hardware levels is not sufficient in some cases. For example, if the hardware version has two levels, i.e. X.Y and we want an OPP to support only version 2.1 and 1.2, we will set the property as:
opp-supported-hw = <0x00000003 0x00000003>;
What this also does is enable hardware versions 2.2 and 1.1, which we don't want.
Extend the property to accept multiple versions, so we can define the property as:
opp-supported-hw = <0x00000002 0x00000001>, <0x00000001 0x00000002>;
While at it, also reword the property description.
--- Documentation/devicetree/bindings/opp/opp.txt | 53 +++++++++++-------- 1 file changed, 32 insertions(+), 21 deletions(-)
Documentation/devicetree/bindings/opp/opp.txt +32 -21
@@ -154,25 +154,27 @@ properties. - opp-suspend: Marks the OPP to be used during device suspend. If multiple OPPs in the table have this, the OPP with highest opp-hz will be used. -- opp-supported-hw: This enables us to select only a subset of OPPs from the - larger OPP table, based on what version of the hardware we are running on. We - still can't have multiple nodes with the same opp-hz value in OPP table. - - It's a user defined array containing a hierarchy of hardware version numbers, - supported by the OPP. For example: a platform with hierarchy of three levels - of versions (A, B and C), this field should be like <X Y Z>, where X - corresponds to Version hierarchy A, Y corresponds to version hierarchy B and Z - corresponds to version hierarchy C. - - Each level of hierarchy is represented by a 32 bit value, and so there can be - only 32 different supported version per hierarchy. i.e. 1 bit per version. A - value of 0xFFFFFFFF will enable the OPP for all versions for that hierarchy - level. And a value of 0x00000000 will disable the OPP completely, and so we - never want that to happen. - - If 32 values aren't sufficient for a version hierarchy, than that version - hierarchy can be contained in multiple 32 bit values. i.e. <X Y Z1 Z2> in the - above example, Z1 & Z2 refer to the version hierarchy Z. +- opp-supported-hw: This property allows a platform to enable only a subset of + the OPPs from the larger set present in the OPP table, based on the current + version of the hardware (already known to the operating system). + + Each block present in the array of blocks in this property, represents a + sub-group of hardware versions supported by the OPP. i.e. <sub-group A>, + <sub-group B>, etc. The OPP will be enabled if _any_ of these sub-groups match + the hardware's version. + + Each sub-group is a platform defined array representing the hierarchy of + hardware versions supported by the platform. For a platform with three + hierarchical levels of version (X.Y.Z), this field shall look like + + opp-supported-hw = <X1 Y1 Z1>, <X2 Y2 Z2>, <X3 Y3 Z3>. + + Each level (eg. X1) in version hierarchy is represented by a 32 bit value, one + bit per version and so there can be maximum 32 versions per level. Logical AND + (&) operation is performed for each level with the hardware's level version + and a non-zero output for _all_ the levels in a sub-group means the OPP is + supported by hardware. A value of 0xFFFFFFFF for each level in the sub-group + will enable the OPP for all versions for the hardware. - status: Marks the node enabled/disabled.
@@ -503,7 +505,6 @@ Example 5: opp-supported-hw */ opp-supported-hw = <0xF 0xFFFFFFFF 0xFFFFFFFF> opp-hz = /bits/ 64 <600000000>; - opp-microvolt = <915000 900000 925000>; ... };
@@ -516,7 +517,17 @@ Example 5: opp-supported-hw */ opp-supported-hw = <0x20 0xff0000ff 0x0000f4f0> opp-hz = /bits/ 64 <800000000>; - opp-microvolt = <915000 900000 925000>; + ... + }; + + opp-900000000 { + /* + * Supports: + * - All cuts and substrate where process version is 0x2. + * - All cuts and process where substrate version is 0x2. + */ + opp-supported-hw = <0xFFFFFFFF 0xFFFFFFFF 0x02>, <0xFFFFFFFF 0x01 0xFFFFFFFF> + opp-hz = /bits/ 64 <900000000>; ... }; };
Signature · 1 line
2.25.0.rc1.19.g042ed3e048af
PATCH 2/3 opp: Allow opp-supported-hw to contain multiple versions
In reply to Viresh KumarThe bindings allow multiple versions to be passed to "opp-supported-hw" property, either of which can result in enabling of the OPP.
Update code to allow that.
--- drivers/opp/of.c | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-)
drivers/opp/of.c +33 -14
@@ -434,9 +434,9 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_of_find_icc_paths);static bool _opp_is_supported (struct device *dev,struct opp_table *opp_table,struct device_node *np) { -unsigned int count = opp_table->supported_hw_count; -u32 version; -int ret; +unsigned int levels = opp_table->supported_hw_count; +int count, versions, ret, i, j; +u32 val;if (!opp_table->supported_hw) {/*
@@ -451,21 +451,40 @@ static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table,return true; } -while (count--) { - ret =of_property_read_u32_index (np,"opp-supported-hw" , count, - &version); -if (ret) { -dev_warn (dev,"%s: failed to read opp-supported-hw property at index %d: %d\n" , - __func__, count, ret); -return false; + count =of_property_count_u32_elems (np,"opp-supported-hw" ); +if (count <=0 || count % levels) { +dev_err (dev,"%s: Invalid opp-supported-hw property (%d)\n" , + __func__, count); +return false; + } + + versions = count / levels; + +/* All levels in at least one of the versions should match */ +for (i =0 ; i < versions; i++) { +bool supported = true; + +for (j =0 ; j < levels; j++) { + ret =of_property_read_u32_index (np,"opp-supported-hw" , + i * levels + j, &val); +if (ret) { +dev_warn (dev,"%s: failed to read opp-supported-hw property at index %d: %d\n" , + __func__, i * levels + j, ret); +return false; + } + +/* Check if the level is supported */ +if (!(val & opp_table->supported_hw[j])) { + supported = false; +break ; + } } -/* Both of these are bitwise masks of the versions */ -if (!(version & opp_table->supported_hw[count])) -return false; +if (supported) +return true; } -return true; +return false; } static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
Signature · 1 line
2.25.0.rc1.19.g042ed3e048af
Quoted 6 lines · Viresh Kumar
The bindings allow multiple versions to be passed to "opp-supported-hw" property, either of which can result in enabling of the OPP.
Update code to allow that.
Signed-off-by Viresh Kumar <[email protected]>
This is exactly what I was looking for!
And it works just fine in my tests:
Thank you!
Stephan
Quoted 76 lines
--- drivers/opp/of.c | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-)drivers/opp/of.c +33
-14@@ -434,9 +434,9 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_of_find_icc_paths);static bool _opp_is_supported (struct device *dev,struct opp_table *opp_table,struct device_node *np) { -unsigned int count = opp_table->supported_hw_count; -u32 version; -int ret; +unsigned int levels = opp_table->supported_hw_count; +int count, versions, ret, i, j; +u32 val;if (!opp_table->supported_hw) {/* @@ -451,21 +451,40 @@ static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table,return true; } -while (count--) { - ret =of_property_read_u32_index (np,"opp-supported-hw" , count, - &version); -if (ret) { -dev_warn (dev,"%s: failed to read opp-supported-hw property at index %d: %d\n" , - __func__, count, ret); -return false; + count =of_property_count_u32_elems (np,"opp-supported-hw" ); +if (count <=0 || count % levels) { +dev_err (dev,"%s: Invalid opp-supported-hw property (%d)\n" , + __func__, count); +return false; + } + + versions = count / levels; + +/* All levels in at least one of the versions should match */ +for (i =0 ; i < versions; i++) { +bool supported = true; + +for (j =0 ; j < levels; j++) { + ret =of_property_read_u32_index (np,"opp-supported-hw" , + i * levels + j, &val); +if (ret) { +dev_warn (dev,"%s: failed to read opp-supported-hw property at index %d: %d\n" , + __func__, i * levels + j, ret); +return false; + } + +/* Check if the level is supported */ +if (!(val & opp_table->supported_hw[j])) { + supported = false; +break ; + } } -/* Both of these are bitwise masks of the versions */ -if (!(version & opp_table->supported_hw[count])) -return false; +if (supported) +return true; } -return true; +return false; } static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,Signature · 1 line
2.25.0.rc1.19.g042ed3e048af
26.08.2020 14:50, Viresh Kumar пишет:
Quoted 9 lines
The bindings allow multiple versions to be passed to "opp-supported-hw" property, either of which can result in enabling of the OPP.
Update code to allow that.
Signed-off-by Viresh Kumar <[email protected]>--- drivers/opp/of.c | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-)
I checked that CPU DVFS works on Nexus 7 after applying this series just like it worked before. Thanks!
PATCH 3/3 ARM: tegra: Pass multiple versions in opp-supported-hw property
In reply to Viresh KumarWe can now pass multiple versions in "opp-supported-hw" property, lets do that and simplify the tables a bit.
---
Dmitry, I think there is further scope of simplifying stuff here by using the opp-microvolt-<name> property and corresponding dev_pm_opp_set_prop_name() call.
--- .../boot/dts/tegra20-cpu-opp-microvolt.dtsi | 36 - arch/arm/boot/dts/tegra20-cpu-opp.dtsi | 67 +- .../boot/dts/tegra30-cpu-opp-microvolt.dtsi | 512 --------- arch/arm/boot/dts/tegra30-cpu-opp.dtsi | 986 +++--------------- 4 files changed, 149 insertions(+), 1452 deletions(-)
arch/arm/boot/dts/tegra20-cpu-opp-microvolt.dtsi +0 -36
@@ -26,14 +26,6 @@ opp@456000000,800 { opp-microvolt = <800000 800000 1125000>; }; - opp@456000000,800,2,2 { - opp-microvolt = <800000 800000 1125000>; - }; - - opp@456000000,800,3,2 { - opp-microvolt = <800000 800000 1125000>; - }; - opp@456000000,825 { opp-microvolt = <825000 825000 1125000>; };
@@ -46,10 +38,6 @@ opp@608000000,800 { opp-microvolt = <800000 800000 1125000>; }; - opp@608000000,800,3,2 { - opp-microvolt = <800000 800000 1125000>; - }; - opp@608000000,825 { opp-microvolt = <825000 825000 1125000>; };
@@ -78,18 +66,6 @@ opp@760000000,875 { opp-microvolt = <875000 875000 1125000>; }; - opp@760000000,875,1,1 { - opp-microvolt = <875000 875000 1125000>; - }; - - opp@760000000,875,0,2 { - opp-microvolt = <875000 875000 1125000>; - }; - - opp@760000000,875,1,2 { - opp-microvolt = <875000 875000 1125000>; - }; - opp@760000000,900 { opp-microvolt = <900000 900000 1125000>; };
@@ -134,14 +110,6 @@ opp@912000000,950 { opp-microvolt = <950000 950000 1125000>; }; - opp@912000000,950,0,2 { - opp-microvolt = <950000 950000 1125000>; - }; - - opp@912000000,950,2,2 { - opp-microvolt = <950000 950000 1125000>; - }; - opp@912000000,1000 { opp-microvolt = <1000000 1000000 1125000>; };
@@ -170,10 +138,6 @@ opp@1000000000,1000 { opp-microvolt = <1000000 1000000 1125000>; }; - opp@1000000000,1000,0,2 { - opp-microvolt = <1000000 1000000 1125000>; - }; - opp@1000000000,1025 { opp-microvolt = <1025000 1025000 1125000>; };
arch/arm/boot/dts/tegra20-cpu-opp.dtsi +8 -59
97 lines not on this page · raw message
arch/arm/boot/dts/tegra30-cpu-opp-microvolt.dtsi +0 -512
604 lines not on this page · raw message
arch/arm/boot/dts/tegra30-cpu-opp.dtsi +141 -845
1,112 lines not on this page · raw message
Signature · 1 line
2.25.0.rc1.19.g042ed3e048af
Re: [PATCH 3/3] ARM: tegra: Pass multiple versions in opp-supported-hw property
26.08.2020 14:50, Viresh Kumar пишет:
Quoted 9 lines
We can now pass multiple versions in "opp-supported-hw" property, lets do that and simplify the tables a bit.
Signed-off-by Viresh Kumar <[email protected]>---
Dmitry, I think there is further scope of simplifying stuff here by using the opp-microvolt-<name> property and correspondingdev_pm_opp_set_prop_name()call.
Quoted 6 lines
--- .../boot/dts/tegra20-cpu-opp-microvolt.dtsi | 36 - arch/arm/boot/dts/tegra20-cpu-opp.dtsi | 67 +- .../boot/dts/tegra30-cpu-opp-microvolt.dtsi | 512 --------- arch/arm/boot/dts/tegra30-cpu-opp.dtsi | 986 +++--------------- 4 files changed, 149 insertions(+), 1452 deletions(-)
Hello, Viresh!
Thank you very much! Very nice cleanup! I changed my OPP-gen tool to produce the new OPP format and then comapared the result to yours change, the result is matching.
...
Quoted 1 line
arch/arm/boot/dts/tegra30-cpu-opp.dtsi +0
-0
...
arch/arm/boot/dts/tegra30-cpu-opp.dtsi opp@475000000,800 { · line 118
Quoted 11 lines
arch/arm/boot/dts/tegra30-cpu-opp.dtsi +6
-4- opp@1000000000,975,3,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0080>; - opp-hz = /bits/ 64 <1000000000>; + opp-supported-hw = <0x0F 0x0001>, + <0x01 0x0002>, + <0x01 0x0010>, + <0x01 0x0080>, + <0x01 0x0100>; + opp-hz = /bits/ 64 <475000000>; };
The only very minor difference between my OPP-gen result and yours is that the above hunk has inconsistent single-column formatting, while all others are two-column.
Re: [PATCH 3/3] ARM: tegra: Pass multiple versions in opp-supported-hw property
Quoted 10 lines · Dmitry Osipenko
26.08.2020 14:50, Viresh Kumar пишет:
Quoted 9 lines
We can now pass multiple versions in "opp-supported-hw" property, lets do that and simplify the tables a bit.
Signed-off-by Viresh Kumar <[email protected]>---
Dmitry, I think there is further scope of simplifying stuff here by using the opp-microvolt-<name> property and correspondingdev_pm_opp_set_prop_name()call.
Any inputs on this Dmitry ?
Quoted 17 lines
Quoted 1 line
arch/arm/boot/dts/tegra30-cpu-opp.dtsi +0
-0...
arch/arm/boot/dts/tegra30-cpu-opp.dtsi opp@475000000,800 { · line 118
Quoted 11 lines
arch/arm/boot/dts/tegra30-cpu-opp.dtsi +6
-4- opp@1000000000,975,3,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0080>; - opp-hz = /bits/ 64 <1000000000>; + opp-supported-hw = <0x0F 0x0001>, + <0x01 0x0002>, + <0x01 0x0010>, + <0x01 0x0080>, + <0x01 0x0100>; + opp-hz = /bits/ 64 <475000000>; };The only very minor difference between my OPP-gen result and yours is that the above hunk has inconsistent single-column formatting, while all others are two-column.
Ah, my mistake. Fixed and pushed now.
Quoted 2 lines
Reviewed-by Dmitry Osipenko <[email protected]>Tested-by Dmitry Osipenko <[email protected]>
Thanks.
Signature · 1 line
viresh
Re: [PATCH 3/3] ARM: tegra: Pass multiple versions in opp-supported-hw property
31.08.2020 07:39, Viresh Kumar пишет:
...
Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
Dmitry, I think there is further scope of simplifying stuff here by using the opp-microvolt-<name> property and corresponding
dev_pm_opp_set_prop_name()call.Any inputs on this Dmitry ?
Could you please give an example?
Re: [PATCH 3/3] ARM: tegra: Pass multiple versions in opp-supported-hw property
Quoted 9 lines · Dmitry Osipenko
31.08.2020 07:39, Viresh Kumar пишет:
...Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
Dmitry, I think there is further scope of simplifying stuff here by using the opp-microvolt-<name> property and corresponding
dev_pm_opp_set_prop_name()call.Any inputs on this Dmitry ?
Could you please give an example?
There are many users of it in the kernel. grep for "opp-microvolt-" in the DT files and you will see.
The use of this property is to specific multiple microvolt properties to the same frequency without a need to create separate nodes for them all. The right microvolt property will be selected based on the call made to dev_pm_opp_set_prop_name(), search for that too in kernel.
Signature · 1 line
viresh
Re: [PATCH 3/3] ARM: tegra: Pass multiple versions in opp-supported-hw property
31.08.2020 11:41, Viresh Kumar пишет:
Quoted 11 lines · Dmitry Osipenko
Quoted 9 lines
31.08.2020 07:39, Viresh Kumar пишет:
...Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
Dmitry, I think there is further scope of simplifying stuff here by using the opp-microvolt-<name> property and corresponding
dev_pm_opp_set_prop_name()call.Any inputs on this Dmitry ?
Could you please give an example?
Quoted 8 lines
There are many users of it in the kernel. grep for "opp-microvolt-" in the DT files and you will see.
The use of this property is to specific multiple microvolt properties to the same frequency without a need to create separate nodes for them all. The right microvolt property will be selected based on the call made to
dev_pm_opp_set_prop_name(), search for that too in kernel.
It's not clear to me how it could be applicable to the Tegra CPU OPP because Tegra depends on a combination of SPEEDO + PROCESS versions.
It's not like all voltages are the same for all OPPs that have the same PROCESS ID, otherwise it indeed would be nice to have "opp-microvolt-process0", but unfortunately this variant is not suitable for Tegra because some freqs have different voltages using the same PROCESS ID and the same applies to the SPEEDO ID.
Re: [PATCH 3/3] ARM: tegra: Pass multiple versions in opp-supported-hw property
Quoted 8 lines · Dmitry Osipenko
It's not clear to me how it could be applicable to the Tegra CPU OPP because Tegra depends on a combination of SPEEDO + PROCESS versions.
It's not like all voltages are the same for all OPPs that have the same PROCESS ID, otherwise it indeed would be nice to have "opp-microvolt-process0", but unfortunately this variant is not suitable for Tegra because some freqs have different voltages using the same PROCESS ID and the same applies to the SPEEDO ID.
How exactly do you know what voltage belongs to a particular OPP ?
opp@216000000 {
clock-latency-ns = <400000>;
opp-supported-hw = <0x0F 0x0003>;
opp-hz = /bits/ 64 <216000000>;
opp-microvolt-fast-process0 = <750000 750000 1125000>;
opp-microvolt-slow-process0 = <750000 850000 1125000>;
};
opp@312000000 {
clock-latency-ns = <400000>;
opp-supported-hw = <0x0F 0x0003>;
opp-hz = /bits/ 64 <312000000>;
opp-microvolt-fast-process0 = <750000 750000 1125000>;
opp-microvolt-slow-process0 = <750000 850000 1125000>;
};You can make any combinations of such names that come from speedo, process, or something else. If you can get this done as a fixed formula then it is workable.
Signature · 1 line
viresh
Re: [PATCH 3/3] ARM: tegra: Pass multiple versions in opp-supported-hw property
31.08.2020 14:04, Viresh Kumar пишет:
Quoted 11 lines · Dmitry Osipenko
Quoted 8 lines
It's not clear to me how it could be applicable to the Tegra CPU OPP because Tegra depends on a combination of SPEEDO + PROCESS versions.
It's not like all voltages are the same for all OPPs that have the same PROCESS ID, otherwise it indeed would be nice to have "opp-microvolt-process0", but unfortunately this variant is not suitable for Tegra because some freqs have different voltages using the same PROCESS ID and the same applies to the SPEEDO ID.
How exactly do you know what voltage belongs to a particular OPP ?
From these tables:
Quoted 17 lines
opp@216000000 {
clock-latency-ns = <400000>;
opp-supported-hw = <0x0F 0x0003>;
opp-hz = /bits/ 64 <216000000>;
opp-microvolt-fast-process0 = <750000 750000 1125000>;
opp-microvolt-slow-process0 = <750000 850000 1125000>;
};
opp@312000000 {
clock-latency-ns = <400000>;
opp-supported-hw = <0x0F 0x0003>;
opp-hz = /bits/ 64 <312000000>;
opp-microvolt-fast-process0 = <750000 750000 1125000>;
opp-microvolt-slow-process0 = <750000 850000 1125000>;
};Quoted 4 lines
You can make any combinations of such names that come from speedo, process, or something else. If you can get this done as a fixed formula then it is workable.
IIUC, there is no fixed formula for Tegra, at least I don't see it. For example, if you'll take a look at the 1300MHz OPP of Tegra30, then you could see that this freq has a lot of voltages each depending on specific combination of SPEEDO+PROCESS versions.
Re: [PATCH 3/3] ARM: tegra: Pass multiple versions in opp-supported-hw property
Quoted 4 lines · Dmitry Osipenko
IIUC, there is no fixed formula for Tegra, at least I don't see it. For example, if you'll take a look at the 1300MHz OPP of Tegra30, then you could see that this freq has a lot of voltages each depending on specific combination of SPEEDO+PROCESS versions.
Right, it may not be worth it to clean this up :)
Signature · 1 line
viresh