1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
/* 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 <x86_common_pwrseq.h>
#include <x86_non_dsx_common_pwrseq_sm_handler.h>
LOG_MODULE_DECLARE(ap_pwrseq, CONFIG_AP_PWRSEQ_LOG_LEVEL);
/**
* Determine the current state of the CPU from the
* power signals.
*/
enum power_states_ndsx chipset_pwr_seq_get_state(void)
{
power_signal_mask_t sig = power_get_signals();
/*
* Chip is shut down, G3 state.
*/
if ((sig & MASK_ALL_POWER_GOOD) == 0) {
LOG_DBG("All power rails off, G3 state");
return SYS_POWER_STATE_G3;
}
/*
* Not enough power rails up to read VW signals.
* Force a shutdown.
*/
if ((sig & MASK_VW_POWER) != VALUE_VW_POWER) {
LOG_ERR("Not enough power signals on (%#x), forcing shutdown",
sig);
ap_power_force_shutdown(AP_POWER_SHUTDOWN_G3);
return SYS_POWER_STATE_G3;
}
/*
* Enough power signals are up, so
* wait for virtual wire signals to become available.
* Not sure how long to wait? 5 seconds total.
*/
for (int delay = 0; delay < 500; k_msleep(10), delay++) {
#if defined(CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI_VW_SLP_S3)
if (power_signal_get(PWR_SLP_S3) < 0)
continue;
#endif
#if defined(CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI_VW_SLP_S4)
if (power_signal_get(PWR_SLP_S4) < 0)
continue;
#endif
#if defined(CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI_VW_SLP_S5)
if (power_signal_get(PWR_SLP_S5) < 0)
continue;
#endif
/*
* All signals valid.
*/
LOG_DBG("All VW signals valid after %d ms", delay * 10);
break;
}
/* Re-read the power signals */
sig = power_get_signals();
/*
* S0, all power OK, no suspend or sleep on.
*/
if ((sig & MASK_S0) == VALUE_S0) {
LOG_DBG("CPU in S0 state");
return SYS_POWER_STATE_S0;
}
/*
* S3, all power OK, PWR_SLP_S3 on.
*/
if ((sig & MASK_S3) == VALUE_S3) {
LOG_DBG("CPU in S3 state");
return SYS_POWER_STATE_S3;
}
/*
* S5, some power signals on, PWR_SLP_S5 on.
*/
if ((sig & MASK_S5) == VALUE_S5) {
LOG_DBG("CPU in S5 state");
return SYS_POWER_STATE_S5;
}
/*
* Unable to determine state, force to G3.
*/
LOG_INF("Unable to determine CPU state (%#x), forcing shutdown", sig);
ap_power_force_shutdown(AP_POWER_SHUTDOWN_G3);
return SYS_POWER_STATE_G3;
}
|