Subject: [PATCH v3 0/10] cpufreq: add generic cpufreq driver support for Exynos542x/5800 platforms

Hi,

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

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

Please note that this is not a final version of the patchset.
I just wanted to push out current work-in-progress patches that
integrate changes from Anand, Ben and me.

TODO:
- porting the Exynos542x/5800 support over cpufreq-dt

Depends on:
- next-20151124 branch of linux-next kernel tree

Changes since v2:
- ported over next-20151124 branch
- integrated missing CLK_RECALC_NEW_RATES flags fix to patch #3
(from Anand Moon)
- added regulator supply properties for ODROID-XU3 Lite and
ODROID-XU4 in patch #2
- ported CPU OPPs to operating-points-v2 (from Ben Gamari)
- added "ARM: dts: Exynos5422: fix OPP tables" patch (from Ben
Gamari)
- added "cpufreq: arm-big-little: accept operating-points-v2
nodes" patch (from Ben Gamari)
- renamed OPP nodes as opp@<opp-hz>

Changes since v1:
- added CPU cluster regulator supply properties to
exynos5420-arndale-octa.dts, exynos5420-peach-pit.dts,
exynos5420-smdk5420.dts and exynos5800-peach-pi.dts

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: Exynos5420/5800: add cluster regulator supply properties
clk: samsung: exynos5800: fix cpu clock configuration data
ARM: dts: Exynos5800: fix CPU OPP

Ben Gamari (2):
ARM: dts: Exynos5422: fix OPP tables
cpufreq: arm-big-little: accept operating-points-v2 nodes

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-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/exynos5420.dtsi | 122 ++++++++++++++
arch/arm/boot/dts/exynos5422-cpus.dtsi | 10 ++
arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts | 8 +
arch/arm/boot/dts/exynos5422-odroidxu3.dts | 8 +
arch/arm/boot/dts/exynos5422-odroidxu4.dts | 8 +
arch/arm/boot/dts/exynos5800-peach-pi.dts | 8 +
arch/arm/boot/dts/exynos5800.dtsi | 165 +++++++++++++++++++
arch/arm/mach-exynos/exynos.c | 8 +
drivers/clk/samsung/clk-exynos5420.c | 88 ++++++++++-
drivers/cpufreq/arm_big_little.c | 175 +++++++++++++++++----
drivers/cpufreq/arm_big_little_dt.c | 12 +-
include/dt-bindings/clock/exynos5420.h | 2 +
16 files changed, 608 insertions(+), 34 deletions(-)

--
1.9.1


Subject: [PATCH v3 01/10] cpufreq: arm_big_little: add cluster regulator support

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 <[email protected]>
Cc: Doug Anderson <[email protected]>
Cc: Javier Martinez Canillas <[email protected]>
Cc: Andreas Faerber <[email protected]>
Cc: Sachin Kamat <[email protected]>
Cc: Thomas Abraham <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
.../bindings/cpufreq/arm_big_little_dt.txt | 4 +
drivers/cpufreq/arm_big_little.c | 175 +++++++++++++++++----
2 files changed, 151 insertions(+), 28 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 c5d256c..8b05137 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 "arm_big_little.h"

@@ -57,6 +58,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];

@@ -125,30 +129,53 @@ static unsigned int bL_cpufreq_get_rate(unsigned int cpu)
}
}

-static unsigned int
-bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate)
+static int
+bL_cpufreq_set_rate_cluster(u32 cpu, u32 cluster, u32 new_rate)
{
- u32 new_rate, prev_rate;
+ unsigned long volt = 0, volt_old = 0;
+ long freq_Hz;
+ u32 old_rate;
int ret;
- bool bLs = is_bL_switching_enabled();

- mutex_lock(&cluster_lock[new_cluster]);
+ freq_Hz = new_rate * 1000;
+ old_rate = clk_get_rate(clk[cluster]) / 1000;

- if (bLs) {
- prev_rate = per_cpu(cpu_last_req_freq, cpu);
- per_cpu(cpu_last_req_freq, cpu) = rate;
- per_cpu(physical_cluster, cpu) = new_cluster;
+ if (!IS_ERR(reg[cluster])) {
+ struct dev_pm_opp *opp;
+ unsigned long opp_freq;

- new_rate = find_cluster_maxfreq(new_cluster);
- new_rate = ACTUAL_FREQ(new_cluster, new_rate);
- } else {
- new_rate = rate;
+ 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, old cluster: %d, new cluster: %d, freq: %d\n",
- __func__, cpu, old_cluster, new_cluster, new_rate);
+ 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);

- ret = clk_set_rate(clk[new_cluster], new_rate * 1000);
+ /* 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 (!ret) {
/*
* FIXME: clk_set_rate hasn't returned an error here however it
@@ -158,25 +185,66 @@ bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate)
* problem we will read back the clock rate and check it is
* correct. This needs to be removed once clk core is fixed.
*/
- if (clk_get_rate(clk[new_cluster]) != new_rate * 1000)
+ if (clk_get_rate(clk[cluster]) != new_rate * 1000)
ret = -EIO;
}

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;
+ 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;
}
+ }

