summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarthur.lin <arthur.lin@lcfc.corp-partner.google.com>2022-01-13 11:16:48 +0800
committerCommit Bot <commit-bot@chromium.org>2022-02-26 14:51:39 +0000
commitebf0318eafd2c50d31a8b84a81c371c5de3851a6 (patch)
tree010b641fe94886819363b40aa2d8eeea9ade5aca
parent1e194f6d1a1d821e625f86f38864b2ed1c347263 (diff)
downloadchrome-ec-ebf0318eafd2c50d31a8b84a81c371c5de3851a6.tar.gz
treeya: add psl code back for some sku request
Add the the PSL code to the treeya's board.c file, and use sku id to distinguish for enter PSL or not. BUG=b:214155147 BRANCH=None TEST=make buildall -j In Treeya360, keep KSI1, KSI2, and KSI3 on when system in hibernate Cq-Depend: chromium:3325632 Signed-off-by: arthur.lin <arthur.lin@lcfc.corp-partner.google.com> Change-Id: I9877bda5024964e83797cdf2cb6301c59886d68f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3384980 Reviewed-by: Martin Roth <martinroth@google.com> Commit-Queue: Martin Roth <martinroth@google.com> (cherry picked from commit eecb83f9ba22f7c65d054dbdc6d0c2b16fe7f7dd) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3487375
-rw-r--r--board/treeya/board.c98
1 files changed, 96 insertions, 2 deletions
diff --git a/board/treeya/board.c b/board/treeya/board.c
index 58ae880a89..5d9430689e 100644
--- a/board/treeya/board.c
+++ b/board/treeya/board.c
@@ -19,9 +19,12 @@
#include "switch.h"
#include "tablet_mode.h"
#include "task.h"
+#include "system_chip.h"
#include "gpio_list.h"
+static uint8_t is_psl_hibernate;
+
const enum gpio_signal hibernate_wake_pins[] = {
GPIO_LID_OPEN,
GPIO_AC_PRESENT,
@@ -163,6 +166,8 @@ static int board_use_st_sensor(void)
*/
void board_update_sensor_config_from_sku(void)
{
+ uint32_t sku_id = system_get_sku_id();
+
if (board_is_convertible()) {
/* sku_id a8-a9 use ST sensors */
if (board_use_st_sensor()) {
@@ -185,6 +190,13 @@ void board_update_sensor_config_from_sku(void)
gpio_set_flags(GPIO_6AXIS_INT_L,
GPIO_INPUT | GPIO_PULL_DOWN);
}
+
+ if (sku_id == 160 || sku_id == 168 || sku_id == 169 ||
+ sku_id == 190 || sku_id == 191) {
+ is_psl_hibernate = 0;
+ } else {
+ is_psl_hibernate = 1;
+ }
}
/* bmi160 or lsm6dsm need differenct interrupt function */
@@ -195,10 +207,92 @@ void board_bmi160_lsm6dsm_interrupt(enum gpio_signal signal)
else
bmi160_interrupt(signal);
}
-
#endif
+static void system_psl_type_sel(int psl_no, uint32_t flags)
+{
+ /* Set PSL input events' type as level or edge trigger */
+ if ((flags & GPIO_INT_F_HIGH) || (flags & GPIO_INT_F_LOW))
+ CLEAR_BIT(NPCX_GLUE_PSL_CTS, psl_no + 4);
+ else if ((flags & GPIO_INT_F_RISING) || (flags & GPIO_INT_F_FALLING))
+ SET_BIT(NPCX_GLUE_PSL_CTS, psl_no + 4);
+
+ /*
+ * Set PSL input events' polarity is low (high-to-low) active or
+ * high (low-to-high) active
+ */
+ if (flags & GPIO_HIB_WAKE_HIGH)
+ SET_BIT(NPCX_DEVALT(ALT_GROUP_D), 2 * psl_no);
+ else
+ CLEAR_BIT(NPCX_DEVALT(ALT_GROUP_D), 2 * psl_no);
+}
+
+int system_config_psl_mode(enum gpio_signal signal)
+{
+ int psl_no;
+ const struct gpio_info *g = gpio_list + signal;
+
+ if (g->port == GPIO_PORT_D && g->mask == MASK_PIN2) /* GPIOD2 */
+ psl_no = 0;
+ else if (g->port == GPIO_PORT_0 && (g->mask & 0x07)) /* GPIO00/01/02 */
+ psl_no = GPIO_MASK_TO_NUM(g->mask) + 1;
+ else
+ return 0;
+
+ system_psl_type_sel(psl_no, g->flags);
+ return 1;
+}
+
+void system_enter_psl_mode(void)
+{
+ /* Configure pins from GPIOs to PSL which rely on VSBY power rail. */
+ gpio_config_module(MODULE_PMU, 1);
+
+ /*
+ * Only PSL_IN events can pull PSL_OUT to high and reboot ec.
+ * We should treat it as wake-up pin reset.
+ */
+ NPCX_BBRAM(BBRM_DATA_INDEX_WAKE) = HIBERNATE_WAKE_PIN;
+
+ /*
+ * Pull PSL_OUT (GPIO85) to low to cut off ec's VCC power rail by
+ * setting bit 5 of PDOUT(8).
+ */
+ SET_BIT(NPCX_PDOUT(GPIO_PORT_8), 5);
+}
+
+/* Hibernate function implemented by PSL (Power Switch Logic) mode. */
+void __keep __attribute__ ((noreturn)) __enter_hibernate_in_psl(void)
+{
+ system_enter_psl_mode();
+ /* Spin and wait for PSL cuts power; should never return */
+ while (1)
+ ;
+}
+
void board_hibernate_late(void)
{
- NPCX_KBSINPU = 0x0A;
+ int i;
+
+ /*
+ * If the SKU cannot use PSL hibernate, immediately return to go the
+ * non-PSL hibernate flow.
+ */
+ if (!is_psl_hibernate) {
+ NPCX_KBSINPU = 0x0A;
+ return;
+ }
+
+ for (i = 0; i < hibernate_wake_pins_used; i++) {
+ /* Config PSL pins setting for wake-up inputs */
+ if (!system_config_psl_mode(hibernate_wake_pins[i]))
+ ccprintf("Invalid PSL setting in wake-up pin %d\n", i);
+ }
+
+ /* Clear all pending IRQ otherwise wfi will have no affect */
+ for (i = NPCX_IRQ_0 ; i < NPCX_IRQ_COUNT ; i++)
+ task_clear_pending_irq(i);
+
+ __enter_hibernate_in_psl();
}
+