Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1619364 > unrolled thread

[PATCH 0/5] Some Allwinner CCU tweaks and basical DVFS support for H3/H2+

Started byIcenowy Zheng <icenowy@aosc.io>
First post2017-04-08 21:00 +0200
Last post2017-04-08 21:00 +0200
Articles 6 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/5] Some Allwinner CCU tweaks and basical DVFS support for H3/H2+ Icenowy Zheng <icenowy@aosc.io> - 2017-04-08 21:00 +0200
    [PATCH 3/5] cpufreq: dt: Add support for some new Allwinner SoCs Icenowy Zheng <icenowy@aosc.io> - 2017-04-08 21:00 +0200
    [PATCH 1/5] clk: sunxi-ng: prevent NKMP clocks from temporarily get higher freq Icenowy Zheng <icenowy@aosc.io> - 2017-04-08 21:00 +0200
      Re: [linux-sunxi] [PATCH 1/5] clk: sunxi-ng: prevent NKMP clocks  from temporarily get higher freq Ondřej Jirman <megi@xff.cz> - 2017-04-09 00:10 +0200
    [PATCH 4/5] ARM: sun8i: h3: add operating-points-v2 table for CPU Icenowy Zheng <icenowy@aosc.io> - 2017-04-08 21:00 +0200
    [PATCH 5/5] ARM: sun8i: h2+: add SY8113B regulator used by Orange Pi Zero board Icenowy Zheng <icenowy@aosc.io> - 2017-04-08 21:00 +0200

#1619364 — [PATCH 0/5] Some Allwinner CCU tweaks and basical DVFS support for H3/H2+

FromIcenowy Zheng <icenowy@aosc.io>
Date2017-04-08 21:00 +0200
Subject[PATCH 0/5] Some Allwinner CCU tweaks and basical DVFS support for H3/H2+
Message-ID<tu3Kx-yE-3@gated-at.bofh.it>
This patchset aim to add basical DVFS support for Allwinner H3/H2+ SoCs, they
seem to be nearly the same.

The first patch is a CCU fix for all NKMP-type clocks, not H3 limited. Please
schedule this patch to 4.11 queue, as A33 needs also this patch. It solves the
problem that system hangs when the PLL_CPUX change for the first time.

The second patch allows the PLL_CPUX to change for CPUX clock on H3.

The third patch imports a bunch of new SoCs' compatibles into
cpufreq-dt-platdev driver.

The fourth patch adds several operating points for Allwinner H3/H2+ CPU.

The fifth patch adds the regulator node to Orange Pi Zero board's device
tree.

Icenowy Zheng (5):
  clk: sunxi-ng: prevent NKMP clocks from temporarily get higher freq
  clk: sunxi-ng: allow set parent clock (PLL_CPUX) for CPUX clock on H3
  cpufreq: dt: Add support for some new Allwinner SoCs
  ARM: sun8i: h3: add operating-points-v2 table for CPU
  ARM: sun8i: h2+: add SY8113B regulator used by Orange Pi Zero board

 arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts | 21 +++++++
 arch/arm/boot/dts/sun8i-h3.dtsi                   | 38 +++++++++++-
 drivers/clk/sunxi-ng/ccu-sun8i-h3.c               |  2 +-
 drivers/clk/sunxi-ng/ccu_nkmp.c                   | 76 +++++++++++++++++++----
 drivers/cpufreq/cpufreq-dt-platdev.c              |  5 ++
 5 files changed, 129 insertions(+), 13 deletions(-)

-- 
2.12.2

[toc] | [next] | [standalone]


#1619365 — [PATCH 3/5] cpufreq: dt: Add support for some new Allwinner SoCs

FromIcenowy Zheng <icenowy@aosc.io>
Date2017-04-08 21:00 +0200
Subject[PATCH 3/5] cpufreq: dt: Add support for some new Allwinner SoCs
Message-ID<tu3Kx-yE-5@gated-at.bofh.it>
In reply to#1619364
Some new Allwinner SoCs get supported in the kernel after the
compatibles are added to cpufreq-dt-platdev driver.

