Linux Power Management development
 help / color / mirror / Atom feed
* Re: [PATCH V3] powercap/drivers/idle_injection: Add an idle injection framework
From: Daniel Lezcano @ 2018-05-23 13:19 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: rjw, edubezval, kevin.wangtao, leo.yan, vincent.guittot,
	linux-kernel, javi.merino, rui.zhang, linux-pm, daniel.thompson
In-Reply-To: <20180523095549.mbit5plvqoppnasu@vireshk-i7>

On 23/05/2018 11:55, Viresh Kumar wrote:
> On 23-05-18, 10:00, Daniel Lezcano wrote:

[ ... ]

> Maybe I wasn't able to explain the problem I see, but lemme retry
> that. Assume that there is only one use and that id cpu-idle-cooling.
> We are currently running the idle loop with idle duration X and run
> duration Y.
> 
> Now lets say the cooling device gets unregistered itself (maybe module
> removal, etc). And it calls idle_injection_unregister() with a valid
> pointer. Not sure if the thermal framework will call set_cur_state
> anymore. But the problem will remain even if it does that.
> 
> We call idle_injection_stop() from unregister, which will cancel
> hrtimer, set durations as 0 and return. Then we free the iidev. It is
> certainly possible at this point of time that the kthread is still
> running the idle loop which it may have started before unregister was
> called. And so after the idle loop is finished it will try to access
> ii_dev, which is already freed.
> 
> So, idle_injection_stop() needs to guarantee that the kthread and the
> hrtimer are all stopped now and no one is using the ii_dev structure
> anymore.
> 
> Perhaps you need some completion stuff here to give confirmation here,
> etc.

Ok, let me come back with something.

Thanks for reviewing again.

  -- Daniel



-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply

* [PATCH v11 2/2] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu
From: Ilia Lin @ 2018-05-23 12:38 UTC (permalink / raw)
  To: vireshk, nm, sboyd, robh, mark.rutland, rjw, linux-pm, devicetree,
	linux-kernel
In-Reply-To: <1527079139-3558-1-git-send-email-ilialin@codeaurora.org>

The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
to provide the OPP framework with required information.
This is used to determine the voltage and frequency value for each OPP of
operating-points-v2 table when it is parsed by the OPP framework.

This change adds documentation for the DT bindings.
The "operating-points-v2-kryo-cpu" DT extends the "operating-points-v2"
with following parameters:
- nvmem-cells (NVMEM area containig the speedbin information)
- opp-supported-hw: A single 32 bit bitmap value,
  representing compatible HW:
			0:	MSM8996 V3, speedbin 0
			1:	MSM8996 V3, speedbin 1
			2:	MSM8996 V3, speedbin 2
			3:	unused
			4:	MSM8996 SG, speedbin 0
			5:	MSM8996 SG, speedbin 1
			6:	MSM8996 SG, speedbin 2
			7-31:	unused

Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 .../devicetree/bindings/opp/kryo-cpufreq.txt       | 680 +++++++++++++++++++++
 1 file changed, 680 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt

