Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0bc67e80 authored by David Collins's avatar David Collins Committed by Matt Wagantall
Browse files

regulator: cpr3-regulator: Add closed-loop CPR3 support



Add support in the cpr3-regulator driver to configure CPR3
controller registers.  This allows the supply rail to operate
in CPR closed-loop mode in which the CPR hardware is active.

For HMSS CPR3 controllers, also add support for CPR hardware
closed-loop mode.  Hardware closed-loop mode operates the same
way as software closed-loop mode except that CPR up/down voltage
stepping recommendations are handled completely in hardware.
Software does not receive any CPR interrupts when using hardware
closed-loop mode.

Change-Id: I67d13695bc82fbcfac8037990ab476ff76822235
Signed-off-by: default avatarDavid Collins <collinsd@codeaurora.org>
parent 2dc3a8f9
Loading
Loading
Loading
Loading
+83 −6
Original line number Diff line number Diff line
@@ -59,6 +59,42 @@ HMSS specific properties:
		    which may be used as the ceiling for the corner.  If this
		    property is not specified, then a value of 0 is assumed.

- qcom,cpr-up-down-delay-time
	Usage:      required
	Value type: <u32>
	Definition: The time to delay in nanoseconds between consecutive CPR
		    measurements when the last measurement recommended
		    increasing or decreasing the vdd-supply voltage.

- qcom,cpr-hw-closed-loop
	Usage:      optional
	Value type: <empty>
	Definition: Boolean flag which indicates that the HMSS CPR3 controller
		    should operate in hardware closed-loop mode as opposed to
		    software closed-loop mode.

- vdd-limit-supply
	Usage:      required
	Value type: <phandle>
	Definition: phandle of the VDD supply limit regulator which controls the
		    CPR ceiling and floor voltages when operating in hardware
		    closed-loop mode.

- qcom,cpr-clock-throttling
	Usage:      optional
	Value type: <u32>
	Definition: Specifies the power domains for which CPR processor clock
		    throttling should be enabled.  This feature reduces the
		    processor's clock frequency when it is resuming from a low
		    power mode until CPR is able to raise the supply voltage to
		    a final settled value.  The following bits may be set:
			BIT(0) - Power cluster L2 cache
			BIT(1) - Power cluster core 1
			BIT(2) - Power cluster core 0
			BIT(5) - Performance cluster L2 cache
			BIT(6) - Performance cluster core 1
			BIT(7) - Performance cluster core 0

=================================================
Second Level Nodes - CPR Threads for a Controller
=================================================
@@ -67,8 +103,13 @@ HMSS specific properties:
- qcom,cpr-fuse-corners
	Usage:      required
	Value type: <u32>
	Definition: Specifies the number of fuse corners.  This value must be 4
		    for HMSS.
	Definition: Specifies the number of fuse corners.  This value must be 5
		    for HMSS.  These fuse corners are: MinSVS, LowSVS, SVS,
		    Nominal, and Turbo.  Note that a specific fused target
		    quotient is available for the LowSVS corner but a fused
		    open-loop voltage is not available.  The LowSVS open-loop
		    voltage is calculated using linear interpolation between
		    the MinSVS and SVS values.

- qcom,cpr-fuse-combos
	Usage:      required
@@ -79,6 +120,13 @@ HMSS specific properties:
		    possible for a given regulator type.  For HMSS the maximum
		    supported value is 1.

- qcom,allow-quotient-interpolation
	Usage:      optional
	Value type: <empty>
	Definition: Boolean flag which indicates that it is acceptable to use
		    interpolated CPR target quotient values.  These values are
		    interpolated between the target quotient Fmax fuse values.

