Skip to content

Commit 4c2b2bc

Browse files
Josh-Tsaiamstan
authored andcommitted
fwk: dogwood: 5vsb entering/exit improvements
Lowered trip points so system does not brown out. Added hysteris (0.3A delta) so any noise will have a harder time dancing around the trip points. Even with hysteris, added a timeout so it makes sure the load doesn't return soon. Timeout increases exponentially so it gets more and more quieter. Improve debugging so all of the above can be tested better. BUG=Nirav's system BUG=https://app.clickup.com/t/86etqaz6v BUG=https://app.clickup.com/t/86etqb6qx TEST=Make Windows go to sleep, no more annoying clicking TEST=With a 5V USB load, try to find the trip point, there is not a ton of clicking anymore due to the hysterisis and timeout TEST=System does not brown out due to lower trip points TEST=While doing above, look at the console, there should be nicer logs BRANCH=fwk-dogwood-27111 Signed-off-by: Josh Tsai <Josh_Tsai@compal.com>
1 parent 34445a7 commit 4c2b2bc

File tree

3 files changed

+80
-24
lines changed

3 files changed

+80
-24
lines changed

zephyr/program/framework/dogwood/src/power_monitor.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@
2323
#define INA236_ADC_RANGE 2500 /* 2500 nV */
2424
#define INA236_ALERT_LIMIT(x) ((x * INA236_SHUNT_RESISTOR) * 1000 / INA236_ADC_RANGE)
2525

26-
#define INA236_MONITOR_12V_CURRENT 30000 /* 30 A */
27-
#define INA236_MONITOR_5V_CURRENT 2400 /* 2.4 A */
28-
2926
/**
3027
* We measured the timing between EC turns on the ps_on and recevies the pok_l signal.
3128
* The average timing is 400 ~ 420 ms.
@@ -89,7 +86,7 @@ static void power_monitor_update_ina236(int idx)
8986
if (idx == INA236_IDX_PSU_12V)
9087
current = INA236_MONITOR_12V_CURRENT;
9188
else if (idx == INA236_IDX_PSU_5V)
92-
current = INA236_MONITOR_5V_CURRENT;
89+
current = INA236_MONITOR_5V_UPPER_CURRENT_MA;
9390
else {
9491
CPRINTS("%s gets invalid index: %d", __func__, idx);
9592
return;
@@ -100,17 +97,24 @@ static void power_monitor_update_ina236(int idx)
10097
if (rv != EC_SUCCESS)
10198
CPRINTS("INA236 index %d write config fail", idx);
10299

103-
rv = ina2xx_set_alert(idx, INA236_ALERT_LIMIT(current));
104-
105-
if (rv != EC_SUCCESS)
106-
CPRINTS("INA236 index %d write alert fail", idx);
100+
power_monitor_set_alert_current(idx, current);
107101

108102
rv = ina2xx_set_mask(idx, INA2XX_MASK_EN_SOL);
109103

110104
if (rv != EC_SUCCESS)
111105
CPRINTS("INA236 index %d mask fail", idx);
112106
}
113107

108+
void power_monitor_set_alert_current(int idx, int ma)
109+
{
110+
int rv;
111+
112+
rv = ina2xx_set_alert(idx, INA236_ALERT_LIMIT(ma));
113+
114+
if (rv != EC_SUCCESS)
115+
CPRINTS("INA236 index %d write alert fail", idx);
116+
}
117+
114118
void power_monitor_init(void)
115119
{
116120
int index;
@@ -143,6 +147,8 @@ static void power_monitor_resume(void)
143147
/* Clear the alert status before disabling the interrupt */
144148
power_monitor_set_5vsb_alert(false);
145149
power_monitor_disable_interrupt(INA236_IDX_PSU_5V);
150+
power_monitor_set_alert_current(INA236_IDX_PSU_5V,
151+
INA236_MONITOR_5V_UPPER_CURRENT_MA);
146152
}
147153
}
148154
DECLARE_HOOK(HOOK_CHIPSET_RESUME, power_monitor_resume, HOOK_PRIO_DEFAULT);

zephyr/program/framework/dogwood/src/power_sequence.c

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,19 @@
4444
*/
4545
#define TIMEOUT_VS_POWER_TURN_OFF (20 * MSEC)
4646

47+
/*
48+
* Time to wait until turning off the power supply in low power
49+
* usage (like suspend).
50+
*
51+
* _MIN start at this timeout,
52+
* After every low-power entry we'll *= by _INCREASE_FACTOR.
53+
* for a max of _MAX
54+
*/
55+
#define TIMEOUT_5VSB_MIN (3 * MINUTE)
56+
#define TIMEOUT_5VSB_INCREASE_FACTOR 2
57+
#define TIMEOUT_5VSB_MAX (30 * MINUTE)
58+
static int timeout_5vsb = TIMEOUT_5VSB_MIN;
59+
4760
static bool power_s5_up; /* Chipset is sequencing up or down */
4861
static int force_shutdown_flags;
4962
static int d3cold_is_entry; /* check the d3cold status */
@@ -62,6 +75,7 @@ static bool power_enable_psu(bool enable)
6275
gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_ps_on), enable);
6376

6477
if (enable) {
78+
CPRINTS("PS_ON was sent, waiting for POK");
6579
/**
6680
* Wait for the PSU power good.
6781
* According to the waveform, EC needs to delay 500ms to
@@ -355,7 +369,8 @@ void power_5vsb_enter(void)
355369
if (force_enable_psu)
356370
return;
357371

358-
CPRINTS("power 5vsb enter");
372+
CPRINTS("current was low (<%dmA) for a long time, switching to 5vsb",
373+
INA236_MONITOR_5V_LOWER_CURRENT_MA);
359374

360375
gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_en_s0ix), 1);
361376

@@ -364,21 +379,40 @@ void power_5vsb_enter(void)
364379

365380
k_msleep(10);
366381
power_enable_psu(0);
382+
383+
/* Set the upper current limit */
384+
power_monitor_set_alert_current(INA236_IDX_PSU_5V,
385+
INA236_MONITOR_5V_UPPER_CURRENT_MA);
367386
}
368387

388+
static void power_5vsb_enter_deferred(void)
389+
{
390+
power_5vsb_enter();
391+
timeout_5vsb *= TIMEOUT_5VSB_INCREASE_FACTOR;
392+
if (timeout_5vsb > TIMEOUT_5VSB_MAX)
393+
timeout_5vsb = TIMEOUT_5VSB_MAX;
394+
}
395+
DECLARE_DEFERRED(power_5vsb_enter_deferred);
396+
369397
bool power_5vsb_exit(void)
370398
{
371-
CPRINTS("power 5vsb exit");
399+
CPRINTS("5vsb is not enough (>%dmA), turning on PSU",
400+
INA236_MONITOR_5V_UPPER_CURRENT_MA);
372401

373402
if (!power_enable_psu(1))
374403
return false;
375404

376405
k_msleep(10);
377406
gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_en_rvsp_l), 1);
407+
CPRINTS("switched to high power rails");
378408

379409
k_msleep(10);
380410
gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_en_s0ix), 0);
381411

412+
/* Set the lower current limit */
413+
power_monitor_set_alert_current(INA236_IDX_PSU_5V,
414+
INA236_MONITOR_5V_LOWER_CURRENT_MA);
415+
382416
return true;
383417
}
384418

@@ -428,7 +462,6 @@ static void diagnostic_power_glitch_detect(void)
428462
enum power_state power_handle_state(enum power_state state)
429463
{
430464
int s5_exit_tries = 0; /* For global reset to wait SLP_S5 signal de-asserts */
431-
432465
if (run_diagnostics == 1)
433466
diagnostic_power_glitch_detect();
434467

@@ -570,16 +603,22 @@ enum power_state power_handle_state(enum power_state state)
570603
!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_en_s0ix));
571604
bool has_alert = power_monitor_get_5vsb_alert();
572605

