Przeglądaj źródła

disp: msm: disable regulator load after the regulator was disabled

Setting a lower load can make the regulator enter into LPM. Now the
lower load was set before the regulator disable, there's a risk here.
The regulator has been LPM, while it was not disable, if the cosumer
has a higher current needed than LPM at this time, that will lead OCP
on this regulator. The right operation for a regulator enable/disable
should be:
 1. regulator_set_voltage(vreg, active_min_uV, active_max_uV) and
    regulator_set_load(vreg, active_load_uA); in either order
 2. regulator_enable()
 3. regulator_disable()
 4. regulator_set_voltage(vreg, inactive_min_uV, inactive_max_uV)
    and regulator_set_load(vreg, inactive_load_uA); in either order

Change-Id: Ibe4f888a5675baf2691e479daa163d8867902e69
Signed-off-by: Zhao, Yuan <[email protected]>
Zhao, Yuan 4 lat temu
rodzic
commit
d9c2a8d3a6
3 zmienionych plików z 24 dodań i 21 usunięć
  1. 13 10
      msm/dsi/dsi_pwr.c
  2. 6 6
      msm/sde_io_util.c
  3. 5 5
      rotator/sde_rotator_io_util.c

+ 13 - 10
msm/dsi/dsi_pwr.c

@@ -179,9 +179,14 @@ static int dsi_pwr_enable_vregs(struct dsi_regulator_info *regs, bool enable)
 				usleep_range((pre_off_ms * 1000),
 						(pre_off_ms * 1000) + 10);
 
+			(void)regulator_disable(regs->vregs[i].vreg);
+
+			if (post_off_ms)
+				usleep_range((post_off_ms * 1000),
+						(post_off_ms * 1000) + 10);
+
 			(void)regulator_set_load(regs->vregs[i].vreg,
 						regs->vregs[i].disable_load);
-			(void)regulator_disable(regs->vregs[i].vreg);
 
 			num_of_v = regulator_count_voltages(vreg->vreg);
 			if (num_of_v > 0)
@@ -189,9 +194,6 @@ static int dsi_pwr_enable_vregs(struct dsi_regulator_info *regs, bool enable)
 						regs->vregs[i].off_min_voltage,
 						regs->vregs[i].max_voltage);
 
-			if (post_off_ms)
-				usleep_range((post_off_ms * 1000),
-						(post_off_ms * 1000) + 10);
 		}
 	}
 
@@ -214,19 +216,20 @@ error:
 			usleep_range((pre_off_ms * 1000),
 					(pre_off_ms * 1000) + 10);
 
+		(void)regulator_disable(regs->vregs[i].vreg);
+
+		if (post_off_ms)
+			usleep_range((post_off_ms * 1000),
+					(post_off_ms * 1000) + 10);
+
 		(void)regulator_set_load(regs->vregs[i].vreg,
 					 regs->vregs[i].disable_load);
 
 		num_of_v = regulator_count_voltages(regs->vregs[i].vreg);
 		if (num_of_v > 0)
 			(void)regulator_set_voltage(regs->vregs[i].vreg,
-					    0, regs->vregs[i].max_voltage);
+				0, regs->vregs[i].max_voltage);
 
-		(void)regulator_disable(regs->vregs[i].vreg);
-
-		if (post_off_ms)
-			usleep_range((post_off_ms * 1000),
-					(post_off_ms * 1000) + 10);
 	}
 
 	return rc;

+ 6 - 6
msm/sde_io_util.c

@@ -419,15 +419,15 @@ int msm_dss_enable_vreg(struct dss_vreg *in_vreg, int num_vreg, int enable)
 			if (in_vreg[i].pre_off_sleep)
 				usleep_range(in_vreg[i].pre_off_sleep * 1000,
 					(in_vreg[i].pre_off_sleep * 1000) + 10);
+			regulator_disable(in_vreg[i].vreg);
+			if (in_vreg[i].post_off_sleep)
+				usleep_range(in_vreg[i].post_off_sleep * 1000,
+				(in_vreg[i].post_off_sleep * 1000) + 10);
 			regulator_set_load(in_vreg[i].vreg,
 				in_vreg[i].disable_load);
-			regulator_disable(in_vreg[i].vreg);
 			if (regulator_count_voltages(in_vreg[i].vreg) > 0)
 				regulator_set_voltage(in_vreg[i].vreg, 0,
 						in_vreg[i].max_voltage);
-			if (in_vreg[i].post_off_sleep)
-				usleep_range(in_vreg[i].post_off_sleep * 1000,
-				(in_vreg[i].post_off_sleep * 1000) + 10);
 		}
 	}
 	return rc;
@@ -440,12 +440,12 @@ vreg_set_opt_mode_fail:
 		if (in_vreg[i].pre_off_sleep)
 			usleep_range(in_vreg[i].pre_off_sleep * 1000,
 				(in_vreg[i].pre_off_sleep * 1000) + 10);
-		regulator_set_load(in_vreg[i].vreg,
-			in_vreg[i].disable_load);
 		regulator_disable(in_vreg[i].vreg);
 		if (in_vreg[i].post_off_sleep)
 			usleep_range(in_vreg[i].post_off_sleep * 1000,
 				(in_vreg[i].post_off_sleep * 1000) + 10);
+		regulator_set_load(in_vreg[i].vreg,
+			in_vreg[i].disable_load);
 	}
 
 	return rc;

+ 5 - 5
rotator/sde_rotator_io_util.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2012, 2015-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012, 2015-2020, The Linux Foundation. All rights reserved.
  */
 #define pr_fmt(fmt)	"%s: " fmt, __func__
 
@@ -255,12 +255,12 @@ int sde_rot_enable_vreg(struct sde_vreg *in_vreg, int num_vreg, int enable)
 			if (in_vreg[i].pre_off_sleep)
 				usleep_range(in_vreg[i].pre_off_sleep * 1000,
 					in_vreg[i].pre_off_sleep * 1000);
-			regulator_set_load(in_vreg[i].vreg,
-				in_vreg[i].disable_load);
 			regulator_disable(in_vreg[i].vreg);
 			if (in_vreg[i].post_off_sleep)
 				usleep_range(in_vreg[i].post_off_sleep * 1000,
 					in_vreg[i].post_off_sleep * 1000);
+			regulator_set_load(in_vreg[i].vreg,
+				in_vreg[i].disable_load);
 		}
 	}
 	return rc;
@@ -273,12 +273,12 @@ vreg_set_opt_mode_fail:
 		if (in_vreg[i].pre_off_sleep)
 			usleep_range(in_vreg[i].pre_off_sleep * 1000,
 				in_vreg[i].pre_off_sleep * 1000);
-		regulator_set_load(in_vreg[i].vreg,
-			in_vreg[i].disable_load);
 		regulator_disable(in_vreg[i].vreg);
 		if (in_vreg[i].post_off_sleep)
 			usleep_range(in_vreg[i].post_off_sleep * 1000,
 				in_vreg[i].post_off_sleep * 1000);
+		regulator_set_load(in_vreg[i].vreg,
+			in_vreg[i].disable_load);
 	}
 
 	return rc;