diff options
author | Divya Sasidharan <divya.s.sasidharan@intel.com> | 2022-01-10 15:34:35 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2022-02-15 03:42:11 +0000 |
commit | 7c1a85031b3dfb0577083f554104540594bde2da (patch) | |
tree | feed93d5d127ad8d62f848b4dd2460ae162c6f5c | |
parent | d059ea64ba23dff66392677367cf70c26e20cf6a (diff) | |
download | chrome-ec-7c1a85031b3dfb0577083f554104540594bde2da.tar.gz |
zephyr: subsys/ap_pwrseq: Add espi callback handling
Change of power signals over espi (SLP_S3/S4/S5) would
change the power sequence state machine.
BUG=b:203446068
BRANCH=None
TEST=zmake testall; verified prints to indicate SLP signal
changes during boot.
Change-Id: Icabcddfabf687470f5266a7d537343691877c198
Signed-off-by: Divya Sasidharan <divya.s.sasidharan@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3378975
Reviewed-by: Andrew McRae <amcrae@google.com>
6 files changed, 134 insertions, 0 deletions
diff --git a/zephyr/dts/bindings/power/intel,ap-pwrseq.yaml b/zephyr/dts/bindings/power/intel,ap-pwrseq.yaml index f584c19df7..ebc875814d 100644 --- a/zephyr/dts/bindings/power/intel,ap-pwrseq.yaml +++ b/zephyr/dts/bindings/power/intel,ap-pwrseq.yaml @@ -79,6 +79,13 @@ properties: description: | Timeout in ms for monitoring power signals. + pwrseq-espi-max-freq: + type: int + required: false + default: 20 + description: | + Maximum configured frequency for espi channel. + pg-ec-dsw-pwrok-gpios: type: phandle-array required: false diff --git a/zephyr/subsys/ap_pwrseq/CMakeLists.txt b/zephyr/subsys/ap_pwrseq/CMakeLists.txt index f08bb3e476..e4f5c6c3d3 100644 --- a/zephyr/subsys/ap_pwrseq/CMakeLists.txt +++ b/zephyr/subsys/ap_pwrseq/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_include_directories(include) zephyr_sources_ifdef(CONFIG_X86_NON_DSX_PWRSEQ x86_non_dsx_common_pwrseq_sm_handler.c) +zephyr_sources_ifdef(CONFIG_X86_NON_DSX_PWRSEQ x86_non_dsx_espi.c) zephyr_sources_ifdef(CONFIG_X86_NON_DSX_PWRSEQ_CONSOLE x86_non_dsx_common_pwrseq_console.c) zephyr_sources_ifdef(CONFIG_X86_NON_DSX_PWRSEQ_ADL x86_non_dsx_adlp_pwrseq_sm.c) diff --git a/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_common_pwrseq_sm_handler.h b/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_common_pwrseq_sm_handler.h index fe1aae194f..51c1c17a6c 100644 --- a/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_common_pwrseq_sm_handler.h +++ b/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_common_pwrseq_sm_handler.h @@ -7,6 +7,8 @@ #define __X86_NON_DSX_COMMON_PWRSEQ_SM_HANDLER_H__ #include <x86_common_pwrseq.h> +#include <x86_non_dsx_espi.h> +#include <zephyr/types.h> #define DT_DRV_COMPAT intel_ap_pwrseq #define INTEL_COM_POWER_NODE DT_INST(0, intel_ap_pwrseq) diff --git a/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_espi.h b/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_espi.h new file mode 100644 index 0000000000..72ee197d92 --- /dev/null +++ b/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_espi.h @@ -0,0 +1,21 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __X86_NON_DSX_ESPI_H__ +#define __X86_NON_DSX_ESPI_H__ + +/** + * @brief Configure eSPI channels for Non Deep Sleep well platforms + */ +void ndsx_espi_configure(void); + +/** + * @brief Return Virtual wire value + + * @retval Actual Virtual Wire value or 0 on failure + */ +uint8_t vw_get_level(enum espi_vwire_signal signal); + +#endif /* __NDSX_ESPI_H__ */ diff --git a/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_sm_handler.c b/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_sm_handler.c index 8c23b4de8a..c87dbc111d 100644 --- a/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_sm_handler.c +++ b/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_sm_handler.c @@ -292,6 +292,8 @@ static int pwrseq_init() /* Configure gpio from device tree */ pwrseq_gpio_init(); LOG_DBG("Done gpio init"); + /* Register espi handler */ + ndsx_espi_configure(); /* TODO: Define initial state of power sequence */ LOG_DBG("Init pwr seq state"); init_pwr_seq_state(); diff --git a/zephyr/subsys/ap_pwrseq/x86_non_dsx_espi.c b/zephyr/subsys/ap_pwrseq/x86_non_dsx_espi.c new file mode 100644 index 0000000000..9625adca57 --- /dev/null +++ b/zephyr/subsys/ap_pwrseq/x86_non_dsx_espi.c @@ -0,0 +1,101 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <drivers/espi.h> +#include <x86_non_dsx_espi.h> +#include <x86_non_dsx_common_pwrseq_sm_handler.h> + +LOG_MODULE_DECLARE(ap_pwrseq, 3); + +#define espi_dev DEVICE_DT_GET(DT_CHOSEN(intel_ap_pwrseq_espi)) + +struct espi_callback espi_bus_cb; +struct espi_callback espi_chan_cb; +struct espi_callback espi_vw_cb; + +static void espi_bus_vw_handler(const struct device *dev, + struct espi_callback *cb, + struct espi_event event) +{ + LOG_DBG("VW is triggered, event=%d, val=%d\n", event.evt_details, + vw_get_level(event.evt_details)); + + switch (event.evt_details) { + case ESPI_VWIRE_SIGNAL_SLP_S3: + case ESPI_VWIRE_SIGNAL_SLP_S4: + break; + default: + break; + } +} + +/* This should be overridden by the chipset */ +__attribute__((weak)) void espi_bus_reset(void) +{ + /* Do nothing */ +} + +static void espi_bus_reset_handler(const struct device *dev, + struct espi_callback *cb, + struct espi_event event) +{ + LOG_DBG("ESPI bus reset"); + espi_bus_reset(); +} + +static void espi_bus_channel_handler(const struct device *dev, + struct espi_callback *cb, + struct espi_event event) +{ + LOG_DBG("ESPI channel ready"); +} + +uint8_t vw_get_level(enum espi_vwire_signal signal) +{ + uint8_t level; + + if (espi_receive_vwire(espi_dev, signal, &level)) { + LOG_DBG("Espi: Failed to the espi GPIO level\n"); + return 0; + } + + LOG_DBG("Espi: GPIO level = %d\n", level); + return level; +} + +void ndsx_espi_configure(void) +{ + struct espi_cfg cfg = { + .io_caps = ESPI_IO_MODE_SINGLE_LINE, + .channel_caps = ESPI_CHANNEL_VWIRE | + ESPI_CHANNEL_PERIPHERAL | + ESPI_CHANNEL_OOB, + /* ESPI_FREQ_MHZ */ + .max_freq = DT_INST_PROP(0, pwrseq_espi_max_freq), + }; + + if (!device_is_ready(espi_dev)) { + LOG_ERR("Espi device is not ready"); + return; + } + + if (espi_config(espi_dev, &cfg)) { + LOG_ERR("Failed to configure eSPI"); + return; + } + + /* Configure handler for eSPI events */ + espi_init_callback(&espi_bus_cb, espi_bus_reset_handler, + ESPI_BUS_RESET); + espi_add_callback(espi_dev, &espi_bus_cb); + + espi_init_callback(&espi_chan_cb, espi_bus_channel_handler, + ESPI_BUS_EVENT_CHANNEL_READY); + espi_add_callback(espi_dev, &espi_chan_cb); + + espi_init_callback(&espi_vw_cb, espi_bus_vw_handler, + ESPI_BUS_EVENT_VWIRE_RECEIVED); + espi_add_callback(espi_dev, &espi_vw_cb); +} |