diff --git a/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt b/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
new file mode 100644
index 0000000..c2127b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
@@ -0,0 +1,680 @@
+Qualcomm Technologies, Inc. KRYO CPUFreq and OPP bindings
+===================================
+
+In Certain Qualcomm Technologies, Inc. SoCs like apq8096 and msm8996
+that have KRYO processors, the CPU ferequencies subset and voltage value
+of each OPP varies based on the silicon variant in use.
+Qualcomm Technologies, Inc. Process Voltage Scaling Tables
+defines the voltage and frequency value based on the msm-id in SMEM
+and speedbin blown in the efuse combination.
+The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
+to provide the OPP framework with required information (existing HW bitmap).
+This is used to determine the voltage and frequency value for each OPP of
+operating-points-v2 table when it is parsed by the OPP framework.
+
+Required properties:
+--------------------
+In 'cpus' nodes:
+- operating-points-v2: Phandle to the operating-points-v2 table to use.
+
+In 'operating-points-v2' table:
+- compatible: Should be
+	- 'operating-points-v2-kryo-cpu' for apq8096 and msm8996.
+- nvmem-cells: A phandle pointing to a nvmem-cells node representing the
+		efuse registers that has information about the
+		speedbin that is used to select the right frequency/voltage
+		value pair.
+		Please refer the for nvmem-cells
+		bindings Documentation/devicetree/bindings/nvmem/nvmem.txt
+		and also examples below.
+
+In every OPP node:
+- opp-supported-hw: A single 32 bit bitmap value, representing compatible HW.
+		    Bitmap:
+			0:	MSM8996 V3, speedbin 0
+			1:	MSM8996 V3, speedbin 1
+			2:	MSM8996 V3, speedbin 2
+			3:	unused
+			4:	MSM8996 SG, speedbin 0
+			5:	MSM8996 SG, speedbin 1
+			6:	MSM8996 SG, speedbin 2
+			7-31:	unused
+
+Example 1:
+---------
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		CPU0: cpu@0 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			clocks = <&kryocc 0>;
+			cpu-supply = <&pm8994_s11_saw>;
+			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
+			next-level-cache = <&L2_0>;
+			L2_0: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			};
+		};
+
+		CPU1: cpu@1 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			clocks = <&kryocc 0>;
+			cpu-supply = <&pm8994_s11_saw>;
+			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU2: cpu@100 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			clocks = <&kryocc 1>;
+			cpu-supply = <&pm8994_s11_saw>;
+			operating-points-v2 = <&cluster1_opp>;
+			#cooling-cells = <2>;
+			next-level-cache = <&L2_1>;
+			L2_1: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			};
+		};
+
+		CPU3: cpu@101 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			clocks = <&kryocc 1>;
+			cpu-supply = <&pm8994_s11_saw>;
+			operating-points-v2 = <&cluster1_opp>;
+			#cooling-cells = <2>;
+			next-level-cache = <&L2_1>;
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+
+				core1 {
+					cpu = <&CPU1>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&CPU2>;
+				};
+
+				core1 {
+					cpu = <&CPU3>;
+				};
+			};
+		};
+	};
+
+	cluster0_opp: opp_table0 {
+		compatible = "operating-points-v2-kryo-cpu";
+		nvmem-cells = <&speedbin_efuse>;
+		opp-shared;
+
+		opp-307200000 {
+			opp-hz = /bits/ 64 <307200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x77>;
+			clock-latency-ns = <200000>;
+		};
+		opp-384000000 {
+			opp-hz = /bits/ 64 <384000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-422400000 {
+			opp-hz = /bits/ 64 <422400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-460800000 {
+			opp-hz = /bits/ 64 <460800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-480000000 {
+			opp-hz = /bits/ 64 <480000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-537600000 {
+			opp-hz = /bits/ 64 <537600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-556800000 {
+			opp-hz = /bits/ 64 <556800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-614400000 {
+			opp-hz = /bits/ 64 <614400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-652800000 {
+			opp-hz = /bits/ 64 <652800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-691200000 {
+			opp-hz = /bits/ 64 <691200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-729600000 {
+			opp-hz = /bits/ 64 <729600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-768000000 {
+			opp-hz = /bits/ 64 <768000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-844800000 {
+			opp-hz = /bits/ 64 <844800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x77>;
+			clock-latency-ns = <200000>;
+		};
+		opp-902400000 {
+			opp-hz = /bits/ 64 <902400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-960000000 {
+			opp-hz = /bits/ 64 <960000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-979200000 {
+			opp-hz = /bits/ 64 <979200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1036800000 {
+			opp-hz = /bits/ 64 <1036800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1056000000 {
+			opp-hz = /bits/ 64 <1056000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1113600000 {
+			opp-hz = /bits/ 64 <1113600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1132800000 {
+			opp-hz = /bits/ 64 <1132800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1190400000 {
+			opp-hz = /bits/ 64 <1190400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1209600000 {
+			opp-hz = /bits/ 64 <1209600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1228800000 {
+			opp-hz = /bits/ 64 <1228800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1286400000 {
+			opp-hz = /bits/ 64 <1286400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1324800000 {
+			opp-hz = /bits/ 64 <1324800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x5>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1363200000 {
+			opp-hz = /bits/ 64 <1363200000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x72>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1401600000 {
+			opp-hz = /bits/ 64 <1401600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x5>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1440000000 {
+			opp-hz = /bits/ 64 <1440000000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1478400000 {
+			opp-hz = /bits/ 64 <1478400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x1>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1497600000 {
+			opp-hz = /bits/ 64 <1497600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x4>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1516800000 {
+			opp-hz = /bits/ 64 <1516800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1593600000 {
+			opp-hz = /bits/ 64 <1593600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x71>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1996800000 {
+			opp-hz = /bits/ 64 <1996800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x20>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2188800000 {
+			opp-hz = /bits/ 64 <2188800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x10>;
+			clock-latency-ns = <200000>;
+		};
+	};
+
+	cluster1_opp: opp_table1 {
+		compatible = "operating-points-v2-kryo-cpu";
+		nvmem-cells = <&speedbin_efuse>;
+		opp-shared;
+
+		opp-307200000 {
+			opp-hz = /bits/ 64 <307200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x77>;
+			clock-latency-ns = <200000>;
+		};
+		opp-384000000 {
+			opp-hz = /bits/ 64 <384000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-403200000 {
+			opp-hz = /bits/ 64 <403200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-460800000 {
+			opp-hz = /bits/ 64 <460800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-480000000 {
+			opp-hz = /bits/ 64 <480000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-537600000 {
+			opp-hz = /bits/ 64 <537600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-556800000 {
+			opp-hz = /bits/ 64 <556800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-614400000 {
+			opp-hz = /bits/ 64 <614400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-652800000 {
+			opp-hz = /bits/ 64 <652800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-691200000 {
+			opp-hz = /bits/ 64 <691200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-729600000 {
+			opp-hz = /bits/ 64 <729600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-748800000 {
+			opp-hz = /bits/ 64 <748800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-806400000 {
+			opp-hz = /bits/ 64 <806400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-825600000 {
+			opp-hz = /bits/ 64 <825600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-883200000 {
+			opp-hz = /bits/ 64 <883200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-902400000 {
+			opp-hz = /bits/ 64 <902400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-940800000 {
+			opp-hz = /bits/ 64 <940800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-979200000 {
+			opp-hz = /bits/ 64 <979200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1036800000 {
+			opp-hz = /bits/ 64 <1036800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1056000000 {
+			opp-hz = /bits/ 64 <1056000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1113600000 {
+			opp-hz = /bits/ 64 <1113600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1132800000 {
+			opp-hz = /bits/ 64 <1132800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1190400000 {
+			opp-hz = /bits/ 64 <1190400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1209600000 {
+			opp-hz = /bits/ 64 <1209600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1248000000 {
+			opp-hz = /bits/ 64 <1248000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1286400000 {
+			opp-hz = /bits/ 64 <1286400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1324800000 {
+			opp-hz = /bits/ 64 <1324800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1363200000 {
+			opp-hz = /bits/ 64 <1363200000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1401600000 {
+			opp-hz = /bits/ 64 <1401600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1440000000 {
+			opp-hz = /bits/ 64 <1440000000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1478400000 {
+			opp-hz = /bits/ 64 <1478400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1516800000 {
+			opp-hz = /bits/ 64 <1516800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1555200000 {
+			opp-hz = /bits/ 64 <1555200000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1593600000 {
+			opp-hz = /bits/ 64 <1593600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1632000000 {
+			opp-hz = /bits/ 64 <1632000000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1670400000 {
+			opp-hz = /bits/ 64 <1670400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1708800000 {
+			opp-hz = /bits/ 64 <1708800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1747200000 {
+			opp-hz = /bits/ 64 <1747200000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1785600000 {
+			opp-hz = /bits/ 64 <1785600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1804800000 {
+			opp-hz = /bits/ 64 <1804800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x6>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1824000000 {
+			opp-hz = /bits/ 64 <1824000000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x71>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1900800000 {
+			opp-hz = /bits/ 64 <1900800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x74>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1920000000 {
+			opp-hz = /bits/ 64 <1920000000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x1>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1977600000 {
+			opp-hz = /bits/ 64 <1977600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x30>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1996800000 {
+			opp-hz = /bits/ 64 <1996800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x1>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2054400000 {
+			opp-hz = /bits/ 64 <2054400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x30>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2073600000 {
+			opp-hz = /bits/ 64 <2073600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x1>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2150400000 {
+			opp-hz = /bits/ 64 <2150400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x31>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2246400000 {
+			opp-hz = /bits/ 64 <2246400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x10>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2342400000 {
+			opp-hz = /bits/ 64 <2342400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x10>;
+			clock-latency-ns = <200000>;
+		};
+	};
+
+....
+
+reserved-memory {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	ranges;
+....
+	smem_mem: smem-mem@86000000 {
+		reg = <0x0 0x86000000 0x0 0x200000>;
+		no-map;
+	};
+....
+};
+
+smem {
+	compatible = "qcom,smem";
+	memory-region = <&smem_mem>;
+	hwlocks = <&tcsr_mutex 3>;
+};
+
+soc {
+....
+	qfprom: qfprom@74000 {
+		compatible = "qcom,qfprom";
+		reg = <0x00074000 0x8ff>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		....
+		speedbin_efuse: speedbin@133 {
+			reg = <0x133 0x1>;
+			bits = <5 3>;
+		};
+	};
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v11 1/2] cpufreq: Add Kryo CPU scaling driver
From: Ilia Lin @ 2018-05-23 12:38 UTC (permalink / raw)
  To: vireshk, nm, sboyd, robh, mark.rutland, rjw, linux-pm, devicetree,
	linux-kernel
In-Reply-To: <1527079139-3558-1-git-send-email-ilialin@codeaurora.org>

In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
the CPU frequency subset and voltage value of each OPP varies
based on the silicon variant in use. Qualcomm Process Voltage Scaling Tables
defines the voltage and frequency value based on the msm-id in SMEM
and speedbin blown in the efuse combination.
The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
to provide the OPP framework with required information.
This is used to determine the voltage and frequency value for each OPP of
operating-points-v2 table when it is parsed by the OPP framework.

Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
 drivers/cpufreq/Kconfig.arm          |  10 ++
 drivers/cpufreq/Makefile             |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c  | 181 +++++++++++++++++++++++++++++++++++
 4 files changed, 195 insertions(+)
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index de55c7d..0bfd40e 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -124,6 +124,16 @@ config ARM_OMAP2PLUS_CPUFREQ
 	depends on ARCH_OMAP2PLUS
 	default ARCH_OMAP2PLUS
 
+config ARM_QCOM_CPUFREQ_KRYO
+	bool "Qualcomm Kryo based CPUFreq"
+	depends on QCOM_QFPROM
+	depends on QCOM_SMEM
+	select PM_OPP
+	help
+	  This adds the CPUFreq driver for Qualcomm Kryo SoC based boards.
+
+	  If in doubt, say N.
+
 config ARM_S3C_CPUFREQ
 	bool
 	help
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 8d24ade..fb4a2ec 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_MACH_MVEBU_V7)		+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)	+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)	+= pxa2xx-cpufreq.o
 obj-$(CONFIG_PXA3xx)			+= pxa3xx-cpufreq.o
+obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRYO)	+= qcom-cpufreq-kryo.o
 obj-$(CONFIG_ARM_S3C2410_CPUFREQ)	+= s3c2410-cpufreq.o
 obj-$(CONFIG_ARM_S3C2412_CPUFREQ)	+= s3c2412-cpufreq.o
 obj-$(CONFIG_ARM_S3C2416_CPUFREQ)	+= s3c2416-cpufreq.o
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index 3b585e4..77d6ab8 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -118,6 +118,9 @@
 
 	{ .compatible = "nvidia,tegra124", },
 
+	{ .compatible = "qcom,apq8096", },
+	{ .compatible = "qcom,msm8996", },
+
 	{ .compatible = "st,stih407", },
 	{ .compatible = "st,stih410", },
 
diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c b/drivers/cpufreq/qcom-cpufreq-kryo.c
new file mode 100644
index 0000000..2339ea99d
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+/*
+ * In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
+ * the CPU frequency subset and voltage value of each OPP varies
+ * based on the silicon variant in use. Qualcomm Process Voltage Scaling Tables
+ * defines the voltage and frequency value based on the msm-id in SMEM
+ * and speedbin blown in the efuse combination.
+ * The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
+ * to provide the OPP framework with required information.
+ * This is used to determine the voltage and frequency value for each OPP of
+ * operating-points-v2 table when it is parsed by the OPP framework.
+ */
+
+#include <linux/cpu.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+#include <linux/soc/qcom/smem.h>
+
+#define MSM_ID_SMEM	137
+
+enum _msm_id {
+	MSM8996V3 = 0xF6ul,
+	APQ8096V3 = 0x123ul,
+	MSM8996SG = 0x131ul,
+	APQ8096SG = 0x138ul,
+};
+
+enum _msm8996_version {
+	MSM8996_V3,
+	MSM8996_SG,
+	NUM_OF_MSM8996_VERSIONS,
+};
+
+static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void)
+{
+	size_t len;
+	u32 *msm_id;
+	enum _msm8996_version version;
+
+	msm_id = qcom_smem_get(QCOM_SMEM_HOST_ANY, MSM_ID_SMEM, &len);
+	/* The first 4 bytes are format, next to them is the actual msm-id */
+	msm_id++;
+
+	switch ((enum _msm_id)*msm_id) {
+	case MSM8996V3:
+	case APQ8096V3:
+		version = MSM8996_V3;
+		break;
+	case MSM8996SG:
+	case APQ8096SG:
+		version = MSM8996_SG;
+		break;
+	default:
+		version = NUM_OF_MSM8996_VERSIONS;
+	}
+
+	return version;
+}
+
+static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
+{
+	struct opp_table *opp_tables[NR_CPUS] = {0};
+	struct platform_device *cpufreq_dt_pdev;
+	enum _msm8996_version msm8996_version;
+	struct nvmem_cell *speedbin_nvmem;
+	struct device_node *np;
+	struct device *cpu_dev;
+	unsigned cpu;
+	u8 *speedbin;
+	u32 versions;
+	size_t len;
+	int ret;
+
+	cpu_dev = get_cpu_device(0);
+	if (NULL == cpu_dev)
+		return -ENODEV;
+
+	msm8996_version = qcom_cpufreq_kryo_get_msm_id();
+	if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
+		dev_err(cpu_dev, "Not Snapdragon 820/821!");
+		return -ENODEV;
+	}
+
+	np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
+	if (IS_ERR(np))
+		return PTR_ERR(np);
+
+	if (!of_device_is_compatible(np, "operating-points-v2-kryo-cpu")) {
+		of_node_put(np);
+		return -ENOENT;
+	}
+
+	speedbin_nvmem = of_nvmem_cell_get(np, NULL);
+	of_node_put(np);
+	if (IS_ERR(speedbin_nvmem)) {
+		dev_err(cpu_dev, "Could not get nvmem cell: %d\n", ret);
+		return PTR_ERR(speedbin_nvmem);
+	}
+
+	speedbin = nvmem_cell_read(speedbin_nvmem, &len);
+	nvmem_cell_put(speedbin_nvmem);
+
+	switch (msm8996_version) {
+	case MSM8996_V3:
+		versions = 1 << (unsigned int)(*speedbin);
+		break;
+	case MSM8996_SG:
+		versions = 1 << ((unsigned int)(*speedbin) + 4);
+		break;
+	default:
+		BUG();
+		break;
+	}
+
+	for_each_possible_cpu(cpu) {
+		cpu_dev = get_cpu_device(cpu);
+		if (NULL == cpu_dev) {
+			ret = -ENODEV;
+			goto free_opp;
+		}
+
+		opp_tables[cpu] = dev_pm_opp_set_supported_hw(cpu_dev,
+							      &versions, 1);
+		if (IS_ERR(opp_tables[cpu])) {
+			ret = PTR_ERR(opp_tables[cpu]);
+			dev_err(cpu_dev, "Failed to set supported hardware\n");
+			goto free_opp;
+		}
+	}
+
+	cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+	if (!IS_ERR(cpufreq_dt_pdev))
+		return 0;
+
+	ret = PTR_ERR(cpufreq_dt_pdev);
+	dev_err(cpu_dev, "Failed to register platform device\n");
+
+free_opp:
+	for_each_possible_cpu(cpu) {
+		if (IS_ERR_OR_NULL(opp_tables[cpu]))
+			break;
+		dev_pm_opp_put_supported_hw(opp_tables[cpu]);
+	}
+
+	return ret;
+}
+
+static int __init qcom_cpufreq_kryo_init(void)
+{
+	/*
+	 * Since the driver depends on smem and nvmem drivers, which may
+	 * return EPROBE_DEFER, all the real activity is done in the probe,
+	 * which may be defered as well. The init here is only registering
+	 * a platform device.
+	 */
+	platform_device_register_simple("qcom-cpufreq-kryo", -1, NULL, 0);
+	return 0;
+}
+module_init(qcom_cpufreq_kryo_init);
+
+static struct platform_driver qcom_cpufreq_kryo_driver = {
+	.probe = qcom_cpufreq_kryo_probe,
+	.driver = {
+		.name = "qcom-cpufreq-kryo",
+	},
+};
+builtin_platform_driver(qcom_cpufreq_kryo_driver);
+
+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related

* [PATCH v11 0/2] Kryo CPU scaling driver
From: Ilia Lin @ 2018-05-23 12:38 UTC (permalink / raw)
  To: vireshk, nm, sboyd, robh, mark.rutland, rjw, linux-pm, devicetree,
	linux-kernel

[v11]
 * Addressed comment from Russel about device_node reference
 * Addressed comment from Sudeep about the late_initcall
 * Transformed init into probe to take care of deferals

[v10]
 * Split the series into domains
 * Addressed comments from Viresh and Sudeep about logical CPU numbering.

The qcom-cpufreq-kryo driver is aimed to support different SOC versions.
The driver reads eFuse information and chooses the required OPP subset
by passing the OPP supported-hw parameter.

The series depends on the series from Viresh:
https://patchwork.kernel.org/patch/10418139/

The previous spin was here:
https://patchwork.kernel.org/patch/10420809/

Ilia Lin (2):
  cpufreq: Add Kryo CPU scaling driver
  dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu

 .../devicetree/bindings/opp/kryo-cpufreq.txt       | 680 +++++++++++++++++++++
 drivers/cpufreq/Kconfig.arm                        |  10 +
 drivers/cpufreq/Makefile                           |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c               |   3 +
 drivers/cpufreq/qcom-cpufreq-kryo.c                | 181 ++++++
 5 files changed, 875 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
 create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c

-- 
1.9.1

^ permalink raw reply

* Re: [PATCH v10 1/2] cpufreq: Add Kryo CPU scaling driver
From: Viresh Kumar @ 2018-05-23 11:51 UTC (permalink / raw)
  To: Ilia Lin
  Cc: Sudeep Holla, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	Rob Herring, Mark Rutland, Rafael J. Wysocki,
	linux-pm@vger.kernel.org, devicetree@vger.kernel.org,
	Linux Kernel Mailing List
In-Reply-To: <002d01d3f28b$d3ce3980$7b6aac80$@codeaurora.org>

On 23 May 2018 at 17:17,  <ilialin@codeaurora.org> wrote:
> The nvmem will return EPROBE_DEFER, and so will my driver's init. But then no one will call the init again.

So even your driver needs to be registered as a platform driver then
and you can create its device
from the init function, and add a comment on why you create the
platform device in the driver itself.

--
viresh

^ permalink raw reply

* RE: [PATCH v10 1/2] cpufreq: Add Kryo CPU scaling driver
From: ilialin @ 2018-05-23 11:47 UTC (permalink / raw)
  To: 'Viresh Kumar'
  Cc: 'Sudeep Holla', 'Viresh Kumar',
	'Nishanth Menon', 'Stephen Boyd',
	'Rob Herring', 'Mark Rutland',
	'Rafael J. Wysocki', linux-pm, devicetree,
	'Linux Kernel Mailing List'
In-Reply-To: <CAKohponruWpcjuSDg-=ZbZ1=qm2iPZs36mfKYJ3nQZREkc3JCw@mail.gmail.com>

The nvmem will return EPROBE_DEFER, and so will my driver's init. But then no one will call the init again.

> -----Original Message-----
> From: Viresh Kumar <viresh.kumar@linaro.org>
> Sent: Wednesday, May 23, 2018 14:46
> To: Ilia Lin <ilialin@codeaurora.org>
> Cc: Sudeep Holla <sudeep.holla@arm.com>; Viresh Kumar
> <vireshk@kernel.org>; Nishanth Menon <nm@ti.com>; Stephen Boyd
> <sboyd@kernel.org>; Rob Herring <robh@kernel.org>; Mark Rutland
> <mark.rutland@arm.com>; Rafael J. Wysocki <rjw@rjwysocki.net>; linux-
> pm@vger.kernel.org; devicetree@vger.kernel.org; Linux Kernel Mailing List
> <linux-kernel@vger.kernel.org>
> Subject: Re: [PATCH v10 1/2] cpufreq: Add Kryo CPU scaling driver
> 
> On 23 May 2018 at 17:04,  <ilialin@codeaurora.org> wrote:
> > You are right. I already checked that in the code...
> > However, with module_init() the driver fails on reading the nvmem.
> 
> And why is it failing ?

^ permalink raw reply

* Re: [PATCH v10 1/2] cpufreq: Add Kryo CPU scaling driver
From: Viresh Kumar @ 2018-05-23 11:46 UTC (permalink / raw)
  To: Ilia Lin
  Cc: Sudeep Holla, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	Rob Herring, Mark Rutland, Rafael J. Wysocki,
	linux-pm@vger.kernel.org, devicetree@vger.kernel.org,
	Linux Kernel Mailing List
In-Reply-To: <002b01d3f28a$0d033900$2709ab00$@codeaurora.org>

On 23 May 2018 at 17:04,  <ilialin@codeaurora.org> wrote:
> You are right. I already checked that in the code...
> However, with module_init() the driver fails on reading the nvmem.

And why is it failing ?

^ permalink raw reply

* Re: [PATCH v4 0/2] Fix and cleanup iowait boost
From: Rafael J. Wysocki @ 2018-05-23 11:37 UTC (permalink / raw)
  To: Patrick Bellasi
  Cc: linux-kernel, linux-pm, Ingo Molnar, Peter Zijlstra,
	Rafael J . Wysocki, Viresh Kumar, Vincent Guittot,
	Dietmar Eggemann, Juri Lelli, Joel Fernandes
In-Reply-To: <20180522110754.20832-1-patrick.bellasi@arm.com>

On Tuesday, May 22, 2018 1:07:52 PM CEST Patrick Bellasi wrote:
> Here is the (hopefully) final update of:
> 
>    https://lkml.org/lkml/2018/5/21/114
>    20180521085120.7902-1-patrick.bellasi@arm.com
> 
> which just includes the small typo fixes suggested by Jeol and the ack
> and review tags collected so far.
> 
> Cheers Patrick
> 
> Changes in v4:
>  - fixed typos in changelog (Joel)
>  - added Reviewed-by Joel Fernandes
>  - added Acked-by Viresh and Peter
> 
> Changes in v3:
>  - renamed the iowait boost functions (Peter)
>  - moved boost reset into a dedicated function (Peter)
>  - split the fix into a separated patch (Viresh)
>  - added "Fixes" tag (Viresh)
> 
> Patrick Bellasi (2):
>   cpufreq: schedutil: Fix iowait boost reset
>   cpufreq: schedutil: Cleanup and document iowait boost
> 
>  kernel/sched/cpufreq_schedutil.c | 152 +++++++++++++++++++++++++++------------
>  1 file changed, 108 insertions(+), 44 deletions(-)
> 
> 

Both patches applied, thanks!

^ permalink raw reply

* RE: [PATCH v10 1/2] cpufreq: Add Kryo CPU scaling driver
From: ilialin @ 2018-05-23 11:34 UTC (permalink / raw)
  To: 'Viresh Kumar', 'Sudeep Holla'
  Cc: 'Viresh Kumar', 'Nishanth Menon',
	'Stephen Boyd', 'Rob Herring',
	'Mark Rutland', 'Rafael J. Wysocki', linux-pm,
	devicetree, 'Linux Kernel Mailing List'
In-Reply-To: <CAKohponbpErCeTYu9iQm_-dupz5SUr+TKsYXzqmmARB-pq95iA@mail.gmail.com>



> -----Original Message-----
> From: Viresh Kumar <viresh.kumar@linaro.org>
> Sent: Wednesday, May 23, 2018 14:31
> To: Ilia Lin <ilialin@codeaurora.org>
> Cc: Sudeep Holla <sudeep.holla@arm.com>; Viresh Kumar
> <vireshk@kernel.org>; Nishanth Menon <nm@ti.com>; Stephen Boyd
> <sboyd@kernel.org>; Rob Herring <robh@kernel.org>; Mark Rutland
> <mark.rutland@arm.com>; Rafael J. Wysocki <rjw@rjwysocki.net>; linux-
> pm@vger.kernel.org; devicetree@vger.kernel.org; Linux Kernel Mailing List
> <linux-kernel@vger.kernel.org>
> Subject: Re: [PATCH v10 1/2] cpufreq: Add Kryo CPU scaling driver
> 
> On 23 May 2018 at 16:36,  <ilialin@codeaurora.org> wrote:
> >
> >
> >> -----Original Message-----
> >> From: Sudeep Holla <sudeep.holla@arm.com>
> >> Sent: Wednesday, May 23, 2018 13:40
> >> To: Ilia Lin <ilialin@codeaurora.org>; vireshk@kernel.org; nm@ti.com;
> >> sboyd@kernel.org; robh@kernel.org; mark.rutland@arm.com;
> >> rjw@rjwysocki.net; linux-pm@vger.kernel.org;
> >> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org
> >> Cc: Sudeep Holla <sudeep.holla@arm.com>
> >> Subject: Re: [PATCH v10 1/2] cpufreq: Add Kryo CPU scaling driver
> >>
> >>
> >>
> >> On 23/05/18 10:40, Ilia Lin wrote:
> >> > In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO
> >> > processors, the CPU frequency subset and voltage value of each OPP
> >> > varies based on the silicon variant in use. Qualcomm Process
> >> > Voltage Scaling Tables defines the voltage and frequency value
> >> > based on the msm-id in SMEM and speedbin blown in the efuse
> combination.
> >> > The qcom-cpufreq-kryo driver reads the msm-id and efuse value from
> >> > the SoC to provide the OPP framework with required information.
> >> > This is used to determine the voltage and frequency value for each
> >> > OPP of
> >> > operating-points-v2 table when it is parsed by the OPP framework.
> >> >
> >> > Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
> >>
> >> [...]
> >>
> >> > +   pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
> >> > +   if (!IS_ERR(pdev))
> >> > +           return 0;
> >> > +
> >> > +   ret = PTR_ERR(pdev);
> >> > +   dev_err(cpu_dev, "Failed to register platform device\n");
> >> > +
> >> > +free_opp:
> >> > +   for_each_possible_cpu(cpu) {
> >> > +           if (IS_ERR_OR_NULL(opp_tables[cpu]))
> >> > +                   break;
> >> > +           dev_pm_opp_put_supported_hw(opp_tables[cpu]);
> >> > +   }
> >> > +free_np:
> >> > +   of_node_put(np);
> >> > +
> >> > +   return ret;
> >> > +}
> >> > +late_initcall(qcom_cpufreq_kryo_driver_init);
> >>
> >> Any particular reason why this *has* to be late initcall ?
> >> Please change it to module_initcall otherwise.
> >
> > The purpose is to give the cpufreq-dt the time to register the driver and
> only then my driver will add the platform device.
> 
> That isn't required, the device and its driver can be registered in any order.

You are right. I already checked that in the code...
However, with module_init() the driver fails on reading the nvmem.

^ permalink raw reply

* Re: [PATCH v10 1/2] cpufreq: Add Kryo CPU scaling driver
From: Viresh Kumar @ 2018-05-23 11:31 UTC (permalink / raw)
  To: Ilia Lin
  Cc: Sudeep Holla, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	Rob Herring, Mark Rutland, Rafael J. Wysocki,
	linux-pm@vger.kernel.org, devicetree@vger.kernel.org,
	Linux Kernel Mailing List
In-Reply-To: <002901d3f286$198878b0$4c996a10$@codeaurora.org>

On 23 May 2018 at 16:36,  <ilialin@codeaurora.org> wrote:
>
>
>> -----Original Message-----
>> From: Sudeep Holla <sudeep.holla@arm.com>
>> Sent: Wednesday, May 23, 2018 13:40
>> To: Ilia Lin <ilialin@codeaurora.org>; vireshk@kernel.org; nm@ti.com;
>> sboyd@kernel.org; robh@kernel.org; mark.rutland@arm.com;
>> rjw@rjwysocki.net; linux-pm@vger.kernel.org; devicetree@vger.kernel.org;
>> linux-kernel@vger.kernel.org
>> Cc: Sudeep Holla <sudeep.holla@arm.com>
>> Subject: Re: [PATCH v10 1/2] cpufreq: Add Kryo CPU scaling driver
>>
>>
>>
>> On 23/05/18 10:40, Ilia Lin wrote:
>> > In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO
>> > processors, the CPU frequency subset and voltage value of each OPP
>> > varies based on the silicon variant in use. Qualcomm Process Voltage
>> > Scaling Tables defines the voltage and frequency value based on the
>> > msm-id in SMEM and speedbin blown in the efuse combination.
>> > The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the
>> > SoC to provide the OPP framework with required information.
>> > This is used to determine the voltage and frequency value for each OPP
>> > of
>> > operating-points-v2 table when it is parsed by the OPP framework.
>> >
>> > Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
>>
>> [...]
>>
>> > +   pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
>> > +   if (!IS_ERR(pdev))
>> > +           return 0;
>> > +
>> > +   ret = PTR_ERR(pdev);
>> > +   dev_err(cpu_dev, "Failed to register platform device\n");
>> > +
>> > +free_opp:
>> > +   for_each_possible_cpu(cpu) {
>> > +           if (IS_ERR_OR_NULL(opp_tables[cpu]))
>> > +                   break;
>> > +           dev_pm_opp_put_supported_hw(opp_tables[cpu]);
>> > +   }
>> > +free_np:
>> > +   of_node_put(np);
>> > +
>> > +   return ret;
>> > +}
>> > +late_initcall(qcom_cpufreq_kryo_driver_init);
>>
>> Any particular reason why this *has* to be late initcall ?
>> Please change it to module_initcall otherwise.
>
> The purpose is to give the cpufreq-dt the time to register the driver and only then my driver will add the platform device.

That isn't required, the device and its driver can be registered in any order.

^ permalink raw reply

* Re: [PATCH v3 07/13] soc: rockchip: power-domain: add power domain support for rk3128
From: Heiko Stübner @ 2018-05-23 11:18 UTC (permalink / raw)
  To: Elaine Zhang
  Cc: robh+dt, mark.rutland, devicetree, rjw, khilman, ulf.hansson,
	linux-pm, linux-arm-kernel, linux-rockchip, linux-kernel, wxt,
	xxx, xf, huangtao
In-Reply-To: <1527058270-10412-1-git-send-email-zhangqing@rock-chips.com>

Am Mittwoch, 23. Mai 2018, 08:51:10 CEST schrieb Elaine Zhang:
> This driver is modified to support RK3128 SoC.
> 
> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>

applied for 4.18 or 4.19 (not sure yet).

Patch 8/13 had the licensing issue Rob pointed out, so while
with your fixed SPDX tag everything should be fine, I'll give
Rob the chance to look it over :-)


Heiko

^ permalink raw reply

* Re: [PATCH v3 06/13] dt-bindings: add binding for rk3128 power domains
From: Heiko Stübner @ 2018-05-23 11:17 UTC (permalink / raw)
  To: Elaine Zhang
  Cc: robh+dt, mark.rutland, devicetree, rjw, khilman, ulf.hansson,
	linux-pm, linux-arm-kernel, linux-rockchip, linux-kernel, wxt,
	xxx, xf, huangtao
In-Reply-To: <1527058248-10366-1-git-send-email-zhangqing@rock-chips.com>

Am Mittwoch, 23. Mai 2018, 08:50:48 CEST schrieb Elaine Zhang:
> Add binding documentation for the power domains
> found on Rockchip RK3128 SoCs.
> 
> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
> Acked-by: Rob Herring <robh@kernel.org>

applied for 4.18 or 4.19 (not sure yet).

^ permalink raw reply

* Re: [PATCH v3 05/13] dt-bindings: power: add RK3128 SoCs header for power-domain
From: Heiko Stübner @ 2018-05-23 11:16 UTC (permalink / raw)
  To: Elaine Zhang
  Cc: robh+dt, mark.rutland, devicetree, rjw, khilman, ulf.hansson,
	linux-pm, linux-arm-kernel, linux-rockchip, linux-kernel, wxt,
	xxx, xf, huangtao
In-Reply-To: <1527058231-10319-1-git-send-email-zhangqing@rock-chips.com>

Am Mittwoch, 23. Mai 2018, 08:50:31 CEST schrieb Elaine Zhang:
> According to a description from TRM, add all the power domains.
> 
> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>

applied for 4.18 or 4.19 (not sure yet) after adding
Rob's Review-tag from v2.


Thanks
Heiko

^ permalink raw reply

* RE: [PATCH v10 1/2] cpufreq: Add Kryo CPU scaling driver
From: ilialin @ 2018-05-23 11:06 UTC (permalink / raw)
  To: 'Sudeep Holla'
  Cc: vireshk, nm, sboyd, robh, mark.rutland, rjw, linux-pm, devicetree,
	linux-kernel
In-Reply-To: <3f1ca60e-7aa8-fccc-ab1c-4b7c37731cce@arm.com>



> -----Original Message-----
> From: Sudeep Holla <sudeep.holla@arm.com>
> Sent: Wednesday, May 23, 2018 13:40
> To: Ilia Lin <ilialin@codeaurora.org>; vireshk@kernel.org; nm@ti.com;
> sboyd@kernel.org; robh@kernel.org; mark.rutland@arm.com;
> rjw@rjwysocki.net; linux-pm@vger.kernel.org; devicetree@vger.kernel.org;
> linux-kernel@vger.kernel.org
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Subject: Re: [PATCH v10 1/2] cpufreq: Add Kryo CPU scaling driver
> 
> 
> 
> On 23/05/18 10:40, Ilia Lin wrote:
> > In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO
> > processors, the CPU frequency subset and voltage value of each OPP
> > varies based on the silicon variant in use. Qualcomm Process Voltage
> > Scaling Tables defines the voltage and frequency value based on the
> > msm-id in SMEM and speedbin blown in the efuse combination.
> > The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the
> > SoC to provide the OPP framework with required information.
> > This is used to determine the voltage and frequency value for each OPP
> > of
> > operating-points-v2 table when it is parsed by the OPP framework.
> >
> > Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
> 
> [...]
> 
> > +	pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
> > +	if (!IS_ERR(pdev))
> > +		return 0;
> > +
> > +	ret = PTR_ERR(pdev);
> > +	dev_err(cpu_dev, "Failed to register platform device\n");
> > +
> > +free_opp:
> > +	for_each_possible_cpu(cpu) {
> > +		if (IS_ERR_OR_NULL(opp_tables[cpu]))
> > +			break;
> > +		dev_pm_opp_put_supported_hw(opp_tables[cpu]);
> > +	}
> > +free_np:
> > +	of_node_put(np);
> > +
> > +	return ret;
> > +}
> > +late_initcall(qcom_cpufreq_kryo_driver_init);
> 
> Any particular reason why this *has* to be late initcall ?
> Please change it to module_initcall otherwise.

The purpose is to give the cpufreq-dt the time to register the driver and only then my driver will add the platform device.

> Also address the of_node comments from Viresh.
> 
> Otherwise, it looks good.
> --
> Regards,
> Sudeep

^ permalink raw reply

* Re: [PATCH v3 04/13] soc: rockchip: power-domain: Fix wrong value when power up pd
From: Heiko Stübner @ 2018-05-23 10:57 UTC (permalink / raw)
  To: Elaine Zhang
  Cc: robh+dt, mark.rutland, devicetree, rjw, khilman, ulf.hansson,
	linux-pm, linux-arm-kernel, linux-rockchip, linux-kernel, wxt,
	xxx, xf, huangtao, Finley Xiao
In-Reply-To: <1527058129-10260-5-git-send-email-zhangqing@rock-chips.com>

Am Mittwoch, 23. Mai 2018, 08:48:40 CEST schrieb Elaine Zhang:
> From: Finley Xiao <finley.xiao@rock-chips.com>
> 
> Solve the pd could only ever turn off but never turn them on again,
> If the pd registers have the writemask bits.
> 
> Fix up the code error for commit:
> 	commit 79bb17ce8edb3141339b5882e372d0ec7346217c
> 	Author: Elaine Zhang <zhangqing@rock-chips.com>
> 	Date:   Fri Dec 23 11:47:52 2016 +0800
> 
> 	soc: rockchip: power-domain: Support domain control in hiword-registers
> 
> 	New Rockchips SoCs may have their power-domain control in registers
> 	using a writemask-based access scheme (upper 16bit being the write
> 	mask). So add a DOMAIN_M type and handle this case accordingly.
> 	Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
> 	Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> 
> Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>

I've already applied that patch from v2.


Heiko

^ permalink raw reply

* Re: [PATCH v3 03/13] Soc: rockchip: power-domain: add power domain support for rk3036
From: Heiko Stübner @ 2018-05-23 10:57 UTC (permalink / raw)
  To: Elaine Zhang
  Cc: robh+dt, mark.rutland, devicetree, rjw, khilman, ulf.hansson,
	linux-pm, linux-arm-kernel, linux-rockchip, linux-kernel, wxt,
	xxx, xf, huangtao
In-Reply-To: <1527058129-10260-4-git-send-email-zhangqing@rock-chips.com>

Am Mittwoch, 23. Mai 2018, 08:48:39 CEST schrieb Elaine Zhang:
> From: Caesar Wang <wxt@rock-chips.com>
> 
> This driver is modified to support RK3036 SoC.
> 
> Signed-off-by: Caesar Wang <wxt@rock-chips.com>
> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>

> @@ -102,6 +103,14 @@ struct rockchip_pmu {
>  	.ack_mask = (ack >= 0) ? BIT(ack) : 0,		\
>  	.active_wakeup = wakeup,			\
>  }

I've added a blank line here, made "Soc" in the subject lower case and
applied it for 4.18 or 4.19 (not sure yet).


Thanks
Heiko

> +#define DOMAIN_RK3036(req, ack, idle, wakeup)		\
> +{							\
> +	.req_mask = (req >= 0) ? BIT(req) : 0,		\
> +	.req_w_mask = (req >= 0) ?  BIT(req + 16) : 0,	\
> +	.ack_mask = (ack >= 0) ? BIT(ack) : 0,		\
> +	.idle_mask = (idle >= 0) ? BIT(idle) : 0,	\
> +	.active_wakeup = wakeup,			\
> +}

^ permalink raw reply

* Re: [PATCH v3 02/13] dt-bindings: add binding for rk3036 power domains
From: Heiko Stübner @ 2018-05-23 10:56 UTC (permalink / raw)
  To: Elaine Zhang
  Cc: robh+dt, mark.rutland, devicetree, rjw, khilman, ulf.hansson,
	linux-pm, linux-arm-kernel, linux-rockchip, linux-kernel, wxt,
	xxx, xf, huangtao
In-Reply-To: <1527058129-10260-3-git-send-email-zhangqing@rock-chips.com>

Am Mittwoch, 23. Mai 2018, 08:48:38 CEST schrieb Elaine Zhang:
> From: Caesar Wang <wxt@rock-chips.com>
> 
> Add binding documentation for the power domains
> found on Rockchip RK3036 SoCs.
> 
> Signed-off-by: Caesar Wang <wxt@rock-chips.com>
> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
> Acked-by: Rob Herring <robh@kernel.org>


applied for 4.18 or 4.19 (not sure yet).


Thanks
Heiko

^ permalink raw reply

* Re: [PATCH v3 01/13] dt-bindings: power: add RK3036 SoCs header for power-domain
From: Heiko Stübner @ 2018-05-23 10:55 UTC (permalink / raw)
  To: Elaine Zhang
  Cc: robh+dt, mark.rutland, devicetree, rjw, khilman, ulf.hansson,
	linux-pm, linux-arm-kernel, linux-rockchip, linux-kernel, wxt,
	xxx, xf, huangtao
In-Reply-To: <1527058129-10260-2-git-send-email-zhangqing@rock-chips.com>

Am Mittwoch, 23. Mai 2018, 08:48:37 CEST schrieb Elaine Zhang:
> From: Caesar Wang <wxt@rock-chips.com>
> 
> According to a description from TRM, add all the power domains.
> 
> Signed-off-by: Caesar Wang <wxt@rock-chips.com>
> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>

applied for 4.18 or 4.19 (not sure yet) after adding
Rob's Review-tag from v2.


Thanks
Heiko

^ permalink raw reply

* Re: [PATCH v1] cpufreq: tegra20: Fix imbalanced clock enable count
From: Dmitry Osipenko @ 2018-05-23 10:44 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Thierry Reding, Jonathan Hunter, linux-tegra,
	linux-pm, linux-kernel
In-Reply-To: <20180523055817.subrv6oeckfecpcp@vireshk-i7>

On 23.05.2018 08:58, Viresh Kumar wrote:
> On 23-05-18, 00:14, Dmitry Osipenko wrote:
>> Tegra20-cpufreq driver missed enabling the CPU clocks. This results in a
>> clock-enable refcount disbalance on PLL_P <-> PLL_X reparent, causing
>> PLL_X to get disabled while it shouldn't. Fix this by enabling the clocks
>> on the driver probe.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>
>> CPUFreq maintainers,
>>
>> Please take into account that this patch is made on top of my recent
>> series of patches [0] "Clean up Tegra20 cpufreq driver" that was fully
>> reviewed, but seems not applied yet. Let me know if you prefer to re-spin
>> the [0], including this patch into the series.
>>
>> [0] https://patchwork.ozlabs.org/project/linux-tegra/list/?series=45321
> 
> This is already picked by Rafael and is sitting in pm/bleeding-edge
> branch. Should get merged into linux-next in a day or two.
> 
>>  drivers/cpufreq/tegra20-cpufreq.c | 16 +++++++++++++++-
>>  1 file changed, 15 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/cpufreq/tegra20-cpufreq.c b/drivers/cpufreq/tegra20-cpufreq.c
>> index 05f57dcd5215..ca5229265b60 100644
>> --- a/drivers/cpufreq/tegra20-cpufreq.c
>> +++ b/drivers/cpufreq/tegra20-cpufreq.c
>> @@ -176,6 +176,14 @@ static int tegra20_cpufreq_probe(struct platform_device *pdev)
>>  		goto put_pll_x;
>>  	}
>>  
>> +	err = clk_prepare_enable(cpufreq->pll_x_clk);
>> +	if (err)
>> +		goto put_pll_p;
>> +
>> +	err = clk_prepare_enable(cpufreq->pll_p_clk);
>> +	if (err)
>> +		goto disable_pll_x;
>> +
>>  	cpufreq->dev = &pdev->dev;
>>  	cpufreq->driver.get = cpufreq_generic_get;
>>  	cpufreq->driver.attr = cpufreq_generic_attr;
>> @@ -192,12 +200,16 @@ static int tegra20_cpufreq_probe(struct platform_device *pdev)
>>  
>>  	err = cpufreq_register_driver(&cpufreq->driver);
>>  	if (err)
>> -		goto put_pll_p;
>> +		goto disable_pll_p;
>>  
>>  	platform_set_drvdata(pdev, cpufreq);
>>  
>>  	return 0;
>>  
>> +disable_pll_p:
>> +	clk_disable_unprepare(cpufreq->pll_p_clk);
>> +disable_pll_x:
>> +	clk_disable_unprepare(cpufreq->pll_x_clk);
>>  put_pll_p:
>>  	clk_put(cpufreq->pll_p_clk);
>>  put_pll_x:
>> @@ -214,6 +226,8 @@ static int tegra20_cpufreq_remove(struct platform_device *pdev)
>>  
>>  	cpufreq_unregister_driver(&cpufreq->driver);
>>  
>> +	clk_disable_unprepare(cpufreq->pll_p_clk);
>> +	clk_disable_unprepare(cpufreq->pll_x_clk);
>>  	clk_put(cpufreq->pll_p_clk);
>>  	clk_put(cpufreq->pll_x_clk);
>>  	clk_put(cpufreq->cpu_clk);
> 
> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
> 

Please hold on this patch, seems I interpreted the cpufreq driver logic
incorrectly and it is probably fine as it is. I'll re-check later today.

^ permalink raw reply

* Re: [PATCH v10 1/2] cpufreq: Add Kryo CPU scaling driver
From: Sudeep Holla @ 2018-05-23 10:39 UTC (permalink / raw)
  To: Ilia Lin, vireshk, nm, sboyd, robh, mark.rutland, rjw, linux-pm,
	devicetree, linux-kernel
  Cc: Sudeep Holla
In-Reply-To: <1527068454-28921-2-git-send-email-ilialin@codeaurora.org>



On 23/05/18 10:40, Ilia Lin wrote:
> In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
> the CPU frequency subset and voltage value of each OPP varies
> based on the silicon variant in use. Qualcomm Process Voltage Scaling Tables
> defines the voltage and frequency value based on the msm-id in SMEM
> and speedbin blown in the efuse combination.
> The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
> to provide the OPP framework with required information.
> This is used to determine the voltage and frequency value for each OPP of
> operating-points-v2 table when it is parsed by the OPP framework.
> 
> Signed-off-by: Ilia Lin <ilialin@codeaurora.org>

[...]

> +	pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
> +	if (!IS_ERR(pdev))
> +		return 0;
> +
> +	ret = PTR_ERR(pdev);
> +	dev_err(cpu_dev, "Failed to register platform device\n");
> +
> +free_opp:
> +	for_each_possible_cpu(cpu) {
> +		if (IS_ERR_OR_NULL(opp_tables[cpu]))
> +			break;
> +		dev_pm_opp_put_supported_hw(opp_tables[cpu]);
> +	}
> +free_np:
> +	of_node_put(np);
> +
> +	return ret;
> +}
> +late_initcall(qcom_cpufreq_kryo_driver_init);

Any particular reason why this *has* to be late initcall ?
Please change it to module_initcall otherwise.
Also address the of_node comments from Viresh.

Otherwise, it looks good.
-- 
Regards,
Sudeep

^ permalink raw reply

* Re: [PATCH 8/9] PM / Domains: Add support for multi PM domains per device to genpd
From: Jon Hunter @ 2018-05-23 10:22 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rajendra Nayak, Geert Uytterhoeven, Linux PM, Greg Kroah-Hartman,
	Kevin Hilman, Rafael J . Wysocki, Linux Kernel Mailing List,
	Todor Tomov, Viresh Kumar, linux-tegra, Vincent Guittot,
	Linux ARM
In-Reply-To: <CAPDyKFoHwujfL4vpB8kq+rxDP4cThW4xB4nwb8Qc6_bZwTPbzA@mail.gmail.com>


On 23/05/18 10:47, Ulf Hansson wrote:
> On 23 May 2018 at 11:45, Jon Hunter <jonathanh@nvidia.com> wrote:
>>
>> On 23/05/18 10:33, Ulf Hansson wrote:
>>>
>>> On 23 May 2018 at 11:27, Rajendra Nayak <rnayak@codeaurora.org> wrote:
>>>>
>>>>
>>>>
>>>> On 05/23/2018 02:37 PM, Jon Hunter wrote:
>>>>>
>>>>>
>>>>> On 23/05/18 07:12, Ulf Hansson wrote:
>>>>>
>>>>> ...
>>>>>
>>>>>>>>>> Thanks for sending this. Believe it or not this has still been on
>>>>>>>>>> my to-do list
>>>>>>>>>> and so we definitely need a solution for Tegra.
>>>>>>>>>>
>>>>>>>>>> Looking at the above it appears that additional power-domains
>>>>>>>>>> exposed as devices
>>>>>>>>>> to the client device. So I assume that this means that the drivers
>>>>>>>>>> for devices
>>>>>>>>>> with multiple power-domains will need to call RPM APIs for each of
>>>>>>>>>> these
>>>>>>>>>> additional power-domains. Is that correct?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> They can, but should not!
>>>>>>>>>
>>>>>>>>> Instead, the driver shall use device_link_add() and
>>>>>>>>> device_link_del(),
>>>>>>>>> dynamically, depending on what PM domain that their original device
>>>>>>>>> needs for the current running use case.
>>>>>>>>>
>>>>>>>>> In that way, they keep existing runtime PM deployment, operating on
>>>>>>>>> its original device.
>>>>>>>>
>>>>>>>>
>>>>>>>> OK, sounds good. Any reason why the linking cannot be handled by the
>>>>>>>> above API? Is there a use-case where you would not want it linked?
>>>>>>>
>>>>>>>
>>>>>>> I am guessing the linking is what would give the driver the ability to
>>>>>>> decide which subset of powerdomains it actually wants to control
>>>>>>> at any point using runtime PM. If we have cases wherein the driver
>>>>>>> would want to turn on/off _all_ its associated powerdomains _always_
>>>>>>> then a default linking of all would help.
>>>>>>
>>>>>>
>>>>>> First, I think we need to decide on *where* the linking should be
>>>>>> done, not at both places, as that would just mess up synchronization
>>>>>> of who is responsible for calling the device_link_del() at detach.
>>>>>>
>>>>>> Second, It would in principle be fine to call device_link_add() and
>>>>>> device_link_del() as a part of the attach/detach APIs. However, there
>>>>>> is a downside to such solution, which would be that the driver then
>>>>>> needs call the detach API, just to do device_link_del(). Of course
>>>>>> then it would also needs to call the attach API later if/when needed.
>>>>>> Doing this adds unnecessary overhead - comparing to just let the
>>>>>> driver call device_link_add|del() when needed. On the upside, yes, it
>>>>>> would put less burden on the drivers as it then only needs to care
>>>>>> about using one set of functions.
>>>>>>
>>>>>> Which solution do you prefer?
>>>>>
>>>>>
>>>>> Any reason why we could not add a 'boolean' argument to the API to
>>>>> indicate whether the new device should be linked? I think that I prefer the
>>>>> API handles it, but I can see there could be instances where drivers may
>>>>> wish to handle it themselves.
>>>>>
>>>>> Rajendra, do you have a use-case right now where the driver would want
>>>>> to handle the linking?
>>>>
>>>>
>>>> So if I understand this right, any driver which does want to control
>>>> individual powerdomain state would
>>>> need to do the linking itself right?
>>>>
>>>> What I am saying is, if I have device A, with powerdomains X and Y, and
>>>> if I want to turn on only X,
>>>> then I would want only X to be linked with A, and at a later point if I
>>>> want both X and Y to be turned on,
>>>> I would then go ahead and link both X and Y to A? Is that correct or did
>>>> I get it all wrong?
>>>
>>>
>>> Correct!
>>>
>>>>
>>>> I know atleast Camera on msm8996 would need to do this since it has 2 vfe
>>>> powerdoamins, which can be
>>>> turned on one at a time (depending on what resolution needs to be
>>>> supported) or both together if we
>>>> really need very high resolution using both vfe modules.
>>>
>>>
>>> I think this is also the case for the Tegra XUSB subsystem.
>>>
>>> The usb device is always attached to one PM domain, but depending on
>>> if super-speed mode is used, another PM domain for that logic needs to
>>> be powered on as well.
>>>
>>> Jon, please correct me if I am wrong!
>>
>>
>> Yes this is technically correct, however, in reality I think we are always
>> going to enable the superspeed domain if either the host or device domain is
>> enabled. So we would probably always link the superspeed with the host and
>> device devices.
> 
> Why? Wouldn't that waste power if the superspeed mode isn't used?

Simply to reduce complexity.

Jon

-- 
nvpublic

^ permalink raw reply

* Re: [PATCH] cpufreq: schedutil: Avoid missing updates for one-CPU policies
From: Viresh Kumar @ 2018-05-23 10:14 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM, LKML, Peter Zijlstra, Juri Lelli, Joel Fernandes,
	Patrick Bellasi, claudio, Todd Kjos
In-Reply-To: <1672734.JYOlA1IWnU@aspire.rjw.lan>

On 23-05-18, 11:47, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Commit 152db033d775 (schedutil: Allow cpufreq requests to be made
> even when kthread kicked) made changes to prevent utilization updates
> from being discarded during processing a previous request, but it
> left a small window in which that still can happen in the one-CPU
> policy case.  Namely, updates coming in after setting work_in_progress
> in sugov_update_commit() and clearing it in sugov_work() will still
> be dropped due to the work_in_progress check in sugov_update_single().
> 
> To close that window, rearrange the code so as to acquire the update
> lock around the deferred update branch in sugov_update_single()
> and drop the work_in_progress check from it.
> 
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  kernel/sched/cpufreq_schedutil.c |   70 ++++++++++++++++++++++++++-------------
>  1 file changed, 47 insertions(+), 23 deletions(-)
> 
> Index: linux-pm/kernel/sched/cpufreq_schedutil.c
> ===================================================================
> --- linux-pm.orig/kernel/sched/cpufreq_schedutil.c
> +++ linux-pm/kernel/sched/cpufreq_schedutil.c
> @@ -100,25 +100,41 @@ static bool sugov_should_update_freq(str
>  	return delta_ns >= sg_policy->freq_update_delay_ns;
>  }
>  
> -static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time,
> -				unsigned int next_freq)
> +static bool sugov_update_next_freq(struct sugov_policy *sg_policy, u64 time,
> +				   unsigned int next_freq)
>  {
> -	struct cpufreq_policy *policy = sg_policy->policy;
> -
>  	if (sg_policy->next_freq == next_freq)
> -		return;
> +		return false;
>  
>  	sg_policy->next_freq = next_freq;
>  	sg_policy->last_freq_update_time = time;
>  
> -	if (policy->fast_switch_enabled) {
> -		next_freq = cpufreq_driver_fast_switch(policy, next_freq);
> -		if (!next_freq)
> -			return;
> +	return true;
> +}
> +
> +static void sugov_fast_switch(struct sugov_policy *sg_policy, u64 time,
> +			      unsigned int next_freq)
> +{
> +	struct cpufreq_policy *policy = sg_policy->policy;
> +
> +	if (!sugov_update_next_freq(sg_policy, time, next_freq))
> +		return;
> +
> +	next_freq = cpufreq_driver_fast_switch(policy, next_freq);
> +	if (!next_freq)
> +		return;
>  
> -		policy->cur = next_freq;
> -		trace_cpu_frequency(next_freq, smp_processor_id());
> -	} else if (!sg_policy->work_in_progress) {
> +	policy->cur = next_freq;
> +	trace_cpu_frequency(next_freq, smp_processor_id());
> +}
> +
> +static void sugov_deferred_update(struct sugov_policy *sg_policy, u64 time,
> +				  unsigned int next_freq)
> +{
> +	if (!sugov_update_next_freq(sg_policy, time, next_freq))
> +		return;
> +
> +	if (!sg_policy->work_in_progress) {
>  		sg_policy->work_in_progress = true;
>  		irq_work_queue(&sg_policy->irq_work);
>  	}
> @@ -363,13 +379,6 @@ static void sugov_update_single(struct u
>  
>  	ignore_dl_rate_limit(sg_cpu, sg_policy);
>  
> -	/*
> -	 * For slow-switch systems, single policy requests can't run at the
> -	 * moment if update is in progress, unless we acquire update_lock.
> -	 */
> -	if (sg_policy->work_in_progress)
> -		return;
> -
>  	if (!sugov_should_update_freq(sg_policy, time))
>  		return;
>  
> @@ -391,7 +400,18 @@ static void sugov_update_single(struct u
>  		sg_policy->cached_raw_freq = 0;
>  	}
>  
> -	sugov_update_commit(sg_policy, time, next_f);
> +	/*
> +	 * This code runs under rq->lock for the target CPU, so it won't run
> +	 * concurrently on two different CPUs for the same target and it is not
> +	 * necessary to acquire the lock in the fast switch case.
> +	 */
> +	if (sg_policy->policy->fast_switch_enabled) {
> +		sugov_fast_switch(sg_policy, time, next_f);
> +	} else {
> +		raw_spin_lock(&sg_policy->update_lock);
> +		sugov_deferred_update(sg_policy, time, next_f);
> +		raw_spin_unlock(&sg_policy->update_lock);
> +	}
>  }
>  
>  static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu, u64 time)
> @@ -435,7 +455,11 @@ sugov_update_shared(struct update_util_d
>  
>  	if (sugov_should_update_freq(sg_policy, time)) {
>  		next_f = sugov_next_freq_shared(sg_cpu, time);
> -		sugov_update_commit(sg_policy, time, next_f);
> +
> +		if (sg_policy->policy->fast_switch_enabled)
> +			sugov_fast_switch(sg_policy, time, next_f);
> +		else
> +			sugov_deferred_update(sg_policy, time, next_f);
>  	}
>  
>  	raw_spin_unlock(&sg_policy->update_lock);
> @@ -450,11 +474,11 @@ static void sugov_work(struct kthread_wo
>  	/*
>  	 * Hold sg_policy->update_lock shortly to handle the case where:
>  	 * incase sg_policy->next_freq is read here, and then updated by
> -	 * sugov_update_shared just before work_in_progress is set to false
> +	 * sugov_deferred_update() just before work_in_progress is set to false
>  	 * here, we may miss queueing the new update.
>  	 *
>  	 * Note: If a work was queued after the update_lock is released,
> -	 * sugov_work will just be called again by kthread_work code; and the
> +	 * sugov_work() will just be called again by kthread_work code; and the
>  	 * request will be proceed before the sugov thread sleeps.
>  	 */
>  	raw_spin_lock_irqsave(&sg_policy->update_lock, flags);

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

-- 
viresh

^ permalink raw reply

* Re: [PATCH] cpufreq: schedutil: Avoid missing updates for one-CPU policies
From: Juri Lelli @ 2018-05-23 10:13 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM, LKML, Peter Zijlstra, Viresh Kumar, Joel Fernandes,
	Patrick Bellasi, claudio, Todd Kjos
In-Reply-To: <1672734.JYOlA1IWnU@aspire.rjw.lan>

On 23/05/18 11:47, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Commit 152db033d775 (schedutil: Allow cpufreq requests to be made
> even when kthread kicked) made changes to prevent utilization updates
> from being discarded during processing a previous request, but it
> left a small window in which that still can happen in the one-CPU
> policy case.  Namely, updates coming in after setting work_in_progress
> in sugov_update_commit() and clearing it in sugov_work() will still
> be dropped due to the work_in_progress check in sugov_update_single().
> 
> To close that window, rearrange the code so as to acquire the update
> lock around the deferred update branch in sugov_update_single()
> and drop the work_in_progress check from it.
> 
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

I don't have a platform at hand where to test this. But, it looks OK to
me.

Reviewed-by: Juri Lelli <juri.lelli@redhat.com>

Best,

- Juri

^ permalink raw reply

* Re: [PATCH v2] schedutil: Allow cpufreq requests to be made even when kthread kicked
From: Viresh Kumar @ 2018-05-23 10:06 UTC (permalink / raw)
  To: Joel Fernandes
  Cc: Joel Fernandes (Google.), linux-kernel, Rafael J . Wysocki,
	Peter Zijlstra, Ingo Molnar, Patrick Bellasi, Juri Lelli,
	Luca Abeni, Todd Kjos, claudio, kernel-team, linux-pm
In-Reply-To: <6A76301E-E383-439D-AD1E-6DC2B2CAC3CE@joelfernandes.org>

On 23-05-18, 02:42, Joel Fernandes wrote:
> Probably. But then Rafael is changing single policy to use the lock
> so then barrier wouldn't be needed at all. In that case, both mine
> and Rafael new patch can go into stable which handles your race (
> optimization == fix in this case :P )

Yeah, we discussed that offline.

Go get some sleep. There are no barriers in this world :)

-- 
viresh

^ permalink raw reply

* Re: [PATCH v10 1/2] cpufreq: Add Kryo CPU scaling driver
From: Viresh Kumar @ 2018-05-23 10:03 UTC (permalink / raw)
  To: Ilia Lin
  Cc: vireshk, nm, sboyd, robh, mark.rutland, rjw, linux-pm, devicetree,
	linux-kernel
In-Reply-To: <1527068454-28921-2-git-send-email-ilialin@codeaurora.org>

On 23-05-18, 12:40, Ilia Lin wrote:
> In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
> the CPU frequency subset and voltage value of each OPP varies
> based on the silicon variant in use. Qualcomm Process Voltage Scaling Tables
> defines the voltage and frequency value based on the msm-id in SMEM
> and speedbin blown in the efuse combination.
> The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
> to provide the OPP framework with required information.
> This is used to determine the voltage and frequency value for each OPP of
> operating-points-v2 table when it is parsed by the OPP framework.
> 
> Signed-off-by: Ilia Lin <ilialin@codeaurora.org>

Well I gave you an Ack and you should have kept it here :(

> +static int __init qcom_cpufreq_kryo_driver_init(void)
> +{
> +	struct opp_table *opp_tables[NR_CPUS] = {0};
> +	enum _msm8996_version msm8996_version;
> +	struct nvmem_cell *speedbin_nvmem;
> +	struct platform_device *pdev;
> +	struct device_node *np;
> +	struct device *cpu_dev;
> +	unsigned cpu;
> +	u8 *speedbin;
> +	u32 versions;
> +	size_t len;
> +	int ret;
> +
> +	cpu_dev = get_cpu_device(0);
> +	if (NULL == cpu_dev)
> +		return -ENODEV;
> +
> +	msm8996_version = qcom_cpufreq_kryo_get_msm_id();
> +	if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
> +		dev_err(cpu_dev, "Not Snapdragon 820/821!");
> +		return -ENODEV;
> +	}
> +
> +	np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
> +	if (IS_ERR(np))
> +		return PTR_ERR(np);
> +
> +	if (!of_device_is_compatible(np, "operating-points-v2-kryo-cpu")) {
> +		ret = -ENOENT;
> +		goto free_np;

As Russell pointed out, drop this goto here and write:

                of_node_put(np);
                return -ENOENT;
        }

> +	}
> +
> +	speedbin_nvmem = of_nvmem_cell_get(np, NULL);

And do the same here unconditionally as you don't need to use np
anymore, i.e.

        of_node_put(np);

> +	if (IS_ERR(speedbin_nvmem)) {
> +		ret = PTR_ERR(speedbin_nvmem);
> +		dev_err(cpu_dev, "Could not get nvmem cell: %d\n", ret);
> +		goto free_np;
> +	}
> +
> +	speedbin = nvmem_cell_read(speedbin_nvmem, &len);
> +	nvmem_cell_put(speedbin_nvmem);
> +
> +	switch (msm8996_version) {
> +	case MSM8996_V3:
> +		versions = 1 << (unsigned int)(*speedbin);
> +		break;
> +	case MSM8996_SG:
> +		versions = 1 << ((unsigned int)(*speedbin) + 4);
> +		break;
> +	default:
> +		BUG();
> +		break;
> +	}
> +
> +	for_each_possible_cpu(cpu) {
> +		cpu_dev = get_cpu_device(cpu);
> +		if (NULL == cpu_dev) {
> +			ret = -ENODEV;
> +			goto free_opp;
> +		}
> +
> +		opp_tables[cpu] = dev_pm_opp_set_supported_hw(cpu_dev,
> +							      &versions, 1);
> +		if (IS_ERR(opp_tables[cpu])) {
> +			ret = PTR_ERR(opp_tables[cpu]);
> +			dev_err(cpu_dev, "Failed to set supported hardware\n");
> +			goto free_opp;
> +		}
> +	}
> +
> +	pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
> +	if (!IS_ERR(pdev))
> +		return 0;
> +
> +	ret = PTR_ERR(pdev);
> +	dev_err(cpu_dev, "Failed to register platform device\n");
> +
> +free_opp:
> +	for_each_possible_cpu(cpu) {
> +		if (IS_ERR_OR_NULL(opp_tables[cpu]))
> +			break;
> +		dev_pm_opp_put_supported_hw(opp_tables[cpu]);
> +	}
> +free_np:
> +	of_node_put(np);

And then you can remove the label and above statement.

> +
> +	return ret;
> +}
> +late_initcall(qcom_cpufreq_kryo_driver_init);
> +
> +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
> +MODULE_LICENSE("GPL v2");
> -- 
> 1.9.1

-- 
viresh

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox