linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms
@ 2015-04-21 13:17 Bartlomiej Zolnierkiewicz
  2015-04-21 13:17 ` [PATCH 1/8] cpufreq: arm_big_little: add cluster regulator support Bartlomiej Zolnierkiewicz
                   ` (8 more replies)
  0 siblings, 9 replies; 18+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2015-04-21 13:17 UTC (permalink / raw)
  To: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar
  Cc: Tomasz Figa, Lukasz Majewski, Heiko Stuebner, Chanwoo Choi,
	Kevin Hilman, Javier Martinez Canillas, linux-samsung-soc,
	linux-pm, linux-arm-kernel, linux-kernel, b.zolnierkie

Hi,

This patch series adds generic arm_big_little_dt cpufreq driver
support for Exynos5420/5800 (using the new CPU clock type which
allows it).  It also:
- enhances arm_big_little[_dt] driver with CPU cluster regulator
  support
- fixes CPU clock configuration data and CPU operating points
  setup for Exynos5800
- adds CPU cluster regulator supplies for ODROID-XU3 board

This patch series has been tested on Exynos5800 based ODROID-XU3
board.

Depends on:
- next-20150330 branch of linux-next kernel tree
- "[PATCH 0/6] cpufreq: use generic cpufreq drivers for Exynos4210
  platform" [1]
- "[PATCH 0/6] cpufreq: use generic cpufreq drivers for Exynos4x12
  platform" [2]
- "[PATCH] cpufreq: exynos: remove dead ->need_apll_change method" [3]
- "[PATCH 0/4] cpufreq: use generic cpufreq drivers for Exynos5250
  platform" [4]

[1] http://www.kernelhub.org/?msg=721136&p=2
[2] http://marc.info/?l=linux-pm&m=142868881101873&w=2
[3] https://lkml.org/lkml/2015/3/27/574
[4] https://lkml.org/lkml/2015/4/13/611

Changes over Thomas' original v12 code:
- split Exynos5420 and Exynos5800 support
- moved E5420_[EGL,KFC]_DIV0() macros to clk-exynos5420.c
- disabled cpufreq if big.LITTLE switcher support is enabled
- enhanced arm_big_little[_dt] driver with CPU cluster regulator
  support
- fixed CPU clock configuration data for Exynos5800
- fixed CPU operating points setup for Exynos5800
- added CPU cluster regulator supplies for ODROID-XU3 board

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics


Bartlomiej Zolnierkiewicz (4):
  cpufreq: arm_big_little: add cluster regulator support
  ARM: dts: add cluster regulator supply properties for
    exynos5422-odroidxu3
  clk: samsung: exynos5800: fix cpu clock configuration data
  ARM: dts: Exynos5800: fix CPU OPP

Thomas Abraham (4):
  clk: samsung: exynos5420: add cpu clock configuration data and
    instantiate cpu clock
  ARM: dts: Exynos5420: add CPU OPP and regulator supply property
  ARM: Exynos: use generic cpufreq driver for Exynos5420
  ARM: Exynos: use generic cpufreq driver for Exynos5800

 .../bindings/cpufreq/arm_big_little_dt.txt         |    4 +
 arch/arm/boot/dts/exynos5420.dtsi                  |   38 +++++
 arch/arm/boot/dts/exynos5422-odroidxu3.dts         |    8 +
 arch/arm/boot/dts/exynos5800.dtsi                  |   39 +++++
 arch/arm/mach-exynos/exynos.c                      |    8 +
 drivers/clk/samsung/clk-exynos5420.c               |   88 ++++++++++-
 drivers/cpufreq/arm_big_little.c                   |  153 +++++++++++++++++---
 include/dt-bindings/clock/exynos5420.h             |    2 +
 8 files changed, 320 insertions(+), 20 deletions(-)

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/8] cpufreq: arm_big_little: add cluster regulator support
  2015-04-21 13:17 [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms Bartlomiej Zolnierkiewicz
@ 2015-04-21 13:17 ` Bartlomiej Zolnierkiewicz
  2015-04-22  8:07   ` Lukasz Majewski
                     ` (2 more replies)
  2015-04-21 13:17 ` [PATCH 2/8] ARM: dts: add cluster regulator supply properties for exynos5422-odroidxu3 Bartlomiej Zolnierkiewicz
                   ` (7 subsequent siblings)
  8 siblings, 3 replies; 18+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2015-04-21 13:17 UTC (permalink / raw)
  To: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar
  Cc: Tomasz Figa, Lukasz Majewski, Heiko Stuebner, Chanwoo Choi,
	Kevin Hilman, Javier Martinez Canillas, linux-samsung-soc,
	linux-pm, linux-arm-kernel, linux-kernel, b.zolnierkie,
	Doug Anderson, Andreas Faerber, Sachin Kamat

Add cluster regulator support as a preparation to adding
generic arm_big_little_dt cpufreq_dt driver support for
ODROID-XU3 board.  This allows arm_big_little[_dt] driver
to set not only the frequency but also the voltage (which
is obtained from operating point's voltage value) for CPU
clusters.

Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Doug Anderson <dianders@chromium.org>
Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Cc: Andreas Faerber <afaerber@suse.de>
Cc: Sachin Kamat <sachin.kamat@linaro.org>
Cc: Thomas Abraham <thomas.ab@samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 .../bindings/cpufreq/arm_big_little_dt.txt         |    4 +
 drivers/cpufreq/arm_big_little.c                   |  153 +++++++++++++++++---
 2 files changed, 139 insertions(+), 18 deletions(-)

diff --git a/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt b/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt
index 0715695..8ca4a12 100644
--- a/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt
+++ b/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt
@@ -18,6 +18,10 @@ Required properties:
 Optional properties:
 - clock-latency: Specify the possible maximum transition latency for clock,
   in unit of nanoseconds.
+- cpu-cluster.0-supply: Provides the regulator node supplying voltage to CPU
+  cluster 0.
+- cpu-cluster.1-supply: Provides the regulator node supplying voltage to CPU
+  cluster 1.
 
 Examples:
 
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
index e1a6ba6..edb461b 100644
--- a/drivers/cpufreq/arm_big_little.c
+++ b/drivers/cpufreq/arm_big_little.c
@@ -31,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/topology.h>
 #include <linux/types.h>
+#include <linux/regulator/consumer.h>
 #include <asm/bL_switcher.h>
 
 #include "arm_big_little.h"
@@ -54,6 +55,9 @@ static bool bL_switching_enabled;
 
 static struct cpufreq_arm_bL_ops *arm_bL_ops;
 static struct clk *clk[MAX_CLUSTERS];
+static struct regulator *reg[MAX_CLUSTERS];
+static struct device *cpu_devs[MAX_CLUSTERS];
+static int transition_latencies[MAX_CLUSTERS];
 static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1];
 static atomic_t cluster_usage[MAX_CLUSTERS + 1];
 
@@ -122,7 +126,76 @@ static unsigned int bL_cpufreq_get_rate(unsigned int cpu)
 	}
 }
 
-static unsigned int
+static int
+bL_cpufreq_set_rate_cluster(u32 cpu, u32 cluster, u32 new_rate)
+{
+	unsigned long volt = 0, volt_old = 0;
+	long freq_Hz;
+	u32 old_rate;
+	int ret;
+
+	freq_Hz = new_rate * 1000;
+	old_rate = clk_get_rate(clk[cluster]) / 1000;
+
+	if (!IS_ERR(reg[cluster])) {
+		struct dev_pm_opp *opp;
+		unsigned long opp_freq;
+
+		rcu_read_lock();
+		opp = dev_pm_opp_find_freq_ceil(cpu_devs[cluster], &freq_Hz);
+		if (IS_ERR(opp)) {
+			rcu_read_unlock();
+			pr_err("%s: cpu %d, cluster: %d, failed to find OPP for %ld\n",
+				__func__, cpu, cluster, freq_Hz);
+			return PTR_ERR(opp);
+		}
+		volt = dev_pm_opp_get_voltage(opp);
+		opp_freq = dev_pm_opp_get_freq(opp);
+		rcu_read_unlock();
+		volt_old = regulator_get_voltage(reg[cluster]);
+		pr_debug("%s: cpu %d, cluster: %d, Found OPP: %ld kHz, %ld uV\n",
+			__func__, cpu, cluster, opp_freq / 1000, volt);
+	}
+
+	pr_debug("%s: cpu %d, cluster: %d, %u MHz, %ld mV --> %u MHz, %ld mV\n",
+		__func__, cpu, cluster,
+		old_rate / 1000, (volt_old > 0) ? volt_old / 1000 : -1,
+		new_rate / 1000, volt ? volt / 1000 : -1);
+
+	/* scaling up? scale voltage before frequency */
+	if (!IS_ERR(reg[cluster]) && new_rate > old_rate) {
+		ret = regulator_set_voltage_tol(reg[cluster], volt, 0);
+		if (ret) {
+			pr_err("%s: cpu: %d, cluster: %d, failed to scale voltage up: %d\n",
+				__func__, cpu, cluster, ret);
+			return ret;
+		}
+	}
+
+	ret = clk_set_rate(clk[cluster], new_rate * 1000);
+	if (WARN_ON(ret)) {
+		pr_err("%s: clk_set_rate failed: %d, cluster: %d\n",
+			__func__, cluster, ret);
+		if (!IS_ERR(reg[cluster]) && volt_old > 0)
+			regulator_set_voltage_tol(reg[cluster], volt_old, 0);
+		return ret;
+	}
+
+	/* scaling down? scale voltage after frequency */
+	if (!IS_ERR(reg[cluster]) && new_rate < old_rate) {
+		ret = regulator_set_voltage_tol(reg[cluster], volt, 0);
+		if (ret) {
+			pr_err("%s: cpu: %d, cluster: %d, failed to scale voltage down: %d\n",
+				__func__, cpu, cluster, ret);
+			clk_set_rate(clk[cluster], old_rate * 1000);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int
 bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate)
 {
 	u32 new_rate, prev_rate;
@@ -145,22 +218,17 @@ bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate)
 	pr_debug("%s: cpu: %d, old cluster: %d, new cluster: %d, freq: %d\n",
 			__func__, cpu, old_cluster, new_cluster, new_rate);
 
-	ret = clk_set_rate(clk[new_cluster], new_rate * 1000);
-	if (WARN_ON(ret)) {
-		pr_err("clk_set_rate failed: %d, new cluster: %d\n", ret,
-				new_cluster);
-		if (bLs) {
-			per_cpu(cpu_last_req_freq, cpu) = prev_rate;
-			per_cpu(physical_cluster, cpu) = old_cluster;
-		}
-
-		mutex_unlock(&cluster_lock[new_cluster]);
-
-		return ret;
+	ret = bL_cpufreq_set_rate_cluster(cpu, new_cluster, new_rate);
+	if (ret && bLs) {
+		per_cpu(cpu_last_req_freq, cpu) = prev_rate;
+		per_cpu(physical_cluster, cpu) = old_cluster;
 	}
 
 	mutex_unlock(&cluster_lock[new_cluster]);
 
+	if (ret)
+		return ret;
+
 	/* Recalc freq for old cluster when switching clusters */
 	if (old_cluster != new_cluster) {
 		pr_debug("%s: cpu: %d, old cluster: %d, new cluster: %d\n",
@@ -174,14 +242,11 @@ bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate)
 		/* Set freq of old cluster if there are cpus left on it */
 		new_rate = find_cluster_maxfreq(old_cluster);
 		new_rate = ACTUAL_FREQ(old_cluster, new_rate);
-
 		if (new_rate) {
 			pr_debug("%s: Updating rate of old cluster: %d, to freq: %d\n",
 					__func__, old_cluster, new_rate);
 
-			if (clk_set_rate(clk[old_cluster], new_rate * 1000))
-				pr_err("%s: clk_set_rate failed: %d, old cluster: %d\n",
-						__func__, ret, old_cluster);
+			bL_cpufreq_set_rate_cluster(cpu, old_cluster, new_rate);
 		}
 		mutex_unlock(&cluster_lock[old_cluster]);
 	}
@@ -288,6 +353,8 @@ static void _put_cluster_clk_and_freq_table(struct device *cpu_dev)
 		return;
 
 	clk_put(clk[cluster]);
+	if (!IS_ERR(reg[cluster]))
+		regulator_put(reg[cluster]);
 	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table[cluster]);
 	if (arm_bL_ops->free_opp_table)
 		arm_bL_ops->free_opp_table(cpu_dev);
@@ -321,6 +388,7 @@ static void put_cluster_clk_and_freq_table(struct device *cpu_dev)
 
 static int _get_cluster_clk_and_freq_table(struct device *cpu_dev)
 {
+	unsigned long min_uV = ~0, max_uV = 0;
 	u32 cluster = raw_cpu_to_cluster(cpu_dev->id);
 	char name[14] = "cpu-cluster.";
 	int ret;
@@ -335,6 +403,51 @@ static int _get_cluster_clk_and_freq_table(struct device *cpu_dev)
 		goto out;
 	}
 
+	name[12] = cluster + '0';
+	reg[cluster] = regulator_get_optional(cpu_dev, name);
+	if (!IS_ERR(reg[cluster])) {
+		unsigned long opp_freq = 0;
+
+		dev_dbg(cpu_dev, "%s: reg: %p, cluster: %d\n",
+			__func__, reg[cluster], cluster);
+		cpu_devs[cluster] = cpu_dev;
+
+		/*
+		 * Disable any OPPs where the connected regulator isn't able to
+		 * provide the specified voltage and record minimum and maximum
+		 * voltage levels.
+		 */
+		while (1) {
+			struct dev_pm_opp *opp;
+			unsigned long opp_uV;
+
+			rcu_read_lock();
+			opp = dev_pm_opp_find_freq_ceil(cpu_dev, &opp_freq);
+			if (IS_ERR(opp)) {
+				rcu_read_unlock();
+				break;
+			}
+			opp_uV = dev_pm_opp_get_voltage(opp);
+			rcu_read_unlock();
+
+			if (regulator_is_supported_voltage(reg[cluster], opp_uV,
+							   opp_uV)) {
+				if (opp_uV < min_uV)
+					min_uV = opp_uV;
+				if (opp_uV > max_uV)
+					max_uV = opp_uV;
+			} else {
+				dev_pm_opp_disable(cpu_dev, opp_freq);
+			}
+
+			opp_freq++;
+		}
+
+		ret = regulator_set_voltage_time(reg[cluster], min_uV, max_uV);
+		if (ret > 0)
+			transition_latencies[cluster] = ret * 1000;
+	}
+
 	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table[cluster]);
 	if (ret) {
 		dev_err(cpu_dev, "%s: failed to init cpufreq table, cpu: %d, err: %d\n",
@@ -342,7 +455,6 @@ static int _get_cluster_clk_and_freq_table(struct device *cpu_dev)
 		goto free_opp_table;
 	}
 
-	name[12] = cluster + '0';
 	clk[cluster] = clk_get(cpu_dev, name);
 	if (!IS_ERR(clk[cluster])) {
 		dev_dbg(cpu_dev, "%s: clk: %p & freq table: %p, cluster: %d\n",
@@ -469,6 +581,11 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy)
 	else
 		policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
 
+	if (cur_cluster < MAX_CLUSTERS &&
+	    policy->cpuinfo.transition_latency != CPUFREQ_ETERNAL)
+		policy->cpuinfo.transition_latency
+			+= transition_latencies[cur_cluster];
+
 	if (is_bL_switching_enabled())
 		per_cpu(cpu_last_req_freq, policy->cpu) = clk_get_cpu_rate(policy->cpu);
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/8] ARM: dts: add cluster regulator supply properties for exynos5422-odroidxu3
  2015-04-21 13:17 [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms Bartlomiej Zolnierkiewicz
  2015-04-21 13:17 ` [PATCH 1/8] cpufreq: arm_big_little: add cluster regulator support Bartlomiej Zolnierkiewicz
@ 2015-04-21 13:17 ` Bartlomiej Zolnierkiewicz
  2015-04-22  8:07   ` Lukasz Majewski
  2015-04-21 13:17 ` [PATCH 3/8] clk: samsung: exynos5420: add cpu clock configuration data and instantiate cpu clock Bartlomiej Zolnierkiewicz
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2015-04-21 13:17 UTC (permalink / raw)
  To: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar
  Cc: Tomasz Figa, Lukasz Majewski, Heiko Stuebner, Chanwoo Choi,
	Kevin Hilman, Javier Martinez Canillas, linux-samsung-soc,
	linux-pm, linux-arm-kernel, linux-kernel, b.zolnierkie,
	Doug Anderson, Andreas Faerber, Sachin Kamat

Add cluster regulator supply properties as a preparation to
adding generic arm_big_little_dt cpufreq driver support for
ODROID-XU3 board.

Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Doug Anderson <dianders@chromium.org>
Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Cc: Andreas Faerber <afaerber@suse.de>
Cc: Sachin Kamat <sachin.kamat@linaro.org>
Cc: Thomas Abraham <thomas.ab@samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 arch/arm/boot/dts/exynos5422-odroidxu3.dts |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
index edc25cf..e876016 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
@@ -355,6 +355,14 @@
 	dr_mode = "otg";
 };
 
+&cpu0 {
+	cpu-cluster.0-supply = <&buck2_reg>;
+};
+
+&cpu4 {
+	cpu-cluster.1-supply = <&buck6_reg>;
+};
+
 &i2c_0 {
 	status = "okay";
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 3/8] clk: samsung: exynos5420: add cpu clock configuration data and instantiate cpu clock
  2015-04-21 13:17 [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms Bartlomiej Zolnierkiewicz
  2015-04-21 13:17 ` [PATCH 1/8] cpufreq: arm_big_little: add cluster regulator support Bartlomiej Zolnierkiewicz
  2015-04-21 13:17 ` [PATCH 2/8] ARM: dts: add cluster regulator supply properties for exynos5422-odroidxu3 Bartlomiej Zolnierkiewicz
@ 2015-04-21 13:17 ` Bartlomiej Zolnierkiewicz
  2015-04-22  8:10   ` Lukasz Majewski
  2015-04-21 13:17 ` [PATCH 4/8] ARM: dts: Exynos5420: add CPU OPP and regulator supply property Bartlomiej Zolnierkiewicz
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2015-04-21 13:17 UTC (permalink / raw)
  To: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar
  Cc: Tomasz Figa, Lukasz Majewski, Heiko Stuebner, Chanwoo Choi,
	Kevin Hilman, Javier Martinez Canillas, linux-samsung-soc,
	linux-pm, linux-arm-kernel, linux-kernel, b.zolnierkie

From: Thomas Abraham <thomas.ab@samsung.com>

With the addition of the new Samsung specific cpu-clock type, the
arm clock can be represented as a cpu-clock type. Add the CPU clock
configuration data and instantiate the CPU clock type for Exynos5420.

Changes by Bartlomiej:
- split Exynos5420 support from the original patches
- moved E5420_[EGL,KFC]_DIV0() macros to clk-exynos5420.c

Cc: Tomasz Figa <tomasz.figa@gmail.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 drivers/clk/samsung/clk-exynos5420.c   |   58 ++++++++++++++++++++++++++++++--
 include/dt-bindings/clock/exynos5420.h |    2 ++
 2 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 07d666c..9398a2d 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -19,6 +19,7 @@
 #include <linux/syscore_ops.h>
 
 #include "clk.h"
+#include "clk-cpu.h"
 
 #define APLL_LOCK		0x0
 #define APLL_CON0		0x100
@@ -616,9 +617,11 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
 	MUX(0, "mout_mspll_kfc", mout_mspll_cpu_p, SRC_TOP7, 8, 2),
 	MUX(0, "mout_mspll_cpu", mout_mspll_cpu_p, SRC_TOP7, 12, 2),
 
-	MUX(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1),
+	MUX_F(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
+	      CLK_SET_RATE_PARENT, 0),
 	MUX(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1),
-	MUX(0, "mout_kpll", mout_kpll_p, SRC_KFC, 0, 1),
+	MUX_F(0, "mout_kpll", mout_kpll_p, SRC_KFC, 0, 1,
+	      CLK_SET_RATE_PARENT, 0),
 	MUX(0, "mout_kfc", mout_kfc_p, SRC_KFC, 16, 1),
 
 	MUX(0, "mout_aclk200", mout_group1_p, SRC_TOP0, 8, 2),
@@ -1246,6 +1249,50 @@ static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
 		KPLL_CON0, NULL),
 };
 
+#define E5420_EGL_DIV0(apll, pclk_dbg, atb, cpud)			\
+		((((apll) << 24) | ((pclk_dbg) << 20) | ((atb) << 16) |	\
+		 ((cpud) << 4)))
+
+static const struct exynos_cpuclk_cfg_data exynos5420_eglclk_d[] __initconst = {
+	{ 1800000, E5420_EGL_DIV0(3, 7, 7, 4), },
+	{ 1700000, E5420_EGL_DIV0(3, 7, 7, 3), },
+	{ 1600000, E5420_EGL_DIV0(3, 7, 7, 3), },
+	{ 1500000, E5420_EGL_DIV0(3, 7, 7, 3), },
+	{ 1400000, E5420_EGL_DIV0(3, 7, 7, 3), },
+	{ 1300000, E5420_EGL_DIV0(3, 7, 7, 2), },
+	{ 1200000, E5420_EGL_DIV0(3, 7, 7, 2), },
+	{ 1100000, E5420_EGL_DIV0(3, 7, 7, 2), },
+	{ 1000000, E5420_EGL_DIV0(3, 6, 6, 2), },
+	{  900000, E5420_EGL_DIV0(3, 6, 6, 2), },
+	{  800000, E5420_EGL_DIV0(3, 5, 5, 2), },
+	{  700000, E5420_EGL_DIV0(3, 5, 5, 2), },
+	{  600000, E5420_EGL_DIV0(3, 4, 4, 2), },
+	{  500000, E5420_EGL_DIV0(3, 3, 3, 2), },
+	{  400000, E5420_EGL_DIV0(3, 3, 3, 2), },
+	{  300000, E5420_EGL_DIV0(3, 3, 3, 2), },
+	{  200000, E5420_EGL_DIV0(3, 3, 3, 2), },
+	{  0 },
+};
+
+#define E5420_KFC_DIV(kpll, pclk, aclk)					\
+		((((kpll) << 24) | ((pclk) << 20) | ((aclk) << 4)))
+
+static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[] __initconst = {
+	{ 1300000, E5420_KFC_DIV(3, 5, 2), },
+	{ 1200000, E5420_KFC_DIV(3, 5, 2), },
+	{ 1100000, E5420_KFC_DIV(3, 5, 2), },
+	{ 1000000, E5420_KFC_DIV(3, 5, 2), },
+	{  900000, E5420_KFC_DIV(3, 5, 2), },
+	{  800000, E5420_KFC_DIV(3, 5, 2), },
+	{  700000, E5420_KFC_DIV(3, 4, 2), },
+	{  600000, E5420_KFC_DIV(3, 4, 2), },
+	{  500000, E5420_KFC_DIV(3, 4, 2), },
+	{  400000, E5420_KFC_DIV(3, 3, 2), },
+	{  300000, E5420_KFC_DIV(3, 3, 2), },
+	{  200000, E5420_KFC_DIV(3, 3, 2), },
+	{  0 },
+};
+
 static const struct of_device_id ext_clk_match[] __initconst = {
 	{ .compatible = "samsung,exynos5420-oscclk", .data = (void *)0, },
 	{ },
@@ -1310,6 +1357,13 @@ static void __init exynos5x_clk_init(struct device_node *np,
 				ARRAY_SIZE(exynos5800_gate_clks));
 	}
 
+	exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
+		mout_cpu_p[0], mout_cpu_p[1], 0x200,
+		exynos5420_eglclk_d, ARRAY_SIZE(exynos5420_eglclk_d), 0);
+	exynos_register_cpu_clock(ctx, CLK_KFC_CLK, "kfcclk",
+		mout_kfc_p[0], mout_kfc_p[1], 0x28200,
+		exynos5420_kfcclk_d, ARRAY_SIZE(exynos5420_kfcclk_d), 0);
+
 	exynos5420_clk_sleep_init();
 
 	samsung_clk_of_add_provider(np, ctx);
diff --git a/include/dt-bindings/clock/exynos5420.h b/include/dt-bindings/clock/exynos5420.h
index 99da0d1..dde9664 100644
--- a/include/dt-bindings/clock/exynos5420.h
+++ b/include/dt-bindings/clock/exynos5420.h
@@ -25,6 +25,8 @@
 #define CLK_FOUT_MPLL		10
 #define CLK_FOUT_BPLL		11
 #define CLK_FOUT_KPLL		12
