aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mvebu
diff options
context:
space:
mode:
authorTomasz Maciej Nowak <tomek_n@o2.pl>2019-01-13 21:30:26 +0100
committerHauke Mehrtens <hauke@hauke-m.de>2019-01-27 00:16:14 +0100
commit7d188fb4dbdc5336cf7a802a9af9355fb69b0e97 (patch)
tree99fa66d8ef3d3c1db7c9a4fe31342349b72d9e9f /target/linux/mvebu
parent9b1102416fff7257626fa0bcdfe2fead9f0b2aeb (diff)
downloadupstream-7d188fb4dbdc5336cf7a802a9af9355fb69b0e97.tar.gz
upstream-7d188fb4dbdc5336cf7a802a9af9355fb69b0e97.tar.bz2
upstream-7d188fb4dbdc5336cf7a802a9af9355fb69b0e97.zip
mvebu: backport upstream fixes for armada 37xx
Upstream patches for processor frequency scaling, which fix possible system hard lockups. Signed-off-by: Tomasz Maciej Nowak <tomek_n@o2.pl>
Diffstat (limited to 'target/linux/mvebu')
-rw-r--r--target/linux/mvebu/patches-4.14/510-clk-mvebu-armada-37xx-periph-Fix-switching-CPU-rate-.patch92
-rw-r--r--target/linux/mvebu/patches-4.14/511-clk-mvebu-armada-37xx-periph-Fix-wrong-return-value-.patch33
-rw-r--r--target/linux/mvebu/patches-4.14/512-clk-mvebu-armada-37xx-periph-Remove-unused-var-num_p.patch33
3 files changed, 158 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-4.14/510-clk-mvebu-armada-37xx-periph-Fix-switching-CPU-rate-.patch b/target/linux/mvebu/patches-4.14/510-clk-mvebu-armada-37xx-periph-Fix-switching-CPU-rate-.patch
new file mode 100644
index 0000000000..42bfef7b7e
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/510-clk-mvebu-armada-37xx-periph-Fix-switching-CPU-rate-.patch
@@ -0,0 +1,92 @@
+From 61c40f35f5cd6f67ccbd7319a1722eb78c815989 Mon Sep 17 00:00:00 2001
+From: Gregory CLEMENT <gregory.clement@bootlin.com>
+Date: Tue, 19 Jun 2018 14:34:45 +0200
+Subject: [PATCH] clk: mvebu: armada-37xx-periph: Fix switching CPU rate from
+ 300Mhz to 1.2GHz
+
+Switching the CPU from the L2 or L3 frequencies (300 and 200 Mhz
+respectively) to L0 frequency (1.2 Ghz) requires a significant amount
+of time to let VDD stabilize to the appropriate voltage. This amount of
+time is large enough that it cannot be covered by the hardware
+countdown register. Due to this, the CPU might start operating at L0
+before the voltage is stabilized, leading to CPU stalls.
+
+To work around this problem, we prevent switching directly from the
+L2/L3 frequencies to the L0 frequency, and instead switch to the L1
+frequency in-between. The sequence therefore becomes:
+
+1. First switch from L2/L3(200/300MHz) to L1(600MHZ)
+2. Sleep 20ms for stabling VDD voltage
+3. Then switch from L1(600MHZ) to L0(1200Mhz).
+
+It is based on the work done by Ken Ma <make@marvell.com>
+
+Cc: stable@vger.kernel.org
+Fixes: 2089dc33ea0e ("clk: mvebu: armada-37xx-periph: add DVFS support for cpu clocks")
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mvebu/armada-37xx-periph.c | 38 ++++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+--- a/drivers/clk/mvebu/armada-37xx-periph.c
++++ b/drivers/clk/mvebu/armada-37xx-periph.c
+@@ -35,6 +35,7 @@
+ #define CLK_SEL 0x10
+ #define CLK_DIS 0x14
+
++#define ARMADA_37XX_DVFS_LOAD_1 1
+ #define LOAD_LEVEL_NR 4
+
+ #define ARMADA_37XX_NB_L0L1 0x18
+@@ -507,6 +508,40 @@ static long clk_pm_cpu_round_rate(struct
+ return -EINVAL;
+ }
+
++/*
++ * Switching the CPU from the L2 or L3 frequencies (300 and 200 Mhz
++ * respectively) to L0 frequency (1.2 Ghz) requires a significant
++ * amount of time to let VDD stabilize to the appropriate
++ * voltage. This amount of time is large enough that it cannot be
++ * covered by the hardware countdown register. Due to this, the CPU
++ * might start operating at L0 before the voltage is stabilized,
++ * leading to CPU stalls.
++ *
++ * To work around this problem, we prevent switching directly from the
++ * L2/L3 frequencies to the L0 frequency, and instead switch to the L1
++ * frequency in-between. The sequence therefore becomes:
++ * 1. First switch from L2/L3(200/300MHz) to L1(600MHZ)
++ * 2. Sleep 20ms for stabling VDD voltage
++ * 3. Then switch from L1(600MHZ) to L0(1200Mhz).
++ */
++static void clk_pm_cpu_set_rate_wa(unsigned long rate, struct regmap *base)
++{
++ unsigned int cur_level;
++
++ if (rate != 1200 * 1000 * 1000)
++ return;
++
++ regmap_read(base, ARMADA_37XX_NB_CPU_LOAD, &cur_level);
++ cur_level &= ARMADA_37XX_NB_CPU_LOAD_MASK;
++ if (cur_level <= ARMADA_37XX_DVFS_LOAD_1)
++ return;
++
++ regmap_update_bits(base, ARMADA_37XX_NB_CPU_LOAD,
++ ARMADA_37XX_NB_CPU_LOAD_MASK,
++ ARMADA_37XX_DVFS_LOAD_1);
++ msleep(20);
++}
++
+ static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+ {
+@@ -537,6 +572,9 @@ static int clk_pm_cpu_set_rate(struct cl
+ */
+ reg = ARMADA_37XX_NB_CPU_LOAD;
+ mask = ARMADA_37XX_NB_CPU_LOAD_MASK;
++
++ clk_pm_cpu_set_rate_wa(rate, base);
++
+ regmap_update_bits(base, reg, mask, load_level);
+
+ return rate;
diff --git a/target/linux/mvebu/patches-4.14/511-clk-mvebu-armada-37xx-periph-Fix-wrong-return-value-.patch b/target/linux/mvebu/patches-4.14/511-clk-mvebu-armada-37xx-periph-Fix-wrong-return-value-.patch
new file mode 100644
index 0000000000..389a13a2b4
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/511-clk-mvebu-armada-37xx-periph-Fix-wrong-return-value-.patch
@@ -0,0 +1,33 @@
+From 616bf80d381da13fbb392ebff06f46f946e3ee84 Mon Sep 17 00:00:00 2001
+From: Gregory CLEMENT <gregory.clement@bootlin.com>
+Date: Fri, 13 Jul 2018 12:27:26 +0200
+Subject: [PATCH] clk: mvebu: armada-37xx-periph: Fix wrong return value in
+ get_parent
+
+The return value of the get_parent operation is a u8, whereas a -EINVAL
+was returned. This wrong value was return if the value was bigger that
+the number of parent but this case was already handled by the core.
+
+So we can just remove this chunk of code to fix the issue.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Fixes: 9818a7a4fd10 ("clk: mvebu: armada-37xx-periph: prepare cpu clk to
+be used with DVFS")
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mvebu/armada-37xx-periph.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/drivers/clk/mvebu/armada-37xx-periph.c
++++ b/drivers/clk/mvebu/armada-37xx-periph.c
+@@ -429,9 +429,6 @@ static u8 clk_pm_cpu_get_parent(struct c
+ val &= pm_cpu->mask_mux;
+ }
+
+- if (val >= num_parents)
+- return -EINVAL;
+-
+ return val;
+ }
+
diff --git a/target/linux/mvebu/patches-4.14/512-clk-mvebu-armada-37xx-periph-Remove-unused-var-num_p.patch b/target/linux/mvebu/patches-4.14/512-clk-mvebu-armada-37xx-periph-Remove-unused-var-num_p.patch
new file mode 100644
index 0000000000..874f982bd7
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/512-clk-mvebu-armada-37xx-periph-Remove-unused-var-num_p.patch
@@ -0,0 +1,33 @@
+From 8927c27b32703e28041ae19bf25ea53461be83a1 Mon Sep 17 00:00:00 2001
+From: Anders Roxell <anders.roxell@linaro.org>
+Date: Fri, 27 Jul 2018 00:27:21 +0200
+Subject: [PATCH] clk: mvebu: armada-37xx-periph: Remove unused var num_parents
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When building armada-37xx-periph, num_parents isn't used in function
+clk_pm_cpu_get_parent:
+drivers/clk/mvebu/armada-37xx-periph.c: In function ‘clk_pm_cpu_get_parent’:
+drivers/clk/mvebu/armada-37xx-periph.c:419:6: warning: unused variable ‘num_parents’ [-Wunused-variable]
+ int num_parents = clk_hw_get_num_parents(hw);
+ ^~~~~~~~~~~
+Remove the declaration of num_parents to dispose the warning.
+
+Fixes: 616bf80d381d ("clk: mvebu: armada-37xx-periph: Fix wrong return value in get_parent")
+Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mvebu/armada-37xx-periph.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/clk/mvebu/armada-37xx-periph.c
++++ b/drivers/clk/mvebu/armada-37xx-periph.c
+@@ -419,7 +419,6 @@ static unsigned int armada_3700_pm_dvfs_
+ static u8 clk_pm_cpu_get_parent(struct clk_hw *hw)
+ {
+ struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
+- int num_parents = clk_hw_get_num_parents(hw);
+ u32 val;
+
+ if (armada_3700_pm_dvfs_is_enabled(pm_cpu->nb_pm_base)) {