- mutex_unlock(&cluster_lock[new_cluster]);
+ return 0;
+}

- return ret;
+static int
+bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate)
+{
+ u32 new_rate, prev_rate;
+ int ret;
+ bool bLs = is_bL_switching_enabled();
+
+ mutex_lock(&cluster_lock[new_cluster]);
+
+ if (bLs) {
+ prev_rate = per_cpu(cpu_last_req_freq, cpu);
+ per_cpu(cpu_last_req_freq, cpu) = rate;
+ per_cpu(physical_cluster, cpu) = new_cluster;
+
+ new_rate = find_cluster_maxfreq(new_cluster);
+ new_rate = ACTUAL_FREQ(new_cluster, new_rate);
+ } else {
+ new_rate = rate;
+ }
+
+ pr_debug("%s: cpu: %d, old cluster: %d, new cluster: %d, freq: %d\n",
+ __func__, cpu, old_cluster, new_cluster, new_rate);
+
+ 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",
@@ -190,14 +258,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]);
}
@@ -304,6 +369,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);
@@ -337,7 +404,9 @@ 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;

if (freq_table[cluster])
@@ -350,6 +419,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",
@@ -483,6 +597,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.9.1

Subject: [PATCH v3 02/10] 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 <[email protected]>
Cc: Doug Anderson <[email protected]>
Cc: Javier Martinez Canillas <[email protected]>
Cc: Andreas Faerber <[email protected]>
Cc: Sachin Kamat <[email protected]>
Cc: Thomas Abraham <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
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-lite.dts | 8 ++++++++
arch/arm/boot/dts/exynos5422-odroidxu3.dts | 8 ++++++++
arch/arm/boot/dts/exynos5422-odroidxu4.dts | 8 ++++++++
arch/arm/boot/dts/exynos5800-peach-pi.dts | 8 ++++++++
7 files changed, 56 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
index 4ecef69..24b8a35 100644
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -52,6 +52,14 @@
};
};

+&cpu0 {
+ cpu-cluster.0-supply = <&buck2_reg>;
+};
+
+&cpu4 {
+ cpu-cluster.1-supply = <&buck6_reg>;
+};
+
&usbdrd_dwc3_1 {
dr_mode = "host";
};
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 35cfb07..2b74230 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -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>;
diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
index ac35aef..9e2dc5f 100644
--- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
+++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
@@ -423,3 +423,11 @@
&usbdrd_phy1 {
vbus-supply = <&usb301_vbus_reg>;
};
+
+&cpu0 {
+ cpu-cluster.0-supply = <&buck2_reg>;
+};
+
+&cpu4 {
+ cpu-cluster.1-supply = <&buck6_reg>;
+};
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts b/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
index 2ae1cf4..6f1de7c 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
@@ -54,6 +54,14 @@
};
};

+&cpu0 {
+ cpu-cluster.1-supply = <&buck6_reg>;
+};
+
+&cpu4 {
+ cpu-cluster.0-supply = <&buck2_reg>;
+};
+
&pwm {
/*
* PWM 0 -- fan
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
index 432406d..6b64122 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
@@ -53,6 +53,14 @@
};
};

+&cpu0 {
+ cpu-cluster.1-supply = <&buck6_reg>;
+};
+
+&cpu4 {
+ cpu-cluster.0-supply = <&buck2_reg>;
+};
+
&i2c_0 {
status = "okay";

diff --git a/arch/arm/boot/dts/exynos5422-odroidxu4.dts b/arch/arm/boot/dts/exynos5422-odroidxu4.dts
index 2faf886..516a40f 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu4.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu4.dts
@@ -32,6 +32,14 @@
};
};

+&cpu0 {
+ cpu-cluster.1-supply = <&buck6_reg>;
+};
+
+&cpu4 {
+ cpu-cluster.0-supply = <&buck2_reg>;
+};
+
&pwm {
/*
* PWM 0 -- fan
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 7b018e4..34aaaacd 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -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>;
--
1.9.1

Subject: [PATCH v3 03/10] clk: samsung: exynos5420: add cpu clock configuration data and instantiate cpu clock

From: Thomas Abraham <[email protected]>

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 <[email protected]>
Cc: Mike Turquette <[email protected]>
Cc: Javier Martinez Canillas <[email protected]>
Signed-off-by: Thomas Abraham <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
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 389af3c..2a92546 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -18,6 +18,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 | CLK_RECALC_NEW_RATES, 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 | CLK_RECALC_NEW_RATES, 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.9.1

Subject: [PATCH v3 04/10] ARM: dts: Exynos5420: add CPU OPP and regulator supply property

From: Thomas Abraham <[email protected]>

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

Changes by Ben Gamari:
- Port to operating-points-v2

Cc: Kukjin Kim <[email protected]>
Cc: Doug Anderson <[email protected]>
Cc: Javier Martinez Canillas <[email protected]>
Cc: Andreas Faerber <[email protected]>
Cc: Sachin Kamat <[email protected]>
Cc: Thomas Abraham <[email protected]>
Signed-off-by: Ben Gamari <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
arch/arm/boot/dts/exynos5420.dtsi | 122 ++++++++++++++++++++++++++++++++++++++
1 file changed, 122 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index 48a0a55..f8f70a5 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -50,6 +50,116 @@
usbdrdphy1 = &usbdrd_phy1;
};

+ cpu0_opp_table: opp_table0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+ opp00@1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <1250000>;
+ clock-latency-ns = <140000>;
+ };
+ opp01@1700000000 {
+ opp-hz = /bits/ 64 <1700000000>;
+ opp-microvolt = <1212500>;
+ clock-latency-ns = <140000>;
+ };
+ opp02@1600000000 {
+ opp-hz = /bits/ 64 <1600000000>;
+ opp-microvolt = <1175000>;
+ clock-latency-ns = <140000>;
+ };
+ opp03@1500000000 {
+ opp-hz = /bits/ 64 <1500000000>;
+ opp-microvolt = <1137500>;
+ clock-latency-ns = <140000>;
+ };
+ opp04@1400000000 {
+ opp-hz = /bits/ 64 <1400000000>;
+ opp-microvolt = <1112500>;
+ clock-latency-ns = <140000>;
+ };
+ opp05@1300000000 {
+ opp-hz = /bits/ 64 <1300000000>;
+ opp-microvolt = <1062500>;
+ clock-latency-ns = <140000>;
+ };
+ opp06@1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <1037500>;
+ clock-latency-ns = <140000>;
+ };
+ opp07@1100000000 {
+ opp-hz = /bits/ 64 <1100000000>;
+ opp-microvolt = <1012500>;
+ clock-latency-ns = <140000>;
+ };
+ opp08@1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = < 987500>;
+ clock-latency-ns = <140000>;
+ };
+ opp09@900000000 {
+ opp-hz = /bits/ 64 <900000000>;
+ opp-microvolt = < 962500>;
+ clock-latency-ns = <140000>;
+ };
+ opp10@800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = < 937500>;
+ clock-latency-ns = <140000>;
+ };
+ opp11@700000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ opp-microvolt = < 912500>;
+ clock-latency-ns = <140000>;
+ };
+ };
+
+ cpu1_opp_table: opp_table1 {
+ compatible = "operating-points-v2";
+ opp-shared;
+ opp00@1300000000 {
+ opp-hz = /bits/ 64 <1300000000>;
+ opp-microvolt = <1275000>;
+ clock-latency-ns = <140000>;
+ };
+ opp01@1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <1212500>;
+ clock-latency-ns = <140000>;
+ };
+ opp02@1100000000 {
+ opp-hz = /bits/ 64 <1100000000>;
+ opp-microvolt = <1162500>;
+ clock-latency-ns = <140000>;
+ };
+ opp03@1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <1112500>;
+ clock-latency-ns = <140000>;
+ };
+ opp04@900000000 {
+ opp-hz = /bits/ 64 <900000000>;
+ opp-microvolt = <1062500>;
+ clock-latency-ns = <140000>;
+ };
+ opp05@800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <1025000>;
+ clock-latency-ns = <140000>;
+ };
+ opp06@700000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ opp-microvolt = <975000>;
+ clock-latency-ns = <140000>;
+ };
+ opp07@600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <937500>;
+ clock-latency-ns = <140000>;
+ };
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -58,8 +168,11 @@
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>;
+ operating-points-v2 = <&cpu0_opp_table>;
};

cpu1: cpu@1 {
@@ -68,6 +181,7 @@
reg = <0x1>;
clock-frequency = <1800000000>;
cci-control-port = <&cci_control1>;
+ operating-points-v2 = <&cpu0_opp_table>;
};

cpu2: cpu@2 {
@@ -76,6 +190,7 @@
reg = <0x2>;
clock-frequency = <1800000000>;
cci-control-port = <&cci_control1>;
+ operating-points-v2 = <&cpu0_opp_table>;
};

cpu3: cpu@3 {
@@ -84,14 +199,18 @@
reg = <0x3>;
clock-frequency = <1800000000>;
cci-control-port = <&cci_control1>;
+ operating-points-v2 = <&cpu0_opp_table>;
};

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>;
+ operating-points-v2 = <&cpu1_opp_table>;
};

cpu5: cpu@101 {
@@ -100,6 +219,7 @@
reg = <0x101>;
clock-frequency = <1000000000>;
cci-control-port = <&cci_control0>;
+ operating-points-v2 = <&cpu1_opp_table>;
};

cpu6: cpu@102 {
@@ -108,6 +228,7 @@
reg = <0x102>;
clock-frequency = <1000000000>;
cci-control-port = <&cci_control0>;
+ operating-points-v2 = <&cpu1_opp_table>;
};

cpu7: cpu@103 {
@@ -116,6 +237,7 @@
reg = <0x103>;
clock-frequency = <1000000000>;
cci-control-port = <&cci_control0>;
+ operating-points-v2 = <&cpu1_opp_table>;
};
};

--
1.9.1

Subject: [PATCH v3 05/10] ARM: Exynos: use generic cpufreq driver for Exynos5420

From: Thomas Abraham <[email protected]>

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 <[email protected]>
Cc: Kukjin Kim <[email protected]>
Cc: Javier Martinez Canillas <[email protected]>
Signed-off-by: Thomas Abraham <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
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 1c47aee..6d97145 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -230,6 +230,13 @@ static const struct of_device_id exynos_cpufreq_matches[] = {
{ .compatible = "samsung,exynos4212", .data = "cpufreq-dt" },
{ .compatible = "samsung,exynos4412", .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.9.1

Subject: [PATCH v3 06/10] clk: samsung: exynos5800: fix cpu clock configuration data

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 <[email protected]>
Cc: Mike Turquette <[email protected]>
Cc: Javier Martinez Canillas <[email protected]>
Cc: Thomas Abraham <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
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 2a92546..837329d 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.9.1

Subject: [PATCH v3 07/10] ARM: dts: Exynos5800: fix CPU OPP

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.

Changes by Ben Gamari:
- Port to operating-points-v2

Cc: Kukjin Kim <[email protected]>
Cc: Doug Anderson <[email protected]>
Cc: Javier Martinez Canillas <[email protected]>
Cc: Andreas Faerber <[email protected]>
Cc: Sachin Kamat <[email protected]>
Cc: Thomas Abraham <[email protected]>
Signed-off-by: Ben Gamari <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
arch/arm/boot/dts/exynos5800.dtsi | 165 ++++++++++++++++++++++++++++++++++++++
1 file changed, 165 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5800.dtsi b/arch/arm/boot/dts/exynos5800.dtsi
index c0bb356..e417218 100644
--- a/arch/arm/boot/dts/exynos5800.dtsi
+++ b/arch/arm/boot/dts/exynos5800.dtsi
@@ -17,8 +17,173 @@

/ {
compatible = "samsung,exynos5800", "samsung,exynos5";
+
+ cpu0_opp_table: opp_table0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+ opp00@1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <1250000>;
+ clock-latency-ns = <140000>;
+ };
+ opp01@1700000000 {
+ opp-hz = /bits/ 64 <1700000000>;
+ opp-microvolt = <1250000>;
+ clock-latency-ns = <140000>;
+ };
+ opp02@1600000000 {
+ opp-hz = /bits/ 64 <1600000000>;
+ opp-microvolt = <1250000>;
+ clock-latency-ns = <140000>;
+ };
+ opp03@1500000000 {
+ opp-hz = /bits/ 64 <1500000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <140000>;
+ };
+ opp04@1400000000 {
+ opp-hz = /bits/ 64 <1400000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <140000>;
+ };
+ opp05@1300000000 {
+ opp-hz = /bits/ 64 <1300000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <140000>;
+ };
+ opp06@1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <140000>;
+ };
+ opp07@1100000000 {
+ opp-hz = /bits/ 64 <1100000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <140000>;
+ };
+ opp08@1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <140000>;
+ };
+ opp09@900000000 {
+ opp-hz = /bits/ 64 <900000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <140000>;
+ };
+ opp10@800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <140000>;
+ };
+ opp11@700000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <140000>;
+ };
+ opp12@600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <140000>;
+ };
+ opp13@500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <140000>;
+ };
+ opp14@400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <140000>;
+ };
+ opp15@300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <140000>;
+ };
+ opp16@200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <140000>;
+ };
+ };
+
+ cpu1_opp_table: opp_table1 {
+ compatible = "operating-points-v2";
+ opp-shared;
+ opp00@1300000000 {
+ opp-hz = /bits/ 64 <1300000000>;
+ opp-microvolt = <1250000>;
+ clock-latency-ns = <140000>;
+ };
+ opp01@1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <1250000>;
+ clock-latency-ns = <140000>;
+ };
+ opp02@1100000000 {
+ opp-hz = /bits/ 64 <1100000000>;
+ opp-microvolt = <1250000>;
+ clock-latency-ns = <140000>;
+ };
+ opp03@1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <140000>;
+ };
+ opp04@900000000 {
+ opp-hz = /bits/ 64 <900000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <140000>;
+ };
+ opp05@800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <140000>;
+ };
+ opp06@700000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <140000>;
+ };
+ opp07@600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <140000>;
+ };
+ opp08@500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <140000>;
+ };
+ opp09@400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <140000>;
+ };
+ opp10@300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <140000>;
+ };
+ opp11@200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ opp-microvolt = <900000>;
+ clock-latency-ns = <140000>;
+ };
+ };
};

+&cpu0 { operating-points-v2 = <&cpu0_opp_table>; };
+&cpu1 { operating-points-v2 = <&cpu0_opp_table>; };
+&cpu2 { operating-points-v2 = <&cpu0_opp_table>; };
+&cpu3 { operating-points-v2 = <&cpu0_opp_table>; };
+
+&cpu4 { operating-points-v2 = <&cpu1_opp_table>; };
+&cpu5 { operating-points-v2 = <&cpu1_opp_table>; };
+&cpu6 { operating-points-v2 = <&cpu1_opp_table>; };
+&cpu7 { operating-points-v2 = <&cpu1_opp_table>; };
+
&clock {
compatible = "samsung,exynos5800-clock";
};
--
1.9.1

Subject: [PATCH v3 08/10] ARM: dts: Exynos5422: fix OPP tables

From: Ben Gamari <[email protected]>

The Exynos 5422 is identical to the 5800 except for the fact that it
boots from the A7 cores. Consequently, the core numbering is different:
cores 0-3 are A7s whereas 4-7 are A15s.

We can reuse the device tree of the 5800 for the 5422 but we must take
care to override the OPP tables and CPU clocks. These are otherwise
inherited from the exynos5800 devicetree, which has the CPU clusters
reversed compared to the 5422. This results in the A15 cores only
reaching 1.4GHz, the maximum rate of the KFC clock.

Cc: Javier Martinez Canillas <[email protected]>
Signed-off-by: Ben Gamari <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
arch/arm/boot/dts/exynos5422-cpus.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5422-cpus.dtsi b/arch/arm/boot/dts/exynos5422-cpus.dtsi
index b7f60c8..9a5131d 100644
--- a/arch/arm/boot/dts/exynos5422-cpus.dtsi
+++ b/arch/arm/boot/dts/exynos5422-cpus.dtsi
@@ -20,8 +20,10 @@
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x100>;
+ clocks = <&clock CLK_KFC_CLK>;
clock-frequency = <1000000000>;
cci-control-port = <&cci_control0>;
+ operating-points-v2 = <&cpu1_opp_table>;
};

&cpu1 {
@@ -30,6 +32,7 @@
reg = <0x101>;
clock-frequency = <1000000000>;
cci-control-port = <&cci_control0>;
+ operating-points-v2 = <&cpu1_opp_table>;
};

&cpu2 {
@@ -38,6 +41,7 @@
reg = <0x102>;
clock-frequency = <1000000000>;
cci-control-port = <&cci_control0>;
+ operating-points-v2 = <&cpu1_opp_table>;
};

&cpu3 {
@@ -46,14 +50,17 @@
reg = <0x103>;
clock-frequency = <1000000000>;
cci-control-port = <&cci_control0>;
+ operating-points-v2 = <&cpu1_opp_table>;
};

&cpu4 {
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <0x0>;
+ clocks = <&clock CLK_ARM_CLK>;
clock-frequency = <1800000000>;
cci-control-port = <&cci_control1>;
+ operating-points-v2 = <&cpu0_opp_table>;
};

&cpu5 {
@@ -62,6 +69,7 @@
reg = <0x1>;
clock-frequency = <1800000000>;
cci-control-port = <&cci_control1>;
+ operating-points-v2 = <&cpu0_opp_table>;
};

&cpu6 {
@@ -70,6 +78,7 @@
reg = <0x2>;
clock-frequency = <1800000000>;
cci-control-port = <&cci_control1>;
+ operating-points-v2 = <&cpu0_opp_table>;
};

&cpu7 {
@@ -78,4 +87,5 @@
reg = <0x3>;
clock-frequency = <1800000000>;
cci-control-port = <&cci_control1>;
+ operating-points-v2 = <&cpu0_opp_table>;
};
--
1.9.1

Subject: [PATCH v3 09/10] ARM: Exynos: use generic cpufreq driver for Exynos5800

From: Thomas Abraham <[email protected]>

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 <[email protected]>
Cc: Kukjin Kim <[email protected]>
Cc: Javier Martinez Canillas <[email protected]>
Signed-off-by: Thomas Abraham <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
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 6d97145..73853de 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -236,6 +236,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.9.1

Subject: [PATCH v3 10/10] cpufreq: arm-big-little: accept operating-points-v2 nodes

From: Ben Gamari <[email protected]>

The arm_big_little cpufreq driver can use operating points from
operating-points-v2 nodes without any trouble.

Cc: Javier Martinez Canillas <[email protected]>
Signed-off-by: Ben Gamari <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/cpufreq/arm_big_little_dt.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c
index 16ddeef..be7f632 100644
--- a/drivers/cpufreq/arm_big_little_dt.c
+++ b/drivers/cpufreq/arm_big_little_dt.c
@@ -35,12 +35,16 @@ static struct device_node *get_cpu_node_with_valid_op(int cpu)
{
struct device_node *np = of_cpu_device_node_get(cpu);

- if (!of_get_property(np, "operating-points", NULL)) {
- of_node_put(np);
- np = NULL;
+ if (of_get_property(np, "operating-points-v2", NULL)) {
+ return np;
}

- return np;
+ if (of_get_property(np, "operating-points", NULL)) {
+ return np;
+ }
+
+ of_node_put(np);
+ return NULL;
}

static int dt_init_opp_table(struct device *cpu_dev)
--
1.9.1

2015-12-05 03:54:51

by Viresh Kumar

[permalink] [raw]
Subject: Re: [PATCH v3 0/10] cpufreq: add generic cpufreq driver support for Exynos542x/5800 platforms

On 04-12-15, 18:30, Bartlomiej Zolnierkiewicz wrote:
> Hi,
>
> This patch series adds generic arm_big_little_dt cpufreq driver
> support for Exynos542x/5800 (using the new CPU clock type which
> allows it). It also:
> - enhances arm_big_little[_dt] driver with CPU cluster regulator
> support
> - adds CPU clock configuration data and CPU operating points
> setup for Exynos542x/5800
> - adds CPU cluster regulator supplies for Exynos542x/5800 boards
>
> This patch series has been tested on Exynos5422 based ODROID-XU3
> Lite board.
>
> Please note that this is not a final version of the patchset.
> I just wanted to push out current work-in-progress patches that
> integrate changes from Anand, Ben and me.

What's going on guys, Ben tried exactly same thing few days back:

http://marc.info/?l=linux-kernel&m=144909193925508&w=2

And the comments given there applies to you as well.

--
viresh

Subject: Re: [PATCH v3 0/10] cpufreq: add generic cpufreq driver support for Exynos542x/5800 platforms


Hi,

On Saturday, December 05, 2015 09:24:44 AM Viresh Kumar wrote:
> On 04-12-15, 18:30, Bartlomiej Zolnierkiewicz wrote:
> > Hi,
> >
> > This patch series adds generic arm_big_little_dt cpufreq driver
> > support for Exynos542x/5800 (using the new CPU clock type which
> > allows it). It also:
> > - enhances arm_big_little[_dt] driver with CPU cluster regulator
> > support
> > - adds CPU clock configuration data and CPU operating points
> > setup for Exynos542x/5800
> > - adds CPU cluster regulator supplies for Exynos542x/5800 boards
> >
> > This patch series has been tested on Exynos5422 based ODROID-XU3
> > Lite board.
> >
> > Please note that this is not a final version of the patchset.
> > I just wanted to push out current work-in-progress patches that
> > integrate changes from Anand, Ben and me.
>
> What's going on guys, Ben tried exactly same thing few days back:
>
> http://marc.info/?l=linux-kernel&m=144909193925508&w=2

Why I appreciate Ben's work this not exactly the same thing as
the above patchset lacks critical CLK_RECALC_NEW_RATES bugfix and
few other minor fixes.

> And the comments given there applies to you as well.

Yes, sure. That's why I wrote that this is work-in-progress
and put the TODO in the cover letter.

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

2015-12-06 02:26:11

by Viresh Kumar

[permalink] [raw]
Subject: Re: [PATCH v3 0/10] cpufreq: add generic cpufreq driver support for Exynos542x/5800 platforms

On 05-12-15, 08:49, Bartlomiej Zolnierkiewicz wrote:
> Why I appreciate Ben's work this not exactly the same thing as
> the above patchset lacks critical CLK_RECALC_NEW_RATES bugfix and
> few other minor fixes.

I am not saying that these are exactly same, code wise, but you are
both targeting to solve the same problem.

> > And the comments given there applies to you as well.
>
> Yes, sure. That's why I wrote that this is work-in-progress
> and put the TODO in the cover letter.

As I mentioned there, you need to migrate to cpufreq-dt instead of
arm-big-little now.

--
viresh

2015-12-07 15:25:50

by Sylwester Nawrocki

[permalink] [raw]
Subject: Re: [PATCH v3 03/10] clk: samsung: exynos5420: add cpu clock configuration data and instantiate cpu clock

On 04/12/15 18:30, Bartlomiej Zolnierkiewicz wrote:
> From: Thomas Abraham <[email protected]>
>
> 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 <[email protected]>
> Cc: Mike Turquette <[email protected]>
> Cc: Javier Martinez Canillas <[email protected]>
> Signed-off-by: Thomas Abraham <[email protected]>
> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>

Acked-by: Sylwester Nawrocki <[email protected]>

--
Regards,
Sylwester

2015-12-07 15:27:35

by Sylwester Nawrocki

[permalink] [raw]
Subject: Re: [PATCH v3 06/10] clk: samsung: exynos5800: fix cpu clock configuration data

On 04/12/15 18:30, Bartlomiej Zolnierkiewicz wrote:
> 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 <[email protected]>
> Cc: Mike Turquette <[email protected]>
> Cc: Javier Martinez Canillas <[email protected]>
> Cc: Thomas Abraham <[email protected]>
> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>

Acked-by: Sylwester Nawrocki <[email protected]>

--
Regards,
Sylwester

2015-12-07 15:54:08

by Markus Reichl

[permalink] [raw]
Subject: Re: [PATCH v3 0/10] cpufreq: add generic cpufreq driver support for Exynos542x/5800 platforms

Hi,

I have tested this patch set on Odroid-XU4 and get:

[ 2.140821] cpu cpu0: Looking up cpu-cluster.1-supply from device tree
[ 2.142780] cpu cpu0: bL_cpufreq_init: CPU 0 initialized
[ 2.146858] cpufreq: ondemand governor failed, too long transition latency of HW, fallback to performance governor
[ 2.161574] cpu cpu4: Looking up cpu-cluster.0-supply from device tree
[ 2.163277] cpu cpu4: bL_cpufreq_init: CPU 4 initialized
[ 2.167263] cpufreq: ondemand governor failed, too long transition latency of HW, fallback to performance governor
[ 2.180092] arm_big_little: bL_cpufreq_register: Registered platform driver: dt-bl

cpufreq stays in performance mode and does not change down from highest frequency.

Had the same behaviour with Ben Gamari's patch.

Thanks,
--
Markus


Am 04.12.2015 um 18:30 schrieb Bartlomiej Zolnierkiewicz:
> Hi,
>
> This patch series adds generic arm_big_little_dt cpufreq driver
> support for Exynos542x/5800 (using the new CPU clock type which
> allows it). It also:
> - enhances arm_big_little[_dt] driver with CPU cluster regulator
> support
> - adds CPU clock configuration data and CPU operating points
> setup for Exynos542x/5800
> - adds CPU cluster regulator supplies for Exynos542x/5800 boards
>
> This patch series has been tested on Exynos5422 based ODROID-XU3
> Lite board.
>
> Please note that this is not a final version of the patchset.
> I just wanted to push out current work-in-progress patches that
> integrate changes from Anand, Ben and me.
>
> TODO:
> - porting the Exynos542x/5800 support over cpufreq-dt
>
> Depends on:
> - next-20151124 branch of linux-next kernel tree
>
> Changes since v2:
> - ported over next-20151124 branch
> - integrated missing CLK_RECALC_NEW_RATES flags fix to patch #3
> (from Anand Moon)
> - added regulator supply properties for ODROID-XU3 Lite and
> ODROID-XU4 in patch #2
> - ported CPU OPPs to operating-points-v2 (from Ben Gamari)
> - added "ARM: dts: Exynos5422: fix OPP tables" patch (from Ben
> Gamari)
> - added "cpufreq: arm-big-little: accept operating-points-v2
> nodes" patch (from Ben Gamari)
> - renamed OPP nodes as opp@<opp-hz>
>
> Changes since v1:
> - added CPU cluster regulator supply properties to
> exynos5420-arndale-octa.dts, exynos5420-peach-pit.dts,
> exynos5420-smdk5420.dts and exynos5800-peach-pi.dts
>
> 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: Exynos5420/5800: add cluster regulator supply properties
> clk: samsung: exynos5800: fix cpu clock configuration data
> ARM: dts: Exynos5800: fix CPU OPP
>
> Ben Gamari (2):
> ARM: dts: Exynos5422: fix OPP tables
> cpufreq: arm-big-little: accept operating-points-v2 nodes
>
> 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-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/exynos5420.dtsi | 122 ++++++++++++++
> arch/arm/boot/dts/exynos5422-cpus.dtsi | 10 ++
> arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts | 8 +
> arch/arm/boot/dts/exynos5422-odroidxu3.dts | 8 +
> arch/arm/boot/dts/exynos5422-odroidxu4.dts | 8 +
> arch/arm/boot/dts/exynos5800-peach-pi.dts | 8 +
> arch/arm/boot/dts/exynos5800.dtsi | 165 +++++++++++++++++++
> arch/arm/mach-exynos/exynos.c | 8 +
> drivers/clk/samsung/clk-exynos5420.c | 88 ++++++++++-
> drivers/cpufreq/arm_big_little.c | 175 +++++++++++++++++----
> drivers/cpufreq/arm_big_little_dt.c | 12 +-
> include/dt-bindings/clock/exynos5420.h | 2 +
> 16 files changed, 608 insertions(+), 34 deletions(-)
>