573-
if (has_alert && !has_exited_5vsb) {
574-
if (!power_5vsb_exit()) {
606+
if (has_alert) {
607+
/* clear the enter 5VSB timer if over upper current */
608+
hook_call_deferred(&power_5vsb_enter_deferred_data, -1);
609+
if (!has_exited_5vsb && !power_5vsb_exit()) {
575610
resume_ms_flag = 0;
576611
enter_ms_flag = 0;
577612
system_in_s0ix = 0;
578613
chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
579614
return POWER_S3S5;
580615
}
581-
} else if (!has_alert && has_exited_5vsb)
582-
power_5vsb_enter();
616+
} else if (!has_alert && has_exited_5vsb) {
617+
hook_call_deferred(&power_5vsb_enter_deferred_data, timeout_5vsb);
618+
CPRINTS("5V current under %dmA, don't need power supply, but waiting another %d min",
619+
INA236_MONITOR_5V_LOWER_CURRENT_MA,
620+
timeout_5vsb / MINUTE);
621+
}
583622
}
584623

585624
break;
@@ -635,6 +674,8 @@ enum power_state power_handle_state(enum power_state state)
635674
return POWER_S0;
636675

637676
case POWER_S0:
677+
/* Reset the timeout so we're power efficient entering suspend. */
678+
timeout_5vsb = TIMEOUT_5VSB_MIN;
638679

639680
if (gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_slp_s3_l)) == 0 ||
640681
force_shutdown_flags) {
@@ -702,13 +743,7 @@ enum power_state power_handle_state(enum power_state state)
702743
return POWER_S0;
703744
}
704745

705-
/**
706-
* Don't convert the 5VALW to 5VSB if the 5V current is over 2.4A.
707-
*/
708-
if (!power_monitor_get_5vsb_alert()) {
709-
k_msleep(10);
710-
power_5vsb_enter();
711-
}
746+
hook_call_deferred(&power_5vsb_enter_deferred_data, timeout_5vsb);
712747
}
713748

714749
return POWER_S3;
@@ -717,8 +752,12 @@ enum power_state power_handle_state(enum power_state state)
717752
/* Enable power for CPU check system */
718753
k_msleep(10);
719754
if (board_get_version() >= BOARD_VERSION_8) {
755+
bool has_exited_5vsb =
756+
!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_en_s0ix));
720757

721-
if (!power_5vsb_exit()) {
758+
/* clear the enter 5VSB timer if resume to s0ix */
759+
hook_call_deferred(&power_5vsb_enter_deferred_data, -1);
760+
if (!has_exited_5vsb && !power_5vsb_exit()) {
722761
resume_ms_flag = 0;
723762
enter_ms_flag = 0;
724763
system_in_s0ix = 0;
@@ -776,7 +815,6 @@ enum power_state power_handle_state(enum power_state state)
776815

777816
lpc_s0ix_resume_restore_masks();
778817
hook_notify(HOOK_CHIPSET_RESUME);
779-
780818
return POWER_S0;
781819

782820
break;

zephyr/program/framework/include/dogwood/power_monitor.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,23 @@
99
#define INA236_IDX_PSU_12V INA236_INDEX_ADD_PIN_GND
1010
#define INA236_IDX_PSU_5V INA236_INDEX_ADD_PIN_VS
1111

12+
#define INA236_MONITOR_12V_CURRENT 30000 /* 30 A */
13+
#define INA236_MONITOR_5V_UPPER_CURRENT_MA 1000
14+
#define INA236_MONITOR_5V_LOWER_CURRENT_MA 700
15+
1216
/**
1317
* Return the alert flag
1418
*
1519
* @return true when the EC detects the alert
1620
*/
1721
bool power_monitor_get_5vsb_alert(void);
1822

23+
/**
24+
* Set the alert current
25+
*
26+
* @param idx the index of the ina236
27+
* @param current set the alert current
28+
*/
29+
void power_monitor_set_alert_current(int idx, int ma);
30+
1931
#endif /* __CROS_EC_POWER_MONITOR_H */

0 commit comments

Comments
 (0)