Add their compatible strings in the cpufreq-dt-platdev driver.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 drivers/cpufreq/cpufreq-dt-platdev.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index 921b4a6c3d16..2180e509e383 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -24,7 +24,12 @@ static const struct of_device_id machines[] __initconst = {
 	{ .compatible = "allwinner,sun8i-a23", },
 	{ .compatible = "allwinner,sun8i-a33", },
 	{ .compatible = "allwinner,sun8i-a83t", },
+	{ .compatible = "allwinner,sun8i-h2-plus", },
 	{ .compatible = "allwinner,sun8i-h3", },
+	{ .compatible = "allwinner,sun8i-v3s", },
+	{ .compatible = "allwinner,sun50i-a64", },
+	{ .compatible = "allwinner,sun50i-h5", },
+	{ .compatible = "nextthing,gr8", },
 
 	{ .compatible = "apm,xgene-shadowcat", },
 
-- 
2.12.2

[toc] | [prev] | [next] | [standalone]


#1619367 — [PATCH 1/5] clk: sunxi-ng: prevent NKMP clocks from temporarily get higher freq

FromIcenowy Zheng <icenowy@aosc.io>
Date2017-04-08 21:00 +0200
Subject[PATCH 1/5] clk: sunxi-ng: prevent NKMP clocks from temporarily get higher freq
Message-ID<tu3Kx-yE-11@gated-at.bofh.it>
In reply to#1619364
It seems that on newer SoCs (already observed on A33, H3), when setting
all NKMP factors at the same time, the multiplier get applied first,
then the divider get applied. In some situations (e.g. the multiplier
increased but the divider decreased), this will make the clock
frequency temporarily higher than both the original frequency and the
target frequency, which may lead to system hang due to PLL_CPU(X) clock
usually being a NKMP clock.

A comparsion between the old divider (M*P) and the new one is added, and
if the divider get smaller when changing clock, the multiplier will be
applied first, so that the clock won't go to a frequency higher than
normal.

The interval between applying the first group of factors and the second
group is based on experiments results on an Orange Pi Zero board.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 drivers/clk/sunxi-ng/ccu_nkmp.c | 76 +++++++++++++++++++++++++++++++++++------
 1 file changed, 65 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
index e58c95787f94..5da77eb60335 100644
--- a/drivers/clk/sunxi-ng/ccu_nkmp.c
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/clk-provider.h>
+#include <linux/delay.h>
 
 #include "ccu_gate.h"
 #include "ccu_nkmp.h"
@@ -130,12 +131,49 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
 	return *parent_rate * _nkmp.n * _nkmp.k / (_nkmp.m * _nkmp.p);
 }
 
