diff --git a/board/slippy/board.c b/board/slippy/board.c index b170382cec..aa77c2e5e4 100644 --- a/board/slippy/board.c +++ b/board/slippy/board.c @@ -25,67 +25,66 @@ /* GPIO signal list. Must match order from enum gpio_signal. */ const struct gpio_info gpio_list[GPIO_COUNT] = { /* Inputs with interrupt handlers are first for efficiency */ - {"POWER_BUTTON_L", LM4_GPIO_K, (1<<7), GPIO_INT_BOTH, + {"POWER_BUTTON_L", LM4_GPIO_A, (1<<2), GPIO_INT_BOTH, switch_interrupt}, - {"LID_OPEN", LM4_GPIO_K, (1<<5), GPIO_INT_BOTH, + {"LID_OPEN", LM4_GPIO_A, (1<<3), GPIO_INT_BOTH, lid_interrupt}, - /* Other inputs */ - {"THERMAL_DATA_READY_L", LM4_GPIO_B, (1<<4), 0, NULL}, {"AC_PRESENT", LM4_GPIO_H, (1<<3), GPIO_INT_BOTH, extpower_interrupt}, - {"BOARD_VERSION1", LM4_GPIO_H, (1<<6), 0, NULL}, - {"BOARD_VERSION2", LM4_GPIO_L, (1<<6), 0, NULL}, - {"BOARD_VERSION3", LM4_GPIO_L, (1<<7), 0, NULL}, - {"PCH_BKLTEN", LM4_GPIO_J, (1<<3), GPIO_INT_BOTH, + {"PCH_BKLTEN", LM4_GPIO_M, (1<<3), GPIO_INT_BOTH, switch_interrupt}, - {"PCH_SLP_A_L", LM4_GPIO_G, (1<<5), GPIO_INT_BOTH, + {"PCH_SLP_S0_L", LM4_GPIO_G, (1<<6), GPIO_INT_BOTH, x86_power_interrupt}, - {"PCH_SLP_ME_CSW_DEV_L", LM4_GPIO_G, (1<<4), GPIO_INT_BOTH, + {"PCH_SLP_S3_L", LM4_GPIO_G, (1<<7), GPIO_INT_BOTH, x86_power_interrupt}, - {"PCH_SLP_S3_L", LM4_GPIO_J, (1<<0), GPIO_INT_BOTH, - x86_power_interrupt}, - {"PCH_SLP_S4_L", LM4_GPIO_J, (1<<1), GPIO_INT_BOTH, - x86_power_interrupt}, - {"PCH_SLP_S5_L", LM4_GPIO_J, (1<<2), GPIO_INT_BOTH, + {"PCH_SLP_S5_L", LM4_GPIO_H, (1<<1), GPIO_INT_BOTH, x86_power_interrupt}, {"PCH_SLP_SUS_L", LM4_GPIO_G, (1<<3), GPIO_INT_BOTH, x86_power_interrupt}, {"PCH_SUSWARN_L", LM4_GPIO_G, (1<<2), GPIO_INT_BOTH, x86_power_interrupt}, - {"PGOOD_1_5V_DDR", LM4_GPIO_K, (1<<0), GPIO_INT_BOTH, + {"PP1050_PGOOD", LM4_GPIO_H, (1<<4), GPIO_INT_BOTH, x86_power_interrupt}, - {"PGOOD_1_5V_PCH", LM4_GPIO_K, (1<<1), GPIO_INT_BOTH, + {"PP1350_PGOOD", LM4_GPIO_H, (1<<6), GPIO_INT_BOTH, x86_power_interrupt}, - {"PGOOD_1_8VS", LM4_GPIO_K, (1<<3), GPIO_INT_BOTH, + {"PP5000_PGOOD", LM4_GPIO_N, (1<<0), GPIO_INT_BOTH, x86_power_interrupt}, - {"PGOOD_5VALW", LM4_GPIO_H, (1<<0), GPIO_INT_BOTH, + {"VCORE_PGOOD", LM4_GPIO_C, (1<<6), GPIO_INT_BOTH, x86_power_interrupt}, - {"PGOOD_CPU_CORE", LM4_GPIO_M, (1<<3), GPIO_INT_BOTH, + {"CPU_PGOOD", LM4_GPIO_C, (1<<4), GPIO_INT_BOTH, x86_power_interrupt}, - {"PGOOD_VCCP", LM4_GPIO_K, (1<<2), GPIO_INT_BOTH, + {"PCH_EDP_VDD_EN", LM4_GPIO_J, (1<<1), GPIO_INT_BOTH, x86_power_interrupt}, - {"PGOOD_VCCSA", LM4_GPIO_H, (1<<1), GPIO_INT_BOTH, - x86_power_interrupt}, - {"PGOOD_VGFX_CORE", LM4_GPIO_D, (1<<2), GPIO_INT_BOTH, - x86_power_interrupt}, - {"RECOVERY_L", LM4_GPIO_H, (1<<7), GPIO_INT_BOTH, + {"RECOVERY_L", LM4_GPIO_A, (1<<5), GPIO_INT_BOTH, switch_interrupt}, - {"USB1_STATUS_L", LM4_GPIO_E, (1<<7), 0, NULL}, - {"USB2_STATUS_L", LM4_GPIO_E, (1<<1), 0, NULL}, - {"WRITE_PROTECT", LM4_GPIO_J, (1<<4), GPIO_INT_BOTH, + {"WRITE_PROTECT", LM4_GPIO_A, (1<<4), GPIO_INT_BOTH, switch_interrupt}, + + /* Other inputs */ + {"FAN_ALERT_L", LM4_GPIO_B, (1<<0), GPIO_INPUT, NULL}, + {"USB1_OC_L", LM4_GPIO_E, (1<<7), GPIO_INPUT, NULL}, + {"USB2_OC_L", LM4_GPIO_E, (1<<0), GPIO_INPUT, NULL}, + {"BOARD_VERSION1", LM4_GPIO_Q, (1<<5), GPIO_INPUT, NULL}, + {"BOARD_VERSION2", LM4_GPIO_Q, (1<<6), GPIO_INPUT, NULL}, + {"BOARD_VERSION3", LM4_GPIO_Q, (1<<7), GPIO_INPUT, NULL}, + /* Outputs; all unasserted by default except for reset signals */ - {"CPU_PROCHOT", LM4_GPIO_F, (1<<2), GPIO_OUT_LOW, NULL}, - {"ENABLE_1_5V_DDR", LM4_GPIO_H, (1<<5), GPIO_OUT_LOW, NULL}, - {"ENABLE_5VALW", LM4_GPIO_K, (1<<4), GPIO_OUT_HIGH, NULL}, - {"ENABLE_BACKLIGHT", LM4_GPIO_H, (1<<4), GPIO_OUT_LOW, NULL}, - {"ENABLE_TOUCHPAD", LM4_GPIO_C, (1<<6), GPIO_OUT_LOW, NULL}, - {"ENABLE_VCORE", LM4_GPIO_F, (1<<7), GPIO_OUT_LOW, NULL}, - {"ENABLE_VS", LM4_GPIO_G, (1<<6), GPIO_OUT_LOW, NULL}, - {"ENABLE_WLAN", LM4_GPIO_Q, (1<<5), GPIO_OUT_LOW, NULL}, - {"ENTERING_RW", LM4_GPIO_J, (1<<5), GPIO_OUT_LOW, NULL}, - {"LIGHTBAR_RESET_L", LM4_GPIO_B, (1<<1), GPIO_OUT_LOW, NULL}, - {"PCH_A20GATE", LM4_GPIO_Q, (1<<6), GPIO_OUT_LOW, NULL}, + {"CPU_PROCHOT", LM4_GPIO_B, (1<<1), GPIO_OUT_LOW, NULL}, + {"PP1350_EN", LM4_GPIO_H, (1<<5), GPIO_OUT_LOW, NULL}, + {"PP3300_DSW_GATED_EN", LM4_GPIO_J, (1<<3), GPIO_OUT_LOW, NULL}, + {"PP3300_DX_EN", LM4_GPIO_J, (1<<2), GPIO_OUT_LOW, NULL}, + {"PP3300_LTE_EN", LM4_GPIO_D, (1<<2), GPIO_OUT_LOW, NULL}, + {"PP3300_WLAN_EN", LM4_GPIO_J, (1<<0), GPIO_OUT_LOW, NULL}, + {"SUSP_VR_EN", LM4_GPIO_C, (1<<7), GPIO_OUT_LOW, NULL}, + {"VCORE_EN", LM4_GPIO_C, (1<<5), GPIO_OUT_LOW, NULL}, + {"PP5000_EN", LM4_GPIO_H, (1<<7), GPIO_OUT_LOW, NULL}, + {"SYS_PWROK", LM4_GPIO_H, (1<<2), GPIO_OUT_LOW, NULL}, + {"WLAN_OFF_L", LM4_GPIO_J, (1<<4), GPIO_OUT_LOW, NULL}, + {"CHARGE_L", LM4_GPIO_E, (1<<6), GPIO_OUT_LOW, NULL}, + + {"ENABLE_BACKLIGHT", LM4_GPIO_M, (1<<7), GPIO_OUT_LOW, NULL}, + {"ENABLE_TOUCHPAD", LM4_GPIO_N, (1<<1), GPIO_OUT_LOW, NULL}, + {"ENTERING_RW", LM4_GPIO_D, (1<<3), GPIO_OUT_LOW, NULL}, {"PCH_DPWROK", LM4_GPIO_G, (1<<0), GPIO_OUT_LOW, NULL}, /* * HDA_SDO is technically an output, but we need to leave it as an @@ -93,29 +92,23 @@ const struct gpio_info gpio_list[GPIO_COUNT] = { */ {"PCH_HDA_SDO", LM4_GPIO_G, (1<<1), GPIO_INPUT, NULL}, {"PCH_WAKE_L", LM4_GPIO_F, (1<<0), GPIO_OUT_HIGH, NULL}, - {"PCH_NMI_L", LM4_GPIO_M, (1<<2), GPIO_OUT_HIGH, NULL}, - {"PCH_PWRBTN_L", LM4_GPIO_G, (1<<7), GPIO_OUT_HIGH, NULL}, + {"PCH_NMI_L", LM4_GPIO_F, (1<<2), GPIO_OUT_HIGH, NULL}, + {"PCH_PWRBTN_L", LM4_GPIO_H, (1<<0), GPIO_OUT_HIGH, NULL}, {"PCH_PWROK", LM4_GPIO_F, (1<<5), GPIO_OUT_LOW, NULL}, - {"PCH_RCIN_L", LM4_GPIO_Q, (1<<7), GPIO_HI_Z, NULL}, + {"PCH_RCIN_L", LM4_GPIO_L, (1<<6), GPIO_HI_Z, NULL}, {"PCH_RSMRST_L", LM4_GPIO_F, (1<<1), GPIO_OUT_LOW, NULL}, - {"PCH_RTCRST_L", LM4_GPIO_F, (1<<6), GPIO_HI_Z, NULL}, {"PCH_SMI_L", LM4_GPIO_F, (1<<4), GPIO_OUT_HIGH, NULL}, - {"PCH_SRTCRST_L", LM4_GPIO_C, (1<<7), GPIO_HI_Z, NULL}, - {"PCH_SUSACK_L", LM4_GPIO_F, (1<<3), GPIO_OUT_HIGH, NULL}, - {"RADIO_ENABLE_WLAN", LM4_GPIO_D, (1<<0), GPIO_OUT_LOW, NULL}, - {"RADIO_ENABLE_BT", LM4_GPIO_D, (1<<1), GPIO_OUT_LOW, NULL}, - {"SPI_CS_L", LM4_GPIO_A, (1<<3), GPIO_HI_Z, NULL}, - {"TOUCHSCREEN_RESET_L", LM4_GPIO_B, (1<<0), GPIO_OUT_LOW, NULL}, - {"USB1_CTL1", LM4_GPIO_E, (1<<2), GPIO_OUT_LOW, NULL}, - {"USB1_CTL2", LM4_GPIO_E, (1<<3), GPIO_OUT_LOW, NULL}, - {"USB1_CTL3", LM4_GPIO_E, (1<<4), GPIO_OUT_LOW, NULL}, - {"USB1_ENABLE", LM4_GPIO_E, (1<<5), GPIO_OUT_LOW, NULL}, - {"USB1_ILIM_SEL", LM4_GPIO_E, (1<<6), GPIO_OUT_LOW, NULL}, - {"USB2_CTL1", LM4_GPIO_D, (1<<4), GPIO_OUT_LOW, NULL}, - {"USB2_CTL2", LM4_GPIO_D, (1<<5), GPIO_OUT_LOW, NULL}, - {"USB2_CTL3", LM4_GPIO_D, (1<<6), GPIO_OUT_LOW, NULL}, - {"USB2_ENABLE", LM4_GPIO_D, (1<<7), GPIO_OUT_LOW, NULL}, - {"USB2_ILIM_SEL", LM4_GPIO_E, (1<<0), GPIO_OUT_LOW, NULL}, + {"TOUCHSCREEN_RESET_L", LM4_GPIO_N, (1<<7), GPIO_OUT_LOW, NULL}, + {"EC_EDP_VDD_EN", LM4_GPIO_J, (1<<5), GPIO_OUT_LOW, NULL}, + + {"LPC_CLKRUN_L", LM4_GPIO_M, (1<<2), GPIO_OUT_HIGH, NULL}, + {"USB1_ENABLE", LM4_GPIO_E, (1<<4), GPIO_OUT_LOW, NULL}, + {"USB2_ENABLE", LM4_GPIO_D, (1<<5), GPIO_OUT_LOW, NULL}, + + /* {"PCH_SUSACK_L", LM4_GPIO_F, (1<<3), GPIO_INPUT, NULL}, */ + {"PCH_CATERR_L", LM4_GPIO_F, (1<<3), GPIO_INPUT, NULL}, + {"PCH_RTCRST_L", LM4_GPIO_F, (1<<6), GPIO_INPUT, NULL}, + {"PCH_SRTCRST_L", LM4_GPIO_F, (1<<7), GPIO_INPUT, NULL}, }; /* ADC channels. Must be in the exactly same order as in enum adc_channel. */ diff --git a/board/slippy/board.h b/board/slippy/board.h index 1c268f6641..93b0b187b9 100644 --- a/board/slippy/board.h +++ b/board/slippy/board.h @@ -65,71 +65,68 @@ enum gpio_signal { /* Inputs with interrupt handlers are first for efficiency */ GPIO_POWER_BUTTON_L = 0, /* Power button */ GPIO_LID_OPEN, /* Lid switch */ - GPIO_THERMAL_DATA_READY_L, /* Data ready from I2C thermal sensor */ - /* Other inputs */ GPIO_AC_PRESENT, /* AC power present */ - GPIO_BOARD_VERSION1, /* Board version stuffing resistor 1 */ - GPIO_BOARD_VERSION2, /* Board version stuffing resistor 2 */ - GPIO_BOARD_VERSION3, /* Board version stuffing resistor 3 */ GPIO_PCH_BKLTEN, /* Backlight enable signal from PCH */ - GPIO_PCH_SLP_A_L, /* SLP_A# signal from PCH */ - GPIO_PCH_SLP_ME_CSW_DEV_L, /* SLP_ME_CSW_DEV# signal from PCH */ + GPIO_PCH_SLP_S0_L, /* SLP_S0# signal from PCH */ GPIO_PCH_SLP_S3_L, /* SLP_S3# signal from PCH */ - GPIO_PCH_SLP_S4_L, /* SLP_S4# signal from PCH */ GPIO_PCH_SLP_S5_L, /* SLP_S5# signal from PCH */ GPIO_PCH_SLP_SUS_L, /* SLP_SUS# signal from PCH */ GPIO_PCH_SUSWARN_L, /* SUSWARN# signal from PCH */ - GPIO_PGOOD_1_5V_DDR, /* Power good on +1.5V_DDR */ - GPIO_PGOOD_1_5V_PCH, /* Power good on +1.5V_PCH */ - GPIO_PGOOD_1_8VS, /* Power good on +1.8VS */ - GPIO_PGOOD_5VALW, /* Power good on +5VALW */ - GPIO_PGOOD_CPU_CORE, /* Power good on +CPU_CORE */ - GPIO_PGOOD_VCCP, /* Power good on +VCCP */ - GPIO_PGOOD_VCCSA, /* Power good on +VCCSA */ - GPIO_PGOOD_VGFX_CORE, /* Power good on +VGFX_CORE */ + GPIO_PP1050_PGOOD, /* Power good on 1.05V */ + GPIO_PP1350_PGOOD, /* Power good on 1.35V (DRAM) */ + GPIO_PP5000_PGOOD, /* Power good on 5V */ + GPIO_VCORE_PGOOD, /* Power good on core VR */ + GPIO_CPU_PGOOD, /* Power good on CPU */ + GPIO_PCH_EDP_VDD_EN, /* PCH wants EDP enabled */ GPIO_RECOVERY_L, /* Recovery signal from servo */ - GPIO_USB1_STATUS_L, /* USB charger port 1 status output */ - GPIO_USB2_STATUS_L, /* USB charger port 2 status output */ GPIO_WRITE_PROTECT, /* Write protect input */ + + /* Other inputs */ + GPIO_FAN_ALERT_L, /* From thermal sensor */ + GPIO_USB1_OC_L, /* USB port overcurrent warning */ + GPIO_USB2_OC_L, /* USB port overcurrent warning */ + GPIO_BOARD_VERSION1, /* Board version stuffing resistor 1 */ + GPIO_BOARD_VERSION2, /* Board version stuffing resistor 2 */ + GPIO_BOARD_VERSION3, /* Board version stuffing resistor 3 */ + /* Outputs */ GPIO_CPU_PROCHOT, /* Force CPU to think it's overheated */ - GPIO_ENABLE_1_5V_DDR, /* Enable +1.5V_DDR supply */ - GPIO_ENABLE_5VALW, /* Enable +5V always on rail */ + GPIO_PP1350_EN, /* Enable 1.35V supply */ + GPIO_PP3300_DSW_GATED_EN, /* Enable DSW rails */ + GPIO_PP3300_DX_EN, /* Enable power to lots of peripherals */ + GPIO_PP3300_LTE_EN, /* Enable LTE radio */ + GPIO_PP3300_WLAN_EN, /* Enable WiFi radio */ + GPIO_SUSP_VR_EN, /* Enable 1.05V regulator */ + GPIO_VCORE_EN, /* Stuffing option - not connected */ + GPIO_PP5000_EN, /* Enable 5V supply */ + GPIO_SYS_PWROK, /* EC thinks everything is up and ready */ + GPIO_WLAN_OFF_L, /* Disable WiFi chip? Or just the radio? */ + GPIO_CHARGE_L, /* Allow battery to charge when on AC */ + GPIO_ENABLE_BACKLIGHT, /* Enable backlight power */ GPIO_ENABLE_TOUCHPAD, /* Enable touchpad power */ - GPIO_ENABLE_VCORE, /* Enable +CPU_CORE and +VGFX_CORE */ - GPIO_ENABLE_VS, /* Enable VS power supplies */ - GPIO_ENABLE_WLAN, /* Enable WLAN module power (+3VS_WLAN) */ GPIO_ENTERING_RW, /* Indicate when EC is entering RW code */ - GPIO_LIGHTBAR_RESET_L, /* Reset lightbar controllers */ - GPIO_PCH_A20GATE, /* A20GATE signal to PCH */ - GPIO_PCH_DPWROK, /* DPWROK signal to PCH */ + GPIO_PCH_DPWROK, /* Indicate when VccDSW is good */ + GPIO_PCH_HDA_SDO, /* HDA_SDO signal to PCH; when high, ME * ignores security descriptor */ - GPIO_PCH_WAKE_L, /* Wake signal output to PCH */ + GPIO_PCH_WAKE_L, /* Wake signal from EC to PCH */ GPIO_PCH_NMI_L, /* Non-maskable interrupt pin to PCH */ GPIO_PCH_PWRBTN_L, /* Power button output to PCH */ GPIO_PCH_PWROK, /* PWROK / APWROK signals to PCH */ - GPIO_PCH_RCIN_L, /* RCIN# signal to PCH */ + GPIO_PCH_RCIN_L, /* RCIN# line to PCH (for 8042 emulation) */ GPIO_PCH_RSMRST_L, /* Reset PCH resume power plane logic */ - GPIO_PCH_RTCRST_L, /* Reset PCH RTC well */ GPIO_PCH_SMI_L, /* System management interrupt to PCH */ - GPIO_PCH_SRTCRST_L, /* Reset PCH ME RTC well */ - GPIO_PCH_SUSACK_L, /* Acknowledge PCH SUSWARN# signal */ - GPIO_RADIO_ENABLE_WLAN, /* Enable WLAN radio */ - GPIO_RADIO_ENABLE_BT, /* Enable bluetooth radio */ - GPIO_SPI_CS_L, /* SPI chip select */ GPIO_TOUCHSCREEN_RESET_L, /* Reset touch screen */ - GPIO_USB1_CTL1, /* USB charger port 1 CTL1 output */ - GPIO_USB1_CTL2, /* USB charger port 1 CTL2 output */ - GPIO_USB1_CTL3, /* USB charger port 1 CTL3 output */ - GPIO_USB1_ENABLE, /* USB charger port 1 enable */ - GPIO_USB1_ILIM_SEL, /* USB charger port 1 ILIM_SEL output */ - GPIO_USB2_CTL1, /* USB charger port 2 CTL1 output */ - GPIO_USB2_CTL2, /* USB charger port 2 CTL2 output */ - GPIO_USB2_CTL3, /* USB charger port 2 CTL3 output */ - GPIO_USB2_ENABLE, /* USB charger port 2 enable */ - GPIO_USB2_ILIM_SEL, /* USB charger port 2 ILIM_SEL output */ + GPIO_EC_EDP_VDD_EN, /* Enable EDP (passthru from PCH) */ + GPOI_LPC_CLKRUN_L, /* Dunno. Probably important, though. */ + + GPIO_USB1_ENABLE, /* USB port 1 output power enable */ + GPIO_USB2_ENABLE, /* USB port 2 output power enable */ + + GPIO_PCH_CATERR_L, /* Wanted CATERR# from PCH, probably NC */ + GPIO_PCH_RTCRST_L, /* Not supposed to be here */ + GPIO_PCH_SRTCRST_L, /* Not supposed to be here */ /* Number of GPIOs; not an actual GPIO */ GPIO_COUNT diff --git a/common/x86_power_haswell.c b/common/x86_power_haswell.c index 469702b224..a29062d4e7 100644 --- a/common/x86_power_haswell.c +++ b/common/x86_power_haswell.c @@ -24,203 +24,13 @@ #define CPUTS(outstr) cputs(CC_CHIPSET, outstr) #define CPRINTF(format, args...) cprintf(CC_CHIPSET, format, ## args) -/* - * Default timeout in us; if we've been waiting this long for an input - * transition, just jump to the next state. - */ -#define DEFAULT_TIMEOUT SECOND - -/* Timeout for dropping back from S5 to G3 */ -#define S5_INACTIVITY_TIMEOUT (10 * SECOND) - -enum x86_state { - X86_G3 = 0, /* - * System is off (not technically all the - * way into G3, which means totally - * unpowered...) - */ - X86_S5, /* System is soft-off */ - X86_S3, /* Suspend; RAM on, processor is asleep */ - X86_S0, /* System is on */ - - /* Transitions */ - X86_G3S5, /* G3 -> S5 (at system init time) */ - X86_S5S3, /* S5 -> S3 */ - X86_S3S0, /* S3 -> S0 */ - X86_S0S3, /* S0 -> S3 */ - X86_S3S5, /* S3 -> S5 */ - X86_S5G3, /* S5 -> G3 */ -}; - -static const char * const state_names[] = { - "G3", - "S5", - "S3", - "S0", - "G3->S5", - "S5->S3", - "S3->S0", - "S0->S3", - "S3->S5", - "S5->G3", -}; - -/* Input state flags */ -#define IN_PGOOD_5VALW 0x0001 -#define IN_PGOOD_1_5V_DDR 0x0002 -#define IN_PGOOD_1_5V_PCH 0x0004 -#define IN_PGOOD_1_8VS 0x0008 -#define IN_PGOOD_VCCP 0x0010 -#define IN_PGOOD_VCCSA 0x0020 -#define IN_PGOOD_CPU_CORE 0x0040 -#define IN_PGOOD_VGFX_CORE 0x0080 -#define IN_PCH_SLP_S3n_DEASSERTED 0x0100 -#define IN_PCH_SLP_S4n_DEASSERTED 0x0200 -#define IN_PCH_SLP_S5n_DEASSERTED 0x0400 -#define IN_PCH_SLP_An_DEASSERTED 0x0800 -#define IN_PCH_SLP_SUSn_DEASSERTED 0x1000 -#define IN_PCH_SLP_MEn_DEASSERTED 0x2000 -#define IN_PCH_SUSWARNn_DEASSERTED 0x4000 -/* All always-on supplies */ -#define IN_PGOOD_ALWAYS_ON (IN_PGOOD_5VALW) -/* All non-core power rails */ -#define IN_PGOOD_ALL_NONCORE (IN_PGOOD_1_5V_DDR | IN_PGOOD_1_5V_PCH | \ - IN_PGOOD_1_8VS | IN_PGOOD_VCCP | IN_PGOOD_VCCSA) -/* All core power rails */ -#define IN_PGOOD_ALL_CORE (IN_PGOOD_CPU_CORE | IN_PGOOD_VGFX_CORE) -/* Rails required for S3 */ -#define IN_PGOOD_S3 (IN_PGOOD_ALWAYS_ON | IN_PGOOD_1_5V_DDR) -/* Rails required for S0 */ -#define IN_PGOOD_S0 (IN_PGOOD_ALWAYS_ON | IN_PGOOD_ALL_NONCORE) - -/* All PM_SLP signals from PCH deasserted */ -#define IN_ALL_PM_SLP_DEASSERTED (IN_PCH_SLP_S3n_DEASSERTED | \ - IN_PCH_SLP_S4n_DEASSERTED | \ - IN_PCH_SLP_S5n_DEASSERTED | \ - IN_PCH_SLP_An_DEASSERTED) -/* All inputs in the right state for S0 */ -#define IN_ALL_S0 (IN_PGOOD_ALWAYS_ON | IN_PGOOD_ALL_NONCORE | \ - IN_PGOOD_CPU_CORE | IN_ALL_PM_SLP_DEASSERTED) - -static enum x86_state state = X86_G3; /* Current state */ -static uint32_t in_signals; /* Current input signal states (IN_PGOOD_*) */ -static uint32_t in_want; /* Input signal state we're waiting for */ -static uint32_t in_debug; /* Signal values which print debug output */ -static int want_g3_exit; /* Should we exit the G3 state? */ -static int throttle_cpu; /* Throttle CPU? */ - -/* When did we enter G3? */ -static uint64_t last_shutdown_time; -/* Delay before go into hibernation in seconds*/ -static uint32_t hibernate_delay = 3600; /* 1 Hour */ - -/** - * Update input signal state. - */ -static void update_in_signals(void) -{ - uint32_t inew = 0; - int v; - - if (gpio_get_level(GPIO_PGOOD_5VALW)) - inew |= IN_PGOOD_5VALW; - - if (gpio_get_level(GPIO_PGOOD_1_5V_DDR)) - inew |= IN_PGOOD_1_5V_DDR; - if (gpio_get_level(GPIO_PGOOD_1_5V_PCH)) - inew |= IN_PGOOD_1_5V_PCH; - if (gpio_get_level(GPIO_PGOOD_1_8VS)) - inew |= IN_PGOOD_1_8VS; - if (gpio_get_level(GPIO_PGOOD_VCCP)) - inew |= IN_PGOOD_VCCP; - if (gpio_get_level(GPIO_PGOOD_VCCSA)) - inew |= IN_PGOOD_VCCSA; - - if (gpio_get_level(GPIO_PGOOD_CPU_CORE)) - inew |= IN_PGOOD_CPU_CORE; - if (gpio_get_level(GPIO_PGOOD_VGFX_CORE)) - inew |= IN_PGOOD_VGFX_CORE; - - if (gpio_get_level(GPIO_PCH_SLP_A_L)) - inew |= IN_PCH_SLP_An_DEASSERTED; - if (gpio_get_level(GPIO_PCH_SLP_S3_L)) - inew |= IN_PCH_SLP_S3n_DEASSERTED; - if (gpio_get_level(GPIO_PCH_SLP_S4_L)) - inew |= IN_PCH_SLP_S4n_DEASSERTED; - if (gpio_get_level(GPIO_PCH_SLP_S5_L)) - inew |= IN_PCH_SLP_S5n_DEASSERTED; - - if (gpio_get_level(GPIO_PCH_SLP_SUS_L)) - inew |= IN_PCH_SLP_SUSn_DEASSERTED; - if (gpio_get_level(GPIO_PCH_SLP_ME_CSW_DEV_L)) - inew |= IN_PCH_SLP_MEn_DEASSERTED; - - v = gpio_get_level(GPIO_PCH_SUSWARN_L); - if (v) - inew |= IN_PCH_SUSWARNn_DEASSERTED; - /* Copy SUSWARN# signal from PCH to SUSACK# */ - gpio_set_level(GPIO_PCH_SUSACK_L, v); - - if ((in_signals & in_debug) != (inew & in_debug)) - CPRINTF("[%T x86 in 0x%04x]\n", inew); - - in_signals = inew; -} - -/** - * Check for required inputs - * - * @param want Input flags which must be present (IN_*) - * - * @return Non-zero if all present; zero if a required signal is missing. - */ -static int have_all_in_signals(uint32_t want) -{ - if ((in_signals & want) == want) - return 1; - - CPRINTF("[%T x86 power lost input; wanted 0x%04x, got 0x%04x]\n", - want, in_signals & want); - - return 0; -} - -/** - * Wait for inputs to be present - * - * @param want Input flags which must be present (IN_*) - * - * @return EC_SUCCESS when all inputs are present, or ERROR_TIMEOUT if timeout - * before reaching the desired state. - */ -static int wait_in_signals(uint32_t want) -{ - in_want = want; - - while ((in_signals & in_want) != in_want) { - if (task_wait_event(DEFAULT_TIMEOUT) == TASK_EVENT_TIMER) { - update_in_signals(); - CPRINTF("[%T x86 power timeout on input; " - "wanted 0x%04x, got 0x%04x]\n", - in_want, in_signals & in_want); - return EC_ERROR_TIMEOUT; - } - /* - * TODO: should really shrink the remaining timeout if we woke - * up but didn't have all the signals we wanted. Also need to - * handle aborts if we're no longer in the same state we were - * when we started waiting. - */ - } - return EC_SUCCESS; -} /*****************************************************************************/ /* Chipset interface */ void chipset_force_shutdown(void) { - CPRINTF("[%T chipset force shutdown]\n"); + CPRINTF("[%T %s()]\n", __func__); /* * Force x86 off. This condition will reset once the state machine @@ -232,6 +42,7 @@ void chipset_force_shutdown(void) void chipset_reset(int cold_reset) { + CPRINTF("[%T %s(%d)]\n", __func__, cold_reset); if (cold_reset) { /* * Drop and restore PWROK. This causes the PCH to reboot, @@ -266,68 +77,19 @@ void chipset_reset(int cold_reset) int chipset_in_state(int state_mask) { - int need_mask = 0; - - /* - * TODO: what to do about state transitions? If the caller wants - * HARD_OFF|SOFT_OFF and we're in G3S5, we could still return - * non-zero. - */ - switch (state) { - case X86_G3: - need_mask = CHIPSET_STATE_HARD_OFF; - break; - case X86_G3S5: - case X86_S5G3: - /* - * In between hard and soft off states. Match only if caller - * will accept both. - */ - need_mask = CHIPSET_STATE_HARD_OFF | CHIPSET_STATE_SOFT_OFF; - break; - case X86_S5: - need_mask = CHIPSET_STATE_SOFT_OFF; - break; - case X86_S5S3: - case X86_S3S5: - need_mask = CHIPSET_STATE_SOFT_OFF | CHIPSET_STATE_SUSPEND; - break; - case X86_S3: - need_mask = CHIPSET_STATE_SUSPEND; - break; - case X86_S3S0: - case X86_S0S3: - need_mask = CHIPSET_STATE_SUSPEND | CHIPSET_STATE_ON; - break; - case X86_S0: - need_mask = CHIPSET_STATE_ON; - break; - } - - /* Return non-zero if all needed bits are present */ - return (state_mask & need_mask) == need_mask; + /* HEY - Hard code to off for now. Perhaps use a console command to + * manually specify certain states for the other tasks to look at. */ + return CHIPSET_STATE_HARD_OFF; } void chipset_exit_hard_off(void) { - /* If not in the hard-off state nor headed there, nothing to do */ - if (state != X86_G3 && state != X86_S5G3) - return; - - /* Set a flag to leave G3, then wake the task */ - want_g3_exit = 1; - - if (task_start_called()) - task_wake(TASK_ID_CHIPSET); + CPRINTF("[%T %s()]\n", __func__); } void chipset_throttle_cpu(int throttle) { - throttle_cpu = throttle; - - /* Immediately set throttling if CPU is on */ - if (state == X86_S0) - gpio_set_level(GPIO_CPU_PROCHOT, throttle); + CPRINTF("[%T %s(%d)]\n", __func__, throttle); } /*****************************************************************************/ @@ -335,8 +97,7 @@ void chipset_throttle_cpu(int throttle) static void x86_lid_change(void) { - /* Wake up the task to update power state */ - task_wake(TASK_ID_CHIPSET); + CPRINTF("[%T %s()]\n", __func__); } DECLARE_HOOK(HOOK_LID_CHANGE, x86_lid_change, HOOK_PRIO_DEFAULT); @@ -346,64 +107,32 @@ static void x86_power_ac_change(void) CPRINTF("[%T x86 AC on]\n"); } else { CPRINTF("[%T x86 AC off]\n"); - - if (state == X86_G3) { - last_shutdown_time = get_time().val; - task_wake(TASK_ID_CHIPSET); - } } } DECLARE_HOOK(HOOK_AC_CHANGE, x86_power_ac_change, HOOK_PRIO_DEFAULT); static void x86_power_init(void) { - /* Update input state */ - update_in_signals(); - in_want = 0; - - /* The initial state is G3. Set shut down timestamp to now. */ - last_shutdown_time = get_time().val; - - /* - * If we're switching between images without rebooting, see if the x86 - * is already powered on; if so, leave it there instead of cycling - * through G3. - */ - if (system_jumped_to_this_image()) { - if ((in_signals & IN_ALL_S0) == IN_ALL_S0) { - CPRINTF("[%T x86 already in S0]\n"); - state = X86_S0; - } else { - /* Force all signals to their G3 states */ - CPRINTF("[%T x86 forcing G3]\n"); - gpio_set_level(GPIO_PCH_PWROK, 0); - gpio_set_level(GPIO_ENABLE_VCORE, 0); - gpio_set_level(GPIO_ENABLE_VS, 0); - gpio_set_level(GPIO_ENABLE_TOUCHPAD, 0); - gpio_set_level(GPIO_TOUCHSCREEN_RESET_L, 0); - gpio_set_level(GPIO_ENABLE_1_5V_DDR, 0); - gpio_set_level(GPIO_PCH_RSMRST_L, 0); - gpio_set_level(GPIO_PCH_DPWROK, 0); - } - } + CPRINTF("[%T %s()]\n", __func__); /* Enable interrupts for our GPIOs */ + gpio_enable_interrupt(GPIO_POWER_BUTTON_L); + gpio_enable_interrupt(GPIO_LID_OPEN); + gpio_enable_interrupt(GPIO_AC_PRESENT); gpio_enable_interrupt(GPIO_PCH_BKLTEN); - gpio_enable_interrupt(GPIO_PCH_SLP_A_L); - gpio_enable_interrupt(GPIO_PCH_SLP_ME_CSW_DEV_L); + gpio_enable_interrupt(GPIO_PCH_SLP_S0_L); gpio_enable_interrupt(GPIO_PCH_SLP_S3_L); - gpio_enable_interrupt(GPIO_PCH_SLP_S4_L); gpio_enable_interrupt(GPIO_PCH_SLP_S5_L); gpio_enable_interrupt(GPIO_PCH_SLP_SUS_L); gpio_enable_interrupt(GPIO_PCH_SUSWARN_L); - gpio_enable_interrupt(GPIO_PGOOD_1_5V_DDR); - gpio_enable_interrupt(GPIO_PGOOD_1_5V_PCH); - gpio_enable_interrupt(GPIO_PGOOD_1_8VS); - gpio_enable_interrupt(GPIO_PGOOD_5VALW); - gpio_enable_interrupt(GPIO_PGOOD_CPU_CORE); - gpio_enable_interrupt(GPIO_PGOOD_VCCP); - gpio_enable_interrupt(GPIO_PGOOD_VCCSA); - gpio_enable_interrupt(GPIO_PGOOD_VGFX_CORE); + gpio_enable_interrupt(GPIO_PP1050_PGOOD); + gpio_enable_interrupt(GPIO_PP1350_PGOOD); + gpio_enable_interrupt(GPIO_PP5000_PGOOD); + gpio_enable_interrupt(GPIO_VCORE_PGOOD); + gpio_enable_interrupt(GPIO_CPU_PGOOD); + gpio_enable_interrupt(GPIO_PCH_EDP_VDD_EN); + gpio_enable_interrupt(GPIO_RECOVERY_L); + gpio_enable_interrupt(GPIO_WRITE_PROTECT); } DECLARE_HOOK(HOOK_INIT, x86_power_init, HOOK_PRIO_INIT_CHIPSET); @@ -412,11 +141,7 @@ DECLARE_HOOK(HOOK_INIT, x86_power_init, HOOK_PRIO_INIT_CHIPSET); void x86_power_interrupt(enum gpio_signal signal) { - /* Shadow signals and compare with our desired signal state. */ - update_in_signals(); - - /* Wake up the task */ - task_wake(TASK_ID_CHIPSET); + CPRINTF("[%T %s(%d)]\n", __func__, signal); } /*****************************************************************************/ @@ -424,345 +149,23 @@ void x86_power_interrupt(enum gpio_signal signal) void chipset_task(void) { - uint64_t time_now; - while (1) { - CPRINTF("[%T x86 power state %d = %s, in 0x%04x]\n", - state, state_names[state], in_signals); - - switch (state) { - case X86_G3: - if (want_g3_exit) { - want_g3_exit = 0; - state = X86_G3S5; - break; - } - - in_want = 0; - if (extpower_is_present()) - task_wait_event(-1); - else { - uint64_t target_time = last_shutdown_time + - hibernate_delay * 1000000ull; - time_now = get_time().val; - if (time_now > target_time) { - /* - * Time's up. Hibernate until wake pin - * asserted. - */ - CPRINTF("[%T x86 hibernating]\n"); - system_hibernate(0, 0); - } else { - uint64_t wait = target_time - time_now; - if (wait > TASK_MAX_WAIT_US) - wait = TASK_MAX_WAIT_US; - - /* Wait for a message */ - task_wait_event(wait); - } - } - - break; - - case X86_S5: - if (gpio_get_level(GPIO_PCH_SLP_S5_L) == 1) { - /* Power up to next state */ - state = X86_S5S3; - break; - } - - /* Wait for inactivity timeout */ - in_want = 0; - if (task_wait_event(S5_INACTIVITY_TIMEOUT) == - TASK_EVENT_TIMER) { - /* Drop to G3; wake not requested yet */ - want_g3_exit = 0; - state = X86_S5G3; - } - break; - - case X86_S3: - /* - * If lid is closed; hold touchscreen in reset to cut - * power usage. If lid is open, take touchscreen out - * of reset so it can wake the processor. - */ - gpio_set_level(GPIO_TOUCHSCREEN_RESET_L, lid_is_open()); - - /* Check for state transitions */ - if (!have_all_in_signals(IN_PGOOD_S3)) { - /* Required rail went away */ - chipset_force_shutdown(); - state = X86_S3S5; - break; - } else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 1) { - /* Power up to next state */ - state = X86_S3S0; - break; - } else if (gpio_get_level(GPIO_PCH_SLP_S5_L) == 0) { - /* Power down to next state */ - state = X86_S3S5; - break; - } - - /* Otherwise, steady state; wait for a message */ - in_want = 0; - task_wait_event(-1); - break; - - case X86_S0: - if (!have_all_in_signals(IN_PGOOD_S0)) { - /* Required rail went away */ - chipset_force_shutdown(); - state = X86_S0S3; - break; - } else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 0) { - /* Power down to next state */ - state = X86_S0S3; - break; - } - - /* Otherwise, steady state; wait for a message */ - in_want = 0; - task_wait_event(-1); - break; - - case X86_G3S5: - /* - * Wait 10ms after +3VALW good, since that powers - * VccDSW and VccSUS. - */ - msleep(10); - - /* Assert DPWROK, deassert RSMRST# */ - gpio_set_level(GPIO_PCH_DPWROK, 1); - gpio_set_level(GPIO_PCH_RSMRST_L, 1); - - /* Wait 5ms for SUSCLK to stabilize */ - msleep(5); - - state = X86_S5; - break; - - case X86_S5S3: - /* Wait for the always-on rails to be good */ - if (wait_in_signals(IN_PGOOD_ALWAYS_ON)) { - chipset_force_shutdown(); - state = X86_S5; - } - - /* - * Take lightbar out of reset, now that +5VALW is - * available and we won't leak +3VALW through the reset - * line. - */ - gpio_set_level(GPIO_LIGHTBAR_RESET_L, 1); - - /* Turn on power to RAM */ - gpio_set_level(GPIO_ENABLE_1_5V_DDR, 1); - if (wait_in_signals(IN_PGOOD_S3)) { - chipset_force_shutdown(); - state = X86_S5; - } - - /* - * Enable touchpad power so it can wake the system from - * suspend. - */ - gpio_set_level(GPIO_ENABLE_TOUCHPAD, 1); - - /* Call hooks now that rails are up */ - hook_notify(HOOK_CHIPSET_STARTUP); - - state = X86_S3; - break; - - case X86_S3S0: - /* Turn on power rails */ - gpio_set_level(GPIO_ENABLE_VS, 1); - - /* Enable WLAN */ - gpio_set_level(GPIO_ENABLE_WLAN, 1); - gpio_set_level(GPIO_RADIO_ENABLE_WLAN, 1); - gpio_set_level(GPIO_RADIO_ENABLE_BT, 1); - - /* - * Make sure touchscreen is out if reset (even if the - * lid is still closed); it may have been turned off if - * the lid was closed in S3. - */ - gpio_set_level(GPIO_TOUCHSCREEN_RESET_L, 1); - - /* Wait for non-core power rails good */ - if (wait_in_signals(IN_PGOOD_S0)) { - chipset_force_shutdown(); - gpio_set_level(GPIO_TOUCHSCREEN_RESET_L, 0); - gpio_set_level(GPIO_ENABLE_WLAN, 0); - gpio_set_level(GPIO_RADIO_ENABLE_WLAN, 0); - gpio_set_level(GPIO_RADIO_ENABLE_BT, 0); - gpio_set_level(GPIO_ENABLE_VS, 0); - state = X86_S3; - } - - /* - * Enable +CPU_CORE and +VGFX_CORE regulator. The CPU - * itself will request the supplies when it's ready. - */ - gpio_set_level(GPIO_ENABLE_VCORE, 1); - - /* Call hooks now that rails are up */ - hook_notify(HOOK_CHIPSET_RESUME); - - /* Wait 99ms after all voltages good */ - msleep(99); - - /* - * Throttle CPU if necessary. This should only be - * asserted when +VCCP is powered (it is by now). - */ - gpio_set_level(GPIO_CPU_PROCHOT, throttle_cpu); - - /* Set PCH_PWROK */ - gpio_set_level(GPIO_PCH_PWROK, 1); - - state = X86_S0; - break; - - case X86_S0S3: - /* Call hooks before we remove power rails */ - hook_notify(HOOK_CHIPSET_SUSPEND); - - /* Clear PCH_PWROK */ - gpio_set_level(GPIO_PCH_PWROK, 0); - - /* Wait 40ns */ - udelay(1); - - /* Disable +CPU_CORE and +VGFX_CORE */ - gpio_set_level(GPIO_ENABLE_VCORE, 0); - - /* Disable WLAN */ - gpio_set_level(GPIO_ENABLE_WLAN, 0); - gpio_set_level(GPIO_RADIO_ENABLE_WLAN, 0); - gpio_set_level(GPIO_RADIO_ENABLE_BT, 0); - - /* - * Deassert prochot since CPU is off and we're about - * to drop +VCCP. - */ - gpio_set_level(GPIO_CPU_PROCHOT, 0); - - /* Turn off power rails */ - gpio_set_level(GPIO_ENABLE_VS, 0); - - state = X86_S3; - break; - - case X86_S3S5: - /* Call hooks before we remove power rails */ - hook_notify(HOOK_CHIPSET_SHUTDOWN); - - /* Disable touchpad power */ - gpio_set_level(GPIO_ENABLE_TOUCHPAD, 0); - - /* Turn off power to RAM */ - gpio_set_level(GPIO_ENABLE_1_5V_DDR, 0); - - /* - * Put touchscreen and lightbar in reset, so we won't - * leak +3VALW through the reset line to chips powered - * by +5VALW. - * - * (Note that we're no longer powering down +5VALW due - * to crosbug.com/p/16600, but to minimize side effects - * of that change we'll still reset these components in - * S5.) - */ - gpio_set_level(GPIO_TOUCHSCREEN_RESET_L, 0); - gpio_set_level(GPIO_LIGHTBAR_RESET_L, 0); - - state = X86_S5; - break; - - case X86_S5G3: - /* Deassert DPWROK, assert RSMRST# */ - gpio_set_level(GPIO_PCH_DPWROK, 0); - gpio_set_level(GPIO_PCH_RSMRST_L, 0); - - /* Record the time we go into G3 */ - last_shutdown_time = get_time().val; - - state = X86_G3; - break; - } + CPRINTF("[%T %s()]\n", __func__); + /* do NOTHING until we know what we should do. */ + task_wait_event(-1); } } /*****************************************************************************/ /* Console commands */ -static int command_powerinfo(int argc, char **argv) +static int command_power(int argc, char **argv) { - /* - * Print x86 power state in same format as state machine. This is - * used by FAFT tests, so must match exactly. - */ - ccprintf("[%T x86 power state %d = %s, in 0x%04x]\n", - state, state_names[state], in_signals); - + ccprintf("No commands defined yet. Add some for bringup.\n"); return EC_SUCCESS; } -DECLARE_CONSOLE_COMMAND(powerinfo, command_powerinfo, +DECLARE_CONSOLE_COMMAND(power, command_power, NULL, - "Show current x86 power state", + "Manually drive power states for bringup", NULL); -static int command_x86indebug(int argc, char **argv) -{ - char *e; - - /* If one arg, set the mask */ - if (argc == 2) { - int m = strtoi(argv[1], &e, 0); - if (*e) - return EC_ERROR_PARAM1; - - in_debug = m; - } - - /* Print the mask */ - ccprintf("x86 in: 0x%04x\n", in_signals); - ccprintf("debug mask: 0x%04x\n", in_debug); - return EC_SUCCESS; -}; -DECLARE_CONSOLE_COMMAND(x86indebug, command_x86indebug, - "[mask]", - "Get/set x86 input debug mask", - NULL); - -static int command_hibernation_delay(int argc, char **argv) -{ - char *e; - uint32_t time_g3 = ((uint32_t)(get_time().val - last_shutdown_time)) - / SECOND; - - if (argc >= 2) { - uint32_t s = strtoi(argv[1], &e, 0); - if (*e) - return EC_ERROR_PARAM1; - - hibernate_delay = s; - } - - /* Print the current setting */ - ccprintf("Hibernation delay: %d s\n", hibernate_delay); - if (state == X86_G3 && !extpower_is_present()) { - ccprintf("Time G3: %d s\n", time_g3); - ccprintf("Time left: %d s\n", hibernate_delay - time_g3); - } - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(hibdelay, command_hibernation_delay, - "[sec]", - "Set the delay before going into hibernation", - NULL);