summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2013-10-15 11:09:39 +0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-10-15 21:01:12 +0000
commit21db824efefde9237db0f92e6145a10bbdd47b53 (patch)
tree63d46d36ec6d72e438965418b1cefd196bf6b6f5
parente96a8dc7cf707e847da138c8450f955aa8154d5f (diff)
downloadchrome-ec-21db824efefde9237db0f92e6145a10bbdd47b53.tar.gz
spring: Prevent cutting off power on sysjump
If the battery is dead, we must ensure the input current is not cut off on sysjump. To do so, we record the time of the jump and the I_LIM PWM duty cycle when jumping. Within 20 seconds from the jump, restrict the input current to be equal to or higher than that when jumping. This will ensure the system have at least the same amount of power as when sysjump happens. If the user switches to a low power charger within the 20-second interval, the worst case is that the charger browns out and then recover after 20 seconds, which should be fine. BUG=chrome-os-partner:23055 TEST=Unplug battery and do 'sysjump RW' in S0. Without this CL, the AP shuts down and the EC browns out. With this CL, the AP remains in S0. BRANCH=Spring Change-Id: Icf12cd2ec3a59786c01e0b1464a6f094e7c12756 Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/173073 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Commit-Queue: Vincent Palatin <vpalatin@chromium.org> Tested-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--board/spring/usb_charging.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/board/spring/usb_charging.c b/board/spring/usb_charging.c
index 2125dc8ec3..4032a63bee 100644
--- a/board/spring/usb_charging.c
+++ b/board/spring/usb_charging.c
@@ -88,6 +88,9 @@
#define S5_BOOST_CTRL_LOWER_BOUND 94
#define S5_BOOST_CTRL_UPPER_BOUND 98
+static timestamp_t jump_time;
+static int jump_pwm_duty;
+
static int current_dev_type = TSU6721_TYPE_NONE;
static int nominal_pwm_duty;
static int current_pwm_duty;
@@ -214,7 +217,12 @@ static void board_ilim_use_pwm(void)
*/
STM32_TIM_PSC(3) = CPU_CLOCK / PWM_FREQUENCY / 100 - 1; /* pre-scaler */
STM32_TIM_ARR(3) = 100; /* auto-reload value */
- STM32_TIM_CCR1(3) = 100; /* duty cycle */
+
+ /*
+ * Note that we don't set STM32_TIM_CCR1 here so as to prevent
+ * setting a wrong value. The caller of this function must ensure
+ * STM32_TIM_CCR1 is set correctly before calling this function.
+ */
/* CC1 configured as output, PWM mode 1, preload enable */
STM32_TIM_CCMR1(3) = (6 << 4) | (1 << 3);
@@ -349,18 +357,38 @@ int board_has_high_power_ac(void)
void board_pwm_duty_cycle(int percent)
{
- if (current_ilim_config != ILIM_CONFIG_PWM)
- board_ilim_config(ILIM_CONFIG_PWM);
if (percent < 0)
percent = 0;
if (percent > 100)
percent = 100;
- STM32_TIM_CCR1(3) = (percent * STM32_TIM_ARR(3)) / 100;
+
+ /*
+ * If we are in RW, we need to prevent unsetting the PWM duty cycle RO
+ * set. Otherwise the EC might cut its own power when the battery is
+ * dead.
+ *
+ * If we jumped from RO within the last 20 seconds, only allow higher
+ * current than that when jumping.
+ */
+ if (system_get_image_copy() == SYSTEM_IMAGE_RW) {
+ if (get_time().val - jump_time.val < (20 * SECOND) &&
+ percent > jump_pwm_duty)
+ percent = jump_pwm_duty;
+ }
+
+ STM32_TIM_CCR1(3) = percent;
+ if (current_ilim_config != ILIM_CONFIG_PWM)
+ board_ilim_config(ILIM_CONFIG_PWM);
current_pwm_duty = percent;
}
void board_pwm_init_limit(void)
{
+ if (system_get_image_copy() == SYSTEM_IMAGE_RW) {
+ jump_time = get_time();
+ jump_pwm_duty = STM32_TIM_CCR1(3);
+ }
+
/*
* put a high initial limit to avoid browning out the system
* when we turn on charging, lower power bricks might cut off