blob: 7b684598cb469b577fcee1ee68200b492fa9557f [file] [log] [blame]
/* Copyright 2012 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.
*/
/*
* Chipset module for Chrome EC.
*
* This is intended to be a platform/chipset-neutral interface, implemented by
* all main chipsets (x86, gaia, etc.).
*/
#ifndef __CROS_EC_CHIPSET_H
#define __CROS_EC_CHIPSET_H
#include "common.h"
#include "compile_time_macros.h"
#include "ec_commands.h"
#include "gpio.h"
#include "stddef.h"
/*
* Chipset state mask
*
* Note that this is a non-exhaustive list of states which the main chipset can
* be in, and is potentially one-to-many for real, underlying chipset states.
* That's why chipset_in_state() asks "Is the chipset in something
* approximating this state?" and not "Tell me what state the chipset is in and
* I'll compare it myself with the state(s) I want."
*/
enum chipset_state_mask {
CHIPSET_STATE_HARD_OFF = 0x01, /* Hard off (G3) */
CHIPSET_STATE_SOFT_OFF = 0x02, /* Soft off (S5) */
CHIPSET_STATE_SUSPEND = 0x04, /* Suspend (S3) */
CHIPSET_STATE_ON = 0x08, /* On (S0) */
CHIPSET_STATE_STANDBY = 0x10, /* Standby (S0ix) */
/* Common combinations */
CHIPSET_STATE_ANY_OFF = (CHIPSET_STATE_HARD_OFF |
CHIPSET_STATE_SOFT_OFF), /* Any off state */
/* This combination covers any kind of suspend i.e. S3 or S0ix. */
CHIPSET_STATE_ANY_SUSPEND = (CHIPSET_STATE_SUSPEND |
CHIPSET_STATE_STANDBY),
};
/*
* Reason codes used by the AP after a shutdown to figure out why it was reset
* by the EC. These are sent in EC commands. Therefore, to maintain protocol
* compatibility:
* - New entries must be inserted prior to the _COUNT field
* - If an existing entry is no longer in service, it must be replaced with a
* RESERVED entry instead.
* - The semantic meaning of an entry should not change.
* - Do not exceed 2^15 - 1 for reset reasons or 2^16 - 1 for shutdown reasons.
*/
enum chipset_reset_reason {
CHIPSET_RESET_BEGIN = 0,
CHIPSET_RESET_UNKNOWN = CHIPSET_RESET_BEGIN,
/* Custom reason defined by a board.c or baseboard.c file */
CHIPSET_RESET_BOARD_CUSTOM,
/* Believe that the AP has hung */
CHIPSET_RESET_HANG_REBOOT,
/* Reset by EC console command */
CHIPSET_RESET_CONSOLE_CMD,
/* Reset by EC host command */
CHIPSET_RESET_HOST_CMD,
/* Keyboard module reset key combination */
CHIPSET_RESET_KB_SYSRESET,
/* Keyboard module warm reboot */
CHIPSET_RESET_KB_WARM_REBOOT,
/* Debug module warm reboot */
CHIPSET_RESET_DBG_WARM_REBOOT,
/* I cannot self-terminate. You must lower me into the steel. */
CHIPSET_RESET_AP_REQ,
/* Reset as side-effect of startup sequence */
CHIPSET_RESET_INIT,
/* EC detected an AP watchdog event. */
CHIPSET_RESET_AP_WATCHDOG,
CHIPSET_RESET_COUNT,
};
/*
* Hard shutdowns are logged on the same path as resets.
*/
enum chipset_shutdown_reason {
CHIPSET_SHUTDOWN_BEGIN = BIT(15),
CHIPSET_SHUTDOWN_POWERFAIL = CHIPSET_SHUTDOWN_BEGIN,
/* Forcing a shutdown as part of EC initialization */
CHIPSET_SHUTDOWN_INIT,
/* Custom reason on a per-board basis. */
CHIPSET_SHUTDOWN_BOARD_CUSTOM,
/* This is a reason to inhibit startup, not cause shut down. */
CHIPSET_SHUTDOWN_BATTERY_INHIBIT,
/* A power_wait_signal is being asserted */
CHIPSET_SHUTDOWN_WAIT,
/* Critical battery level. */
CHIPSET_SHUTDOWN_BATTERY_CRIT,
/* Because you told me to. */
CHIPSET_SHUTDOWN_CONSOLE_CMD,
/* Forcing a shutdown to effect entry to G3. */
CHIPSET_SHUTDOWN_G3,
/* Force shutdown due to over-temperature. */
CHIPSET_SHUTDOWN_THERMAL,
/* Force a chipset shutdown from the power button through EC */
CHIPSET_SHUTDOWN_BUTTON,
CHIPSET_SHUTDOWN_COUNT,
};
enum critical_shutdown {
CRITICAL_SHUTDOWN_IGNORE,
CRITICAL_SHUTDOWN_HIBERNATE,
CRITICAL_SHUTDOWN_CUTOFF,
};
#ifdef HAS_TASK_CHIPSET
/**
* Check if chipset is in a given state.
*
* @param state_mask Combination of one or more CHIPSET_STATE_* flags.
*
* @return non-zero if the chipset is in one of the states specified in the
* mask.
*/
int chipset_in_state(int state_mask);
/**
* Check if chipset is in a given state or if the chipset task is currently
* transitioning to that state. For example, G3S5, S5, and S3S5 would all count
* as the S5 state.
*
* @param state_mask Combination of one or more CHIPSET_STATE_* flags.
*
* @return non-zero if the chipset is in one of the states specified in the
* mask.
*/
int chipset_in_or_transitioning_to_state(int state_mask);
/**
* Ask the chipset to exit the hard off state.
*
* Does nothing if the chipset has already left the state, or was not in the
* state to begin with.
*/
void chipset_exit_hard_off(void);
/* This is a private chipset-specific implementation for use only by
* throttle_ap() . Don't call this directly!
*/
void chipset_throttle_cpu(int throttle);
/**
* Immediately shut off power to main processor and chipset.
*
* This is intended for use when the system is too hot or battery power is
* critical.
*/
void chipset_force_shutdown(enum chipset_shutdown_reason reason);
/**
* Reset the CPU and/or chipset.
*/
void chipset_reset(enum chipset_reset_reason reason);
/**
* Interrupt handler to power GPIO inputs.
*/
void power_interrupt(enum gpio_signal signal);
/**
* Handle assert of eSPI_Reset# pin.
*/
void chipset_handle_espi_reset_assert(void);
/**
* Perform chipset pre-initialization work within the context of chipset task.
*/
void chipset_pre_init_callback(void);
#else /* !HAS_TASK_CHIPSET */
/* When no chipset is present, assume it is always off. */
static inline int chipset_in_state(int state_mask)
{
return state_mask & CHIPSET_STATE_ANY_OFF;
}
static inline int chipset_in_or_transitioning_to_state(int state_mask)
{
return state_mask & CHIPSET_STATE_ANY_OFF;
}
static inline void chipset_exit_hard_off(void) { }
static inline void chipset_throttle_cpu(int throttle) { }
static inline void chipset_force_shutdown(enum chipset_shutdown_reason reason)
{
}
static inline void chipset_reset(enum chipset_reset_reason reason) { }
static inline void power_interrupt(enum gpio_signal signal) { }
static inline void chipset_handle_espi_reset_assert(void) { }
static inline void chipset_handle_reboot(void) { }
static inline void chipset_reset_request_interrupt(enum gpio_signal signal) { }
static inline void chipset_warm_reset_interrupt(enum gpio_signal signal) { }
static inline void chipset_watchdog_interrupt(enum gpio_signal signal) { }
#endif /* !HAS_TASK_CHIPSET */
/**
* Optional chipset check if PLTRST# is valid.
*
* @return non-zero if PLTRST# is valid, 0 if invalid.
*/
int chipset_pltrst_is_valid(void) __attribute__((weak));
/**
* Execute chipset-specific reboot.
*/
void chipset_handle_reboot(void);
/**
* GPIO interrupt handler of reset request from AP.
*
* It is used in SDM845/MT8183 chipset power sequence.
*/
void chipset_reset_request_interrupt(enum gpio_signal signal);
/**
* GPIO interrupt handler of warm reset signal from servo or H1.
*
* It is used in SDM845 chipset power sequence.
*/
void chipset_warm_reset_interrupt(enum gpio_signal signal);
/**
* GPIO interrupt handler of watchdog from AP.
*
* It is used in MT8183 chipset, where it must be setup to trigger on falling
* edge only.
*/
void chipset_watchdog_interrupt(enum gpio_signal signal);
/**
* Callback which allows board to take custom action on G3 timer expiration
*
* @param last_shutdown_time Last shutdown time
* @param target Expiration time. Can be modified by board.
* @param now Current time
* @return Action to take
*/
__override_proto enum critical_shutdown board_system_is_idle(
uint64_t last_shutdown_time, uint64_t *target, uint64_t now);
#ifdef CONFIG_CMD_AP_RESET_LOG
/**
* Report that the AP is being reset to the reset log.
*/
void report_ap_reset(enum chipset_shutdown_reason reason);
/**
* Get statistics about AP resets.
*
* @param reset_log_entries Pointer to array of log entries.
* @param num_reset_log_entries Number of items in reset_log_entries.
* @param resets_since_ec_boot Number of AP resets since EC boot.
*/
test_mockable enum ec_error_list
get_ap_reset_stats(struct ap_reset_log_entry *reset_log_entries,
size_t num_reset_log_entries,
uint32_t *resets_since_ec_boot);
#else
static inline void report_ap_reset(enum chipset_shutdown_reason reason) { }
test_mockable_static_inline enum ec_error_list
get_ap_reset_stats(struct ap_reset_log_entry *reset_log_entries,
size_t num_reset_log_entries, uint32_t *resets_since_ec_boot)
{
return EC_SUCCESS;
}
#endif /* !CONFIG_CMD_AP_RESET_LOG */
#endif /* __CROS_EC_CHIPSET_H */
/**
* Initialize reset logs and next reset log.
*/
void init_reset_log(void);