+#define CLK_ARM_CLK		13
+#define CLK_KFC_CLK		14
 
 /* gate for special clocks (sclk) */
 #define CLK_SCLK_UART0		128
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 4/8] ARM: dts: Exynos5420: add CPU OPP and regulator supply property
  2015-04-21 13:17 [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms Bartlomiej Zolnierkiewicz
                   ` (2 preceding siblings ...)
  2015-04-21 13:17 ` [PATCH 3/8] clk: samsung: exynos5420: add cpu clock configuration data and instantiate cpu clock Bartlomiej Zolnierkiewicz
@ 2015-04-21 13:17 ` Bartlomiej Zolnierkiewicz
  2015-04-22  8:12   ` Lukasz Majewski
  2015-04-21 13:17 ` [PATCH 5/8] ARM: Exynos: use generic cpufreq driver for Exynos5420 Bartlomiej Zolnierkiewicz
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2015-04-21 13:17 UTC (permalink / raw)
  To: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar
  Cc: Tomasz Figa, Lukasz Majewski, Heiko Stuebner, Chanwoo Choi,
	Kevin Hilman, Javier Martinez Canillas, linux-samsung-soc,
	linux-pm, linux-arm-kernel, linux-kernel, b.zolnierkie,
	Doug Anderson, Andreas Faerber, Sachin Kamat

From: Thomas Abraham <thomas.ab@samsung.com>

For Exynos5420 platforms, add CPU operating points and CPU
regulator supply properties for migrating from Exynos specific
cpufreq driver to using generic cpufreq driver.

Changes by Bartlomiej:
- split Exynos5420 support from the original patch

Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Doug Anderson <dianders@chromium.org>
Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Cc: Andreas Faerber <afaerber@suse.de>
Cc: Sachin Kamat <sachin.kamat@linaro.org>
Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 arch/arm/boot/dts/exynos5420.dtsi |   38 +++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index f67b23f..85b9cfc 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -59,8 +59,26 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a15";
 			reg = <0x0>;
+			clocks = <&clock CLK_ARM_CLK>;
+			clock-names = "cpu-cluster.0";
 			clock-frequency = <1800000000>;
 			cci-control-port = <&cci_control1>;
+			clock-latency = <140000>;
+
+			operating-points = <
+				1800000 1250000
+				1700000 1212500
+				1600000 1175000
+				1500000 1137500
+				1400000 1112500
+				1300000 1062500
+				1200000 1037500
+				1100000 1012500
+				1000000 987500
+				 900000 962500
+				 800000 937500
+				 700000 912500
+			>;
 		};
 
 		cpu1: cpu@1 {
@@ -69,6 +87,7 @@
 			reg = <0x1>;
 			clock-frequency = <1800000000>;
 			cci-control-port = <&cci_control1>;
+			clock-latency = <140000>;
 		};
 
 		cpu2: cpu@2 {
@@ -77,6 +96,7 @@
 			reg = <0x2>;
 			clock-frequency = <1800000000>;
 			cci-control-port = <&cci_control1>;
+			clock-latency = <140000>;
 		};
 
 		cpu3: cpu@3 {
@@ -85,14 +105,29 @@
 			reg = <0x3>;
 			clock-frequency = <1800000000>;
 			cci-control-port = <&cci_control1>;
+			clock-latency = <140000>;
 		};
 
 		cpu4: cpu@100 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x100>;
+			clocks = <&clock CLK_KFC_CLK>;
+			clock-names = "cpu-cluster.1";
 			clock-frequency = <1000000000>;
 			cci-control-port = <&cci_control0>;
+			clock-latency = <140000>;
+
+			operating-points = <
+				1300000 1275000
+				1200000 1212500
+				1100000 1162500
+				1000000 1112500
+				 900000 1062500
+				 800000 1025000
+				 700000 975000
+				 600000 937500
+			>;
 		};
 
 		cpu5: cpu@101 {
@@ -101,6 +136,7 @@
 			reg = <0x101>;
 			clock-frequency = <1000000000>;
 			cci-control-port = <&cci_control0>;
+			clock-latency = <140000>;
 		};
 
 		cpu6: cpu@102 {
@@ -109,6 +145,7 @@
 			reg = <0x102>;
 			clock-frequency = <1000000000>;
 			cci-control-port = <&cci_control0>;
+			clock-latency = <140000>;
 		};
 
 		cpu7: cpu@103 {
@@ -117,6 +154,7 @@
 			reg = <0x103>;
 			clock-frequency = <1000000000>;
 			cci-control-port = <&cci_control0>;
+			clock-latency = <140000>;
 		};
 	};
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 5/8] ARM: Exynos: use generic cpufreq driver for Exynos5420
  2015-04-21 13:17 [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms Bartlomiej Zolnierkiewicz
                   ` (3 preceding siblings ...)
  2015-04-21 13:17 ` [PATCH 4/8] ARM: dts: Exynos5420: add CPU OPP and regulator supply property Bartlomiej Zolnierkiewicz
@ 2015-04-21 13:17 ` Bartlomiej Zolnierkiewicz
  2015-04-22  8:13   ` Lukasz Majewski
  2015-04-21 13:17 ` [PATCH 6/8] clk: samsung: exynos5800: fix cpu clock configuration data Bartlomiej Zolnierkiewicz
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2015-04-21 13:17 UTC (permalink / raw)
  To: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar
  Cc: Tomasz Figa, Lukasz Majewski, Heiko Stuebner, Chanwoo Choi,
	Kevin Hilman, Javier Martinez Canillas, linux-samsung-soc,
	linux-pm, linux-arm-kernel, linux-kernel, b.zolnierkie

From: Thomas Abraham <thomas.ab@samsung.com>

The new CPU clock type allows the use of generic arm_big_little_dt
cpufreq driver for Exynos5420.

Changes by Bartlomiej:
- split Exynos5420 support from the original patch
- disable cpufreq if big.LITTLE switcher support is enabled

Cc: Tomasz Figa <tomasz.figa@gmail.com>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 arch/arm/mach-exynos/exynos.c |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index 4b03a32..11ac7fb 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -207,6 +207,13 @@ struct cpufreq_dt_platform_data cpufreq_dt_pd = {
 static const struct of_device_id exynos_cpufreq_matches[] = {
 	{ .compatible = "samsung,exynos4210", .data = "cpufreq-dt" },
 	{ .compatible = "samsung,exynos5250", .data = "cpufreq-dt" },
+/*
+ * FIXME: When big.LITTLE switcher is enabled system lockups during
+ * ondemand governor stress testing (observed on ODROID-XU3 board).
+ */
+#ifndef CONFIG_BL_SWITCHER
+	{ .compatible = "samsung,exynos5420", .data = "arm-bL-cpufreq-dt" },
+#endif
 	{ /* sentinel */ }
 };
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 6/8] clk: samsung: exynos5800: fix cpu clock configuration data
  2015-04-21 13:17 [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms Bartlomiej Zolnierkiewicz
                   ` (4 preceding siblings ...)
  2015-04-21 13:17 ` [PATCH 5/8] ARM: Exynos: use generic cpufreq driver for Exynos5420 Bartlomiej Zolnierkiewicz
@ 2015-04-21 13:17 ` Bartlomiej Zolnierkiewicz
  2015-04-22  8:14   ` Lukasz Majewski
  2015-04-21 13:17 ` [PATCH 7/8] ARM: dts: Exynos5800: fix CPU OPP Bartlomiej Zolnierkiewicz
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2015-04-21 13:17 UTC (permalink / raw)
  To: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar
  Cc: Tomasz Figa, Lukasz Majewski, Heiko Stuebner, Chanwoo Choi,
	Kevin Hilman, Javier Martinez Canillas, linux-samsung-soc,
	linux-pm, linux-arm-kernel, linux-kernel, b.zolnierkie

Fix cpu clock configuration data for Exynos5800 (it uses
higher PCLK_DBG divider values than Exynos5420 and supports
additional frequencies).

Based on Hardkernel's kernel for ODROID-XU3 board.

Cc: Tomasz Figa <tomasz.figa@gmail.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Cc: Thomas Abraham <thomas.ab@samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 drivers/clk/samsung/clk-exynos5420.c |   36 +++++++++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 9398a2d..462aaee 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -1274,10 +1274,34 @@ static const struct exynos_cpuclk_cfg_data exynos5420_eglclk_d[] __initconst = {
 	{  0 },
 };
 
+static const struct exynos_cpuclk_cfg_data exynos5800_eglclk_d[] __initconst = {
+	{ 2000000, E5420_EGL_DIV0(3, 7, 7, 4), },
+	{ 1900000, E5420_EGL_DIV0(3, 7, 7, 4), },
+	{ 1800000, E5420_EGL_DIV0(3, 7, 7, 4), },
+	{ 1700000, E5420_EGL_DIV0(3, 7, 7, 3), },
+	{ 1600000, E5420_EGL_DIV0(3, 7, 7, 3), },
+	{ 1500000, E5420_EGL_DIV0(3, 7, 7, 3), },
+	{ 1400000, E5420_EGL_DIV0(3, 7, 7, 3), },
+	{ 1300000, E5420_EGL_DIV0(3, 7, 7, 2), },
+	{ 1200000, E5420_EGL_DIV0(3, 7, 7, 2), },
+	{ 1100000, E5420_EGL_DIV0(3, 7, 7, 2), },
+	{ 1000000, E5420_EGL_DIV0(3, 7, 6, 2), },
+	{  900000, E5420_EGL_DIV0(3, 7, 6, 2), },
+	{  800000, E5420_EGL_DIV0(3, 7, 5, 2), },
+	{  700000, E5420_EGL_DIV0(3, 7, 5, 2), },
+	{  600000, E5420_EGL_DIV0(3, 7, 4, 2), },
+	{  500000, E5420_EGL_DIV0(3, 7, 3, 2), },
+	{  400000, E5420_EGL_DIV0(3, 7, 3, 2), },
+	{  300000, E5420_EGL_DIV0(3, 7, 3, 2), },
+	{  200000, E5420_EGL_DIV0(3, 7, 3, 2), },
+	{  0 },
+};
+
 #define E5420_KFC_DIV(kpll, pclk, aclk)					\
 		((((kpll) << 24) | ((pclk) << 20) | ((aclk) << 4)))
 
 static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[] __initconst = {
+	{ 1400000, E5420_KFC_DIV(3, 5, 3), }, /* for Exynos5800 */
 	{ 1300000, E5420_KFC_DIV(3, 5, 2), },
 	{ 1200000, E5420_KFC_DIV(3, 5, 2), },
 	{ 1100000, E5420_KFC_DIV(3, 5, 2), },
@@ -1357,9 +1381,15 @@ static void __init exynos5x_clk_init(struct device_node *np,
 				ARRAY_SIZE(exynos5800_gate_clks));
 	}
 
-	exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-		mout_cpu_p[0], mout_cpu_p[1], 0x200,
-		exynos5420_eglclk_d, ARRAY_SIZE(exynos5420_eglclk_d), 0);
+	if (soc == EXYNOS5420) {
+		exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
+			mout_cpu_p[0], mout_cpu_p[1], 0x200,
+			exynos5420_eglclk_d, ARRAY_SIZE(exynos5420_eglclk_d), 0);
+	} else {
+		exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
+			mout_cpu_p[0], mout_cpu_p[1], 0x200,
+			exynos5800_eglclk_d, ARRAY_SIZE(exynos5800_eglclk_d), 0);
+	}
 	exynos_register_cpu_clock(ctx, CLK_KFC_CLK, "kfcclk",
 		mout_kfc_p[0], mout_kfc_p[1], 0x28200,
 		exynos5420_kfcclk_d, ARRAY_SIZE(exynos5420_kfcclk_d), 0);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 7/8] ARM: dts: Exynos5800: fix CPU OPP
  2015-04-21 13:17 [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms Bartlomiej Zolnierkiewicz
                   ` (5 preceding siblings ...)
  2015-04-21 13:17 ` [PATCH 6/8] clk: samsung: exynos5800: fix cpu clock configuration data Bartlomiej Zolnierkiewicz
@ 2015-04-21 13:17 ` Bartlomiej Zolnierkiewicz
  2015-04-21 13:17 ` [PATCH 8/8] ARM: Exynos: use generic cpufreq driver for Exynos5800 Bartlomiej Zolnierkiewicz
  2015-04-21 15:34 ` [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms Bartlomiej Zolnierkiewicz
  8 siblings, 0 replies; 18+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2015-04-21 13:17 UTC (permalink / raw)
  To: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar
  Cc: Tomasz Figa, Lukasz Majewski, Heiko Stuebner, Chanwoo Choi,
	Kevin Hilman, Javier Martinez Canillas, linux-samsung-soc,
	linux-pm, linux-arm-kernel, linux-kernel, b.zolnierkie,
	Doug Anderson, Andreas Faerber, Sachin Kamat

Fix CPU operating points for Exynos5800 (it uses different
voltages than Exynos5420 and supports additional frequencies).
However don't use 2000MHz & 1900MHz OPPs (for A15 cores) and
1400MHz OPP (for A7 cores) until there is a separate DTS for
ODROID-XU3 Lite board (which doesn't support these higher
OPPs).

Based on Hardkernel's kernel for ODROID-XU3 board.

Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Doug Anderson <dianders@chromium.org>
Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Cc: Andreas Faerber <afaerber@suse.de>
Cc: Sachin Kamat <sachin.kamat@linaro.org>
Cc: Thomas Abraham <thomas.ab@samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 arch/arm/boot/dts/exynos5800.dtsi |   39 +++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5800.dtsi b/arch/arm/boot/dts/exynos5800.dtsi
index c0bb356..ba7ecd2 100644
--- a/arch/arm/boot/dts/exynos5800.dtsi
+++ b/arch/arm/boot/dts/exynos5800.dtsi
@@ -19,6 +19,45 @@
 	compatible = "samsung,exynos5800", "samsung,exynos5";
 };
 
+&cpu0 {
+	operating-points = <
+		1800000 1250000
+		1700000 1250000
+		1600000 1250000
+		1500000 1100000
+		1400000 1100000
+		1300000 1100000
+		1200000 1000000
+		1100000 1000000
+		1000000 1000000
+		 900000 1000000
+		 800000  900000
+		 700000  900000
+		 600000  900000
+		 500000  900000
+		 400000  900000
+		 300000  900000
+		 200000  900000
+	>;
+};
+
+&cpu4 {
+	operating-points = <
+		1300000 1250000
+		1200000 1250000
+		1100000 1250000
+		1000000 1100000
+		 900000 1100000
+		 800000 1100000
+		 700000 1000000
+		 600000 1000000
+		 500000 1000000
+		 400000 1000000
+		 300000  900000
+		 200000  900000
+	>;
+};
+
 &clock {
 	compatible = "samsung,exynos5800-clock";
 };
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 8/8] ARM: Exynos: use generic cpufreq driver for Exynos5800
  2015-04-21 13:17 [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms Bartlomiej Zolnierkiewicz
                   ` (6 preceding siblings ...)
  2015-04-21 13:17 ` [PATCH 7/8] ARM: dts: Exynos5800: fix CPU OPP Bartlomiej Zolnierkiewicz
@ 2015-04-21 13:17 ` Bartlomiej Zolnierkiewicz
  2015-04-21 15:34 ` [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms Bartlomiej Zolnierkiewicz
  8 siblings, 0 replies; 18+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2015-04-21 13:17 UTC (permalink / raw)
  To: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar
  Cc: Tomasz Figa, Lukasz Majewski, Heiko Stuebner, Chanwoo Choi,
	Kevin Hilman, Javier Martinez Canillas, linux-samsung-soc,
	linux-pm, linux-arm-kernel, linux-kernel, b.zolnierkie

From: Thomas Abraham <thomas.ab@samsung.com>

The new CPU clock type allows the use of generic arm_big_little_dt
cpufreq driver for Exynos5800.

Changes by Bartlomiej:
- split Exynos5800 support from the original patch
- disable cpufreq if big.LITTLE switcher support is enabled

Cc: Tomasz Figa <tomasz.figa@gmail.com>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 arch/arm/mach-exynos/exynos.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index 11ac7fb..7892062 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -213,6 +213,7 @@ static const struct of_device_id exynos_cpufreq_matches[] = {
  */
 #ifndef CONFIG_BL_SWITCHER
 	{ .compatible = "samsung,exynos5420", .data = "arm-bL-cpufreq-dt" },
+	{ .compatible = "samsung,exynos5800", .data = "arm-bL-cpufreq-dt" },
 #endif
 	{ /* sentinel */ }
 };
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms
  2015-04-21 13:17 [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms Bartlomiej Zolnierkiewicz
                   ` (7 preceding siblings ...)
  2015-04-21 13:17 ` [PATCH 8/8] ARM: Exynos: use generic cpufreq driver for Exynos5800 Bartlomiej Zolnierkiewicz
@ 2015-04-21 15:34 ` Bartlomiej Zolnierkiewicz
  8 siblings, 0 replies; 18+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2015-04-21 15:34 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: Sylwester Nawrocki, Mike Turquette, Kukjin Kim, Kukjin Kim,
	Viresh Kumar, Tomasz Figa, Lukasz Majewski, Heiko Stuebner,
	Chanwoo Choi, Kevin Hilman, Javier Martinez Canillas,
	linux-samsung-soc, linux-pm, linux-arm-kernel, linux-kernel

On Tuesday, April 21, 2015 03:17:50 PM Bartlomiej Zolnierkiewicz wrote:
> Hi,
> 
> This patch series adds generic arm_big_little_dt cpufreq driver
> support for Exynos5420/5800 (using the new CPU clock type which
> allows it).  It also:
> - enhances arm_big_little[_dt] driver with CPU cluster regulator
>   support
> - fixes CPU clock configuration data and CPU operating points
>   setup for Exynos5800
> - adds CPU cluster regulator supplies for ODROID-XU3 board
> 
> This patch series has been tested on Exynos5800 based ODROID-XU3
> board.
> 
> Depends on:
> - next-20150330 branch of linux-next kernel tree
> - "[PATCH 0/6] cpufreq: use generic cpufreq drivers for Exynos4210
>   platform" [1]
> - "[PATCH 0/6] cpufreq: use generic cpufreq drivers for Exynos4x12
>   platform" [2]
> - "[PATCH] cpufreq: exynos: remove dead ->need_apll_change method" [3]
> - "[PATCH 0/4] cpufreq: use generic cpufreq drivers for Exynos5250
>   platform" [4]
> 
> [1] http://www.kernelhub.org/?msg=721136&p=2
> [2] http://marc.info/?l=linux-pm&m=142868881101873&w=2
> [3] https://lkml.org/lkml/2015/3/27/574
> [4] https://lkml.org/lkml/2015/4/13/611
> 
> Changes over Thomas' original v12 code:
> - split Exynos5420 and Exynos5800 support
> - moved E5420_[EGL,KFC]_DIV0() macros to clk-exynos5420.c
> - disabled cpufreq if big.LITTLE switcher support is enabled
> - enhanced arm_big_little[_dt] driver with CPU cluster regulator
>   support
> - fixed CPU clock configuration data for Exynos5800
> - fixed CPU operating points setup for Exynos5800
> - added CPU cluster regulator supplies for ODROID-XU3 board
> 
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics
> 
> 
> Bartlomiej Zolnierkiewicz (4):
>   cpufreq: arm_big_little: add cluster regulator support
>   ARM: dts: add cluster regulator supply properties for
>     exynos5422-odroidxu3
>   clk: samsung: exynos5800: fix cpu clock configuration data
>   ARM: dts: Exynos5800: fix CPU OPP
> 
> Thomas Abraham (4):
>   clk: samsung: exynos5420: add cpu clock configuration data and
>     instantiate cpu clock
>   ARM: dts: Exynos5420: add CPU OPP and regulator supply property
>   ARM: Exynos: use generic cpufreq driver for Exynos5420
>   ARM: Exynos: use generic cpufreq driver for Exynos5800
> 
>  .../bindings/cpufreq/arm_big_little_dt.txt         |    4 +
>  arch/arm/boot/dts/exynos5420.dtsi                  |   38 +++++
>  arch/arm/boot/dts/exynos5422-odroidxu3.dts         |    8 +
>  arch/arm/boot/dts/exynos5800.dtsi                  |   39 +++++
>  arch/arm/mach-exynos/exynos.c                      |    8 +
>  drivers/clk/samsung/clk-exynos5420.c               |   88 ++++++++++-
>  drivers/cpufreq/arm_big_little.c                   |  153 +++++++++++++++++---
>  include/dt-bindings/clock/exynos5420.h             |    2 +
>  8 files changed, 320 insertions(+), 20 deletions(-)

If you are using exynos5420-arndale-octa.dts, exynos5420-peach-pit.dts,
exynos5420-smdk5420.dts or exynos5800-peach-pi.dts please use the attached
patch instead of patch #2/8.  Sorry for the inconvenience.

From: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Subject: [PATCH v2 2/8] ARM: dts: Exynos5420/5800: add cluster regulator supply properties

Add cluster regulator supply properties as a preparation to
adding generic arm_big_little_dt cpufreq driver support for
Exynos5420 and Exynos5800 based boards.

Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Doug Anderson <dianders@chromium.org>
Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Cc: Andreas Faerber <afaerber@suse.de>
Cc: Sachin Kamat <sachin.kamat@linaro.org>
Cc: Thomas Abraham <thomas.ab@samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
---
 arch/arm/boot/dts/exynos5420-arndale-octa.dts |    8 ++++++++
 arch/arm/boot/dts/exynos5420-peach-pit.dts    |    8 ++++++++
 arch/arm/boot/dts/exynos5420-smdk5420.dts     |    8 ++++++++
 arch/arm/boot/dts/exynos5422-odroidxu3.dts    |    8 ++++++++
 arch/arm/boot/dts/exynos5800-peach-pi.dts     |    8 ++++++++
 5 files changed, 40 insertions(+)

Index: b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
===================================================================
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts	2015-04-21 16:26:53.022509881 +0200
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts	2015-04-21 17:25:30.250396715 +0200
@@ -369,6 +369,14 @@
 	};
 };
 
+&cpu0 {
+	cpu-cluster.0-supply = <&buck2_reg>;
+};
+
+&cpu4 {
+	cpu-cluster.1-supply = <&buck6_reg>;
+};
+
 &usbdrd_dwc3_1 {
 	dr_mode = "host";
 };
Index: b/arch/arm/boot/dts/exynos5420-peach-pit.dts
===================================================================
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts	2015-04-21 16:26:53.022509881 +0200
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts	2015-04-21 17:26:32.034394727 +0200
@@ -676,6 +676,14 @@
 	};
 };
 
+&cpu0 {
+	cpu-cluster.0-supply = <&buck2_reg>;
+};
+
+&cpu4 {
+	cpu-cluster.1-supply = <&buck6_reg>;
+};
+
 &i2c_2 {
 	status = "okay";
 	samsung,i2c-sda-delay = <100>;
Index: b/arch/arm/boot/dts/exynos5420-smdk5420.dts
===================================================================
--- a/arch/arm/boot/dts/exynos5420-smdk5420.dts	2015-04-21 16:26:53.022509881 +0200
+++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts	2015-04-21 17:27:04.338393689 +0200
@@ -420,3 +420,11 @@
 		};
 	};
 };
+
+&cpu0 {
+	cpu-cluster.0-supply = <&buck2_reg>;
+};
+
+&cpu4 {
+	cpu-cluster.1-supply = <&buck6_reg>;
+};
Index: b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
===================================================================
--- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts	2015-04-21 17:23:44.334400124 +0200
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts	2015-04-21 17:24:05.454399445 +0200
@@ -355,6 +355,14 @@
 	dr_mode = "otg";
 };
 
+&cpu0 {
+	cpu-cluster.0-supply = <&buck2_reg>;
+};
+
+&cpu4 {
+	cpu-cluster.1-supply = <&buck6_reg>;
+};
+
 &i2c_0 {
 	status = "okay";
 
Index: b/arch/arm/boot/dts/exynos5800-peach-pi.dts
===================================================================
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts	2015-04-21 16:26:53.030509881 +0200
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts	2015-04-21 17:27:47.674392295 +0200
@@ -638,6 +638,14 @@
 	};
 };
 
+&cpu0 {
+	cpu-cluster.0-supply = <&buck2_reg>;
+};
+
+&cpu4 {
+	cpu-cluster.1-supply = <&buck6_reg>;
+};
+
 &i2c_2 {
 	status = "okay";
 	samsung,i2c-sda-delay = <100>;





^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/8] cpufreq: arm_big_little: add cluster regulator support
  2015-04-21 13:17 ` [PATCH 1/8] cpufreq: arm_big_little: add cluster regulator support Bartlomiej Zolnierkiewicz
@ 2015-04-22  8:07   ` Lukasz Majewski
  2015-04-27  5:15   ` Viresh Kumar
  2015-06-11 22:17   ` Heiko Stübner
  2 siblings, 0 replies; 18+ messages in thread
From: Lukasz Majewski @ 2015-04-22  8:07 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar, Doug Anderson, Kevin Hilman,
	Heiko Stuebner, linux-pm, Sachin Kamat, Tomasz Figa,
	linux-kernel, Chanwoo Choi, linux-samsung-soc, Andreas Faerber,
	Javier Martinez Canillas, linux-arm-kernel

Hi Bartlomiej,

> Add cluster regulator support as a preparation to adding
> generic arm_big_little_dt cpufreq_dt driver support for
> ODROID-XU3 board.  This allows arm_big_little[_dt] driver
> to set not only the frequency but also the voltage (which
> is obtained from operating point's voltage value) for CPU
> clusters.
> 
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Cc: Doug Anderson <dianders@chromium.org>
> Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> Cc: Andreas Faerber <afaerber@suse.de>
> Cc: Sachin Kamat <sachin.kamat@linaro.org>
> Cc: Thomas Abraham <thomas.ab@samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> ---
>  .../bindings/cpufreq/arm_big_little_dt.txt         |    4 +
>  drivers/cpufreq/arm_big_little.c                   |  153
> +++++++++++++++++--- 2 files changed, 139 insertions(+), 18
> deletions(-)
> 
> diff --git
> a/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt
> b/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt
> index 0715695..8ca4a12 100644 ---
> a/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt +++
> b/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt @@
> -18,6 +18,10 @@ Required properties: Optional properties:
>  - clock-latency: Specify the possible maximum transition latency for
> clock, in unit of nanoseconds.
> +- cpu-cluster.0-supply: Provides the regulator node supplying
> voltage to CPU
> +  cluster 0.
> +- cpu-cluster.1-supply: Provides the regulator node supplying
> voltage to CPU
> +  cluster 1.
>  
>  Examples:
>  
> diff --git a/drivers/cpufreq/arm_big_little.c
> b/drivers/cpufreq/arm_big_little.c index e1a6ba6..edb461b 100644
> --- a/drivers/cpufreq/arm_big_little.c
> +++ b/drivers/cpufreq/arm_big_little.c
> @@ -31,6 +31,7 @@
>  #include <linux/slab.h>
>  #include <linux/topology.h>
>  #include <linux/types.h>
> +#include <linux/regulator/consumer.h>
>  #include <asm/bL_switcher.h>
>  
>  #include "arm_big_little.h"
> @@ -54,6 +55,9 @@ static bool bL_switching_enabled;
>  
>  static struct cpufreq_arm_bL_ops *arm_bL_ops;
>  static struct clk *clk[MAX_CLUSTERS];
> +static struct regulator *reg[MAX_CLUSTERS];
> +static struct device *cpu_devs[MAX_CLUSTERS];
> +static int transition_latencies[MAX_CLUSTERS];
>  static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1];
>  static atomic_t cluster_usage[MAX_CLUSTERS + 1];
>  
> @@ -122,7 +126,76 @@ static unsigned int bL_cpufreq_get_rate(unsigned
> int cpu) }
>  }
>  
> -static unsigned int
> +static int
> +bL_cpufreq_set_rate_cluster(u32 cpu, u32 cluster, u32 new_rate)
> +{
> +	unsigned long volt = 0, volt_old = 0;
> +	long freq_Hz;
> +	u32 old_rate;
> +	int ret;
> +
> +	freq_Hz = new_rate * 1000;
> +	old_rate = clk_get_rate(clk[cluster]) / 1000;
> +
> +	if (!IS_ERR(reg[cluster])) {
> +		struct dev_pm_opp *opp;
> +		unsigned long opp_freq;
> +
> +		rcu_read_lock();
> +		opp = dev_pm_opp_find_freq_ceil(cpu_devs[cluster],
> &freq_Hz);
> +		if (IS_ERR(opp)) {
> +			rcu_read_unlock();
> +			pr_err("%s: cpu %d, cluster: %d, failed to
> find OPP for %ld\n",
> +				__func__, cpu, cluster, freq_Hz);
> +			return PTR_ERR(opp);
> +		}
> +		volt = dev_pm_opp_get_voltage(opp);
> +		opp_freq = dev_pm_opp_get_freq(opp);
> +		rcu_read_unlock();
> +		volt_old = regulator_get_voltage(reg[cluster]);
> +		pr_debug("%s: cpu %d, cluster: %d, Found OPP: %ld
> kHz, %ld uV\n",
> +			__func__, cpu, cluster, opp_freq / 1000,
> volt);
> +	}
> +
> +	pr_debug("%s: cpu %d, cluster: %d, %u MHz, %ld mV --> %u
> MHz, %ld mV\n",
> +		__func__, cpu, cluster,
> +		old_rate / 1000, (volt_old > 0) ? volt_old / 1000 :
> -1,
> +		new_rate / 1000, volt ? volt / 1000 : -1);
> +
> +	/* scaling up? scale voltage before frequency */
> +	if (!IS_ERR(reg[cluster]) && new_rate > old_rate) {
> +		ret = regulator_set_voltage_tol(reg[cluster], volt,
> 0);
> +		if (ret) {
> +			pr_err("%s: cpu: %d, cluster: %d, failed to
> scale voltage up: %d\n",
> +				__func__, cpu, cluster, ret);
> +			return ret;
> +		}
> +	}
> +
> +	ret = clk_set_rate(clk[cluster], new_rate * 1000);
> +	if (WARN_ON(ret)) {
> +		pr_err("%s: clk_set_rate failed: %d, cluster: %d\n",
> +			__func__, cluster, ret);
> +		if (!IS_ERR(reg[cluster]) && volt_old > 0)
> +			regulator_set_voltage_tol(reg[cluster],
> volt_old, 0);
> +		return ret;
> +	}
> +
> +	/* scaling down? scale voltage after frequency */
> +	if (!IS_ERR(reg[cluster]) && new_rate < old_rate) {
> +		ret = regulator_set_voltage_tol(reg[cluster], volt,
> 0);
> +		if (ret) {
> +			pr_err("%s: cpu: %d, cluster: %d, failed to
> scale voltage down: %d\n",
> +				__func__, cpu, cluster, ret);
> +			clk_set_rate(clk[cluster], old_rate * 1000);
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int
>  bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32
> rate) {
>  	u32 new_rate, prev_rate;
> @@ -145,22 +218,17 @@ bL_cpufreq_set_rate(u32 cpu, u32 old_cluster,
> u32 new_cluster, u32 rate) pr_debug("%s: cpu: %d, old cluster: %d,
> new cluster: %d, freq: %d\n", __func__, cpu, old_cluster,
> new_cluster, new_rate); 
> -	ret = clk_set_rate(clk[new_cluster], new_rate * 1000);
> -	if (WARN_ON(ret)) {
> -		pr_err("clk_set_rate failed: %d, new cluster: %d\n",
> ret,
> -				new_cluster);
> -		if (bLs) {
> -			per_cpu(cpu_last_req_freq, cpu) = prev_rate;
> -			per_cpu(physical_cluster, cpu) = old_cluster;
> -		}
> -
> -		mutex_unlock(&cluster_lock[new_cluster]);
> -
> -		return ret;
> +	ret = bL_cpufreq_set_rate_cluster(cpu, new_cluster,
> new_rate);
> +	if (ret && bLs) {
> +		per_cpu(cpu_last_req_freq, cpu) = prev_rate;
> +		per_cpu(physical_cluster, cpu) = old_cluster;
>  	}
>  
>  	mutex_unlock(&cluster_lock[new_cluster]);
>  
> +	if (ret)
> +		return ret;
> +
>  	/* Recalc freq for old cluster when switching clusters */
>  	if (old_cluster != new_cluster) {
>  		pr_debug("%s: cpu: %d, old cluster: %d, new cluster:
> %d\n", @@ -174,14 +242,11 @@ bL_cpufreq_set_rate(u32 cpu, u32
> old_cluster, u32 new_cluster, u32 rate) /* Set freq of old cluster if
> there are cpus left on it */ new_rate =
> find_cluster_maxfreq(old_cluster); new_rate =
> ACTUAL_FREQ(old_cluster, new_rate); -
>  		if (new_rate) {
>  			pr_debug("%s: Updating rate of old cluster:
> %d, to freq: %d\n", __func__, old_cluster, new_rate);
>  
> -			if (clk_set_rate(clk[old_cluster], new_rate
> * 1000))
> -				pr_err("%s: clk_set_rate failed: %d,
> old cluster: %d\n",
> -						__func__, ret,
> old_cluster);
> +			bL_cpufreq_set_rate_cluster(cpu,
> old_cluster, new_rate); }
>  		mutex_unlock(&cluster_lock[old_cluster]);
>  	}
> @@ -288,6 +353,8 @@ static void
> _put_cluster_clk_and_freq_table(struct device *cpu_dev) return;
>  
>  	clk_put(clk[cluster]);
> +	if (!IS_ERR(reg[cluster]))
> +		regulator_put(reg[cluster]);
>  	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table[cluster]);
>  	if (arm_bL_ops->free_opp_table)
>  		arm_bL_ops->free_opp_table(cpu_dev);
> @@ -321,6 +388,7 @@ static void put_cluster_clk_and_freq_table(struct
> device *cpu_dev) 
>  static int _get_cluster_clk_and_freq_table(struct device *cpu_dev)
>  {
> +	unsigned long min_uV = ~0, max_uV = 0;
>  	u32 cluster = raw_cpu_to_cluster(cpu_dev->id);
>  	char name[14] = "cpu-cluster.";
>  	int ret;
> @@ -335,6 +403,51 @@ static int
> _get_cluster_clk_and_freq_table(struct device *cpu_dev) goto out;
>  	}
>  
> +	name[12] = cluster + '0';
> +	reg[cluster] = regulator_get_optional(cpu_dev, name);
> +	if (!IS_ERR(reg[cluster])) {
> +		unsigned long opp_freq = 0;
> +
> +		dev_dbg(cpu_dev, "%s: reg: %p, cluster: %d\n",
> +			__func__, reg[cluster], cluster);
> +		cpu_devs[cluster] = cpu_dev;
> +
> +		/*
> +		 * Disable any OPPs where the connected regulator
> isn't able to
> +		 * provide the specified voltage and record minimum
> and maximum
> +		 * voltage levels.
> +		 */
> +		while (1) {
> +			struct dev_pm_opp *opp;
> +			unsigned long opp_uV;
> +
> +			rcu_read_lock();
> +			opp = dev_pm_opp_find_freq_ceil(cpu_dev,
> &opp_freq);
> +			if (IS_ERR(opp)) {
> +				rcu_read_unlock();
> +				break;
> +			}
> +			opp_uV = dev_pm_opp_get_voltage(opp);
> +			rcu_read_unlock();
> +
> +			if
> (regulator_is_supported_voltage(reg[cluster], opp_uV,
> +							   opp_uV)) {
> +				if (opp_uV < min_uV)
> +					min_uV = opp_uV;
> +				if (opp_uV > max_uV)
> +					max_uV = opp_uV;
> +			} else {
> +				dev_pm_opp_disable(cpu_dev,
> opp_freq);
> +			}
> +
> +			opp_freq++;
> +		}
> +
> +		ret = regulator_set_voltage_time(reg[cluster],
> min_uV, max_uV);
> +		if (ret > 0)
> +			transition_latencies[cluster] = ret * 1000;
> +	}
> +
>  	ret = dev_pm_opp_init_cpufreq_table(cpu_dev,
> &freq_table[cluster]); if (ret) {
>  		dev_err(cpu_dev, "%s: failed to init cpufreq table,
> cpu: %d, err: %d\n", @@ -342,7 +455,6 @@ static int
> _get_cluster_clk_and_freq_table(struct device *cpu_dev) goto
> free_opp_table; }
>  
> -	name[12] = cluster + '0';
>  	clk[cluster] = clk_get(cpu_dev, name);
>  	if (!IS_ERR(clk[cluster])) {
>  		dev_dbg(cpu_dev, "%s: clk: %p & freq table: %p,
> cluster: %d\n", @@ -469,6 +581,11 @@ static int
> bL_cpufreq_init(struct cpufreq_policy *policy) else
>  		policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
>  
> +	if (cur_cluster < MAX_CLUSTERS &&
> +	    policy->cpuinfo.transition_latency != CPUFREQ_ETERNAL)
> +		policy->cpuinfo.transition_latency
> +			+= transition_latencies[cur_cluster];
> +
>  	if (is_bL_switching_enabled())
>  		per_cpu(cpu_last_req_freq, policy->cpu) =
> clk_get_cpu_rate(policy->cpu); 

Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>

-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/8] ARM: dts: add cluster regulator supply properties for exynos5422-odroidxu3
  2015-04-21 13:17 ` [PATCH 2/8] ARM: dts: add cluster regulator supply properties for exynos5422-odroidxu3 Bartlomiej Zolnierkiewicz
@ 2015-04-22  8:07   ` Lukasz Majewski
  0 siblings, 0 replies; 18+ messages in thread
From: Lukasz Majewski @ 2015-04-22  8:07 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar, Tomasz Figa, Heiko Stuebner,
	Chanwoo Choi, Kevin Hilman, Javier Martinez Canillas,
	linux-samsung-soc, linux-pm, linux-arm-kernel, linux-kernel,
	Doug Anderson, Andreas Faerber, Sachin Kamat

Hi Bartlomiej,

> Add cluster regulator supply properties as a preparation to
> adding generic arm_big_little_dt cpufreq driver support for
> ODROID-XU3 board.
> 
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Cc: Doug Anderson <dianders@chromium.org>
> Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> Cc: Andreas Faerber <afaerber@suse.de>
> Cc: Sachin Kamat <sachin.kamat@linaro.org>
> Cc: Thomas Abraham <thomas.ab@samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> ---
>  arch/arm/boot/dts/exynos5422-odroidxu3.dts |    8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
> b/arch/arm/boot/dts/exynos5422-odroidxu3.dts index edc25cf..e876016
> 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
> +++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
> @@ -355,6 +355,14 @@
>  	dr_mode = "otg";
>  };
>  
> +&cpu0 {
> +	cpu-cluster.0-supply = <&buck2_reg>;
> +};
> +
> +&cpu4 {
> +	cpu-cluster.1-supply = <&buck6_reg>;
> +};
> +
>  &i2c_0 {
>  	status = "okay";
>  

Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>

-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/8] clk: samsung: exynos5420: add cpu clock configuration data and instantiate cpu clock
  2015-04-21 13:17 ` [PATCH 3/8] clk: samsung: exynos5420: add cpu clock configuration data and instantiate cpu clock Bartlomiej Zolnierkiewicz
@ 2015-04-22  8:10   ` Lukasz Majewski
  0 siblings, 0 replies; 18+ messages in thread
From: Lukasz Majewski @ 2015-04-22  8:10 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar, Kevin Hilman, Heiko Stuebner, linux-pm,
	Tomasz Figa, linux-kernel, Chanwoo Choi, linux-samsung-soc,
	Javier Martinez Canillas, linux-arm-kernel

Hi Bartlomiej,

> From: Thomas Abraham <thomas.ab@samsung.com>
> 
> With the addition of the new Samsung specific cpu-clock type, the
> arm clock can be represented as a cpu-clock type. Add the CPU clock
> configuration data and instantiate the CPU clock type for Exynos5420.
> 
> Changes by Bartlomiej:
> - split Exynos5420 support from the original patches
> - moved E5420_[EGL,KFC]_DIV0() macros to clk-exynos5420.c
> 
> Cc: Tomasz Figa <tomasz.figa@gmail.com>
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> ---
>  drivers/clk/samsung/clk-exynos5420.c   |   58
> ++++++++++++++++++++++++++++++--
> include/dt-bindings/clock/exynos5420.h |    2 ++ 2 files changed, 58
> insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-exynos5420.c
> b/drivers/clk/samsung/clk-exynos5420.c index 07d666c..9398a2d 100644
> --- a/drivers/clk/samsung/clk-exynos5420.c
> +++ b/drivers/clk/samsung/clk-exynos5420.c
> @@ -19,6 +19,7 @@
>  #include <linux/syscore_ops.h>
>  
>  #include "clk.h"
> +#include "clk-cpu.h"
>  
>  #define APLL_LOCK		0x0
>  #define APLL_CON0		0x100
> @@ -616,9 +617,11 @@ static struct samsung_mux_clock
> exynos5x_mux_clks[] __initdata = { MUX(0, "mout_mspll_kfc",
> mout_mspll_cpu_p, SRC_TOP7, 8, 2), MUX(0, "mout_mspll_cpu",
> mout_mspll_cpu_p, SRC_TOP7, 12, 2), 
> -	MUX(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1),
> +	MUX_F(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
> +	      CLK_SET_RATE_PARENT, 0),
>  	MUX(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1),
> -	MUX(0, "mout_kpll", mout_kpll_p, SRC_KFC, 0, 1),
> +	MUX_F(0, "mout_kpll", mout_kpll_p, SRC_KFC, 0, 1,
> +	      CLK_SET_RATE_PARENT, 0),
>  	MUX(0, "mout_kfc", mout_kfc_p, SRC_KFC, 16, 1),
>  
>  	MUX(0, "mout_aclk200", mout_group1_p, SRC_TOP0, 8, 2),
> @@ -1246,6 +1249,50 @@ static struct samsung_pll_clock
> exynos5x_plls[nr_plls] __initdata = { KPLL_CON0, NULL),
>  };
>  
> +#define E5420_EGL_DIV0(apll, pclk_dbg, atb,
> cpud)			\
> +		((((apll) << 24) | ((pclk_dbg) << 20) | ((atb) <<
> 16) |	\
> +		 ((cpud) << 4)))
> +
> +static const struct exynos_cpuclk_cfg_data exynos5420_eglclk_d[]
> __initconst = {
> +	{ 1800000, E5420_EGL_DIV0(3, 7, 7, 4), },
> +	{ 1700000, E5420_EGL_DIV0(3, 7, 7, 3), },
> +	{ 1600000, E5420_EGL_DIV0(3, 7, 7, 3), },
> +	{ 1500000, E5420_EGL_DIV0(3, 7, 7, 3), },
> +	{ 1400000, E5420_EGL_DIV0(3, 7, 7, 3), },
> +	{ 1300000, E5420_EGL_DIV0(3, 7, 7, 2), },
> +	{ 1200000, E5420_EGL_DIV0(3, 7, 7, 2), },
> +	{ 1100000, E5420_EGL_DIV0(3, 7, 7, 2), },
> +	{ 1000000, E5420_EGL_DIV0(3, 6, 6, 2), },
> +	{  900000, E5420_EGL_DIV0(3, 6, 6, 2), },
> +	{  800000, E5420_EGL_DIV0(3, 5, 5, 2), },
> +	{  700000, E5420_EGL_DIV0(3, 5, 5, 2), },
> +	{  600000, E5420_EGL_DIV0(3, 4, 4, 2), },
> +	{  500000, E5420_EGL_DIV0(3, 3, 3, 2), },
> +	{  400000, E5420_EGL_DIV0(3, 3, 3, 2), },
> +	{  300000, E5420_EGL_DIV0(3, 3, 3, 2), },
> +	{  200000, E5420_EGL_DIV0(3, 3, 3, 2), },
> +	{  0 },
> +};
> +
> +#define E5420_KFC_DIV(kpll, pclk,
> aclk)					\
> +		((((kpll) << 24) | ((pclk) << 20) | ((aclk) << 4)))
> +
> +static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[]
> __initconst = {
> +	{ 1300000, E5420_KFC_DIV(3, 5, 2), },
> +	{ 1200000, E5420_KFC_DIV(3, 5, 2), },
> +	{ 1100000, E5420_KFC_DIV(3, 5, 2), },
> +	{ 1000000, E5420_KFC_DIV(3, 5, 2), },
> +	{  900000, E5420_KFC_DIV(3, 5, 2), },
> +	{  800000, E5420_KFC_DIV(3, 5, 2), },
> +	{  700000, E5420_KFC_DIV(3, 4, 2), },
> +	{  600000, E5420_KFC_DIV(3, 4, 2), },
> +	{  500000, E5420_KFC_DIV(3, 4, 2), },
> +	{  400000, E5420_KFC_DIV(3, 3, 2), },
> +	{  300000, E5420_KFC_DIV(3, 3, 2), },
> +	{  200000, E5420_KFC_DIV(3, 3, 2), },
> +	{  0 },
> +};
> +
>  static const struct of_device_id ext_clk_match[] __initconst = {
>  	{ .compatible = "samsung,exynos5420-oscclk", .data = (void
> *)0, }, { },
> @@ -1310,6 +1357,13 @@ static void __init exynos5x_clk_init(struct
> device_node *np, ARRAY_SIZE(exynos5800_gate_clks));
>  	}
>  
> +	exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
> +		mout_cpu_p[0], mout_cpu_p[1], 0x200,
> +		exynos5420_eglclk_d,
> ARRAY_SIZE(exynos5420_eglclk_d), 0);
> +	exynos_register_cpu_clock(ctx, CLK_KFC_CLK, "kfcclk",
> +		mout_kfc_p[0], mout_kfc_p[1], 0x28200,
> +		exynos5420_kfcclk_d,
> ARRAY_SIZE(exynos5420_kfcclk_d), 0); +
>  	exynos5420_clk_sleep_init();
>  
>  	samsung_clk_of_add_provider(np, ctx);
> diff --git a/include/dt-bindings/clock/exynos5420.h
> b/include/dt-bindings/clock/exynos5420.h index 99da0d1..dde9664 100644
> --- a/include/dt-bindings/clock/exynos5420.h
> +++ b/include/dt-bindings/clock/exynos5420.h
> @@ -25,6 +25,8 @@
>  #define CLK_FOUT_MPLL		10
>  #define CLK_FOUT_BPLL		11
>  #define CLK_FOUT_KPLL		12
> +#define CLK_ARM_CLK		13
> +#define CLK_KFC_CLK		14
>  
>  /* gate for special clocks (sclk) */
>  #define CLK_SCLK_UART0		128

Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>

-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 4/8] ARM: dts: Exynos5420: add CPU OPP and regulator supply property
  2015-04-21 13:17 ` [PATCH 4/8] ARM: dts: Exynos5420: add CPU OPP and regulator supply property Bartlomiej Zolnierkiewicz
@ 2015-04-22  8:12   ` Lukasz Majewski
  0 siblings, 0 replies; 18+ messages in thread
From: Lukasz Majewski @ 2015-04-22  8:12 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar, Doug Anderson, Kevin Hilman,
	Heiko Stuebner, linux-pm, Sachin Kamat, Tomasz Figa,
	linux-kernel, Chanwoo Choi, linux-samsung-soc, Andreas Faerber,
	Javier Martinez Canillas, linux-arm-kernel

Hi Bartlomiej,

> From: Thomas Abraham <thomas.ab@samsung.com>
> 
> For Exynos5420 platforms, add CPU operating points and CPU
> regulator supply properties for migrating from Exynos specific
> cpufreq driver to using generic cpufreq driver.
> 
> Changes by Bartlomiej:
> - split Exynos5420 support from the original patch
> 
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Cc: Doug Anderson <dianders@chromium.org>
> Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> Cc: Andreas Faerber <afaerber@suse.de>
> Cc: Sachin Kamat <sachin.kamat@linaro.org>
> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> ---
>  arch/arm/boot/dts/exynos5420.dtsi |   38
> +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/exynos5420.dtsi
> b/arch/arm/boot/dts/exynos5420.dtsi index f67b23f..85b9cfc 100644
> --- a/arch/arm/boot/dts/exynos5420.dtsi
> +++ b/arch/arm/boot/dts/exynos5420.dtsi
> @@ -59,8 +59,26 @@
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a15";
>  			reg = <0x0>;
> +			clocks = <&clock CLK_ARM_CLK>;
> +			clock-names = "cpu-cluster.0";
>  			clock-frequency = <1800000000>;
>  			cci-control-port = <&cci_control1>;
> +			clock-latency = <140000>;
> +
> +			operating-points = <
> +				1800000 1250000
> +				1700000 1212500
> +				1600000 1175000
> +				1500000 1137500
> +				1400000 1112500
> +				1300000 1062500
> +				1200000 1037500
> +				1100000 1012500
> +				1000000 987500
> +				 900000 962500
> +				 800000 937500
> +				 700000 912500
> +			>;
>  		};
>  
>  		cpu1: cpu@1 {
> @@ -69,6 +87,7 @@
>  			reg = <0x1>;
>  			clock-frequency = <1800000000>;
>  			cci-control-port = <&cci_control1>;
> +			clock-latency = <140000>;
>  		};
>  
>  		cpu2: cpu@2 {
> @@ -77,6 +96,7 @@
>  			reg = <0x2>;
>  			clock-frequency = <1800000000>;
>  			cci-control-port = <&cci_control1>;
> +			clock-latency = <140000>;
>  		};
>  
>  		cpu3: cpu@3 {
> @@ -85,14 +105,29 @@
>  			reg = <0x3>;
>  			clock-frequency = <1800000000>;
>  			cci-control-port = <&cci_control1>;
> +			clock-latency = <140000>;
>  		};
>  
>  		cpu4: cpu@100 {
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a7";
>  			reg = <0x100>;
> +			clocks = <&clock CLK_KFC_CLK>;
> +			clock-names = "cpu-cluster.1";
>  			clock-frequency = <1000000000>;
>  			cci-control-port = <&cci_control0>;
> +			clock-latency = <140000>;
> +
> +			operating-points = <
> +				1300000 1275000
> +				1200000 1212500
> +				1100000 1162500
> +				1000000 1112500
> +				 900000 1062500
> +				 800000 1025000
> +				 700000 975000
> +				 600000 937500
> +			>;
>  		};
>  
>  		cpu5: cpu@101 {
> @@ -101,6 +136,7 @@
>  			reg = <0x101>;
>  			clock-frequency = <1000000000>;
>  			cci-control-port = <&cci_control0>;
> +			clock-latency = <140000>;
>  		};
>  
>  		cpu6: cpu@102 {
> @@ -109,6 +145,7 @@
>  			reg = <0x102>;
>  			clock-frequency = <1000000000>;
>  			cci-control-port = <&cci_control0>;
> +			clock-latency = <140000>;
>  		};
>  
>  		cpu7: cpu@103 {
> @@ -117,6 +154,7 @@
>  			reg = <0x103>;
>  			clock-frequency = <1000000000>;
>  			cci-control-port = <&cci_control0>;
> +			clock-latency = <140000>;
>  		};
>  	};
>  

Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>

-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/8] ARM: Exynos: use generic cpufreq driver for Exynos5420
  2015-04-21 13:17 ` [PATCH 5/8] ARM: Exynos: use generic cpufreq driver for Exynos5420 Bartlomiej Zolnierkiewicz
@ 2015-04-22  8:13   ` Lukasz Majewski
  0 siblings, 0 replies; 18+ messages in thread
From: Lukasz Majewski @ 2015-04-22  8:13 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar, Kevin Hilman, Heiko Stuebner, linux-pm,
	Tomasz Figa, linux-kernel, Chanwoo Choi, linux-samsung-soc,
	Javier Martinez Canillas, linux-arm-kernel

Hi Bartlomiej,

> From: Thomas Abraham <thomas.ab@samsung.com>
> 
> The new CPU clock type allows the use of generic arm_big_little_dt
> cpufreq driver for Exynos5420.
> 
> Changes by Bartlomiej:
> - split Exynos5420 support from the original patch
> - disable cpufreq if big.LITTLE switcher support is enabled
> 
> Cc: Tomasz Figa <tomasz.figa@gmail.com>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> ---
>  arch/arm/mach-exynos/exynos.c |    7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm/mach-exynos/exynos.c
> b/arch/arm/mach-exynos/exynos.c index 4b03a32..11ac7fb 100644
> --- a/arch/arm/mach-exynos/exynos.c
> +++ b/arch/arm/mach-exynos/exynos.c
> @@ -207,6 +207,13 @@ struct cpufreq_dt_platform_data cpufreq_dt_pd = {
>  static const struct of_device_id exynos_cpufreq_matches[] = {
>  	{ .compatible = "samsung,exynos4210", .data = "cpufreq-dt" },
>  	{ .compatible = "samsung,exynos5250", .data = "cpufreq-dt" },
> +/*
> + * FIXME: When big.LITTLE switcher is enabled system lockups during
> + * ondemand governor stress testing (observed on ODROID-XU3 board).
> + */
> +#ifndef CONFIG_BL_SWITCHER
> +	{ .compatible = "samsung,exynos5420", .data =
> "arm-bL-cpufreq-dt" }, +#endif
>  	{ /* sentinel */ }
>  };
>  

Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>

-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 6/8] clk: samsung: exynos5800: fix cpu clock configuration data
  2015-04-21 13:17 ` [PATCH 6/8] clk: samsung: exynos5800: fix cpu clock configuration data Bartlomiej Zolnierkiewicz
@ 2015-04-22  8:14   ` Lukasz Majewski
  0 siblings, 0 replies; 18+ messages in thread
From: Lukasz Majewski @ 2015-04-22  8:14 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar, Kevin Hilman, Heiko Stuebner, linux-pm,
	Tomasz Figa, linux-kernel, Chanwoo Choi, linux-samsung-soc,
	Javier Martinez Canillas, linux-arm-kernel

Hi Bartlomiej,

> Fix cpu clock configuration data for Exynos5800 (it uses
> higher PCLK_DBG divider values than Exynos5420 and supports
> additional frequencies).
> 
> Based on Hardkernel's kernel for ODROID-XU3 board.
> 
> Cc: Tomasz Figa <tomasz.figa@gmail.com>
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> Cc: Thomas Abraham <thomas.ab@samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> ---
>  drivers/clk/samsung/clk-exynos5420.c |   36
> +++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+),
> 3 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-exynos5420.c
> b/drivers/clk/samsung/clk-exynos5420.c index 9398a2d..462aaee 100644
> --- a/drivers/clk/samsung/clk-exynos5420.c
> +++ b/drivers/clk/samsung/clk-exynos5420.c
> @@ -1274,10 +1274,34 @@ static const struct exynos_cpuclk_cfg_data
> exynos5420_eglclk_d[] __initconst = { {  0 },
>  };
>  
> +static const struct exynos_cpuclk_cfg_data exynos5800_eglclk_d[]
> __initconst = {
> +	{ 2000000, E5420_EGL_DIV0(3, 7, 7, 4), },
> +	{ 1900000, E5420_EGL_DIV0(3, 7, 7, 4), },
> +	{ 1800000, E5420_EGL_DIV0(3, 7, 7, 4), },
> +	{ 1700000, E5420_EGL_DIV0(3, 7, 7, 3), },
> +	{ 1600000, E5420_EGL_DIV0(3, 7, 7, 3), },
> +	{ 1500000, E5420_EGL_DIV0(3, 7, 7, 3), },
> +	{ 1400000, E5420_EGL_DIV0(3, 7, 7, 3), },
> +	{ 1300000, E5420_EGL_DIV0(3, 7, 7, 2), },
> +	{ 1200000, E5420_EGL_DIV0(3, 7, 7, 2), },
> +	{ 1100000, E5420_EGL_DIV0(3, 7, 7, 2), },
> +	{ 1000000, E5420_EGL_DIV0(3, 7, 6, 2), },
> +	{  900000, E5420_EGL_DIV0(3, 7, 6, 2), },
> +	{  800000, E5420_EGL_DIV0(3, 7, 5, 2), },
> +	{  700000, E5420_EGL_DIV0(3, 7, 5, 2), },
> +	{  600000, E5420_EGL_DIV0(3, 7, 4, 2), },
> +	{  500000, E5420_EGL_DIV0(3, 7, 3, 2), },
> +	{  400000, E5420_EGL_DIV0(3, 7, 3, 2), },
> +	{  300000, E5420_EGL_DIV0(3, 7, 3, 2), },
> +	{  200000, E5420_EGL_DIV0(3, 7, 3, 2), },
> +	{  0 },
> +};
> +
>  #define E5420_KFC_DIV(kpll, pclk,
> aclk)					\ ((((kpll) << 24) |
> ((pclk) << 20) | ((aclk) << 4))) 
>  static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[]
> __initconst = {
> +	{ 1400000, E5420_KFC_DIV(3, 5, 3), }, /* for Exynos5800 */
>  	{ 1300000, E5420_KFC_DIV(3, 5, 2), },
>  	{ 1200000, E5420_KFC_DIV(3, 5, 2), },
>  	{ 1100000, E5420_KFC_DIV(3, 5, 2), },
> @@ -1357,9 +1381,15 @@ static void __init exynos5x_clk_init(struct
> device_node *np, ARRAY_SIZE(exynos5800_gate_clks));
>  	}
>  
> -	exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
> -		mout_cpu_p[0], mout_cpu_p[1], 0x200,
> -		exynos5420_eglclk_d,
> ARRAY_SIZE(exynos5420_eglclk_d), 0);
> +	if (soc == EXYNOS5420) {
> +		exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
> +			mout_cpu_p[0], mout_cpu_p[1], 0x200,
> +			exynos5420_eglclk_d,
> ARRAY_SIZE(exynos5420_eglclk_d), 0);
> +	} else {
> +		exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
> +			mout_cpu_p[0], mout_cpu_p[1], 0x200,
> +			exynos5800_eglclk_d,
> ARRAY_SIZE(exynos5800_eglclk_d), 0);
> +	}
>  	exynos_register_cpu_clock(ctx, CLK_KFC_CLK, "kfcclk",
>  		mout_kfc_p[0], mout_kfc_p[1], 0x28200,
>  		exynos5420_kfcclk_d,
> ARRAY_SIZE(exynos5420_kfcclk_d), 0);

Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>

-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/8] cpufreq: arm_big_little: add cluster regulator support
  2015-04-21 13:17 ` [PATCH 1/8] cpufreq: arm_big_little: add cluster regulator support Bartlomiej Zolnierkiewicz
  2015-04-22  8:07   ` Lukasz Majewski
@ 2015-04-27  5:15   ` Viresh Kumar
  2015-06-11 22:17   ` Heiko Stübner
  2 siblings, 0 replies; 18+ messages in thread
From: Viresh Kumar @ 2015-04-27  5:15 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Tomasz Figa, Lukasz Majewski, Heiko Stuebner,
	Chanwoo Choi, Kevin Hilman, Javier Martinez Canillas,
	linux-samsung-soc, linux-pm, linux-arm-kernel,
	Linux Kernel Mailing List, Doug Anderson, Andreas Faerber,
	Sachin Kamat

On 21 April 2015 at 18:47, Bartlomiej Zolnierkiewicz
<b.zolnierkie@samsung.com> wrote:
> Add cluster regulator support as a preparation to adding
> generic arm_big_little_dt cpufreq_dt driver support for
> ODROID-XU3 board.  This allows arm_big_little[_dt] driver

This is irrelevant here, its not about XU3 but any board that
wants to use it..

> to set not only the frequency but also the voltage (which
> is obtained from operating point's voltage value) for CPU
> clusters.
>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Cc: Doug Anderson <dianders@chromium.org>
> Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> Cc: Andreas Faerber <afaerber@suse.de>
> Cc: Sachin Kamat <sachin.kamat@linaro.org>
> Cc: Thomas Abraham <thomas.ab@samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> ---
>  .../bindings/cpufreq/arm_big_little_dt.txt         |    4 +
>  drivers/cpufreq/arm_big_little.c                   |  153 +++++++++++++++++---
>  2 files changed, 139 insertions(+), 18 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt b/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt
> index 0715695..8ca4a12 100644
> --- a/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt
> +++ b/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt
> @@ -18,6 +18,10 @@ Required properties:
>  Optional properties:
>  - clock-latency: Specify the possible maximum transition latency for clock,
>    in unit of nanoseconds.
> +- cpu-cluster.0-supply: Provides the regulator node supplying voltage to CPU
> +  cluster 0.
> +- cpu-cluster.1-supply: Provides the regulator node supplying voltage to CPU
> +  cluster 1.

I don't think you need these..

http://permalink.gmane.org/gmane.linux.power-management.general/58548

>  Examples:
>
> diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
> index e1a6ba6..edb461b 100644
> --- a/drivers/cpufreq/arm_big_little.c
> +++ b/drivers/cpufreq/arm_big_little.c
> @@ -31,6 +31,7 @@
>  #include <linux/slab.h>
>  #include <linux/topology.h>
>  #include <linux/types.h>
> +#include <linux/regulator/consumer.h>
>  #include <asm/bL_switcher.h>
>
>  #include "arm_big_little.h"
> @@ -54,6 +55,9 @@ static bool bL_switching_enabled;
>
>  static struct cpufreq_arm_bL_ops *arm_bL_ops;
>  static struct clk *clk[MAX_CLUSTERS];
> +static struct regulator *reg[MAX_CLUSTERS];
> +static struct device *cpu_devs[MAX_CLUSTERS];
> +static int transition_latencies[MAX_CLUSTERS];
>  static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1];
>  static atomic_t cluster_usage[MAX_CLUSTERS + 1];
>
> @@ -122,7 +126,76 @@ static unsigned int bL_cpufreq_get_rate(unsigned int cpu)
>         }
>  }
>
> -static unsigned int
> +static int
> +bL_cpufreq_set_rate_cluster(u32 cpu, u32 cluster, u32 new_rate)
> +{
> +       unsigned long volt = 0, volt_old = 0;
> +       long freq_Hz;
> +       u32 old_rate;
> +       int ret;
> +
> +       freq_Hz = new_rate * 1000;
> +       old_rate = clk_get_rate(clk[cluster]) / 1000;
> +
> +       if (!IS_ERR(reg[cluster])) {
> +               struct dev_pm_opp *opp;
> +               unsigned long opp_freq;
> +
> +               rcu_read_lock();
> +               opp = dev_pm_opp_find_freq_ceil(cpu_devs[cluster], &freq_Hz);
> +               if (IS_ERR(opp)) {
> +                       rcu_read_unlock();
> +                       pr_err("%s: cpu %d, cluster: %d, failed to find OPP for %ld\n",
> +                               __func__, cpu, cluster, freq_Hz);
> +                       return PTR_ERR(opp);
> +               }
> +               volt = dev_pm_opp_get_voltage(opp);
> +               opp_freq = dev_pm_opp_get_freq(opp);
> +               rcu_read_unlock();
> +               volt_old = regulator_get_voltage(reg[cluster]);
> +               pr_debug("%s: cpu %d, cluster: %d, Found OPP: %ld kHz, %ld uV\n",
> +                       __func__, cpu, cluster, opp_freq / 1000, volt);
> +       }
> +
> +       pr_debug("%s: cpu %d, cluster: %d, %u MHz, %ld mV --> %u MHz, %ld mV\n",
> +               __func__, cpu, cluster,
> +               old_rate / 1000, (volt_old > 0) ? volt_old / 1000 : -1,
> +               new_rate / 1000, volt ? volt / 1000 : -1);
> +
> +       /* scaling up? scale voltage before frequency */
> +       if (!IS_ERR(reg[cluster]) && new_rate > old_rate) {
> +               ret = regulator_set_voltage_tol(reg[cluster], volt, 0);
> +               if (ret) {
> +                       pr_err("%s: cpu: %d, cluster: %d, failed to scale voltage up: %d\n",
> +                               __func__, cpu, cluster, ret);
> +                       return ret;
> +               }
> +       }
> +
> +       ret = clk_set_rate(clk[cluster], new_rate * 1000);
> +       if (WARN_ON(ret)) {
> +               pr_err("%s: clk_set_rate failed: %d, cluster: %d\n",
> +                       __func__, cluster, ret);
> +               if (!IS_ERR(reg[cluster]) && volt_old > 0)
> +                       regulator_set_voltage_tol(reg[cluster], volt_old, 0);
> +               return ret;
> +       }
> +
> +       /* scaling down? scale voltage after frequency */
> +       if (!IS_ERR(reg[cluster]) && new_rate < old_rate) {
> +               ret = regulator_set_voltage_tol(reg[cluster], volt, 0);
> +               if (ret) {
> +                       pr_err("%s: cpu: %d, cluster: %d, failed to scale voltage down: %d\n",
> +                               __func__, cpu, cluster, ret);
> +                       clk_set_rate(clk[cluster], old_rate * 1000);
> +                       return ret;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static int

If you want to make such fixes, please add them separately.

>  bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate)
>  {
>         u32 new_rate, prev_rate;
> @@ -145,22 +218,17 @@ bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate)
>         pr_debug("%s: cpu: %d, old cluster: %d, new cluster: %d, freq: %d\n",
>                         __func__, cpu, old_cluster, new_cluster, new_rate);
>
> -       ret = clk_set_rate(clk[new_cluster], new_rate * 1000);
> -       if (WARN_ON(ret)) {
> -               pr_err("clk_set_rate failed: %d, new cluster: %d\n", ret,
> -                               new_cluster);
> -               if (bLs) {
> -                       per_cpu(cpu_last_req_freq, cpu) = prev_rate;
> -                       per_cpu(physical_cluster, cpu) = old_cluster;
> -               }
> -
> -               mutex_unlock(&cluster_lock[new_cluster]);
> -
> -               return ret;
> +       ret = bL_cpufreq_set_rate_cluster(cpu, new_cluster, new_rate);
> +       if (ret && bLs) {
> +               per_cpu(cpu_last_req_freq, cpu) = prev_rate;
> +               per_cpu(physical_cluster, cpu) = old_cluster;
>         }
>
>         mutex_unlock(&cluster_lock[new_cluster]);
>
> +       if (ret)
> +               return ret;
> +
>         /* Recalc freq for old cluster when switching clusters */
>         if (old_cluster != new_cluster) {
>                 pr_debug("%s: cpu: %d, old cluster: %d, new cluster: %d\n",
> @@ -174,14 +242,11 @@ bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate)
>                 /* Set freq of old cluster if there are cpus left on it */
>                 new_rate = find_cluster_maxfreq(old_cluster);
>                 new_rate = ACTUAL_FREQ(old_cluster, new_rate);
> -

??

>                 if (new_rate) {
>                         pr_debug("%s: Updating rate of old cluster: %d, to freq: %d\n",
>                                         __func__, old_cluster, new_rate);
>
> -                       if (clk_set_rate(clk[old_cluster], new_rate * 1000))
> -                               pr_err("%s: clk_set_rate failed: %d, old cluster: %d\n",
> -                                               __func__, ret, old_cluster);
> +                       bL_cpufreq_set_rate_cluster(cpu, old_cluster, new_rate);
>                 }
>                 mutex_unlock(&cluster_lock[old_cluster]);
>         }
> @@ -288,6 +353,8 @@ static void _put_cluster_clk_and_freq_table(struct device *cpu_dev)
>                 return;
>
>         clk_put(clk[cluster]);
> +       if (!IS_ERR(reg[cluster]))
> +               regulator_put(reg[cluster]);
>         dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table[cluster]);
>         if (arm_bL_ops->free_opp_table)
>                 arm_bL_ops->free_opp_table(cpu_dev);
> @@ -321,6 +388,7 @@ static void put_cluster_clk_and_freq_table(struct device *cpu_dev)
>
>  static int _get_cluster_clk_and_freq_table(struct device *cpu_dev)
>  {
> +       unsigned long min_uV = ~0, max_uV = 0;
>         u32 cluster = raw_cpu_to_cluster(cpu_dev->id);
>         char name[14] = "cpu-cluster.";
>         int ret;
> @@ -335,6 +403,51 @@ static int _get_cluster_clk_and_freq_table(struct device *cpu_dev)
>                 goto out;
>         }
>
> +       name[12] = cluster + '0';
> +       reg[cluster] = regulator_get_optional(cpu_dev, name);

Just pass NULL instead of name.

> +       if (!IS_ERR(reg[cluster])) {
> +               unsigned long opp_freq = 0;
> +
> +               dev_dbg(cpu_dev, "%s: reg: %p, cluster: %d\n",
> +                       __func__, reg[cluster], cluster);
> +               cpu_devs[cluster] = cpu_dev;

If you want to save cpu_dev for further use, save it in bL_cpufreq_init()
not here.

> +               /*
> +                * Disable any OPPs where the connected regulator isn't able to
> +                * provide the specified voltage and record minimum and maximum
> +                * voltage levels.
> +                */
> +               while (1) {
> +                       struct dev_pm_opp *opp;
> +                       unsigned long opp_uV;
> +
> +                       rcu_read_lock();
> +                       opp = dev_pm_opp_find_freq_ceil(cpu_dev, &opp_freq);
> +                       if (IS_ERR(opp)) {
> +                               rcu_read_unlock();
> +                               break;
> +                       }
> +                       opp_uV = dev_pm_opp_get_voltage(opp);
> +                       rcu_read_unlock();
> +
> +                       if (regulator_is_supported_voltage(reg[cluster], opp_uV,
> +                                                          opp_uV)) {
> +                               if (opp_uV < min_uV)
> +                                       min_uV = opp_uV;
> +                               if (opp_uV > max_uV)
> +                                       max_uV = opp_uV;
> +                       } else {
> +                               dev_pm_opp_disable(cpu_dev, opp_freq);
> +                       }
> +
> +                       opp_freq++;
> +               }
> +
> +               ret = regulator_set_voltage_time(reg[cluster], min_uV, max_uV);
> +               if (ret > 0)
> +                       transition_latencies[cluster] = ret * 1000;
> +       }
> +
>         ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table[cluster]);
>         if (ret) {
>                 dev_err(cpu_dev, "%s: failed to init cpufreq table, cpu: %d, err: %d\n",
> @@ -342,7 +455,6 @@ static int _get_cluster_clk_and_freq_table(struct device *cpu_dev)
>                 goto free_opp_table;
>         }
>
> -       name[12] = cluster + '0';
>         clk[cluster] = clk_get(cpu_dev, name);
>         if (!IS_ERR(clk[cluster])) {
>                 dev_dbg(cpu_dev, "%s: clk: %p & freq table: %p, cluster: %d\n",
> @@ -469,6 +581,11 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy)
>         else
>                 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
>
> +       if (cur_cluster < MAX_CLUSTERS &&
> +           policy->cpuinfo.transition_latency != CPUFREQ_ETERNAL)
> +               policy->cpuinfo.transition_latency
> +                       += transition_latencies[cur_cluster];

Instead of the crap here + a global array for transition latencies,
pass 'policy' to _get_cluster_clk_and_freq_table() and add it
directly to policy.

> +
>         if (is_bL_switching_enabled())
>                 per_cpu(cpu_last_req_freq, policy->cpu) = clk_get_cpu_rate(policy->cpu);
>
> --
> 1.7.9.5
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/8] cpufreq: arm_big_little: add cluster regulator support
  2015-04-21 13:17 ` [PATCH 1/8] cpufreq: arm_big_little: add cluster regulator support Bartlomiej Zolnierkiewicz
  2015-04-22  8:07   ` Lukasz Majewski
  2015-04-27  5:15   ` Viresh Kumar
@ 2015-06-11 22:17   ` Heiko Stübner
  2 siblings, 0 replies; 18+ messages in thread
From: Heiko Stübner @ 2015-06-11 22:17 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Thomas Abraham, Sylwester Nawrocki, Mike Turquette, Kukjin Kim,
	Kukjin Kim, Viresh Kumar, Tomasz Figa, Lukasz Majewski,
	Chanwoo Choi, Kevin Hilman, Javier Martinez Canillas,
	linux-samsung-soc, linux-pm, linux-arm-kernel, linux-kernel,
	Doug Anderson, Andreas Faerber, Sachin Kamat

Hi,

Am Dienstag, 21. April 2015, 15:17:51 schrieb Bartlomiej Zolnierkiewicz:
> Add cluster regulator support as a preparation to adding
> generic arm_big_little_dt cpufreq_dt driver support for
> ODROID-XU3 board.  This allows arm_big_little[_dt] driver
> to set not only the frequency but also the voltage (which
> is obtained from operating point's voltage value) for CPU
> clusters.
> 
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Cc: Doug Anderson <dianders@chromium.org>
> Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> Cc: Andreas Faerber <afaerber@suse.de>
> Cc: Sachin Kamat <sachin.kamat@linaro.org>
> Cc: Thomas Abraham <thomas.ab@samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>

I gave this a spin on the rk3368 arm64 soc from Rockchip, mainly to check if
my armclk handling was correct.

Your patch here only supports individual supplies per cluster but my
current board shares the supplies over both cpu clusters, so I've cooked
up a patch to also try to support shared supplies
[0].

Nevertheless,
Tested-by: Heiko Stuebner <heiko@sntech.de>

Do you plan to continue working on this?


Thanks
Heiko


[0] ---------------- 8< -----------------------------
From: Heiko Stuebner <heiko@sntech.de>
Subject: [PATCH] cpufreq: arm_big_little: add support for shared cluster regulators

In some socs or board designs the supplying regulator is shared between
more than one cluster but the current regulator support for big_little
sets the target voltage without any tolerance.

So when cluster0 requests 0.9V and cluster1 1.3V no suitable frequency
span is available that fits both. To accomodate this, look for shared
regulators and calculate the maximum voltage necessary. If the regulator
of the remote cluster has a lower voltage, its maximum also gets increased.

If cluster supplies are not shared, the behaviour is the same as before
with one specific voltage being set instead of a voltage-range.

When adapting shared voltages the remote clusters need to be locked too,
because cpufreq can very well try to change more than one cluster at the
same time. While the used mutex_trylock prevents deadlocks reliably,
it might also prevent some (or a lot) frequency changes from succeeding:

	lock cluster0
				lock cluster1
	trylock cluster1
				trylock cluster0
			both fail

I'm probably simply overlooking some better way currently.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/cpufreq/arm_big_little.c | 102 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 91 insertions(+), 11 deletions(-)

diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
index e04ca0c..c65b111 100644
--- a/drivers/cpufreq/arm_big_little.c
+++ b/drivers/cpufreq/arm_big_little.c
@@ -130,12 +130,78 @@ static unsigned int bL_cpufreq_get_rate(unsigned int cpu)
 }
 
 static int
+bL_adapt_shared_regulators(u32 cluster, unsigned long *volt_max)
+{
+	unsigned long other_volt;
+	int ret, i;
+
+	for (i = 0; i < MAX_CLUSTERS; i++) {
+		if (i == cluster || IS_ERR_OR_NULL(reg[i]))
+			continue;
+
+		if (regulator_is_match(reg[cluster], reg[i])) {
+			other_volt = regulator_get_voltage(reg[i]);
+			if (other_volt > *volt_max) {
+				*volt_max = other_volt;
+			} else {
+				pr_debug("%s: adapting shared regulator in cluster %d to %lu-%lu mV\n",
+					 __func__, i, other_volt / 1000, *volt_max / 1000);
+				ret = regulator_set_voltage(reg[i], other_volt, *volt_max);
+				if (ret) {
+					pr_err("%s: shared-supply for cluster: %d, failed to scale voltage up: %d\n",
+					       __func__, cluster, ret);
+					return ret;
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int
+bL_lock_shared_regulators(u32 cluster)
+{
+	int ret, i;
+
+	for (i = 0; i < MAX_CLUSTERS; i++) {
+		if (i == cluster || IS_ERR_OR_NULL(reg[i]))
+			continue;
+
+		if (regulator_is_match(reg[cluster], reg[i])) {
+			ret = mutex_trylock(&cluster_lock[i]);
+			if (!ret) {
+				for (i--; i >= 0; i--)
+					mutex_unlock(&cluster_lock[i]);
+				return -EBUSY;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void
+bL_unlock_shared_regulators(u32 cluster)
+{
+	int i;
+
+	for (i = 0; i < MAX_CLUSTERS; i++) {
+		if (i == cluster || IS_ERR_OR_NULL(reg[i]))
+			continue;
+
+		if (regulator_is_match(reg[cluster], reg[i]))
+			mutex_unlock(&cluster_lock[i]);
+	}
+}
+
+static int
 bL_cpufreq_set_rate_cluster(u32 cpu, u32 cluster, u32 new_rate)
 {
-	unsigned long volt = 0, volt_old = 0;
+	unsigned long volt = 0, volt_max = 0, volt_old = 0;
 	long freq_Hz;
 	u32 old_rate;
-	int ret;
+	int ret = 0;
 
 	freq_Hz = new_rate * 1000;
 	old_rate = clk_get_rate(clk[cluster]) / 1000;
@@ -144,13 +210,18 @@ bL_cpufreq_set_rate_cluster(u32 cpu, u32 cluster, u32 new_rate)
 		struct dev_pm_opp *opp;
 		unsigned long opp_freq;
 
+		ret = bL_lock_shared_regulators(cluster);
+		if(ret)
+			return 0;
+
 		rcu_read_lock();
 		opp = dev_pm_opp_find_freq_ceil(cpu_devs[cluster], &freq_Hz);
 		if (IS_ERR(opp)) {
 			rcu_read_unlock();
 			pr_err("%s: cpu %d, cluster: %d, failed to find OPP for %ld\n",
 				__func__, cpu, cluster, freq_Hz);
-			return PTR_ERR(opp);
+			ret = PTR_ERR(opp);
+			goto unlock;
 		}
 		volt = dev_pm_opp_get_voltage(opp);
 		opp_freq = dev_pm_opp_get_freq(opp);
@@ -158,20 +229,25 @@ bL_cpufreq_set_rate_cluster(u32 cpu, u32 cluster, u32 new_rate)
 		volt_old = regulator_get_voltage(reg[cluster]);
 		pr_debug("%s: cpu %d, cluster: %d, Found OPP: %ld kHz, %ld uV\n",
 			__func__, cpu, cluster, opp_freq / 1000, volt);
+
+		volt_max = volt;
+		ret = bL_adapt_shared_regulators(cluster, &volt_max);
+		if (ret)
+			goto unlock;
 	}
 
-	pr_debug("%s: cpu %d, cluster: %d, %u MHz, %ld mV --> %u MHz, %ld mV\n",
+	pr_debug("%s: cpu %d, cluster: %d, %u MHz, %ld mV --> %u MHz, %ld-%ld mV\n",
 		__func__, cpu, cluster,
 		old_rate / 1000, (volt_old > 0) ? volt_old / 1000 : -1,
-		new_rate / 1000, volt ? volt / 1000 : -1);
+		new_rate / 1000, volt ? volt / 1000 : -1, volt_max ? volt_max / 1000 : -1);
 
 	/* scaling up? scale voltage before frequency */
 	if (!IS_ERR(reg[cluster]) && new_rate > old_rate) {
-		ret = regulator_set_voltage_tol(reg[cluster], volt, 0);
+		ret = regulator_set_voltage(reg[cluster], volt, volt_max);
 		if (ret) {
 			pr_err("%s: cpu: %d, cluster: %d, failed to scale voltage up: %d\n",
 				__func__, cpu, cluster, ret);
-			return ret;
+			goto unlock;
 		}
 	}
 
@@ -181,21 +257,25 @@ bL_cpufreq_set_rate_cluster(u32 cpu, u32 cluster, u32 new_rate)
 			__func__, cluster, ret);
 		if (!IS_ERR(reg[cluster]) && volt_old > 0)
 			regulator_set_voltage_tol(reg[cluster], volt_old, 0);
-		return ret;
+		goto unlock;
 	}
 
 	/* scaling down? scale voltage after frequency */
 	if (!IS_ERR(reg[cluster]) && new_rate < old_rate) {
-		ret = regulator_set_voltage_tol(reg[cluster], volt, 0);
+		ret = regulator_set_voltage(reg[cluster], volt, volt_max);
 		if (ret) {
 			pr_err("%s: cpu: %d, cluster: %d, failed to scale voltage down: %d\n",
 				__func__, cpu, cluster, ret);
 			clk_set_rate(clk[cluster], old_rate * 1000);
-			return ret;
+			goto unlock;
 		}
 	}
 
-	return 0;
+unlock:
+	if (!IS_ERR(reg[cluster]))
+		bL_unlock_shared_regulators(cluster);
+
+	return ret;
 }
 
 static int
-- 
2.1.4

---------------- 8< ----------------
From: Heiko Stuebner <heiko@sntech.de>
Subject: [PATCH] regulator: add a regulator_is_match function

Another stolen concept from the common clock framework. At some points it
can be useful to check if two regulator structs are actually pointing to
the same regulator_dev.

The usecase in question was to check if the supplying regulators of two
cpu clusters are actually the same and the regulator is thus shared
between these cpu clusters.

Therefore add regulator_is_match() that compares the rdev pointers
of two regulators and emits a bool stating if they match.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/regulator/core.c           | 23 +++++++++++++++++++++++
 include/linux/regulator/consumer.h |  7 +++++++
 2 files changed, 30 insertions(+)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 443eaab..6bb7e70 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1591,6 +1591,29 @@ void regulator_put(struct regulator *regulator)
 EXPORT_SYMBOL_GPL(regulator_put);
 
 /**
+ * regulator_is_match - check if two regulator's point to the same rdev
+ * @p: regulator compared against q
+ * @q: regulator compared against p
+ *
+ * Returns true if the two struct regulator pointers both point to the same rdev
+ * Returns false otherwise. Note that two NULL clks are treated as matching.
+ */
+bool regulator_is_match(const struct regulator *p, const struct regulator *q)
+{
+	/* trivial case: identical struct regulator's or both NULL */
+	if (p == q)
+		return true;
+
+	/* true if clk->core pointers match. Avoid derefing garbage */
+	if (!IS_ERR_OR_NULL(p) && !IS_ERR_OR_NULL(q))
+		if (p->rdev == q->rdev)
+			return true;
+
+	return false;
+}
+EXPORT_SYMBOL_GPL(regulator_is_match);
+
+/**
  * regulator_register_supply_alias - Provide device alias for supply lookup
  *
  * @dev: device that will be given as the regulator "consumer"
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index f8a689e..38ffaa0 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -172,6 +172,7 @@ struct regulator *__must_check devm_regulator_get_optional(struct device *dev,
 							   const char *id);
 void regulator_put(struct regulator *regulator);
 void devm_regulator_put(struct regulator *regulator);
+bool regulator_is_match(const struct regulator *p, const struct regulator *q);
 
 int regulator_register_supply_alias(struct device *dev, const char *id,
 				    struct device *alias_dev,
@@ -316,6 +317,12 @@ static inline void devm_regulator_put(struct regulator *regulator)
 {
 }
 
+static inline bool regulator_is_match(const struct regulator *p,
+				      const struct regulator *q)
+{
+	return true;
+}
+
 static inline int regulator_register_supply_alias(struct device *dev,
 						  const char *id,
 						  struct device *alias_dev,
-- 
2.1.4




^ permalink raw reply related	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2015-06-11 22:17 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-21 13:17 [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms Bartlomiej Zolnierkiewicz
2015-04-21 13:17 ` [PATCH 1/8] cpufreq: arm_big_little: add cluster regulator support Bartlomiej Zolnierkiewicz
2015-04-22  8:07   ` Lukasz Majewski
2015-04-27  5:15   ` Viresh Kumar
2015-06-11 22:17   ` Heiko Stübner
2015-04-21 13:17 ` [PATCH 2/8] ARM: dts: add cluster regulator supply properties for exynos5422-odroidxu3 Bartlomiej Zolnierkiewicz
2015-04-22  8:07   ` Lukasz Majewski
2015-04-21 13:17 ` [PATCH 3/8] clk: samsung: exynos5420: add cpu clock configuration data and instantiate cpu clock Bartlomiej Zolnierkiewicz
2015-04-22  8:10   ` Lukasz Majewski
2015-04-21 13:17 ` [PATCH 4/8] ARM: dts: Exynos5420: add CPU OPP and regulator supply property Bartlomiej Zolnierkiewicz
2015-04-22  8:12   ` Lukasz Majewski
2015-04-21 13:17 ` [PATCH 5/8] ARM: Exynos: use generic cpufreq driver for Exynos5420 Bartlomiej Zolnierkiewicz
2015-04-22  8:13   ` Lukasz Majewski
2015-04-21 13:17 ` [PATCH 6/8] clk: samsung: exynos5800: fix cpu clock configuration data Bartlomiej Zolnierkiewicz
2015-04-22  8:14   ` Lukasz Majewski
2015-04-21 13:17 ` [PATCH 7/8] ARM: dts: Exynos5800: fix CPU OPP Bartlomiej Zolnierkiewicz
2015-04-21 13:17 ` [PATCH 8/8] ARM: Exynos: use generic cpufreq driver for Exynos5800 Bartlomiej Zolnierkiewicz
2015-04-21 15:34 ` [PATCH 0/8] cpufreq: add generic cpufreq driver support for Exynos5250/5800 platforms Bartlomiej Zolnierkiewicz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).