+static void ccu_nkmp_extract_factors(const struct ccu_nkmp *nkmp,
+				     struct _ccu_nkmp *_nkmp, u32 reg)
+{
+	_nkmp->n = ((reg >> nkmp->n.shift) & GENMASK(nkmp->n.width - 1, 0))
+		   + nkmp->n.offset;
+	_nkmp->k = ((reg >> nkmp->k.shift) & GENMASK(nkmp->k.width - 1, 0))
+		   + nkmp->k.offset;
+	_nkmp->m = ((reg >> nkmp->m.shift) & GENMASK(nkmp->m.width - 1, 0))
+		   + nkmp->m.offset;
+	_nkmp->p = 1 <<
+		   ((reg >> nkmp->p.shift) & GENMASK(nkmp->p.width - 1, 0));
+}
+
+static u32 ccu_nkmp_apply_multiplier(const struct ccu_nkmp *nkmp,
+				     const struct _ccu_nkmp *_nkmp, u32 reg)
+{
+	reg &= ~GENMASK(nkmp->n.width + nkmp->n.shift - 1, nkmp->n.shift);
+	reg &= ~GENMASK(nkmp->k.width + nkmp->k.shift - 1, nkmp->k.shift);
+
+	reg |= (_nkmp->n - nkmp->n.offset) << nkmp->n.shift;
+	reg |= (_nkmp->k - nkmp->k.offset) << nkmp->k.shift;
+
+	return reg;
+}
+
+static u32 ccu_nkmp_apply_divider(const struct ccu_nkmp *nkmp,
+				  const struct _ccu_nkmp *_nkmp, u32 reg)
+{
+	reg &= ~GENMASK(nkmp->m.width + nkmp->m.shift - 1, nkmp->m.shift);
+	reg &= ~GENMASK(nkmp->p.width + nkmp->p.shift - 1, nkmp->p.shift);
+
+	reg |= (_nkmp->m - nkmp->m.offset) << nkmp->m.shift;
+	reg |= ilog2(_nkmp->p) << nkmp->p.shift;
+
+	return reg;
+}
+
 static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
 			   unsigned long parent_rate)
 {
 	struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
-	struct _ccu_nkmp _nkmp;
-	unsigned long flags;
+	struct _ccu_nkmp _nkmp, _nkmp_old;
+	unsigned long flags, old_mp, mp;
 	u32 reg;
 
 	_nkmp.min_n = nkmp->n.min ?: 1;
@@ -152,17 +190,33 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
 	spin_lock_irqsave(nkmp->common.lock, flags);
 
 	reg = readl(nkmp->common.base + nkmp->common.reg);
-	reg &= ~GENMASK(nkmp->n.width + nkmp->n.shift - 1, nkmp->n.shift);
-	reg &= ~GENMASK(nkmp->k.width + nkmp->k.shift - 1, nkmp->k.shift);
-	reg &= ~GENMASK(nkmp->m.width + nkmp->m.shift - 1, nkmp->m.shift);
-	reg &= ~GENMASK(nkmp->p.width + nkmp->p.shift - 1, nkmp->p.shift);
 
-	reg |= (_nkmp.n - nkmp->n.offset) << nkmp->n.shift;
-	reg |= (_nkmp.k - nkmp->k.offset) << nkmp->k.shift;
-	reg |= (_nkmp.m - nkmp->m.offset) << nkmp->m.shift;
-	reg |= ilog2(_nkmp.p) << nkmp->p.shift;
+	ccu_nkmp_extract_factors(nkmp, &_nkmp_old, reg);
+
+	old_mp = _nkmp_old.m * _nkmp_old.p;
+	mp = _nkmp.m * _nkmp.p;
+
+	if (mp > old_mp) {
+		reg = ccu_nkmp_apply_divider(nkmp, &_nkmp, reg);
+		writel(reg, nkmp->common.base + nkmp->common.reg);
+
+		/*
+		 * This value is decided by experiment results on an
+		 * Allwinner H2+ board (Orange Pi Zero).
+		 */
+		udelay(500);
 
-	writel(reg, nkmp->common.base + nkmp->common.reg);
+		reg = ccu_nkmp_apply_multiplier(nkmp, &_nkmp, reg);
+		writel(reg, nkmp->common.base + nkmp->common.reg);
+	} else {
+		reg = ccu_nkmp_apply_multiplier(nkmp, &_nkmp, reg);
+		writel(reg, nkmp->common.base + nkmp->common.reg);
+
+		udelay(500);
+
+		reg = ccu_nkmp_apply_divider(nkmp, &_nkmp, reg);
+		writel(reg, nkmp->common.base + nkmp->common.reg);
+	}
 
 	spin_unlock_irqrestore(nkmp->common.lock, flags);
 
-- 
2.12.2

[toc] | [prev] | [next] | [standalone]


#1619392 — Re: [linux-sunxi] [PATCH 1/5] clk: sunxi-ng: prevent NKMP clocks from temporarily get higher freq

FromOndřej Jirman <megi@xff.cz>
Date2017-04-09 00:10 +0200
SubjectRe: [linux-sunxi] [PATCH 1/5] clk: sunxi-ng: prevent NKMP clocks from temporarily get higher freq
Message-ID<tu6Iq-2HH-1@gated-at.bofh.it>
In reply to#1619367
Hi Icenowy,

I already tried this approach to changing CPUX_PLL and it didn't work
well. I've written a test program for CPUS (additional RISC-V processor
on H3 SoC) for testing various NKMP clock change algorithms, by
randomly changing the PLL frequency. Everything except simply not using
dividers except for P for frequencies < 288MHz just led to crashes of
the main CPU.

