* [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps @ 2020-04-01 17:50 Loic Poulain 2020-04-01 23:46 ` Bjorn Andersson ` (2 more replies) 0 siblings, 3 replies; 32+ messages in thread From: Loic Poulain @ 2020-04-01 17:50 UTC (permalink / raw) To: bjorn.andersson, agross; +Cc: linux-arm-msm, Loic Poulain The highest cpu frequency opps have been dropped because CPR is not supported. However, we can simply specify operating voltage so that they match the max corner voltages for each freq. With that, we can support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to fine tune operating voltages and optimize power consumption. This patch: - Adds missing opps and corresponding target voltages to msm8916.dtsi. - Adds cpu-supply to apq8016-sbc.dtsi (board level info). - Adds pm8916 spmi regulator node to pm8916.dtsi. Tested with a dragonboard-410c. Signed-off-by: Loic Poulain <loic.poulain@linaro.org> --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 24 ++++++++++++++++++++++++ arch/arm64/boot/dts/qcom/msm8916.dtsi | 24 ++++++++++++++++++++++++ arch/arm64/boot/dts/qcom/pm8916.dtsi | 6 ++++++ 3 files changed, 54 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 037e26b..f1c1216 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -560,6 +560,30 @@ qcom,mbhc-vthreshold-high = <75 150 237 450 500>; }; +&spm_regulators { + vdd_cpu: s2 { + regulator-always-on; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1350000>; + }; +}; + +&CPU0 { + cpu-supply = <&vdd_cpu>; +}; + +&CPU1 { + cpu-supply = <&vdd_cpu>; +}; + +&CPU2 { + cpu-supply = <&vdd_cpu>; +}; + +&CPU3 { + cpu-supply = <&vdd_cpu>; +}; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l5-supply = <&pm8916_s3>; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 9f31064..9805af0 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -342,15 +342,39 @@ opp-200000000 { opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <1050000>; }; opp-400000000 { opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <1050000>; + }; + opp-533330000 { + opp-hz = /bits/ 64 <533330000>; + opp-microvolt = <1150000>; }; opp-800000000 { opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <1150000>; }; opp-998400000 { opp-hz = /bits/ 64 <998400000>; + opp-microvolt = <1350000>; + }; + opp-1094400000 { + opp-hz = /bits/ 64 <1094400000>; + opp-microvolt = <1350000>; + }; + opp-1152000000 { + opp-hz = /bits/ 64 <1152000000>; + opp-microvolt = <1350000>; + }; + opp-1209600000 { + opp-hz = /bits/ 64 <1209600000>; + opp-microvolt = <1350000>; + }; + opp-1363200000 { + opp-hz = /bits/ 64 <1363200000>; + opp-microvolt = <1350000>; }; }; diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi index 0bcdf04..c9b9c4f 100644 --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi @@ -157,5 +157,11 @@ vdd-micbias-supply = <&pm8916_l13>; #sound-dai-cells = <1>; }; + + spm_regulators: spm_regulators { + compatible = "qcom,pm8916-regulators"; + #address-cells = <1>; + #size-cells = <1>; + }; }; }; -- 2.7.4 ^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-04-01 17:50 [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps Loic Poulain @ 2020-04-01 23:46 ` Bjorn Andersson 2020-04-02 8:13 ` Stephan Gerhold 2020-04-28 20:04 ` Amit Kucheria 2 siblings, 0 replies; 32+ messages in thread From: Bjorn Andersson @ 2020-04-01 23:46 UTC (permalink / raw) To: Loic Poulain; +Cc: agross, linux-arm-msm On Wed 01 Apr 10:50 PDT 2020, Loic Poulain wrote: > The highest cpu frequency opps have been dropped because CPR is not > supported. However, we can simply specify operating voltage so that > they match the max corner voltages for each freq. With that, we can > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > fine tune operating voltages and optimize power consumption. > > This patch: > - Adds missing opps and corresponding target voltages to msm8916.dtsi. > - Adds cpu-supply to apq8016-sbc.dtsi (board level info). > - Adds pm8916 spmi regulator node to pm8916.dtsi. > > Tested with a dragonboard-410c. > Thanks Loic, happy to see you tying up these loose ends! Just one minor nit below. > Signed-off-by: Loic Poulain <loic.poulain@linaro.org> > --- > arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 24 ++++++++++++++++++++++++ > arch/arm64/boot/dts/qcom/msm8916.dtsi | 24 ++++++++++++++++++++++++ > arch/arm64/boot/dts/qcom/pm8916.dtsi | 6 ++++++ > 3 files changed, 54 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > index 037e26b..f1c1216 100644 > --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > @@ -560,6 +560,30 @@ > qcom,mbhc-vthreshold-high = <75 150 237 450 500>; > }; > > +&spm_regulators { > + vdd_cpu: s2 { > + regulator-always-on; > + regulator-min-microvolt = <1050000>; > + regulator-max-microvolt = <1350000>; > + }; > +}; > + > +&CPU0 { > + cpu-supply = <&vdd_cpu>; > +}; > + > +&CPU1 { > + cpu-supply = <&vdd_cpu>; > +}; > + > +&CPU2 { > + cpu-supply = <&vdd_cpu>; > +}; > + > +&CPU3 { > + cpu-supply = <&vdd_cpu>; > +}; > + > &smd_rpm_regulators { > vdd_l1_l2_l3-supply = <&pm8916_s3>; > vdd_l5-supply = <&pm8916_s3>; > diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi > index 9f31064..9805af0 100644 > --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi > +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi > @@ -342,15 +342,39 @@ > > opp-200000000 { > opp-hz = /bits/ 64 <200000000>; > + opp-microvolt = <1050000>; > }; > opp-400000000 { > opp-hz = /bits/ 64 <400000000>; > + opp-microvolt = <1050000>; > + }; > + opp-533330000 { > + opp-hz = /bits/ 64 <533330000>; > + opp-microvolt = <1150000>; > }; > opp-800000000 { > opp-hz = /bits/ 64 <800000000>; > + opp-microvolt = <1150000>; > }; > opp-998400000 { > opp-hz = /bits/ 64 <998400000>; > + opp-microvolt = <1350000>; > + }; > + opp-1094400000 { > + opp-hz = /bits/ 64 <1094400000>; > + opp-microvolt = <1350000>; > + }; > + opp-1152000000 { > + opp-hz = /bits/ 64 <1152000000>; > + opp-microvolt = <1350000>; > + }; > + opp-1209600000 { > + opp-hz = /bits/ 64 <1209600000>; > + opp-microvolt = <1350000>; > + }; > + opp-1363200000 { > + opp-hz = /bits/ 64 <1363200000>; > + opp-microvolt = <1350000>; > }; > }; > > diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi > index 0bcdf04..c9b9c4f 100644 > --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi > +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi > @@ -157,5 +157,11 @@ > vdd-micbias-supply = <&pm8916_l13>; > #sound-dai-cells = <1>; > }; > + > + spm_regulators: spm_regulators { There is the SPM regulator interface in the CPU subsystem, which is used for hardware assisted entering and exiting of low power modes. And then there's the direct PMIC control over SPMI. Except for the fact that the SPM hardware uses SPMI for controlling the PMIC these are two different things, and this is the SPMI one. So the label, and node should be spmi_regulators: regulators { Regards, Bjorn > + compatible = "qcom,pm8916-regulators"; > + #address-cells = <1>; > + #size-cells = <1>; > + }; > }; > }; > -- > 2.7.4 > ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-04-01 17:50 [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps Loic Poulain 2020-04-01 23:46 ` Bjorn Andersson @ 2020-04-02 8:13 ` Stephan Gerhold 2020-04-02 9:58 ` Loic Poulain 2020-04-03 1:31 ` Bjorn Andersson 2020-04-28 20:04 ` Amit Kucheria 2 siblings, 2 replies; 32+ messages in thread From: Stephan Gerhold @ 2020-04-02 8:13 UTC (permalink / raw) To: Loic Poulain; +Cc: bjorn.andersson, agross, linux-arm-msm, Niklas Cassel Hi, On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > The highest cpu frequency opps have been dropped because CPR is not > supported. However, we can simply specify operating voltage so that > they match the max corner voltages for each freq. With that, we can > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > fine tune operating voltages and optimize power consumption. Thanks for the patch! I was wondering how to enable the higher CPU frequencies for a while now... I was actually quite excited to see CPR being mainlined for QCS404. If we are trying to add such a workaround (rather than CPR) for MSM8916 now, does that mean it's unlikely to see CPR working for MSM8916 anytime soon? AFAICT, there is a WIP branch from Niklas Cassel here: https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline but it hasn't been updated for a while. (Not sure if it was working already...) Can someone explain what is missing to make CPR work for MSM8916? One other minor comment/question below. > > This patch: > - Adds missing opps and corresponding target voltages to msm8916.dtsi. > - Adds cpu-supply to apq8016-sbc.dtsi (board level info). > - Adds pm8916 spmi regulator node to pm8916.dtsi. > > Tested with a dragonboard-410c. > > Signed-off-by: Loic Poulain <loic.poulain@linaro.org> > --- > arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 24 ++++++++++++++++++++++++ > arch/arm64/boot/dts/qcom/msm8916.dtsi | 24 ++++++++++++++++++++++++ > arch/arm64/boot/dts/qcom/pm8916.dtsi | 6 ++++++ > 3 files changed, 54 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > index 037e26b..f1c1216 100644 > --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > @@ -560,6 +560,30 @@ > qcom,mbhc-vthreshold-high = <75 150 237 450 500>; > }; > > +&spm_regulators { > + vdd_cpu: s2 { > + regulator-always-on; > + regulator-min-microvolt = <1050000>; > + regulator-max-microvolt = <1350000>; > + }; > +}; > + > +&CPU0 { > + cpu-supply = <&vdd_cpu>; > +}; > + > +&CPU1 { > + cpu-supply = <&vdd_cpu>; > +}; > + > +&CPU2 { > + cpu-supply = <&vdd_cpu>; > +}; > + > +&CPU3 { > + cpu-supply = <&vdd_cpu>; > +}; > + I'm a bit confused about the separation here. The cpu-supply is defined in the board-specific device tree, yet the voltages are set in the common device tree below. Is it even possible that the CPU is supplied by something other than S2 and if yes, how likely is this? I'm asking because I have two other MSM8916 devices in mainline (and a few more pending upstreaming), and it seems like I would need to duplicate this into each of them. Thanks, Stephan > &smd_rpm_regulators { > vdd_l1_l2_l3-supply = <&pm8916_s3>; > vdd_l5-supply = <&pm8916_s3>; > diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi > index 9f31064..9805af0 100644 > --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi > +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi > @@ -342,15 +342,39 @@ > > opp-200000000 { > opp-hz = /bits/ 64 <200000000>; > + opp-microvolt = <1050000>; > }; > opp-400000000 { > opp-hz = /bits/ 64 <400000000>; > + opp-microvolt = <1050000>; > + }; > + opp-533330000 { > + opp-hz = /bits/ 64 <533330000>; > + opp-microvolt = <1150000>; > }; > opp-800000000 { > opp-hz = /bits/ 64 <800000000>; > + opp-microvolt = <1150000>; > }; > opp-998400000 { > opp-hz = /bits/ 64 <998400000>; > + opp-microvolt = <1350000>; > + }; > + opp-1094400000 { > + opp-hz = /bits/ 64 <1094400000>; > + opp-microvolt = <1350000>; > + }; > + opp-1152000000 { > + opp-hz = /bits/ 64 <1152000000>; > + opp-microvolt = <1350000>; > + }; > + opp-1209600000 { > + opp-hz = /bits/ 64 <1209600000>; > + opp-microvolt = <1350000>; > + }; > + opp-1363200000 { > + opp-hz = /bits/ 64 <1363200000>; > + opp-microvolt = <1350000>; > }; > }; > > diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi > index 0bcdf04..c9b9c4f 100644 > --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi > +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi > @@ -157,5 +157,11 @@ > vdd-micbias-supply = <&pm8916_l13>; > #sound-dai-cells = <1>; > }; > + > + spm_regulators: spm_regulators { > + compatible = "qcom,pm8916-regulators"; > + #address-cells = <1>; > + #size-cells = <1>; > + }; > }; > }; > -- > 2.7.4 > ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-04-02 8:13 ` Stephan Gerhold @ 2020-04-02 9:58 ` Loic Poulain 2020-04-03 1:31 ` Bjorn Andersson 1 sibling, 0 replies; 32+ messages in thread From: Loic Poulain @ 2020-04-02 9:58 UTC (permalink / raw) To: Stephan Gerhold; +Cc: Bjorn Andersson, Andy Gross, linux-arm-msm, Niklas Cassel Hi Stephan, On Thu, 2 Apr 2020 at 10:14, Stephan Gerhold <stephan@gerhold.net> wrote: > > Hi, > > On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > > The highest cpu frequency opps have been dropped because CPR is not > > supported. However, we can simply specify operating voltage so that > > they match the max corner voltages for each freq. With that, we can > > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > > fine tune operating voltages and optimize power consumption. > > Thanks for the patch! I was wondering how to enable the higher CPU > frequencies for a while now... > > I was actually quite excited to see CPR being mainlined for QCS404. > If we are trying to add such a workaround (rather than CPR) for MSM8916 > now, does that mean it's unlikely to see CPR working for MSM8916 > anytime soon? > > AFAICT, there is a WIP branch from Niklas Cassel here: > https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline > but it hasn't been updated for a while. (Not sure if it was working > already...) > > Can someone explain what is missing to make CPR work for MSM8916? Support should be relatively straightforward to add, but would request some time to implement and validate. This patch can be considered as a first step, using the ceiling voltages. > > One other minor comment/question below. > > > > > This patch: > > - Adds missing opps and corresponding target voltages to msm8916.dtsi. > > - Adds cpu-supply to apq8016-sbc.dtsi (board level info). > > - Adds pm8916 spmi regulator node to pm8916.dtsi. > > > > Tested with a dragonboard-410c. > > > > Signed-off-by: Loic Poulain <loic.poulain@linaro.org> > > --- > > arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 24 ++++++++++++++++++++++++ > > arch/arm64/boot/dts/qcom/msm8916.dtsi | 24 ++++++++++++++++++++++++ > > arch/arm64/boot/dts/qcom/pm8916.dtsi | 6 ++++++ > > 3 files changed, 54 insertions(+) > > > > diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > > index 037e26b..f1c1216 100644 > > --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > > +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > > @@ -560,6 +560,30 @@ > > qcom,mbhc-vthreshold-high = <75 150 237 450 500>; > > }; > > > > +&spm_regulators { > > + vdd_cpu: s2 { > > + regulator-always-on; > > + regulator-min-microvolt = <1050000>; > > + regulator-max-microvolt = <1350000>; > > + }; > > +}; > > + > > +&CPU0 { > > + cpu-supply = <&vdd_cpu>; > > +}; > > + > > +&CPU1 { > > + cpu-supply = <&vdd_cpu>; > > +}; > > + > > +&CPU2 { > > + cpu-supply = <&vdd_cpu>; > > +}; > > + > > +&CPU3 { > > + cpu-supply = <&vdd_cpu>; > > +}; > > + > > I'm a bit confused about the separation here. The cpu-supply is defined > in the board-specific device tree, yet the voltages are set in the > common device tree below. > > Is it even possible that the CPU is supplied by something other than S2 > and if yes, how likely is this? Well nothing prevents to use a different PMIC, but you're right in practice msm8916 is tightly coupled to pm8916 and s2 is clearly specified as application processor regulator in pm8916 spec. So I'll move that into msm8916 for the v2. > I'm asking because I have two other MSM8916 devices in mainline > (and a few more pending upstreaming), and it seems like I would need to > duplicate this into each of them. Would you be able to test and ack the V2 with these boards? Regards, Loic ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-04-02 8:13 ` Stephan Gerhold 2020-04-02 9:58 ` Loic Poulain @ 2020-04-03 1:31 ` Bjorn Andersson 2020-04-03 10:09 ` Stephan Gerhold 1 sibling, 1 reply; 32+ messages in thread From: Bjorn Andersson @ 2020-04-03 1:31 UTC (permalink / raw) To: Stephan Gerhold; +Cc: Loic Poulain, agross, linux-arm-msm On Thu 02 Apr 01:13 PDT 2020, Stephan Gerhold wrote: > Hi, > > On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > > The highest cpu frequency opps have been dropped because CPR is not > > supported. However, we can simply specify operating voltage so that > > they match the max corner voltages for each freq. With that, we can > > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > > fine tune operating voltages and optimize power consumption. > > Thanks for the patch! I was wondering how to enable the higher CPU > frequencies for a while now... > > I was actually quite excited to see CPR being mainlined for QCS404. > If we are trying to add such a workaround (rather than CPR) for MSM8916 > now, does that mean it's unlikely to see CPR working for MSM8916 > anytime soon? > > AFAICT, there is a WIP branch from Niklas Cassel here: > https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline > but it hasn't been updated for a while. (Not sure if it was working > already...) > > Can someone explain what is missing to make CPR work for MSM8916? > CPR needs to control 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 it seems we don't have to adjust VDD_MX, so the code for this is missing from the driver. So, afaict, what's missing is that rpmpd.c needs to gain support for 8916, then the CPR driver needs to gain a cpr_acc_desc and compatible for 8916, it needs to reference the VDDMX power domain and before/after we're adjusting the corner of the CPR we need to adjust the MX according to the mapping specified in the downstream kernel (i.e. 1->4, 2->5 and 3->7). Unfortunately, the requirement that VDDMX (VDD_MEM I presume) must be higher than VDD_APC most likely needs to be taken into consideration for Loic's proposed static voltage scaling as well. Unless VDD_MEM is left in Turbo mode from the boot loader I think we need to take VDDMX to corner 7 for speeds 998MHz and above (i.e. where we pull VDD_APC to 1.35V). Regards, Bjorn > One other minor comment/question below. > > > > > This patch: > > - Adds missing opps and corresponding target voltages to msm8916.dtsi. > > - Adds cpu-supply to apq8016-sbc.dtsi (board level info). > > - Adds pm8916 spmi regulator node to pm8916.dtsi. > > > > Tested with a dragonboard-410c. > > > > Signed-off-by: Loic Poulain <loic.poulain@linaro.org> > > --- > > arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 24 ++++++++++++++++++++++++ > > arch/arm64/boot/dts/qcom/msm8916.dtsi | 24 ++++++++++++++++++++++++ > > arch/arm64/boot/dts/qcom/pm8916.dtsi | 6 ++++++ > > 3 files changed, 54 insertions(+) > > > > diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > > index 037e26b..f1c1216 100644 > > --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > > +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > > @@ -560,6 +560,30 @@ > > qcom,mbhc-vthreshold-high = <75 150 237 450 500>; > > }; > > > > +&spm_regulators { > > + vdd_cpu: s2 { > > + regulator-always-on; > > + regulator-min-microvolt = <1050000>; > > + regulator-max-microvolt = <1350000>; > > + }; > > +}; > > + > > +&CPU0 { > > + cpu-supply = <&vdd_cpu>; > > +}; > > + > > +&CPU1 { > > + cpu-supply = <&vdd_cpu>; > > +}; > > + > > +&CPU2 { > > + cpu-supply = <&vdd_cpu>; > > +}; > > + > > +&CPU3 { > > + cpu-supply = <&vdd_cpu>; > > +}; > > + > > I'm a bit confused about the separation here. The cpu-supply is defined > in the board-specific device tree, yet the voltages are set in the > common device tree below. > > Is it even possible that the CPU is supplied by something other than S2 > and if yes, how likely is this? > > I'm asking because I have two other MSM8916 devices in mainline > (and a few more pending upstreaming), and it seems like I would need to > duplicate this into each of them. > > Thanks, > Stephan > > > &smd_rpm_regulators { > > vdd_l1_l2_l3-supply = <&pm8916_s3>; > > vdd_l5-supply = <&pm8916_s3>; > > diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > index 9f31064..9805af0 100644 > > --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi > > +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > @@ -342,15 +342,39 @@ > > > > opp-200000000 { > > opp-hz = /bits/ 64 <200000000>; > > + opp-microvolt = <1050000>; > > }; > > opp-400000000 { > > opp-hz = /bits/ 64 <400000000>; > > + opp-microvolt = <1050000>; > > + }; > > + opp-533330000 { > > + opp-hz = /bits/ 64 <533330000>; > > + opp-microvolt = <1150000>; > > }; > > opp-800000000 { > > opp-hz = /bits/ 64 <800000000>; > > + opp-microvolt = <1150000>; > > }; > > opp-998400000 { > > opp-hz = /bits/ 64 <998400000>; > > + opp-microvolt = <1350000>; > > + }; > > + opp-1094400000 { > > + opp-hz = /bits/ 64 <1094400000>; > > + opp-microvolt = <1350000>; > > + }; > > + opp-1152000000 { > > + opp-hz = /bits/ 64 <1152000000>; > > + opp-microvolt = <1350000>; > > + }; > > + opp-1209600000 { > > + opp-hz = /bits/ 64 <1209600000>; > > + opp-microvolt = <1350000>; > > + }; > > + opp-1363200000 { > > + opp-hz = /bits/ 64 <1363200000>; > > + opp-microvolt = <1350000>; > > }; > > }; > > > > diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi > > index 0bcdf04..c9b9c4f 100644 > > --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi > > +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi > > @@ -157,5 +157,11 @@ > > vdd-micbias-supply = <&pm8916_l13>; > > #sound-dai-cells = <1>; > > }; > > + > > + spm_regulators: spm_regulators { > > + compatible = "qcom,pm8916-regulators"; > > + #address-cells = <1>; > > + #size-cells = <1>; > > + }; > > }; > > }; > > -- > > 2.7.4 > > ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-04-03 1:31 ` Bjorn Andersson @ 2020-04-03 10:09 ` Stephan Gerhold 2020-04-03 18:00 ` Stephan Gerhold 0 siblings, 1 reply; 32+ messages in thread From: Stephan Gerhold @ 2020-04-03 10:09 UTC (permalink / raw) To: Bjorn Andersson; +Cc: Loic Poulain, agross, linux-arm-msm On Thu, Apr 02, 2020 at 06:31:19PM -0700, Bjorn Andersson wrote: > On Thu 02 Apr 01:13 PDT 2020, Stephan Gerhold wrote: > > > Hi, > > > > On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > > > The highest cpu frequency opps have been dropped because CPR is not > > > supported. However, we can simply specify operating voltage so that > > > they match the max corner voltages for each freq. With that, we can > > > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > > > fine tune operating voltages and optimize power consumption. > > > > Thanks for the patch! I was wondering how to enable the higher CPU > > frequencies for a while now... > > > > I was actually quite excited to see CPR being mainlined for QCS404. > > If we are trying to add such a workaround (rather than CPR) for MSM8916 > > now, does that mean it's unlikely to see CPR working for MSM8916 > > anytime soon? > > > > AFAICT, there is a WIP branch from Niklas Cassel here: > > https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline > > but it hasn't been updated for a while. (Not sure if it was working > > already...) > > > > Can someone explain what is missing to make CPR work for MSM8916? > > > > CPR needs to control 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 it > seems we don't have to adjust VDD_MX, so the code for this is missing > from the driver. > > So, afaict, what's missing is that rpmpd.c needs to gain support for > 8916, then the CPR driver needs to gain a cpr_acc_desc and compatible > for 8916, it needs to reference the VDDMX power domain and before/after > we're adjusting the corner of the CPR we need to adjust the MX according > to the mapping specified in the downstream kernel (i.e. 1->4, 2->5 and > 3->7). > > > Unfortunately, the requirement that VDDMX (VDD_MEM I presume) must be > higher than VDD_APC most likely needs to be taken into consideration for > Loic's proposed static voltage scaling as well. Unless VDD_MEM is left > in Turbo mode from the boot loader I think we need to take VDDMX to > corner 7 for speeds 998MHz and above (i.e. where we pull VDD_APC to > 1.35V). > I see! I wonder how hard it would be to add MSM8916 to rpmpd, looking at previous commits it's mainly setting up a few defines? If I understand it correctly, the OPPs from rpmpd could then be referenced as "required-opps" in the CPU OPP table so that VDD_MX is scaled together with the CPU frequency, and doesn't need to stay at turbo mode (like in v3 from Loic) the whole time. Scaling VDD_APC and VDD_MEM to the maximum necessary for the selected CPU frequency sounds like a good (temporary) solution to me until we have full CPR eventually at some point. Thanks, Stephan > > One other minor comment/question below. > > > > > > > > This patch: > > > - Adds missing opps and corresponding target voltages to msm8916.dtsi. > > > - Adds cpu-supply to apq8016-sbc.dtsi (board level info). > > > - Adds pm8916 spmi regulator node to pm8916.dtsi. > > > > > > Tested with a dragonboard-410c. > > > > > > Signed-off-by: Loic Poulain <loic.poulain@linaro.org> > > > --- > > > arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 24 ++++++++++++++++++++++++ > > > arch/arm64/boot/dts/qcom/msm8916.dtsi | 24 ++++++++++++++++++++++++ > > > arch/arm64/boot/dts/qcom/pm8916.dtsi | 6 ++++++ > > > 3 files changed, 54 insertions(+) > > > > > > diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > > > index 037e26b..f1c1216 100644 > > > --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > > > +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > > > @@ -560,6 +560,30 @@ > > > qcom,mbhc-vthreshold-high = <75 150 237 450 500>; > > > }; > > > > > > +&spm_regulators { > > > + vdd_cpu: s2 { > > > + regulator-always-on; > > > + regulator-min-microvolt = <1050000>; > > > + regulator-max-microvolt = <1350000>; > > > + }; > > > +}; > > > + > > > +&CPU0 { > > > + cpu-supply = <&vdd_cpu>; > > > +}; > > > + > > > +&CPU1 { > > > + cpu-supply = <&vdd_cpu>; > > > +}; > > > + > > > +&CPU2 { > > > + cpu-supply = <&vdd_cpu>; > > > +}; > > > + > > > +&CPU3 { > > > + cpu-supply = <&vdd_cpu>; > > > +}; > > > + > > > > I'm a bit confused about the separation here. The cpu-supply is defined > > in the board-specific device tree, yet the voltages are set in the > > common device tree below. > > > > Is it even possible that the CPU is supplied by something other than S2 > > and if yes, how likely is this? > > > > I'm asking because I have two other MSM8916 devices in mainline > > (and a few more pending upstreaming), and it seems like I would need to > > duplicate this into each of them. > > > > Thanks, > > Stephan > > > > > &smd_rpm_regulators { > > > vdd_l1_l2_l3-supply = <&pm8916_s3>; > > > vdd_l5-supply = <&pm8916_s3>; > > > diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > index 9f31064..9805af0 100644 > > > --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > @@ -342,15 +342,39 @@ > > > > > > opp-200000000 { > > > opp-hz = /bits/ 64 <200000000>; > > > + opp-microvolt = <1050000>; > > > }; > > > opp-400000000 { > > > opp-hz = /bits/ 64 <400000000>; > > > + opp-microvolt = <1050000>; > > > + }; > > > + opp-533330000 { > > > + opp-hz = /bits/ 64 <533330000>; > > > + opp-microvolt = <1150000>; > > > }; > > > opp-800000000 { > > > opp-hz = /bits/ 64 <800000000>; > > > + opp-microvolt = <1150000>; > > > }; > > > opp-998400000 { > > > opp-hz = /bits/ 64 <998400000>; > > > + opp-microvolt = <1350000>; > > > + }; > > > + opp-1094400000 { > > > + opp-hz = /bits/ 64 <1094400000>; > > > + opp-microvolt = <1350000>; > > > + }; > > > + opp-1152000000 { > > > + opp-hz = /bits/ 64 <1152000000>; > > > + opp-microvolt = <1350000>; > > > + }; > > > + opp-1209600000 { > > > + opp-hz = /bits/ 64 <1209600000>; > > > + opp-microvolt = <1350000>; > > > + }; > > > + opp-1363200000 { > > > + opp-hz = /bits/ 64 <1363200000>; > > > + opp-microvolt = <1350000>; > > > }; > > > }; > > > > > > diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi > > > index 0bcdf04..c9b9c4f 100644 > > > --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi > > > +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi > > > @@ -157,5 +157,11 @@ > > > vdd-micbias-supply = <&pm8916_l13>; > > > #sound-dai-cells = <1>; > > > }; > > > + > > > + spm_regulators: spm_regulators { > > > + compatible = "qcom,pm8916-regulators"; > > > + #address-cells = <1>; > > > + #size-cells = <1>; > > > + }; > > > }; > > > }; > > > -- > > > 2.7.4 > > > ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-04-03 10:09 ` Stephan Gerhold @ 2020-04-03 18:00 ` Stephan Gerhold 2020-04-23 4:55 ` Bjorn Andersson 0 siblings, 1 reply; 32+ messages in thread From: Stephan Gerhold @ 2020-04-03 18:00 UTC (permalink / raw) To: Bjorn Andersson; +Cc: Loic Poulain, agross, linux-arm-msm On Fri, Apr 03, 2020 at 12:09:25PM +0200, Stephan Gerhold wrote: > On Thu, Apr 02, 2020 at 06:31:19PM -0700, Bjorn Andersson wrote: > > On Thu 02 Apr 01:13 PDT 2020, Stephan Gerhold wrote: > > > > > Hi, > > > > > > On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > > > > The highest cpu frequency opps have been dropped because CPR is not > > > > supported. However, we can simply specify operating voltage so that > > > > they match the max corner voltages for each freq. With that, we can > > > > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > > > > fine tune operating voltages and optimize power consumption. > > > > > > Thanks for the patch! I was wondering how to enable the higher CPU > > > frequencies for a while now... > > > > > > I was actually quite excited to see CPR being mainlined for QCS404. > > > If we are trying to add such a workaround (rather than CPR) for MSM8916 > > > now, does that mean it's unlikely to see CPR working for MSM8916 > > > anytime soon? > > > > > > AFAICT, there is a WIP branch from Niklas Cassel here: > > > https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline > > > but it hasn't been updated for a while. (Not sure if it was working > > > already...) > > > > > > Can someone explain what is missing to make CPR work for MSM8916? > > > > > > > CPR needs to control 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 it > > seems we don't have to adjust VDD_MX, so the code for this is missing > > from the driver. > > > > So, afaict, what's missing is that rpmpd.c needs to gain support for > > 8916, then the CPR driver needs to gain a cpr_acc_desc and compatible > > for 8916, it needs to reference the VDDMX power domain and before/after > > we're adjusting the corner of the CPR we need to adjust the MX according > > to the mapping specified in the downstream kernel (i.e. 1->4, 2->5 and > > 3->7). > > > > > > Unfortunately, the requirement that VDDMX (VDD_MEM I presume) must be > > higher than VDD_APC most likely needs to be taken into consideration for > > Loic's proposed static voltage scaling as well. Unless VDD_MEM is left > > in Turbo mode from the boot loader I think we need to take VDDMX to > > corner 7 for speeds 998MHz and above (i.e. where we pull VDD_APC to > > 1.35V). > > > > I see! I wonder how hard it would be to add MSM8916 to rpmpd, > looking at previous commits it's mainly setting up a few defines? > > If I understand it correctly, the OPPs from rpmpd could then be > referenced as "required-opps" in the CPU OPP table so that VDD_MX is > scaled together with the CPU frequency, and doesn't need to stay at > turbo mode (like in v3 from Loic) the whole time. > I have been thinking about this some more and I think I came up with some changes that make sense (but not entirely sure). Based on the available downstream sources I guessed the defines to add for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as "required-opps" to the CPU OPP table so it would vote for the appopriate corners (with the mapping you mentioned above). I haven't tested it yet, maybe I can get some feedback first if the code seems reasonable or if I'm missing something obvious? :) Also: Is there a good way to validate these changes? I suppose I could check the genpd state but that wouldn't tell me if the corner was applied correctly. Maybe I can check the actual voltage through the SPMI interface, hm... If this seems like a good approach I can split up the changes in reasonable patches and post it separately. For now the full diff below. Stephan arch/arm64/boot/dts/qcom/msm8916.dtsi | 65 +++++++++++++++++++++++++++++----- drivers/cpufreq/cpufreq-dt-platdev.c | 1 + drivers/cpufreq/qcom-cpufreq-nvmem.c | 11 ++++++ drivers/soc/qcom/rpmpd.c | 21 +++++++++++ include/dt-bindings/power/qcom-rpmpd.h | 7 ++++ 5 files changed, 96 insertions(+), 9 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index b0a82447976a..5b8fce8609d0 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -10,6 +10,7 @@ #include <dt-bindings/soc/qcom,apr.h> #include <dt-bindings/sound/qcom,q6afe.h> #include <dt-bindings/thermal/thermal.h> +#include <dt-bindings/power/qcom-rpmpd.h> / { interrupt-parent = <&intc>; @@ -108,8 +109,8 @@ CPU0: cpu@0 { cpu-supply = <&pm8916_spmi_s2>; operating-points-v2 = <&cpu_opp_table>; #cooling-cells = <2>; - power-domains = <&CPU_PD0>; - power-domain-names = "psci"; + power-domains = <&CPU_PD0>, <&rpmpd MSM8916_VDDMX_AO>; + power-domain-names = "psci", "mx"; }; CPU1: cpu@1 { @@ -122,8 +123,8 @@ CPU1: cpu@1 { cpu-supply = <&pm8916_spmi_s2>; operating-points-v2 = <&cpu_opp_table>; #cooling-cells = <2>; - power-domains = <&CPU_PD1>; - power-domain-names = "psci"; + power-domains = <&CPU_PD1>, <&rpmpd MSM8916_VDDMX_AO>; + power-domain-names = "psci", "mx"; }; CPU2: cpu@2 { @@ -136,8 +137,8 @@ CPU2: cpu@2 { cpu-supply = <&pm8916_spmi_s2>; operating-points-v2 = <&cpu_opp_table>; #cooling-cells = <2>; - power-domains = <&CPU_PD2>; - power-domain-names = "psci"; + power-domains = <&CPU_PD2>, <&rpmpd MSM8916_VDDMX_AO>; + power-domain-names = "psci", "mx"; }; CPU3: cpu@3 { @@ -150,8 +151,8 @@ CPU3: cpu@3 { cpu-supply = <&pm8916_spmi_s2>; operating-points-v2 = <&cpu_opp_table>; #cooling-cells = <2>; - power-domains = <&CPU_PD3>; - power-domain-names = "psci"; + power-domains = <&CPU_PD3>, <&rpmpd MSM8916_VDDMX_AO>; + power-domain-names = "psci", "mx"; }; L2_0: l2-cache { @@ -343,40 +344,52 @@ modem_alert0: trip-point@0 { }; cpu_opp_table: cpu_opp_table { - compatible = "operating-points-v2"; + /* + * FIXME: The naming here is really weird, since MSM8916 does + * not have kyro. Maybe we should add a more generic compatible? + */ + compatible = "operating-points-v2-kryo-cpu"; opp-shared; opp-200000000 { opp-hz = /bits/ 64 <200000000>; opp-microvolt = <1050000>; + required-opps = <&rpmpd_opp_svs_soc>; }; opp-400000000 { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <1050000>; + required-opps = <&rpmpd_opp_svs_soc>; }; opp-533330000 { opp-hz = /bits/ 64 <533330000>; opp-microvolt = <1150000>; + required-opps = <&rpmpd_opp_nom>; }; opp-800000000 { opp-hz = /bits/ 64 <800000000>; opp-microvolt = <1150000>; + required-opps = <&rpmpd_opp_nom>; }; opp-998400000 { opp-hz = /bits/ 64 <998400000>; opp-microvolt = <1350000>; + required-opps = <&rpmpd_opp_super_turbo>; }; opp-1094400000 { opp-hz = /bits/ 64 <1094400000>; opp-microvolt = <1350000>; + required-opps = <&rpmpd_opp_super_turbo>; }; opp-1152000000 { opp-hz = /bits/ 64 <1152000000>; opp-microvolt = <1350000>; + required-opps = <&rpmpd_opp_super_turbo>; }; opp-1209600000 { opp-hz = /bits/ 64 <1209600000>; opp-microvolt = <1350000>; + required-opps = <&rpmpd_opp_super_turbo>; }; }; @@ -1710,6 +1723,40 @@ rpmcc: qcom,rpmcc { #clock-cells = <1>; }; + rpmpd: power-controller { + compatible = "qcom,msm8916-rpmpd"; + #power-domain-cells = <1>; + operating-points-v2 = <&rpmpd_opp_table>; + + rpmpd_opp_table: opp-table { + compatible = "operating-points-v2"; + + rpmpd_opp_ret: opp1 { + opp-level = <1>; + }; + + rpmpd_opp_svs: opp2 { + opp-level = <2>; + }; + + rpmpd_opp_svs_soc: opp3 { + opp-level = <3>; + }; + + rpmpd_opp_nom: opp4 { + opp-level = <4>; + }; + + rpmpd_opp_turbo: opp5 { + opp-level = <5>; + }; + + rpmpd_opp_super_turbo: opp6 { + opp-level = <6>; + }; + }; + }; + smd_rpm_regulators: pm8916-regulators { compatible = "qcom,rpm-pm8916-regulators"; diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index f2ae9cd455c1..b0f6bd0fffc1 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -128,6 +128,7 @@ static const struct of_device_id blacklist[] __initconst = { { .compatible = "nvidia,tegra210", }, { .compatible = "qcom,apq8096", }, + { .compatible = "qcom,msm8916", }, { .compatible = "qcom,msm8996", }, { .compatible = "qcom,qcs404", }, diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c index f0d2d5035413..c77a30349d08 100644 --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c @@ -129,6 +129,16 @@ static const struct qcom_cpufreq_match_data match_data_kryo = { .get_version = qcom_cpufreq_kryo_name_version, }; +static const char *msm8916_genpd_names[] = { "mx", NULL }; + +static const struct qcom_cpufreq_match_data match_data_msm8916 = { + /* + * FIXME: Might need to implement .get_version here to handle + * different frequencies depending on speedbin/pvs version. + */ + .genpd_names = msm8916_genpd_names, +}; + static const char *qcs404_genpd_names[] = { "cpr", NULL }; static const struct qcom_cpufreq_match_data match_data_qcs404 = { @@ -301,6 +311,7 @@ static struct platform_driver qcom_cpufreq_driver = { static const struct of_device_id qcom_cpufreq_match_list[] __initconst = { { .compatible = "qcom,apq8096", .data = &match_data_kryo }, + { .compatible = "qcom,msm8916", .data = &match_data_msm8916 }, { .compatible = "qcom,msm8996", .data = &match_data_kryo }, { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, {}, diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index 2b1834c5609a..192ba9099964 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -115,6 +115,26 @@ struct rpmpd_desc { static DEFINE_MUTEX(rpmpd_lock); +/* msm8916 RPM Power Domains */ +DEFINE_RPMPD_PAIR(msm8916, vddcx, vddcx_ao, SMPA, CORNER, 1); +DEFINE_RPMPD_PAIR(msm8916, vddmx, vddmx_ao, LDOA, CORNER, 3); + +DEFINE_RPMPD_VFC(msm8916, vddcx_vfc, SMPA, 1); + +static struct rpmpd *msm8916_rpmpds[] = { + [MSM8916_VDDCX] = &msm8916_vddcx, + [MSM8916_VDDCX_AO] = &msm8916_vddcx_ao, + [MSM8916_VDDCX_VFC] = &msm8916_vddcx_vfc, + [MSM8916_VDDMX] = &msm8916_vddmx, + [MSM8916_VDDMX_AO] = &msm8916_vddmx_ao, +}; + +static const struct rpmpd_desc msm8916_desc = { + .rpmpds = msm8916_rpmpds, + .num_pds = ARRAY_SIZE(msm8916_rpmpds), + .max_state = MAX_8996_RPMPD_STATE, +}; + /* msm8976 RPM Power Domains */ DEFINE_RPMPD_PAIR(msm8976, vddcx, vddcx_ao, SMPA, LEVEL, 2); DEFINE_RPMPD_PAIR(msm8976, vddmx, vddmx_ao, SMPA, LEVEL, 6); @@ -220,6 +240,7 @@ static const struct rpmpd_desc qcs404_desc = { }; static const struct of_device_id rpmpd_match_table[] = { + { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc }, { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc }, { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index 3f74096d5a7c..70d304a2deae 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -51,6 +51,13 @@ #define RPMH_REGULATOR_LEVEL_TURBO 384 #define RPMH_REGULATOR_LEVEL_TURBO_L1 416 +/* MSM8916 Power Domain Indexes */ +#define MSM8916_VDDCX 0 +#define MSM8916_VDDCX_AO 1 +#define MSM8916_VDDCX_VFC 2 +#define MSM8916_VDDMX 3 +#define MSM8916_VDDMX_AO 4 + /* MSM8976 Power Domain Indexes */ #define MSM8976_VDDCX 0 #define MSM8976_VDDCX_AO 1 ^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-04-03 18:00 ` Stephan Gerhold @ 2020-04-23 4:55 ` Bjorn Andersson 2020-04-26 12:31 ` Stephan Gerhold 2020-05-25 15:32 ` Niklas Cassel 0 siblings, 2 replies; 32+ messages in thread From: Bjorn Andersson @ 2020-04-23 4:55 UTC (permalink / raw) To: Stephan Gerhold; +Cc: Loic Poulain, agross, linux-arm-msm On Fri 03 Apr 11:00 PDT 2020, Stephan Gerhold wrote: > On Fri, Apr 03, 2020 at 12:09:25PM +0200, Stephan Gerhold wrote: > > On Thu, Apr 02, 2020 at 06:31:19PM -0700, Bjorn Andersson wrote: > > > On Thu 02 Apr 01:13 PDT 2020, Stephan Gerhold wrote: > > > > > > > Hi, > > > > > > > > On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > > > > > The highest cpu frequency opps have been dropped because CPR is not > > > > > supported. However, we can simply specify operating voltage so that > > > > > they match the max corner voltages for each freq. With that, we can > > > > > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > > > > > fine tune operating voltages and optimize power consumption. > > > > > > > > Thanks for the patch! I was wondering how to enable the higher CPU > > > > frequencies for a while now... > > > > > > > > I was actually quite excited to see CPR being mainlined for QCS404. > > > > If we are trying to add such a workaround (rather than CPR) for MSM8916 > > > > now, does that mean it's unlikely to see CPR working for MSM8916 > > > > anytime soon? > > > > > > > > AFAICT, there is a WIP branch from Niklas Cassel here: > > > > https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline > > > > but it hasn't been updated for a while. (Not sure if it was working > > > > already...) > > > > > > > > Can someone explain what is missing to make CPR work for MSM8916? > > > > > > > > > > CPR needs to control 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 it > > > seems we don't have to adjust VDD_MX, so the code for this is missing > > > from the driver. > > > > > > So, afaict, what's missing is that rpmpd.c needs to gain support for > > > 8916, then the CPR driver needs to gain a cpr_acc_desc and compatible > > > for 8916, it needs to reference the VDDMX power domain and before/after > > > we're adjusting the corner of the CPR we need to adjust the MX according > > > to the mapping specified in the downstream kernel (i.e. 1->4, 2->5 and > > > 3->7). > > > > > > > > > Unfortunately, the requirement that VDDMX (VDD_MEM I presume) must be > > > higher than VDD_APC most likely needs to be taken into consideration for > > > Loic's proposed static voltage scaling as well. Unless VDD_MEM is left > > > in Turbo mode from the boot loader I think we need to take VDDMX to > > > corner 7 for speeds 998MHz and above (i.e. where we pull VDD_APC to > > > 1.35V). > > > > > > > I see! I wonder how hard it would be to add MSM8916 to rpmpd, > > looking at previous commits it's mainly setting up a few defines? > > > > If I understand it correctly, the OPPs from rpmpd could then be > > referenced as "required-opps" in the CPU OPP table so that VDD_MX is > > scaled together with the CPU frequency, and doesn't need to stay at > > turbo mode (like in v3 from Loic) the whole time. > > > > I have been thinking about this some more and I think I came up with > some changes that make sense (but not entirely sure). > > Based on the available downstream sources I guessed the defines to add > for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as > "required-opps" to the CPU OPP table so it would vote for the appopriate > corners (with the mapping you mentioned above). > I was not aware it was possible to describe the dependency between the CPU opp table and MX in this fashion. If that's the case then this looks really good and it should be straight forward to add MSM8916 support to the CPR driver as well. > I haven't tested it yet, maybe I can get some feedback first if the code > seems reasonable or if I'm missing something obvious? :) > Have you tested this yet? > Also: Is there a good way to validate these changes? > I suppose I could check the genpd state but that wouldn't tell me if the > corner was applied correctly. Maybe I can check the actual voltage > through the SPMI interface, hm... > Validating that S2 and VDD_MX changes appropriately in Linux would be a pretty good test. > If this seems like a good approach I can split up the changes in > reasonable patches and post it separately. For now the full diff below. > Please do Regards, Bjorn > Stephan > > arch/arm64/boot/dts/qcom/msm8916.dtsi | 65 +++++++++++++++++++++++++++++----- > drivers/cpufreq/cpufreq-dt-platdev.c | 1 + > drivers/cpufreq/qcom-cpufreq-nvmem.c | 11 ++++++ > drivers/soc/qcom/rpmpd.c | 21 +++++++++++ > include/dt-bindings/power/qcom-rpmpd.h | 7 ++++ > 5 files changed, 96 insertions(+), 9 deletions(-) > > diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi > index b0a82447976a..5b8fce8609d0 100644 > --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi > +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi > @@ -10,6 +10,7 @@ > #include <dt-bindings/soc/qcom,apr.h> > #include <dt-bindings/sound/qcom,q6afe.h> > #include <dt-bindings/thermal/thermal.h> > +#include <dt-bindings/power/qcom-rpmpd.h> > > / { > interrupt-parent = <&intc>; > @@ -108,8 +109,8 @@ CPU0: cpu@0 { > cpu-supply = <&pm8916_spmi_s2>; > operating-points-v2 = <&cpu_opp_table>; > #cooling-cells = <2>; > - power-domains = <&CPU_PD0>; > - power-domain-names = "psci"; > + power-domains = <&CPU_PD0>, <&rpmpd MSM8916_VDDMX_AO>; > + power-domain-names = "psci", "mx"; > }; > > CPU1: cpu@1 { > @@ -122,8 +123,8 @@ CPU1: cpu@1 { > cpu-supply = <&pm8916_spmi_s2>; > operating-points-v2 = <&cpu_opp_table>; > #cooling-cells = <2>; > - power-domains = <&CPU_PD1>; > - power-domain-names = "psci"; > + power-domains = <&CPU_PD1>, <&rpmpd MSM8916_VDDMX_AO>; > + power-domain-names = "psci", "mx"; > }; > > CPU2: cpu@2 { > @@ -136,8 +137,8 @@ CPU2: cpu@2 { > cpu-supply = <&pm8916_spmi_s2>; > operating-points-v2 = <&cpu_opp_table>; > #cooling-cells = <2>; > - power-domains = <&CPU_PD2>; > - power-domain-names = "psci"; > + power-domains = <&CPU_PD2>, <&rpmpd MSM8916_VDDMX_AO>; > + power-domain-names = "psci", "mx"; > }; > > CPU3: cpu@3 { > @@ -150,8 +151,8 @@ CPU3: cpu@3 { > cpu-supply = <&pm8916_spmi_s2>; > operating-points-v2 = <&cpu_opp_table>; > #cooling-cells = <2>; > - power-domains = <&CPU_PD3>; > - power-domain-names = "psci"; > + power-domains = <&CPU_PD3>, <&rpmpd MSM8916_VDDMX_AO>; > + power-domain-names = "psci", "mx"; > }; > > L2_0: l2-cache { > @@ -343,40 +344,52 @@ modem_alert0: trip-point@0 { > }; > > cpu_opp_table: cpu_opp_table { > - compatible = "operating-points-v2"; > + /* > + * FIXME: The naming here is really weird, since MSM8916 does > + * not have kyro. Maybe we should add a more generic compatible? > + */ > + compatible = "operating-points-v2-kryo-cpu"; > opp-shared; > > opp-200000000 { > opp-hz = /bits/ 64 <200000000>; > opp-microvolt = <1050000>; > + required-opps = <&rpmpd_opp_svs_soc>; > }; > opp-400000000 { > opp-hz = /bits/ 64 <400000000>; > opp-microvolt = <1050000>; > + required-opps = <&rpmpd_opp_svs_soc>; > }; > opp-533330000 { > opp-hz = /bits/ 64 <533330000>; > opp-microvolt = <1150000>; > + required-opps = <&rpmpd_opp_nom>; > }; > opp-800000000 { > opp-hz = /bits/ 64 <800000000>; > opp-microvolt = <1150000>; > + required-opps = <&rpmpd_opp_nom>; > }; > opp-998400000 { > opp-hz = /bits/ 64 <998400000>; > opp-microvolt = <1350000>; > + required-opps = <&rpmpd_opp_super_turbo>; > }; > opp-1094400000 { > opp-hz = /bits/ 64 <1094400000>; > opp-microvolt = <1350000>; > + required-opps = <&rpmpd_opp_super_turbo>; > }; > opp-1152000000 { > opp-hz = /bits/ 64 <1152000000>; > opp-microvolt = <1350000>; > + required-opps = <&rpmpd_opp_super_turbo>; > }; > opp-1209600000 { > opp-hz = /bits/ 64 <1209600000>; > opp-microvolt = <1350000>; > + required-opps = <&rpmpd_opp_super_turbo>; > }; > }; > > @@ -1710,6 +1723,40 @@ rpmcc: qcom,rpmcc { > #clock-cells = <1>; > }; > > + rpmpd: power-controller { > + compatible = "qcom,msm8916-rpmpd"; > + #power-domain-cells = <1>; > + operating-points-v2 = <&rpmpd_opp_table>; > + > + rpmpd_opp_table: opp-table { > + compatible = "operating-points-v2"; > + > + rpmpd_opp_ret: opp1 { > + opp-level = <1>; > + }; > + > + rpmpd_opp_svs: opp2 { > + opp-level = <2>; > + }; > + > + rpmpd_opp_svs_soc: opp3 { > + opp-level = <3>; > + }; > + > + rpmpd_opp_nom: opp4 { > + opp-level = <4>; > + }; > + > + rpmpd_opp_turbo: opp5 { > + opp-level = <5>; > + }; > + > + rpmpd_opp_super_turbo: opp6 { > + opp-level = <6>; > + }; > + }; > + }; > + > smd_rpm_regulators: pm8916-regulators { > compatible = "qcom,rpm-pm8916-regulators"; > > diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c > index f2ae9cd455c1..b0f6bd0fffc1 100644 > --- a/drivers/cpufreq/cpufreq-dt-platdev.c > +++ b/drivers/cpufreq/cpufreq-dt-platdev.c > @@ -128,6 +128,7 @@ static const struct of_device_id blacklist[] __initconst = { > { .compatible = "nvidia,tegra210", }, > > { .compatible = "qcom,apq8096", }, > + { .compatible = "qcom,msm8916", }, > { .compatible = "qcom,msm8996", }, > { .compatible = "qcom,qcs404", }, > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > index f0d2d5035413..c77a30349d08 100644 > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > @@ -129,6 +129,16 @@ static const struct qcom_cpufreq_match_data match_data_kryo = { > .get_version = qcom_cpufreq_kryo_name_version, > }; > > +static const char *msm8916_genpd_names[] = { "mx", NULL }; > + > +static const struct qcom_cpufreq_match_data match_data_msm8916 = { > + /* > + * FIXME: Might need to implement .get_version here to handle > + * different frequencies depending on speedbin/pvs version. > + */ > + .genpd_names = msm8916_genpd_names, > +}; > + > static const char *qcs404_genpd_names[] = { "cpr", NULL }; > > static const struct qcom_cpufreq_match_data match_data_qcs404 = { > @@ -301,6 +311,7 @@ static struct platform_driver qcom_cpufreq_driver = { > > static const struct of_device_id qcom_cpufreq_match_list[] __initconst = { > { .compatible = "qcom,apq8096", .data = &match_data_kryo }, > + { .compatible = "qcom,msm8916", .data = &match_data_msm8916 }, > { .compatible = "qcom,msm8996", .data = &match_data_kryo }, > { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, > {}, > diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c > index 2b1834c5609a..192ba9099964 100644 > --- a/drivers/soc/qcom/rpmpd.c > +++ b/drivers/soc/qcom/rpmpd.c > @@ -115,6 +115,26 @@ struct rpmpd_desc { > > static DEFINE_MUTEX(rpmpd_lock); > > +/* msm8916 RPM Power Domains */ > +DEFINE_RPMPD_PAIR(msm8916, vddcx, vddcx_ao, SMPA, CORNER, 1); > +DEFINE_RPMPD_PAIR(msm8916, vddmx, vddmx_ao, LDOA, CORNER, 3); > + > +DEFINE_RPMPD_VFC(msm8916, vddcx_vfc, SMPA, 1); > + > +static struct rpmpd *msm8916_rpmpds[] = { > + [MSM8916_VDDCX] = &msm8916_vddcx, > + [MSM8916_VDDCX_AO] = &msm8916_vddcx_ao, > + [MSM8916_VDDCX_VFC] = &msm8916_vddcx_vfc, > + [MSM8916_VDDMX] = &msm8916_vddmx, > + [MSM8916_VDDMX_AO] = &msm8916_vddmx_ao, > +}; > + > +static const struct rpmpd_desc msm8916_desc = { > + .rpmpds = msm8916_rpmpds, > + .num_pds = ARRAY_SIZE(msm8916_rpmpds), > + .max_state = MAX_8996_RPMPD_STATE, > +}; > + > /* msm8976 RPM Power Domains */ > DEFINE_RPMPD_PAIR(msm8976, vddcx, vddcx_ao, SMPA, LEVEL, 2); > DEFINE_RPMPD_PAIR(msm8976, vddmx, vddmx_ao, SMPA, LEVEL, 6); > @@ -220,6 +240,7 @@ static const struct rpmpd_desc qcs404_desc = { > }; > > static const struct of_device_id rpmpd_match_table[] = { > + { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc }, > { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc }, > { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, > { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, > diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h > index 3f74096d5a7c..70d304a2deae 100644 > --- a/include/dt-bindings/power/qcom-rpmpd.h > +++ b/include/dt-bindings/power/qcom-rpmpd.h > @@ -51,6 +51,13 @@ > #define RPMH_REGULATOR_LEVEL_TURBO 384 > #define RPMH_REGULATOR_LEVEL_TURBO_L1 416 > > +/* MSM8916 Power Domain Indexes */ > +#define MSM8916_VDDCX 0 > +#define MSM8916_VDDCX_AO 1 > +#define MSM8916_VDDCX_VFC 2 > +#define MSM8916_VDDMX 3 > +#define MSM8916_VDDMX_AO 4 > + > /* MSM8976 Power Domain Indexes */ > #define MSM8976_VDDCX 0 > #define MSM8976_VDDCX_AO 1 ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-04-23 4:55 ` Bjorn Andersson @ 2020-04-26 12:31 ` Stephan Gerhold 2020-05-06 21:18 ` Stephan Gerhold 2020-05-25 15:32 ` Niklas Cassel 1 sibling, 1 reply; 32+ messages in thread From: Stephan Gerhold @ 2020-04-26 12:31 UTC (permalink / raw) To: Bjorn Andersson; +Cc: Loic Poulain, agross, linux-arm-msm On Wed, Apr 22, 2020 at 09:55:06PM -0700, Bjorn Andersson wrote: > On Fri 03 Apr 11:00 PDT 2020, Stephan Gerhold wrote: > > > On Fri, Apr 03, 2020 at 12:09:25PM +0200, Stephan Gerhold wrote: > > > On Thu, Apr 02, 2020 at 06:31:19PM -0700, Bjorn Andersson wrote: > > > > On Thu 02 Apr 01:13 PDT 2020, Stephan Gerhold wrote: > > > > > > > > > Hi, > > > > > > > > > > On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > > > > > > The highest cpu frequency opps have been dropped because CPR is not > > > > > > supported. However, we can simply specify operating voltage so that > > > > > > they match the max corner voltages for each freq. With that, we can > > > > > > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > > > > > > fine tune operating voltages and optimize power consumption. > > > > > > > > > > Thanks for the patch! I was wondering how to enable the higher CPU > > > > > frequencies for a while now... > > > > > > > > > > I was actually quite excited to see CPR being mainlined for QCS404. > > > > > If we are trying to add such a workaround (rather than CPR) for MSM8916 > > > > > now, does that mean it's unlikely to see CPR working for MSM8916 > > > > > anytime soon? > > > > > > > > > > AFAICT, there is a WIP branch from Niklas Cassel here: > > > > > https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline > > > > > but it hasn't been updated for a while. (Not sure if it was working > > > > > already...) > > > > > > > > > > Can someone explain what is missing to make CPR work for MSM8916? > > > > > > > > > > > > > CPR needs to control 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 it > > > > seems we don't have to adjust VDD_MX, so the code for this is missing > > > > from the driver. > > > > > > > > So, afaict, what's missing is that rpmpd.c needs to gain support for > > > > 8916, then the CPR driver needs to gain a cpr_acc_desc and compatible > > > > for 8916, it needs to reference the VDDMX power domain and before/after > > > > we're adjusting the corner of the CPR we need to adjust the MX according > > > > to the mapping specified in the downstream kernel (i.e. 1->4, 2->5 and > > > > 3->7). > > > > > > > > > > > > Unfortunately, the requirement that VDDMX (VDD_MEM I presume) must be > > > > higher than VDD_APC most likely needs to be taken into consideration for > > > > Loic's proposed static voltage scaling as well. Unless VDD_MEM is left > > > > in Turbo mode from the boot loader I think we need to take VDDMX to > > > > corner 7 for speeds 998MHz and above (i.e. where we pull VDD_APC to > > > > 1.35V). > > > > > > > > > > I see! I wonder how hard it would be to add MSM8916 to rpmpd, > > > looking at previous commits it's mainly setting up a few defines? > > > > > > If I understand it correctly, the OPPs from rpmpd could then be > > > referenced as "required-opps" in the CPU OPP table so that VDD_MX is > > > scaled together with the CPU frequency, and doesn't need to stay at > > > turbo mode (like in v3 from Loic) the whole time. > > > > > > > I have been thinking about this some more and I think I came up with > > some changes that make sense (but not entirely sure). > > > > Based on the available downstream sources I guessed the defines to add > > for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as > > "required-opps" to the CPU OPP table so it would vote for the appopriate > > corners (with the mapping you mentioned above). > > > > I was not aware it was possible to describe the dependency between the > CPU opp table and MX in this fashion. If that's the case then this looks > really good and it should be straight forward to add MSM8916 support to > the CPR driver as well. > Indeed! > > I haven't tested it yet, maybe I can get some feedback first if the code > > seems reasonable or if I'm missing something obvious? :) > > > > Have you tested this yet? > I just did. It does not fully work, yet: rpmpd_set_performance() is indeed called as necessary when switching the CPU frequency. When I set 200 MHz it sets corner 3, with 533 MHz corner 4 and starting with 998 MHz corner 6. So far so good :) However, there is never actually anything sent to the RPM. :( It bails out in rpmpd_set_performance() before calling rpmpd_aggregate_corner(): /* Always send updates for vfc and vfl */ if (!pd->enabled && pd->key != KEY_FLOOR_CORNER && pd->key != KEY_FLOOR_LEVEL) goto out; Seems like we just try to set performance states, but never actually enable (rpmpd_power_on()) the power domain (pd->enabled == false). I'm not sure which of the components involved here should handle that. The OPP core when setting required OPPs, the genpd core etc. Any ideas? Thanks, Stephan > > Also: Is there a good way to validate these changes? > > I suppose I could check the genpd state but that wouldn't tell me if the > > corner was applied correctly. Maybe I can check the actual voltage > > through the SPMI interface, hm... > > > > Validating that S2 and VDD_MX changes appropriately in Linux would be a > pretty good test. > > > If this seems like a good approach I can split up the changes in > > reasonable patches and post it separately. For now the full diff below. > > > > Please do > > Regards, > Bjorn > > > Stephan > > > > arch/arm64/boot/dts/qcom/msm8916.dtsi | 65 +++++++++++++++++++++++++++++----- > > drivers/cpufreq/cpufreq-dt-platdev.c | 1 + > > drivers/cpufreq/qcom-cpufreq-nvmem.c | 11 ++++++ > > drivers/soc/qcom/rpmpd.c | 21 +++++++++++ > > include/dt-bindings/power/qcom-rpmpd.h | 7 ++++ > > 5 files changed, 96 insertions(+), 9 deletions(-) > > > > diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > index b0a82447976a..5b8fce8609d0 100644 > > --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi > > +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > @@ -10,6 +10,7 @@ > > #include <dt-bindings/soc/qcom,apr.h> > > #include <dt-bindings/sound/qcom,q6afe.h> > > #include <dt-bindings/thermal/thermal.h> > > +#include <dt-bindings/power/qcom-rpmpd.h> > > > > / { > > interrupt-parent = <&intc>; > > @@ -108,8 +109,8 @@ CPU0: cpu@0 { > > cpu-supply = <&pm8916_spmi_s2>; > > operating-points-v2 = <&cpu_opp_table>; > > #cooling-cells = <2>; > > - power-domains = <&CPU_PD0>; > > - power-domain-names = "psci"; > > + power-domains = <&CPU_PD0>, <&rpmpd MSM8916_VDDMX_AO>; > > + power-domain-names = "psci", "mx"; > > }; > > > > CPU1: cpu@1 { > > @@ -122,8 +123,8 @@ CPU1: cpu@1 { > > cpu-supply = <&pm8916_spmi_s2>; > > operating-points-v2 = <&cpu_opp_table>; > > #cooling-cells = <2>; > > - power-domains = <&CPU_PD1>; > > - power-domain-names = "psci"; > > + power-domains = <&CPU_PD1>, <&rpmpd MSM8916_VDDMX_AO>; > > + power-domain-names = "psci", "mx"; > > }; > > > > CPU2: cpu@2 { > > @@ -136,8 +137,8 @@ CPU2: cpu@2 { > > cpu-supply = <&pm8916_spmi_s2>; > > operating-points-v2 = <&cpu_opp_table>; > > #cooling-cells = <2>; > > - power-domains = <&CPU_PD2>; > > - power-domain-names = "psci"; > > + power-domains = <&CPU_PD2>, <&rpmpd MSM8916_VDDMX_AO>; > > + power-domain-names = "psci", "mx"; > > }; > > > > CPU3: cpu@3 { > > @@ -150,8 +151,8 @@ CPU3: cpu@3 { > > cpu-supply = <&pm8916_spmi_s2>; > > operating-points-v2 = <&cpu_opp_table>; > > #cooling-cells = <2>; > > - power-domains = <&CPU_PD3>; > > - power-domain-names = "psci"; > > + power-domains = <&CPU_PD3>, <&rpmpd MSM8916_VDDMX_AO>; > > + power-domain-names = "psci", "mx"; > > }; > > > > L2_0: l2-cache { > > @@ -343,40 +344,52 @@ modem_alert0: trip-point@0 { > > }; > > > > cpu_opp_table: cpu_opp_table { > > - compatible = "operating-points-v2"; > > + /* > > + * FIXME: The naming here is really weird, since MSM8916 does > > + * not have kyro. Maybe we should add a more generic compatible? > > + */ > > + compatible = "operating-points-v2-kryo-cpu"; > > opp-shared; > > > > opp-200000000 { > > opp-hz = /bits/ 64 <200000000>; > > opp-microvolt = <1050000>; > > + required-opps = <&rpmpd_opp_svs_soc>; > > }; > > opp-400000000 { > > opp-hz = /bits/ 64 <400000000>; > > opp-microvolt = <1050000>; > > + required-opps = <&rpmpd_opp_svs_soc>; > > }; > > opp-533330000 { > > opp-hz = /bits/ 64 <533330000>; > > opp-microvolt = <1150000>; > > + required-opps = <&rpmpd_opp_nom>; > > }; > > opp-800000000 { > > opp-hz = /bits/ 64 <800000000>; > > opp-microvolt = <1150000>; > > + required-opps = <&rpmpd_opp_nom>; > > }; > > opp-998400000 { > > opp-hz = /bits/ 64 <998400000>; > > opp-microvolt = <1350000>; > > + required-opps = <&rpmpd_opp_super_turbo>; > > }; > > opp-1094400000 { > > opp-hz = /bits/ 64 <1094400000>; > > opp-microvolt = <1350000>; > > + required-opps = <&rpmpd_opp_super_turbo>; > > }; > > opp-1152000000 { > > opp-hz = /bits/ 64 <1152000000>; > > opp-microvolt = <1350000>; > > + required-opps = <&rpmpd_opp_super_turbo>; > > }; > > opp-1209600000 { > > opp-hz = /bits/ 64 <1209600000>; > > opp-microvolt = <1350000>; > > + required-opps = <&rpmpd_opp_super_turbo>; > > }; > > }; > > > > @@ -1710,6 +1723,40 @@ rpmcc: qcom,rpmcc { > > #clock-cells = <1>; > > }; > > > > + rpmpd: power-controller { > > + compatible = "qcom,msm8916-rpmpd"; > > + #power-domain-cells = <1>; > > + operating-points-v2 = <&rpmpd_opp_table>; > > + > > + rpmpd_opp_table: opp-table { > > + compatible = "operating-points-v2"; > > + > > + rpmpd_opp_ret: opp1 { > > + opp-level = <1>; > > + }; > > + > > + rpmpd_opp_svs: opp2 { > > + opp-level = <2>; > > + }; > > + > > + rpmpd_opp_svs_soc: opp3 { > > + opp-level = <3>; > > + }; > > + > > + rpmpd_opp_nom: opp4 { > > + opp-level = <4>; > > + }; > > + > > + rpmpd_opp_turbo: opp5 { > > + opp-level = <5>; > > + }; > > + > > + rpmpd_opp_super_turbo: opp6 { > > + opp-level = <6>; > > + }; > > + }; > > + }; > > + > > smd_rpm_regulators: pm8916-regulators { > > compatible = "qcom,rpm-pm8916-regulators"; > > > > diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c > > index f2ae9cd455c1..b0f6bd0fffc1 100644 > > --- a/drivers/cpufreq/cpufreq-dt-platdev.c > > +++ b/drivers/cpufreq/cpufreq-dt-platdev.c > > @@ -128,6 +128,7 @@ static const struct of_device_id blacklist[] __initconst = { > > { .compatible = "nvidia,tegra210", }, > > > > { .compatible = "qcom,apq8096", }, > > + { .compatible = "qcom,msm8916", }, > > { .compatible = "qcom,msm8996", }, > > { .compatible = "qcom,qcs404", }, > > > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > index f0d2d5035413..c77a30349d08 100644 > > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > @@ -129,6 +129,16 @@ static const struct qcom_cpufreq_match_data match_data_kryo = { > > .get_version = qcom_cpufreq_kryo_name_version, > > }; > > > > +static const char *msm8916_genpd_names[] = { "mx", NULL }; > > + > > +static const struct qcom_cpufreq_match_data match_data_msm8916 = { > > + /* > > + * FIXME: Might need to implement .get_version here to handle > > + * different frequencies depending on speedbin/pvs version. > > + */ > > + .genpd_names = msm8916_genpd_names, > > +}; > > + > > static const char *qcs404_genpd_names[] = { "cpr", NULL }; > > > > static const struct qcom_cpufreq_match_data match_data_qcs404 = { > > @@ -301,6 +311,7 @@ static struct platform_driver qcom_cpufreq_driver = { > > > > static const struct of_device_id qcom_cpufreq_match_list[] __initconst = { > > { .compatible = "qcom,apq8096", .data = &match_data_kryo }, > > + { .compatible = "qcom,msm8916", .data = &match_data_msm8916 }, > > { .compatible = "qcom,msm8996", .data = &match_data_kryo }, > > { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, > > {}, > > diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c > > index 2b1834c5609a..192ba9099964 100644 > > --- a/drivers/soc/qcom/rpmpd.c > > +++ b/drivers/soc/qcom/rpmpd.c > > @@ -115,6 +115,26 @@ struct rpmpd_desc { > > > > static DEFINE_MUTEX(rpmpd_lock); > > > > +/* msm8916 RPM Power Domains */ > > +DEFINE_RPMPD_PAIR(msm8916, vddcx, vddcx_ao, SMPA, CORNER, 1); > > +DEFINE_RPMPD_PAIR(msm8916, vddmx, vddmx_ao, LDOA, CORNER, 3); > > + > > +DEFINE_RPMPD_VFC(msm8916, vddcx_vfc, SMPA, 1); > > + > > +static struct rpmpd *msm8916_rpmpds[] = { > > + [MSM8916_VDDCX] = &msm8916_vddcx, > > + [MSM8916_VDDCX_AO] = &msm8916_vddcx_ao, > > + [MSM8916_VDDCX_VFC] = &msm8916_vddcx_vfc, > > + [MSM8916_VDDMX] = &msm8916_vddmx, > > + [MSM8916_VDDMX_AO] = &msm8916_vddmx_ao, > > +}; > > + > > +static const struct rpmpd_desc msm8916_desc = { > > + .rpmpds = msm8916_rpmpds, > > + .num_pds = ARRAY_SIZE(msm8916_rpmpds), > > + .max_state = MAX_8996_RPMPD_STATE, > > +}; > > + > > /* msm8976 RPM Power Domains */ > > DEFINE_RPMPD_PAIR(msm8976, vddcx, vddcx_ao, SMPA, LEVEL, 2); > > DEFINE_RPMPD_PAIR(msm8976, vddmx, vddmx_ao, SMPA, LEVEL, 6); > > @@ -220,6 +240,7 @@ static const struct rpmpd_desc qcs404_desc = { > > }; > > > > static const struct of_device_id rpmpd_match_table[] = { > > + { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc }, > > { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc }, > > { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, > > { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, > > diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h > > index 3f74096d5a7c..70d304a2deae 100644 > > --- a/include/dt-bindings/power/qcom-rpmpd.h > > +++ b/include/dt-bindings/power/qcom-rpmpd.h > > @@ -51,6 +51,13 @@ > > #define RPMH_REGULATOR_LEVEL_TURBO 384 > > #define RPMH_REGULATOR_LEVEL_TURBO_L1 416 > > > > +/* MSM8916 Power Domain Indexes */ > > +#define MSM8916_VDDCX 0 > > +#define MSM8916_VDDCX_AO 1 > > +#define MSM8916_VDDCX_VFC 2 > > +#define MSM8916_VDDMX 3 > > +#define MSM8916_VDDMX_AO 4 > > + > > /* MSM8976 Power Domain Indexes */ > > #define MSM8976_VDDCX 0 > > #define MSM8976_VDDCX_AO 1 ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-04-26 12:31 ` Stephan Gerhold @ 2020-05-06 21:18 ` Stephan Gerhold 2020-05-07 5:34 ` Bjorn Andersson 2020-05-07 10:46 ` Stephan Gerhold 0 siblings, 2 replies; 32+ messages in thread From: Stephan Gerhold @ 2020-05-06 21:18 UTC (permalink / raw) To: Bjorn Andersson; +Cc: Loic Poulain, agross, linux-arm-msm Hi, On Sun, Apr 26, 2020 at 02:31:48PM +0200, Stephan Gerhold wrote: > On Wed, Apr 22, 2020 at 09:55:06PM -0700, Bjorn Andersson wrote: > > On Fri 03 Apr 11:00 PDT 2020, Stephan Gerhold wrote: > > > > > On Fri, Apr 03, 2020 at 12:09:25PM +0200, Stephan Gerhold wrote: > > > > On Thu, Apr 02, 2020 at 06:31:19PM -0700, Bjorn Andersson wrote: > > > > > On Thu 02 Apr 01:13 PDT 2020, Stephan Gerhold wrote: > > > > > > > > > > > Hi, > > > > > > > > > > > > On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > > > > > > > The highest cpu frequency opps have been dropped because CPR is not > > > > > > > supported. However, we can simply specify operating voltage so that > > > > > > > they match the max corner voltages for each freq. With that, we can > > > > > > > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > > > > > > > fine tune operating voltages and optimize power consumption. > > > > > > > > > > > > Thanks for the patch! I was wondering how to enable the higher CPU > > > > > > frequencies for a while now... > > > > > > > > > > > > I was actually quite excited to see CPR being mainlined for QCS404. > > > > > > If we are trying to add such a workaround (rather than CPR) for MSM8916 > > > > > > now, does that mean it's unlikely to see CPR working for MSM8916 > > > > > > anytime soon? > > > > > > > > > > > > AFAICT, there is a WIP branch from Niklas Cassel here: > > > > > > https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline > > > > > > but it hasn't been updated for a while. (Not sure if it was working > > > > > > already...) > > > > > > > > > > > > Can someone explain what is missing to make CPR work for MSM8916? > > > > > > > > > > > > > > > > CPR needs to control 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 it > > > > > seems we don't have to adjust VDD_MX, so the code for this is missing > > > > > from the driver. > > > > > > > > > > So, afaict, what's missing is that rpmpd.c needs to gain support for > > > > > 8916, then the CPR driver needs to gain a cpr_acc_desc and compatible > > > > > for 8916, it needs to reference the VDDMX power domain and before/after > > > > > we're adjusting the corner of the CPR we need to adjust the MX according > > > > > to the mapping specified in the downstream kernel (i.e. 1->4, 2->5 and > > > > > 3->7). > > > > > > > > > > > > > > > Unfortunately, the requirement that VDDMX (VDD_MEM I presume) must be > > > > > higher than VDD_APC most likely needs to be taken into consideration for > > > > > Loic's proposed static voltage scaling as well. Unless VDD_MEM is left > > > > > in Turbo mode from the boot loader I think we need to take VDDMX to > > > > > corner 7 for speeds 998MHz and above (i.e. where we pull VDD_APC to > > > > > 1.35V). > > > > > > > > > > > > > I see! I wonder how hard it would be to add MSM8916 to rpmpd, > > > > looking at previous commits it's mainly setting up a few defines? > > > > > > > > If I understand it correctly, the OPPs from rpmpd could then be > > > > referenced as "required-opps" in the CPU OPP table so that VDD_MX is > > > > scaled together with the CPU frequency, and doesn't need to stay at > > > > turbo mode (like in v3 from Loic) the whole time. > > > > > > > > > > I have been thinking about this some more and I think I came up with > > > some changes that make sense (but not entirely sure). > > > > > > Based on the available downstream sources I guessed the defines to add > > > for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as > > > "required-opps" to the CPU OPP table so it would vote for the appopriate > > > corners (with the mapping you mentioned above). > > > > > > > I was not aware it was possible to describe the dependency between the > > CPU opp table and MX in this fashion. If that's the case then this looks > > really good and it should be straight forward to add MSM8916 support to > > the CPR driver as well. > > > > Indeed! > > > > I haven't tested it yet, maybe I can get some feedback first if the code > > > seems reasonable or if I'm missing something obvious? :) > > > > > > > Have you tested this yet? > > > > I just did. It does not fully work, yet: > > rpmpd_set_performance() is indeed called as necessary when switching the > CPU frequency. When I set 200 MHz it sets corner 3, with 533 MHz corner 4 > and starting with 998 MHz corner 6. So far so good :) > > However, there is never actually anything sent to the RPM. :( > It bails out in rpmpd_set_performance() before calling rpmpd_aggregate_corner(): > > /* Always send updates for vfc and vfl */ > if (!pd->enabled && pd->key != KEY_FLOOR_CORNER && > pd->key != KEY_FLOOR_LEVEL) > goto out; > > Seems like we just try to set performance states, but never actually > enable (rpmpd_power_on()) the power domain (pd->enabled == false). > > I'm not sure which of the components involved here should handle that. > The OPP core when setting required OPPs, the genpd core etc. > > Any ideas? > > Thanks, > Stephan > For now I have added something to qcom-cpufreq-nvmem.c to power on/enable the power domain (not really sure if it belongs there...): diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c index a1b8238872a2..ed352ead037e 100644 --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c @@ -26,6 +26,7 @@ #include <linux/platform_device.h> #include <linux/pm_domain.h> #include <linux/pm_opp.h> +#include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/soc/qcom/smem.h> @@ -370,10 +371,13 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) } if (drv->data->genpd_names) { + struct device **pd_dev; + const char **name = drv->data->genpd_names; + drv->genpd_opp_tables[cpu] = dev_pm_opp_attach_genpd(cpu_dev, drv->data->genpd_names, - NULL); + &pd_dev); if (IS_ERR(drv->genpd_opp_tables[cpu])) { ret = PTR_ERR(drv->genpd_opp_tables[cpu]); if (ret != -EPROBE_DEFER) @@ -382,6 +386,12 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) ret); goto free_genpd_opp; } + + while (*name) { + pm_runtime_get_sync(*pd_dev); + name++; + pd_dev++; + } } } I really wonder why this doesn't affect CPR (or does it?). So far I was not able to find anything that would power on/enable the "cpr" power domain either. But I don't have a qcs404 to verify. As far as I can tell from the log, the corner votes are correctly sent to the RPM now when the CPU frequency is changed. However... > > > Also: Is there a good way to validate these changes? > > > I suppose I could check the genpd state but that wouldn't tell me if the > > > corner was applied correctly. Maybe I can check the actual voltage > > > through the SPMI interface, hm... > > > > > > > Validating that S2 and VDD_MX changes appropriately in Linux would be a > > pretty good test. > > Unfortunately I was not able to see any change in the voltage of L3 yet. On samsung-a5u, /sys/class/regulator/<l3 spmi regulator>/microvolts permanently reports 1300000 uV, even after a few different corner votes. I'm not sure if: - This is normal (maybe some other remoteproc has a higher vote?) - I tried to disable wcnss, venus and hexagon without difference - I'm just missing something in the code - This is some peculiarity of the RPM firmware on samsung-a5u. (Although that seems quite unlikely to me...) Any ideas? :/ Thanks, Stephan > > > If this seems like a good approach I can split up the changes in > > > reasonable patches and post it separately. For now the full diff below. > > > > > > > Please do > > > > Regards, > > Bjorn > > > > > Stephan > > > > > > arch/arm64/boot/dts/qcom/msm8916.dtsi | 65 +++++++++++++++++++++++++++++----- > > > drivers/cpufreq/cpufreq-dt-platdev.c | 1 + > > > drivers/cpufreq/qcom-cpufreq-nvmem.c | 11 ++++++ > > > drivers/soc/qcom/rpmpd.c | 21 +++++++++++ > > > include/dt-bindings/power/qcom-rpmpd.h | 7 ++++ > > > 5 files changed, 96 insertions(+), 9 deletions(-) > > > > > > diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > index b0a82447976a..5b8fce8609d0 100644 > > > --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > @@ -10,6 +10,7 @@ > > > #include <dt-bindings/soc/qcom,apr.h> > > > #include <dt-bindings/sound/qcom,q6afe.h> > > > #include <dt-bindings/thermal/thermal.h> > > > +#include <dt-bindings/power/qcom-rpmpd.h> > > > > > > / { > > > interrupt-parent = <&intc>; > > > @@ -108,8 +109,8 @@ CPU0: cpu@0 { > > > cpu-supply = <&pm8916_spmi_s2>; > > > operating-points-v2 = <&cpu_opp_table>; > > > #cooling-cells = <2>; > > > - power-domains = <&CPU_PD0>; > > > - power-domain-names = "psci"; > > > + power-domains = <&CPU_PD0>, <&rpmpd MSM8916_VDDMX_AO>; > > > + power-domain-names = "psci", "mx"; > > > }; > > > > > > CPU1: cpu@1 { > > > @@ -122,8 +123,8 @@ CPU1: cpu@1 { > > > cpu-supply = <&pm8916_spmi_s2>; > > > operating-points-v2 = <&cpu_opp_table>; > > > #cooling-cells = <2>; > > > - power-domains = <&CPU_PD1>; > > > - power-domain-names = "psci"; > > > + power-domains = <&CPU_PD1>, <&rpmpd MSM8916_VDDMX_AO>; > > > + power-domain-names = "psci", "mx"; > > > }; > > > > > > CPU2: cpu@2 { > > > @@ -136,8 +137,8 @@ CPU2: cpu@2 { > > > cpu-supply = <&pm8916_spmi_s2>; > > > operating-points-v2 = <&cpu_opp_table>; > > > #cooling-cells = <2>; > > > - power-domains = <&CPU_PD2>; > > > - power-domain-names = "psci"; > > > + power-domains = <&CPU_PD2>, <&rpmpd MSM8916_VDDMX_AO>; > > > + power-domain-names = "psci", "mx"; > > > }; > > > > > > CPU3: cpu@3 { > > > @@ -150,8 +151,8 @@ CPU3: cpu@3 { > > > cpu-supply = <&pm8916_spmi_s2>; > > > operating-points-v2 = <&cpu_opp_table>; > > > #cooling-cells = <2>; > > > - power-domains = <&CPU_PD3>; > > > - power-domain-names = "psci"; > > > + power-domains = <&CPU_PD3>, <&rpmpd MSM8916_VDDMX_AO>; > > > + power-domain-names = "psci", "mx"; > > > }; > > > > > > L2_0: l2-cache { > > > @@ -343,40 +344,52 @@ modem_alert0: trip-point@0 { > > > }; > > > > > > cpu_opp_table: cpu_opp_table { > > > - compatible = "operating-points-v2"; > > > + /* > > > + * FIXME: The naming here is really weird, since MSM8916 does > > > + * not have kyro. Maybe we should add a more generic compatible? > > > + */ > > > + compatible = "operating-points-v2-kryo-cpu"; > > > opp-shared; > > > > > > opp-200000000 { > > > opp-hz = /bits/ 64 <200000000>; > > > opp-microvolt = <1050000>; > > > + required-opps = <&rpmpd_opp_svs_soc>; > > > }; > > > opp-400000000 { > > > opp-hz = /bits/ 64 <400000000>; > > > opp-microvolt = <1050000>; > > > + required-opps = <&rpmpd_opp_svs_soc>; > > > }; > > > opp-533330000 { > > > opp-hz = /bits/ 64 <533330000>; > > > opp-microvolt = <1150000>; > > > + required-opps = <&rpmpd_opp_nom>; > > > }; > > > opp-800000000 { > > > opp-hz = /bits/ 64 <800000000>; > > > opp-microvolt = <1150000>; > > > + required-opps = <&rpmpd_opp_nom>; > > > }; > > > opp-998400000 { > > > opp-hz = /bits/ 64 <998400000>; > > > opp-microvolt = <1350000>; > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > }; > > > opp-1094400000 { > > > opp-hz = /bits/ 64 <1094400000>; > > > opp-microvolt = <1350000>; > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > }; > > > opp-1152000000 { > > > opp-hz = /bits/ 64 <1152000000>; > > > opp-microvolt = <1350000>; > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > }; > > > opp-1209600000 { > > > opp-hz = /bits/ 64 <1209600000>; > > > opp-microvolt = <1350000>; > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > }; > > > }; > > > > > > @@ -1710,6 +1723,40 @@ rpmcc: qcom,rpmcc { > > > #clock-cells = <1>; > > > }; > > > > > > + rpmpd: power-controller { > > > + compatible = "qcom,msm8916-rpmpd"; > > > + #power-domain-cells = <1>; > > > + operating-points-v2 = <&rpmpd_opp_table>; > > > + > > > + rpmpd_opp_table: opp-table { > > > + compatible = "operating-points-v2"; > > > + > > > + rpmpd_opp_ret: opp1 { > > > + opp-level = <1>; > > > + }; > > > + > > > + rpmpd_opp_svs: opp2 { > > > + opp-level = <2>; > > > + }; > > > + > > > + rpmpd_opp_svs_soc: opp3 { > > > + opp-level = <3>; > > > + }; > > > + > > > + rpmpd_opp_nom: opp4 { > > > + opp-level = <4>; > > > + }; > > > + > > > + rpmpd_opp_turbo: opp5 { > > > + opp-level = <5>; > > > + }; > > > + > > > + rpmpd_opp_super_turbo: opp6 { > > > + opp-level = <6>; > > > + }; > > > + }; > > > + }; > > > + > > > smd_rpm_regulators: pm8916-regulators { > > > compatible = "qcom,rpm-pm8916-regulators"; > > > > > > diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c > > > index f2ae9cd455c1..b0f6bd0fffc1 100644 > > > --- a/drivers/cpufreq/cpufreq-dt-platdev.c > > > +++ b/drivers/cpufreq/cpufreq-dt-platdev.c > > > @@ -128,6 +128,7 @@ static const struct of_device_id blacklist[] __initconst = { > > > { .compatible = "nvidia,tegra210", }, > > > > > > { .compatible = "qcom,apq8096", }, > > > + { .compatible = "qcom,msm8916", }, > > > { .compatible = "qcom,msm8996", }, > > > { .compatible = "qcom,qcs404", }, > > > > > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > index f0d2d5035413..c77a30349d08 100644 > > > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > @@ -129,6 +129,16 @@ static const struct qcom_cpufreq_match_data match_data_kryo = { > > > .get_version = qcom_cpufreq_kryo_name_version, > > > }; > > > > > > +static const char *msm8916_genpd_names[] = { "mx", NULL }; > > > + > > > +static const struct qcom_cpufreq_match_data match_data_msm8916 = { > > > + /* > > > + * FIXME: Might need to implement .get_version here to handle > > > + * different frequencies depending on speedbin/pvs version. > > > + */ > > > + .genpd_names = msm8916_genpd_names, > > > +}; > > > + > > > static const char *qcs404_genpd_names[] = { "cpr", NULL }; > > > > > > static const struct qcom_cpufreq_match_data match_data_qcs404 = { > > > @@ -301,6 +311,7 @@ static struct platform_driver qcom_cpufreq_driver = { > > > > > > static const struct of_device_id qcom_cpufreq_match_list[] __initconst = { > > > { .compatible = "qcom,apq8096", .data = &match_data_kryo }, > > > + { .compatible = "qcom,msm8916", .data = &match_data_msm8916 }, > > > { .compatible = "qcom,msm8996", .data = &match_data_kryo }, > > > { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, > > > {}, > > > diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c > > > index 2b1834c5609a..192ba9099964 100644 > > > --- a/drivers/soc/qcom/rpmpd.c > > > +++ b/drivers/soc/qcom/rpmpd.c > > > @@ -115,6 +115,26 @@ struct rpmpd_desc { > > > > > > static DEFINE_MUTEX(rpmpd_lock); > > > > > > +/* msm8916 RPM Power Domains */ > > > +DEFINE_RPMPD_PAIR(msm8916, vddcx, vddcx_ao, SMPA, CORNER, 1); > > > +DEFINE_RPMPD_PAIR(msm8916, vddmx, vddmx_ao, LDOA, CORNER, 3); > > > + > > > +DEFINE_RPMPD_VFC(msm8916, vddcx_vfc, SMPA, 1); > > > + > > > +static struct rpmpd *msm8916_rpmpds[] = { > > > + [MSM8916_VDDCX] = &msm8916_vddcx, > > > + [MSM8916_VDDCX_AO] = &msm8916_vddcx_ao, > > > + [MSM8916_VDDCX_VFC] = &msm8916_vddcx_vfc, > > > + [MSM8916_VDDMX] = &msm8916_vddmx, > > > + [MSM8916_VDDMX_AO] = &msm8916_vddmx_ao, > > > +}; > > > + > > > +static const struct rpmpd_desc msm8916_desc = { > > > + .rpmpds = msm8916_rpmpds, > > > + .num_pds = ARRAY_SIZE(msm8916_rpmpds), > > > + .max_state = MAX_8996_RPMPD_STATE, > > > +}; > > > + > > > /* msm8976 RPM Power Domains */ > > > DEFINE_RPMPD_PAIR(msm8976, vddcx, vddcx_ao, SMPA, LEVEL, 2); > > > DEFINE_RPMPD_PAIR(msm8976, vddmx, vddmx_ao, SMPA, LEVEL, 6); > > > @@ -220,6 +240,7 @@ static const struct rpmpd_desc qcs404_desc = { > > > }; > > > > > > static const struct of_device_id rpmpd_match_table[] = { > > > + { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc }, > > > { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc }, > > > { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, > > > { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, > > > diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h > > > index 3f74096d5a7c..70d304a2deae 100644 > > > --- a/include/dt-bindings/power/qcom-rpmpd.h > > > +++ b/include/dt-bindings/power/qcom-rpmpd.h > > > @@ -51,6 +51,13 @@ > > > #define RPMH_REGULATOR_LEVEL_TURBO 384 > > > #define RPMH_REGULATOR_LEVEL_TURBO_L1 416 > > > > > > +/* MSM8916 Power Domain Indexes */ > > > +#define MSM8916_VDDCX 0 > > > +#define MSM8916_VDDCX_AO 1 > > > +#define MSM8916_VDDCX_VFC 2 > > > +#define MSM8916_VDDMX 3 > > > +#define MSM8916_VDDMX_AO 4 > > > + > > > /* MSM8976 Power Domain Indexes */ > > > #define MSM8976_VDDCX 0 > > > #define MSM8976_VDDCX_AO 1 ^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-06 21:18 ` Stephan Gerhold @ 2020-05-07 5:34 ` Bjorn Andersson 2020-05-08 12:08 ` Ulf Hansson 2020-05-07 10:46 ` Stephan Gerhold 1 sibling, 1 reply; 32+ messages in thread From: Bjorn Andersson @ 2020-05-07 5:34 UTC (permalink / raw) To: Stephan Gerhold, Viresh Kumar, Ulf Hansson Cc: Loic Poulain, agross, linux-arm-msm On Wed 06 May 14:18 PDT 2020, Stephan Gerhold wrote: Viresh, Ulf, Stephan is trying to describe the relationship between the CPU rail and the memory rail on db410c (where the performance state of the memory rail needs to be kept above the performance state of the CPU supply. The latter is modelled as a power-domain and the performance state changes as expected, but no one enables the power-domain. What's the appropriate method for ensuring the power-domain is enabled/disabled as needed? Should it be referenced in the hierarchical power domain for the CPUs perhaps? Regards, Bjorn > Hi, > > On Sun, Apr 26, 2020 at 02:31:48PM +0200, Stephan Gerhold wrote: > > On Wed, Apr 22, 2020 at 09:55:06PM -0700, Bjorn Andersson wrote: > > > On Fri 03 Apr 11:00 PDT 2020, Stephan Gerhold wrote: > > > > > > > On Fri, Apr 03, 2020 at 12:09:25PM +0200, Stephan Gerhold wrote: > > > > > On Thu, Apr 02, 2020 at 06:31:19PM -0700, Bjorn Andersson wrote: > > > > > > On Thu 02 Apr 01:13 PDT 2020, Stephan Gerhold wrote: > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > > > > > > > > The highest cpu frequency opps have been dropped because CPR is not > > > > > > > > supported. However, we can simply specify operating voltage so that > > > > > > > > they match the max corner voltages for each freq. With that, we can > > > > > > > > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > > > > > > > > fine tune operating voltages and optimize power consumption. > > > > > > > > > > > > > > Thanks for the patch! I was wondering how to enable the higher CPU > > > > > > > frequencies for a while now... > > > > > > > > > > > > > > I was actually quite excited to see CPR being mainlined for QCS404. > > > > > > > If we are trying to add such a workaround (rather than CPR) for MSM8916 > > > > > > > now, does that mean it's unlikely to see CPR working for MSM8916 > > > > > > > anytime soon? > > > > > > > > > > > > > > AFAICT, there is a WIP branch from Niklas Cassel here: > > > > > > > https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline > > > > > > > but it hasn't been updated for a while. (Not sure if it was working > > > > > > > already...) > > > > > > > > > > > > > > Can someone explain what is missing to make CPR work for MSM8916? > > > > > > > > > > > > > > > > > > > CPR needs to control 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 it > > > > > > seems we don't have to adjust VDD_MX, so the code for this is missing > > > > > > from the driver. > > > > > > > > > > > > So, afaict, what's missing is that rpmpd.c needs to gain support for > > > > > > 8916, then the CPR driver needs to gain a cpr_acc_desc and compatible > > > > > > for 8916, it needs to reference the VDDMX power domain and before/after > > > > > > we're adjusting the corner of the CPR we need to adjust the MX according > > > > > > to the mapping specified in the downstream kernel (i.e. 1->4, 2->5 and > > > > > > 3->7). > > > > > > > > > > > > > > > > > > Unfortunately, the requirement that VDDMX (VDD_MEM I presume) must be > > > > > > higher than VDD_APC most likely needs to be taken into consideration for > > > > > > Loic's proposed static voltage scaling as well. Unless VDD_MEM is left > > > > > > in Turbo mode from the boot loader I think we need to take VDDMX to > > > > > > corner 7 for speeds 998MHz and above (i.e. where we pull VDD_APC to > > > > > > 1.35V). > > > > > > > > > > > > > > > > I see! I wonder how hard it would be to add MSM8916 to rpmpd, > > > > > looking at previous commits it's mainly setting up a few defines? > > > > > > > > > > If I understand it correctly, the OPPs from rpmpd could then be > > > > > referenced as "required-opps" in the CPU OPP table so that VDD_MX is > > > > > scaled together with the CPU frequency, and doesn't need to stay at > > > > > turbo mode (like in v3 from Loic) the whole time. > > > > > > > > > > > > > I have been thinking about this some more and I think I came up with > > > > some changes that make sense (but not entirely sure). > > > > > > > > Based on the available downstream sources I guessed the defines to add > > > > for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as > > > > "required-opps" to the CPU OPP table so it would vote for the appopriate > > > > corners (with the mapping you mentioned above). > > > > > > > > > > I was not aware it was possible to describe the dependency between the > > > CPU opp table and MX in this fashion. If that's the case then this looks > > > really good and it should be straight forward to add MSM8916 support to > > > the CPR driver as well. > > > > > > > Indeed! > > > > > > I haven't tested it yet, maybe I can get some feedback first if the code > > > > seems reasonable or if I'm missing something obvious? :) > > > > > > > > > > Have you tested this yet? > > > > > > > I just did. It does not fully work, yet: > > > > rpmpd_set_performance() is indeed called as necessary when switching the > > CPU frequency. When I set 200 MHz it sets corner 3, with 533 MHz corner 4 > > and starting with 998 MHz corner 6. So far so good :) > > > > However, there is never actually anything sent to the RPM. :( > > It bails out in rpmpd_set_performance() before calling rpmpd_aggregate_corner(): > > > > /* Always send updates for vfc and vfl */ > > if (!pd->enabled && pd->key != KEY_FLOOR_CORNER && > > pd->key != KEY_FLOOR_LEVEL) > > goto out; > > > > Seems like we just try to set performance states, but never actually > > enable (rpmpd_power_on()) the power domain (pd->enabled == false). > > > > I'm not sure which of the components involved here should handle that. > > The OPP core when setting required OPPs, the genpd core etc. > > > > Any ideas? > > > > Thanks, > > Stephan > > > > For now I have added something to qcom-cpufreq-nvmem.c to power on/enable > the power domain (not really sure if it belongs there...): > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > index a1b8238872a2..ed352ead037e 100644 > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > @@ -26,6 +26,7 @@ > #include <linux/platform_device.h> > #include <linux/pm_domain.h> > #include <linux/pm_opp.h> > +#include <linux/pm_runtime.h> > #include <linux/slab.h> > #include <linux/soc/qcom/smem.h> > > @@ -370,10 +371,13 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) > } > > if (drv->data->genpd_names) { > + struct device **pd_dev; > + const char **name = drv->data->genpd_names; > + > drv->genpd_opp_tables[cpu] = > dev_pm_opp_attach_genpd(cpu_dev, > drv->data->genpd_names, > - NULL); > + &pd_dev); > if (IS_ERR(drv->genpd_opp_tables[cpu])) { > ret = PTR_ERR(drv->genpd_opp_tables[cpu]); > if (ret != -EPROBE_DEFER) > @@ -382,6 +386,12 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) > ret); > goto free_genpd_opp; > } > + > + while (*name) { > + pm_runtime_get_sync(*pd_dev); > + name++; > + pd_dev++; > + } > } > } > > I really wonder why this doesn't affect CPR (or does it?). > So far I was not able to find anything that would power on/enable > the "cpr" power domain either. But I don't have a qcs404 to verify. > > As far as I can tell from the log, the corner votes are correctly sent > to the RPM now when the CPU frequency is changed. > > However... > > > > > Also: Is there a good way to validate these changes? > > > > I suppose I could check the genpd state but that wouldn't tell me if the > > > > corner was applied correctly. Maybe I can check the actual voltage > > > > through the SPMI interface, hm... > > > > > > > > > > Validating that S2 and VDD_MX changes appropriately in Linux would be a > > > pretty good test. > > > > > Unfortunately I was not able to see any change in the voltage of L3 yet. > On samsung-a5u, /sys/class/regulator/<l3 spmi regulator>/microvolts > permanently reports 1300000 uV, even after a few different corner votes. > > I'm not sure if: > > - This is normal (maybe some other remoteproc has a higher vote?) > - I tried to disable wcnss, venus and hexagon without difference > > - I'm just missing something in the code > > - This is some peculiarity of the RPM firmware on samsung-a5u. > (Although that seems quite unlikely to me...) > > Any ideas? :/ > > Thanks, > Stephan > > > > > If this seems like a good approach I can split up the changes in > > > > reasonable patches and post it separately. For now the full diff below. > > > > > > > > > > Please do > > > > > > Regards, > > > Bjorn > > > > > > > Stephan > > > > > > > > arch/arm64/boot/dts/qcom/msm8916.dtsi | 65 +++++++++++++++++++++++++++++----- > > > > drivers/cpufreq/cpufreq-dt-platdev.c | 1 + > > > > drivers/cpufreq/qcom-cpufreq-nvmem.c | 11 ++++++ > > > > drivers/soc/qcom/rpmpd.c | 21 +++++++++++ > > > > include/dt-bindings/power/qcom-rpmpd.h | 7 ++++ > > > > 5 files changed, 96 insertions(+), 9 deletions(-) > > > > > > > > diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > > index b0a82447976a..5b8fce8609d0 100644 > > > > --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > > +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > > @@ -10,6 +10,7 @@ > > > > #include <dt-bindings/soc/qcom,apr.h> > > > > #include <dt-bindings/sound/qcom,q6afe.h> > > > > #include <dt-bindings/thermal/thermal.h> > > > > +#include <dt-bindings/power/qcom-rpmpd.h> > > > > > > > > / { > > > > interrupt-parent = <&intc>; > > > > @@ -108,8 +109,8 @@ CPU0: cpu@0 { > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > operating-points-v2 = <&cpu_opp_table>; > > > > #cooling-cells = <2>; > > > > - power-domains = <&CPU_PD0>; > > > > - power-domain-names = "psci"; > > > > + power-domains = <&CPU_PD0>, <&rpmpd MSM8916_VDDMX_AO>; > > > > + power-domain-names = "psci", "mx"; > > > > }; > > > > > > > > CPU1: cpu@1 { > > > > @@ -122,8 +123,8 @@ CPU1: cpu@1 { > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > operating-points-v2 = <&cpu_opp_table>; > > > > #cooling-cells = <2>; > > > > - power-domains = <&CPU_PD1>; > > > > - power-domain-names = "psci"; > > > > + power-domains = <&CPU_PD1>, <&rpmpd MSM8916_VDDMX_AO>; > > > > + power-domain-names = "psci", "mx"; > > > > }; > > > > > > > > CPU2: cpu@2 { > > > > @@ -136,8 +137,8 @@ CPU2: cpu@2 { > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > operating-points-v2 = <&cpu_opp_table>; > > > > #cooling-cells = <2>; > > > > - power-domains = <&CPU_PD2>; > > > > - power-domain-names = "psci"; > > > > + power-domains = <&CPU_PD2>, <&rpmpd MSM8916_VDDMX_AO>; > > > > + power-domain-names = "psci", "mx"; > > > > }; > > > > > > > > CPU3: cpu@3 { > > > > @@ -150,8 +151,8 @@ CPU3: cpu@3 { > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > operating-points-v2 = <&cpu_opp_table>; > > > > #cooling-cells = <2>; > > > > - power-domains = <&CPU_PD3>; > > > > - power-domain-names = "psci"; > > > > + power-domains = <&CPU_PD3>, <&rpmpd MSM8916_VDDMX_AO>; > > > > + power-domain-names = "psci", "mx"; > > > > }; > > > > > > > > L2_0: l2-cache { > > > > @@ -343,40 +344,52 @@ modem_alert0: trip-point@0 { > > > > }; > > > > > > > > cpu_opp_table: cpu_opp_table { > > > > - compatible = "operating-points-v2"; > > > > + /* > > > > + * FIXME: The naming here is really weird, since MSM8916 does > > > > + * not have kyro. Maybe we should add a more generic compatible? > > > > + */ > > > > + compatible = "operating-points-v2-kryo-cpu"; > > > > opp-shared; > > > > > > > > opp-200000000 { > > > > opp-hz = /bits/ 64 <200000000>; > > > > opp-microvolt = <1050000>; > > > > + required-opps = <&rpmpd_opp_svs_soc>; > > > > }; > > > > opp-400000000 { > > > > opp-hz = /bits/ 64 <400000000>; > > > > opp-microvolt = <1050000>; > > > > + required-opps = <&rpmpd_opp_svs_soc>; > > > > }; > > > > opp-533330000 { > > > > opp-hz = /bits/ 64 <533330000>; > > > > opp-microvolt = <1150000>; > > > > + required-opps = <&rpmpd_opp_nom>; > > > > }; > > > > opp-800000000 { > > > > opp-hz = /bits/ 64 <800000000>; > > > > opp-microvolt = <1150000>; > > > > + required-opps = <&rpmpd_opp_nom>; > > > > }; > > > > opp-998400000 { > > > > opp-hz = /bits/ 64 <998400000>; > > > > opp-microvolt = <1350000>; > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > }; > > > > opp-1094400000 { > > > > opp-hz = /bits/ 64 <1094400000>; > > > > opp-microvolt = <1350000>; > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > }; > > > > opp-1152000000 { > > > > opp-hz = /bits/ 64 <1152000000>; > > > > opp-microvolt = <1350000>; > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > }; > > > > opp-1209600000 { > > > > opp-hz = /bits/ 64 <1209600000>; > > > > opp-microvolt = <1350000>; > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > }; > > > > }; > > > > > > > > @@ -1710,6 +1723,40 @@ rpmcc: qcom,rpmcc { > > > > #clock-cells = <1>; > > > > }; > > > > > > > > + rpmpd: power-controller { > > > > + compatible = "qcom,msm8916-rpmpd"; > > > > + #power-domain-cells = <1>; > > > > + operating-points-v2 = <&rpmpd_opp_table>; > > > > + > > > > + rpmpd_opp_table: opp-table { > > > > + compatible = "operating-points-v2"; > > > > + > > > > + rpmpd_opp_ret: opp1 { > > > > + opp-level = <1>; > > > > + }; > > > > + > > > > + rpmpd_opp_svs: opp2 { > > > > + opp-level = <2>; > > > > + }; > > > > + > > > > + rpmpd_opp_svs_soc: opp3 { > > > > + opp-level = <3>; > > > > + }; > > > > + > > > > + rpmpd_opp_nom: opp4 { > > > > + opp-level = <4>; > > > > + }; > > > > + > > > > + rpmpd_opp_turbo: opp5 { > > > > + opp-level = <5>; > > > > + }; > > > > + > > > > + rpmpd_opp_super_turbo: opp6 { > > > > + opp-level = <6>; > > > > + }; > > > > + }; > > > > + }; > > > > + > > > > smd_rpm_regulators: pm8916-regulators { > > > > compatible = "qcom,rpm-pm8916-regulators"; > > > > > > > > diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c > > > > index f2ae9cd455c1..b0f6bd0fffc1 100644 > > > > --- a/drivers/cpufreq/cpufreq-dt-platdev.c > > > > +++ b/drivers/cpufreq/cpufreq-dt-platdev.c > > > > @@ -128,6 +128,7 @@ static const struct of_device_id blacklist[] __initconst = { > > > > { .compatible = "nvidia,tegra210", }, > > > > > > > > { .compatible = "qcom,apq8096", }, > > > > + { .compatible = "qcom,msm8916", }, > > > > { .compatible = "qcom,msm8996", }, > > > > { .compatible = "qcom,qcs404", }, > > > > > > > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > > index f0d2d5035413..c77a30349d08 100644 > > > > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > > @@ -129,6 +129,16 @@ static const struct qcom_cpufreq_match_data match_data_kryo = { > > > > .get_version = qcom_cpufreq_kryo_name_version, > > > > }; > > > > > > > > +static const char *msm8916_genpd_names[] = { "mx", NULL }; > > > > + > > > > +static const struct qcom_cpufreq_match_data match_data_msm8916 = { > > > > + /* > > > > + * FIXME: Might need to implement .get_version here to handle > > > > + * different frequencies depending on speedbin/pvs version. > > > > + */ > > > > + .genpd_names = msm8916_genpd_names, > > > > +}; > > > > + > > > > static const char *qcs404_genpd_names[] = { "cpr", NULL }; > > > > > > > > static const struct qcom_cpufreq_match_data match_data_qcs404 = { > > > > @@ -301,6 +311,7 @@ static struct platform_driver qcom_cpufreq_driver = { > > > > > > > > static const struct of_device_id qcom_cpufreq_match_list[] __initconst = { > > > > { .compatible = "qcom,apq8096", .data = &match_data_kryo }, > > > > + { .compatible = "qcom,msm8916", .data = &match_data_msm8916 }, > > > > { .compatible = "qcom,msm8996", .data = &match_data_kryo }, > > > > { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, > > > > {}, > > > > diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c > > > > index 2b1834c5609a..192ba9099964 100644 > > > > --- a/drivers/soc/qcom/rpmpd.c > > > > +++ b/drivers/soc/qcom/rpmpd.c > > > > @@ -115,6 +115,26 @@ struct rpmpd_desc { > > > > > > > > static DEFINE_MUTEX(rpmpd_lock); > > > > > > > > +/* msm8916 RPM Power Domains */ > > > > +DEFINE_RPMPD_PAIR(msm8916, vddcx, vddcx_ao, SMPA, CORNER, 1); > > > > +DEFINE_RPMPD_PAIR(msm8916, vddmx, vddmx_ao, LDOA, CORNER, 3); > > > > + > > > > +DEFINE_RPMPD_VFC(msm8916, vddcx_vfc, SMPA, 1); > > > > + > > > > +static struct rpmpd *msm8916_rpmpds[] = { > > > > + [MSM8916_VDDCX] = &msm8916_vddcx, > > > > + [MSM8916_VDDCX_AO] = &msm8916_vddcx_ao, > > > > + [MSM8916_VDDCX_VFC] = &msm8916_vddcx_vfc, > > > > + [MSM8916_VDDMX] = &msm8916_vddmx, > > > > + [MSM8916_VDDMX_AO] = &msm8916_vddmx_ao, > > > > +}; > > > > + > > > > +static const struct rpmpd_desc msm8916_desc = { > > > > + .rpmpds = msm8916_rpmpds, > > > > + .num_pds = ARRAY_SIZE(msm8916_rpmpds), > > > > + .max_state = MAX_8996_RPMPD_STATE, > > > > +}; > > > > + > > > > /* msm8976 RPM Power Domains */ > > > > DEFINE_RPMPD_PAIR(msm8976, vddcx, vddcx_ao, SMPA, LEVEL, 2); > > > > DEFINE_RPMPD_PAIR(msm8976, vddmx, vddmx_ao, SMPA, LEVEL, 6); > > > > @@ -220,6 +240,7 @@ static const struct rpmpd_desc qcs404_desc = { > > > > }; > > > > > > > > static const struct of_device_id rpmpd_match_table[] = { > > > > + { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc }, > > > > { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc }, > > > > { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, > > > > { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, > > > > diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h > > > > index 3f74096d5a7c..70d304a2deae 100644 > > > > --- a/include/dt-bindings/power/qcom-rpmpd.h > > > > +++ b/include/dt-bindings/power/qcom-rpmpd.h > > > > @@ -51,6 +51,13 @@ > > > > #define RPMH_REGULATOR_LEVEL_TURBO 384 > > > > #define RPMH_REGULATOR_LEVEL_TURBO_L1 416 > > > > > > > > +/* MSM8916 Power Domain Indexes */ > > > > +#define MSM8916_VDDCX 0 > > > > +#define MSM8916_VDDCX_AO 1 > > > > +#define MSM8916_VDDCX_VFC 2 > > > > +#define MSM8916_VDDMX 3 > > > > +#define MSM8916_VDDMX_AO 4 > > > > + > > > > /* MSM8976 Power Domain Indexes */ > > > > #define MSM8976_VDDCX 0 > > > > #define MSM8976_VDDCX_AO 1 ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-07 5:34 ` Bjorn Andersson @ 2020-05-08 12:08 ` Ulf Hansson 2020-05-08 13:42 ` Stephan Gerhold 2020-05-11 5:29 ` Viresh Kumar 0 siblings, 2 replies; 32+ messages in thread From: Ulf Hansson @ 2020-05-08 12:08 UTC (permalink / raw) To: Bjorn Andersson, Stephan Gerhold Cc: Viresh Kumar, Loic Poulain, Andy Gross, linux-arm-msm, Lina Iyer + Lina On Thu, 7 May 2020 at 07:33, Bjorn Andersson <bjorn.andersson@linaro.org> wrote: > > On Wed 06 May 14:18 PDT 2020, Stephan Gerhold wrote: > > Viresh, Ulf, > > Stephan is trying to describe the relationship between the CPU rail and > the memory rail on db410c (where the performance state of the memory > rail needs to be kept above the performance state of the CPU supply. > > The latter is modelled as a power-domain and the performance state > changes as expected, but no one enables the power-domain. Just to make one thing clear, from a genpd framework point of view, power on/off of a genpd is orthogonal to setting/aggregating performance states for it. It's instead up to the genpd provider to deal with this (as I understand, that seems to be the issue from the below discussions). > > What's the appropriate method for ensuring the power-domain is > enabled/disabled as needed? Should it be referenced in the hierarchical > power domain for the CPUs perhaps? If I understand the dependency correctly, perhaps you are right that there needs to be a subdomain assigned. Although, I don't know if this ever has been tested to work for a real use case, when it comes to performance state propagations upwards in the hierarchy. Viresh? If you also need to manage genpd power on/off, that should be managed by using runtime PM reference counting on those devices that are attached to the genpd in question. Kind regards Uffe > > Regards, > Bjorn > > > Hi, > > > > On Sun, Apr 26, 2020 at 02:31:48PM +0200, Stephan Gerhold wrote: > > > On Wed, Apr 22, 2020 at 09:55:06PM -0700, Bjorn Andersson wrote: > > > > On Fri 03 Apr 11:00 PDT 2020, Stephan Gerhold wrote: > > > > > > > > > On Fri, Apr 03, 2020 at 12:09:25PM +0200, Stephan Gerhold wrote: > > > > > > On Thu, Apr 02, 2020 at 06:31:19PM -0700, Bjorn Andersson wrote: > > > > > > > On Thu 02 Apr 01:13 PDT 2020, Stephan Gerhold wrote: > > > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > > > On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > > > > > > > > > The highest cpu frequency opps have been dropped because CPR is not > > > > > > > > > supported. However, we can simply specify operating voltage so that > > > > > > > > > they match the max corner voltages for each freq. With that, we can > > > > > > > > > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > > > > > > > > > fine tune operating voltages and optimize power consumption. > > > > > > > > > > > > > > > > Thanks for the patch! I was wondering how to enable the higher CPU > > > > > > > > frequencies for a while now... > > > > > > > > > > > > > > > > I was actually quite excited to see CPR being mainlined for QCS404. > > > > > > > > If we are trying to add such a workaround (rather than CPR) for MSM8916 > > > > > > > > now, does that mean it's unlikely to see CPR working for MSM8916 > > > > > > > > anytime soon? > > > > > > > > > > > > > > > > AFAICT, there is a WIP branch from Niklas Cassel here: > > > > > > > > https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline > > > > > > > > but it hasn't been updated for a while. (Not sure if it was working > > > > > > > > already...) > > > > > > > > > > > > > > > > Can someone explain what is missing to make CPR work for MSM8916? > > > > > > > > > > > > > > > > > > > > > > CPR needs to control 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 it > > > > > > > seems we don't have to adjust VDD_MX, so the code for this is missing > > > > > > > from the driver. > > > > > > > > > > > > > > So, afaict, what's missing is that rpmpd.c needs to gain support for > > > > > > > 8916, then the CPR driver needs to gain a cpr_acc_desc and compatible > > > > > > > for 8916, it needs to reference the VDDMX power domain and before/after > > > > > > > we're adjusting the corner of the CPR we need to adjust the MX according > > > > > > > to the mapping specified in the downstream kernel (i.e. 1->4, 2->5 and > > > > > > > 3->7). > > > > > > > > > > > > > > > > > > > > > Unfortunately, the requirement that VDDMX (VDD_MEM I presume) must be > > > > > > > higher than VDD_APC most likely needs to be taken into consideration for > > > > > > > Loic's proposed static voltage scaling as well. Unless VDD_MEM is left > > > > > > > in Turbo mode from the boot loader I think we need to take VDDMX to > > > > > > > corner 7 for speeds 998MHz and above (i.e. where we pull VDD_APC to > > > > > > > 1.35V). > > > > > > > > > > > > > > > > > > > I see! I wonder how hard it would be to add MSM8916 to rpmpd, > > > > > > looking at previous commits it's mainly setting up a few defines? > > > > > > > > > > > > If I understand it correctly, the OPPs from rpmpd could then be > > > > > > referenced as "required-opps" in the CPU OPP table so that VDD_MX is > > > > > > scaled together with the CPU frequency, and doesn't need to stay at > > > > > > turbo mode (like in v3 from Loic) the whole time. > > > > > > > > > > > > > > > > I have been thinking about this some more and I think I came up with > > > > > some changes that make sense (but not entirely sure). > > > > > > > > > > Based on the available downstream sources I guessed the defines to add > > > > > for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as > > > > > "required-opps" to the CPU OPP table so it would vote for the appopriate > > > > > corners (with the mapping you mentioned above). > > > > > > > > > > > > > I was not aware it was possible to describe the dependency between the > > > > CPU opp table and MX in this fashion. If that's the case then this looks > > > > really good and it should be straight forward to add MSM8916 support to > > > > the CPR driver as well. > > > > > > > > > > Indeed! > > > > > > > > I haven't tested it yet, maybe I can get some feedback first if the code > > > > > seems reasonable or if I'm missing something obvious? :) > > > > > > > > > > > > > Have you tested this yet? > > > > > > > > > > I just did. It does not fully work, yet: > > > > > > rpmpd_set_performance() is indeed called as necessary when switching the > > > CPU frequency. When I set 200 MHz it sets corner 3, with 533 MHz corner 4 > > > and starting with 998 MHz corner 6. So far so good :) > > > > > > However, there is never actually anything sent to the RPM. :( > > > It bails out in rpmpd_set_performance() before calling rpmpd_aggregate_corner(): > > > > > > /* Always send updates for vfc and vfl */ > > > if (!pd->enabled && pd->key != KEY_FLOOR_CORNER && > > > pd->key != KEY_FLOOR_LEVEL) > > > goto out; > > > > > > Seems like we just try to set performance states, but never actually > > > enable (rpmpd_power_on()) the power domain (pd->enabled == false). > > > > > > I'm not sure which of the components involved here should handle that. > > > The OPP core when setting required OPPs, the genpd core etc. > > > > > > Any ideas? > > > > > > Thanks, > > > Stephan > > > > > > > For now I have added something to qcom-cpufreq-nvmem.c to power on/enable > > the power domain (not really sure if it belongs there...): > > > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > index a1b8238872a2..ed352ead037e 100644 > > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > @@ -26,6 +26,7 @@ > > #include <linux/platform_device.h> > > #include <linux/pm_domain.h> > > #include <linux/pm_opp.h> > > +#include <linux/pm_runtime.h> > > #include <linux/slab.h> > > #include <linux/soc/qcom/smem.h> > > > > @@ -370,10 +371,13 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) > > } > > > > if (drv->data->genpd_names) { > > + struct device **pd_dev; > > + const char **name = drv->data->genpd_names; > > + > > drv->genpd_opp_tables[cpu] = > > dev_pm_opp_attach_genpd(cpu_dev, > > drv->data->genpd_names, > > - NULL); > > + &pd_dev); > > if (IS_ERR(drv->genpd_opp_tables[cpu])) { > > ret = PTR_ERR(drv->genpd_opp_tables[cpu]); > > if (ret != -EPROBE_DEFER) > > @@ -382,6 +386,12 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) > > ret); > > goto free_genpd_opp; > > } > > + > > + while (*name) { > > + pm_runtime_get_sync(*pd_dev); > > + name++; > > + pd_dev++; > > + } > > } > > } > > > > I really wonder why this doesn't affect CPR (or does it?). > > So far I was not able to find anything that would power on/enable > > the "cpr" power domain either. But I don't have a qcs404 to verify. > > > > As far as I can tell from the log, the corner votes are correctly sent > > to the RPM now when the CPU frequency is changed. > > > > However... > > > > > > > Also: Is there a good way to validate these changes? > > > > > I suppose I could check the genpd state but that wouldn't tell me if the > > > > > corner was applied correctly. Maybe I can check the actual voltage > > > > > through the SPMI interface, hm... > > > > > > > > > > > > > Validating that S2 and VDD_MX changes appropriately in Linux would be a > > > > pretty good test. > > > > > > > > Unfortunately I was not able to see any change in the voltage of L3 yet. > > On samsung-a5u, /sys/class/regulator/<l3 spmi regulator>/microvolts > > permanently reports 1300000 uV, even after a few different corner votes. > > > > I'm not sure if: > > > > - This is normal (maybe some other remoteproc has a higher vote?) > > - I tried to disable wcnss, venus and hexagon without difference > > > > - I'm just missing something in the code > > > > - This is some peculiarity of the RPM firmware on samsung-a5u. > > (Although that seems quite unlikely to me...) > > > > Any ideas? :/ > > > > Thanks, > > Stephan > > > > > > > If this seems like a good approach I can split up the changes in > > > > > reasonable patches and post it separately. For now the full diff below. > > > > > > > > > > > > > Please do > > > > > > > > Regards, > > > > Bjorn > > > > > > > > > Stephan > > > > > > > > > > arch/arm64/boot/dts/qcom/msm8916.dtsi | 65 +++++++++++++++++++++++++++++----- > > > > > drivers/cpufreq/cpufreq-dt-platdev.c | 1 + > > > > > drivers/cpufreq/qcom-cpufreq-nvmem.c | 11 ++++++ > > > > > drivers/soc/qcom/rpmpd.c | 21 +++++++++++ > > > > > include/dt-bindings/power/qcom-rpmpd.h | 7 ++++ > > > > > 5 files changed, 96 insertions(+), 9 deletions(-) > > > > > > > > > > diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > > > index b0a82447976a..5b8fce8609d0 100644 > > > > > --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > > > +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > > > @@ -10,6 +10,7 @@ > > > > > #include <dt-bindings/soc/qcom,apr.h> > > > > > #include <dt-bindings/sound/qcom,q6afe.h> > > > > > #include <dt-bindings/thermal/thermal.h> > > > > > +#include <dt-bindings/power/qcom-rpmpd.h> > > > > > > > > > > / { > > > > > interrupt-parent = <&intc>; > > > > > @@ -108,8 +109,8 @@ CPU0: cpu@0 { > > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > > operating-points-v2 = <&cpu_opp_table>; > > > > > #cooling-cells = <2>; > > > > > - power-domains = <&CPU_PD0>; > > > > > - power-domain-names = "psci"; > > > > > + power-domains = <&CPU_PD0>, <&rpmpd MSM8916_VDDMX_AO>; > > > > > + power-domain-names = "psci", "mx"; > > > > > }; > > > > > > > > > > CPU1: cpu@1 { > > > > > @@ -122,8 +123,8 @@ CPU1: cpu@1 { > > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > > operating-points-v2 = <&cpu_opp_table>; > > > > > #cooling-cells = <2>; > > > > > - power-domains = <&CPU_PD1>; > > > > > - power-domain-names = "psci"; > > > > > + power-domains = <&CPU_PD1>, <&rpmpd MSM8916_VDDMX_AO>; > > > > > + power-domain-names = "psci", "mx"; > > > > > }; > > > > > > > > > > CPU2: cpu@2 { > > > > > @@ -136,8 +137,8 @@ CPU2: cpu@2 { > > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > > operating-points-v2 = <&cpu_opp_table>; > > > > > #cooling-cells = <2>; > > > > > - power-domains = <&CPU_PD2>; > > > > > - power-domain-names = "psci"; > > > > > + power-domains = <&CPU_PD2>, <&rpmpd MSM8916_VDDMX_AO>; > > > > > + power-domain-names = "psci", "mx"; > > > > > }; > > > > > > > > > > CPU3: cpu@3 { > > > > > @@ -150,8 +151,8 @@ CPU3: cpu@3 { > > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > > operating-points-v2 = <&cpu_opp_table>; > > > > > #cooling-cells = <2>; > > > > > - power-domains = <&CPU_PD3>; > > > > > - power-domain-names = "psci"; > > > > > + power-domains = <&CPU_PD3>, <&rpmpd MSM8916_VDDMX_AO>; > > > > > + power-domain-names = "psci", "mx"; > > > > > }; > > > > > > > > > > L2_0: l2-cache { > > > > > @@ -343,40 +344,52 @@ modem_alert0: trip-point@0 { > > > > > }; > > > > > > > > > > cpu_opp_table: cpu_opp_table { > > > > > - compatible = "operating-points-v2"; > > > > > + /* > > > > > + * FIXME: The naming here is really weird, since MSM8916 does > > > > > + * not have kyro. Maybe we should add a more generic compatible? > > > > > + */ > > > > > + compatible = "operating-points-v2-kryo-cpu"; > > > > > opp-shared; > > > > > > > > > > opp-200000000 { > > > > > opp-hz = /bits/ 64 <200000000>; > > > > > opp-microvolt = <1050000>; > > > > > + required-opps = <&rpmpd_opp_svs_soc>; > > > > > }; > > > > > opp-400000000 { > > > > > opp-hz = /bits/ 64 <400000000>; > > > > > opp-microvolt = <1050000>; > > > > > + required-opps = <&rpmpd_opp_svs_soc>; > > > > > }; > > > > > opp-533330000 { > > > > > opp-hz = /bits/ 64 <533330000>; > > > > > opp-microvolt = <1150000>; > > > > > + required-opps = <&rpmpd_opp_nom>; > > > > > }; > > > > > opp-800000000 { > > > > > opp-hz = /bits/ 64 <800000000>; > > > > > opp-microvolt = <1150000>; > > > > > + required-opps = <&rpmpd_opp_nom>; > > > > > }; > > > > > opp-998400000 { > > > > > opp-hz = /bits/ 64 <998400000>; > > > > > opp-microvolt = <1350000>; > > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > > }; > > > > > opp-1094400000 { > > > > > opp-hz = /bits/ 64 <1094400000>; > > > > > opp-microvolt = <1350000>; > > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > > }; > > > > > opp-1152000000 { > > > > > opp-hz = /bits/ 64 <1152000000>; > > > > > opp-microvolt = <1350000>; > > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > > }; > > > > > opp-1209600000 { > > > > > opp-hz = /bits/ 64 <1209600000>; > > > > > opp-microvolt = <1350000>; > > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > > }; > > > > > }; > > > > > > > > > > @@ -1710,6 +1723,40 @@ rpmcc: qcom,rpmcc { > > > > > #clock-cells = <1>; > > > > > }; > > > > > > > > > > + rpmpd: power-controller { > > > > > + compatible = "qcom,msm8916-rpmpd"; > > > > > + #power-domain-cells = <1>; > > > > > + operating-points-v2 = <&rpmpd_opp_table>; > > > > > + > > > > > + rpmpd_opp_table: opp-table { > > > > > + compatible = "operating-points-v2"; > > > > > + > > > > > + rpmpd_opp_ret: opp1 { > > > > > + opp-level = <1>; > > > > > + }; > > > > > + > > > > > + rpmpd_opp_svs: opp2 { > > > > > + opp-level = <2>; > > > > > + }; > > > > > + > > > > > + rpmpd_opp_svs_soc: opp3 { > > > > > + opp-level = <3>; > > > > > + }; > > > > > + > > > > > + rpmpd_opp_nom: opp4 { > > > > > + opp-level = <4>; > > > > > + }; > > > > > + > > > > > + rpmpd_opp_turbo: opp5 { > > > > > + opp-level = <5>; > > > > > + }; > > > > > + > > > > > + rpmpd_opp_super_turbo: opp6 { > > > > > + opp-level = <6>; > > > > > + }; > > > > > + }; > > > > > + }; > > > > > + > > > > > smd_rpm_regulators: pm8916-regulators { > > > > > compatible = "qcom,rpm-pm8916-regulators"; > > > > > > > > > > diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c > > > > > index f2ae9cd455c1..b0f6bd0fffc1 100644 > > > > > --- a/drivers/cpufreq/cpufreq-dt-platdev.c > > > > > +++ b/drivers/cpufreq/cpufreq-dt-platdev.c > > > > > @@ -128,6 +128,7 @@ static const struct of_device_id blacklist[] __initconst = { > > > > > { .compatible = "nvidia,tegra210", }, > > > > > > > > > > { .compatible = "qcom,apq8096", }, > > > > > + { .compatible = "qcom,msm8916", }, > > > > > { .compatible = "qcom,msm8996", }, > > > > > { .compatible = "qcom,qcs404", }, > > > > > > > > > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > > > index f0d2d5035413..c77a30349d08 100644 > > > > > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > > > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > > > @@ -129,6 +129,16 @@ static const struct qcom_cpufreq_match_data match_data_kryo = { > > > > > .get_version = qcom_cpufreq_kryo_name_version, > > > > > }; > > > > > > > > > > +static const char *msm8916_genpd_names[] = { "mx", NULL }; > > > > > + > > > > > +static const struct qcom_cpufreq_match_data match_data_msm8916 = { > > > > > + /* > > > > > + * FIXME: Might need to implement .get_version here to handle > > > > > + * different frequencies depending on speedbin/pvs version. > > > > > + */ > > > > > + .genpd_names = msm8916_genpd_names, > > > > > +}; > > > > > + > > > > > static const char *qcs404_genpd_names[] = { "cpr", NULL }; > > > > > > > > > > static const struct qcom_cpufreq_match_data match_data_qcs404 = { > > > > > @@ -301,6 +311,7 @@ static struct platform_driver qcom_cpufreq_driver = { > > > > > > > > > > static const struct of_device_id qcom_cpufreq_match_list[] __initconst = { > > > > > { .compatible = "qcom,apq8096", .data = &match_data_kryo }, > > > > > + { .compatible = "qcom,msm8916", .data = &match_data_msm8916 }, > > > > > { .compatible = "qcom,msm8996", .data = &match_data_kryo }, > > > > > { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, > > > > > {}, > > > > > diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c > > > > > index 2b1834c5609a..192ba9099964 100644 > > > > > --- a/drivers/soc/qcom/rpmpd.c > > > > > +++ b/drivers/soc/qcom/rpmpd.c > > > > > @@ -115,6 +115,26 @@ struct rpmpd_desc { > > > > > > > > > > static DEFINE_MUTEX(rpmpd_lock); > > > > > > > > > > +/* msm8916 RPM Power Domains */ > > > > > +DEFINE_RPMPD_PAIR(msm8916, vddcx, vddcx_ao, SMPA, CORNER, 1); > > > > > +DEFINE_RPMPD_PAIR(msm8916, vddmx, vddmx_ao, LDOA, CORNER, 3); > > > > > + > > > > > +DEFINE_RPMPD_VFC(msm8916, vddcx_vfc, SMPA, 1); > > > > > + > > > > > +static struct rpmpd *msm8916_rpmpds[] = { > > > > > + [MSM8916_VDDCX] = &msm8916_vddcx, > > > > > + [MSM8916_VDDCX_AO] = &msm8916_vddcx_ao, > > > > > + [MSM8916_VDDCX_VFC] = &msm8916_vddcx_vfc, > > > > > + [MSM8916_VDDMX] = &msm8916_vddmx, > > > > > + [MSM8916_VDDMX_AO] = &msm8916_vddmx_ao, > > > > > +}; > > > > > + > > > > > +static const struct rpmpd_desc msm8916_desc = { > > > > > + .rpmpds = msm8916_rpmpds, > > > > > + .num_pds = ARRAY_SIZE(msm8916_rpmpds), > > > > > + .max_state = MAX_8996_RPMPD_STATE, > > > > > +}; > > > > > + > > > > > /* msm8976 RPM Power Domains */ > > > > > DEFINE_RPMPD_PAIR(msm8976, vddcx, vddcx_ao, SMPA, LEVEL, 2); > > > > > DEFINE_RPMPD_PAIR(msm8976, vddmx, vddmx_ao, SMPA, LEVEL, 6); > > > > > @@ -220,6 +240,7 @@ static const struct rpmpd_desc qcs404_desc = { > > > > > }; > > > > > > > > > > static const struct of_device_id rpmpd_match_table[] = { > > > > > + { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc }, > > > > > { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc }, > > > > > { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, > > > > > { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, > > > > > diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h > > > > > index 3f74096d5a7c..70d304a2deae 100644 > > > > > --- a/include/dt-bindings/power/qcom-rpmpd.h > > > > > +++ b/include/dt-bindings/power/qcom-rpmpd.h > > > > > @@ -51,6 +51,13 @@ > > > > > #define RPMH_REGULATOR_LEVEL_TURBO 384 > > > > > #define RPMH_REGULATOR_LEVEL_TURBO_L1 416 > > > > > > > > > > +/* MSM8916 Power Domain Indexes */ > > > > > +#define MSM8916_VDDCX 0 > > > > > +#define MSM8916_VDDCX_AO 1 > > > > > +#define MSM8916_VDDCX_VFC 2 > > > > > +#define MSM8916_VDDMX 3 > > > > > +#define MSM8916_VDDMX_AO 4 > > > > > + > > > > > /* MSM8976 Power Domain Indexes */ > > > > > #define MSM8976_VDDCX 0 > > > > > #define MSM8976_VDDCX_AO 1 ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-08 12:08 ` Ulf Hansson @ 2020-05-08 13:42 ` Stephan Gerhold 2020-05-11 5:29 ` Viresh Kumar 1 sibling, 0 replies; 32+ messages in thread From: Stephan Gerhold @ 2020-05-08 13:42 UTC (permalink / raw) To: Ulf Hansson Cc: Bjorn Andersson, Viresh Kumar, Loic Poulain, Andy Gross, linux-arm-msm, Lina Iyer On Fri, May 08, 2020 at 02:08:09PM +0200, Ulf Hansson wrote: > + Lina > > On Thu, 7 May 2020 at 07:33, Bjorn Andersson <bjorn.andersson@linaro.org> wrote: > > > > On Wed 06 May 14:18 PDT 2020, Stephan Gerhold wrote: > > > > Viresh, Ulf, > > > > Stephan is trying to describe the relationship between the CPU rail and > > the memory rail on db410c (where the performance state of the memory > > rail needs to be kept above the performance state of the CPU supply. > > > > The latter is modelled as a power-domain and the performance state > > changes as expected, but no one enables the power-domain. > > Just to make one thing clear, from a genpd framework point of view, > power on/off of a genpd is orthogonal to setting/aggregating > performance states for it. > > It's instead up to the genpd provider to deal with this (as I > understand, that seems to be the issue from the below discussions). > > > > > What's the appropriate method for ensuring the power-domain is > > enabled/disabled as needed? Should it be referenced in the hierarchical > > power domain for the CPUs perhaps? > > If I understand the dependency correctly, perhaps you are right that > there needs to be a subdomain assigned. Although, I don't know if this > ever has been tested to work for a real use case, when it comes to > performance state propagations upwards in the hierarchy. > What I don't understand is why this is only happening for me, and not also for CPR on QCS404 (or does that have the same problem?). See commit 04aadcaadd39 ("arm64: dts: qcom: qcs404: Add CPR and populate OPP table"). Essentially that works exactly like the "mx" power domain I'm trying to add, it references the "cpr" power domain performance states from the CPU opps. Someone also needs to power on the CPR power domain, and AFAICT there is nothing that does that at the moment. > Viresh? > > If you also need to manage genpd power on/off, that should be managed > by using runtime PM reference counting on those devices that are > attached to the genpd in question. > For testing I have added a pm_runtime_get_sync() for the virtual devices returned by dev_pm_opp_attach_genpd() in qcom-cpufreq-nvmem.c. That works fine, but it means the power domain is powered on permanently. (Which might be the correct behavior in this case, not sure powering off VDD_MX would ever work correctly...) > Kind regards > Uffe > > > > > > Regards, > > Bjorn > > > > > Hi, > > > > > > On Sun, Apr 26, 2020 at 02:31:48PM +0200, Stephan Gerhold wrote: > > > > On Wed, Apr 22, 2020 at 09:55:06PM -0700, Bjorn Andersson wrote: > > > > > On Fri 03 Apr 11:00 PDT 2020, Stephan Gerhold wrote: > > > > > > > > > > > On Fri, Apr 03, 2020 at 12:09:25PM +0200, Stephan Gerhold wrote: > > > > > > > On Thu, Apr 02, 2020 at 06:31:19PM -0700, Bjorn Andersson wrote: > > > > > > > > On Thu 02 Apr 01:13 PDT 2020, Stephan Gerhold wrote: > > > > > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > > > > > On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > > > > > > > > > > The highest cpu frequency opps have been dropped because CPR is not > > > > > > > > > > supported. However, we can simply specify operating voltage so that > > > > > > > > > > they match the max corner voltages for each freq. With that, we can > > > > > > > > > > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > > > > > > > > > > fine tune operating voltages and optimize power consumption. > > > > > > > > > > > > > > > > > > Thanks for the patch! I was wondering how to enable the higher CPU > > > > > > > > > frequencies for a while now... > > > > > > > > > > > > > > > > > > I was actually quite excited to see CPR being mainlined for QCS404. > > > > > > > > > If we are trying to add such a workaround (rather than CPR) for MSM8916 > > > > > > > > > now, does that mean it's unlikely to see CPR working for MSM8916 > > > > > > > > > anytime soon? > > > > > > > > > > > > > > > > > > AFAICT, there is a WIP branch from Niklas Cassel here: > > > > > > > > > https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline > > > > > > > > > but it hasn't been updated for a while. (Not sure if it was working > > > > > > > > > already...) > > > > > > > > > > > > > > > > > > Can someone explain what is missing to make CPR work for MSM8916? > > > > > > > > > > > > > > > > > > > > > > > > > CPR needs to control 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 it > > > > > > > > seems we don't have to adjust VDD_MX, so the code for this is missing > > > > > > > > from the driver. > > > > > > > > > > > > > > > > So, afaict, what's missing is that rpmpd.c needs to gain support for > > > > > > > > 8916, then the CPR driver needs to gain a cpr_acc_desc and compatible > > > > > > > > for 8916, it needs to reference the VDDMX power domain and before/after > > > > > > > > we're adjusting the corner of the CPR we need to adjust the MX according > > > > > > > > to the mapping specified in the downstream kernel (i.e. 1->4, 2->5 and > > > > > > > > 3->7). > > > > > > > > > > > > > > > > > > > > > > > > Unfortunately, the requirement that VDDMX (VDD_MEM I presume) must be > > > > > > > > higher than VDD_APC most likely needs to be taken into consideration for > > > > > > > > Loic's proposed static voltage scaling as well. Unless VDD_MEM is left > > > > > > > > in Turbo mode from the boot loader I think we need to take VDDMX to > > > > > > > > corner 7 for speeds 998MHz and above (i.e. where we pull VDD_APC to > > > > > > > > 1.35V). > > > > > > > > > > > > > > > > > > > > > > I see! I wonder how hard it would be to add MSM8916 to rpmpd, > > > > > > > looking at previous commits it's mainly setting up a few defines? > > > > > > > > > > > > > > If I understand it correctly, the OPPs from rpmpd could then be > > > > > > > referenced as "required-opps" in the CPU OPP table so that VDD_MX is > > > > > > > scaled together with the CPU frequency, and doesn't need to stay at > > > > > > > turbo mode (like in v3 from Loic) the whole time. > > > > > > > > > > > > > > > > > > > I have been thinking about this some more and I think I came up with > > > > > > some changes that make sense (but not entirely sure). > > > > > > > > > > > > Based on the available downstream sources I guessed the defines to add > > > > > > for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as > > > > > > "required-opps" to the CPU OPP table so it would vote for the appopriate > > > > > > corners (with the mapping you mentioned above). > > > > > > > > > > > > > > > > I was not aware it was possible to describe the dependency between the > > > > > CPU opp table and MX in this fashion. If that's the case then this looks > > > > > really good and it should be straight forward to add MSM8916 support to > > > > > the CPR driver as well. > > > > > > > > > > > > > Indeed! > > > > > > > > > > I haven't tested it yet, maybe I can get some feedback first if the code > > > > > > seems reasonable or if I'm missing something obvious? :) > > > > > > > > > > > > > > > > Have you tested this yet? > > > > > > > > > > > > > I just did. It does not fully work, yet: > > > > > > > > rpmpd_set_performance() is indeed called as necessary when switching the > > > > CPU frequency. When I set 200 MHz it sets corner 3, with 533 MHz corner 4 > > > > and starting with 998 MHz corner 6. So far so good :) > > > > > > > > However, there is never actually anything sent to the RPM. :( > > > > It bails out in rpmpd_set_performance() before calling rpmpd_aggregate_corner(): > > > > > > > > /* Always send updates for vfc and vfl */ > > > > if (!pd->enabled && pd->key != KEY_FLOOR_CORNER && > > > > pd->key != KEY_FLOOR_LEVEL) > > > > goto out; > > > > > > > > Seems like we just try to set performance states, but never actually > > > > enable (rpmpd_power_on()) the power domain (pd->enabled == false). > > > > > > > > I'm not sure which of the components involved here should handle that. > > > > The OPP core when setting required OPPs, the genpd core etc. > > > > > > > > Any ideas? > > > > > > > > Thanks, > > > > Stephan > > > > > > > > > > For now I have added something to qcom-cpufreq-nvmem.c to power on/enable > > > the power domain (not really sure if it belongs there...): > > > > > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > index a1b8238872a2..ed352ead037e 100644 > > > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > @@ -26,6 +26,7 @@ > > > #include <linux/platform_device.h> > > > #include <linux/pm_domain.h> > > > #include <linux/pm_opp.h> > > > +#include <linux/pm_runtime.h> > > > #include <linux/slab.h> > > > #include <linux/soc/qcom/smem.h> > > > > > > @@ -370,10 +371,13 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) > > > } > > > > > > if (drv->data->genpd_names) { > > > + struct device **pd_dev; > > > + const char **name = drv->data->genpd_names; > > > + > > > drv->genpd_opp_tables[cpu] = > > > dev_pm_opp_attach_genpd(cpu_dev, > > > drv->data->genpd_names, > > > - NULL); > > > + &pd_dev); > > > if (IS_ERR(drv->genpd_opp_tables[cpu])) { > > > ret = PTR_ERR(drv->genpd_opp_tables[cpu]); > > > if (ret != -EPROBE_DEFER) > > > @@ -382,6 +386,12 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) > > > ret); > > > goto free_genpd_opp; > > > } > > > + > > > + while (*name) { > > > + pm_runtime_get_sync(*pd_dev); > > > + name++; > > > + pd_dev++; > > > + } > > > } > > > } > > > > > > I really wonder why this doesn't affect CPR (or does it?). > > > So far I was not able to find anything that would power on/enable > > > the "cpr" power domain either. But I don't have a qcs404 to verify. > > > > > > As far as I can tell from the log, the corner votes are correctly sent > > > to the RPM now when the CPU frequency is changed. > > > > > > However... > > > > > > > > > Also: Is there a good way to validate these changes? > > > > > > I suppose I could check the genpd state but that wouldn't tell me if the > > > > > > corner was applied correctly. Maybe I can check the actual voltage > > > > > > through the SPMI interface, hm... > > > > > > > > > > > > > > > > Validating that S2 and VDD_MX changes appropriately in Linux would be a > > > > > pretty good test. > > > > > > > > > > > Unfortunately I was not able to see any change in the voltage of L3 yet. > > > On samsung-a5u, /sys/class/regulator/<l3 spmi regulator>/microvolts > > > permanently reports 1300000 uV, even after a few different corner votes. > > > > > > I'm not sure if: > > > > > > - This is normal (maybe some other remoteproc has a higher vote?) > > > - I tried to disable wcnss, venus and hexagon without difference > > > > > > - I'm just missing something in the code > > > > > > - This is some peculiarity of the RPM firmware on samsung-a5u. > > > (Although that seems quite unlikely to me...) > > > > > > Any ideas? :/ > > > > > > Thanks, > > > Stephan > > > > > > > > > If this seems like a good approach I can split up the changes in > > > > > > reasonable patches and post it separately. For now the full diff below. > > > > > > > > > > > > > > > > Please do > > > > > > > > > > Regards, > > > > > Bjorn > > > > > > > > > > > Stephan > > > > > > > > > > > > arch/arm64/boot/dts/qcom/msm8916.dtsi | 65 +++++++++++++++++++++++++++++----- > > > > > > drivers/cpufreq/cpufreq-dt-platdev.c | 1 + > > > > > > drivers/cpufreq/qcom-cpufreq-nvmem.c | 11 ++++++ > > > > > > drivers/soc/qcom/rpmpd.c | 21 +++++++++++ > > > > > > include/dt-bindings/power/qcom-rpmpd.h | 7 ++++ > > > > > > 5 files changed, 96 insertions(+), 9 deletions(-) > > > > > > > > > > > > diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > > > > index b0a82447976a..5b8fce8609d0 100644 > > > > > > --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > > > > +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > > > > @@ -10,6 +10,7 @@ > > > > > > #include <dt-bindings/soc/qcom,apr.h> > > > > > > #include <dt-bindings/sound/qcom,q6afe.h> > > > > > > #include <dt-bindings/thermal/thermal.h> > > > > > > +#include <dt-bindings/power/qcom-rpmpd.h> > > > > > > > > > > > > / { > > > > > > interrupt-parent = <&intc>; > > > > > > @@ -108,8 +109,8 @@ CPU0: cpu@0 { > > > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > > > operating-points-v2 = <&cpu_opp_table>; > > > > > > #cooling-cells = <2>; > > > > > > - power-domains = <&CPU_PD0>; > > > > > > - power-domain-names = "psci"; > > > > > > + power-domains = <&CPU_PD0>, <&rpmpd MSM8916_VDDMX_AO>; > > > > > > + power-domain-names = "psci", "mx"; > > > > > > }; > > > > > > > > > > > > CPU1: cpu@1 { > > > > > > @@ -122,8 +123,8 @@ CPU1: cpu@1 { > > > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > > > operating-points-v2 = <&cpu_opp_table>; > > > > > > #cooling-cells = <2>; > > > > > > - power-domains = <&CPU_PD1>; > > > > > > - power-domain-names = "psci"; > > > > > > + power-domains = <&CPU_PD1>, <&rpmpd MSM8916_VDDMX_AO>; > > > > > > + power-domain-names = "psci", "mx"; > > > > > > }; > > > > > > > > > > > > CPU2: cpu@2 { > > > > > > @@ -136,8 +137,8 @@ CPU2: cpu@2 { > > > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > > > operating-points-v2 = <&cpu_opp_table>; > > > > > > #cooling-cells = <2>; > > > > > > - power-domains = <&CPU_PD2>; > > > > > > - power-domain-names = "psci"; > > > > > > + power-domains = <&CPU_PD2>, <&rpmpd MSM8916_VDDMX_AO>; > > > > > > + power-domain-names = "psci", "mx"; > > > > > > }; > > > > > > > > > > > > CPU3: cpu@3 { > > > > > > @@ -150,8 +151,8 @@ CPU3: cpu@3 { > > > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > > > operating-points-v2 = <&cpu_opp_table>; > > > > > > #cooling-cells = <2>; > > > > > > - power-domains = <&CPU_PD3>; > > > > > > - power-domain-names = "psci"; > > > > > > + power-domains = <&CPU_PD3>, <&rpmpd MSM8916_VDDMX_AO>; > > > > > > + power-domain-names = "psci", "mx"; > > > > > > }; > > > > > > > > > > > > L2_0: l2-cache { > > > > > > @@ -343,40 +344,52 @@ modem_alert0: trip-point@0 { > > > > > > }; > > > > > > > > > > > > cpu_opp_table: cpu_opp_table { > > > > > > - compatible = "operating-points-v2"; > > > > > > + /* > > > > > > + * FIXME: The naming here is really weird, since MSM8916 does > > > > > > + * not have kyro. Maybe we should add a more generic compatible? > > > > > > + */ > > > > > > + compatible = "operating-points-v2-kryo-cpu"; > > > > > > opp-shared; > > > > > > > > > > > > opp-200000000 { > > > > > > opp-hz = /bits/ 64 <200000000>; > > > > > > opp-microvolt = <1050000>; > > > > > > + required-opps = <&rpmpd_opp_svs_soc>; > > > > > > }; > > > > > > opp-400000000 { > > > > > > opp-hz = /bits/ 64 <400000000>; > > > > > > opp-microvolt = <1050000>; > > > > > > + required-opps = <&rpmpd_opp_svs_soc>; > > > > > > }; > > > > > > opp-533330000 { > > > > > > opp-hz = /bits/ 64 <533330000>; > > > > > > opp-microvolt = <1150000>; > > > > > > + required-opps = <&rpmpd_opp_nom>; > > > > > > }; > > > > > > opp-800000000 { > > > > > > opp-hz = /bits/ 64 <800000000>; > > > > > > opp-microvolt = <1150000>; > > > > > > + required-opps = <&rpmpd_opp_nom>; > > > > > > }; > > > > > > opp-998400000 { > > > > > > opp-hz = /bits/ 64 <998400000>; > > > > > > opp-microvolt = <1350000>; > > > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > > > }; > > > > > > opp-1094400000 { > > > > > > opp-hz = /bits/ 64 <1094400000>; > > > > > > opp-microvolt = <1350000>; > > > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > > > }; > > > > > > opp-1152000000 { > > > > > > opp-hz = /bits/ 64 <1152000000>; > > > > > > opp-microvolt = <1350000>; > > > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > > > }; > > > > > > opp-1209600000 { > > > > > > opp-hz = /bits/ 64 <1209600000>; > > > > > > opp-microvolt = <1350000>; > > > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > > > }; > > > > > > }; > > > > > > > > > > > > @@ -1710,6 +1723,40 @@ rpmcc: qcom,rpmcc { > > > > > > #clock-cells = <1>; > > > > > > }; > > > > > > > > > > > > + rpmpd: power-controller { > > > > > > + compatible = "qcom,msm8916-rpmpd"; > > > > > > + #power-domain-cells = <1>; > > > > > > + operating-points-v2 = <&rpmpd_opp_table>; > > > > > > + > > > > > > + rpmpd_opp_table: opp-table { > > > > > > + compatible = "operating-points-v2"; > > > > > > + > > > > > > + rpmpd_opp_ret: opp1 { > > > > > > + opp-level = <1>; > > > > > > + }; > > > > > > + > > > > > > + rpmpd_opp_svs: opp2 { > > > > > > + opp-level = <2>; > > > > > > + }; > > > > > > + > > > > > > + rpmpd_opp_svs_soc: opp3 { > > > > > > + opp-level = <3>; > > > > > > + }; > > > > > > + > > > > > > + rpmpd_opp_nom: opp4 { > > > > > > + opp-level = <4>; > > > > > > + }; > > > > > > + > > > > > > + rpmpd_opp_turbo: opp5 { > > > > > > + opp-level = <5>; > > > > > > + }; > > > > > > + > > > > > > + rpmpd_opp_super_turbo: opp6 { > > > > > > + opp-level = <6>; > > > > > > + }; > > > > > > + }; > > > > > > + }; > > > > > > + > > > > > > smd_rpm_regulators: pm8916-regulators { > > > > > > compatible = "qcom,rpm-pm8916-regulators"; > > > > > > > > > > > > diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c > > > > > > index f2ae9cd455c1..b0f6bd0fffc1 100644 > > > > > > --- a/drivers/cpufreq/cpufreq-dt-platdev.c > > > > > > +++ b/drivers/cpufreq/cpufreq-dt-platdev.c > > > > > > @@ -128,6 +128,7 @@ static const struct of_device_id blacklist[] __initconst = { > > > > > > { .compatible = "nvidia,tegra210", }, > > > > > > > > > > > > { .compatible = "qcom,apq8096", }, > > > > > > + { .compatible = "qcom,msm8916", }, > > > > > > { .compatible = "qcom,msm8996", }, > > > > > > { .compatible = "qcom,qcs404", }, > > > > > > > > > > > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > > > > index f0d2d5035413..c77a30349d08 100644 > > > > > > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > > > > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > > > > @@ -129,6 +129,16 @@ static const struct qcom_cpufreq_match_data match_data_kryo = { > > > > > > .get_version = qcom_cpufreq_kryo_name_version, > > > > > > }; > > > > > > > > > > > > +static const char *msm8916_genpd_names[] = { "mx", NULL }; > > > > > > + > > > > > > +static const struct qcom_cpufreq_match_data match_data_msm8916 = { > > > > > > + /* > > > > > > + * FIXME: Might need to implement .get_version here to handle > > > > > > + * different frequencies depending on speedbin/pvs version. > > > > > > + */ > > > > > > + .genpd_names = msm8916_genpd_names, > > > > > > +}; > > > > > > + > > > > > > static const char *qcs404_genpd_names[] = { "cpr", NULL }; > > > > > > > > > > > > static const struct qcom_cpufreq_match_data match_data_qcs404 = { > > > > > > @@ -301,6 +311,7 @@ static struct platform_driver qcom_cpufreq_driver = { > > > > > > > > > > > > static const struct of_device_id qcom_cpufreq_match_list[] __initconst = { > > > > > > { .compatible = "qcom,apq8096", .data = &match_data_kryo }, > > > > > > + { .compatible = "qcom,msm8916", .data = &match_data_msm8916 }, > > > > > > { .compatible = "qcom,msm8996", .data = &match_data_kryo }, > > > > > > { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, > > > > > > {}, > > > > > > diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c > > > > > > index 2b1834c5609a..192ba9099964 100644 > > > > > > --- a/drivers/soc/qcom/rpmpd.c > > > > > > +++ b/drivers/soc/qcom/rpmpd.c > > > > > > @@ -115,6 +115,26 @@ struct rpmpd_desc { > > > > > > > > > > > > static DEFINE_MUTEX(rpmpd_lock); > > > > > > > > > > > > +/* msm8916 RPM Power Domains */ > > > > > > +DEFINE_RPMPD_PAIR(msm8916, vddcx, vddcx_ao, SMPA, CORNER, 1); > > > > > > +DEFINE_RPMPD_PAIR(msm8916, vddmx, vddmx_ao, LDOA, CORNER, 3); > > > > > > + > > > > > > +DEFINE_RPMPD_VFC(msm8916, vddcx_vfc, SMPA, 1); > > > > > > + > > > > > > +static struct rpmpd *msm8916_rpmpds[] = { > > > > > > + [MSM8916_VDDCX] = &msm8916_vddcx, > > > > > > + [MSM8916_VDDCX_AO] = &msm8916_vddcx_ao, > > > > > > + [MSM8916_VDDCX_VFC] = &msm8916_vddcx_vfc, > > > > > > + [MSM8916_VDDMX] = &msm8916_vddmx, > > > > > > + [MSM8916_VDDMX_AO] = &msm8916_vddmx_ao, > > > > > > +}; > > > > > > + > > > > > > +static const struct rpmpd_desc msm8916_desc = { > > > > > > + .rpmpds = msm8916_rpmpds, > > > > > > + .num_pds = ARRAY_SIZE(msm8916_rpmpds), > > > > > > + .max_state = MAX_8996_RPMPD_STATE, > > > > > > +}; > > > > > > + > > > > > > /* msm8976 RPM Power Domains */ > > > > > > DEFINE_RPMPD_PAIR(msm8976, vddcx, vddcx_ao, SMPA, LEVEL, 2); > > > > > > DEFINE_RPMPD_PAIR(msm8976, vddmx, vddmx_ao, SMPA, LEVEL, 6); > > > > > > @@ -220,6 +240,7 @@ static const struct rpmpd_desc qcs404_desc = { > > > > > > }; > > > > > > > > > > > > static const struct of_device_id rpmpd_match_table[] = { > > > > > > + { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc }, > > > > > > { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc }, > > > > > > { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, > > > > > > { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, > > > > > > diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h > > > > > > index 3f74096d5a7c..70d304a2deae 100644 > > > > > > --- a/include/dt-bindings/power/qcom-rpmpd.h > > > > > > +++ b/include/dt-bindings/power/qcom-rpmpd.h > > > > > > @@ -51,6 +51,13 @@ > > > > > > #define RPMH_REGULATOR_LEVEL_TURBO 384 > > > > > > #define RPMH_REGULATOR_LEVEL_TURBO_L1 416 > > > > > > > > > > > > +/* MSM8916 Power Domain Indexes */ > > > > > > +#define MSM8916_VDDCX 0 > > > > > > +#define MSM8916_VDDCX_AO 1 > > > > > > +#define MSM8916_VDDCX_VFC 2 > > > > > > +#define MSM8916_VDDMX 3 > > > > > > +#define MSM8916_VDDMX_AO 4 > > > > > > + > > > > > > /* MSM8976 Power Domain Indexes */ > > > > > > #define MSM8976_VDDCX 0 > > > > > > #define MSM8976_VDDCX_AO 1 ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-08 12:08 ` Ulf Hansson 2020-05-08 13:42 ` Stephan Gerhold @ 2020-05-11 5:29 ` Viresh Kumar 1 sibling, 0 replies; 32+ messages in thread From: Viresh Kumar @ 2020-05-11 5:29 UTC (permalink / raw) To: Ulf Hansson Cc: Bjorn Andersson, Stephan Gerhold, Loic Poulain, Andy Gross, linux-arm-msm, Lina Iyer On 08-05-20, 14:08, Ulf Hansson wrote: > + Lina > > On Thu, 7 May 2020 at 07:33, Bjorn Andersson <bjorn.andersson@linaro.org> wrote: > > > > On Wed 06 May 14:18 PDT 2020, Stephan Gerhold wrote: > > > > Viresh, Ulf, > > > > Stephan is trying to describe the relationship between the CPU rail and > > the memory rail on db410c (where the performance state of the memory > > rail needs to be kept above the performance state of the CPU supply. > > > > The latter is modelled as a power-domain and the performance state > > changes as expected, but no one enables the power-domain. > > Just to make one thing clear, from a genpd framework point of view, > power on/off of a genpd is orthogonal to setting/aggregating > performance states for it. > > It's instead up to the genpd provider to deal with this (as I > understand, that seems to be the issue from the below discussions). > > > > > What's the appropriate method for ensuring the power-domain is > > enabled/disabled as needed? Should it be referenced in the hierarchical > > power domain for the CPUs perhaps? > > If I understand the dependency correctly, perhaps you are right that > there needs to be a subdomain assigned. Although, I don't know if this > ever has been tested to work for a real use case, when it comes to > performance state propagations upwards in the hierarchy. > > Viresh? I have modeled that with a fake system, and yes it was tested. But not on real hardware but it should work nevertheless. -- viresh ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-06 21:18 ` Stephan Gerhold 2020-05-07 5:34 ` Bjorn Andersson @ 2020-05-07 10:46 ` Stephan Gerhold 2020-05-21 19:18 ` Stephan Gerhold 1 sibling, 1 reply; 32+ messages in thread From: Stephan Gerhold @ 2020-05-07 10:46 UTC (permalink / raw) To: Bjorn Andersson; +Cc: Loic Poulain, agross, linux-arm-msm [-- Attachment #1: Type: text/plain, Size: 19475 bytes --] On Wed, May 06, 2020 at 11:18:07PM +0200, Stephan Gerhold wrote: > Hi, > > On Sun, Apr 26, 2020 at 02:31:48PM +0200, Stephan Gerhold wrote: > > On Wed, Apr 22, 2020 at 09:55:06PM -0700, Bjorn Andersson wrote: > > > On Fri 03 Apr 11:00 PDT 2020, Stephan Gerhold wrote: > > > > > > > On Fri, Apr 03, 2020 at 12:09:25PM +0200, Stephan Gerhold wrote: > > > > > On Thu, Apr 02, 2020 at 06:31:19PM -0700, Bjorn Andersson wrote: > > > > > > On Thu 02 Apr 01:13 PDT 2020, Stephan Gerhold wrote: > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > > > > > > > > The highest cpu frequency opps have been dropped because CPR is not > > > > > > > > supported. However, we can simply specify operating voltage so that > > > > > > > > they match the max corner voltages for each freq. With that, we can > > > > > > > > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > > > > > > > > fine tune operating voltages and optimize power consumption. > > > > > > > > > > > > > > Thanks for the patch! I was wondering how to enable the higher CPU > > > > > > > frequencies for a while now... > > > > > > > > > > > > > > I was actually quite excited to see CPR being mainlined for QCS404. > > > > > > > If we are trying to add such a workaround (rather than CPR) for MSM8916 > > > > > > > now, does that mean it's unlikely to see CPR working for MSM8916 > > > > > > > anytime soon? > > > > > > > > > > > > > > AFAICT, there is a WIP branch from Niklas Cassel here: > > > > > > > https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline > > > > > > > but it hasn't been updated for a while. (Not sure if it was working > > > > > > > already...) > > > > > > > > > > > > > > Can someone explain what is missing to make CPR work for MSM8916? > > > > > > > > > > > > > > > > > > > CPR needs to control 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 it > > > > > > seems we don't have to adjust VDD_MX, so the code for this is missing > > > > > > from the driver. > > > > > > > > > > > > So, afaict, what's missing is that rpmpd.c needs to gain support for > > > > > > 8916, then the CPR driver needs to gain a cpr_acc_desc and compatible > > > > > > for 8916, it needs to reference the VDDMX power domain and before/after > > > > > > we're adjusting the corner of the CPR we need to adjust the MX according > > > > > > to the mapping specified in the downstream kernel (i.e. 1->4, 2->5 and > > > > > > 3->7). > > > > > > > > > > > > > > > > > > Unfortunately, the requirement that VDDMX (VDD_MEM I presume) must be > > > > > > higher than VDD_APC most likely needs to be taken into consideration for > > > > > > Loic's proposed static voltage scaling as well. Unless VDD_MEM is left > > > > > > in Turbo mode from the boot loader I think we need to take VDDMX to > > > > > > corner 7 for speeds 998MHz and above (i.e. where we pull VDD_APC to > > > > > > 1.35V). > > > > > > > > > > > > > > > > I see! I wonder how hard it would be to add MSM8916 to rpmpd, > > > > > looking at previous commits it's mainly setting up a few defines? > > > > > > > > > > If I understand it correctly, the OPPs from rpmpd could then be > > > > > referenced as "required-opps" in the CPU OPP table so that VDD_MX is > > > > > scaled together with the CPU frequency, and doesn't need to stay at > > > > > turbo mode (like in v3 from Loic) the whole time. > > > > > > > > > > > > > I have been thinking about this some more and I think I came up with > > > > some changes that make sense (but not entirely sure). > > > > > > > > Based on the available downstream sources I guessed the defines to add > > > > for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as > > > > "required-opps" to the CPU OPP table so it would vote for the appopriate > > > > corners (with the mapping you mentioned above). > > > > > > > > > > I was not aware it was possible to describe the dependency between the > > > CPU opp table and MX in this fashion. If that's the case then this looks > > > really good and it should be straight forward to add MSM8916 support to > > > the CPR driver as well. > > > > > > > Indeed! > > > > > > I haven't tested it yet, maybe I can get some feedback first if the code > > > > seems reasonable or if I'm missing something obvious? :) > > > > > > > > > > Have you tested this yet? > > > > > > > I just did. It does not fully work, yet: > > > > rpmpd_set_performance() is indeed called as necessary when switching the > > CPU frequency. When I set 200 MHz it sets corner 3, with 533 MHz corner 4 > > and starting with 998 MHz corner 6. So far so good :) > > > > However, there is never actually anything sent to the RPM. :( > > It bails out in rpmpd_set_performance() before calling rpmpd_aggregate_corner(): > > > > /* Always send updates for vfc and vfl */ > > if (!pd->enabled && pd->key != KEY_FLOOR_CORNER && > > pd->key != KEY_FLOOR_LEVEL) > > goto out; > > > > Seems like we just try to set performance states, but never actually > > enable (rpmpd_power_on()) the power domain (pd->enabled == false). > > > > I'm not sure which of the components involved here should handle that. > > The OPP core when setting required OPPs, the genpd core etc. > > > > Any ideas? > > > > Thanks, > > Stephan > > > > For now I have added something to qcom-cpufreq-nvmem.c to power on/enable > the power domain (not really sure if it belongs there...): > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > index a1b8238872a2..ed352ead037e 100644 > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > @@ -26,6 +26,7 @@ > #include <linux/platform_device.h> > #include <linux/pm_domain.h> > #include <linux/pm_opp.h> > +#include <linux/pm_runtime.h> > #include <linux/slab.h> > #include <linux/soc/qcom/smem.h> > > @@ -370,10 +371,13 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) > } > > if (drv->data->genpd_names) { > + struct device **pd_dev; > + const char **name = drv->data->genpd_names; > + > drv->genpd_opp_tables[cpu] = > dev_pm_opp_attach_genpd(cpu_dev, > drv->data->genpd_names, > - NULL); > + &pd_dev); > if (IS_ERR(drv->genpd_opp_tables[cpu])) { > ret = PTR_ERR(drv->genpd_opp_tables[cpu]); > if (ret != -EPROBE_DEFER) > @@ -382,6 +386,12 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) > ret); > goto free_genpd_opp; > } > + > + while (*name) { > + pm_runtime_get_sync(*pd_dev); > + name++; > + pd_dev++; > + } > } > } > > I really wonder why this doesn't affect CPR (or does it?). > So far I was not able to find anything that would power on/enable > the "cpr" power domain either. But I don't have a qcs404 to verify. > > As far as I can tell from the log, the corner votes are correctly sent > to the RPM now when the CPU frequency is changed. > > However... > > > > > Also: Is there a good way to validate these changes? > > > > I suppose I could check the genpd state but that wouldn't tell me if the > > > > corner was applied correctly. Maybe I can check the actual voltage > > > > through the SPMI interface, hm... > > > > > > > > > > Validating that S2 and VDD_MX changes appropriately in Linux would be a > > > pretty good test. > > > > > Unfortunately I was not able to see any change in the voltage of L3 yet. > On samsung-a5u, /sys/class/regulator/<l3 spmi regulator>/microvolts > permanently reports 1300000 uV, even after a few different corner votes. > > I'm not sure if: > > - This is normal (maybe some other remoteproc has a higher vote?) > - I tried to disable wcnss, venus and hexagon without difference > > - I'm just missing something in the code > > - This is some peculiarity of the RPM firmware on samsung-a5u. > (Although that seems quite unlikely to me...) > > Any ideas? :/ > I just tried the same on the downstream kernel for samsung-a5u. There the L3 voltage doesn't change either, it stays on 1300000 uV permanently. So more likely would be either "this is normal" or "This is some peculiarity of the RPM firmware on samsung-a5u". I don't have a DB410c available for testing, but I'm curious if it would work correctly there. So far I have been unable to find any obvious mistake in my changes. I'm attaching the full diff (including Loic's changes) in case someone wants to test this on the DB410c (or some other MSM8916 device). Basically you need to: 1. CONFIG_QCOM_RPMPD=y CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y 2. Run it and change CPU frequencies a bit (either with an automatic CPU governor, or by setting speeds manually with powersave/performance/userspace) 3. There should be "set performance state" messages in dmesg for the VDD_MX corner votes 4. Identify the spmi l3 regulator using /sys/class/regulator/*/name 5. Check the reported voltage in /sys/class/regulator/.../microvolts For me it stays on 1300000 uV, permanently. :( Thanks, Stephan > > > > If this seems like a good approach I can split up the changes in > > > > reasonable patches and post it separately. For now the full diff below. > > > > > > > > > > Please do > > > > > > Regards, > > > Bjorn > > > > > > > Stephan > > > > > > > > arch/arm64/boot/dts/qcom/msm8916.dtsi | 65 +++++++++++++++++++++++++++++----- > > > > drivers/cpufreq/cpufreq-dt-platdev.c | 1 + > > > > drivers/cpufreq/qcom-cpufreq-nvmem.c | 11 ++++++ > > > > drivers/soc/qcom/rpmpd.c | 21 +++++++++++ > > > > include/dt-bindings/power/qcom-rpmpd.h | 7 ++++ > > > > 5 files changed, 96 insertions(+), 9 deletions(-) > > > > > > > > diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > > index b0a82447976a..5b8fce8609d0 100644 > > > > --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > > +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi > > > > @@ -10,6 +10,7 @@ > > > > #include <dt-bindings/soc/qcom,apr.h> > > > > #include <dt-bindings/sound/qcom,q6afe.h> > > > > #include <dt-bindings/thermal/thermal.h> > > > > +#include <dt-bindings/power/qcom-rpmpd.h> > > > > > > > > / { > > > > interrupt-parent = <&intc>; > > > > @@ -108,8 +109,8 @@ CPU0: cpu@0 { > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > operating-points-v2 = <&cpu_opp_table>; > > > > #cooling-cells = <2>; > > > > - power-domains = <&CPU_PD0>; > > > > - power-domain-names = "psci"; > > > > + power-domains = <&CPU_PD0>, <&rpmpd MSM8916_VDDMX_AO>; > > > > + power-domain-names = "psci", "mx"; > > > > }; > > > > > > > > CPU1: cpu@1 { > > > > @@ -122,8 +123,8 @@ CPU1: cpu@1 { > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > operating-points-v2 = <&cpu_opp_table>; > > > > #cooling-cells = <2>; > > > > - power-domains = <&CPU_PD1>; > > > > - power-domain-names = "psci"; > > > > + power-domains = <&CPU_PD1>, <&rpmpd MSM8916_VDDMX_AO>; > > > > + power-domain-names = "psci", "mx"; > > > > }; > > > > > > > > CPU2: cpu@2 { > > > > @@ -136,8 +137,8 @@ CPU2: cpu@2 { > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > operating-points-v2 = <&cpu_opp_table>; > > > > #cooling-cells = <2>; > > > > - power-domains = <&CPU_PD2>; > > > > - power-domain-names = "psci"; > > > > + power-domains = <&CPU_PD2>, <&rpmpd MSM8916_VDDMX_AO>; > > > > + power-domain-names = "psci", "mx"; > > > > }; > > > > > > > > CPU3: cpu@3 { > > > > @@ -150,8 +151,8 @@ CPU3: cpu@3 { > > > > cpu-supply = <&pm8916_spmi_s2>; > > > > operating-points-v2 = <&cpu_opp_table>; > > > > #cooling-cells = <2>; > > > > - power-domains = <&CPU_PD3>; > > > > - power-domain-names = "psci"; > > > > + power-domains = <&CPU_PD3>, <&rpmpd MSM8916_VDDMX_AO>; > > > > + power-domain-names = "psci", "mx"; > > > > }; > > > > > > > > L2_0: l2-cache { > > > > @@ -343,40 +344,52 @@ modem_alert0: trip-point@0 { > > > > }; > > > > > > > > cpu_opp_table: cpu_opp_table { > > > > - compatible = "operating-points-v2"; > > > > + /* > > > > + * FIXME: The naming here is really weird, since MSM8916 does > > > > + * not have kyro. Maybe we should add a more generic compatible? > > > > + */ > > > > + compatible = "operating-points-v2-kryo-cpu"; > > > > opp-shared; > > > > > > > > opp-200000000 { > > > > opp-hz = /bits/ 64 <200000000>; > > > > opp-microvolt = <1050000>; > > > > + required-opps = <&rpmpd_opp_svs_soc>; > > > > }; > > > > opp-400000000 { > > > > opp-hz = /bits/ 64 <400000000>; > > > > opp-microvolt = <1050000>; > > > > + required-opps = <&rpmpd_opp_svs_soc>; > > > > }; > > > > opp-533330000 { > > > > opp-hz = /bits/ 64 <533330000>; > > > > opp-microvolt = <1150000>; > > > > + required-opps = <&rpmpd_opp_nom>; > > > > }; > > > > opp-800000000 { > > > > opp-hz = /bits/ 64 <800000000>; > > > > opp-microvolt = <1150000>; > > > > + required-opps = <&rpmpd_opp_nom>; > > > > }; > > > > opp-998400000 { > > > > opp-hz = /bits/ 64 <998400000>; > > > > opp-microvolt = <1350000>; > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > }; > > > > opp-1094400000 { > > > > opp-hz = /bits/ 64 <1094400000>; > > > > opp-microvolt = <1350000>; > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > }; > > > > opp-1152000000 { > > > > opp-hz = /bits/ 64 <1152000000>; > > > > opp-microvolt = <1350000>; > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > }; > > > > opp-1209600000 { > > > > opp-hz = /bits/ 64 <1209600000>; > > > > opp-microvolt = <1350000>; > > > > + required-opps = <&rpmpd_opp_super_turbo>; > > > > }; > > > > }; > > > > > > > > @@ -1710,6 +1723,40 @@ rpmcc: qcom,rpmcc { > > > > #clock-cells = <1>; > > > > }; > > > > > > > > + rpmpd: power-controller { > > > > + compatible = "qcom,msm8916-rpmpd"; > > > > + #power-domain-cells = <1>; > > > > + operating-points-v2 = <&rpmpd_opp_table>; > > > > + > > > > + rpmpd_opp_table: opp-table { > > > > + compatible = "operating-points-v2"; > > > > + > > > > + rpmpd_opp_ret: opp1 { > > > > + opp-level = <1>; > > > > + }; > > > > + > > > > + rpmpd_opp_svs: opp2 { > > > > + opp-level = <2>; > > > > + }; > > > > + > > > > + rpmpd_opp_svs_soc: opp3 { > > > > + opp-level = <3>; > > > > + }; > > > > + > > > > + rpmpd_opp_nom: opp4 { > > > > + opp-level = <4>; > > > > + }; > > > > + > > > > + rpmpd_opp_turbo: opp5 { > > > > + opp-level = <5>; > > > > + }; > > > > + > > > > + rpmpd_opp_super_turbo: opp6 { > > > > + opp-level = <6>; > > > > + }; > > > > + }; > > > > + }; > > > > + > > > > smd_rpm_regulators: pm8916-regulators { > > > > compatible = "qcom,rpm-pm8916-regulators"; > > > > > > > > diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c > > > > index f2ae9cd455c1..b0f6bd0fffc1 100644 > > > > --- a/drivers/cpufreq/cpufreq-dt-platdev.c > > > > +++ b/drivers/cpufreq/cpufreq-dt-platdev.c > > > > @@ -128,6 +128,7 @@ static const struct of_device_id blacklist[] __initconst = { > > > > { .compatible = "nvidia,tegra210", }, > > > > > > > > { .compatible = "qcom,apq8096", }, > > > > + { .compatible = "qcom,msm8916", }, > > > > { .compatible = "qcom,msm8996", }, > > > > { .compatible = "qcom,qcs404", }, > > > > > > > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > > index f0d2d5035413..c77a30349d08 100644 > > > > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > > @@ -129,6 +129,16 @@ static const struct qcom_cpufreq_match_data match_data_kryo = { > > > > .get_version = qcom_cpufreq_kryo_name_version, > > > > }; > > > > > > > > +static const char *msm8916_genpd_names[] = { "mx", NULL }; > > > > + > > > > +static const struct qcom_cpufreq_match_data match_data_msm8916 = { > > > > + /* > > > > + * FIXME: Might need to implement .get_version here to handle > > > > + * different frequencies depending on speedbin/pvs version. > > > > + */ > > > > + .genpd_names = msm8916_genpd_names, > > > > +}; > > > > + > > > > static const char *qcs404_genpd_names[] = { "cpr", NULL }; > > > > > > > > static const struct qcom_cpufreq_match_data match_data_qcs404 = { > > > > @@ -301,6 +311,7 @@ static struct platform_driver qcom_cpufreq_driver = { > > > > > > > > static const struct of_device_id qcom_cpufreq_match_list[] __initconst = { > > > > { .compatible = "qcom,apq8096", .data = &match_data_kryo }, > > > > + { .compatible = "qcom,msm8916", .data = &match_data_msm8916 }, > > > > { .compatible = "qcom,msm8996", .data = &match_data_kryo }, > > > > { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, > > > > {}, > > > > diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c > > > > index 2b1834c5609a..192ba9099964 100644 > > > > --- a/drivers/soc/qcom/rpmpd.c > > > > +++ b/drivers/soc/qcom/rpmpd.c > > > > @@ -115,6 +115,26 @@ struct rpmpd_desc { > > > > > > > > static DEFINE_MUTEX(rpmpd_lock); > > > > > > > > +/* msm8916 RPM Power Domains */ > > > > +DEFINE_RPMPD_PAIR(msm8916, vddcx, vddcx_ao, SMPA, CORNER, 1); > > > > +DEFINE_RPMPD_PAIR(msm8916, vddmx, vddmx_ao, LDOA, CORNER, 3); > > > > + > > > > +DEFINE_RPMPD_VFC(msm8916, vddcx_vfc, SMPA, 1); > > > > + > > > > +static struct rpmpd *msm8916_rpmpds[] = { > > > > + [MSM8916_VDDCX] = &msm8916_vddcx, > > > > + [MSM8916_VDDCX_AO] = &msm8916_vddcx_ao, > > > > + [MSM8916_VDDCX_VFC] = &msm8916_vddcx_vfc, > > > > + [MSM8916_VDDMX] = &msm8916_vddmx, > > > > + [MSM8916_VDDMX_AO] = &msm8916_vddmx_ao, > > > > +}; > > > > + > > > > +static const struct rpmpd_desc msm8916_desc = { > > > > + .rpmpds = msm8916_rpmpds, > > > > + .num_pds = ARRAY_SIZE(msm8916_rpmpds), > > > > + .max_state = MAX_8996_RPMPD_STATE, > > > > +}; > > > > + > > > > /* msm8976 RPM Power Domains */ > > > > DEFINE_RPMPD_PAIR(msm8976, vddcx, vddcx_ao, SMPA, LEVEL, 2); > > > > DEFINE_RPMPD_PAIR(msm8976, vddmx, vddmx_ao, SMPA, LEVEL, 6); > > > > @@ -220,6 +240,7 @@ static const struct rpmpd_desc qcs404_desc = { > > > > }; > > > > > > > > static const struct of_device_id rpmpd_match_table[] = { > > > > + { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc }, > > > > { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc }, > > > > { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, > > > > { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, > > > > diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h > > > > index 3f74096d5a7c..70d304a2deae 100644 > > > > --- a/include/dt-bindings/power/qcom-rpmpd.h > > > > +++ b/include/dt-bindings/power/qcom-rpmpd.h > > > > @@ -51,6 +51,13 @@ > > > > #define RPMH_REGULATOR_LEVEL_TURBO 384 > > > > #define RPMH_REGULATOR_LEVEL_TURBO_L1 416 > > > > > > > > +/* MSM8916 Power Domain Indexes */ > > > > +#define MSM8916_VDDCX 0 > > > > +#define MSM8916_VDDCX_AO 1 > > > > +#define MSM8916_VDDCX_VFC 2 > > > > +#define MSM8916_VDDMX 3 > > > > +#define MSM8916_VDDMX_AO 4 > > > > + > > > > /* MSM8976 Power Domain Indexes */ > > > > #define MSM8976_VDDCX 0 > > > > #define MSM8976_VDDCX_AO 1 [-- Attachment #2: msm8916-vdd-mx.patch --] [-- Type: text/plain, Size: 10913 bytes --] diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 9254e4423d0c..b7e871d8f857 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -11,6 +11,7 @@ #include <dt-bindings/sound/qcom,q6afe.h> #include <dt-bindings/sound/qcom,q6asm.h> #include <dt-bindings/thermal/thermal.h> +#include <dt-bindings/power/qcom-rpmpd.h> / { interrupt-parent = <&intc>; @@ -106,10 +107,11 @@ CPU0: cpu@0 { next-level-cache = <&L2_0>; enable-method = "psci"; clocks = <&apcs>; + cpu-supply = <&pm8916_spmi_s2>; operating-points-v2 = <&cpu_opp_table>; #cooling-cells = <2>; - power-domains = <&CPU_PD0>; - power-domain-names = "psci"; + power-domains = <&CPU_PD0>, <&rpmpd MSM8916_VDDMX_AO>; + power-domain-names = "psci", "mx"; }; CPU1: cpu@1 { @@ -119,10 +121,11 @@ CPU1: cpu@1 { next-level-cache = <&L2_0>; enable-method = "psci"; clocks = <&apcs>; + cpu-supply = <&pm8916_spmi_s2>; operating-points-v2 = <&cpu_opp_table>; #cooling-cells = <2>; - power-domains = <&CPU_PD1>; - power-domain-names = "psci"; + power-domains = <&CPU_PD1>, <&rpmpd MSM8916_VDDMX_AO>; + power-domain-names = "psci", "mx"; }; CPU2: cpu@2 { @@ -132,10 +135,11 @@ CPU2: cpu@2 { next-level-cache = <&L2_0>; enable-method = "psci"; clocks = <&apcs>; + cpu-supply = <&pm8916_spmi_s2>; operating-points-v2 = <&cpu_opp_table>; #cooling-cells = <2>; - power-domains = <&CPU_PD2>; - power-domain-names = "psci"; + power-domains = <&CPU_PD2>, <&rpmpd MSM8916_VDDMX_AO>; + power-domain-names = "psci", "mx"; }; CPU3: cpu@3 { @@ -145,10 +149,11 @@ CPU3: cpu@3 { next-level-cache = <&L2_0>; enable-method = "psci"; clocks = <&apcs>; + cpu-supply = <&pm8916_spmi_s2>; operating-points-v2 = <&cpu_opp_table>; #cooling-cells = <2>; - power-domains = <&CPU_PD3>; - power-domain-names = "psci"; + power-domains = <&CPU_PD3>, <&rpmpd MSM8916_VDDMX_AO>; + power-domain-names = "psci", "mx"; }; L2_0: l2-cache { @@ -340,20 +345,48 @@ modem_alert0: trip-point@0 { }; cpu_opp_table: cpu_opp_table { - compatible = "operating-points-v2"; + compatible = "operating-points-v2-qcom-cpu"; opp-shared; opp-200000000 { opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <1050000>; + required-opps = <&rpmpd_opp_svs_soc>; }; opp-400000000 { opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <1050000>; + required-opps = <&rpmpd_opp_svs_soc>; + }; + opp-533330000 { + opp-hz = /bits/ 64 <533330000>; + opp-microvolt = <1150000>; + required-opps = <&rpmpd_opp_nom>; }; opp-800000000 { opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <1150000>; + required-opps = <&rpmpd_opp_nom>; }; opp-998400000 { opp-hz = /bits/ 64 <998400000>; + opp-microvolt = <1350000>; + required-opps = <&rpmpd_opp_super_turbo>; + }; + opp-1094400000 { + opp-hz = /bits/ 64 <1094400000>; + opp-microvolt = <1350000>; + required-opps = <&rpmpd_opp_super_turbo>; + }; + opp-1152000000 { + opp-hz = /bits/ 64 <1152000000>; + opp-microvolt = <1350000>; + required-opps = <&rpmpd_opp_super_turbo>; + }; + opp-1209600000 { + opp-hz = /bits/ 64 <1209600000>; + opp-microvolt = <1350000>; + required-opps = <&rpmpd_opp_super_turbo>; }; }; @@ -1725,10 +1758,45 @@ rpmcc: qcom,rpmcc { #clock-cells = <1>; }; + rpmpd: power-controller { + compatible = "qcom,msm8916-rpmpd"; + #power-domain-cells = <1>; + operating-points-v2 = <&rpmpd_opp_table>; + + rpmpd_opp_table: opp-table { + compatible = "operating-points-v2"; + + rpmpd_opp_ret: opp1 { + opp-level = <1>; + }; + + rpmpd_opp_svs: opp2 { + opp-level = <2>; + }; + + rpmpd_opp_svs_soc: opp3 { + opp-level = <3>; + }; + + rpmpd_opp_nom: opp4 { + opp-level = <4>; + }; + + rpmpd_opp_turbo: opp5 { + opp-level = <5>; + }; + + rpmpd_opp_super_turbo: opp6 { + opp-level = <6>; + }; + }; + }; + smd_rpm_regulators: pm8916-regulators { compatible = "qcom,rpm-pm8916-regulators"; pm8916_s1: s1 {}; + /* s2 is directly controlled via spmi */ pm8916_s3: s3 {}; pm8916_s4: s4 {}; diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi index cbb96f23c2f7..c1505fc4a077 100644 --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi @@ -163,5 +163,18 @@ wcd_codec: codec@f000 { vdd-micbias-supply = <&pm8916_l13>; #sound-dai-cells = <1>; }; + + spmi_regulators: spmi_regulators { + compatible = "qcom,pm8916-regulators"; + #address-cells = <1>; + #size-cells = <1>; + + pm8916_spmi_s2: s2 { + regulator-always-on; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1350000>; + }; + /* other regulators can be controlled via rpm */ + }; }; }; diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index cb9db16bea61..4a261101de3f 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -128,6 +128,7 @@ static const struct of_device_id blacklist[] __initconst = { { .compatible = "nvidia,tegra210", }, { .compatible = "qcom,apq8096", }, + { .compatible = "qcom,msm8916", }, { .compatible = "qcom,msm8996", }, { .compatible = "qcom,qcs404", }, diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c index a1b8238872a2..16d31f724bb8 100644 --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c @@ -26,6 +26,7 @@ #include <linux/platform_device.h> #include <linux/pm_domain.h> #include <linux/pm_opp.h> +#include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/soc/qcom/smem.h> @@ -252,6 +253,16 @@ static const struct qcom_cpufreq_match_data match_data_krait = { .get_version = qcom_cpufreq_krait_name_version, }; +static const char *msm8916_genpd_names[] = { "mx", NULL }; + +static const struct qcom_cpufreq_match_data match_data_msm8916 = { + /* + * FIXME: Might need to implement .get_version here to handle + * different frequencies depending on speedbin/pvs version. + */ + .genpd_names = msm8916_genpd_names, +}; + static const char *qcs404_genpd_names[] = { "cpr", NULL }; static const struct qcom_cpufreq_match_data match_data_qcs404 = { @@ -370,10 +381,13 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) } if (drv->data->genpd_names) { + struct device **pd_dev; + const char **name = drv->data->genpd_names; + drv->genpd_opp_tables[cpu] = dev_pm_opp_attach_genpd(cpu_dev, drv->data->genpd_names, - NULL); + &pd_dev); if (IS_ERR(drv->genpd_opp_tables[cpu])) { ret = PTR_ERR(drv->genpd_opp_tables[cpu]); if (ret != -EPROBE_DEFER) @@ -382,6 +396,12 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) ret); goto free_genpd_opp; } + + while (*name) { + pm_runtime_get_sync(*pd_dev); + name++; + pd_dev++; + } } } @@ -456,6 +476,7 @@ static struct platform_driver qcom_cpufreq_driver = { static const struct of_device_id qcom_cpufreq_match_list[] __initconst = { { .compatible = "qcom,apq8096", .data = &match_data_kryo }, + { .compatible = "qcom,msm8916", .data = &match_data_msm8916 }, { .compatible = "qcom,msm8996", .data = &match_data_kryo }, { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, { .compatible = "qcom,ipq8064", .data = &match_data_krait }, diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index 2b1834c5609a..705a52b9ebc5 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -115,6 +115,26 @@ struct rpmpd_desc { static DEFINE_MUTEX(rpmpd_lock); +/* msm8916 RPM Power Domains */ +DEFINE_RPMPD_PAIR(msm8916, vddcx, vddcx_ao, SMPA, CORNER, 1); +DEFINE_RPMPD_PAIR(msm8916, vddmx, vddmx_ao, LDOA, CORNER, 3); + +DEFINE_RPMPD_VFC(msm8916, vddcx_vfc, SMPA, 1); + +static struct rpmpd *msm8916_rpmpds[] = { + [MSM8916_VDDCX] = &msm8916_vddcx, + [MSM8916_VDDCX_AO] = &msm8916_vddcx_ao, + [MSM8916_VDDCX_VFC] = &msm8916_vddcx_vfc, + [MSM8916_VDDMX] = &msm8916_vddmx, + [MSM8916_VDDMX_AO] = &msm8916_vddmx_ao, +}; + +static const struct rpmpd_desc msm8916_desc = { + .rpmpds = msm8916_rpmpds, + .num_pds = ARRAY_SIZE(msm8916_rpmpds), + .max_state = MAX_8996_RPMPD_STATE, +}; + /* msm8976 RPM Power Domains */ DEFINE_RPMPD_PAIR(msm8976, vddcx, vddcx_ao, SMPA, LEVEL, 2); DEFINE_RPMPD_PAIR(msm8976, vddmx, vddmx_ao, SMPA, LEVEL, 6); @@ -220,6 +240,7 @@ static const struct rpmpd_desc qcs404_desc = { }; static const struct of_device_id rpmpd_match_table[] = { + { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc }, { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc }, { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, @@ -235,6 +256,8 @@ static int rpmpd_send_enable(struct rpmpd *pd, bool enable) .value = cpu_to_le32(enable), }; + pr_err("rpmpd enable %#x %#x: %d\n", pd->res_type, pd->res_id, enable); + return qcom_rpm_smd_write(pd->rpm, QCOM_SMD_RPM_ACTIVE_STATE, pd->res_type, pd->res_id, &req, sizeof(req)); } @@ -247,6 +270,8 @@ static int rpmpd_send_corner(struct rpmpd *pd, int state, unsigned int corner) .value = cpu_to_le32(corner), }; + pr_err("rpmpd corner %#x %#x state %d: %u\n", pd->res_type, pd->res_id, state, corner); + return qcom_rpm_smd_write(pd->rpm, state, pd->res_type, pd->res_id, &req, sizeof(req)); }; @@ -331,6 +356,8 @@ static int rpmpd_set_performance(struct generic_pm_domain *domain, int ret = 0; struct rpmpd *pd = domain_to_rpmpd(domain); + pr_err("set performance: %d\n", state); + if (state > pd->max_state) state = pd->max_state; @@ -340,8 +367,10 @@ static int rpmpd_set_performance(struct generic_pm_domain *domain, /* Always send updates for vfc and vfl */ if (!pd->enabled && pd->key != KEY_FLOOR_CORNER && - pd->key != KEY_FLOOR_LEVEL) + pd->key != KEY_FLOOR_LEVEL) { + pr_err("not enabled\n"); goto out; + } ret = rpmpd_aggregate_corner(pd); diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index 3f74096d5a7c..70d304a2deae 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -51,6 +51,13 @@ #define RPMH_REGULATOR_LEVEL_TURBO 384 #define RPMH_REGULATOR_LEVEL_TURBO_L1 416 +/* MSM8916 Power Domain Indexes */ +#define MSM8916_VDDCX 0 +#define MSM8916_VDDCX_AO 1 +#define MSM8916_VDDCX_VFC 2 +#define MSM8916_VDDMX 3 +#define MSM8916_VDDMX_AO 4 + /* MSM8976 Power Domain Indexes */ #define MSM8976_VDDCX 0 #define MSM8976_VDDCX_AO 1 ^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-07 10:46 ` Stephan Gerhold @ 2020-05-21 19:18 ` Stephan Gerhold 2020-05-23 12:08 ` Stephan Gerhold 0 siblings, 1 reply; 32+ messages in thread From: Stephan Gerhold @ 2020-05-21 19:18 UTC (permalink / raw) To: Bjorn Andersson; +Cc: Loic Poulain, agross, linux-arm-msm On Thu, May 07, 2020 at 12:46:08PM +0200, Stephan Gerhold wrote: > On Wed, May 06, 2020 at 11:18:07PM +0200, Stephan Gerhold wrote: > > Hi, > > > > On Sun, Apr 26, 2020 at 02:31:48PM +0200, Stephan Gerhold wrote: > > > On Wed, Apr 22, 2020 at 09:55:06PM -0700, Bjorn Andersson wrote: > > > > On Fri 03 Apr 11:00 PDT 2020, Stephan Gerhold wrote: > > > > > > > > > On Fri, Apr 03, 2020 at 12:09:25PM +0200, Stephan Gerhold wrote: > > > > > > On Thu, Apr 02, 2020 at 06:31:19PM -0700, Bjorn Andersson wrote: > > > > > > > On Thu 02 Apr 01:13 PDT 2020, Stephan Gerhold wrote: > > > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > > > On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > > > > > > > > > The highest cpu frequency opps have been dropped because CPR is not > > > > > > > > > supported. However, we can simply specify operating voltage so that > > > > > > > > > they match the max corner voltages for each freq. With that, we can > > > > > > > > > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > > > > > > > > > fine tune operating voltages and optimize power consumption. > > > > > > > > > > > > > > > > Thanks for the patch! I was wondering how to enable the higher CPU > > > > > > > > frequencies for a while now... > > > > > > > > > > > > > > > > I was actually quite excited to see CPR being mainlined for QCS404. > > > > > > > > If we are trying to add such a workaround (rather than CPR) for MSM8916 > > > > > > > > now, does that mean it's unlikely to see CPR working for MSM8916 > > > > > > > > anytime soon? > > > > > > > > > > > > > > > > AFAICT, there is a WIP branch from Niklas Cassel here: > > > > > > > > https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline > > > > > > > > but it hasn't been updated for a while. (Not sure if it was working > > > > > > > > already...) > > > > > > > > > > > > > > > > Can someone explain what is missing to make CPR work for MSM8916? > > > > > > > > > > > > > > > > > > > > > > CPR needs to control 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 it > > > > > > > seems we don't have to adjust VDD_MX, so the code for this is missing > > > > > > > from the driver. > > > > > > > > > > > > > > So, afaict, what's missing is that rpmpd.c needs to gain support for > > > > > > > 8916, then the CPR driver needs to gain a cpr_acc_desc and compatible > > > > > > > for 8916, it needs to reference the VDDMX power domain and before/after > > > > > > > we're adjusting the corner of the CPR we need to adjust the MX according > > > > > > > to the mapping specified in the downstream kernel (i.e. 1->4, 2->5 and > > > > > > > 3->7). > > > > > > > > > > > > > > > > > > > > > Unfortunately, the requirement that VDDMX (VDD_MEM I presume) must be > > > > > > > higher than VDD_APC most likely needs to be taken into consideration for > > > > > > > Loic's proposed static voltage scaling as well. Unless VDD_MEM is left > > > > > > > in Turbo mode from the boot loader I think we need to take VDDMX to > > > > > > > corner 7 for speeds 998MHz and above (i.e. where we pull VDD_APC to > > > > > > > 1.35V). > > > > > > > > > > > > > > > > > > > I see! I wonder how hard it would be to add MSM8916 to rpmpd, > > > > > > looking at previous commits it's mainly setting up a few defines? > > > > > > > > > > > > If I understand it correctly, the OPPs from rpmpd could then be > > > > > > referenced as "required-opps" in the CPU OPP table so that VDD_MX is > > > > > > scaled together with the CPU frequency, and doesn't need to stay at > > > > > > turbo mode (like in v3 from Loic) the whole time. > > > > > > > > > > > > > > > > I have been thinking about this some more and I think I came up with > > > > > some changes that make sense (but not entirely sure). > > > > > > > > > > Based on the available downstream sources I guessed the defines to add > > > > > for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as > > > > > "required-opps" to the CPU OPP table so it would vote for the appopriate > > > > > corners (with the mapping you mentioned above). > > > > > > > > > > > > > I was not aware it was possible to describe the dependency between the > > > > CPU opp table and MX in this fashion. If that's the case then this looks > > > > really good and it should be straight forward to add MSM8916 support to > > > > the CPR driver as well. > > > > > > > > > > Indeed! > > > > > > > > I haven't tested it yet, maybe I can get some feedback first if the code > > > > > seems reasonable or if I'm missing something obvious? :) > > > > > > > > > > > > > Have you tested this yet? > > > > > > > > > > I just did. It does not fully work, yet: > > > > > > rpmpd_set_performance() is indeed called as necessary when switching the > > > CPU frequency. When I set 200 MHz it sets corner 3, with 533 MHz corner 4 > > > and starting with 998 MHz corner 6. So far so good :) > > > > > > However, there is never actually anything sent to the RPM. :( > > > It bails out in rpmpd_set_performance() before calling rpmpd_aggregate_corner(): > > > > > > /* Always send updates for vfc and vfl */ > > > if (!pd->enabled && pd->key != KEY_FLOOR_CORNER && > > > pd->key != KEY_FLOOR_LEVEL) > > > goto out; > > > > > > Seems like we just try to set performance states, but never actually > > > enable (rpmpd_power_on()) the power domain (pd->enabled == false). > > > > > > I'm not sure which of the components involved here should handle that. > > > The OPP core when setting required OPPs, the genpd core etc. > > > > > > Any ideas? > > > > > > Thanks, > > > Stephan > > > > > > > For now I have added something to qcom-cpufreq-nvmem.c to power on/enable > > the power domain (not really sure if it belongs there...): > > > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > index a1b8238872a2..ed352ead037e 100644 > > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > @@ -26,6 +26,7 @@ > > #include <linux/platform_device.h> > > #include <linux/pm_domain.h> > > #include <linux/pm_opp.h> > > +#include <linux/pm_runtime.h> > > #include <linux/slab.h> > > #include <linux/soc/qcom/smem.h> > > > > @@ -370,10 +371,13 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) > > } > > > > if (drv->data->genpd_names) { > > + struct device **pd_dev; > > + const char **name = drv->data->genpd_names; > > + > > drv->genpd_opp_tables[cpu] = > > dev_pm_opp_attach_genpd(cpu_dev, > > drv->data->genpd_names, > > - NULL); > > + &pd_dev); > > if (IS_ERR(drv->genpd_opp_tables[cpu])) { > > ret = PTR_ERR(drv->genpd_opp_tables[cpu]); > > if (ret != -EPROBE_DEFER) > > @@ -382,6 +386,12 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) > > ret); > > goto free_genpd_opp; > > } > > + > > + while (*name) { > > + pm_runtime_get_sync(*pd_dev); > > + name++; > > + pd_dev++; > > + } > > } > > } > > > > I really wonder why this doesn't affect CPR (or does it?). > > So far I was not able to find anything that would power on/enable > > the "cpr" power domain either. But I don't have a qcs404 to verify. > > > > As far as I can tell from the log, the corner votes are correctly sent > > to the RPM now when the CPU frequency is changed. > > > > However... > > > > > > > Also: Is there a good way to validate these changes? > > > > > I suppose I could check the genpd state but that wouldn't tell me if the > > > > > corner was applied correctly. Maybe I can check the actual voltage > > > > > through the SPMI interface, hm... > > > > > > > > > > > > > Validating that S2 and VDD_MX changes appropriately in Linux would be a > > > > pretty good test. > > > > > > > > Unfortunately I was not able to see any change in the voltage of L3 yet. > > On samsung-a5u, /sys/class/regulator/<l3 spmi regulator>/microvolts > > permanently reports 1300000 uV, even after a few different corner votes. > > > > I'm not sure if: > > > > - This is normal (maybe some other remoteproc has a higher vote?) > > - I tried to disable wcnss, venus and hexagon without difference > > > > - I'm just missing something in the code > > > > - This is some peculiarity of the RPM firmware on samsung-a5u. > > (Although that seems quite unlikely to me...) > > > > Any ideas? :/ > > > > I just tried the same on the downstream kernel for samsung-a5u. > There the L3 voltage doesn't change either, it stays on 1300000 uV > permanently. So more likely would be either "this is normal" or > "This is some peculiarity of the RPM firmware on samsung-a5u". > > I don't have a DB410c available for testing, but I'm curious if it would > work correctly there. So far I have been unable to find any obvious > mistake in my changes. > > I'm attaching the full diff (including Loic's changes) in case someone > wants to test this on the DB410c (or some other MSM8916 device). > Basically you need to: > > 1. CONFIG_QCOM_RPMPD=y > CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y > 2. Run it and change CPU frequencies a bit > (either with an automatic CPU governor, or by setting speeds > manually with powersave/performance/userspace) > 3. There should be "set performance state" messages in dmesg > for the VDD_MX corner votes > 4. Identify the spmi l3 regulator using /sys/class/regulator/*/name > 5. Check the reported voltage in /sys/class/regulator/.../microvolts > > For me it stays on 1300000 uV, permanently. :( > I recently bought another device that does not have signature checks enabled. For now I have tested with the original firmware there: With or without my changes it stays at 1287500 uV permanently. At least this seems somewhat more realistic since this is the "super turbo" voltage. I tried disabling various things in case they affect this somehow: WCNSS in particular sets 1287500 uV for pm8916_l3. But even with WCNSS disabled, even with the regulator constraints removed for pm8916_l3 and all changes reverted - it keeps reporting 1287500 uV through the SPMI interface, no matter which CPU frequency is selected. This is even more confusing because l3 is still at nominal voltage (1150000 uV) in the lk bootloader. (I ported a part of the mainline spmi_regulator driver to lk so I can dump the voltages from there...) Somehow it gets changed when Linux is booted. Very confusing. Unlike on my previous test device, testing on downstream was successful: - CPU frequency 200MHz - 800MHz results into 1150000 uV reported as voltage for l3 through the SPMI interface (corner 4/5) - Higher CPU frequencies result into 1287500 uV (corner 7) Again I ported the spmi_regulator driver from mainline to downstream, so the way the voltage is read should be the same. Clearly something must be different/missing in my changes, but I still have no idea what exactly. Any suggestions would be highly appreciated :) Thanks, Stephan PS: Does someone know if the RPM firmware on MSM8916 is usually device-specific? After some funny re-partitioning I managed to get PSCI working on this device by flashing the HYP/TZ firmware from DB410c. I was considering also flashing the RPM firmware from DB410c, but not entirely sure if that would be safe. (Any voltages hardcoded there?) ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-21 19:18 ` Stephan Gerhold @ 2020-05-23 12:08 ` Stephan Gerhold 2020-05-27 20:47 ` Georgi Djakov 0 siblings, 1 reply; 32+ messages in thread From: Stephan Gerhold @ 2020-05-23 12:08 UTC (permalink / raw) To: Bjorn Andersson Cc: Loic Poulain, agross, linux-arm-msm, Stephen Boyd, Georgi Djakov +Cc Stephen Boyd, Georgi Djakov On Thu, May 21, 2020 at 09:18:14PM +0200, Stephan Gerhold wrote: > On Thu, May 07, 2020 at 12:46:08PM +0200, Stephan Gerhold wrote: > > On Wed, May 06, 2020 at 11:18:07PM +0200, Stephan Gerhold wrote: > > > Hi, > > > > > > On Sun, Apr 26, 2020 at 02:31:48PM +0200, Stephan Gerhold wrote: > > > > On Wed, Apr 22, 2020 at 09:55:06PM -0700, Bjorn Andersson wrote: > > > > > On Fri 03 Apr 11:00 PDT 2020, Stephan Gerhold wrote: > > > > > > > > > > > On Fri, Apr 03, 2020 at 12:09:25PM +0200, Stephan Gerhold wrote: > > > > > > > On Thu, Apr 02, 2020 at 06:31:19PM -0700, Bjorn Andersson wrote: > > > > > > > > On Thu 02 Apr 01:13 PDT 2020, Stephan Gerhold wrote: > > > > > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > > > > > On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: > > > > > > > > > > The highest cpu frequency opps have been dropped because CPR is not > > > > > > > > > > supported. However, we can simply specify operating voltage so that > > > > > > > > > > they match the max corner voltages for each freq. With that, we can > > > > > > > > > > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > > > > > > > > > > fine tune operating voltages and optimize power consumption. > > > > > > > > > > > > > > > > > > Thanks for the patch! I was wondering how to enable the higher CPU > > > > > > > > > frequencies for a while now... > > > > > > > > > > > > > > > > > > I was actually quite excited to see CPR being mainlined for QCS404. > > > > > > > > > If we are trying to add such a workaround (rather than CPR) for MSM8916 > > > > > > > > > now, does that mean it's unlikely to see CPR working for MSM8916 > > > > > > > > > anytime soon? > > > > > > > > > > > > > > > > > > AFAICT, there is a WIP branch from Niklas Cassel here: > > > > > > > > > https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline > > > > > > > > > but it hasn't been updated for a while. (Not sure if it was working > > > > > > > > > already...) > > > > > > > > > > > > > > > > > > Can someone explain what is missing to make CPR work for MSM8916? > > > > > > > > > > > > > > > > > > > > > > > > > CPR needs to control 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 it > > > > > > > > seems we don't have to adjust VDD_MX, so the code for this is missing > > > > > > > > from the driver. > > > > > > > > > > > > > > > > So, afaict, what's missing is that rpmpd.c needs to gain support for > > > > > > > > 8916, then the CPR driver needs to gain a cpr_acc_desc and compatible > > > > > > > > for 8916, it needs to reference the VDDMX power domain and before/after > > > > > > > > we're adjusting the corner of the CPR we need to adjust the MX according > > > > > > > > to the mapping specified in the downstream kernel (i.e. 1->4, 2->5 and > > > > > > > > 3->7). > > > > > > > > > > > > > > > > > > > > > > > > Unfortunately, the requirement that VDDMX (VDD_MEM I presume) must be > > > > > > > > higher than VDD_APC most likely needs to be taken into consideration for > > > > > > > > Loic's proposed static voltage scaling as well. Unless VDD_MEM is left > > > > > > > > in Turbo mode from the boot loader I think we need to take VDDMX to > > > > > > > > corner 7 for speeds 998MHz and above (i.e. where we pull VDD_APC to > > > > > > > > 1.35V). > > > > > > > > > > > > > > > > > > > > > > I see! I wonder how hard it would be to add MSM8916 to rpmpd, > > > > > > > looking at previous commits it's mainly setting up a few defines? > > > > > > > > > > > > > > If I understand it correctly, the OPPs from rpmpd could then be > > > > > > > referenced as "required-opps" in the CPU OPP table so that VDD_MX is > > > > > > > scaled together with the CPU frequency, and doesn't need to stay at > > > > > > > turbo mode (like in v3 from Loic) the whole time. > > > > > > > > > > > > > > > > > > > I have been thinking about this some more and I think I came up with > > > > > > some changes that make sense (but not entirely sure). > > > > > > > > > > > > Based on the available downstream sources I guessed the defines to add > > > > > > for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as > > > > > > "required-opps" to the CPU OPP table so it would vote for the appopriate > > > > > > corners (with the mapping you mentioned above). > > > > > > > > > > > > > > > > I was not aware it was possible to describe the dependency between the > > > > > CPU opp table and MX in this fashion. If that's the case then this looks > > > > > really good and it should be straight forward to add MSM8916 support to > > > > > the CPR driver as well. > > > > > > > > > > > > > Indeed! > > > > > > > > > > I haven't tested it yet, maybe I can get some feedback first if the code > > > > > > seems reasonable or if I'm missing something obvious? :) > > > > > > > > > > > > > > > > Have you tested this yet? > > > > > > > > > > > > > I just did. It does not fully work, yet: > > > > > > > > rpmpd_set_performance() is indeed called as necessary when switching the > > > > CPU frequency. When I set 200 MHz it sets corner 3, with 533 MHz corner 4 > > > > and starting with 998 MHz corner 6. So far so good :) > > > > > > > > However, there is never actually anything sent to the RPM. :( > > > > It bails out in rpmpd_set_performance() before calling rpmpd_aggregate_corner(): > > > > > > > > /* Always send updates for vfc and vfl */ > > > > if (!pd->enabled && pd->key != KEY_FLOOR_CORNER && > > > > pd->key != KEY_FLOOR_LEVEL) > > > > goto out; > > > > > > > > Seems like we just try to set performance states, but never actually > > > > enable (rpmpd_power_on()) the power domain (pd->enabled == false). > > > > > > > > I'm not sure which of the components involved here should handle that. > > > > The OPP core when setting required OPPs, the genpd core etc. > > > > > > > > Any ideas? > > > > > > > > Thanks, > > > > Stephan > > > > > > > > > > For now I have added something to qcom-cpufreq-nvmem.c to power on/enable > > > the power domain (not really sure if it belongs there...): > > > > > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > index a1b8238872a2..ed352ead037e 100644 > > > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > > > @@ -26,6 +26,7 @@ > > > #include <linux/platform_device.h> > > > #include <linux/pm_domain.h> > > > #include <linux/pm_opp.h> > > > +#include <linux/pm_runtime.h> > > > #include <linux/slab.h> > > > #include <linux/soc/qcom/smem.h> > > > > > > @@ -370,10 +371,13 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) > > > } > > > > > > if (drv->data->genpd_names) { > > > + struct device **pd_dev; > > > + const char **name = drv->data->genpd_names; > > > + > > > drv->genpd_opp_tables[cpu] = > > > dev_pm_opp_attach_genpd(cpu_dev, > > > drv->data->genpd_names, > > > - NULL); > > > + &pd_dev); > > > if (IS_ERR(drv->genpd_opp_tables[cpu])) { > > > ret = PTR_ERR(drv->genpd_opp_tables[cpu]); > > > if (ret != -EPROBE_DEFER) > > > @@ -382,6 +386,12 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) > > > ret); > > > goto free_genpd_opp; > > > } > > > + > > > + while (*name) { > > > + pm_runtime_get_sync(*pd_dev); > > > + name++; > > > + pd_dev++; > > > + } > > > } > > > } > > > > > > I really wonder why this doesn't affect CPR (or does it?). > > > So far I was not able to find anything that would power on/enable > > > the "cpr" power domain either. But I don't have a qcs404 to verify. > > > > > > As far as I can tell from the log, the corner votes are correctly sent > > > to the RPM now when the CPU frequency is changed. > > > > > > However... > > > > > > > > > Also: Is there a good way to validate these changes? > > > > > > I suppose I could check the genpd state but that wouldn't tell me if the > > > > > > corner was applied correctly. Maybe I can check the actual voltage > > > > > > through the SPMI interface, hm... > > > > > > > > > > > > > > > > Validating that S2 and VDD_MX changes appropriately in Linux would be a > > > > > pretty good test. > > > > > > > > > > > Unfortunately I was not able to see any change in the voltage of L3 yet. > > > On samsung-a5u, /sys/class/regulator/<l3 spmi regulator>/microvolts > > > permanently reports 1300000 uV, even after a few different corner votes. > > > > > > I'm not sure if: > > > > > > - This is normal (maybe some other remoteproc has a higher vote?) > > > - I tried to disable wcnss, venus and hexagon without difference > > > > > > - I'm just missing something in the code > > > > > > - This is some peculiarity of the RPM firmware on samsung-a5u. > > > (Although that seems quite unlikely to me...) > > > > > > Any ideas? :/ > > > > > > > I just tried the same on the downstream kernel for samsung-a5u. > > There the L3 voltage doesn't change either, it stays on 1300000 uV > > permanently. So more likely would be either "this is normal" or > > "This is some peculiarity of the RPM firmware on samsung-a5u". > > > > I don't have a DB410c available for testing, but I'm curious if it would > > work correctly there. So far I have been unable to find any obvious > > mistake in my changes. > > > > I'm attaching the full diff (including Loic's changes) in case someone > > wants to test this on the DB410c (or some other MSM8916 device). > > Basically you need to: > > > > 1. CONFIG_QCOM_RPMPD=y > > CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y > > 2. Run it and change CPU frequencies a bit > > (either with an automatic CPU governor, or by setting speeds > > manually with powersave/performance/userspace) > > 3. There should be "set performance state" messages in dmesg > > for the VDD_MX corner votes > > 4. Identify the spmi l3 regulator using /sys/class/regulator/*/name > > 5. Check the reported voltage in /sys/class/regulator/.../microvolts > > > > For me it stays on 1300000 uV, permanently. :( > > > > I recently bought another device that does not have signature checks > enabled. For now I have tested with the original firmware there: > > With or without my changes it stays at 1287500 uV permanently. > At least this seems somewhat more realistic since this is the > "super turbo" voltage. > > I tried disabling various things in case they affect this somehow: > WCNSS in particular sets 1287500 uV for pm8916_l3. > But even with WCNSS disabled, even with the regulator constraints > removed for pm8916_l3 and all changes reverted - it keeps reporting > 1287500 uV through the SPMI interface, no matter which CPU frequency > is selected. > > This is even more confusing because l3 is still at nominal voltage > (1150000 uV) in the lk bootloader. (I ported a part of the mainline > spmi_regulator driver to lk so I can dump the voltages from there...) > Somehow it gets changed when Linux is booted. Very confusing. > > Unlike on my previous test device, testing on downstream was successful: > > - CPU frequency 200MHz - 800MHz results into 1150000 uV > reported as voltage for l3 through the SPMI interface (corner 4/5) > - Higher CPU frequencies result into 1287500 uV (corner 7) > > Again I ported the spmi_regulator driver from mainline to downstream, > so the way the voltage is read should be the same. > > Clearly something must be different/missing in my changes, > but I still have no idea what exactly. > Any suggestions would be highly appreciated :) > After several hours of debugging I finally figured out what's wrong: I guess there are various dependencies on the VDD_CX/VDD_MX voltage rails in the RPM: VDD_MX will be always higher than VDD_CX, and VDD_CX is also influenced by some of the clocks. If I disable the rpmcc/clk-smd-rpm entirely in the device tree, suddenly the VDD_MX voltage scales correctly with my changes. This seems to happen because the clk-smd-rpm forces all clocks to maximum state in the clk_smd_rpm_handoff() function. In my case, the clocks used for interconnect cause VDD_CX to scale to "super turbo", which in turn keeps VDD_MX on "super turbo" as well. I imagine this will be solved properly once we enable the interconnect driver and all the necessary consumers. But in general, I think this "handoff" behavior clk-smd-rpm is a bit weird: As far as I understand, the clock framework normally disables unused clocks shortly after the boot is complete. The clk-smd-rpm driver does the opposite: it forces all clocks to on, to maximum rate and does not seem to report that to the clock framework. If there is no consumer for the clock it seems to stay on and on maximum frequency forever. For example, in order to avoid other remoteprocs influencing the VDD_CX/VDD_MX voting I have disabled all additional remoteprocs in the device tree (e.g. WCNSS, venus, ...) Before Linux is booted (dumped from the PMIC registers in the lk bootloader), the rf_clk1/2 (modem/wcnss) is off. With clk-smd-rpm disabled it stays off too. However, when clk-smd-rpm is loaded that "handoff" function forces them on, and they're never turned off again. This is invisible to the clock framework - according to the clock debugfs they are off. But reading the PMIC registers reveals they are on. I suppose that behavior makes sense for the interconnect clocks, disabling those without an interconnect driver wouldn't do much good. But for the other clocks that doesn't seem quite right to me. What do you think? Thanks, Stephan ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-23 12:08 ` Stephan Gerhold @ 2020-05-27 20:47 ` Georgi Djakov 0 siblings, 0 replies; 32+ messages in thread From: Georgi Djakov @ 2020-05-27 20:47 UTC (permalink / raw) To: Stephan Gerhold, Bjorn Andersson Cc: Loic Poulain, agross, linux-arm-msm, Stephen Boyd Hi Stephan, On 23.05.20 15:08, Stephan Gerhold wrote: > +Cc Stephen Boyd, Georgi Djakov > > On Thu, May 21, 2020 at 09:18:14PM +0200, Stephan Gerhold wrote: >> On Thu, May 07, 2020 at 12:46:08PM +0200, Stephan Gerhold wrote: >>> On Wed, May 06, 2020 at 11:18:07PM +0200, Stephan Gerhold wrote: >>>> Hi, >>>> >>>> On Sun, Apr 26, 2020 at 02:31:48PM +0200, Stephan Gerhold wrote: >>>>> On Wed, Apr 22, 2020 at 09:55:06PM -0700, Bjorn Andersson wrote: >>>>>> On Fri 03 Apr 11:00 PDT 2020, Stephan Gerhold wrote: >>>>>> >>>>>>> On Fri, Apr 03, 2020 at 12:09:25PM +0200, Stephan Gerhold wrote: >>>>>>>> On Thu, Apr 02, 2020 at 06:31:19PM -0700, Bjorn Andersson wrote: >>>>>>>>> On Thu 02 Apr 01:13 PDT 2020, Stephan Gerhold wrote: >>>>>>>>> >>>>>>>>>> Hi, >>>>>>>>>> >>>>>>>>>> On Wed, Apr 01, 2020 at 07:50:59PM +0200, Loic Poulain wrote: >>>>>>>>>>> The highest cpu frequency opps have been dropped because CPR is not >>>>>>>>>>> supported. However, we can simply specify operating voltage so that >>>>>>>>>>> they match the max corner voltages for each freq. With that, we can >>>>>>>>>>> support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to >>>>>>>>>>> fine tune operating voltages and optimize power consumption. >>>>>>>>>> >>>>>>>>>> Thanks for the patch! I was wondering how to enable the higher CPU >>>>>>>>>> frequencies for a while now... >>>>>>>>>> >>>>>>>>>> I was actually quite excited to see CPR being mainlined for QCS404. >>>>>>>>>> If we are trying to add such a workaround (rather than CPR) for MSM8916 >>>>>>>>>> now, does that mean it's unlikely to see CPR working for MSM8916 >>>>>>>>>> anytime soon? >>>>>>>>>> >>>>>>>>>> AFAICT, there is a WIP branch from Niklas Cassel here: >>>>>>>>>> https://git.linaro.org/people/nicolas.dechesne/niklas.cassel/kernel.git/log/?h=cpr-msm8916-mainline >>>>>>>>>> but it hasn't been updated for a while. (Not sure if it was working >>>>>>>>>> already...) >>>>>>>>>> >>>>>>>>>> Can someone explain what is missing to make CPR work for MSM8916? >>>>>>>>>> >>>>>>>>> >>>>>>>>> CPR needs to control 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 it >>>>>>>>> seems we don't have to adjust VDD_MX, so the code for this is missing >>>>>>>>> from the driver. >>>>>>>>> >>>>>>>>> So, afaict, what's missing is that rpmpd.c needs to gain support for >>>>>>>>> 8916, then the CPR driver needs to gain a cpr_acc_desc and compatible >>>>>>>>> for 8916, it needs to reference the VDDMX power domain and before/after >>>>>>>>> we're adjusting the corner of the CPR we need to adjust the MX according >>>>>>>>> to the mapping specified in the downstream kernel (i.e. 1->4, 2->5 and >>>>>>>>> 3->7). >>>>>>>>> >>>>>>>>> >>>>>>>>> Unfortunately, the requirement that VDDMX (VDD_MEM I presume) must be >>>>>>>>> higher than VDD_APC most likely needs to be taken into consideration for >>>>>>>>> Loic's proposed static voltage scaling as well. Unless VDD_MEM is left >>>>>>>>> in Turbo mode from the boot loader I think we need to take VDDMX to >>>>>>>>> corner 7 for speeds 998MHz and above (i.e. where we pull VDD_APC to >>>>>>>>> 1.35V). >>>>>>>>> >>>>>>>> >>>>>>>> I see! I wonder how hard it would be to add MSM8916 to rpmpd, >>>>>>>> looking at previous commits it's mainly setting up a few defines? >>>>>>>> >>>>>>>> If I understand it correctly, the OPPs from rpmpd could then be >>>>>>>> referenced as "required-opps" in the CPU OPP table so that VDD_MX is >>>>>>>> scaled together with the CPU frequency, and doesn't need to stay at >>>>>>>> turbo mode (like in v3 from Loic) the whole time. >>>>>>>> >>>>>>> >>>>>>> I have been thinking about this some more and I think I came up with >>>>>>> some changes that make sense (but not entirely sure). >>>>>>> >>>>>>> Based on the available downstream sources I guessed the defines to add >>>>>>> for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as >>>>>>> "required-opps" to the CPU OPP table so it would vote for the appopriate >>>>>>> corners (with the mapping you mentioned above). >>>>>>> >>>>>> >>>>>> I was not aware it was possible to describe the dependency between the >>>>>> CPU opp table and MX in this fashion. If that's the case then this looks >>>>>> really good and it should be straight forward to add MSM8916 support to >>>>>> the CPR driver as well. >>>>>> >>>>> >>>>> Indeed! >>>>> >>>>>>> I haven't tested it yet, maybe I can get some feedback first if the code >>>>>>> seems reasonable or if I'm missing something obvious? :) >>>>>>> >>>>>> >>>>>> Have you tested this yet? >>>>>> >>>>> >>>>> I just did. It does not fully work, yet: >>>>> >>>>> rpmpd_set_performance() is indeed called as necessary when switching the >>>>> CPU frequency. When I set 200 MHz it sets corner 3, with 533 MHz corner 4 >>>>> and starting with 998 MHz corner 6. So far so good :) >>>>> >>>>> However, there is never actually anything sent to the RPM. :( >>>>> It bails out in rpmpd_set_performance() before calling rpmpd_aggregate_corner(): >>>>> >>>>> /* Always send updates for vfc and vfl */ >>>>> if (!pd->enabled && pd->key != KEY_FLOOR_CORNER && >>>>> pd->key != KEY_FLOOR_LEVEL) >>>>> goto out; >>>>> >>>>> Seems like we just try to set performance states, but never actually >>>>> enable (rpmpd_power_on()) the power domain (pd->enabled == false). >>>>> >>>>> I'm not sure which of the components involved here should handle that. >>>>> The OPP core when setting required OPPs, the genpd core etc. >>>>> >>>>> Any ideas? >>>>> >>>>> Thanks, >>>>> Stephan >>>>> >>>> >>>> For now I have added something to qcom-cpufreq-nvmem.c to power on/enable >>>> the power domain (not really sure if it belongs there...): >>>> >>>> diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c >>>> index a1b8238872a2..ed352ead037e 100644 >>>> --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c >>>> +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c >>>> @@ -26,6 +26,7 @@ >>>> #include <linux/platform_device.h> >>>> #include <linux/pm_domain.h> >>>> #include <linux/pm_opp.h> >>>> +#include <linux/pm_runtime.h> >>>> #include <linux/slab.h> >>>> #include <linux/soc/qcom/smem.h> >>>> >>>> @@ -370,10 +371,13 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) >>>> } >>>> >>>> if (drv->data->genpd_names) { >>>> + struct device **pd_dev; >>>> + const char **name = drv->data->genpd_names; >>>> + >>>> drv->genpd_opp_tables[cpu] = >>>> dev_pm_opp_attach_genpd(cpu_dev, >>>> drv->data->genpd_names, >>>> - NULL); >>>> + &pd_dev); >>>> if (IS_ERR(drv->genpd_opp_tables[cpu])) { >>>> ret = PTR_ERR(drv->genpd_opp_tables[cpu]); >>>> if (ret != -EPROBE_DEFER) >>>> @@ -382,6 +386,12 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) >>>> ret); >>>> goto free_genpd_opp; >>>> } >>>> + >>>> + while (*name) { >>>> + pm_runtime_get_sync(*pd_dev); >>>> + name++; >>>> + pd_dev++; >>>> + } >>>> } >>>> } >>>> >>>> I really wonder why this doesn't affect CPR (or does it?). >>>> So far I was not able to find anything that would power on/enable >>>> the "cpr" power domain either. But I don't have a qcs404 to verify. >>>> >>>> As far as I can tell from the log, the corner votes are correctly sent >>>> to the RPM now when the CPU frequency is changed. >>>> >>>> However... >>>> >>>>>>> Also: Is there a good way to validate these changes? >>>>>>> I suppose I could check the genpd state but that wouldn't tell me if the >>>>>>> corner was applied correctly. Maybe I can check the actual voltage >>>>>>> through the SPMI interface, hm... >>>>>>> >>>>>> >>>>>> Validating that S2 and VDD_MX changes appropriately in Linux would be a >>>>>> pretty good test. >>>>>> >>>> >>>> Unfortunately I was not able to see any change in the voltage of L3 yet. >>>> On samsung-a5u, /sys/class/regulator/<l3 spmi regulator>/microvolts >>>> permanently reports 1300000 uV, even after a few different corner votes. >>>> >>>> I'm not sure if: >>>> >>>> - This is normal (maybe some other remoteproc has a higher vote?) >>>> - I tried to disable wcnss, venus and hexagon without difference >>>> >>>> - I'm just missing something in the code >>>> >>>> - This is some peculiarity of the RPM firmware on samsung-a5u. >>>> (Although that seems quite unlikely to me...) >>>> >>>> Any ideas? :/ >>>> >>> >>> I just tried the same on the downstream kernel for samsung-a5u. >>> There the L3 voltage doesn't change either, it stays on 1300000 uV >>> permanently. So more likely would be either "this is normal" or >>> "This is some peculiarity of the RPM firmware on samsung-a5u". >>> >>> I don't have a DB410c available for testing, but I'm curious if it would >>> work correctly there. So far I have been unable to find any obvious >>> mistake in my changes. >>> >>> I'm attaching the full diff (including Loic's changes) in case someone >>> wants to test this on the DB410c (or some other MSM8916 device). >>> Basically you need to: >>> >>> 1. CONFIG_QCOM_RPMPD=y >>> CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y >>> 2. Run it and change CPU frequencies a bit >>> (either with an automatic CPU governor, or by setting speeds >>> manually with powersave/performance/userspace) >>> 3. There should be "set performance state" messages in dmesg >>> for the VDD_MX corner votes >>> 4. Identify the spmi l3 regulator using /sys/class/regulator/*/name >>> 5. Check the reported voltage in /sys/class/regulator/.../microvolts >>> >>> For me it stays on 1300000 uV, permanently. :( >>> >> >> I recently bought another device that does not have signature checks >> enabled. For now I have tested with the original firmware there: >> >> With or without my changes it stays at 1287500 uV permanently. >> At least this seems somewhat more realistic since this is the >> "super turbo" voltage. >> >> I tried disabling various things in case they affect this somehow: >> WCNSS in particular sets 1287500 uV for pm8916_l3. >> But even with WCNSS disabled, even with the regulator constraints >> removed for pm8916_l3 and all changes reverted - it keeps reporting >> 1287500 uV through the SPMI interface, no matter which CPU frequency >> is selected. >> >> This is even more confusing because l3 is still at nominal voltage >> (1150000 uV) in the lk bootloader. (I ported a part of the mainline >> spmi_regulator driver to lk so I can dump the voltages from there...) >> Somehow it gets changed when Linux is booted. Very confusing. >> >> Unlike on my previous test device, testing on downstream was successful: >> >> - CPU frequency 200MHz - 800MHz results into 1150000 uV >> reported as voltage for l3 through the SPMI interface (corner 4/5) >> - Higher CPU frequencies result into 1287500 uV (corner 7) >> >> Again I ported the spmi_regulator driver from mainline to downstream, >> so the way the voltage is read should be the same. >> >> Clearly something must be different/missing in my changes, >> but I still have no idea what exactly. >> Any suggestions would be highly appreciated :) >> > > After several hours of debugging I finally figured out what's wrong: > > I guess there are various dependencies on the VDD_CX/VDD_MX > voltage rails in the RPM: VDD_MX will be always higher than VDD_CX, > and VDD_CX is also influenced by some of the clocks. > > If I disable the rpmcc/clk-smd-rpm entirely in the device tree, > suddenly the VDD_MX voltage scales correctly with my changes. > > This seems to happen because the clk-smd-rpm forces all clocks to > maximum state in the clk_smd_rpm_handoff() function. In my case, > the clocks used for interconnect cause VDD_CX to scale to "super turbo", > which in turn keeps VDD_MX on "super turbo" as well. > > I imagine this will be solved properly once we enable the interconnect > driver and all the necessary consumers. > > But in general, I think this "handoff" behavior clk-smd-rpm is a bit > weird: As far as I understand, the clock framework normally disables > unused clocks shortly after the boot is complete. > > The clk-smd-rpm driver does the opposite: it forces all clocks to on, > to maximum rate and does not seem to report that to the clock framework. > If there is no consumer for the clock it seems to stay on and on maximum > frequency forever. > > For example, in order to avoid other remoteprocs influencing the > VDD_CX/VDD_MX voting I have disabled all additional remoteprocs in the > device tree (e.g. WCNSS, venus, ...) > > Before Linux is booted (dumped from the PMIC registers in the lk > bootloader), the rf_clk1/2 (modem/wcnss) is off. With clk-smd-rpm > disabled it stays off too. However, when clk-smd-rpm is loaded that > "handoff" function forces them on, and they're never turned off again. > > This is invisible to the clock framework - according to the clock > debugfs they are off. But reading the PMIC registers reveals they are on. > > I suppose that behavior makes sense for the interconnect clocks, > disabling those without an interconnect driver wouldn't do much good. > But for the other clocks that doesn't seem quite right to me. > > What do you think? I agree with you. Sending a clock frequency request from Linux side to the RPM processor would mean that the RPM will maintain the voltage needed for this frequency. We should not "handoff" all RPM clocks, but just the interconnect clocks (snoc, pnoc, bimc). Then, if there is an interconnect driver enabled for the platform, it will take care of scaling these. But from Linux side, we should not touch the other RPM clocks related to wifi, modem etc. Thanks, Georgi ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-04-23 4:55 ` Bjorn Andersson 2020-04-26 12:31 ` Stephan Gerhold @ 2020-05-25 15:32 ` Niklas Cassel 2020-05-25 16:36 ` Stephan Gerhold 1 sibling, 1 reply; 32+ messages in thread From: Niklas Cassel @ 2020-05-25 15:32 UTC (permalink / raw) To: Bjorn Andersson; +Cc: Stephan Gerhold, Loic Poulain, agross, linux-arm-msm On Wed, Apr 22, 2020 at 09:55:06PM -0700, Bjorn Andersson wrote: > > Based on the available downstream sources I guessed the defines to add > > for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as > > "required-opps" to the CPU OPP table so it would vote for the appopriate > > corners (with the mapping you mentioned above). > > > > I was not aware it was possible to describe the dependency between the > CPU opp table and MX in this fashion. If that's the case then this looks > really good and it should be straight forward to add MSM8916 support to > the CPR driver as well. > > > I haven't tested it yet, maybe I can get some feedback first if the code > > seems reasonable or if I'm missing something obvious? :) > > > > Have you tested this yet? > > > Also: Is there a good way to validate these changes? > > I suppose I could check the genpd state but that wouldn't tell me if the > > corner was applied correctly. Maybe I can check the actual voltage > > through the SPMI interface, hm... > > > > Validating that S2 and VDD_MX changes appropriately in Linux would be a > pretty good test. Like Bjorn says, Downstream CPR on MSM8916 controls 3 things; VDD_APC, VDD_MX and MEMACC. On QCS404 we don't have to adjust VDD_MX, therefore this is no code for this in the upstream CPR driver. It just scales VPP_APC and MEMACC. I like Stephan's idea of scaling VDD_APC and VDD_MEM to the maximum necessary for the selected CPU frequency, until there is full CPR support for MSM8916 (if ever). The patch suggested so far looks good, however, I'm slightly worried that this might lead to unstable boards, since MEMACC is never scaled in the suggested patch. Perhaps someone could ask Qualcomm nicely if this is really required. Last time I talked to a Qualcomm engineer, he claimed that it was needed, but I remember that his response was a bit ambiguous. Kind regards, Niklas ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-25 15:32 ` Niklas Cassel @ 2020-05-25 16:36 ` Stephan Gerhold 2020-05-25 19:44 ` Niklas Cassel 0 siblings, 1 reply; 32+ messages in thread From: Stephan Gerhold @ 2020-05-25 16:36 UTC (permalink / raw) To: Niklas Cassel; +Cc: Bjorn Andersson, Loic Poulain, agross, linux-arm-msm On Mon, May 25, 2020 at 05:32:47PM +0200, Niklas Cassel wrote: > On Wed, Apr 22, 2020 at 09:55:06PM -0700, Bjorn Andersson wrote: > > > Based on the available downstream sources I guessed the defines to add > > > for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as > > > "required-opps" to the CPU OPP table so it would vote for the appopriate > > > corners (with the mapping you mentioned above). > > > > > > > I was not aware it was possible to describe the dependency between the > > CPU opp table and MX in this fashion. If that's the case then this looks > > really good and it should be straight forward to add MSM8916 support to > > the CPR driver as well. > > > > > I haven't tested it yet, maybe I can get some feedback first if the code > > > seems reasonable or if I'm missing something obvious? :) > > > > > > > Have you tested this yet? > > > > > Also: Is there a good way to validate these changes? > > > I suppose I could check the genpd state but that wouldn't tell me if the > > > corner was applied correctly. Maybe I can check the actual voltage > > > through the SPMI interface, hm... > > > > > > > Validating that S2 and VDD_MX changes appropriately in Linux would be a > > pretty good test. > > Like Bjorn says, > > Downstream CPR on MSM8916 controls 3 things; VDD_APC, VDD_MX and MEMACC. > > On QCS404 we don't have to adjust VDD_MX, therefore this is no code for > this in the upstream CPR driver. It just scales VPP_APC and MEMACC. > > I like Stephan's idea of scaling VDD_APC and VDD_MEM to the maximum > necessary for the selected CPU frequency, until there is full CPR > support for MSM8916 (if ever). > > > The patch suggested so far looks good, however, I'm slightly worried > that this might lead to unstable boards, since MEMACC is never scaled > in the suggested patch. > Yeah, I was recently looking at that. I have no idea if it's needed. If I understand this correctly, on downstream this is implemented separately as "mem-acc-regulator", although it is controlled by the "cpr-regulator" driver. The mapping seems to be fairly static: Essentially it is just set to Nominal (1), SVS (2) or Turbo (3), depending on the CPU frequency. (On downstream this is specified in the device tree as qcom,cpr-corner-map = <1 1 2 2 3 3 3 3 3>; where each value is one CPU frequency.) Additionally there seem to be some fuses to eventually override that behavior slightly (qcom,override-corner-acc-map). See: https://source.codeaurora.org/quic/la/kernel/msm-3.10/tree/arch/arm/boot/dts/qcom/msm8916-regulator.dtsi?h=LA.BR.1.2.9.1-02310-8x16.0#n29 On mainline this is currently entirely handled by the CPR driver, and the register sequence for QCS404 actually looks a bit more complicated... Hmm. The reason I mention all this: At least as I understand it, this isn't much different from the VDD_MX scaling. Essentially it doesn't strictly have something to do with the voltage scaling we do for CPR (VDD_APC), but rather it seems to be just another requirement when scaling the CPU frequency. In other words, I wonder if we should separate this into yet another power domain driver, and then reference it independently from CPR as additional required-opps for both MSM8916 and QCS404. CPR would then be only responsible for the actual adaptive voltage scaling of VDD_APC. Does that make sense? Thanks, Stephan ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-25 16:36 ` Stephan Gerhold @ 2020-05-25 19:44 ` Niklas Cassel 2020-05-26 8:59 ` Stephan Gerhold 0 siblings, 1 reply; 32+ messages in thread From: Niklas Cassel @ 2020-05-25 19:44 UTC (permalink / raw) To: Stephan Gerhold; +Cc: Bjorn Andersson, Loic Poulain, agross, linux-arm-msm On Mon, May 25, 2020 at 06:36:38PM +0200, Stephan Gerhold wrote: > On Mon, May 25, 2020 at 05:32:47PM +0200, Niklas Cassel wrote: > > On Wed, Apr 22, 2020 at 09:55:06PM -0700, Bjorn Andersson wrote: > > > > Based on the available downstream sources I guessed the defines to add > > > > for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as > > > > "required-opps" to the CPU OPP table so it would vote for the appopriate > > > > corners (with the mapping you mentioned above). > > > > > > > > > > I was not aware it was possible to describe the dependency between the > > > CPU opp table and MX in this fashion. If that's the case then this looks > > > really good and it should be straight forward to add MSM8916 support to > > > the CPR driver as well. > > > > > > > I haven't tested it yet, maybe I can get some feedback first if the code > > > > seems reasonable or if I'm missing something obvious? :) > > > > > > > > > > Have you tested this yet? > > > > > > > Also: Is there a good way to validate these changes? > > > > I suppose I could check the genpd state but that wouldn't tell me if the > > > > corner was applied correctly. Maybe I can check the actual voltage > > > > through the SPMI interface, hm... > > > > > > > > > > Validating that S2 and VDD_MX changes appropriately in Linux would be a > > > pretty good test. > > > > Like Bjorn says, > > > > Downstream CPR on MSM8916 controls 3 things; VDD_APC, VDD_MX and MEMACC. > > > > On QCS404 we don't have to adjust VDD_MX, therefore this is no code for > > this in the upstream CPR driver. It just scales VPP_APC and MEMACC. > > > > I like Stephan's idea of scaling VDD_APC and VDD_MEM to the maximum > > necessary for the selected CPU frequency, until there is full CPR > > support for MSM8916 (if ever). > > > > > > The patch suggested so far looks good, however, I'm slightly worried > > that this might lead to unstable boards, since MEMACC is never scaled > > in the suggested patch. > > > > Yeah, I was recently looking at that. I have no idea if it's needed. > > If I understand this correctly, on downstream this is implemented > separately as "mem-acc-regulator", although it is controlled by the > "cpr-regulator" driver. > > The mapping seems to be fairly static: > Essentially it is just set to Nominal (1), SVS (2) or Turbo (3), > depending on the CPU frequency. (On downstream this is specified in the > device tree as qcom,cpr-corner-map = <1 1 2 2 3 3 3 3 3>; where each > value is one CPU frequency.) > > Additionally there seem to be some fuses to eventually override > that behavior slightly (qcom,override-corner-acc-map). > See: https://source.codeaurora.org/quic/la/kernel/msm-3.10/tree/arch/arm/boot/dts/qcom/msm8916-regulator.dtsi?h=LA.BR.1.2.9.1-02310-8x16.0#n29 > > On mainline this is currently entirely handled by the CPR driver, > and the register sequence for QCS404 actually looks a bit more > complicated... Hmm. I agree: https://source.codeaurora.org/quic/la/kernel/msm-4.14/tree/arch/arm64/boot/dts/qcom/qcs405-regulator.dtsi?h=msm-4.14#n294 > > The reason I mention all this: At least as I understand it, > this isn't much different from the VDD_MX scaling. Essentially it > doesn't strictly have something to do with the voltage scaling > we do for CPR (VDD_APC), but rather it seems to be just another > requirement when scaling the CPU frequency. I agree. > > In other words, I wonder if we should separate this into yet another > power domain driver, and then reference it independently from CPR > as additional required-opps for both MSM8916 and QCS404. While this sounds very nice, by simply referencing these as required-opps, I don't see how the OPP library will be able to set APC, MX and MEMACC in the correct order: https://source.codeaurora.org/quic/la/kernel/msm-4.14/tree/drivers/regulator/cpr-regulator.c?h=msm-4.14#n774 If scaling down, first MEMACC is set, then APC is set, then MX is set. If scaling up, first MX is set, then APC is set, then MEMACC is set. Perhaps the easiest way is to write a minimalistic cpufreq driver, very similar to drivers/cpufreq/omap-cpufreq.c, that implements the .target_index callback, and just like omap_target(), simply gets the OPP using dev_pm_opp_find_freq_ceil(), and then calls regulator_set_voltage() (APC), clk_set_rate() (to change the clock frequency), dev_pm_genpd_set_performance_state() (to set MX), and then do that little code that needs to be done for memacc. Considering that CPR is not an actual power domain, CPR gives adjustments to VDD_APC, but I don't know of any other device connected to VDD_APC, other than the CPU, so in hindsight the CPR driver probably should have been implemented using .target_index(), rather than as a power domain provider using performance states. Kind regards, Niklas ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-25 19:44 ` Niklas Cassel @ 2020-05-26 8:59 ` Stephan Gerhold 2020-05-26 15:54 ` Niklas Cassel 0 siblings, 1 reply; 32+ messages in thread From: Stephan Gerhold @ 2020-05-26 8:59 UTC (permalink / raw) To: Niklas Cassel; +Cc: Bjorn Andersson, Loic Poulain, agross, linux-arm-msm On Mon, May 25, 2020 at 09:44:43PM +0200, Niklas Cassel wrote: > On Mon, May 25, 2020 at 06:36:38PM +0200, Stephan Gerhold wrote: > > On Mon, May 25, 2020 at 05:32:47PM +0200, Niklas Cassel wrote: > > > On Wed, Apr 22, 2020 at 09:55:06PM -0700, Bjorn Andersson wrote: > > > > > Based on the available downstream sources I guessed the defines to add > > > > > for MSM8916 to the rpmpd driver. Then I added the VDD_MX OPPs as > > > > > "required-opps" to the CPU OPP table so it would vote for the appopriate > > > > > corners (with the mapping you mentioned above). > > > > > > > > > > > > > I was not aware it was possible to describe the dependency between the > > > > CPU opp table and MX in this fashion. If that's the case then this looks > > > > really good and it should be straight forward to add MSM8916 support to > > > > the CPR driver as well. > > > > > > > > > I haven't tested it yet, maybe I can get some feedback first if the code > > > > > seems reasonable or if I'm missing something obvious? :) > > > > > > > > > > > > > Have you tested this yet? > > > > > > > > > Also: Is there a good way to validate these changes? > > > > > I suppose I could check the genpd state but that wouldn't tell me if the > > > > > corner was applied correctly. Maybe I can check the actual voltage > > > > > through the SPMI interface, hm... > > > > > > > > > > > > > Validating that S2 and VDD_MX changes appropriately in Linux would be a > > > > pretty good test. > > > > > > Like Bjorn says, > > > > > > Downstream CPR on MSM8916 controls 3 things; VDD_APC, VDD_MX and MEMACC. > > > > > > On QCS404 we don't have to adjust VDD_MX, therefore this is no code for > > > this in the upstream CPR driver. It just scales VPP_APC and MEMACC. > > > > > > I like Stephan's idea of scaling VDD_APC and VDD_MEM to the maximum > > > necessary for the selected CPU frequency, until there is full CPR > > > support for MSM8916 (if ever). > > > > > > > > > The patch suggested so far looks good, however, I'm slightly worried > > > that this might lead to unstable boards, since MEMACC is never scaled > > > in the suggested patch. > > > > > > > Yeah, I was recently looking at that. I have no idea if it's needed. > > > > If I understand this correctly, on downstream this is implemented > > separately as "mem-acc-regulator", although it is controlled by the > > "cpr-regulator" driver. > > > > The mapping seems to be fairly static: > > Essentially it is just set to Nominal (1), SVS (2) or Turbo (3), > > depending on the CPU frequency. (On downstream this is specified in the > > device tree as qcom,cpr-corner-map = <1 1 2 2 3 3 3 3 3>; where each > > value is one CPU frequency.) > > > > Additionally there seem to be some fuses to eventually override > > that behavior slightly (qcom,override-corner-acc-map). > > See: https://source.codeaurora.org/quic/la/kernel/msm-3.10/tree/arch/arm/boot/dts/qcom/msm8916-regulator.dtsi?h=LA.BR.1.2.9.1-02310-8x16.0#n29 > > > > On mainline this is currently entirely handled by the CPR driver, > > and the register sequence for QCS404 actually looks a bit more > > complicated... Hmm. > > I agree: > https://source.codeaurora.org/quic/la/kernel/msm-4.14/tree/arch/arm64/boot/dts/qcom/qcs405-regulator.dtsi?h=msm-4.14#n294 > > > > > The reason I mention all this: At least as I understand it, > > this isn't much different from the VDD_MX scaling. Essentially it > > doesn't strictly have something to do with the voltage scaling > > we do for CPR (VDD_APC), but rather it seems to be just another > > requirement when scaling the CPU frequency. > > I agree. > > > > > In other words, I wonder if we should separate this into yet another > > power domain driver, and then reference it independently from CPR > > as additional required-opps for both MSM8916 and QCS404. > > While this sounds very nice, by simply referencing these as > required-opps, I don't see how the OPP library will be able > to set APC, MX and MEMACC in the correct order: > > https://source.codeaurora.org/quic/la/kernel/msm-4.14/tree/drivers/regulator/cpr-regulator.c?h=msm-4.14#n774 > > If scaling down, first MEMACC is set, then APC is set, then MX is set. > > If scaling up, first MX is set, then APC is set, then MEMACC is set. > Indeed, I was also thinking about this. In general, I'm not sure if this is that much of a problem for the following reason: The OPP core code already has well-defined semantics to ensure required OPPs/regulators are set before/after the frequency change, depending on if we scale up or down, see e.g. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/opp/core.c#n885 If you specify multiple "required-opps" I think in general the order will be either irrelevant, or you want to do them in a particular order for some reason. If you want to do them in a particular order, then likely because there is some dependency between them, i.e. here we could say (to some extent) MEMACC depends on APC, which again depends on MX. If there is such a dependency I think you almost certainly want to apply required OPPs in reverse order when scaling down. I wonder if we could just implement these semantics in the OPP core. It should be pretty simple, just add a boolean parameter to the _set_required_opps() function (that says if we're scaling down) and then iterate over the required OPPs in reverse order. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/opp/core.c#n745 This would result in the correct order iff CPR is used, because you could set required-opps = <&mx_opp &cpr_opp &mem_acc_opp>; When scaling up you would get MX -> CPR (APC) -> MEMACC, when scaling down the reverse MEMACC -> CPR (APC) -> MX. This would not result in the correct order if we use opp-microvolts to scale VDD_APC. The regulator is handled separately, so you would get MX -> MEMACC -> APC, APC -> MEMACC -> MX instead. Oh well. > > Perhaps the easiest way is to write a minimalistic cpufreq driver, > very similar to drivers/cpufreq/omap-cpufreq.c, that implements > the .target_index callback, and just like omap_target(), simply > gets the OPP using dev_pm_opp_find_freq_ceil(), and then calls > regulator_set_voltage() (APC), clk_set_rate() (to change the clock > frequency), dev_pm_genpd_set_performance_state() (to set MX), > and then do that little code that needs to be done for memacc. > I general I like the way these "requirements" for switching to a particular CPU frequency can be described fully from the device tree. The omap-cpufreq code definitely has some duplication with the code I have seen in the OPP core. But yes, a generic approach like the "required-opps" can only work up to some extent - if we have too many requirements for particular order etc a custom cpufreq driver would have probably been easier. > Considering that CPR is not an actual power domain, CPR gives > adjustments to VDD_APC, but I don't know of any other device > connected to VDD_APC, other than the CPU, so in hindsight the CPR > driver probably should have been implemented using .target_index(), > rather than as a power domain provider using performance states. I suppose having CPR, MEMACC etc as power domain providers is a bit overkill, given there is just one consumer. However, at least the "performance state" part fits quite well in my opinion. At the end all these requirements represent some performance state that must be set when the CPU frequency is changed. Stephan ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-26 8:59 ` Stephan Gerhold @ 2020-05-26 15:54 ` Niklas Cassel 2020-05-26 20:54 ` Stephan Gerhold 0 siblings, 1 reply; 32+ messages in thread From: Niklas Cassel @ 2020-05-26 15:54 UTC (permalink / raw) To: Stephan Gerhold; +Cc: Bjorn Andersson, Loic Poulain, agross, linux-arm-msm On Tue, May 26, 2020 at 10:59:48AM +0200, Stephan Gerhold wrote: > > Considering that CPR is not an actual power domain, CPR gives > > adjustments to VDD_APC, but I don't know of any other device > > connected to VDD_APC, other than the CPU, so in hindsight the CPR > > driver probably should have been implemented using .target_index(), > > rather than as a power domain provider using performance states. > > I suppose having CPR, MEMACC etc as power domain providers is a bit > overkill, given there is just one consumer. However, at least the > "performance state" part fits quite well in my opinion. At the end > all these requirements represent some performance state that must be > set when the CPU frequency is changed. > For MX, it makes sense to model it as a power domain provider, and for it to have its own OPP table, since this actually is a power domain. For CPR, I think that the target_index() model of just giving an index in a frequency table is much better, the OPP library can still be used to get the frequencies/frequency_table. Since at least for Qualcom CPU's, the corner (opp-level) is defined as an increasing number 1,2,3,4, without skips. Even if it wasn't always without skips, we could just put opp-level in the CPU opp table, and get it from there. The only thing that the corner is used for really, is to use it as an index the local drv->corner array, which is where the (current) VDD_APC voltage is stored for each index/corner. For CPR, the .target_index() in cpufreq-dt.c gets called, which is supplied with an index, but the index gets converted to a frequency. This frequency is then sent to the OPP library, and is then converted back to an index of the same value (just increased by one), before cpr_set_performance_state() is called (which then has to subtract one). In this case, all the extra overhead of going via genpd is totally unnecessary. This is totally correct when setting a performance state on a power domain like MX, since for an actual power domain you might have multiple consumers, so you need to go via genpd. Considering that CPR is not a power domain, I wish the driver wasn't designed around performance states, which, _for the CPR case_, is misleading, unnecessary, and adds extra overhead for no reason. I realize the irony of me criticizing my own code. I simply know better now, and wish I had designed it differently :) Kind regards, Niklas ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-26 15:54 ` Niklas Cassel @ 2020-05-26 20:54 ` Stephan Gerhold 2020-05-27 10:39 ` Niklas Cassel 0 siblings, 1 reply; 32+ messages in thread From: Stephan Gerhold @ 2020-05-26 20:54 UTC (permalink / raw) To: Niklas Cassel; +Cc: Bjorn Andersson, Loic Poulain, agross, linux-arm-msm On Tue, May 26, 2020 at 05:54:20PM +0200, Niklas Cassel wrote: > On Tue, May 26, 2020 at 10:59:48AM +0200, Stephan Gerhold wrote: > > > Considering that CPR is not an actual power domain, CPR gives > > > adjustments to VDD_APC, but I don't know of any other device > > > connected to VDD_APC, other than the CPU, so in hindsight the CPR > > > driver probably should have been implemented using .target_index(), > > > rather than as a power domain provider using performance states. > > > > I suppose having CPR, MEMACC etc as power domain providers is a bit > > overkill, given there is just one consumer. However, at least the > > "performance state" part fits quite well in my opinion. At the end > > all these requirements represent some performance state that must be > > set when the CPU frequency is changed. > > > > For MX, it makes sense to model it as a power domain provider, and for > it to have its own OPP table, since this actually is a power domain. > > For CPR, I think that the target_index() model of just giving an index > in a frequency table is much better, the OPP library can still be used > to get the frequencies/frequency_table. > Since at least for Qualcom CPU's, the corner (opp-level) is defined as > an increasing number 1,2,3,4, without skips. > > Even if it wasn't always without skips, we could just put opp-level in > the CPU opp table, and get it from there. > > The only thing that the corner is used for really, is to use it as an > index the local drv->corner array, which is where the (current) VDD_APC > voltage is stored for each index/corner. > > For CPR, the .target_index() in cpufreq-dt.c gets called, which is > supplied with an index, but the index gets converted to a frequency. > This frequency is then sent to the OPP library, and is then converted > back to an index of the same value (just increased by one), before > cpr_set_performance_state() is called (which then has to subtract one). > In this case, all the extra overhead of going via genpd is totally > unnecessary. > > This is totally correct when setting a performance state on a power > domain like MX, since for an actual power domain you might have > multiple consumers, so you need to go via genpd. > > Considering that CPR is not a power domain, I wish the driver wasn't > designed around performance states, which, _for the CPR case_, > is misleading, unnecessary, and adds extra overhead for no reason. > > I realize the irony of me criticizing my own code. > I simply know better now, and wish I had designed it differently :) > I see what you mean. I'm not sure how much of a problem the "genpd overhead" really is in practice (although I assume it's called quite frequently with a dynamic CPU frequency governor). There is also the argument of it being slightly misleading (because CPR is not actually a real power domain). Speaking of the current solution, I also have to say that (IMO) the device tree binding for "required-opps" is rather confusing and potentially misleading. e.g. for VDD_MX scaling I use required-opps = <&rpmpd_opp_nom>; but looking at just the OPP table absolutely nothing tells me this is supposed to apply to VDD_MX. You actually need to go search for the cpu@ device tree node and then know that some of the power domains there (in some order) are eventually going to be used for the required-opps there. The order is only defined by the qcom-nvmem-cpufreq driver. It took me a few hours to get that right... :) Nevertheless I guess we need a solution for scaling MEMACC without CPR for now. :) I'm not sure if rewriting all this is very realistic (if even possible). So I guess we might be stuck with the genpd approach? Thanks, Stephan ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-26 20:54 ` Stephan Gerhold @ 2020-05-27 10:39 ` Niklas Cassel 2020-05-27 12:04 ` Stephan Gerhold 0 siblings, 1 reply; 32+ messages in thread From: Niklas Cassel @ 2020-05-27 10:39 UTC (permalink / raw) To: Stephan Gerhold; +Cc: Bjorn Andersson, Loic Poulain, agross, linux-arm-msm On Tue, May 26, 2020 at 10:54:03PM +0200, Stephan Gerhold wrote: > Speaking of the current solution, I also have to say that (IMO) the > device tree binding for "required-opps" is rather confusing > and potentially misleading. > > e.g. for VDD_MX scaling I use > > required-opps = <&rpmpd_opp_nom>; > > but looking at just the OPP table absolutely nothing tells me this is > supposed to apply to VDD_MX. You actually need to go search for the cpu@ > device tree node and then know that some of the power domains there > (in some order) are eventually going to be used for the required-opps > there. The order is only defined by the qcom-nvmem-cpufreq driver. > > It took me a few hours to get that right... :) > > Nevertheless I guess we need a solution for scaling MEMACC without CPR > for now. :) I'm not sure if rewriting all this is very realistic > (if even possible). So I guess we might be stuck with the genpd approach? I agree, the CPR driver will most likely not be changed now, since we need to be compatible with the existing device tree. For DVFS without CPR: You need to scale APC, MX, MEMACC. If we don't care about MEMACC, then the existing code in the OPP library satisfies all our needs. The problem here is if we need to do MEMACC as well. I don't think it is proper to implement MEMACC as a power domain (because it is not). Thus, we can't add it as a required-opp. Another problem is that MEMACC should be done after regulator_set_voltage() when scaling up, and before regulator_set_voltage() when scaling down. So even if MEMACC was a power domain, currently the OPP library does the _set_required_opps() call in the wrong order needed for MEMACC. Like you said, the OPP library almost does everything already, so it probably makes most sense to extend it to your needs, rather than duplicating most of the code inside dev_pm_opp_set_rate(). I guess what you really want is two new optional callbacks in dev_pm_opp_set_rate(), one before _generic_set_opp_regulator() and one after, where you could do the MEMACC thing. The callbacks need to have a parameter that tells if we are scaling down or up. Or, if Viresh doesn't like new function pointers, create a new OPP_EVENT_* that you can register for, and in that callback you do what you need. Or, maybe you can even use the existing CPUFREQ_TRANSITION_NOTIFIER, with CPUFREQ_PRECHANGE / CPUFREQ_POSTCHANGE, however, I'm not sure how nicely they play when you are using the OPP library. Kind regards, Niklas ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-27 10:39 ` Niklas Cassel @ 2020-05-27 12:04 ` Stephan Gerhold 2020-05-27 12:59 ` Niklas Cassel 2020-05-28 4:44 ` Viresh Kumar 0 siblings, 2 replies; 32+ messages in thread From: Stephan Gerhold @ 2020-05-27 12:04 UTC (permalink / raw) To: Niklas Cassel Cc: Bjorn Andersson, Loic Poulain, agross, linux-arm-msm, Viresh Kumar +Cc Viresh (should have already done this earlier :) ) On Wed, May 27, 2020 at 12:39:21PM +0200, Niklas Cassel wrote: > On Tue, May 26, 2020 at 10:54:03PM +0200, Stephan Gerhold wrote: > > Speaking of the current solution, I also have to say that (IMO) the > > device tree binding for "required-opps" is rather confusing > > and potentially misleading. > > > > e.g. for VDD_MX scaling I use > > > > required-opps = <&rpmpd_opp_nom>; > > > > but looking at just the OPP table absolutely nothing tells me this is > > supposed to apply to VDD_MX. You actually need to go search for the cpu@ > > device tree node and then know that some of the power domains there > > (in some order) are eventually going to be used for the required-opps > > there. The order is only defined by the qcom-nvmem-cpufreq driver. > > > > It took me a few hours to get that right... :) > > > > Nevertheless I guess we need a solution for scaling MEMACC without CPR > > for now. :) I'm not sure if rewriting all this is very realistic > > (if even possible). So I guess we might be stuck with the genpd approach? > > I agree, the CPR driver will most likely not be changed now, since we > need to be compatible with the existing device tree. > > > For DVFS without CPR: > > You need to scale APC, MX, MEMACC. > > If we don't care about MEMACC, then the existing code in the OPP library > satisfies all our needs. > The problem here is if we need to do MEMACC as well. > > I don't think it is proper to implement MEMACC as a power domain > (because it is not). Thus, we can't add it as a required-opp. > > Another problem is that MEMACC should be done after regulator_set_voltage() > when scaling up, and before regulator_set_voltage() when scaling down. > > So even if MEMACC was a power domain, currently the OPP library does > the _set_required_opps() call in the wrong order needed for MEMACC. > > Like you said, the OPP library almost does everything already, > so it probably makes most sense to extend it to your needs, > rather than duplicating most of the code inside dev_pm_opp_set_rate(). > > > I guess what you really want is two new optional callbacks in > dev_pm_opp_set_rate(), one before _generic_set_opp_regulator() and one > after, where you could do the MEMACC thing. > > The callbacks need to have a parameter that tells if we are scaling down > or up. > > Or, if Viresh doesn't like new function pointers, create a new > OPP_EVENT_* that you can register for, and in that callback you do what > you need. > > Or, maybe you can even use the existing CPUFREQ_TRANSITION_NOTIFIER, > with CPUFREQ_PRECHANGE / CPUFREQ_POSTCHANGE, however, I'm not sure > how nicely they play when you are using the OPP library. > I'm not sure. Overall all of this doesn't really sound like it is going to make all this easier to understand (from looking at the device tree). We then have required-opps for VDD_MX, and CPR (which isn't really a power domain), and something entirely different for MEMACC (which like CPR, isn't really a power domain). I don't know, right now this mixture of different approaches sounds rather complicated (and confusing) to me... Just to throw another idea in the room: there seems to be a set_opp() callback already in the OPP table, which bypasses the code that updates clock and regulators (see ti-opp-supply.c). Actually if I'm reading this correctly ti-opp-supply seems to implement adaptive voltage scaling similar to CPR with it. Seemingly we have two different solutions for the same concept now: - CPR implements a power domain provider (even though it's not really a power domain since it has only one consumer) - ti-opp-supply implements this with the set_opp() callback In general I think this looks pretty nice - we don't duplicate the full cpufreq driver, but have control about the order regulators/clocks/power domains etc are changed. I think something like this would fit quite well for my case (scaling MX, APC and MEMACC without CPR). However, not sure how it would integrate with the existing CPR driver at some point. Adding Viresh to Cc in case he has some opinion for all this. Thanks, Stephan ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-27 12:04 ` Stephan Gerhold @ 2020-05-27 12:59 ` Niklas Cassel 2020-05-27 20:56 ` Stephan Gerhold 2020-05-28 4:44 ` Viresh Kumar 1 sibling, 1 reply; 32+ messages in thread From: Niklas Cassel @ 2020-05-27 12:59 UTC (permalink / raw) To: Stephan Gerhold Cc: Bjorn Andersson, Loic Poulain, agross, linux-arm-msm, Viresh Kumar On Wed, May 27, 2020 at 02:04:52PM +0200, Stephan Gerhold wrote: > > I guess what you really want is two new optional callbacks in > > dev_pm_opp_set_rate(), one before _generic_set_opp_regulator() and one > > after, where you could do the MEMACC thing. > > > > The callbacks need to have a parameter that tells if we are scaling down > > or up. > > > > Or, if Viresh doesn't like new function pointers, create a new > > OPP_EVENT_* that you can register for, and in that callback you do what > > you need. > > > > Or, maybe you can even use the existing CPUFREQ_TRANSITION_NOTIFIER, > > with CPUFREQ_PRECHANGE / CPUFREQ_POSTCHANGE, however, I'm not sure > > how nicely they play when you are using the OPP library. > > > > I'm not sure. Overall all of this doesn't really sound like it is going > to make all this easier to understand (from looking at the device tree). > We then have required-opps for VDD_MX, and CPR (which isn't really a > power domain), and something entirely different for MEMACC (which like > CPR, isn't really a power domain). > > I don't know, right now this mixture of different approaches sounds > rather complicated (and confusing) to me... You are going to need performance states where it is needed, e.g. for controlling MX (as it is a power domain). For performance states, you using the required-opps DT property. My 50 cents is just to not use it for something that is not a power domain, e.g. MEMACC. > > Just to throw another idea in the room: there seems to be a set_opp() > callback already in the OPP table, which bypasses the code that > updates clock and regulators (see ti-opp-supply.c). Actually if I'm > reading this correctly ti-opp-supply seems to implement adaptive voltage > scaling similar to CPR with it. Seemingly we have two different solutions > for the same concept now: > > - CPR implements a power domain provider (even though it's not really > a power domain since it has only one consumer) > - ti-opp-supply implements this with the set_opp() callback Yes, and there are more ways to implement AVS, see e.g. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=25cb20a212a1f989385dfe23230817e69c62bee5 Which probably would have been a better fit for CPR, if it were to be designed today. > > In general I think this looks pretty nice - we don't duplicate the full > cpufreq driver, but have control about the order > regulators/clocks/power domains etc are changed. > > I think something like this would fit quite well for my case > (scaling MX, APC and MEMACC without CPR). However, not sure how it would > integrate with the existing CPR driver at some point. You care about how to do DVFS without AVS (CPR). Why do you worry about how it will look when, if ever, you transition to full AVS (CPR)? If the CPR driver is not changed, which I doubt, you will simply change the device tree to remove the cpu-supply regulator and move it into the new CPR DT node. Old device trees will still use your DVFS solution, new device trees will use the CPR DT node and will use the AVS solution. Kind regards, Niklas ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-27 12:59 ` Niklas Cassel @ 2020-05-27 20:56 ` Stephan Gerhold 2020-05-27 23:10 ` Niklas Cassel 0 siblings, 1 reply; 32+ messages in thread From: Stephan Gerhold @ 2020-05-27 20:56 UTC (permalink / raw) To: Niklas Cassel Cc: Bjorn Andersson, Loic Poulain, agross, linux-arm-msm, Viresh Kumar On Wed, May 27, 2020 at 02:59:19PM +0200, Niklas Cassel wrote: > On Wed, May 27, 2020 at 02:04:52PM +0200, Stephan Gerhold wrote: > > > I guess what you really want is two new optional callbacks in > > > dev_pm_opp_set_rate(), one before _generic_set_opp_regulator() and one > > > after, where you could do the MEMACC thing. > > > > > > The callbacks need to have a parameter that tells if we are scaling down > > > or up. > > > > > > Or, if Viresh doesn't like new function pointers, create a new > > > OPP_EVENT_* that you can register for, and in that callback you do what > > > you need. > > > > > > Or, maybe you can even use the existing CPUFREQ_TRANSITION_NOTIFIER, > > > with CPUFREQ_PRECHANGE / CPUFREQ_POSTCHANGE, however, I'm not sure > > > how nicely they play when you are using the OPP library. > > > > > > > I'm not sure. Overall all of this doesn't really sound like it is going > > to make all this easier to understand (from looking at the device tree). > > We then have required-opps for VDD_MX, and CPR (which isn't really a > > power domain), and something entirely different for MEMACC (which like > > CPR, isn't really a power domain). > > > > I don't know, right now this mixture of different approaches sounds > > rather complicated (and confusing) to me... > > You are going to need performance states where it is needed, > e.g. for controlling MX (as it is a power domain). > For performance states, you using the required-opps DT property. > > My 50 cents is just to not use it for something that is not > a power domain, e.g. MEMACC. > I agree. > > > > Just to throw another idea in the room: there seems to be a set_opp() > > callback already in the OPP table, which bypasses the code that > > updates clock and regulators (see ti-opp-supply.c). Actually if I'm > > reading this correctly ti-opp-supply seems to implement adaptive voltage > > scaling similar to CPR with it. Seemingly we have two different solutions > > for the same concept now: > > > > - CPR implements a power domain provider (even though it's not really > > a power domain since it has only one consumer) > > - ti-opp-supply implements this with the set_opp() callback > > Yes, and there are more ways to implement AVS, see e.g. > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=25cb20a212a1f989385dfe23230817e69c62bee5 > > Which probably would have been a better fit for CPR, > if it were to be designed today. > Would this actually work if you update the voltage of the current OPP? Looking at the qcom-cpr code the voltage is dynamically changed when receiving IRQs. I would say with that function you can only change the voltage when switching to that OPP the next time. Maybe I'm wrong though. Otherwise that's pretty nice, because the setup is very similar with or without CPR (since the regulator is still managed by the OPP core). > > > > In general I think this looks pretty nice - we don't duplicate the full > > cpufreq driver, but have control about the order > > regulators/clocks/power domains etc are changed. > > > > I think something like this would fit quite well for my case > > (scaling MX, APC and MEMACC without CPR). However, not sure how it would > > integrate with the existing CPR driver at some point. > > You care about how to do DVFS without AVS (CPR). > > Why do you worry about how it will look when, if ever, > you transition to full AVS (CPR)? > I mean, CPR is arguably the better solution on long term. I doubt it will be me who will enable it for MSM8916 (mainly for lack of understanding of the whole scaling formulas etc), but IMO it would be worth to at least consider how to switch in the future. > If the CPR driver is not changed, which I doubt, you will simply change > the device tree to remove the cpu-supply regulator and move it into the > new CPR DT node. > > Old device trees will still use your DVFS solution, new device > trees will use the CPR DT node and will use the AVS solution. > I think my concern is essentially that I would duplicate the MEMACC code into a new driver utilizing .set_opp() - and to keep backwards compatibility we would need to keep that duplication forever. The MEMACC scaling isn't all that complicated, but overall I would prefer to avoid introducing duplication in the first place. Also: If full CPR ever happens we would be basically back to one part of the current discussion: specifying two "required-opps" MX and CPR (= APC + MEMACC) would result in the wrong order when scaling up/down. But maybe I just worry too much? Thanks, Stephan ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-27 20:56 ` Stephan Gerhold @ 2020-05-27 23:10 ` Niklas Cassel 2020-05-28 13:32 ` Stephan Gerhold 0 siblings, 1 reply; 32+ messages in thread From: Niklas Cassel @ 2020-05-27 23:10 UTC (permalink / raw) To: Stephan Gerhold Cc: Bjorn Andersson, Loic Poulain, agross, linux-arm-msm, Viresh Kumar On Wed, May 27, 2020 at 10:56:07PM +0200, Stephan Gerhold wrote: > > If the CPR driver is not changed, which I doubt, you will simply change > > the device tree to remove the cpu-supply regulator and move it into the > > new CPR DT node. > > > > Old device trees will still use your DVFS solution, new device > > trees will use the CPR DT node and will use the AVS solution. > > > > I think my concern is essentially that I would duplicate the MEMACC code > into a new driver utilizing .set_opp() - and to keep backwards > compatibility we would need to keep that duplication forever. The cleanest solution is probably to create a new memacc platform device driver, and make the new code use that, and refactor CPR to use the same. > > The MEMACC scaling isn't all that complicated, but overall I would > prefer to avoid introducing duplication in the first place. > > Also: If full CPR ever happens we would be basically back > to one part of the current discussion: specifying two "required-opps" > MX and CPR (= APC + MEMACC) would result in the wrong order > when scaling up/down. > > But maybe I just worry too much? I guess that whoever implements CPR on msm8916 will either call dev_pm_genpd_set_performance_state() on MX directly from cpr_scale_voltage() or perhaps change OPP core so that it runs the required-opps in reverse order when scaling down, like you previously suggested. Please don't take my suggestions as the only way forward though. Hopefully I provided more clarity than confusion. Will step back so that someone else has a chance to chime in :) Kind regards, Niklas ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-27 23:10 ` Niklas Cassel @ 2020-05-28 13:32 ` Stephan Gerhold 0 siblings, 0 replies; 32+ messages in thread From: Stephan Gerhold @ 2020-05-28 13:32 UTC (permalink / raw) To: Niklas Cassel Cc: Bjorn Andersson, Loic Poulain, agross, linux-arm-msm, Viresh Kumar On Thu, May 28, 2020 at 01:10:25AM +0200, Niklas Cassel wrote: > On Wed, May 27, 2020 at 10:56:07PM +0200, Stephan Gerhold wrote: > > > If the CPR driver is not changed, which I doubt, you will simply change > > > the device tree to remove the cpu-supply regulator and move it into the > > > new CPR DT node. > > > > > > Old device trees will still use your DVFS solution, new device > > > trees will use the CPR DT node and will use the AVS solution. > > > > > > > I think my concern is essentially that I would duplicate the MEMACC code > > into a new driver utilizing .set_opp() - and to keep backwards > > compatibility we would need to keep that duplication forever. > > The cleanest solution is probably to create a new memacc platform device > driver, and make the new code use that, and refactor CPR to use the same. > I will try to come up with something like that, thank you! > > > > The MEMACC scaling isn't all that complicated, but overall I would > > prefer to avoid introducing duplication in the first place. > > > > Also: If full CPR ever happens we would be basically back > > to one part of the current discussion: specifying two "required-opps" > > MX and CPR (= APC + MEMACC) would result in the wrong order > > when scaling up/down. > > > > But maybe I just worry too much? > > I guess that whoever implements CPR on msm8916 will either call > dev_pm_genpd_set_performance_state() on MX directly from cpr_scale_voltage() > or perhaps change OPP core so that it runs the required-opps in reverse > order when scaling down, like you previously suggested. > > Please don't take my suggestions as the only way forward though. > Hopefully I provided more clarity than confusion. > Will step back so that someone else has a chance to chime in :) I'm a bit confused at the moment, but it's mainly because we discussed so many different options. I will need some time to properly look at all of them and come up with a potential solution. Thanks for taking the time to answer all my questions! :) Stephan ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-05-27 12:04 ` Stephan Gerhold 2020-05-27 12:59 ` Niklas Cassel @ 2020-05-28 4:44 ` Viresh Kumar 1 sibling, 0 replies; 32+ messages in thread From: Viresh Kumar @ 2020-05-28 4:44 UTC (permalink / raw) To: Stephan Gerhold Cc: Niklas Cassel, Bjorn Andersson, Loic Poulain, agross, linux-arm-msm, Viresh Kumar On 27-05-20, 14:04, Stephan Gerhold wrote: > +Cc Viresh (should have already done this earlier :) ) > > On Wed, May 27, 2020 at 12:39:21PM +0200, Niklas Cassel wrote: > > On Tue, May 26, 2020 at 10:54:03PM +0200, Stephan Gerhold wrote: > > > Speaking of the current solution, I also have to say that (IMO) the > > > device tree binding for "required-opps" is rather confusing > > > and potentially misleading. > > > > > > e.g. for VDD_MX scaling I use > > > > > > required-opps = <&rpmpd_opp_nom>; > > > > > > but looking at just the OPP table absolutely nothing tells me this is > > > supposed to apply to VDD_MX. You actually need to go search for the cpu@ > > > device tree node and then know that some of the power domains there > > > (in some order) are eventually going to be used for the required-opps > > > there. The order is only defined by the qcom-nvmem-cpufreq driver. > > > > > > It took me a few hours to get that right... :) I agree, we need a way to figure out devices as well for which the required-opp works. And yes that's missing. > > > Nevertheless I guess we need a solution for scaling MEMACC without CPR > > > for now. :) I'm not sure if rewriting all this is very realistic > > > (if even possible). So I guess we might be stuck with the genpd approach? > > > > I agree, the CPR driver will most likely not be changed now, since we > > need to be compatible with the existing device tree. A driver can be changed as much as you want, just that you need to honor both new and old DTs. > > > > For DVFS without CPR: > > > > You need to scale APC, MX, MEMACC. > > > > If we don't care about MEMACC, then the existing code in the OPP library > > satisfies all our needs. > > The problem here is if we need to do MEMACC as well. > > > > I don't think it is proper to implement MEMACC as a power domain > > (because it is not). Thus, we can't add it as a required-opp. Required-opps can be extended if there is a real need. It isn't just about power domains. > > Another problem is that MEMACC should be done after regulator_set_voltage() > > when scaling up, and before regulator_set_voltage() when scaling down. > > > > So even if MEMACC was a power domain, currently the OPP library does > > the _set_required_opps() call in the wrong order needed for MEMACC. > > > > Like you said, the OPP library almost does everything already, > > so it probably makes most sense to extend it to your needs, > > rather than duplicating most of the code inside dev_pm_opp_set_rate(). > > > > > > I guess what you really want is two new optional callbacks in > > dev_pm_opp_set_rate(), one before _generic_set_opp_regulator() and one > > after, where you could do the MEMACC thing. > > > > The callbacks need to have a parameter that tells if we are scaling down > > or up. NAK :) > > Or, if Viresh doesn't like new function pointers, create a new > > OPP_EVENT_* that you can register for, and in that callback you do what > > you need. NAK :) > > Or, maybe you can even use the existing CPUFREQ_TRANSITION_NOTIFIER, > > with CPUFREQ_PRECHANGE / CPUFREQ_POSTCHANGE, however, I'm not sure > > how nicely they play when you are using the OPP library. > > > > I'm not sure. Overall all of this doesn't really sound like it is going > to make all this easier to understand (from looking at the device tree). > We then have required-opps for VDD_MX, and CPR (which isn't really a > power domain), and something entirely different for MEMACC (which like > CPR, isn't really a power domain). > > I don't know, right now this mixture of different approaches sounds > rather complicated (and confusing) to me... > > Just to throw another idea in the room: there seems to be a set_opp() > callback already in the OPP table, which bypasses the code that > updates clock and regulators (see ti-opp-supply.c). Actually if I'm > reading this correctly ti-opp-supply seems to implement adaptive voltage > scaling similar to CPR with it. Seemingly we have two different solutions > for the same concept now: > > - CPR implements a power domain provider (even though it's not really > a power domain since it has only one consumer) > - ti-opp-supply implements this with the set_opp() callback > > In general I think this looks pretty nice - we don't duplicate the full > cpufreq driver, but have control about the order > regulators/clocks/power domains etc are changed. > > I think something like this would fit quite well for my case > (scaling MX, APC and MEMACC without CPR). However, not sure how it would > integrate with the existing CPR driver at some point. > > Adding Viresh to Cc in case he has some opinion for all this. OPP core broadly is a place where we store/parse some data from the DT and keep, so others can use it. opp_set_rate() was added to it to avoid duplicating the same thing across drivers. As you have figured out, the right way for you to solve it is by using your set_opp() callback along with required-opps thing. -- viresh ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps 2020-04-01 17:50 [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps Loic Poulain 2020-04-01 23:46 ` Bjorn Andersson 2020-04-02 8:13 ` Stephan Gerhold @ 2020-04-28 20:04 ` Amit Kucheria 2 siblings, 0 replies; 32+ messages in thread From: Amit Kucheria @ 2020-04-28 20:04 UTC (permalink / raw) To: Loic Poulain; +Cc: Bjorn Andersson, Andy Gross, linux-arm-msm Hi Loic, On Wed, Apr 1, 2020 at 11:17 PM Loic Poulain <loic.poulain@linaro.org> wrote: > > The highest cpu frequency opps have been dropped because CPR is not > supported. However, we can simply specify operating voltage so that > they match the max corner voltages for each freq. With that, we can > support up to 1.36Ghz. Ideally, msm8916 CPR should be implemented to > fine tune operating voltages and optimize power consumption. > > This patch: > - Adds missing opps and corresponding target voltages to msm8916.dtsi. > - Adds cpu-supply to apq8016-sbc.dtsi (board level info). > - Adds pm8916 spmi regulator node to pm8916.dtsi. > > Tested with a dragonboard-410c. FWIW, I took this out for a spin with stress-ng loads. The first output is w/o the patch. --o amitrootfs o--(/sys/devices/system/cpu/cpufreq/policy0/stats) $ grep "" * grep: reset: Permission denied time_in_state:200000 14304 time_in_state:400000 2 time_in_state:800000 40 time_in_state:998400 4316 total_trans:31 trans_table: From : To trans_table: : 200000 400000 800000 998400 trans_table: 200000: 0 1 12 1 trans_table: 400000: 2 0 0 0 trans_table: 800000: 12 0 0 1 trans_table: 998400: 0 1 1 0 The following output is with the patch applied. The cpu ran at 1.3GHz for a short while until thermal kicked in and throttled the device to 800MHz-1GHz OPPs. --o amitrootfs o--(/sys/devices/system/cpu/cpufreq/policy0/stats) $ grep "" * grep: reset: Permission denied time_in_state:200000 201824 time_in_state:400000 158 time_in_state:533330 2501 time_in_state:800000 37804 time_in_state:998400 23326 time_in_state:1094400 2325 time_in_state:1152000 747 time_in_state:1209600 922 time_in_state:1363200 10788 total_trans:1504 trans_table: From : To trans_table: : 200000 400000 533330 800000 998400 1094400 1152000 1209600 1363200 trans_table: 200000: 0 18 5 8 99 0 1 0 2 trans_table: 400000: 18 0 0 0 3 0 0 0 0 trans_table: 533330: 7 1 0 77 1 0 0 0 0 trans_table: 800000: 13 1 1 0 547 0 0 0 1 trans_table: 998400: 92 1 80 477 0 12 0 0 2 trans_table: 1094400: 1 0 0 0 14 0 0 0 2 trans_table: 1152000: 1 0 0 0 1 4 0 0 1 trans_table: 1209600: 0 0 0 0 0 0 5 0 0 trans_table: 1363200: 1 0 0 0 0 1 1 5 0 > Signed-off-by: Loic Poulain <loic.poulain@linaro.org> I haven't found a v2 of this patch incorporating Bjorn's suggestions yet. Until then, Tested-by: Amit Kucheria <amit.kucheria@linaro.org> > --- > arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 24 ++++++++++++++++++++++++ > arch/arm64/boot/dts/qcom/msm8916.dtsi | 24 ++++++++++++++++++++++++ > arch/arm64/boot/dts/qcom/pm8916.dtsi | 6 ++++++ > 3 files changed, 54 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > index 037e26b..f1c1216 100644 > --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi > @@ -560,6 +560,30 @@ > qcom,mbhc-vthreshold-high = <75 150 237 450 500>; > }; > > +&spm_regulators { > + vdd_cpu: s2 { > + regulator-always-on; > + regulator-min-microvolt = <1050000>; > + regulator-max-microvolt = <1350000>; > + }; > +}; > + > +&CPU0 { > + cpu-supply = <&vdd_cpu>; > +}; > + > +&CPU1 { > + cpu-supply = <&vdd_cpu>; > +}; > + > +&CPU2 { > + cpu-supply = <&vdd_cpu>; > +}; > + > +&CPU3 { > + cpu-supply = <&vdd_cpu>; > +}; > + > &smd_rpm_regulators { > vdd_l1_l2_l3-supply = <&pm8916_s3>; > vdd_l5-supply = <&pm8916_s3>; > diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi > index 9f31064..9805af0 100644 > --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi > +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi > @@ -342,15 +342,39 @@ > > opp-200000000 { > opp-hz = /bits/ 64 <200000000>; > + opp-microvolt = <1050000>; > }; > opp-400000000 { > opp-hz = /bits/ 64 <400000000>; > + opp-microvolt = <1050000>; > + }; > + opp-533330000 { > + opp-hz = /bits/ 64 <533330000>; > + opp-microvolt = <1150000>; > }; > opp-800000000 { > opp-hz = /bits/ 64 <800000000>; > + opp-microvolt = <1150000>; > }; > opp-998400000 { > opp-hz = /bits/ 64 <998400000>; > + opp-microvolt = <1350000>; > + }; > + opp-1094400000 { > + opp-hz = /bits/ 64 <1094400000>; > + opp-microvolt = <1350000>; > + }; > + opp-1152000000 { > + opp-hz = /bits/ 64 <1152000000>; > + opp-microvolt = <1350000>; > + }; > + opp-1209600000 { > + opp-hz = /bits/ 64 <1209600000>; > + opp-microvolt = <1350000>; > + }; > + opp-1363200000 { > + opp-hz = /bits/ 64 <1363200000>; > + opp-microvolt = <1350000>; > }; > }; > > diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi > index 0bcdf04..c9b9c4f 100644 > --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi > +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi > @@ -157,5 +157,11 @@ > vdd-micbias-supply = <&pm8916_l13>; > #sound-dai-cells = <1>; > }; > + > + spm_regulators: spm_regulators { > + compatible = "qcom,pm8916-regulators"; > + #address-cells = <1>; > + #size-cells = <1>; > + }; > }; > }; > -- > 2.7.4 > ^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2020-05-28 13:38 UTC | newest] Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-04-01 17:50 [PATCH] arch: arm64: dts: apq8016-dbc: Add missing cpu opps Loic Poulain 2020-04-01 23:46 ` Bjorn Andersson 2020-04-02 8:13 ` Stephan Gerhold 2020-04-02 9:58 ` Loic Poulain 2020-04-03 1:31 ` Bjorn Andersson 2020-04-03 10:09 ` Stephan Gerhold 2020-04-03 18:00 ` Stephan Gerhold 2020-04-23 4:55 ` Bjorn Andersson 2020-04-26 12:31 ` Stephan Gerhold 2020-05-06 21:18 ` Stephan Gerhold 2020-05-07 5:34 ` Bjorn Andersson 2020-05-08 12:08 ` Ulf Hansson 2020-05-08 13:42 ` Stephan Gerhold 2020-05-11 5:29 ` Viresh Kumar 2020-05-07 10:46 ` Stephan Gerhold 2020-05-21 19:18 ` Stephan Gerhold 2020-05-23 12:08 ` Stephan Gerhold 2020-05-27 20:47 ` Georgi Djakov 2020-05-25 15:32 ` Niklas Cassel 2020-05-25 16:36 ` Stephan Gerhold 2020-05-25 19:44 ` Niklas Cassel 2020-05-26 8:59 ` Stephan Gerhold 2020-05-26 15:54 ` Niklas Cassel 2020-05-26 20:54 ` Stephan Gerhold 2020-05-27 10:39 ` Niklas Cassel 2020-05-27 12:04 ` Stephan Gerhold 2020-05-27 12:59 ` Niklas Cassel 2020-05-27 20:56 ` Stephan Gerhold 2020-05-27 23:10 ` Niklas Cassel 2020-05-28 13:32 ` Stephan Gerhold 2020-05-28 4:44 ` Viresh Kumar 2020-04-28 20:04 ` Amit Kucheria
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).