mb/google/rex: Implement S0ix hooks aka `MS0X` method

This patch ensures to be able to drive SYS_SLP_S0IX_L `low` based
on the state of the system while `SLP_S0_L` signal is `low` (while
the system is in S0ix).

Implemented runtime ASL method (MS0X) being called by PEPD device
_DSM to configure `SLP_S0_GATE (GPP_H14)` PIN at S0ix entry/exit.

Scope (\_SB)
{
   Method (MS0X, 1, Serialized)
   {
      If ((Arg0 == One))
      {
         \_SB.PCI0.CTXS (0x75)
      }
      Else
      {
         \_SB.PCI0.STXS (0x75)
      }
}

BUG=b:256807255
TEST=Able to see SYS_SLP_S0IX_L goes low in S0ix.

Signed-off-by: Subrata Banik <subratabanik@google.com>
Change-Id: Ie6b5e066f228ea5dc79ae14dd803fc283fd248ce
Reviewed-on: https://review.coreboot.org/c/coreboot/+/70196
Reviewed-by: Sukumar Ghorai <sukumar.ghorai@intel.com>
Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/mainboard/google/rex/Kconfig b/src/mainboard/google/rex/Kconfig
index 0db76ac..7976e0b 100644
--- a/src/mainboard/google/rex/Kconfig
+++ b/src/mainboard/google/rex/Kconfig
@@ -28,6 +28,7 @@
 	select DRIVERS_INTEL_PMC
 	select DRIVERS_WWAN_FM350GL
 	select ENABLE_TCSS_DISPLAY_DETECTION if RUN_FSP_GOP
+	select HAVE_SLP_S0_GATE
 	select MAINBOARD_HAS_CHROMEOS
 	select MEMORY_SOLDERDOWN
 	select SOC_INTEL_METEORLAKE
@@ -110,4 +111,7 @@
 config USE_PM_ACPI_TIMER
 	default n
 
+config HAVE_SLP_S0_GATE
+	def_bool n
+
 endif # BOARD_GOOGLE_REX_COMMON
diff --git a/src/mainboard/google/rex/mainboard.c b/src/mainboard/google/rex/mainboard.c
index a076ec2..bb64c63 100644
--- a/src/mainboard/google/rex/mainboard.c
+++ b/src/mainboard/google/rex/mainboard.c
@@ -2,6 +2,7 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acpigen.h>
+#include <baseboard/gpio.h>
 #include <baseboard/variants.h>
 #include <device/device.h>
 #include <drivers/wwan/fm/chip.h>
@@ -19,6 +20,36 @@
 	gpio_configure_pads(pads, num);
 }
 
+void __weak variant_generate_s0ix_hook(enum s0ix_entry entry)
+{
+	/* Add board-specific MS0X entries */
+	/*
+	   if (s0ix_entry == S0IX_ENTRY) {
+		implement variant operations here
+	   }
+	   if (s0ix_entry == S0IX_EXIT) {
+		implement variant operations here
+	   }
+	 */
+}
+
+static void mainboard_generate_s0ix_hook(void)
+{
+	acpigen_write_if_lequal_op_int(ARG0_OP, 1);
+	{
+		if (CONFIG(HAVE_SLP_S0_GATE))
+			acpigen_soc_clear_tx_gpio(GPIO_SLP_S0_GATE);
+		variant_generate_s0ix_hook(S0IX_ENTRY);
+	}
+	acpigen_write_else();
+	{
+		if (CONFIG(HAVE_SLP_S0_GATE))
+			acpigen_soc_set_tx_gpio(GPIO_SLP_S0_GATE);
+		variant_generate_s0ix_hook(S0IX_EXIT);
+	}
+	acpigen_write_if_end();
+}
+
 static void mainboard_generate_wwan_shutdown(const struct device *dev)
 {
 	const struct drivers_wwan_fm_config *config = config_of(dev);
@@ -50,6 +81,12 @@
 		acpigen_write_method_end(); /* Method */
 		acpigen_write_scope_end(); /* Scope */
 	}
+
+	acpigen_write_scope("\\_SB");
+	acpigen_write_method_serialized("MS0X", 1);
+	mainboard_generate_s0ix_hook();
+	acpigen_write_method_end(); /* Method */
+	acpigen_write_scope_end(); /* Scope */
 }
 
 static void add_fw_config_oem_string(const struct fw_config *config, void *arg)
diff --git a/src/mainboard/google/rex/variants/baseboard/include/baseboard/variants.h b/src/mainboard/google/rex/variants/baseboard/include/baseboard/variants.h
index 6fd64c9..f3ace8a 100644
--- a/src/mainboard/google/rex/variants/baseboard/include/baseboard/variants.h
+++ b/src/mainboard/google/rex/variants/baseboard/include/baseboard/variants.h
@@ -21,4 +21,11 @@
 int variant_memory_sku(void);
 bool variant_is_half_populated(void);
 
+enum s0ix_entry {
+	S0IX_EXIT,
+	S0IX_ENTRY,
+};
+
+void variant_generate_s0ix_hook(enum s0ix_entry entry);
+
 #endif /*__BASEBOARD_VARIANTS_H__ */
diff --git a/src/mainboard/google/rex/variants/baseboard/rex/include/baseboard/gpio.h b/src/mainboard/google/rex/variants/baseboard/rex/include/baseboard/gpio.h
index 51b9564..613a1fa 100644
--- a/src/mainboard/google/rex/variants/baseboard/rex/include/baseboard/gpio.h
+++ b/src/mainboard/google/rex/variants/baseboard/rex/include/baseboard/gpio.h
@@ -13,6 +13,8 @@
 #define EC_SYNC_IRQ	GPP_A17_IRQ
 /* eSPI virtual wire reporting */
 #define EC_SCI_GPI	GPE0_ESPI
+/* Used to gate SoC's SLP_S0# signal */
+#define GPIO_SLP_S0_GATE	GPP_H14
 /* EC wake is LAN_WAKE# which is a special DeepSX wake pin */
 #define GPE_EC_WAKE	GPE0_LAN_WAK
 /* Memory configuration board straps */