It is really hard to rule out crashes just by using the kernel itself,
because it is hard to hit the wrong change in the combination of NKMP
clock factors.

Here's the code for CPUS test program: https://github.com/megous/h3-fir
mware

Your approach is similar to this (increase dividers if necessary, wait
a bit, then change multipliers, wait a bit, and then decrease dividers
if necessary) - which is the approach taken by Allwinner in their code:

https://github.com/megous/h3-firmware/blob/master/clk.c#L683

It sometimes works when done in the kernel, but it is not stable. You
might get a crash only if thermal throttling causes a specific
transition between two particular frequencies. It's hard and tedious to
reproduce. That's why I have written the test program. In the CPUS test
program it crashes the main CPU predictably in about 2 seconds.

You can try it yourself with your exact algorithm. I guess it will be
crashing too.

regards,
  o.j.

Icenowy Zheng píše v Ne 09. 04. 2017 v 02:50 +0800:
> It seems that on newer SoCs (already observed on A33, H3), when setting
> all NKMP factors at the same time, the multiplier get applied first,
> then the divider get applied. In some situations (e.g. the multiplier
> increased but the divider decreased), this will make the clock
> frequency temporarily higher than both the original frequency and the
> target frequency, which may lead to system hang due to PLL_CPU(X) clock
> usually being a NKMP clock.
> 
> A comparsion between the old divider (M*P) and the new one is added, and
> if the divider get smaller when changing clock, the multiplier will be
> applied first, so that the clock won't go to a frequency higher than
> normal.
> 
> The interval between applying the first group of factors and the second
> group is based on experiments results on an Orange Pi Zero board.
> 
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> ---
>  drivers/clk/sunxi-ng/ccu_nkmp.c | 76 +++++++++++++++++++++++++++++++++++------
>  1 file changed, 65 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
> index e58c95787f94..5da77eb60335 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkmp.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
> @@ -9,6 +9,7 @@
>   */
>  
>  #include <linux/clk-provider.h>
> +#include <linux/delay.h>
>  
>  #include "ccu_gate.h"
>  #include "ccu_nkmp.h"
> @@ -130,12 +131,49 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
>  	return *parent_rate * _nkmp.n * _nkmp.k / (_nkmp.m * _nkmp.p);
>  }
>  
> +static void ccu_nkmp_extract_factors(const struct ccu_nkmp *nkmp,
> +				     struct _ccu_nkmp *_nkmp, u32 reg)
> +{
> +	_nkmp->n = ((reg >> nkmp->n.shift) & GENMASK(nkmp->n.width - 1, 0))
> +		   + nkmp->n.offset;
> +	_nkmp->k = ((reg >> nkmp->k.shift) & GENMASK(nkmp->k.width - 1, 0))
> +		   + nkmp->k.offset;
> +	_nkmp->m = ((reg >> nkmp->m.shift) & GENMASK(nkmp->m.width - 1, 0))
> +		   + nkmp->m.offset;
> +	_nkmp->p = 1 <<
> +		   ((reg >> nkmp->p.shift) & GENMASK(nkmp->p.width - 1, 0));
> +}
> +
> +static u32 ccu_nkmp_apply_multiplier(const struct ccu_nkmp *nkmp,
> +				     const struct _ccu_nkmp *_nkmp, u32 reg)
> +{
> +	reg &= ~GENMASK(nkmp->n.width + nkmp->n.shift - 1, nkmp->n.shift);
> +	reg &= ~GENMASK(nkmp->k.width + nkmp->k.shift - 1, nkmp->k.shift);
> +
> +	reg |= (_nkmp->n - nkmp->n.offset) << nkmp->n.shift;
> +	reg |= (_nkmp->k - nkmp->k.offset) << nkmp->k.shift;
> +
> +	return reg;
> +}
> +
> +static u32 ccu_nkmp_apply_divider(const struct ccu_nkmp *nkmp,
> +				  const struct _ccu_nkmp *_nkmp, u32 reg)
> +{
> +	reg &= ~GENMASK(nkmp->m.width + nkmp->m.shift - 1, nkmp->m.shift);
> +	reg &= ~GENMASK(nkmp->p.width + nkmp->p.shift - 1, nkmp->p.shift);
> +
> +	reg |= (_nkmp->m - nkmp->m.offset) << nkmp->m.shift;
> +	reg |= ilog2(_nkmp->p) << nkmp->p.shift;
> +
> +	return reg;
> +}
> +
>  static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
>  			   unsigned long parent_rate)
>  {
>  	struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
> -	struct _ccu_nkmp _nkmp;
> -	unsigned long flags;
> +	struct _ccu_nkmp _nkmp, _nkmp_old;
> +	unsigned long flags, old_mp, mp;
>  	u32 reg;
>  
>  	_nkmp.min_n = nkmp->n.min ?: 1;
> @@ -152,17 +190,33 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
>  	spin_lock_irqsave(nkmp->common.lock, flags);
>  
>  	reg = readl(nkmp->common.base + nkmp->common.reg);
> -	reg &= ~GENMASK(nkmp->n.width + nkmp->n.shift - 1, nkmp->n.shift);
> -	reg &= ~GENMASK(nkmp->k.width + nkmp->k.shift - 1, nkmp->k.shift);
> -	reg &= ~GENMASK(nkmp->m.width + nkmp->m.shift - 1, nkmp->m.shift);
> -	reg &= ~GENMASK(nkmp->p.width + nkmp->p.shift - 1, nkmp->p.shift);
>  
> -	reg |= (_nkmp.n - nkmp->n.offset) << nkmp->n.shift;
> -	reg |= (_nkmp.k - nkmp->k.offset) << nkmp->k.shift;
> -	reg |= (_nkmp.m - nkmp->m.offset) << nkmp->m.shift;
> -	reg |= ilog2(_nkmp.p) << nkmp->p.shift;
> +	ccu_nkmp_extract_factors(nkmp, &_nkmp_old, reg);
> +
> +	old_mp = _nkmp_old.m * _nkmp_old.p;
> +	mp = _nkmp.m * _nkmp.p;
> +
> +	if (mp > old_mp) {
> +		reg = ccu_nkmp_apply_divider(nkmp, &_nkmp, reg);
> +		writel(reg, nkmp->common.base + nkmp->common.reg);
> +
> +		/*
> +		 * This value is decided by experiment results on an
> +		 * Allwinner H2+ board (Orange Pi Zero).
> +		 */
> +		udelay(500);
>  
> -	writel(reg, nkmp->common.base + nkmp->common.reg);
> +		reg = ccu_nkmp_apply_multiplier(nkmp, &_nkmp, reg);
> +		writel(reg, nkmp->common.base + nkmp->common.reg);
> +	} else {
> +		reg = ccu_nkmp_apply_multiplier(nkmp, &_nkmp, reg);
> +		writel(reg, nkmp->common.base + nkmp->common.reg);
> +
> +		udelay(500);
> +
> +		reg = ccu_nkmp_apply_divider(nkmp, &_nkmp, reg);
> +		writel(reg, nkmp->common.base + nkmp->common.reg);
> +	}
>  
>  	spin_unlock_irqrestore(nkmp->common.lock, flags);
>  
> -- 
> 2.12.2
> 

[toc] | [prev] | [next] | [standalone]


#1619368 — [PATCH 4/5] ARM: sun8i: h3: add operating-points-v2 table for CPU

FromIcenowy Zheng <icenowy@aosc.io>
Date2017-04-08 21:00 +0200
Subject[PATCH 4/5] ARM: sun8i: h3: add operating-points-v2 table for CPU
Message-ID<tu3Kx-yE-13@gated-at.bofh.it>
In reply to#1619364
The CPU on Allwinner H3 can do dynamic frequency scaling.

Add a DVFS table based on the one tweaked by Armbian developers, which
are proven to work stably on BSP kernels.

Frequencies higher than 1008MHz are temporarily dropped in the table, as
they may lead to over voltage on boards without proper regulator
settings or over temperature on boards with proper regulator settings.
They will be added back once regulator settings are ready and thermal
sensor driver is merged.

In order to satisfy all different regulators (SY8106A which is 50mV per
level, SY8113B which have two states: 1.1V and 1.3V, and some board with
non-tweakable regulators), all the OPPs are defined with a range which has
the target value as the minimum allowed value, and 1.3V (the highest
VDD-CPUX voltage suggested by the datasheet) as the maximum allowed value.
It's proven to work well with a board with SY8113B.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 arch/arm/boot/dts/sun8i-h3.dtsi | 38 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index b36f9f423c39..a0cee17fe44b 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -43,32 +43,68 @@
 #include "sunxi-h3-h5.dtsi"
 
 / {
+	cpu0_opp_table: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp@480000000 {
+			opp-hz = /bits/ 64 <480000000>;
+			opp-microvolt = <980000 980000 1300000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp@648000000 {
+			opp-hz = /bits/ 64 <816000000>;
+			opp-microvolt = <1020000 1020000 1300000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp@912000000 {
+			opp-hz = /bits/ 64 <960000000>;
+			opp-microvolt = <1080000 1080000 1300000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp@1008000000 {
+			opp-hz = /bits/ 64 <1008000000>;
+			opp-microvolt = <1140000 1140000 1300000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		cpu@0 {
+		cpu0: cpu@0 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
 			reg = <0>;
+			clocks = <&ccu CLK_CPUX>;
+			clock-names = "cpu";
+			operating-points-v2 = <&cpu0_opp_table>;
+			#cooling-cells = <0x2>;
 		};
 
 		cpu@1 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
 			reg = <1>;
+			operating-points-v2 = <&cpu0_opp_table>;
 		};
 
 		cpu@2 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
 			reg = <2>;
+			operating-points-v2 = <&cpu0_opp_table>;
 		};
 
 		cpu@3 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
 			reg = <3>;
+			operating-points-v2 = <&cpu0_opp_table>;
 		};
 	};
 
-- 
2.12.2

[toc] | [prev] | [next] | [standalone]


#1619369 — [PATCH 5/5] ARM: sun8i: h2+: add SY8113B regulator used by Orange Pi Zero board

FromIcenowy Zheng <icenowy@aosc.io>
Date2017-04-08 21:00 +0200
Subject[PATCH 5/5] ARM: sun8i: h2+: add SY8113B regulator used by Orange Pi Zero board
Message-ID<tu3Kx-yE-15@gated-at.bofh.it>
In reply to#1619364
Orange Pi Zero board has a SY8113B regulator, which is controlled via
GPIO and capable of outputing 1.1V when the PL6 GPIO is set to output 0
or 1.3V when the PL6 GPIO is set to input or output 1, and the output is
the power supply of the ARM cores in H2+ SoC.

Add the device tree node of this regulator and set the cpu's cpu-supply
property to it.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
index 9e8b082c134f..8f6acca7d12d 100644
--- a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
+++ b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
@@ -93,6 +93,27 @@
 		reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>;
 		post-power-on-delay-ms = <200>;
 	};
+
+	reg_sy8113b: gpio-regulator {
+		compatible = "regulator-gpio";
+
+		regulator-name = "vdd-cpux";
+		regulator-type = "voltage";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1300000>;
+		regulator-ramp-delay = <50>; /* 4ms */
+
+		gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
+		gpios-states = <0x1>;
+		states = <1100000 0x0
+			  1300000 0x1>;
+	};
+};
+
+&cpu0 {
+	cpu-supply = <&reg_sy8113b>;
 };
 
 &ehci0 {
-- 
2.12.2

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web