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>
This commit is contained in:
		 Tomasz Maciej Nowak
					Tomasz Maciej Nowak
				
			
				
					committed by
					
						 Hauke Mehrtens
						Hauke Mehrtens
					
				
			
			
				
	
			
			
			 Hauke Mehrtens
						Hauke Mehrtens
					
				
			
						parent
						
							9b1102416f
						
					
				
				
					commit
					7d188fb4db
				
			| @@ -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; | ||||||
| @@ -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; | ||||||
|  |  } | ||||||
|  |   | ||||||
| @@ -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)) { | ||||||
		Reference in New Issue
	
	Block a user