[PATCH mvebu v2 00/10] Armada 37xx: Fix cpufreq changing base CPU speed to 800 MHz from 1000 MHz

Pali Rohár pali at kernel.org
Tue Feb 16 05:41:41 EST 2021


On Monday 15 February 2021 21:48:08 nnet wrote:
> > Could you test following change instead of PATCH 04/10? I added here also
> > logic for 1.2 GHz variant with 1.132 V value another change is that
> > value for load L0 is not touched as it is stable.
> 
> These changes to patch 04/10 worked going 600 MHz <-> 1.2 GHz , _but_ only with:
> 
> ++#define MIN_VOLT_MV_FOR_L1_1200MHZ 1213
> 
> During this latest testing I saw freezes with 1132 mV.
> 
> I've had no lockups with 1213 mV which I just used from the values for L1/L0 from OTP.

I still do not know what is the meaning of values stored in OTP...
And there are more non-zero bits which are not used (yet).

Anyway, with your another test it looks like that limit is not based on
fixed value but rather on current L0 value. Therefore I'm thinking if
the correct way is instead to use L1 := L0 voltage value for 1/1.2 GHz
mode. Could you try following change instead of previous and PATCH 04/10?

diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
index b8dc6c849..12d0ff7b1 100644
--- a/drivers/cpufreq/armada-37xx-cpufreq.c
+++ b/drivers/cpufreq/armada-37xx-cpufreq.c
@@ -208,6 +208,8 @@ static u32 armada_37xx_avs_val_match(int target_vm)
  * - L2 & L3 voltage should be about 150mv smaller than L0 voltage.
  * This function calculates L1 & L2 & L3 AVS values dynamically based
  * on L0 voltage and fill all AVS values to the AVS value table.
+ * When base CPU frequency is 1000 or 1200 MHz then there is additional
+ * minimal avs value for load L1.
  */
 static void __init armada37xx_cpufreq_avs_configure(struct regmap *base,
 						struct armada_37xx_dvfs *dvfs)
@@ -239,17 +241,36 @@ static void __init armada37xx_cpufreq_avs_configure(struct regmap *base,
 		for (load_level = 1; load_level < LOAD_LEVEL_NR; load_level++)
 			dvfs->avs[load_level] = avs_min;
 
+		/*
+		 * Set the avs values for load L0 and L1 when base CPU frequency
+		 * is 1000/1200 MHz to its typical initial values according to
+		 * the Armada 3700 Hardware Specifications.
+		 */
+		if (dvfs->cpu_freq_max >= 1000*1000*1000) {
+			if (dvfs->cpu_freq_max >= 1200*1000*1000)
+				avs_min = armada_37xx_avs_val_match(1155);
+			else
+				avs_min = armada_37xx_avs_val_match(1108);
+			dvfs->avs[0] = dvfs->avs[1] = avs_min;
+		}
+
 		return;
 	}
 
 	/*
 	 * L1 voltage is equal to L0 voltage - 100mv and it must be
-	 * larger than 1000mv
+	 * larger than 1000mv. When base CPU frequency is 1000/1200 MHz,
+	 * L1 voltage must must be equal to L0 voltage, otherwise
+	 * the CPU gets stuck when switching from load L1 to load L0.
 	 */
 
-	target_vm = avs_map[l0_vdd_min] - 100;
-	target_vm = target_vm > MIN_VOLT_MV ? target_vm : MIN_VOLT_MV;
-	dvfs->avs[1] = armada_37xx_avs_val_match(target_vm);
+	if (dvfs->cpu_freq_max >= 1000*1000*1000) {
+		dvfs->avs[1] = dvfs->avs[0];
+	} else {
+		target_vm = avs_map[l0_vdd_min] - 100;
+		target_vm = target_vm > MIN_VOLT_MV ? target_vm : MIN_VOLT_MV;
+		dvfs->avs[1] = armada_37xx_avs_val_match(target_vm);
+	}
 
 	/*
 	 * L2 & L3 voltage is equal to L0 voltage - 150mv and it must



More information about the linux-arm-kernel mailing list