summaryrefslogtreecommitdiff
path: root/power
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2017-12-06 23:20:26 -0800
committerDaisuke Nojiri <dnojiri@chromium.org>2017-12-19 09:13:58 -0800
commita8aa6ed1c68a8ce6093ad0270a2ebe508a3b06a7 (patch)
tree22ed9b7ece54e3e141e133c42c09dadd95620381 /power
parent8ce2ef6c81ecc83314c23d8511f07237e7b9efad (diff)
downloadchrome-ec-a8aa6ed1c68a8ce6093ad0270a2ebe508a3b06a7.tar.gz
power: cannonlake: Fix power state tracking.
The cannonlake power state chipset code would fail to keep an accurate record of the chipset's power state. For example, the EC could claim that the AP was in G3, whereas the SLP_SUS_L signal was deasserted. This commit fixes a few issues with the chipset code. - First, don't have PP3300_DSW_EN enabled by default coming out of reset. The default chipset power state when the EC comes out of reset is G3, therefore we should not enable the PP33000 DSW rail until we decide to leave G3. This is usually triggered by a power button press. - Similarly, when we wish to enter G3, we should turn off the PP3300 DSW rail instead of the noop that was done before. - Lastly, turn on the 5V rail when entering S5 instead of S3 and turn it off when leaving S5 to G3. BUG=b:70184397,b:70244199 BRANCH=None TEST=Flash zoombini; Verify that AP boots to S0 and can shutdown to S5 and the EC tracks it. Verify that after the S5 inactivity timer, we fall to G3. Verify that SLP_SUS_L is asserted and DSWPWROK is low. Verify that we can still perform BC1.2 detection in G3. `reboot ap-off` and verify that the AP does indeed remain off and no port 80 codes are seen. TEST=Verify that 5V is off in G3, but can be turned on if needed. TEST=Verify that 5V is on in S5. TEST=With the exception of BC1.2, repeat the above tests for meowth. Change-Id: I444a8f29969ef6a68a83d1734912d239bad429a5 Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/813501 Commit-Ready: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Shawn N <shawnn@chromium.org>
Diffstat (limited to 'power')
-rw-r--r--power/cannonlake.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/power/cannonlake.c b/power/cannonlake.c
index b9181475ce..b07114eced 100644
--- a/power/cannonlake.c
+++ b/power/cannonlake.c
@@ -74,11 +74,21 @@ void chipset_reset(int cold_reset)
enum power_state chipset_force_g3(void)
{
+ int timeout = 50;
chipset_force_shutdown();
- CPRINTS("Faking G3. (NOOP for now.)");
- /* TODO(aaboagye): Do the right thing for real. */
- /* TODO(aaboagye): maybe turn off DSW load switch. */
+ /* Turn off DSW load switch. */
+ gpio_set_level(GPIO_EN_PP3300_DSW, 0);
+
+ /* Now wait for DSW_PWROK to go away. */
+ while (gpio_get_level(GPIO_PMIC_DPWROK) && (timeout > 0)) {
+ msleep(1);
+ timeout--;
+ };
+
+ if (!timeout)
+ CPRINTS("DSW_PWROK didn't go low! Assuming G3.");
+
return POWER_G3;
}
@@ -86,10 +96,14 @@ enum power_state power_handle_state(enum power_state state)
{
enum power_state new_state;
int dswpwrok_in = gpio_get_level(GPIO_PMIC_DPWROK);
+ static int dswpwrok_out = -1;
/* Pass-through DSW_PWROK to CNL. */
- gpio_set_level(GPIO_PCH_DSW_PWROK, dswpwrok_in);
- CPRINTS("Pass thru GPIO_DSW_PWROK: %d", dswpwrok_in);
+ if (dswpwrok_in != dswpwrok_out) {
+ CPRINTS("Pass thru GPIO_DSW_PWROK: %d", dswpwrok_in);
+ gpio_set_level(GPIO_PCH_DSW_PWROK, dswpwrok_in);
+ dswpwrok_out = dswpwrok_in;
+ }
common_intel_x86_handle_rsmrst(state);
@@ -98,26 +112,34 @@ enum power_state power_handle_state(enum power_state state)
forcing_shutdown = 0;
}
- /* TODO(aaboagye): Enable 3300_DSW in Deep Sx only. */
switch (state) {
- case POWER_S5S3:
- /*
- * In S3, enable 5V rail. Wireless rails are handled by common
- * x86 chipset code.
- */
+ case POWER_G3S5:
+ /* Turn on the PP3300_DSW rail. */
+ gpio_set_level(GPIO_EN_PP3300_DSW, 1);
+ if (power_wait_signals(IN_PGOOD_ALL_CORE))
+ break;
+
+ /* Pass thru DSWPWROK again since we changed it. */
+ dswpwrok_in = gpio_get_level(GPIO_PMIC_DPWROK);
+ gpio_set_level(GPIO_PCH_DSW_PWROK, dswpwrok_in);
+ CPRINTS("Pass thru GPIO_DSW_PWROK: %d", dswpwrok_in);
+ dswpwrok_out = dswpwrok_in;
+
+ /* Enable the 5V rail. */
#ifdef CONFIG_POWER_PP5000_CONTROL
power_5v_enable(task_get_current(), 1);
-#else
+#else /* !defined(CONFIG_POWER_PP5000_CONTROL) */
gpio_set_level(GPIO_EN_PP5000, 1);
-#endif
+#endif /* defined(CONFIG_POWER_PP5000_CONTROL) */
break;
- case POWER_S3S5:
+ case POWER_S5G3:
+ /* Turn off the 5V rail. */
#ifdef CONFIG_POWER_PP5000_CONTROL
power_5v_enable(task_get_current(), 0);
-#else
+#else /* !defined(CONFIG_POWER_PP5000_CONTROL) */
gpio_set_level(GPIO_EN_PP5000, 0);
-#endif
+#endif /* defined(CONFIG_POWER_PP5000_CONTROL) */
break;
default: