Kyösti Mälkki has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/74524 )
Change subject: [WIP] ACPI: Add usb_charge_mode_from_gnvs() ......................................................................
[WIP] ACPI: Add usb_charge_mode_from_gnvs()
Used together with (old API?) of ChromeEC to control USB port power for S3/S4/S5 sleep states.
Change-Id: I7e6f37a023b0e9317dcf0355dfa70e28d51cdad9 Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- M src/acpi/acpi_pm.c M src/ec/google/chromeec/smihandler.c M src/ec/google/chromeec/smm.h M src/include/acpi/acpi_gnvs.h M src/mainboard/google/auron/smihandler.c M src/mainboard/google/butterfly/smihandler.c M src/mainboard/google/cyan/smihandler.c M src/mainboard/google/link/smihandler.c M src/mainboard/google/parrot/smihandler.c M src/mainboard/google/rambi/smihandler.c M src/mainboard/google/slippy/smihandler.c M src/mainboard/google/stout/smihandler.c M src/mainboard/intel/strago/smihandler.c 13 files changed, 104 insertions(+), 99 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/24/74524/1
diff --git a/src/acpi/acpi_pm.c b/src/acpi/acpi_pm.c index 40a3fbd..6786f44 100644 --- a/src/acpi/acpi_pm.c +++ b/src/acpi/acpi_pm.c @@ -59,3 +59,29 @@ } return 0; } + +#if CONFIG(ACPI_SOC_NVS) && ENV_SMM + +#include <acpi/acpi_gnvs.h> +#include <cpu/x86/smm.h> +#include <soc/nvs.h> + +void usb_charge_mode_from_gnvs(uint8_t slp_typ, bool *usb0_disable, bool *usb1_disable) +{ + if (!gnvs) + return; + + switch (slp_typ) { + case ACPI_S3: + *usb0_disable = (gnvs->s3u0 == 0); + *usb1_disable = (gnvs->s3u1 == 0); + break; + case ACPI_S4: /* from slippy */ + case ACPI_S5: + *usb0_disable = (gnvs->s5u0 == 0); + *usb1_disable = (gnvs->s5u1 == 0); + break; + } +} + +#endif diff --git a/src/ec/google/chromeec/smihandler.c b/src/ec/google/chromeec/smihandler.c index cd0cd4f..599a66e 100644 --- a/src/ec/google/chromeec/smihandler.c +++ b/src/ec/google/chromeec/smihandler.c @@ -45,6 +45,15 @@ ; }
+void chromeec_set_usb_charge_mode(bool u0disable, bool u1disable) +{ + if (u0disable) + google_chromeec_set_usb_charge_mode(0, USB_CHARGE_MODE_DISABLED); + + if (u1disable) + google_chromeec_set_usb_charge_mode(1, USB_CHARGE_MODE_DISABLED); +} + void chromeec_smi_sleep(int slp_type, uint64_t s3_mask, uint64_t s5_mask) { if (!google_chromeec_is_uhepi_supported()) { diff --git a/src/ec/google/chromeec/smm.h b/src/ec/google/chromeec/smm.h index 6f209a7..5baf213 100644 --- a/src/ec/google/chromeec/smm.h +++ b/src/ec/google/chromeec/smm.h @@ -8,6 +8,8 @@ /* Process all events from the EC when EC triggered an SMI#. */ void chromeec_smi_process_events(void);
+void chromeec_set_usb_charge_mode(bool u0disable, bool u1disable); + /* * Set wake masks according to sleep type, clear SCI and SMI masks, * and clear any pending events. diff --git a/src/include/acpi/acpi_gnvs.h b/src/include/acpi/acpi_gnvs.h index ef6ec29..fe6924f 100644 --- a/src/include/acpi/acpi_gnvs.h +++ b/src/include/acpi/acpi_gnvs.h @@ -18,6 +18,9 @@ static inline int acpi_reset_gnvs_for_wake(struct global_nvs **gnvs) { return -1; } #endif
+/* Return GNVS fields for USB0/1 disablement for S3/S4/S5 sleep states. */ +void usb_charge_mode_from_gnvs(uint8_t slp_typ, bool *usb0_disable, bool *usb1_disable); + /* * These functions populate the gnvs structure in acpi table. * Defined as weak in common acpi as gnvs structure definition is diff --git a/src/mainboard/google/auron/smihandler.c b/src/mainboard/google/auron/smihandler.c index 237a2b3..bba9fc23 100644 --- a/src/mainboard/google/auron/smihandler.c +++ b/src/mainboard/google/auron/smihandler.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */
#include <acpi/acpi.h> +#include <acpi/acpi_gnvs.h> #include <console/console.h> #include <cpu/x86/smm.h> #include <soc/pm.h> @@ -8,7 +9,6 @@ #include <ec/google/chromeec/smm.h> #include <southbridge/intel/lynxpoint/lp_gpio.h> #include <soc/iomap.h> -#include <soc/nvs.h> #include "ec.h" #include <variant/onboard.h>
@@ -35,29 +35,21 @@
void mainboard_smi_sleep(u8 slp_typ) { + bool u0disable = 0, u1disable = 0; + /* Disable USB charging if required */ + /* NOTE: s3u0 and s5u0 for usb0 also control usb1 here.*/ + usb_charge_mode_from_gnvs(slp_typ, &u0disable, &u1disable); + chromeec_set_usb_charge_mode(u0disable, u0disable); + switch (slp_typ) { case ACPI_S3: - if (gnvs->s3u0 == 0) { - google_chromeec_set_usb_charge_mode( - 0, USB_CHARGE_MODE_DISABLED); - google_chromeec_set_usb_charge_mode( - 1, USB_CHARGE_MODE_DISABLED); - } - mainboard_disable_gpios();
/* Enable wake events */ google_chromeec_set_wake_mask(MAINBOARD_EC_S3_WAKE_EVENTS); break; case ACPI_S5: - if (gnvs->s5u0 == 0) { - google_chromeec_set_usb_charge_mode( - 0, USB_CHARGE_MODE_DISABLED); - google_chromeec_set_usb_charge_mode( - 1, USB_CHARGE_MODE_DISABLED); - } - mainboard_disable_gpios();
/* Enable wake events */ diff --git a/src/mainboard/google/butterfly/smihandler.c b/src/mainboard/google/butterfly/smihandler.c index 23bd683..b72b7da 100644 --- a/src/mainboard/google/butterfly/smihandler.c +++ b/src/mainboard/google/butterfly/smihandler.c @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */
+#include <acpi/acpi_gnvs.h> #include <console/console.h> #include <cpu/x86/smm.h> -#include <soc/nvs.h> #include <southbridge/intel/bd82x6x/pch.h> #include <southbridge/intel/bd82x6x/me.h> #include <northbridge/intel/sandybridge/sandybridge.h> @@ -13,8 +13,11 @@
void mainboard_smi_sleep(u8 slp_typ) { + bool u0disable = 0, u1disable = 0; + /* Tell the EC to Enable USB power for S3 if requested */ - if (gnvs->s3u0 != 0 || gnvs->s3u1 != 0) + usb_charge_mode_from_gnvs(3, &u0disable, &u1disable); + if (!u0disable || !u1disable) ec_mem_write(EC_EC_PSW, ec_mem_read(EC_EC_PSW) | EC_PSW_USB);
/* Disable wake on USB, LAN & RTC */ diff --git a/src/mainboard/google/cyan/smihandler.c b/src/mainboard/google/cyan/smihandler.c index 8f06cf4..562a6bd 100644 --- a/src/mainboard/google/cyan/smihandler.c +++ b/src/mainboard/google/cyan/smihandler.c @@ -1,13 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0-only */
#include <acpi/acpi.h> +#include <acpi/acpi_gnvs.h> #include <device/mmio.h> #include <console/console.h> #include <cpu/x86/smm.h> #include "ec.h" #include <ec/google/chromeec/ec.h> #include <ec/google/chromeec/smm.h> -#include <soc/nvs.h> #include <soc/pm.h> #include <soc/gpio.h>
@@ -30,32 +30,22 @@
void mainboard_smi_sleep(uint8_t slp_typ) { + bool u0disable = 0, u1disable = 0; void *addr; uint32_t mask;
/* Disable USB charging if required */ + usb_charge_mode_from_gnvs(slp_typ, &u0disable, &u1disable); + chromeec_set_usb_charge_mode(u0disable, u1disable); + switch (slp_typ) { case ACPI_S3: - if (gnvs->s3u0 == 0) - google_chromeec_set_usb_charge_mode( - 0, USB_CHARGE_MODE_DISABLED); - if (gnvs->s3u1 == 0) - google_chromeec_set_usb_charge_mode( - 1, USB_CHARGE_MODE_DISABLED); - /* Enable wake events */ google_chromeec_set_wake_mask(MAINBOARD_EC_S3_WAKE_EVENTS); /* Enable wake pin in GPE block. */ enable_gpe(WAKE_GPIO_EN); break; case ACPI_S5: - if (gnvs->s5u0 == 0) - google_chromeec_set_usb_charge_mode( - 0, USB_CHARGE_MODE_DISABLED); - if (gnvs->s5u1 == 0) - google_chromeec_set_usb_charge_mode( - 1, USB_CHARGE_MODE_DISABLED); - /* Enable wake events */ google_chromeec_set_wake_mask(MAINBOARD_EC_S5_WAKE_EVENTS);
diff --git a/src/mainboard/google/link/smihandler.c b/src/mainboard/google/link/smihandler.c index 4a9dfb0..17ef23a 100644 --- a/src/mainboard/google/link/smihandler.c +++ b/src/mainboard/google/link/smihandler.c @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */
#include <acpi/acpi.h> +#include <acpi/acpi_gnvs.h> #include <console/console.h> #include <cpu/x86/smm.h> -#include <soc/nvs.h> #include <southbridge/intel/bd82x6x/pch.h> #include <southbridge/intel/bd82x6x/me.h> #include <northbridge/intel/sandybridge/sandybridge.h> @@ -21,25 +21,11 @@
void mainboard_smi_sleep(u8 slp_typ) { + bool u0disable = 0, u1disable = 0; + /* Disable USB charging if required */ - switch (slp_typ) { - case ACPI_S3: - if (gnvs->s3u0 == 0) - google_chromeec_set_usb_charge_mode( - 0, USB_CHARGE_MODE_DISABLED); - if (gnvs->s3u1 == 0) - google_chromeec_set_usb_charge_mode( - 1, USB_CHARGE_MODE_DISABLED); - break; - case ACPI_S5: - if (gnvs->s5u0 == 0) - google_chromeec_set_usb_charge_mode( - 0, USB_CHARGE_MODE_DISABLED); - if (gnvs->s5u1 == 0) - google_chromeec_set_usb_charge_mode( - 1, USB_CHARGE_MODE_DISABLED); - break; - } + usb_charge_mode_from_gnvs(slp_typ, &u0disable, &u1disable); + chromeec_set_usb_charge_mode(u0disable, u1disable);
/* Disable SCI and SMI events */ google_chromeec_set_smi_mask(0); diff --git a/src/mainboard/google/parrot/smihandler.c b/src/mainboard/google/parrot/smihandler.c index 7d519e3..08be5b0 100644 --- a/src/mainboard/google/parrot/smihandler.c +++ b/src/mainboard/google/parrot/smihandler.c @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */
+#include <acpi/acpi_gnvs.h> #include <console/console.h> #include <cpu/x86/smm.h> #include <halt.h> -#include <soc/nvs.h> #include <southbridge/intel/bd82x6x/pch.h> #include <southbridge/intel/bd82x6x/me.h> #include <southbridge/intel/common/pmutil.h> @@ -48,6 +48,8 @@
void mainboard_smi_sleep(u8 slp_typ) { + bool u0disable = 0, u1disable = 0; + /* Disable SCI and SMI events */
/* Clear pending events that may trigger immediate wake */ @@ -55,7 +57,8 @@ /* Enable wake events */
/* Tell the EC to Disable USB power */ - if (gnvs->s3u0 == 0 && gnvs->s3u1 == 0) { + usb_charge_mode_from_gnvs(3, &u0disable, &u1disable); + if (u0disable && u1disable) { ec_kbc_write_cmd(0x45); ec_kbc_write_ib(0xF2); } diff --git a/src/mainboard/google/rambi/smihandler.c b/src/mainboard/google/rambi/smihandler.c index 3eb1d1d..affa3b0 100644 --- a/src/mainboard/google/rambi/smihandler.c +++ b/src/mainboard/google/rambi/smihandler.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */
#include <acpi/acpi.h> +#include <acpi/acpi_gnvs.h> #include <console/console.h> #include <cpu/x86/smm.h>
@@ -8,7 +9,6 @@ #include <ec/google/chromeec/smm.h> #include "ec.h"
-#include <soc/nvs.h> #include <soc/pm.h>
/* The wake gpio is SUS_GPIO[0]. */ @@ -24,29 +24,20 @@
void mainboard_smi_sleep(uint8_t slp_typ) { + bool u0disable = 0, u1disable = 0; + /* Disable USB charging if required */ + usb_charge_mode_from_gnvs(slp_typ, &u0disable, &u1disable); + chromeec_set_usb_charge_mode(u0disable, u1disable); + switch (slp_typ) { case ACPI_S3: - if (gnvs->s3u0 == 0) - google_chromeec_set_usb_charge_mode( - 0, USB_CHARGE_MODE_DISABLED); - if (gnvs->s3u1 == 0) - google_chromeec_set_usb_charge_mode( - 1, USB_CHARGE_MODE_DISABLED); - /* Enable wake events */ google_chromeec_set_wake_mask(MAINBOARD_EC_S3_WAKE_EVENTS); /* Enable wake pin in GPE block. */ enable_gpe(WAKE_GPIO_EN); break; case ACPI_S5: - if (gnvs->s5u0 == 0) - google_chromeec_set_usb_charge_mode( - 0, USB_CHARGE_MODE_DISABLED); - if (gnvs->s5u1 == 0) - google_chromeec_set_usb_charge_mode( - 1, USB_CHARGE_MODE_DISABLED); - /* Enable wake events */ google_chromeec_set_wake_mask(MAINBOARD_EC_S5_WAKE_EVENTS); break; diff --git a/src/mainboard/google/slippy/smihandler.c b/src/mainboard/google/slippy/smihandler.c index 71e97af..3ac2152 100644 --- a/src/mainboard/google/slippy/smihandler.c +++ b/src/mainboard/google/slippy/smihandler.c @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */
#include <acpi/acpi.h> +#include <acpi/acpi_gnvs.h> #include <console/console.h> #include <cpu/x86/smm.h> -#include <soc/nvs.h> #include <southbridge/intel/lynxpoint/pch.h> #include <southbridge/intel/common/gpio.h> #include <southbridge/intel/lynxpoint/me.h> @@ -30,16 +30,14 @@
void mainboard_smi_sleep(u8 slp_typ) { + bool u0disable = 0, u1disable = 0; + /* Disable USB charging if required */ + usb_charge_mode_from_gnvs(slp_typ, &u0disable, &u1disable); + chromeec_set_usb_charge_mode(u0disable, u1disable); + switch (slp_typ) { case ACPI_S3: - if (gnvs->s3u0 == 0) - google_chromeec_set_usb_charge_mode( - 0, USB_CHARGE_MODE_DISABLED); - if (gnvs->s3u1 == 0) - google_chromeec_set_usb_charge_mode( - 1, USB_CHARGE_MODE_DISABLED); - /* Prevent leak from standby rail to WLAN rail in S3. */ set_gpio(GPIO_WLAN_DISABLE_L, 0); set_gpio(GPIO_PP3300_CODEC_EN, 0); @@ -51,13 +49,6 @@ break; case ACPI_S4: case ACPI_S5: - if (gnvs->s5u0 == 0) - google_chromeec_set_usb_charge_mode( - 0, USB_CHARGE_MODE_DISABLED); - if (gnvs->s5u1 == 0) - google_chromeec_set_usb_charge_mode( - 1, USB_CHARGE_MODE_DISABLED); - /* Prevent leak from standby rail to WLAN rail in S5. */ set_gpio(GPIO_WLAN_DISABLE_L, 0); set_gpio(GPIO_PP3300_CODEC_EN, 0); diff --git a/src/mainboard/google/stout/smihandler.c b/src/mainboard/google/stout/smihandler.c index 30637ab..578bdb5 100644 --- a/src/mainboard/google/stout/smihandler.c +++ b/src/mainboard/google/stout/smihandler.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */
+#include <acpi/acpi_gnvs.h> #include <device/pci_ops.h> #include <console/console.h> #include <cpu/x86/smm.h> @@ -38,6 +39,8 @@
void mainboard_smi_sleep(u8 slp_typ) { + bool u0disable = 0, u1disable = 0; + /* * Tell the EC to Enable USB power for S3 if requested. * Bit0 of 0x0D/Bit0 of 0x26 @@ -47,7 +50,9 @@ * charge smart phone. * 1/1 USB on, yellow port in AUTO mode and didn't support wake up system. */ - if (gnvs->s3u0 != 0 || gnvs->s3u1 != 0) { + usb_charge_mode_from_gnvs(3, &u0disable, &u1disable); + + if (!u0disable || !u1disable) { ec_write(EC_PERIPH_CNTL_3, ec_read(EC_PERIPH_CNTL_3) | 0x00); ec_write(EC_USB_S3_EN, ec_read(EC_USB_S3_EN) | 0x01); printk(BIOS_DEBUG, "USB wake from S3 enabled.\n"); diff --git a/src/mainboard/intel/strago/smihandler.c b/src/mainboard/intel/strago/smihandler.c index a625b62..3daf3b6 100644 --- a/src/mainboard/intel/strago/smihandler.c +++ b/src/mainboard/intel/strago/smihandler.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */
#include <acpi/acpi.h> +#include <acpi/acpi_gnvs.h> #include <console/console.h> #include <cpu/x86/smm.h> #include "ec.h" @@ -8,7 +9,6 @@ #include <ec/google/chromeec/ec.h> #include <ec/google/chromeec/smm.h>
-#include <soc/nvs.h> #include <soc/pm.h> #include <soc/gpio.h>
@@ -29,29 +29,20 @@
void mainboard_smi_sleep(uint8_t slp_typ) { + bool u0disable = 0, u1disable = 0; + /* Disable USB charging if required */ + usb_charge_mode_from_gnvs(slp_typ, &u0disable, &u1disable); + chromeec_set_usb_charge_mode(u0disable, u1disable); + switch (slp_typ) { case ACPI_S3: - if (gnvs->s3u0 == 0) - google_chromeec_set_usb_charge_mode( - 0, USB_CHARGE_MODE_DISABLED); - if (gnvs->s3u1 == 0) - google_chromeec_set_usb_charge_mode( - 1, USB_CHARGE_MODE_DISABLED); - /* Enable wake events */ google_chromeec_set_wake_mask(MAINBOARD_EC_S3_WAKE_EVENTS); /* Enable wake pin in GPE block. */ enable_gpe(WAKE_GPIO_EN); break; case ACPI_S5: - if (gnvs->s5u0 == 0) - google_chromeec_set_usb_charge_mode( - 0, USB_CHARGE_MODE_DISABLED); - if (gnvs->s5u1 == 0) - google_chromeec_set_usb_charge_mode( - 1, USB_CHARGE_MODE_DISABLED); - /* Enable wake events */ google_chromeec_set_wake_mask(MAINBOARD_EC_S5_WAKE_EVENTS); break;