=======
Example
=======
@@ -87,13 +135,28 @@ apcc_cpr: cpr3-ctrl@99e8000 {
	compatible = "qcom,cpr3-msm8996-hmss-regulator";
	reg = <0x099e8000 0x4000>, <0x00074000 0x1000>;
	reg-names = "cpr_ctrl", "fuse_base";
	clocks = <&clock_gcc clk_gcc_hmss_rbcpr_clk>;
	clock-names = "core_clk";
	interrupts = <0 48 0>;
	qcom,cpr-ctrl-name = "apcc";

	qcom,cpr-sensor-time = <1000>;
	qcom,cpr-loop-time = <5000000>;
	qcom,cpr-idle-cycles = <15>;
	qcom,cpr-up-down-delay-time = <3000>;
	qcom,cpr-step-quot-init-min = <13>;
	qcom,cpr-step-quot-init-max = <13>;
	qcom,cpr-count-mode = <2>;

	qcom,apm-ctrl = <&apc_apm>;
	qcom,apm-threshold-voltage = <850000>;
	qcom,apm-hysteresis-voltage = <5000>;

	vdd-supply = <&pm8994_s11>;
	vdd-limit-supply = <&pm8994_s11_limit>;

	qcom,cpr-enable;
	qcom,cpr-hw-closed-loop;

	apc0_vreg: regulator@0 {
		qcom,cpr-thread-id = <0>;
@@ -103,11 +166,16 @@ apcc_cpr: cpr3-ctrl@99e8000 {

		qcom,voltage-step = <5000>;

		qcom,cpr-fuse-corners = <4>;
		qcom,cpr-consecutive-up = <0>;
		qcom,cpr-consecutive-down = <2>;
		qcom,cpr-up-threshold = <0>;
		qcom,cpr-down-threshold = <2>;

		qcom,cpr-fuse-corners = <5>;
		qcom,cpr-fuse-combos = <1>;
		qcom,cpr-corners = <19>;

		qcom,cpr-corner-fmax-map = <1 6 11 19>;
		qcom,cpr-corner-fmax-map = <1 2 6 11 19>;

		qcom,cpr-voltage-ceiling =
			<605000  670000  745000  745000  745000  745000
@@ -128,6 +196,8 @@ apcc_cpr: cpr3-ctrl@99e8000 {
			1344000000 1420800000 1459200000>;

		qcom,allow-voltage-interpolation;
		qcom,allow-quotient-interpolation;
		qcom,cpr-scaled-open-loop-voltage-as-ceiling;
	};

	apc1_vreg: regulator@1 {
@@ -138,11 +208,16 @@ apcc_cpr: cpr3-ctrl@99e8000 {

		qcom,voltage-step = <5000>;

		qcom,cpr-fuse-corners = <4>;
		qcom,cpr-consecutive-up = <0>;
		qcom,cpr-consecutive-down = <2>;
		qcom,cpr-up-threshold = <0>;
		qcom,cpr-down-threshold = <2>;

		qcom,cpr-fuse-corners = <5>;
		qcom,cpr-fuse-combos = <1>;
		qcom,cpr-corners = <18>;

		qcom,cpr-corner-fmax-map = <1 5 11 18>;
		qcom,cpr-corner-fmax-map = <1 3 5 11 18>;

		qcom,cpr-voltage-ceiling =
			<605000  670000  670000  745000  745000  905000
@@ -161,5 +236,7 @@ apcc_cpr: cpr3-ctrl@99e8000 {
			1497600000 1593600000>;

		qcom,allow-voltage-interpolation;
		qcom,allow-quotient-interpolation;
		qcom,cpr-scaled-open-loop-voltage-as-ceiling;
	};
};
+64 −0
Original line number Diff line number Diff line
@@ -28,6 +28,21 @@ MMSS specific properties:
	Value type: <string>
	Definition: should be "qcom,cpr3-msm8996-mmss-regulator"

- clocks
	Usage:      required
	Value type: <prop-encoded-array>
	Definition: Array of clock tuples in which each tuple consists of a
		    phandle to a clock device and a clock ID number.  The
		    following clocks must be specified: MMSS RBCPR, MMSS RBCPR
		    AHB, and MMSS MMAGIC AHB.

- clock-names
	Usage:      required
	Value type: <stringlist>
	Definition: Clock names.  This list must match up 1-to-1 with the clocks
		    specified in the 'clocks' property. "core_clk", "iface_clk",
		    and "bus_clk" must be specified.

=================================================
Second Level Nodes - CPR Threads for a Controller
=================================================
@@ -48,6 +63,29 @@ HMSS specific properties:
		    possible for a given regulator type.  For MMSS the maximum
		    supported value is 1.

- qcom,cpr-target-quotients
	Usage:      required
	Value type: <prop-encoded-array>
	Definition: A grouping of integer tuple lists.  Each tuple defines the
		    CPR target quotient for each ring oscillator (RO) for a
		    given corner.  Since CPR3 supports exactly 16 ROs, each
		    tuple must contain 16 elements corresponding to RO0 through
		    RO15 in order.  If a given RO is unused for a corner, then
		    its target quotient should be specified as 0.

		    Each tuple list must contain the number of tuples defined in
		    the corresponding element of the qcom,cpr-corners property.
		    A single tuple list may only be specified if all of the
		    corner counts in qcom,cpr-corners are the same.  The tuples
		    in a given list are ordered from the lowest corner to the
		    highest corner.

		    The tuple list grouping must contain either
		    qcom,cpr-fuse-combos number of tuple lists in which case the
		    lists are matched to fuse combinations 1-to-1 or the
		    grouping must contain exactly 1 list which is used
		    regardless of the fuse combination found on a given chip.

=======
Example
=======
@@ -56,10 +94,24 @@ gfx_cpr: cpr3-ctrl@838000 {
	compatible = "qcom,cpr3-msm8996-mmss-regulator";
	reg = <0x00838000 0x4000>, <0x00074000 0x1000>;
	reg-names = "cpr_ctrl", "fuse_base";
	clocks = <&clock_mmss clk_mmss_rbcpr_clk>,
		 <&clock_mmss clk_mmss_rbcpr_ahb_clk>,
		 <&clock_mmss clk_mmss_mmagic_ahb_clk>;
	clock-names = "core_clk", "iface_clk", "bus_clk";
	interrupts = <0 166 0>;
	qcom,cpr-ctrl-name = "gfx";

	qcom,cpr-sensor-time = <1000>;
	qcom,cpr-loop-time = <5000000>;
	qcom,cpr-idle-cycles = <15>;
	qcom,cpr-step-quot-init-min = <13>;
	qcom,cpr-step-quot-init-max = <13>;
	qcom,cpr-count-mode = <2>;

	vdd-supply = <&pmi8994_s2>;

	qcom,cpr-enable;

	gfx_vreg: regulator@0 {
		qcom,cpr-thread-id = <0>;
		regulator-name = "gfx_corner";
@@ -68,6 +120,11 @@ gfx_cpr: cpr3-ctrl@838000 {

		qcom,voltage-step = <5000>;

		qcom,cpr-consecutive-up = <0>;
		qcom,cpr-consecutive-down = <2>;
		qcom,cpr-up-threshold = <0>;
		qcom,cpr-down-threshold = <2>;

		qcom,cpr-fuse-corners = <4>;
		qcom,cpr-fuse-combos = <1>;
		qcom,cpr-corners = <4>;
@@ -80,6 +137,13 @@ gfx_cpr: cpr3-ctrl@838000 {
		qcom,corner-frequencies =
			<120000000 205000000 360000000 480000000>;

		qcom,cpr-target-quotients =
			<0 0 0 0 249 232 0  394 0  422 0 0 0 0 0 0>,
			<0 0 0 0 400 363 0  565 0  603 0 0 0 0 0 0>,
			<0 0 0 0 669 601 0  851 0  905 0 0 0 0 0 0>,
			<0 0 0 0 899 806 0 1084 0 1149 0 0 0 0 0 0>;

		qcom,allow-voltage-interpolation;
		qcom,cpr-scaled-open-loop-voltage-as-ceiling;
	};
};
+112 −1
Original line number Diff line number Diff line
@@ -55,6 +55,86 @@ Platform independent properties:
	Definition: phandle of the underlying regulator device that is managed
		    by this CPR controller.

- clocks
	Usage:      required
	Value type: <prop-encoded-array>
	Definition: Array of clock tuples in which each tuple consists of a
		    phandle to a clock device and a clock ID number.  The CPR3
		    core clock must be specified.  See platform specific
		    cpr3-regulator binding documentation for additional clocks
		    that may also need to be specified.

- clock-names
	Usage:      required
	Value type: <stringlist>
	Definition: Clock names.  This list must match up 1-to-1 with the clocks
		    specified in the 'clocks' property. "core_clk" must be
		    specified.  Other clocks may be required for some platforms.

- interrupts
	Usage:      required
	Value type: <prop-encoded-array>
	Definition: CPR interrupt specifier.

- qcom,cpr-sensor-time
	Usage:      required
	Value type: <u32>
	Definition: The time in nanoseconds that each CPR sensor within the
		    sensing loop takes to perform a measurement.

- qcom,cpr-loop-time
	Usage:      required
	Value type: <u32>
	Definition: The time in nanoseconds between consecutive CPR
		    measurements.

- qcom,cpr-idle-cycles
	Usage:      required
	Value type: <u32>
	Definition: The number of CPR core clock cycles for the CPR controller
		    to wait in transitional states.
		    Supported values: 0 - 31.

- qcom,cpr-step-quot-init-min
	Usage:      required
	Value type: <u32>
	Definition: The default minimum CPR step quotient value.  The step
		    quotient is the number of additional ring oscillator ticks
		    observed for each qcom,voltage-step increase in vdd-supply
		    output voltage.  Supported values: 0 - 63.

- qcom,cpr-step-quot-init-max
	Usage:      required
	Value type: <u32>
	Definition: The default maximum CPR step quotient value.
		    Supported values: 0 - 63.

- qcom,cpr-count-mode
	Usage:      required
	Value type: <u32>
	Definition: The CPR counting mode to use during CPR measurements.
		    Supported values:
			0 - Read all sensors at once and use the minimum
			    quotient value observed in repeated measurements.
			1 - Read all sensors at once and use the maximum
			    quotient value observed in repeated measurements.
			2 - Read each sensor once in a sequential, staggered
			    fashion.

- qcom,cpr-count-repeat
	Usage:      optional
	Value type: <u32>
	Definition: The number of times to read CPR sensors during a single CPR
		    measurement when using one of the all-at-once count modes.

- qcom,cpr-enable
	Usage:      optional
	Value type: <empty>
	Definition: Boolean flag which indicates that the CPR3 controller
		    should operate in closed-loop mode (i.e. CPR sensing loop
		    enabled) as opposed to open-loop mode (i.e. CPR sensing loop
		    disabled) by default.

=================================================
Second Level Nodes - CPR Threads for a Controller
=================================================
@@ -89,6 +169,30 @@ Platform independent properties:
	Definition: The voltage in microvolts of a single step of the VDD supply
		    regulator being controlled by CPR.

- qcom,cpr-consecutive-up
	Usage:      required
	Value type: <u32>
	Definition: The number of consecutive CPR step up events needed to
		    to trigger an up interrupt.  Supported values: 0 - 15.

- qcom,cpr-consecutive-down
	Usage:      required
	Value type: <u32>
	Definition: The number of consecutive CPR step down events needed to
		    to trigger a down interrupt.  Supported values: 0 - 15.

- qcom,cpr-up-threshold
	Usage:      required
	Value type: <u32>
	Definition: The number CPR error steps required to generate an up event.
		    Supported values: 0 - 31.

- qcom,cpr-down-threshold
	Usage:      required
	Value type: <u32>
	Definition: The number CPR error steps required to generate a down
		    event.  Supported values: 0 - 31.

- qcom,cpr-fuse-corners
	Usage:      required
	Value type: <u32>
@@ -174,6 +278,13 @@ Platform independent properties:
		    interpolated open-loop voltage values.  These values are
		    interpolated between the open-loop voltage Fmax fuse values.

- qcom,cpr-scaled-open-loop-voltage-as-ceiling
	Usage:      optional
	Value type: <empty>
	Definition: Boolean flag which indicates that it is acceptable to use
		    the interpolated open-loop voltage for each corner as the
		    CPR ceiling voltage for each corner.

All properties specified within the core regulator framework can also be used in
second level nodes.  These bindings can be found in:
Documentation/devicetree/bindings/regulator/regulator.txt.
+54 −4
Original line number Diff line number Diff line
@@ -549,13 +549,25 @@
		compatible = "qcom,cpr3-msm8996-hmss-regulator";
		reg = <0x099e8000 0x4000>, <0x00074000 0x1000>;
		reg-names = "cpr_ctrl", "fuse_base";
		clocks = <&clock_gcc clk_gcc_hmss_rbcpr_clk>;
		clock-names = "core_clk";
		interrupts = <0 48 0>;
		qcom,cpr-ctrl-name = "apcc";

		qcom,cpr-sensor-time = <1000>;
		qcom,cpr-loop-time = <5000000>;
		qcom,cpr-idle-cycles = <15>;
		qcom,cpr-up-down-delay-time = <3000>;
		qcom,cpr-step-quot-init-min = <13>;
		qcom,cpr-step-quot-init-max = <13>;
		qcom,cpr-count-mode = <2>;		/* Staggered */

		qcom,apm-ctrl = <&apc_apm>;
		qcom,apm-threshold-voltage = <850000>;
		qcom,apm-hysteresis-voltage = <5000>;

		vdd-supply = <&pm8994_s11>;
		vdd-limit-supply = <&pm8994_s11_limit>;

		apc0_vreg: regulator@0 {
			qcom,cpr-thread-id = <0>;
@@ -565,11 +577,16 @@

			qcom,voltage-step = <5000>;

			qcom,cpr-fuse-corners = <4>;
			qcom,cpr-consecutive-up = <0>;
			qcom,cpr-consecutive-down = <2>;
			qcom,cpr-up-threshold = <0>;
			qcom,cpr-down-threshold = <2>;

			qcom,cpr-fuse-corners = <5>;
			qcom,cpr-fuse-combos = <1>;
			qcom,cpr-corners = <19>;

			qcom,cpr-corner-fmax-map = <1 6 11 19>;
			qcom,cpr-corner-fmax-map = <1 2 6 11 19>;

			qcom,cpr-voltage-ceiling =
				<605000  670000  745000  745000  745000  745000
@@ -590,6 +607,8 @@
				1344000000 1420800000 1459200000>;

			qcom,allow-voltage-interpolation;
			qcom,allow-quotient-interpolation;
			qcom,cpr-scaled-open-loop-voltage-as-ceiling;
		};

		apc1_vreg: regulator@1 {
@@ -600,11 +619,16 @@

			qcom,voltage-step = <5000>;

			qcom,cpr-fuse-corners = <4>;
			qcom,cpr-consecutive-up = <0>;
			qcom,cpr-consecutive-down = <2>;
			qcom,cpr-up-threshold = <0>;
			qcom,cpr-down-threshold = <2>;

			qcom,cpr-fuse-corners = <5>;
			qcom,cpr-fuse-combos = <1>;
			qcom,cpr-corners = <18>;

			qcom,cpr-corner-fmax-map = <1 5 11 18>;
			qcom,cpr-corner-fmax-map = <1 3 5 11 18>;

			qcom,cpr-voltage-ceiling =
				<605000  670000  670000  745000  745000  905000
@@ -623,6 +647,8 @@
				1497600000 1593600000>;

			qcom,allow-voltage-interpolation;
			qcom,allow-quotient-interpolation;
			qcom,cpr-scaled-open-loop-voltage-as-ceiling;
		};
	};

@@ -630,8 +656,20 @@
		compatible = "qcom,cpr3-msm8996-mmss-regulator";
		reg = <0x00838000 0x4000>, <0x00074000 0x1000>;
		reg-names = "cpr_ctrl", "fuse_base";
		clocks = <&clock_mmss clk_mmss_rbcpr_clk>,
			 <&clock_mmss clk_mmss_rbcpr_ahb_clk>,
			 <&clock_mmss clk_mmss_mmagic_ahb_clk>;
		clock-names = "core_clk", "iface_clk", "bus_clk";
		interrupts = <0 166 0>;
		qcom,cpr-ctrl-name = "gfx";

		qcom,cpr-sensor-time = <1000>;
		qcom,cpr-loop-time = <5000000>;
		qcom,cpr-idle-cycles = <15>;
		qcom,cpr-step-quot-init-min = <13>;
		qcom,cpr-step-quot-init-max = <13>;
		qcom,cpr-count-mode = <2>;		/* Staggered */

		vdd-supply = <&pmi8994_s2>;

		gfx_vreg: regulator@0 {
@@ -642,6 +680,11 @@

			qcom,voltage-step = <5000>;

			qcom,cpr-consecutive-up = <0>;
			qcom,cpr-consecutive-down = <2>;
			qcom,cpr-up-threshold = <0>;
			qcom,cpr-down-threshold = <2>;

			qcom,cpr-fuse-corners = <4>;
			qcom,cpr-fuse-combos = <1>;
			qcom,cpr-corners = <4>;
@@ -656,7 +699,14 @@
			qcom,corner-frequencies =
				<120000000 205000000 360000000 480000000>;

			qcom,cpr-target-quotients =
				<0 0 0 0 249 232 0  394 0  422 0 0 0 0 0 0>,
				<0 0 0 0 400 363 0  565 0  603 0 0 0 0 0 0>,
				<0 0 0 0 669 601 0  851 0  905 0 0 0 0 0 0>,
				<0 0 0 0 899 806 0 1084 0 1149 0 0 0 0 0 0>;

			qcom,allow-voltage-interpolation;
			qcom,cpr-scaled-open-loop-voltage-as-ceiling;
		};
	};
};
+321 −24

File changed.

Preview size limit exceeded, changes collapsed.

Loading