From 792e0a1de80d97cf9772e998ed84adb262dd12b0 Mon Sep 17 00:00:00 2001 From: Scott Collyer Date: Thu, 15 Aug 2019 15:01:42 -0700 Subject: cometlake: Minimize delay for high->low rsmrst passthrough Hatch designs buffer the PG_EC_RSMRST# signal from the Silego power good logic through the EC and out EC_PCH_RSMRST# to the SoC RSMRST# pin. For power off transitions, this should be as fast as possible, in the ns region if possible. However this time is ~1 msec. To reduce this delay as much as possible this CL introduces a new interrupt handler than can be linked to the rsmrst gpio signal. This interrupt routine handles high->low transitions directly to minimize the propagation delay. The power_signal_interrupt is then called which will wake up the chipset task, and low->high transistions continue to be handled in the power state machine. BUG=b:132421681 BRANCH=None TEST=Shorted PP1050_A_PG to ground to force an abrupt power down and then measured time via scope between PG_EC_RSMRST and EC_PCH_RSMRST. The delay is reduced from ~1 msec to 45 uSec. Change-Id: I266138a2e235ce47f3060f8e1f6f9bc6a75073ae Signed-off-by: Scott Collyer Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1757267 Tested-by: Scott Collyer Reviewed-by: Furquan Shaikh Commit-Queue: Scott Collyer --- include/power.h | 11 +++++++++++ power/intel_x86.c | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/power.h b/include/power.h index 60f071a1dc..fac596d44c 100644 --- a/include/power.h +++ b/include/power.h @@ -179,6 +179,17 @@ void power_signal_interrupt(enum gpio_signal signal); static inline void power_signal_interrupt(enum gpio_signal signal) { } #endif /* !HAS_TASK_CHIPSET */ +/** + * Interrupt handler for rsmrst signal GPIO. This interrupt handler should be + * used when there is a requirement to have minimum pass through delay between + * the rsmrst coming to the EC and the rsmrst that goes to the PCH for high->low + * transitions. Low->high transitions are still handled from within the chipset + * task power state machine. + * + * @param signal - The gpio signal that triggered the interrupt. + */ +void intel_x86_rsmrst_signal_interrupt(enum gpio_signal signal); + /** * pause_in_s5 getter method. * diff --git a/power/intel_x86.c b/power/intel_x86.c index 093e9cbc1a..ace891c8b9 100644 --- a/power/intel_x86.c +++ b/power/intel_x86.c @@ -604,6 +604,25 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state) return state; } +void intel_x86_rsmrst_signal_interrupt(enum gpio_signal signal) +{ + int rsmrst_in = gpio_get_level(GPIO_RSMRST_L_PGOOD); + int rsmrst_out = gpio_get_level(GPIO_PCH_RSMRST_L); + + /* + * This function is called when rsmrst changes state. If rsmrst + * has been asserted (high -> low) then pass this new state to PCH. + */ + if (!rsmrst_in && (rsmrst_in != rsmrst_out)) + gpio_set_level(GPIO_PCH_RSMRST_L, rsmrst_in); + + /* + * Call the main power signal interrupt handler to wake up the chipset + * task which handles low->high rsmrst pass through. + */ + power_signal_interrupt(signal); +} + void common_intel_x86_handle_rsmrst(enum power_state state) { /* -- cgit v1.2.1