From d9c2a8d3a6c40fc1f13dedbc9e98985ba5e6520a Mon Sep 17 00:00:00 2001 From: "Zhao, Yuan" Date: Mon, 21 Sep 2020 17:12:16 +0800 Subject: [PATCH] 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 --- msm/dsi/dsi_pwr.c | 23 +++++++++++++---------- msm/sde_io_util.c | 14 +++++++------- rotator/sde_rotator_io_util.c | 10 +++++----- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/msm/dsi/dsi_pwr.c b/msm/dsi/dsi_pwr.c index b7e5ccccde..7b3f9e2c85 100644 --- a/msm/dsi/dsi_pwr.c +++ b/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; diff --git a/msm/sde_io_util.c b/msm/sde_io_util.c index 0d1ec68332..71e6cf56ad 100644 --- a/msm/sde_io_util.c +++ b/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_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); + regulator_set_load(in_vreg[i].vreg, + in_vreg[i].disable_load); + if (regulator_count_voltages(in_vreg[i].vreg) > 0) + regulator_set_voltage(in_vreg[i].vreg, 0, + in_vreg[i].max_voltage); } } 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; diff --git a/rotator/sde_rotator_io_util.c b/rotator/sde_rotator_io_util.c index 3fe1de7f29..1146bf51eb 100644 --- a/rotator/sde_rotator_io_util.c +++ b/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;