summaryrefslogtreecommitdiff
path: root/common/x86_power.c
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-03-15 09:27:45 -0700
committerRandall Spangler <rspangler@chromium.org>2012-03-15 09:27:45 -0700
commit38d1b2e8bad5b9d4698963dbb63684aacbd23ec0 (patch)
treea1071f308986a330b86f3f56e5f6309c5d94f334 /common/x86_power.c
parent0cde4cfec35d34fb77c75d655d098390b70c8655 (diff)
downloadchrome-ec-38d1b2e8bad5b9d4698963dbb63684aacbd23ec0.tar.gz
Add ability to trigger both warm and cold resets.
Keyboard reset now triggers a cold reset. Signed-off-by: Randall Spangler <rspangler@chromium.org> BUG=chrome-os-partner:8397 TEST=power system on, then do 'x86reset cold' for a cold reset or 'x86reset warm' for a warm reset. Check x86 debug console to see that coreboot detects the warm (soft) reset. Change-Id: I00930d9f5df98365277cd5c7f2eb8f135c4e4398
Diffstat (limited to 'common/x86_power.c')
-rw-r--r--common/x86_power.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/common/x86_power.c b/common/x86_power.c
index 8a9664932c..1b6e2a4249 100644
--- a/common/x86_power.c
+++ b/common/x86_power.c
@@ -174,16 +174,38 @@ void x86_power_force_shutdown(void)
}
-void x86_power_reset(void)
+void x86_power_reset(int cold_reset)
{
- /* Ignore if RCINn is already low */
- if (gpio_get_level(GPIO_PCH_RCINn) == 0)
- return;
-
- /* Pulse must be at least 16 PCI clocks long = 500ns */
- gpio_set_level(GPIO_PCH_RCINn, 0);
- udelay(10);
- gpio_set_level(GPIO_PCH_RCINn, 1);
+ if (cold_reset) {
+ /* Drop and restore PWROK. This causes the PCH to reboot,
+ * regardless of its after-G3 setting. This type of reboot
+ * causes the PCH to assert PLTRST#, SLP_S3#, and SLP_S5#, so
+ * we actually drop power to the rest of the system (hence, a
+ * "cold" reboot). */
+
+ /* Ignore if PWROK is already low */
+ if (gpio_get_level(GPIO_PCH_PWROK) == 0)
+ return;
+
+ /* PWROK must deassert for at least 3 RTC clocks = 91 us */
+ gpio_set_level(GPIO_PCH_PWROK, 0);
+ udelay(100);
+ gpio_set_level(GPIO_PCH_PWROK, 1);
+
+ } else {
+ /* Send a RCIN# pulse to the PCH. This just causes it to
+ * assert INIT# to the CPU without dropping power or asserting
+ * PLTRST# to reset the rest of the system. */
+
+ /* Ignore if RCINn is already low */
+ if (gpio_get_level(GPIO_PCH_RCINn) == 0)
+ return;
+
+ /* Pulse must be at least 16 PCI clocks long = 500 ns */
+ gpio_set_level(GPIO_PCH_RCINn, 0);
+ udelay(10);
+ gpio_set_level(GPIO_PCH_RCINn, 1);
+ }
}
/*****************************************************************************/
@@ -431,8 +453,16 @@ DECLARE_CONSOLE_COMMAND(x86power, command_x86power);
static int command_x86reset(int argc, char **argv)
{
+ int is_cold = 1;
+
+ if (argc > 1 && !strcasecmp(argv[1], "cold"))
+ is_cold = 1;
+ else if (argc > 1 && !strcasecmp(argv[1], "warm"))
+ is_cold = 0;
+
/* Force the x86 to reset */
- x86_power_reset();
+ uart_printf("Issuing x86 %s reset...\n", is_cold ? "cold" : "warm");
+ x86_power_reset(is_cold);
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(x86reset, command_x86reset);