summaryrefslogtreecommitdiff
path: root/src/mainboard/google
diff options
context:
space:
mode:
authorShelley Chen <shchen@google.com>2023-09-15 16:01:31 -0700
committerShelley Chen <shchen@google.com>2023-10-13 18:35:11 +0000
commit9b230ae29557f09e67b4d9a598a794af3d092199 (patch)
tree12078f33c248e3088635329c334241f84378ffe7 /src/mainboard/google
parent8032dcee7f2e075972718fa9e639018546febeb7 (diff)
mb/google/brox: Create new Brox baseboard
This CL is just getting the initial brox framework to get the baseboard building. Copied files from brask baseboard and tried to remove contents of some files like the device tree and memory IDs. Added support for memory part "MT62F512M32D2DR-031 WT:B", mapped to DRAM ID 0. BUG=b:300690448 BRANCH=None TEST=./util/abuild/abuild -p none -t GOOGLE_BROX -x -a Change-Id: I929b465646ac4c69d4bab33ce23848c7b1fa0f98 Signed-off-by: Shelley Chen <shchen@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/78009 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Nick Vaccaro <nvaccaro@google.com>
Diffstat (limited to 'src/mainboard/google')
-rw-r--r--src/mainboard/google/brox/Kconfig157
-rw-r--r--src/mainboard/google/brox/Kconfig.name4
-rw-r--r--src/mainboard/google/brox/Makefile.inc23
-rw-r--r--src/mainboard/google/brox/acpi/gps.asl104
-rw-r--r--src/mainboard/google/brox/acpi/gpu_defines.h60
-rw-r--r--src/mainboard/google/brox/acpi/gpu_ec.asl13
-rw-r--r--src/mainboard/google/brox/acpi/gpu_top.asl100
-rw-r--r--src/mainboard/google/brox/acpi/nbci.asl77
-rw-r--r--src/mainboard/google/brox/acpi/nvjt.asl129
-rw-r--r--src/mainboard/google/brox/acpi/nvop.asl69
-rw-r--r--src/mainboard/google/brox/acpi/nvpcf.asl67
-rw-r--r--src/mainboard/google/brox/acpi/peg.asl99
-rw-r--r--src/mainboard/google/brox/acpi/power.asl431
-rw-r--r--src/mainboard/google/brox/acpi/utility.asl54
-rw-r--r--src/mainboard/google/brox/board_info.txt6
-rw-r--r--src/mainboard/google/brox/bootblock.c19
-rw-r--r--src/mainboard/google/brox/chromeos.c29
-rw-r--r--src/mainboard/google/brox/chromeos.fmd60
-rw-r--r--src/mainboard/google/brox/dsdt.asl47
-rw-r--r--src/mainboard/google/brox/ec.c22
-rw-r--r--src/mainboard/google/brox/mainboard.c236
-rw-r--r--src/mainboard/google/brox/romstage.c26
-rw-r--r--src/mainboard/google/brox/smihandler.c29
-rw-r--r--src/mainboard/google/brox/spd/Makefile.inc6
-rw-r--r--src/mainboard/google/brox/variants/baseboard/brox/Makefile.inc12
-rw-r--r--src/mainboard/google/brox/variants/baseboard/brox/devicetree.cb205
-rw-r--r--src/mainboard/google/brox/variants/baseboard/brox/gma-mainboard.ads13
-rw-r--r--src/mainboard/google/brox/variants/baseboard/brox/gpio.c46
-rw-r--r--src/mainboard/google/brox/variants/baseboard/brox/include/baseboard/ec.h79
-rw-r--r--src/mainboard/google/brox/variants/baseboard/brox/include/baseboard/gpio.h22
-rw-r--r--src/mainboard/google/brox/variants/baseboard/brox/memory.c103
-rw-r--r--src/mainboard/google/brox/variants/baseboard/brox/ramstage.c48
-rw-r--r--src/mainboard/google/brox/variants/baseboard/include/baseboard/variants.h90
-rw-r--r--src/mainboard/google/brox/variants/brox/Makefile.inc8
-rw-r--r--src/mainboard/google/brox/variants/brox/data.vbtbin0 -> 8704 bytes
-rw-r--r--src/mainboard/google/brox/variants/brox/fw_config.c8
-rw-r--r--src/mainboard/google/brox/variants/brox/gpio.c218
-rw-r--r--src/mainboard/google/brox/variants/brox/include/variant/ec.h8
-rw-r--r--src/mainboard/google/brox/variants/brox/include/variant/gpio.h14
-rw-r--r--src/mainboard/google/brox/variants/brox/memory/Makefile.inc7
-rw-r--r--src/mainboard/google/brox/variants/brox/memory/dram_id.generated.txt7
-rw-r--r--src/mainboard/google/brox/variants/brox/memory/mem_parts_used.txt1
-rw-r--r--src/mainboard/google/brox/variants/brox/overridetree.cb4
-rw-r--r--src/mainboard/google/brox/variants/brox/ramstage.c18
-rw-r--r--src/mainboard/google/brox/variants/brox/variant.c9
-rw-r--r--src/mainboard/google/brox/wwan_power.asl14
46 files changed, 2801 insertions, 0 deletions
diff --git a/src/mainboard/google/brox/Kconfig b/src/mainboard/google/brox/Kconfig
new file mode 100644
index 0000000000..70a9735f58
--- /dev/null
+++ b/src/mainboard/google/brox/Kconfig
@@ -0,0 +1,157 @@
+config BOARD_GOOGLE_BROX_COMMON
+ def_bool n
+ select DRIVERS_GENERIC_GPIO_KEYS
+ select DRIVERS_I2C_GENERIC
+ select DRIVERS_I2C_HID
+ select DRIVERS_INTEL_DPTF
+ select DRIVERS_INTEL_DPTF_SUPPORTS_TPCH
+ select DRIVERS_INTEL_PMC
+ select DRIVERS_INTEL_SOUNDWIRE
+ select DRIVERS_INTEL_USB4_RETIMER
+ select DRIVERS_SPI_ACPI
+ select DRIVERS_WIFI_GENERIC
+ select EC_GOOGLE_CHROMEEC
+ select EC_GOOGLE_CHROMEEC_BOARDID
+ select EC_GOOGLE_CHROMEEC_ESPI
+ select EC_GOOGLE_CHROMEEC_SKUID
+ select ENABLE_TCSS_USB_DETECTION if !CHROMEOS
+ select FW_CONFIG
+ select FW_CONFIG_SOURCE_CHROMEEC_CBI
+ select GOOGLE_SMBIOS_MAINBOARD_VERSION
+ select HAVE_ACPI_RESUME
+ select HAVE_ACPI_TABLES
+ select HAVE_FSP_LOGO_SUPPORT if RUN_FSP_GOP
+ select I2C_TPM
+ select INTEL_LPSS_UART_FOR_CONSOLE
+ select MAINBOARD_HAS_CHROMEOS
+ select MAINBOARD_HAS_TPM2
+ select PMC_IPC_ACPI_INTERFACE
+ select SOC_INTEL_CSE_LITE_SKU
+# select SOC_INTEL_CSE_SEND_EOP_ASYNC
+ select SOC_INTEL_COMMON_BLOCK_USB4
+ select SOC_INTEL_COMMON_BLOCK_TCSS
+ select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES
+ select SOC_INTEL_COMMON_BASECODE_DEBUG_FEATURE
+ select SOC_INTEL_CRASHLOG
+ select SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY_V1
+
+config BOARD_GOOGLE_BASEBOARD_BROX
+ def_bool n
+ select BOARD_GOOGLE_BROX_COMMON
+ select BOARD_ROMSIZE_KB_32768
+ select DRIVERS_AUDIO_SOF
+ select DRIVERS_GFX_GENERIC
+ select HAVE_SLP_S0_GATE
+ select MEMORY_SOLDERDOWN
+ select SOC_INTEL_COMMON_BLOCK_IPU
+ select SOC_INTEL_CRASHLOG
+ select SOC_INTEL_RAPTORLAKE
+ select SOC_INTEL_RAPTORLAKE_PCH_S
+ select SYSTEM_TYPE_LAPTOP
+ select TPM_GOOGLE_CR50
+
+config BOARD_GOOGLE_BROX
+ bool "-> Brox"
+ select BOARD_GOOGLE_BASEBOARD_BROX
+
+if BOARD_GOOGLE_BROX_COMMON
+
+config BASEBOARD_DIR
+ string
+ default "brox" if BOARD_GOOGLE_BASEBOARD_BROX
+
+config CHROMEOS
+ select EC_GOOGLE_CHROMEEC_SWITCHES
+ select HAS_RECOVERY_MRC_CACHE
+
+config CHROMEOS_WIFI_SAR
+ bool "Enable SAR options for ChromeOS build"
+ depends on CHROMEOS
+ select DSAR_ENABLE
+ select GEO_SAR_ENABLE
+ select SAR_ENABLE
+ select USE_SAR
+
+config DEVICETREE
+ default "variants/baseboard/\$(CONFIG_BASEBOARD_DIR)/devicetree.cb"
+
+config DRIVER_TPM_I2C_BUS
+ hex
+ default 0x1 if BOARD_GOOGLE_BROX
+
+config DRIVER_TPM_I2C_ADDR
+ hex
+ default 0x50
+
+config FMDFILE
+ default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/chromeos.fmd" if CHROMEOS
+
+config TPM_TIS_ACPI_INTERRUPT
+ int
+ default 13
+
+config OVERRIDE_DEVICETREE
+ default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb"
+
+config MAINBOARD_DIR
+ default "google/brox"
+
+config MAINBOARD_FAMILY
+ string
+ default "Google_Brox" if BOARD_GOOGLE_BASEBOARD_BROX
+
+config MAINBOARD_PART_NUMBER
+ default "Brox" if BOARD_GOOGLE_BROX
+
+config VARIANT_DIR
+ default "brox" if BOARD_GOOGLE_BROX
+
+config VBOOT
+ select VBOOT_EARLY_EC_SYNC
+ select VBOOT_LID_SWITCH
+
+config DIMM_SPD_SIZE
+ default 512
+
+config UART_FOR_CONSOLE
+ int
+ default 0
+
+config HAVE_WWAN_POWER_SEQUENCE
+ def_bool n
+ help
+ Select this if the variant has a WWAN module and requires the poweroff sequence
+ to be performed on shutdown. Must define WWAN_FCPO, WWAN_RST and WWAN_PERST GPIOs
+ in variant.h, as well as T1_OFF_MS (time between PERST & RST) and T2_OFF_MS (time
+ between RST and FCPO). WWAN_PERST and T1_OFF_MS are only necessary for PCIe WWAN
+ (when HAVE_PCIE_WWAN is also selected).
+
+config HAVE_PCIE_WWAN
+ def_bool n
+
+config USE_PM_ACPI_TIMER
+ default y if BOARD_GOOGLE_PRIMUS4ES
+ default n
+
+config MEMORY_SODIMM
+ def_bool n
+ select SPD_CACHE_ENABLE
+ select SPD_CACHE_IN_FMAP
+
+config MEMORY_SOLDERDOWN
+ def_bool n
+ select CHROMEOS_DRAM_PART_NUMBER_IN_CBI if CHROMEOS
+ select HAVE_SPD_IN_CBFS
+
+config HAVE_SLP_S0_GATE
+ def_bool n
+
+config PCIEXP_DEFAULT_MAX_RESIZABLE_BAR_BITS
+ int
+ default 33
+
+config VBT_DATA_SIZE_KB
+ int
+ default 10
+
+endif # BOARD_GOOGLE_BROX_COMMON
diff --git a/src/mainboard/google/brox/Kconfig.name b/src/mainboard/google/brox/Kconfig.name
new file mode 100644
index 0000000000..95dd5e318e
--- /dev/null
+++ b/src/mainboard/google/brox/Kconfig.name
@@ -0,0 +1,4 @@
+comment "Brox"
+
+config BOARD_GOOGLE_BROX
+ bool "-> Brox"
diff --git a/src/mainboard/google/brox/Makefile.inc b/src/mainboard/google/brox/Makefile.inc
new file mode 100644
index 0000000000..8c7e42d5f7
--- /dev/null
+++ b/src/mainboard/google/brox/Makefile.inc
@@ -0,0 +1,23 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+bootblock-y += bootblock.c
+
+verstage-$(CONFIG_CHROMEOS) += chromeos.c
+
+romstage-$(CONFIG_CHROMEOS) += chromeos.c
+romstage-y += romstage.c
+
+ramstage-$(CONFIG_CHROMEOS) += chromeos.c
+ramstage-y += mainboard.c
+ramstage-y += ec.c
+
+BASEBOARD_DIR:=$(call strip_quotes,$(CONFIG_BASEBOARD_DIR))
+
+subdirs-y += variants/baseboard/$(BASEBOARD_DIR)
+subdirs-y += variants/$(VARIANT_DIR)
+subdirs-y += variants/$(VARIANT_DIR)/memory
+subdirs-$(CONFIG_HAVE_SPD_IN_CBFS) += spd
+
+CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/baseboard/include
+CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/baseboard/$(BASEBOARD_DIR)/include
+CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include
diff --git a/src/mainboard/google/brox/acpi/gps.asl b/src/mainboard/google/brox/acpi/gps.asl
new file mode 100644
index 0000000000..f201037f06
--- /dev/null
+++ b/src/mainboard/google/brox/acpi/gps.asl
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#define GPS_FUNC_SUPPORT 0
+#define GPS_FUNC_GETCALLBACKS 0x13
+#define GPS_FUNC_PSHARESTATUS 0x20
+#define GPS_FUNC_PSHAREPARAMS 0x2a
+#define GPS_FUNC_REQUESTDXSTATE 0x12
+
+#define QUERY_GET_STATUS 0
+#define QUERY_GET_SUPPORTED_FIELDS 1
+#define QUERY_GET_CURRENT_LIMITS 2
+
+#define EC_D_NOTIFY_MASK 0x7
+
+/* GPS return Package */
+Name (GPSP, Buffer (0x28) {0x0})
+CreateDWordField (GPSP, 0, RETN)
+CreateDWordField (GPSP, 4, VRV1)
+CreateDWordField (GPSP, 8, TGPU)
+
+/* GETCALLBACKS return value
+ [0]: Callback for post-mode set
+ [1]: Callback for pre-mode set
+ [2]: Callback for post power state transition */
+Name (GPSR, Buffer (4) { 0x4, 0x0, 0x0, 0x0 })
+
+Method (GPS, 2, Serialized)
+{
+ Switch (ToInteger (Arg0))
+ {
+ Case (GPS_FUNC_SUPPORT)
+ {
+ Return (LTOB(
+ (1 << GPS_FUNC_SUPPORT) |
+ (1 << GPS_FUNC_GETCALLBACKS) |
+ (1 << GPS_FUNC_PSHARESTATUS) |
+ (1 << GPS_FUNC_PSHAREPARAMS) |
+ (1 << GPS_FUNC_REQUESTDXSTATE)))
+ }
+ Case (GPS_FUNC_GETCALLBACKS)
+ {
+ CreateDWordField (Arg1, 0, QURY)
+
+ /* Driver querying for which callbacks the ACPI code
+ wants callbacks for. */
+ If (QURY == 0)
+ {
+ Return (GPSR)
+ }
+
+ If (QURY & 0x4)
+ {
+ Printf("GPS: Kernel driver callback post power state transition")
+ Return (GPSR)
+ }
+ }
+ Case (GPS_FUNC_PSHARESTATUS)
+ {
+ Return (ITOB(
+ (0 << 0) | /* GPS_FUNC_PSHAREPARAMS should not be called
+ again after initialization, i.e., its return
+ value is not dynamically updated. */
+ (1 << 0) | /* System uses both a GPIO and ACPI notification
+ codes to set multiple GPU power limits. */
+ (0 << 21))) /* EDPpeak limit is default */
+ }
+ Case (GPS_FUNC_PSHAREPARAMS)
+ {
+ CreateField (Arg1, 0, 4, QUTY) /* Query type */
+
+ /* Version of return value */
+ VRV1 = 0x10000
+ Switch (ToInteger (QUTY))
+ {
+ Case (QUERY_GET_STATUS)
+ {
+ Return (GPSP)
+ }
+ Case (QUERY_GET_SUPPORTED_FIELDS)
+ {
+ /* Only GPU temperature is supported */
+ RETN = 0x100 | ToInteger (QUTY)
+ Return (GPSP)
+ }
+ Case (QUERY_GET_CURRENT_LIMITS)
+ {
+ /* Request a limit of '0' for the GPU temperature,
+ meaning there is no limit. */
+ RETN = 0x102
+ TGPU = 0
+ Return (GPSP)
+ }
+ }
+ }
+ Case (GPS_FUNC_REQUESTDXSTATE)
+ {
+ Local0 = ToInteger(\_SB.PCI0.LPCB.EC0.GPUD) & EC_D_NOTIFY_MASK
+ \_SB.PCI0.PEG0.PEGP.DNOT (Local0, 1)
+ Return (NV_ERROR_SUCCESS)
+ }
+ }
+
+ Return (NV_ERROR_UNSUPPORTED)
+}
diff --git a/src/mainboard/google/brox/acpi/gpu_defines.h b/src/mainboard/google/brox/acpi/gpu_defines.h
new file mode 100644
index 0000000000..1cb03145b0
--- /dev/null
+++ b/src/mainboard/google/brox/acpi/gpu_defines.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#define NV_ERROR_SUCCESS 0x0
+#define NV_ERROR_UNSPECIFIED 0x80000001
+#define NV_ERROR_UNSUPPORTED 0x80000002
+
+#define PCI_OWNER_SBIOS 0x0
+#define PCI_OWNER_DRIVER 0x1
+
+#define OPTIMUS_POWER_CONTROL_DISABLE 0x2
+#define OPTIMUS_POWER_CONTROL_ENABLE 0x3
+
+#define OPTIMUS_CONTROL_NO_RUN_PS0 0x0
+#define OPTIMUS_CONTROL_RUN_PS0 0x1
+
+#define GC6_STATE_EXITED 0x0
+#define GC6_STATE_ENTERED 0x1
+#define GC6_STATE_TRANSITION 0x2
+
+#define GC6_DEFER_DISABLE 0x0
+#define GC6_DEFER_ENABLE 0x1
+
+#define NOTIFY_GPS_EVENT_STATUS_CHANGE 0xc0
+#define NOTIFY_GPS_NVPCF_STATUS_CHANGE 0xc5
+#define NOTIFY_GPS_EVENT_LIMIT_POWER_0 0xd1
+#define NOTIFY_GPS_EVENT_LIMIT_POWER_1 0xd2
+#define NOTIFY_GPS_EVENT_LIMIT_POWER_2 0xd3
+#define NOTIFY_GPS_EVENT_LIMIT_POWER_3 0xd4
+#define NOTIFY_GPS_EVENT_LIMIT_POWER_4 0xd5
+
+/* Defines for NVJT subfunction */
+#define NVJT_GPC_GSS 0
+#define NVJT_GPC_EGNS 1
+#define NVJT_GPC_EGIS 2
+#define NVJT_GPS_XGXS 3
+#define NVJT_GPS_XGIS 4
+
+#define UUID_NVOP "a486d8f8-0bda-471b-a72b-6042a6b5bee0"
+#define UUID_NVJT "cbeca351-067b-4924-9cbd-b46b00b86f34"
+#define UUID_NBCI "d4a50b75-65c7-46f7-bfb7-41514cea0244"
+#define UUID_NVPCF "36b49710-2483-11e7-9598-0800200c9a66"
+#define UUID_GPS "a3132d01-8cda-49ba-a52e-bc9d46df6b81"
+
+#define REVISION_MIN_NVOP 0x100
+#define REVISION_MIN_NVJT 0x100
+#define REVISION_MIN_NBCI 0x102
+#define REVISION_MIN_NVPCF 0x200
+#define REVISION_MIN_GPS 0x200
+
+#define D1_EC 0
+#define D2_EC 1
+#define D3_EC 2
+#define D4_EC 3
+#define D5_EC 4
+
+#define D1_GPU 0xD1
+#define D2_GPU 0xD2
+#define D3_GPU 0xD3
+#define D4_GPU 0xD4
+#define D5_GPU 0xD5
diff --git a/src/mainboard/google/brox/acpi/gpu_ec.asl b/src/mainboard/google/brox/acpi/gpu_ec.asl
new file mode 100644
index 0000000000..59875ad138
--- /dev/null
+++ b/src/mainboard/google/brox/acpi/gpu_ec.asl
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#define EC_D_NOTIFY_MASK 0x7
+
+Scope (\_SB.PCI0.LPCB.EC0)
+{
+ /* EC has data for GPU in memmap */
+ Method (_Q0C, 0, Serialized)
+ {
+ Local0 = ToInteger(GPUD) & EC_D_NOTIFY_MASK
+ \_SB.PCI0.PEG0.PEGP.DNOT (Local0, 0)
+ }
+}
diff --git a/src/mainboard/google/brox/acpi/gpu_top.asl b/src/mainboard/google/brox/acpi/gpu_top.asl
new file mode 100644
index 0000000000..492502c3d4
--- /dev/null
+++ b/src/mainboard/google/brox/acpi/gpu_top.asl
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_defines.h"
+
+Scope (\_SB.PCI0.PEG0)
+{
+ #include "peg.asl"
+
+ Device (PEGP)
+ {
+ Name (_ADR, 0x0)
+ OperationRegion (PCIC, PCI_Config, 0x00, 0x100)
+ Field (PCIC, DWordAcc, NoLock, Preserve)
+ {
+ NVID, 16,
+ NDID, 16,
+ CMDR, 8,
+ VGAR, 2008, /* VGA Registers */
+ }
+
+ #include "utility.asl"
+ #include "power.asl"
+ #include "nvop.asl"
+ #include "nvjt.asl"
+ #include "nbci.asl"
+ #include "nvpcf.asl"
+ #include "gps.asl"
+ #include "gpu_ec.asl"
+
+ /* Convert D Notify from EC to GPU */
+ Method (CNVD, 1, NotSerialized)
+ {
+ Switch (ToInteger(Arg0)) {
+ Case (D1_EC) { Return (D1_GPU) }
+ Case (D2_EC) { Return (D2_GPU) }
+ Case (D3_EC) { Return (D3_GPU) }
+ Case (D4_EC) { Return (D4_GPU) }
+ Case (D5_EC) { Return (D5_GPU) }
+ Default { Return (D5_GPU) }
+ }
+ }
+
+ /* Current D Notify Value, defaults to D1
+ * Arg0 == Shared value
+ * Arg1 == force notification if no change (0 or 1)
+ */
+ Name (CDNV, D1_EC)
+ Method (DNOT, 2, Serialized)
+ {
+ Printf ("EC: GPU D-Notify, %o", Arg0)
+ If ((Arg0 != CDNV) || (Arg1 == 1))
+ {
+ CDNV = Arg0
+ Local0 = CNVD (Arg0)
+ Notify (\_SB.PCI0.PEG0.PEGP, Local0)
+ }
+ }
+
+ Method (_DSM, 4, Serialized)
+ {
+ If (Arg0 == ToUUID (UUID_NVOP))
+ {
+ If (ToInteger(Arg1) >= REVISION_MIN_NVOP)
+ {
+ Return (NVOP (Arg2, Arg3))
+ }
+ }
+ ElseIf (Arg0 == ToUUID (UUID_NVJT))
+ {
+ If (ToInteger (Arg1) >= REVISION_MIN_NVJT)
+ {
+ Return (NVJT (Arg2, Arg3))
+ }
+ }
+ ElseIf (Arg0 == ToUUID (UUID_NBCI))
+ {
+ If (ToInteger (Arg1) >= REVISION_MIN_NBCI)
+ {
+ Return (NBCI (Arg2, Arg3))
+ }
+ }
+ ElseIf (Arg0 == ToUUID (UUID_NVPCF))
+ {
+ If (ToInteger (Arg1) >= REVISION_MIN_NVPCF)
+ {
+ Return (NPCF (Arg2, Arg3))
+ }
+ }
+ ElseIf (Arg0 == ToUUID (UUID_GPS))
+ {
+ If (ToInteger (Arg1) >= REVISION_MIN_GPS)
+ {
+ Return (GPS (Arg2, Arg3))
+ }
+ }
+
+ Return (NV_ERROR_UNSUPPORTED)
+ }
+ }
+}
diff --git a/src/mainboard/google/brox/acpi/nbci.asl b/src/mainboard/google/brox/acpi/nbci.asl
new file mode 100644
index 0000000000..274c04be7f
--- /dev/null
+++ b/src/mainboard/google/brox/acpi/nbci.asl
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#define NBCI_FUNC_SUPPORT 0
+#define NBCI_FUNC_PLATCAPS 1
+#define NBCI_FUNC_GETOBJBYTYPE 16
+#define NBCI_FUNC_GETCALLBACKS 19
+
+/* 'DR' in ASCII, for DRiver Object */
+#define NBCI_OBJTYPE_DR 0x4452
+
+#define GPS_FUNC_GETCALLBACKS 0x13
+
+Method (NBCI, 2, Serialized)
+{
+ Switch (ToInteger (Arg0))
+ {
+ Case (NBCI_FUNC_SUPPORT)
+ {
+ Return (ITOB(
+ (1 << NBCI_FUNC_SUPPORT) |
+ (1 << NBCI_FUNC_PLATCAPS) |
+ (1 << NBCI_FUNC_GETOBJBYTYPE)))
+ }
+ Case (NBCI_FUNC_PLATCAPS)
+ {
+ Return (ITOB(
+ (0 << 10) | /* No 3D Hotkeys */
+ (0 << 9) | /* Do not enumerate a dock */
+ (0 << 7) | /* Does not have DISPLAYSTATUS */
+ (0 << 5) | /* No LID support */
+ (0 << 4))) /* No Aux power state request */
+ }
+ Case (NBCI_FUNC_GETCALLBACKS)
+ {
+ /* Re-use the GPS subfunction's GETCALLBACKS Method */
+ Return (GPS (GPS_FUNC_GETCALLBACKS, Arg1))
+ }
+ Case (NBCI_FUNC_GETOBJBYTYPE)
+ {
+ CreateWordField (Arg1, 2, BFF0)
+ If (BFF0 == NBCI_OBJTYPE_DR)
+ {
+ Return (Buffer(0xa1)
+ {
+ /* DR ("Driver Object") is a data object which
+ * might vary depending on the eDP panel used. */
+ 0x57, 0x74, 0xdc, 0x86, 0x75, 0x84, 0xec, 0xe7,
+ 0x52, 0x44, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0xde, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x47, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x45, 0x00, 0x00, 0x00, 0x03, 0x00,
+ 0x51, 0x00, 0x00, 0x00, 0x04, 0x00, 0x4f, 0x00,
+ 0x00, 0x00, 0x05, 0x00, 0x4d, 0x00, 0x00, 0x00,
+ 0x06, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x00,
+ 0x49, 0x00, 0x00, 0x00, 0x08, 0x00, 0x47, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd9, 0x1c,
+ 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x41, 0x5d, 0xc9, 0x00, 0x01, 0x24, 0x2e, 0x00,
+ 0x02, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0xd9, 0x1c, 0x04, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x68, 0x9e,
+ 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00
+ })
+ } Else {
+ Return (NV_ERROR_UNSPECIFIED)
+ }
+
+ }
+ }
+
+ Return (NV_ERROR_UNSUPPORTED)
+}
diff --git a/src/mainboard/google/brox/acpi/nvjt.asl b/src/mainboard/google/brox/acpi/nvjt.asl
new file mode 100644
index 0000000000..17011ec2dd
--- /dev/null
+++ b/src/mainboard/google/brox/acpi/nvjt.asl
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#define JT_FUNC_SUPPORT 0
+#define JT_FUNC_CAPS 1
+#define JT_FUNC_POWERCONTROL 3
+#define JT_FUNC_PLATPOLICY 4
+
+Method (NVJT, 2, Serialized)
+{
+ Switch (ToInteger(Arg0))
+ {
+ Case (JT_FUNC_SUPPORT)
+ {
+ Return (ITOB(
+ (1 << JT_FUNC_SUPPORT) |
+ (1 << JT_FUNC_CAPS) |
+ (1 << JT_FUNC_POWERCONTROL) |
+ (1 << JT_FUNC_PLATPOLICY)))
+ }
+ Case (JT_FUNC_CAPS)
+ {
+ Return (ITOB(
+ (0 << 0) | /* JTE: G-Sync NVSR Power Features Enabled */
+ (1 << 0) | /* NVSE: NVSR Disabled */
+ (0 << 3) | /* PPR: Panel Power Rail */
+ (0 << 5) | /* SRPR: Self-Refresh Controller Power Rail */
+ (0 << 6) | /* FBPR: FB Power Rail */
+ (0 << 8) | /* GPR: GPU Power Rail */
+ (0 << 10) | /* GCR: GC6 ROM */
+ (1 << 11) | /* PTH: No SMI Handler */
+ (0 << 12) | /* NOT: Supports Notify on GC6 State done */
+ (1 << 13) | /* MHYB: MS Hybrid Support (deferred GC6) */
+ (0 << 14) | /* RPC: Root Port Control */
+ (0 << 15) | /* GC6 Version (GC6-E) */
+ (0 << 17) | /* GEI: GC6 Exit ISR Support */
+ (0 << 18) | /* GSW: GC6 Self Wakeup */
+ (0x200 << 20))) /* MXRV: Highest Revision */
+ }
+ Case (JT_FUNC_POWERCONTROL)
+ {
+ CreateField (Arg1, 0, 3, GPC) /* GPU Power Control */
+ CreateField (Arg1, 4, 1, PPC) /* Panel Power Control */
+ CreateField (Arg1, 14, 2, DFGC) /* Defer GC6 enter/exit */
+ CreateField (Arg1, 16, 3, GPCX) /* Deferred GC6 exit */
+
+ /* Deferred GC6 entry/exit is requested */
+ If (ToInteger(GPC) != 0 || ToInteger(DFGC) != 0)
+ {
+ DFEN = ToInteger(DFGC)
+ DFCI = ToInteger(GPC)
+ DFCO = ToInteger(GPCX)
+ }
+
+ Local0 = Buffer (4) { 0x0 }
+ CreateField (Local0, 0, 3, CGCS) /* Current GC State */
+ CreateField (Local0, 3, 1, CGPS) /* Current GPU power status */
+ CreateField (Local0, 7, 1, CPSS) /* Current panel and SRC state */
+
+ /* Leave early if deferred GC6 is requested */
+ If (DFEN != 0)
+ {
+ CGCS = 1
+ CGPS = 1
+ Return (Local0)
+ }
+
+ Switch (ToInteger(GPC))
+ {
+ /* Get GCU GCx Sleep Status */
+ Case (NVJT_GPC_GSS)
+ {
+ If (PSTA () != 0)
+ {
+ CGPS = 1
+ CGCS = 1
+ }
+ Else
+ {
+ CGPS = 0
+ CGCS = 3
+ }
+ }
+ Case (NVJT_GPC_EGNS)
+ {
+ /* Enter GC6; no self-refresh */
+ GC6I ()
+ CPSS = 1
+ CGCS = 0
+ }
+ Case (NVJT_GPC_EGIS)
+ {
+ /* Enter GC6; enable self-refresh */
+ GC6I ()
+ If (ToInteger (PPC) == 0)
+ {
+ CPSS = 0
+ }
+ CGCS = 0
+ }
+ Case (NVJT_GPS_XGXS)
+ {
+ /* Exit GC6; stop self-refresh */
+ GC6O ()
+ CGCS = 1
+ CGPS = 1
+ If (ToInteger (PPC) != 0)
+ {
+ CPSS = 0
+ }
+ }
+ Case (NVJT_GPS_XGIS)
+ {
+ /* Exit GC6 for self-refresh */
+ GC6O ()
+ CGCS = 1
+ CGPS = 1
+ If (ToInteger (PPC) != 0)
+ {
+ CPSS = 0
+ }
+ }
+ }
+
+ Return (Local0)
+ }
+ }
+
+ Return (NV_ERROR_UNSUPPORTED)
+}
diff --git a/src/mainboard/google/brox/acpi/nvop.asl b/src/mainboard/google/brox/acpi/nvop.asl
new file mode 100644
index 0000000000..ecf962e180
--- /dev/null
+++ b/src/mainboard/google/brox/acpi/nvop.asl
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#define NVOP_FUNC_SUPPORT 0x00
+#define NVOP_FUNC_GET_OBJ_BY_TYPE 0x10
+#define NVOP_FUNC_OPTIMUS_CAPS 0x1a
+#define NVOP_FUNC_OPTIMUS_STATUS 0x1b
+
+Method (NVOP, 2, Serialized)
+{
+ Switch (ToInteger (Arg0))
+ {
+ Case (NVOP_FUNC_SUPPORT)
+ {
+ Return (ITOB (
+ (1 << NVOP_FUNC_SUPPORT) |
+ (1 << NVOP_FUNC_OPTIMUS_CAPS) |
+ (1 << NVOP_FUNC_OPTIMUS_STATUS)))
+ }
+ Case (NVOP_FUNC_OPTIMUS_CAPS)
+ {
+ CreateField(Arg1, 0, 1, FLUP) /* Flag Update */
+ CreateField(Arg1, 1, 1, CSOT) /* Change configuration Space Owner Target */
+ CreateField(Arg1, 2, 1, CSOW) /* Change configuration Space Owner Write */
+ CreateField(Arg1, 24, 2, NPCE) /* New Power Control Enable setting */
+
+ /* Change Optimus power control capabilities */
+ If (ToInteger (FLUP) != 0 && ToInteger (NPCE) != 0)
+ {
+ OPCS = NPCE
+ }
+
+ /* Change PCI configuration space save/restore owner */
+ If (ToInteger (CSOW) == 1)
+ {
+ PCIO = CSOT
+ }
+
+ /* Current GPU Control Status */
+ If (PSTA () == 1)
+ {
+ Local0 = 3
+ }
+ Else
+ {
+ Local0 = 0
+ }
+
+ Return (ITOB (
+ (1 << 0) | /* Optimus Enabled */
+ (Local0 << 3) | /* Current GPU Control Status */
+ (0 << 6) | /* Shared Discrete GPU Hotplug Capabilities */
+ (0 << 7) | /* MUXed DDC/Aux Capabilities */
+ (PCIO << 8) | /* PCIe Configuration Space Owner */
+ (1 << 24) | /* Platform Optimus Power Capabilities */
+ (0 << 27))) /* Optimus HD Audio Codec Capabilities */
+ }
+ Case (NVOP_FUNC_OPTIMUS_STATUS)
+ {
+ Return (ITOB (
+ (0 << 0) | /* Optimus Audio Codec Control */
+ (0 << 2) | /* Request GPU Power State */
+ (0 << 4) | /* Evaluate Requested GPU Power State */
+ (0 << 5) | /* Request Optimus Adapter Policy */
+ (0 << 7))) /* Evaluate Requested Optimus Adapter Selection */
+ }
+ }
+
+ Return (NV_ERROR_UNSUPPORTED)
+}
diff --git a/src/mainboard/google/brox/acpi/nvpcf.asl b/src/mainboard/google/brox/acpi/nvpcf.asl
new file mode 100644
index 0000000000..9f6c5e1149
--- /dev/null
+++ b/src/mainboard/google/brox/acpi/nvpcf.asl
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#define NVPCF_FUNC_SUPPORT 0
+#define NVPCF_FUNC_GET_STATIC_CONFIG_TABLES 1
+#define NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS 2
+
+Method (NPCF, 2, Serialized)
+{
+ Switch (ToInteger (Arg0))
+ {
+ Case (NVPCF_FUNC_SUPPORT)
+ {
+ Return (ITOB(
+ (1 << NVPCF_FUNC_SUPPORT) |
+ (1 << NVPCF_FUNC_GET_STATIC_CONFIG_TABLES) |
+ (1 << NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS)))
+ }
+ Case (NVPCF_FUNC_GET_STATIC_CONFIG_TABLES)
+ {
+ Return (Buffer () {
+ /* System Device Table Header (v2.0) */
+ 0x20, 0x03, 0x01,
+
+ /* System Device Table Entries */
+ 0x00, /* [3:0] CPU type (0=Intel, 1=AMD),
+ [7:4] GPU type (0=Nvidia) */
+
+ /* System Controller Table Header (v2.2), 1 controller entry */
+ 0x22, 0x04, 0x05, 0x01,
+
+ /* Controller #1 Flags */
+ 0x01, /* [3:0] Controller class
+ 0=Disabled, 1=Dynamic Boost,
+ 2=CTGP-only.
+ [7:4] Reserved. Set to 0. */
+ /* Controller #1 Params */
+ /* Class = Dynamic Boost
+ [0:0] DC support
+ 0=Not supported, 1=Supported
+ [31:1] Reserved. Set to 0. */
+ 0x00, 0x00, 0x00, 0x00,
+
+ /* Twos-complement checksum */
+ 0xaf
+ })
+ }
+ Case (NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS)
+ {
+ Local0 = Buffer (0x31) {
+ /* Dynamic Params Table Header (1 controller entry, 0x1c bytes) */
+ 0x22, 0x05, 0x10, 0x1c, 0x01 }
+
+ CreateWordField (Local0, 0x1d, MAGA)
+ CreateWordField (Local0, 0x19, TPPA)
+ CreateDWordField (Local0, 0x15, CEO0)
+
+ MAGA = 0x50 /* TGP on AC = 10W in 1/8-Watt increments */
+ TPPA = 0xc8 /* TPPA = 25W in 1/8-Watt increments */
+ CEO0 = 0x200 /* [7:0] Controller index
+ [8:8] Disable controller on AC
+ [9:9] Disable controller on DC */
+ Return (Local0)
+ }
+ }
+
+ Return (NV_ERROR_UNSUPPORTED)
+}
diff --git a/src/mainboard/google/brox/acpi/peg.asl b/src/mainboard/google/brox/acpi/peg.asl
new file mode 100644
index 0000000000..ebaeaecd25
--- /dev/null
+++ b/src/mainboard/google/brox/acpi/peg.asl
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+External (\_SB.PCI0.PEG0.PEGP.NPON, MethodObj)
+External (\_SB.PCI0.PEG0.PEGP.NPOF, MethodObj)
+
+OperationRegion (PCIC, PCI_Config, 0x00, 0x100)
+Field (PCIC, AnyAcc, NoLock, Preserve)
+{
+ Offset (0x4a),
+ CEDR, 1, /* Correctable Error Detected, RW/1C/V */
+ Offset (0x52),
+ , 13,
+ LASX, 1, /* Link Active Status */
+ Offset (0x69),
+ , 2,
+ LREN, 1, /* LTR Enabled */
+ Offset (0xe0),
+ , 7,
+ NCB7, 1, /* Scratch bit to save L2/3 state */
+ Offset (0xe2),
+ , 2,
+ L23E, 1, /* L23_Rdy Entry request */
+ L23R, 1 /* L23_Rdy Detect Transition */
+}
+
+/* L2/3 Entry sequence */
+Method (DL23, 0, Serialized)
+{
+ L23E = 1
+ Local0 = 8
+ While (Local0 > 0)
+ {
+ If (!L23E)
+ {
+ Break
+ }
+
+ Sleep (2)
+ Local0--
+ }
+ NCB7 = 1
+}
+
+/* L2/3 exit seqeuence */
+Method (LD23, 0, Serialized)
+{
+ If (!NCB7)
+ {
+ Return
+ }
+
+ L23R = 1
+ Local0 = 20
+ While (Local0 > 0)
+ {
+ If (!L23R)
+ {
+ Break
+ }
+
+ Sleep (2)
+ Local0--
+ }
+
+ NCB7 = 0
+ Local0 = 8
+ While (Local0 > 0)
+ {
+ If (LASX == 1)
+ {
+ Break
+ }
+
+ Sleep (2)
+ Local0--
+ }
+}
+
+/* PEG Power Resource */
+PowerResource (PGPR, 0, 0)
+{
+ Method (_ON, 0, Serialized)
+ {
+ /* Power up GPU from GCOFF (or GC6 exit if deferred) */
+ \_SB.PCI0.PEG0.PEGP.NPON ()
+ _STA = 1
+ }
+ Method (_OFF, 0, Serialized)
+ {
+ /* Power down GPU to GCOFF (or GC6 entry if deferred) */
+ _STA = 0
+ \_SB.PCI0.PEG0.PEGP.NPOF ()
+ }
+ Name (_STA, 0)
+}
+
+Name (_PR0, Package() { PGPR })
+Name (_PR2, Package() { PGPR })
+Name (_PR3, Package() { PGPR })
diff --git a/src/mainboard/google/brox/acpi/power.asl b/src/mainboard/google/brox/acpi/power.asl
new file mode 100644
index 0000000000..389bc4a2a1
--- /dev/null
+++ b/src/mainboard/google/brox/acpi/power.asl
@@ -0,0 +1,431 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <device/pci_ids.h>
+
+External (\_SB.PCI0.PMC.IPCS, MethodObj)
+
+/* Voltage rail control signals */
+
+#define GPIO_1V8_PWR_EN GPP_E11
+
+#define GPIO_NV33_PWR_EN GPP_E1
+#define GPIO_NV33_PG GPP_E2
+
+#define GPIO_1V8_PG GPP_E20
+#define GPIO_NV12_PWR_EN GPP_D0
+#define GPIO_NV12_PG GPP_D1
+
+#define GPIO_NVVDD_PWR_EN GPP_E0
+#define GPIO_PEXVDD_PWR_EN GPP_E10
+#define GPIO_PEXVDD_PG GPP_E17
+#define GPIO_FBVDD_PWR_EN GPP_A19
+#define GPIO_FBVDD_PG GPP_E4
+
+#define GPIO_GPU_PERST_L GPP_B3
+#define GPIO_GPU_ALLRAILS_PG GPP_E5
+#define GPIO_GPU_NVVDD_EN GPP_A17
+
+#define GC6_DEFER_TYPE_EXIT_GC6 3
+
+/* 250ms in "Timer" units (i.e. 100ns increments) */
+#define MIN_OFF_TIME_TIMERS 2500000
+
+#define SRCCLK_DISABLE 0
+#define SRCCLK_ENABLE 1
+
+#define GPU_POWER_STATE_OFF 0
+#define GPU_POWER_STATE_ON 1
+
+/* Dynamically-assigned NVVDD PG GPIO, set in _INI in SSDT */
+Name (NVPG, 0)
+Name (GPEN, 0)
+
+/* Optimus Power Control State */
+Name (OPCS, OPTIMUS_POWER_CONTROL_DISABLE)
+
+/* PCI configuration space Owner */
+Name (PCIO, PCI_OWNER_DRIVER)
+
+/* Saved PCI configuration space memory (VGA Buffer) */
+Name (VGAB, Buffer (0xfb) { 0x00 })
+
+/* Deferred GPU State */
+Name (OPS0, OPTIMUS_CONTROL_NO_RUN_PS0)
+
+/* GC6 Entry/Exit state */
+Name (GC6E, GC6_STATE_EXITED)
+
+/* Power State, GCOFF, GCON */
+Name (GPPS, GPU_POWER_STATE_ON)
+
+/* Defer GC6 entry / exit until D3-cold request */
+Name (DFEN, 0)
+/* Deferred GC6 Enter control */
+Name (DFCI, 0)
+/* Deferred GC6 Exit control */
+Name (DFCO, 0)
+/* GCOFF Timer */
+Name (GCOT, 0)
+
+#define PMC_SRCCLK_PIN 0x1
+#define PMC_SRCCLK_ENABLE 0x1
+#define PMC_SRCCLK_DISABLE 0x0
+
+#define PMC_RP_IDX (1 << 27)
+#define PMC_RP_ENABLE (1 << 27)
+#define PMC_RP_DISABLE 0x0
+/* Copy of LTR enable bit from PEG port */
+Name (SLTR, 0)
+
+/* Control the PCIe SRCCLK# for dGPU */
+Method (SRCC, 1, Serialized)
+{
+ If (!Arg0)
+ {
+ Local0 = PMC_SRCCLK_DISABLE
+ Local1 = PMC_RP_DISABLE
+ }
+ Else
+ {
+ Local0 = PMC_SRCCLK_ENABLE
+ Local1 = PMC_RP_ENABLE
+ }
+
+ \_SB.PCI0.PMC.IPCS (0xac, 0, 16, PMC_SRCCLK_PIN,
+ Local0, PMC_RP_IDX, Local1)
+}
+
+/* "GC6 In", i.e. GC6 Entry Sequence */
+Method (GC6I, 0, Serialized)
+{
+ GC6E = GC6_STATE_TRANSITION
+
+ /* Save the PEG port's LTR setting */
+ SLTR = LREN
+
+ /* Put PCIe link into L2/3 */
+ \_SB.PCI0.PEG0.DL23 ()
+
+ /* Wait for GPU to deassert its GPIO4, i.e. GPU_NVVDD_EN */
+ GPPL (GPIO_GPU_NVVDD_EN, 0, 20)
+
+ /* Deassert PG_GPU_ALLRAILS */
+ CTXS (GPIO_GPU_ALLRAILS_PG)
+
+ /* Ramp down FBVDD - TODO: Remove Agah when board is dropped */
+ CTXS (GPIO_FBVDD_PWR_EN)
+
+ /* Ramp down PEXVDD */
+ CTXS (GPIO_PEXVDD_PWR_EN)
+ Sleep (2)
+
+ /* Deassert EN_PPVAR_GPU_NVVDD */
+ CTXS (GPIO_NVVDD_PWR_EN)
+ Sleep (2)
+
+ /* Assert GPU_PERST_L */
+ CTXS (GPIO_GPU_PERST_L)
+
+ /* Disable PCIe SRCCLK# */
+ SRCC (SRCCLK_DISABLE)
+
+ GC6E = GC6_STATE_ENTERED
+}
+
+/* "GC6 Out", i.e. GC6 Exit Sequence */
+Method (GC6O, 0, Serialized)
+{
+ GC6E = GC6_STATE_TRANSITION
+
+ /* Re-enable PCIe SRCCLK# */
+ SRCC (SRCCLK_ENABLE)
+
+ /* Deassert GPU_PERST_L */
+ STXS (GPIO_GPU_PERST_L)
+
+ /* Wait for GPU to assert GPU_NVVDD_EN */
+ GPPL (GPIO_GPU_NVVDD_EN, 1, 20)
+
+ /* Ramp up NVVDD */
+ STXS (GPIO_NVVDD_PWR_EN)
+ GPPL (NVPG, 1, 4)
+
+ /* Ramp up PEXVDD */
+ STXS (GPIO_PEXVDD_PWR_EN)
+ GPPL (GPIO_PEXVDD_PG, 1, 4)
+
+ /* Ramp up FBVDD - TODO: Remove Agah when board is dropped */
+ STXS (GPIO_FBVDD_PWR_EN)
+
+
+ /* Assert PG_GPU_ALLRAILS */
+ STXS (GPIO_GPU_ALLRAILS_PG)
+
+ /* Restore PCIe link back to L0 state */
+ \_SB.PCI0.PEG0.LD23 ()
+
+ /* Wait for dGPU to reappear on the bus */
+ Local0 = 50
+ While (NVID != PCI_VID_NVIDIA)
+ {
+ Stall (100)
+ Local0--
+ If (Local0 == 0)
+ {
+ Break
+ }
+ }
+
+ /* Restore the PEG LTR enable bit */
+ LREN = SLTR
+
+ /* Clear recoverable errors detected bit */
+ CEDR = 1
+
+ GC6E = GC6_STATE_EXITED
+}
+
+/* GCOFF exit sequence */
+Method (PGON, 0, Serialized)
+{
+ Local0 = Timer - GCOT
+ If (Local0 < MIN_OFF_TIME_TIMERS)
+ {
+ Local1 = (MIN_OFF_TIME_TIMERS - Local0) / 10000
+ Printf("Sleeping %o to ensure min GCOFF time", Local1)
+ Sleep (Local1)
+ }
+
+ /* Assert PERST# */
+ CTXS (GPIO_GPU_PERST_L)
+
+ /* Ramp up 1.2V rail on boards with support */
+ STXS (GPIO_NV12_PWR_EN)
+ GPPL (GPIO_NV12_PG, 1, 5)
+
+ /* Ramp up 1.8V rail */
+ STXS (GPEN)
+ GPPL (GPIO_1V8_PG, 1, 20)
+
+ /* Ramp up NV33 rail */
+ STXS (GPIO_NV33_PWR_EN)
+ GPPL (GPIO_NV33_PG, 1, 20)
+
+ /* Ramp up NVVDD rail */
+ STXS (GPIO_NVVDD_PWR_EN)
+ GPPL (NVPG, 1, 5)
+
+ /* Ramp up PEXVDD rail */
+ STXS (GPIO_PEXVDD_PWR_EN)
+ GPPL (GPIO_PEXVDD_PG, 1, 5)
+
+ /* Ramp up FBVDD rail */
+ STXS (GPIO_FBVDD_PWR_EN)
+
+ GPPL (GPIO_FBVDD_PG, 1, 5)
+
+ /* All rails are good */
+ STXS (GPIO_GPU_ALLRAILS_PG)
+ Sleep (1)
+
+ /* Deassert PERST# */
+ STXS (GPIO_GPU_PERST_L)
+
+
+ GC6E = GC6_STATE_EXITED
+ GPPS = GPU_POWER_STATE_ON
+}
+
+/* GCOFF entry sequence */
+Method (PGOF, 0, Serialized)
+{
+ /* Assert PERST# */
+ CTXS (GPIO_GPU_PERST_L)
+
+ /* All rails are about to go down */
+ CTXS (GPIO_GPU_ALLRAILS_PG)
+ Sleep (1)
+
+ /* Ramp down FBVDD */
+ CTXS (GPIO_FBVDD_PWR_EN)
+
+ /* Ramp down PEXVDD and let rail discharge to <10% */
+ CTXS (GPIO_PEXVDD_PWR_EN)
+ Sleep (2)
+
+ /* Ramp down NVVDD */
+ CTXS (GPIO_NVVDD_PWR_EN)
+ Sleep (2)
+
+ /* Ramp down NV33 */
+ CTXS (GPIO_NV33_PWR_EN)
+ Sleep (4)
+
+ /* Ramp down 1.8V */
+ CTXS (GPEN)
+
+ /* Ramp down 1.2V rail on boards with support */
+ CTXS (GPIO_NV12_PWR_EN)
+
+ GCOT = Timer
+
+ GPPS = GPU_POWER_STATE_OFF
+}
+
+/* GCOFF Out, i.e. full power-on sequence */
+Method (GCOO, 0, Serialized)
+{
+ If (GPPS == GPU_POWER_STATE_ON)
+ {
+ Printf ("PGON: GPU already on")
+ Return
+ }
+
+ SRCC (SRCCLK_ENABLE)
+ PGON ()
+ \_SB.PCI0.PEG0.LD23 ()
+
+ /* Wait for dGPU to reappear on the bus */
+ Local0 = 50
+ While (NVID != PCI_VID_NVIDIA)
+ {
+ Stall (100)
+ Local0--
+ If (Local0 == 0)
+ {
+ Break
+ }
+ }
+
+ /* Restore the PEG LTR enable bit */
+ LREN = SLTR
+
+ /* Clear recoverable errors detected bit */
+ CEDR = 1
+
+ /* Restore the PEG LTR enable bit */
+ LREN = SLTR
+
+ /* Clear recoverable errors detected bit */
+ CEDR = 1
+}
+
+/* GCOFF In, i.e. full power-off sequence */
+Method (GCOI, 0, Serialized)
+{
+ If (GPPS == GPU_POWER_STATE_OFF)
+ {
+ Printf ("GPU already off")
+ Return
+ }
+
+ /* Save the PEG port's LTR setting */
+ SLTR = LREN
+ \_SB.PCI0.PEG0.DL23 ()
+ PGOF ()
+ SRCC (SRCCLK_DISABLE)
+}
+
+/* Handle deferred GC6 vs. poweron request */
+Method (NPON, 0, Serialized)
+{
+ If (DFEN == GC6_DEFER_ENABLE)
+ {
+ If (DFCO == GC6_DEFER_TYPE_EXIT_GC6)
+ {
+ GC6O ()
+ }
+
+ DFEN = GC6_DEFER_DISABLE
+ }
+ Else
+ {
+ GCOO ()
+ }
+}
+
+/* Handle deferred GC6 vs. poweroff request */
+Method (NPOF, 0, Serialized)
+{
+ /* Don't touch the `DFEN` flag until the GC6 exit. */
+ If (DFEN == GC6_DEFER_ENABLE)
+ {
+ /* Deferred GC6 entry */
+ If (DFCI == NVJT_GPC_EGNS || DFCI == NVJT_GPC_EGIS)
+ {
+ GC6I ()
+ }
+ }
+ Else
+ {
+ GCOI ()
+ }
+}
+
+Method (_ON, 0, Serialized)
+{
+ PGON ()
+}
+
+Method (_OFF, 0, Serialized)
+{
+ PGOF ()
+}
+
+/* Put device into D0 */
+Method (_PS0, 0, NotSerialized)
+{
+ If (OPS0 == OPTIMUS_CONTROL_RUN_PS0)
+ {
+ /* Restore PCI config space */
+ If (PCIO == PCI_OWNER_SBIOS)
+ {
+ VGAR = VGAB
+ }
+
+ /* Poweron or deferred GC6 exit */
+ NPON ()
+
+ OPS0 = OPTIMUS_CONTROL_NO_RUN_PS0
+ }
+}
+
+/* Put device into D3 */
+Method (_PS3, 0, NotSerialized)
+{
+ If (OPCS == OPTIMUS_POWER_CONTROL_ENABLE)
+ {
+ /* Save PCI config space to ACPI buffer */
+ If (PCIO == PCI_OWNER_SBIOS)
+ {
+ VGAB = VGAR
+ }
+
+ /* Poweroff or deferred GC6 entry */
+ NPOF ()
+
+ /* Because _PS3 ran NPOF, _PS0 must run NPON */
+ OPS0 = OPTIMUS_CONTROL_RUN_PS0
+
+ /* OPCS is one-shot, so reset it */
+ OPCS = OPTIMUS_POWER_CONTROL_DISABLE
+ }
+}
+
+Method (PSTA, 0, Serialized)
+{
+ If (GC6E == GC6_STATE_EXITED &&
+ \_SB.PCI0.GTXS(GPIO_GPU_ALLRAILS_PG) == 1)
+ {
+ Return (1)
+ }
+ Else
+ {
+ Return (0)
+ }
+}
+
+Method (_STA, 0, Serialized)
+{
+ Return (0xF)
+}
diff --git a/src/mainboard/google/brox/acpi/utility.asl b/src/mainboard/google/brox/acpi/utility.asl
new file mode 100644
index 0000000000..49f3dca8e9
--- /dev/null
+++ b/src/mainboard/google/brox/acpi/utility.asl
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * Poll a GPIO until it goes to the specified state
+ * Arg0 == GPIO #
+ * Arg1 == state (0 or 1)
+ * Arg2 == timeout in ms
+ */
+Method (GPPL, 3, Serialized)
+{
+ Local0 = 0
+ Local1 = Arg2 * 10
+ While (Local0 < Local1)
+ {
+ If (\_SB.PCI0.GRXS (Arg0) == Arg1) {
+ Return (0)
+ } Else {
+ Local0++
+ }
+ Stall (100)
+ }
+
+ If (Local0 == Arg2) {
+ Printf("[ERROR] GPPL for %o timed out", Arg0)
+ }
+
+ Return (0xFF)
+}
+
+/* Convert from 32-bit integer to 4-byte buffer (little-endian) */
+Method (ITOB, 1)
+{
+ Local0 = Buffer(4) { 0, 0, 0, 0 }
+ Local0[0] = Arg0 & 0xFF
+ Local0[1] = (Arg0 >> 8) & 0xFF
+ Local0[2] = (Arg0 >> 16) & 0xFF
+ Local0[3] = (Arg0 >> 24) & 0xFF
+ Return (Local0)
+}
+
+/* Convert from 64-bit integer to 8-byte buffer (little-endian) */
+Method (LTOB, 1)
+{
+ Local0 = Buffer(8) { 0, 0, 0, 0, 0, 0, 0, 0 }
+ Local0[0] = Arg0 & 0xFF
+ Local0[1] = (Arg0 >> 8) & 0xFF
+ Local0[2] = (Arg0 >> 16) & 0xFF
+ Local0[3] = (Arg0 >> 24) & 0xFF
+ Local0[4] = (Arg0 >> 32) & 0xFF
+ Local0[5] = (Arg0 >> 40) & 0xFF
+ Local0[6] = (Arg0 >> 48) & 0xFF
+ Local0[7] = (Arg0 >> 56) & 0xFF
+ Return (Local0)
+}
diff --git a/src/mainboard/google/brox/board_info.txt b/src/mainboard/google/brox/board_info.txt
new file mode 100644
index 0000000000..ae581b69a8
--- /dev/null
+++ b/src/mainboard/google/brox/board_info.txt
@@ -0,0 +1,6 @@
+Vendor name: Google
+Board name: Brox
+Category: laptop
+ROM protocol: SPI
+ROM socketed: n
+Flashrom support: y
diff --git a/src/mainboard/google/brox/bootblock.c b/src/mainboard/google/brox/bootblock.c
new file mode 100644
index 0000000000..c24e9590e2
--- /dev/null
+++ b/src/mainboard/google/brox/bootblock.c
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <baseboard/variants.h>
+#include <bootblock_common.h>
+
+void bootblock_mainboard_early_init(void)
+{
+ const struct pad_config *pads;
+ size_t num;
+ pads = variant_early_gpio_table(&num);
+ gpio_configure_pads(pads, num);
+}
+
+void bootblock_mainboard_init(void)
+{
+ variant_update_descriptor();
+}
+
+void __weak variant_update_descriptor(void) {}
diff --git a/src/mainboard/google/brox/chromeos.c b/src/mainboard/google/brox/chromeos.c
new file mode 100644
index 0000000000..5c99371eb1
--- /dev/null
+++ b/src/mainboard/google/brox/chromeos.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <baseboard/gpio.h>
+#include <bootmode.h>
+#include <boot/coreboot_tables.h>
+#include <gpio.h>
+#include <types.h>
+
+void fill_lb_gpios(struct lb_gpios *gpios)
+{
+ struct lb_gpio chromeos_gpios[] = {
+ {-1, ACTIVE_HIGH, get_lid_switch(), "lid"},
+ {-1, ACTIVE_HIGH, 0, "power"},
+ {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"},
+ {GPIO_EC_IN_RW, ACTIVE_HIGH, gpio_get(GPIO_EC_IN_RW), "EC in RW"},
+ };
+ lb_add_gpios(gpios, chromeos_gpios, ARRAY_SIZE(chromeos_gpios));
+}
+
+int get_write_protect_state(void)
+{
+ return gpio_get(GPIO_PCH_WP);
+}
+
+int get_ec_is_trusted(void)
+{
+ /* EC is trusted if not in RW. */
+ return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/brox/chromeos.fmd b/src/mainboard/google/brox/chromeos.fmd
new file mode 100644
index 0000000000..59b24dd4a2
--- /dev/null
+++ b/src/mainboard/google/brox/chromeos.fmd
@@ -0,0 +1,60 @@
+FLASH 32M {
+ SI_ALL 5M {
+ SI_DESC 4K
+ SI_ME {
+ CSE_LAYOUT 8K
+ CSE_RO 1640K
+ CSE_DATA 420K
+ # 64-KiB aligned to optimize RW erases during CSE update.
+ CSE_RW 3008K
+ }
+ }
+ SI_BIOS 27M {
+ RW_SECTION_A 8M {
+ VBLOCK_A 64K
+ FW_MAIN_A(CBFS)
+ RW_FWID_A 64
+ ME_RW_A(CBFS) 3008K
+ }
+ RW_LEGACY(CBFS) 2M
+ RW_MISC 1M {
+ UNIFIED_MRC_CACHE(PRESERVE) 128K {
+ RECOVERY_MRC_CACHE 64K
+ RW_MRC_CACHE 64K
+ }
+ RW_ELOG(PRESERVE) 16K
+ RW_SHARED 16K {
+ SHARED_DATA 8K
+ VBLOCK_DEV 8K
+ }
+ # The RW_SPD_CACHE region is only used for brox variants that use DDRx memory.
+ # It is placed in the common `chromeos.fmd` file because it is only 4K and there
+ # is free space in the RW_MISC region that cannot be easily reclaimed because
+ # the RW_SECTION_B must start on the 16M boundary.
+ RW_SPD_CACHE(PRESERVE) 4K
+ RW_VPD(PRESERVE) 8K
+ RW_NVRAM(PRESERVE) 24K
+ }
+ # This section starts at the 16M boundary in SPI flash.
+ # ADL does not support a region crossing this boundary,
+ # because the SPI flash is memory-mapped into two non-
+ # contiguous windows.
+ RW_SECTION_B 8M {
+ VBLOCK_B 64K
+ FW_MAIN_B(CBFS)
+ RW_FWID_B 64
+ ME_RW_B(CBFS) 3008K
+ }
+ # Make WP_RO region align with SPI vendor
+ # memory protected range specification.
+ WP_RO 8M {
+ RO_VPD(PRESERVE) 16K
+ RO_SECTION {
+ FMAP 2K
+ RO_FRID 64
+ GBB@4K 448K
+ COREBOOT(CBFS)
+ }
+ }
+ }
+}
diff --git a/src/mainboard/google/brox/dsdt.asl b/src/mainboard/google/brox/dsdt.asl
new file mode 100644
index 0000000000..6ae46946aa
--- /dev/null
+++ b/src/mainboard/google/brox/dsdt.asl
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <acpi/acpi.h>
+#include <variant/ec.h>
+
+DefinitionBlock(
+ "dsdt.aml",
+ "DSDT",
+ ACPI_DSDT_REV_2,
+ OEM_ID,
+ ACPI_TABLE_CREATOR,
+ 0x20110725
+)
+{
+ #include <acpi/dsdt_top.asl>
+ #include <cpu/intel/common/acpi/cpu.asl>
+ #include <soc/intel/common/acpi/platform.asl>
+ #include <soc/intel/common/block/acpi/acpi/globalnvs.asl>
+
+ Scope (\_SB) {
+#if CONFIG(HAVE_WWAN_POWER_SEQUENCE)
+ #include "wwan_power.asl"
+#endif
+ Device (PCI0)
+ {
+ #include <soc/intel/common/block/acpi/acpi/northbridge.asl>
+ #include <soc/intel/alderlake/acpi/southbridge.asl>
+ #include <soc/intel/alderlake/acpi/tcss.asl>
+ }
+ }
+
+ /* Chipset specific sleep states */
+ #include <southbridge/intel/common/acpi/sleepstates.asl>
+
+ /* ChromeOS Embedded Controller */
+ Scope (\_SB.PCI0.LPCB)
+ {
+ /* ACPI code for EC SuperIO functions */
+ #include <ec/google/chromeec/acpi/superio.asl>
+ /* ACPI code for EC functions */
+ #include <ec/google/chromeec/acpi/ec.asl>
+ }
+
+#if CONFIG(INCLUDE_NVIDIA_GPU_ASL)
+ #include "acpi/gpu_top.asl"
+#endif
+}
diff --git a/src/mainboard/google/brox/ec.c b/src/mainboard/google/brox/ec.c
new file mode 100644
index 0000000000..f828bc5547
--- /dev/null
+++ b/src/mainboard/google/brox/ec.c
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <acpi/acpi.h>
+#include <console/console.h>
+#include <ec/ec.h>
+#include <ec/google/chromeec/ec.h>
+#include <variant/ec.h>
+
+void mainboard_ec_init(void)
+{
+ static const struct google_chromeec_event_info info = {
+ .log_events = MAINBOARD_EC_LOG_EVENTS,
+ .sci_events = MAINBOARD_EC_SCI_EVENTS,
+ .s3_wake_events = MAINBOARD_EC_S3_WAKE_EVENTS,
+ .s5_wake_events = MAINBOARD_EC_S5_WAKE_EVENTS,
+ .s0ix_wake_events = MAINBOARD_EC_S0IX_WAKE_EVENTS,
+ };
+
+ printk(BIOS_DEBUG, "mainboard: EC init\n");
+
+ google_chromeec_events_init(&info, acpi_is_wakeup_s3());
+}
diff --git a/src/mainboard/google/brox/mainboard.c b/src/mainboard/google/brox/mainboard.c
new file mode 100644
index 0000000000..f892099be8
--- /dev/null
+++ b/src/mainboard/google/brox/mainboard.c
@@ -0,0 +1,236 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <acpi/acpigen.h>
+#include <baseboard/gpio.h>
+#include <baseboard/variants.h>
+#include <device/device.h>
+#include <drivers/tpm/cr50.h>
+#include <drivers/wwan/fm/chip.h>
+#include <ec/ec.h>
+#include <fw_config.h>
+#include <security/tpm/tss.h>
+#include <soc/gpio.h>
+#include <soc/ramstage.h>
+#include <stdio.h>
+
+WEAK_DEV_PTR(rp6_wwan);
+WEAK_DEV_PTR(dgpu);
+
+static void add_fw_config_oem_string(const struct fw_config *config, void *arg)
+{
+ struct smbios_type11 *t;
+ char buffer[64];
+
+ t = (struct smbios_type11 *)arg;
+
+ snprintf(buffer, sizeof(buffer), "%s-%s", config->field_name, config->option_name);
+ t->count = smbios_add_string(t->eos, buffer);
+}
+
+static void mainboard_smbios_strings(struct device *dev, struct smbios_type11 *t)
+{
+ fw_config_for_each_found(add_fw_config_oem_string, t);
+}
+
+void mainboard_update_soc_chip_config(struct soc_intel_alderlake_config *config)
+{
+ int ret;
+
+ ret = tlcl_lib_init();
+ if (ret != VB2_SUCCESS) {
+ printk(BIOS_ERR, "tlcl_lib_init() failed: 0x%x\n", ret);
+ return;
+ }
+
+ if (cr50_is_long_interrupt_pulse_enabled()) {
+ printk(BIOS_INFO, "Enabling GPIO PM b/c CR50 has long IRQ pulse support\n");
+ config->gpio_override_pm = 0;
+ } else {
+ printk(BIOS_INFO, "Disabling GPIO PM b/c CR50 does not have long IRQ pulse "
+ "support\n");
+ config->gpio_override_pm = 1;
+ config->gpio_pm[COMM_0] = 0;
+ config->gpio_pm[COMM_1] = 0;
+ config->gpio_pm[COMM_2] = 0;
+ config->gpio_pm[COMM_3] = 0;
+ config->gpio_pm[COMM_4] = 0;
+ config->gpio_pm[COMM_5] = 0;
+ }
+
+ variant_update_soc_chip_config(config);
+}
+
+void __weak variant_update_soc_chip_config(struct soc_intel_alderlake_config *config)
+{
+ /* default implementation does nothing */
+}
+
+void __weak variant_init(void)
+{
+ /* default implementation does nothing */
+}
+
+void __weak fw_config_gpio_padbased_override(struct pad_config *padbased_table)
+{
+ /* default implementation does nothing */
+}
+
+void __weak variant_configure_pads(void)
+{
+ const struct pad_config *base_pads;
+ const struct pad_config *override_pads;
+ size_t base_num, override_num;
+
+ base_pads = variant_gpio_table(&base_num);
+ override_pads = variant_gpio_override_table(&override_num);
+ gpio_configure_pads_with_override(base_pads, base_num, override_pads, override_num);
+}
+
+static void mainboard_init(void *chip_info)
+{
+ variant_configure_pads();
+ variant_init();
+ variant_devtree_update();
+}
+
+void __weak variant_devtree_update(void)
+{
+ /* Override dev tree settings per board */
+}
+
+static void mainboard_dev_init(struct device *dev)
+{
+ mainboard_ec_init();
+}
+
+static void mainboard_generate_wwan_shutdown(const struct device *dev)
+{
+ const struct drivers_wwan_fm_config *config = config_of(dev);
+ const struct device *parent = dev->bus->dev;
+
+ if (!config)
+ return;
+ if (config->rtd3dev) {
+ acpigen_write_store();
+ acpigen_emit_namestring(acpi_device_path_join(parent, "RTD3._STA"));
+ acpigen_emit_byte(LOCAL0_OP);
+ acpigen_write_if_lequal_op_int(LOCAL0_OP, ONE_OP);
+ {
+ acpigen_emit_namestring(acpi_device_path_join(dev, "DPTS"));
+ acpigen_emit_byte(ARG0_OP);
+ }
+ acpigen_write_if_end();
+ }
+}
+
+static void mainboard_generate_dgpu_shutdown(const struct device *dev)
+{
+ /* Call `_OFF` from the Power Resource associated with the dGPU's PEG port. */
+ const struct device *parent = dev->bus->dev;
+
+ if (parent)
+ acpigen_emit_namestring(acpi_device_path_join(parent, "PGPR._OFF"));
+}
+
+static void mainboard_generate_mpts(void)
+{
+ const struct device *wwan = DEV_PTR(rp6_wwan);
+ const struct device *dgpu = DEV_PTR(dgpu);
+
+ /*
+ * If HAVE_WWAN_POWER_SEQUENCE is selected, MPTS will be added to the
+ * DSDT via wwan_power.asl. We can't add MPTS to the SSDT as well,
+ * since the duplicate definition will result in a kernel error.
+ *
+ * This special case can be removed in the future if the power-off
+ * sequences for all WWAN devices used on brox are moved to the SSDT.
+ */
+ if (CONFIG(HAVE_WWAN_POWER_SEQUENCE)) {
+ if (wwan || dgpu)
+ printk(BIOS_ERR, "Skip adding duplicate MPTS entry to SSDT\n");
+ return;
+ }
+
+ acpigen_write_scope("\\_SB");
+ acpigen_write_method_serialized("MPTS", 1);
+ if (wwan)
+ mainboard_generate_wwan_shutdown(wwan);
+ if (dgpu)
+ mainboard_generate_dgpu_shutdown(dgpu);
+
+ acpigen_write_method_end(); /* Method */
+ acpigen_write_scope_end(); /* Scope */
+}
+
+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_fill_ssdt(const struct device *dev)
+{
+ mainboard_generate_mpts();
+
+ /* for variant to fill additional SSDT */
+ variant_fill_ssdt(dev);
+
+ acpigen_write_scope("\\_SB");
+ acpigen_write_method_serialized("MS0X", 1);
+ mainboard_generate_s0ix_hook();
+ acpigen_write_method_end(); /* Method */
+ acpigen_write_scope_end(); /* Scope */
+
+}
+
+void __weak variant_fill_ssdt(const struct device *dev)
+{
+ /* Add board-specific SSDT entries */
+}
+
+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_enable(struct device *dev)
+{
+ dev->ops->init = mainboard_dev_init;
+ dev->ops->get_smbios_strings = mainboard_smbios_strings;
+ dev->ops->acpi_fill_ssdt = mainboard_fill_ssdt;
+}
+
+
+void __weak variant_finalize(void)
+{
+}
+
+static void mainboard_final(void *chip_info)
+{
+ variant_finalize();
+}
+
+struct chip_operations mainboard_ops = {
+ .init = mainboard_init,
+ .enable_dev = mainboard_enable,
+ .final = mainboard_final,
+};
diff --git a/src/mainboard/google/brox/romstage.c b/src/mainboard/google/brox/romstage.c
new file mode 100644
index 0000000000..4e88eca617
--- /dev/null
+++ b/src/mainboard/google/brox/romstage.c
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <baseboard/gpio.h>
+#include <baseboard/variants.h>
+#include <fsp/api.h>
+#include <gpio.h>
+#include <soc/romstage.h>
+#include <string.h>
+
+void mainboard_memory_init_params(FSPM_UPD *memupd)
+{
+ const struct mb_cfg *mem_config = variant_memory_params();
+ bool half_populated = variant_is_half_populated();
+ struct mem_spd spd_info;
+
+ memset(&spd_info, 0, sizeof(spd_info));
+ variant_get_spd_info(&spd_info);
+
+ const struct pad_config *pads;
+ size_t pads_num;
+
+ memcfg_init(memupd, mem_config, &spd_info, half_populated);
+
+ pads = variant_romstage_gpio_table(&pads_num);
+ gpio_configure_pads(pads, pads_num);
+}
diff --git a/src/mainboard/google/brox/smihandler.c b/src/mainboard/google/brox/smihandler.c
new file mode 100644
index 0000000000..9208d51613
--- /dev/null
+++ b/src/mainboard/google/brox/smihandler.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <cpu/x86/smm.h>
+#include <ec/google/chromeec/ec.h>
+#include <ec/google/chromeec/smm.h>
+#include <elog.h>
+#include <intelblocks/smihandler.h>
+#include <variant/ec.h>
+
+void mainboard_smi_sleep(u8 slp_typ)
+{
+ chromeec_smi_sleep(slp_typ, MAINBOARD_EC_S3_WAKE_EVENTS, MAINBOARD_EC_S5_WAKE_EVENTS);
+}
+
+int mainboard_smi_apmc(u8 apmc)
+{
+ chromeec_smi_apmc(apmc, MAINBOARD_EC_SCI_EVENTS, MAINBOARD_EC_SMI_EVENTS);
+ return 0;
+}
+
+void elog_gsmi_cb_mainboard_log_wake_source(void)
+{
+ google_chromeec_log_events(MAINBOARD_EC_LOG_EVENTS | MAINBOARD_EC_S0IX_WAKE_EVENTS);
+}
+
+void mainboard_smi_espi_handler(void)
+{
+ chromeec_smi_process_events();
+}
diff --git a/src/mainboard/google/brox/spd/Makefile.inc b/src/mainboard/google/brox/spd/Makefile.inc
new file mode 100644
index 0000000000..be4d98bd1d
--- /dev/null
+++ b/src/mainboard/google/brox/spd/Makefile.inc
@@ -0,0 +1,6 @@
+## SPDX-License-Identifier: GPL-2.0-or-later
+##
+
+ifneq ($(SPD_SOURCES),)
+LIB_SPD_DEPS := $(SPD_SOURCES)
+endif
diff --git a/src/mainboard/google/brox/variants/baseboard/brox/Makefile.inc b/src/mainboard/google/brox/variants/baseboard/brox/Makefile.inc
new file mode 100644
index 0000000000..3a6695828f
--- /dev/null
+++ b/src/mainboard/google/brox/variants/baseboard/brox/Makefile.inc
@@ -0,0 +1,12 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+bootblock-y += gpio.c
+
+romstage-y += memory.c
+romstage-y += gpio.c
+romstage-$(CONFIG_MAINBOARD_USE_EARLY_LIBGFXINIT) += gma-mainboard.ads
+
+ramstage-y += gpio.c
+ramstage-y += ramstage.c
+
+smm-$(CONFIG_SMMSTORE) += gpio.c
diff --git a/src/mainboard/google/brox/variants/baseboard/brox/devicetree.cb b/src/mainboard/google/brox/variants/baseboard/brox/devicetree.cb
new file mode 100644
index 0000000000..186aadb52d
--- /dev/null
+++ b/src/mainboard/google/brox/variants/baseboard/brox/devicetree.cb
@@ -0,0 +1,205 @@
+chip soc/intel/alderlake
+
+ # GPE configuration
+ register "pmc_gpe0_dw0" = "GPP_A"
+ register "pmc_gpe0_dw1" = "GPP_E"
+ register "pmc_gpe0_dw2" = "GPP_F"
+
+ # EC host command ranges are in 0x800-0x8ff & 0x200-0x20f
+ register "gen1_dec" = "0x00fc0801"
+ register "gen2_dec" = "0x000c0201"
+ # EC memory map range is 0x900-0x9ff
+ register "gen3_dec" = "0x00fc0901"
+
+ # S0ix enable
+ register "s0ix_enable" = "1"
+
+ # DPTF enable
+ register "dptf_enable" = "1"
+
+ register "tcc_offset" = "10" # TCC of 90
+
+ # Enable CNVi BT
+ register "cnvi_bt_core" = "true"
+
+ register "usb2_ports[0]" = "USB2_PORT_TYPE_C(OC0)" # USB2_C0
+ register "usb2_ports[1]" = "USB2_PORT_TYPE_C(OC1)" # USB2_C1
+ register "usb2_ports[2]" = "USB2_PORT_TYPE_C(OC2)" # USB2_C2
+ register "usb2_ports[3]" = "USB2_PORT_MID(OC_SKIP)" # M.2 WWAN
+ register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # M.2 Camera
+ register "usb2_ports[8]" = "USB2_PORT_MID(OC_SKIP)" # Type-A Port A0
+ register "usb2_ports[9]" = "USB2_PORT_MID(OC_SKIP)" # M.2 Bluetooth
+
+ register "usb3_ports[0]" = "USB3_PORT_DEFAULT(OC3)" # USB3/2 Type A port A0
+ register "usb3_ports[3]" = "USB3_PORT_DEFAULT(OC_SKIP)" # M.2 WWAN
+
+ register "tcss_ports[0]" = "TCSS_PORT_DEFAULT(OC0)"
+ register "tcss_ports[1]" = "TCSS_PORT_DEFAULT(OC1)"
+ register "tcss_ports[2]" = "TCSS_PORT_DEFAULT(OC2)"
+
+ register "serial_io_i2c_mode" = "{
+ [PchSerialIoIndexI2C0] = PchSerialIoPci,
+ [PchSerialIoIndexI2C1] = PchSerialIoPci,
+ [PchSerialIoIndexI2C2] = PchSerialIoPci,
+ [PchSerialIoIndexI2C3] = PchSerialIoPci,
+ [PchSerialIoIndexI2C4] = PchSerialIoDisabled,
+ [PchSerialIoIndexI2C5] = PchSerialIoPci,
+ }"
+
+ register "serial_io_gspi_mode" = "{
+ [PchSerialIoIndexGSPI0] = PchSerialIoDisabled,
+ [PchSerialIoIndexGSPI1] = PchSerialIoPci,
+ }"
+
+ register "serial_io_uart_mode" = "{
+ [PchSerialIoIndexUART0] = PchSerialIoPci,
+ [PchSerialIoIndexUART1] = PchSerialIoDisabled,
+ [PchSerialIoIndexUART2] = PchSerialIoDisabled,
+ }"
+
+ register "pch_slp_s3_min_assertion_width" = "SLP_S3_ASSERTION_50_MS"
+ register "pch_slp_s4_min_assertion_width" = "SLP_S4_ASSERTION_1S"
+ register "pch_slp_sus_min_assertion_width" = "SLP_SUS_ASSERTION_1_S"
+ register "pch_slp_a_min_assertion_width" = "SLP_A_ASSERTION_98_MS"
+ register "pch_reset_power_cycle_duration" = "POWER_CYCLE_DURATION_1S"
+
+ # HD Audio
+ register "pch_hda_dsp_enable" = "1"
+ register "pch_hda_idisp_link_tmode" = "HDA_TMODE_8T"
+ register "pch_hda_idisp_link_frequency" = "HDA_LINKFREQ_96MHZ"
+ register "pch_hda_idisp_codec_enable" = "1"
+
+ # FIVR RFI Spread Spectrum 1.5%
+ register "fivr_spread_spectrum" = "FIVR_SS_1_5"
+
+ # Intel Common SoC Config
+ #+-------------------+---------------------------+
+ #| Field | Value |
+ #+-------------------+---------------------------+
+ #| GSPI1 | Fingerprint MCU |
+ #| I2C0 | Audio and WFC |
+ #| I2C1 | cr50 TPM. Early init is |
+ #| | required to set up a BAR |
+ #| | for TPM communication |
+ #| I2C2 | SAR0 |
+ #| I2C3 | Touchscreen |
+ #| I2C5 | Trackpad |
+ #+-------------------+---------------------------+
+ register "common_soc_config" = "{
+ .i2c[0] = {
+ .speed = I2C_SPEED_FAST,
+ .rise_time_ns = 650,
+ .fall_time_ns = 400,
+ .data_hold_time_ns = 50,
+ },
+ .i2c[1] = {
+ .speed = I2C_SPEED_FAST,
+ .rise_time_ns = 650,
+ .fall_time_ns = 400,
+ .data_hold_time_ns = 50,
+ },
+ .i2c[2] = {
+ .speed = I2C_SPEED_FAST,
+ .rise_time_ns = 900,
+ .fall_time_ns = 400,
+ .data_hold_time_ns = 50,
+ },
+ .i2c[3] = {
+ .early_init = 1,
+ .speed = I2C_SPEED_FAST,
+ .rise_time_ns = 600,
+ .fall_time_ns = 400,
+ .data_hold_time_ns = 50,
+ },
+ .i2c[5] = {
+ .speed = I2C_SPEED_FAST,
+ .rise_time_ns = 650,
+ .fall_time_ns = 400,
+ .data_hold_time_ns = 50,
+ },
+ }"
+
+ device domain 0 on
+ # The timing values can be derived from datasheet of display panel
+ # You can use EDID string to identify the type of display on the board
+ # use below command to get display info from EDID
+ # strings /sys/devices/pci0000:00/0000:00:02.0/drm/card0/card0-eDP-1/edid
+
+ # refer to display PRM document (Volume 2b: Command Reference: Registers)
+ # for more info on display control registers
+ # https://01.org/linuxgraphics/documentation/hardware-specification-prms
+ #+-----------------------------+---------------------------------------+-----+
+ #| Intel docs | devicetree.cb | eDP |
+ #+-----------------------------+---------------------------------------+-----+
+ #| Power up delay | `gpu_panel_power_up_delay` | T3 |
+ #+-----------------------------+---------------------------------------+-----+
+ #| Power on to backlight on | `gpu_panel_power_backlight_on_delay` | T7 |
+ #+-----------------------------+---------------------------------------+-----+
+ #| Power Down delay | `gpu_panel_power_down_delay` | T10 |
+ #+-----------------------------+---------------------------------------+-----+
+ #| Backlight off to power down | `gpu_panel_power_backlight_off_delay` | T9 |
+ #+-----------------------------+---------------------------------------+-----+
+ #| Power Cycle Delay | `gpu_panel_power_cycle_delay` | T12 |
+ #+-----------------------------+---------------------------------------+-----+
+ device ref igpu on
+ register "panel_cfg" = "{
+ .up_delay_ms = 200,
+ .down_delay_ms = 50,
+ .cycle_delay_ms = 500,
+ .backlight_on_delay_ms = 1,
+ .backlight_off_delay_ms = 200,
+ .backlight_pwm_hz = 200,
+ }"
+ end
+ device ref dtt on end
+# device ref tbt_pcie_rp0 off end
+# device ref tbt_pcie_rp1 off end
+# device ref tbt_pcie_rp2 off end
+# device ref tcss_xhci on end
+# device ref tcss_dma0 on end
+# device ref tcss_dma1 on end
+ device ref xhci on end
+ device ref shared_sram on end
+ device ref cnvi_wifi on
+ chip drivers/wifi/generic
+ register "wake" = "GPE0_PME_B0"
+ register "add_acpi_dma_property" = "true"
+ device generic 0 on end
+ end
+ end
+ device ref i2c3 on end
+ device ref heci1 on end
+ device ref sata on end
+ device ref pcie_rp8 on
+ # Enable SD Card PCIE 8 using clk 3
+ register "pch_pcie_rp[PCH_RP(8)]" = "{
+ .clk_src = 3,
+ .clk_req = 3,
+ .flags = PCIE_RP_HOTPLUG | PCIE_RP_LTR | PCIE_RP_AER,
+ }"
+ end #PCIE8 SD card
+ device ref pcie_rp9 on
+ # Enable NVMe PCIE 9 using clk 1
+ register "pch_pcie_rp[PCH_RP(9)]" = "{
+ .clk_src = 1,
+ .clk_req = 1,
+ .flags = PCIE_RP_LTR | PCIE_RP_AER,
+ }"
+ end #PCIE9-12 SSD
+ device ref uart0 on end
+ device ref gspi1 on end
+ device ref pch_espi on
+ chip ec/google/chromeec
+ device pnp 0c09.0 on end
+ end
+ end
+ device ref hda on
+ chip drivers/sof
+ register "spkr_tplg" = "max98360a"
+ register "jack_tplg" = "rt5682"
+ register "mic_tplg" = "_2ch_pdm0"
+ device generic 0 on end
+ end
+ end
+ end
+end
diff --git a/src/mainboard/google/brox/variants/baseboard/brox/gma-mainboard.ads b/src/mainboard/google/brox/variants/baseboard/brox/gma-mainboard.ads
new file mode 100644
index 0000000000..3b02f14d95
--- /dev/null
+++ b/src/mainboard/google/brox/variants/baseboard/brox/gma-mainboard.ads
@@ -0,0 +1,13 @@
+-- SPDX-License-Identifier: GPL-2.0-or-later
+
+with HW.GFX.GMA;
+with HW.GFX.GMA.Display_Probing;
+
+use HW.GFX.GMA;
+use HW.GFX.GMA.Display_Probing;
+
+private package GMA.Mainboard is
+ ports : constant Port_List :=
+ (eDP,
+ others => Disabled);
+end GMA.Mainboard;
diff --git a/src/mainboard/google/brox/variants/baseboard/brox/gpio.c b/src/mainboard/google/brox/variants/baseboard/brox/gpio.c
new file mode 100644
index 0000000000..6161b2ab83
--- /dev/null
+++ b/src/mainboard/google/brox/variants/baseboard/brox/gpio.c
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <baseboard/gpio.h>
+#include <baseboard/variants.h>
+#include <types.h>
+#include <soc/gpio.h>
+#include <vendorcode/google/chromeos/chromeos.h>
+
+/* Pad configuration in ramstage */
+static const struct pad_config gpio_table[] = {
+};
+
+/* Early pad configuration in bootblock */
+static const struct pad_config early_gpio_table[] = {
+};
+
+const struct pad_config *__weak variant_gpio_table(size_t *num)
+{
+ *num = ARRAY_SIZE(gpio_table);
+ return gpio_table;
+}
+
+const struct pad_config *__weak variant_gpio_override_table(size_t *num)
+{
+ *num = 0;
+ return NULL;
+}
+
+const struct pad_config *__weak variant_early_gpio_table(size_t *num)
+{
+ *num = ARRAY_SIZE(early_gpio_table);
+ return early_gpio_table;
+}
+
+static const struct cros_gpio cros_gpios[] = {
+ CROS_GPIO_REC_AL(CROS_GPIO_VIRTUAL, CROS_GPIO_DEVICE_NAME),
+ CROS_GPIO_WP_AH(GPIO_PCH_WP, CROS_GPIO_DEVICE_NAME),
+};
+
+DECLARE_WEAK_CROS_GPIOS(cros_gpios);
+
+const struct pad_config *__weak variant_romstage_gpio_table(size_t *num)
+{
+ *num = 0;
+ return NULL;
+}
diff --git a/src/mainboard/google/brox/variants/baseboard/brox/include/baseboard/ec.h b/src/mainboard/google/brox/variants/baseboard/brox/include/baseboard/ec.h
new file mode 100644
index 0000000000..722f48bb32
--- /dev/null
+++ b/src/mainboard/google/brox/variants/baseboard/brox/include/baseboard/ec.h
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef __BASEBOARD_EC_H__
+#define __BASEBOARD_EC_H__
+
+#include <baseboard/gpio.h>
+#include <ec/ec.h>
+#include <ec/google/chromeec/ec_commands.h>
+
+#define VARIANT_EC_SCI_EVENTS 0
+
+#define MAINBOARD_EC_SCI_EVENTS \
+ (EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_CONNECTED) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_LOW) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_CRITICAL) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_STATUS) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_THERMAL_THRESHOLD) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_THROTTLE_START) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_THROTTLE_STOP) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_MKBP) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_MODE_CHANGE) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_USB_MUX) |\
+ VARIANT_EC_SCI_EVENTS)
+#define MAINBOARD_EC_SMI_EVENTS \
+ (EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED))
+/* EC can wake from S5 with lid or power button */
+#define MAINBOARD_EC_S5_WAKE_EVENTS \
+ (EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON))
+/*
+ * EC can wake from S3/S0ix with:
+ * 1. Lid open
+ * 2. AC Connect/Disconnect
+ * 3. Power button
+ * 4. Key press
+ * 5. Mode change
+ * 6. Low battery
+ */
+#define MAINBOARD_EC_S3_WAKE_EVENTS \
+ (MAINBOARD_EC_S5_WAKE_EVENTS |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_CONNECTED) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEY_PRESSED) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_MODE_CHANGE) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_CRITICAL) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_SHUTDOWN))
+#define MAINBOARD_EC_S0IX_WAKE_EVENTS \
+ (MAINBOARD_EC_S3_WAKE_EVENTS |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_USB_MUX) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_HANG_DETECT))
+/* Log EC wake events plus EC shutdown events */
+#define MAINBOARD_EC_LOG_EVENTS \
+ (EC_HOST_EVENT_MASK(EC_HOST_EVENT_THERMAL_SHUTDOWN) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_SHUTDOWN) |\
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_PANIC))
+/*
+ * ACPI related definitions for ASL code.
+ */
+/* Enable Keyboard Backlight */
+#define EC_ENABLE_KEYBOARD_BACKLIGHT
+/* Enable MKBP for buttons and switches */
+#define EC_ENABLE_MKBP_DEVICE
+/* Enable LID switch and provide wake pin for EC */
+#define EC_ENABLE_LID_SWITCH
+#define EC_ENABLE_WAKE_PIN GPE_EC_WAKE
+/* Enable EC backed PD MCU device in ACPI */
+#define EC_ENABLE_PD_MCU_DEVICE
+#define SIO_EC_MEMMAP_ENABLE /* EC Memory Map Resources */
+#define SIO_EC_HOST_ENABLE /* EC Host Interface Resources */
+#define SIO_EC_ENABLE_PS2K /* Enable PS/2 Keyboard */
+
+#define EC_ENABLE_SYNC_IRQ /* Enable tight timestamp / wake support */
+
+#endif /* __BASEBOARD_EC_H__ */
diff --git a/src/mainboard/google/brox/variants/baseboard/brox/include/baseboard/gpio.h b/src/mainboard/google/brox/variants/baseboard/brox/include/baseboard/gpio.h
new file mode 100644
index 0000000000..0de7ffd36c
--- /dev/null
+++ b/src/mainboard/google/brox/variants/baseboard/brox/include/baseboard/gpio.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef __BASEBOARD_GPIO_H__
+#define __BASEBOARD_GPIO_H__
+
+#include <soc/gpe.h>
+#include <soc/gpio.h>
+
+/* eSPI virtual wire reporting */
+#define EC_SCI_GPI GPE0_ESPI
+/* EC wake is EC_PCH_INT which is routed to GPP_F17 pin */
+#define GPE_EC_WAKE GPE0_DW2_17
+/* WP signal to PCH */
+#define GPIO_PCH_WP GPP_E15
+/* EC in RW or RO */
+#define GPIO_EC_IN_RW GPP_F18
+/* Used to gate SoC's SLP_S0# signal */
+#define GPIO_SLP_S0_GATE GPP_F9
+/* GPIO IRQ for tight timestamps / wake support */
+#define EC_SYNC_IRQ GPP_F17_IRQ
+
+#endif /* __BASEBOARD_GPIO_H__ */
diff --git a/src/mainboard/google/brox/variants/baseboard/brox/memory.c b/src/mainboard/google/brox/variants/baseboard/brox/memory.c
new file mode 100644
index 0000000000..bcad9b4be9
--- /dev/null
+++ b/src/mainboard/google/brox/variants/baseboard/brox/memory.c
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <baseboard/gpio.h>
+#include <baseboard/variants.h>
+#include <gpio.h>
+
+static const struct mb_cfg baseboard_memcfg = {
+ .type = MEM_TYPE_LP4X,
+
+ .rcomp = {
+ /* Baseboard uses only 100ohm Rcomp resistors */
+ .resistor = 100,
+
+ /* Baseboard Rcomp target values */
+ .targets = {40, 30, 30, 30, 30},
+ },
+
+ /* DQ byte map */
+ .lpx_dq_map = {
+ .ddr0 = {
+ .dq0 = { 9, 11, 8, 10, 12, 14, 13, 15, },
+ .dq1 = { 4, 7, 6, 5, 2, 3, 0, 1, },
+ },
+ .ddr1 = {
+ .dq0 = { 15, 12, 14, 13, 9, 10, 11, 8, },
+ .dq1 = { 0, 1, 3, 2, 7, 5, 4, 6, },
+ },
+ .ddr2 = {
+ .dq0 = { 2, 3, 1, 0, 6, 7, 5, 4, },
+ .dq1 = { 15, 9, 14, 8, 11, 10, 13, 12, },
+ },
+ .ddr3 = {
+ .dq0 = { 3, 1, 2, 0, 4, 6, 7, 5, },
+ .dq1 = { 13, 15, 14, 12, 11, 9, 8, 10, },
+ },
+ .ddr4 = {
+ .dq0 = { 13, 12, 14, 15, 9, 8, 10, 11, },
+ .dq1 = { 4, 7, 5, 6, 1, 2, 0, 3, },
+ },
+ .ddr5 = {
+ .dq0 = { 5, 0, 6, 4, 3, 1, 7, 2, },
+ .dq1 = { 11, 9, 10, 8, 15, 12, 14, 13, },
+ },
+ .ddr6 = {
+ .dq0 = { 15, 12, 14, 13, 10, 9, 11, 8, },
+ .dq1 = { 0, 1, 2, 3, 5, 6, 4, 7, },
+ },
+ .ddr7 = {
+ .dq0 = { 0, 3, 1, 2, 4, 5, 6, 7, },
+ .dq1 = { 11, 8, 13, 14, 9, 12, 15, 10, },
+ },
+ },
+
+ /* DQS CPU<>DRAM map */
+ .lpx_dqs_map = {
+ .ddr0 = { .dqs0 = 1, .dqs1 = 0 },
+ .ddr1 = { .dqs0 = 1, .dqs1 = 0 },
+ .ddr2 = { .dqs0 = 0, .dqs1 = 1 },
+ .ddr3 = { .dqs0 = 0, .dqs1 = 1 },
+ .ddr4 = { .dqs0 = 1, .dqs1 = 0 },
+ .ddr5 = { .dqs0 = 0, .dqs1 = 1 },
+ .ddr6 = { .dqs0 = 1, .dqs1 = 0 },
+ .ddr7 = { .dqs0 = 0, .dqs1 = 1 },
+ },
+
+ .ect = 1, /* Enable Early Command Training */
+};
+
+const struct mb_cfg *__weak variant_memory_params(void)
+{
+ return &baseboard_memcfg;
+}
+
+int __weak variant_memory_sku(void)
+{
+ /*
+ * Memory configuration board straps
+ * GPIO_MEM_CONFIG_0 GPP_E11
+ * GPIO_MEM_CONFIG_1 GPP_E2
+ * GPIO_MEM_CONFIG_2 GPP_E1
+ * GPIO_MEM_CONFIG_3 GPP_E12
+ */
+ gpio_t spd_gpios[] = {
+ GPP_E11,
+ GPP_E2,
+ GPP_E1,
+ GPP_E12,
+ };
+
+ return gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios));
+}
+
+bool __weak variant_is_half_populated(void)
+{
+ /* GPIO_MEM_CH_SEL GPP_E13 */
+ return gpio_get(GPP_E13);
+}
+
+void __weak variant_get_spd_info(struct mem_spd *spd_info)
+{
+ spd_info->topo = MEM_TOPO_MEMORY_DOWN;
+ spd_info->cbfs_index = variant_memory_sku();
+}
diff --git a/src/mainboard/google/brox/variants/baseboard/brox/ramstage.c b/src/mainboard/google/brox/variants/baseboard/brox/ramstage.c
new file mode 100644
index 0000000000..78538631e7
--- /dev/null
+++ b/src/mainboard/google/brox/variants/baseboard/brox/ramstage.c
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <acpi/acpi_device.h>
+#include <baseboard/variants.h>
+#include <console/console.h>
+#include <device/pci_ops.h>
+#include <drivers/intel/dptf/chip.h>
+#include <intelblocks/power_limit.h>
+#include <soc/pci_devs.h>
+
+
+WEAK_DEV_PTR(dptf_policy);
+
+void variant_update_power_limits(const struct cpu_power_limits *limits, size_t num_entries)
+{
+ if (!num_entries)
+ return;
+
+ const struct device *policy_dev = DEV_PTR(dptf_policy);
+ if (!policy_dev)
+ return;
+
+ struct drivers_intel_dptf_config *config = policy_dev->chip_info;
+
+ uint16_t mchid = pci_s_read_config16(PCI_DEV(0, 0, 0), PCI_DEVICE_ID);
+
+ u8 tdp = get_cpu_tdp();
+
+ for (size_t i = 0; i < num_entries; i++) {
+ if (mchid == limits[i].mchid && tdp == limits[i].cpu_tdp) {
+ struct dptf_power_limits *settings = &config->controls.power_limits;
+ config_t *conf = config_of_soc();
+ struct soc_power_limits_config *soc_config = conf->power_limits_config;
+ settings->pl1.min_power = limits[i].pl1_min_power;
+ settings->pl1.max_power = limits[i].pl1_max_power;
+ settings->pl2.min_power = limits[i].pl2_min_power;
+ settings->pl2.max_power = limits[i].pl2_max_power;
+ soc_config->tdp_pl4 = DIV_ROUND_UP(limits[i].pl4_power,
+ MILLIWATTS_TO_WATTS);
+ printk(BIOS_INFO, "Overriding power limits PL1 (%u, %u) PL2 (%u, %u) PL4 (%u)\n",
+ limits[i].pl1_min_power,
+ limits[i].pl1_max_power,
+ limits[i].pl2_min_power,
+ limits[i].pl2_max_power,
+ limits[i].pl4_power);
+ }
+ }
+}
diff --git a/src/mainboard/google/brox/variants/baseboard/include/baseboard/variants.h b/src/mainboard/google/brox/variants/baseboard/include/baseboard/variants.h
new file mode 100644
index 0000000000..ad8eb05833
--- /dev/null
+++ b/src/mainboard/google/brox/variants/baseboard/include/baseboard/variants.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef __BASEBOARD_VARIANTS_H__
+#define __BASEBOARD_VARIANTS_H__
+
+#include <chip.h>
+#include <soc/gpio.h>
+#include <soc/meminit.h>
+#include <stdint.h>
+
+/* The next set of functions return the gpio table and fill in the number of entries for
+ * each table.
+ */
+
+const struct pad_config *variant_gpio_table(size_t *num);
+const struct pad_config *variant_gpio_override_table(size_t *num);
+const struct pad_config *variant_early_gpio_table(size_t *num);
+const struct pad_config *variant_romstage_gpio_table(size_t *num);
+void fw_config_gpio_padbased_override(struct pad_config *padbased_table);
+
+const struct mb_cfg *variant_memory_params(void);
+void variant_get_spd_info(struct mem_spd *spd_info);
+int variant_memory_sku(void);
+bool variant_is_half_populated(void);
+void variant_update_soc_chip_config(struct soc_intel_alderlake_config *config);
+void variant_fill_ssdt(const struct device *dev);
+void variant_configure_pads(void);
+
+enum s0ix_entry {
+ S0IX_EXIT,
+ S0IX_ENTRY,
+};
+
+void variant_generate_s0ix_hook(enum s0ix_entry entry);
+
+/* Modify devictree settings during ramstage */
+void variant_devtree_update(void);
+
+void variant_update_descriptor(void);
+
+struct cpu_power_limits {
+ uint16_t mchid;
+ u8 cpu_tdp;
+ unsigned int pl1_min_power;
+ unsigned int pl1_max_power;
+ unsigned int pl2_min_power;
+ unsigned int pl2_max_power;
+ unsigned int pl4_power;
+};
+
+struct system_power_limits {
+ uint16_t mchid;
+ u8 cpu_tdp;
+ /* PsysPL2 in Watts */
+ unsigned int psys_pl2_power;
+};
+
+struct psys_config {
+ /*
+ * The efficiency of type-c chargers
+ * For example, 'efficiency = 97' means setting 97% of max power to account for
+ * cable loss and FET Rdson loss in the path from the source.
+ */
+ unsigned int efficiency;
+
+ /* The maximum current maps to the Psys signal */
+ unsigned int psys_imax_ma;
+
+ /* The voltage of barrel jack */
+ unsigned int bj_volts_mv;
+};
+
+/* Modify Power Limit devictree settings during ramstage */
+void variant_update_power_limits(const struct cpu_power_limits *limits,
+ size_t num_entries);
+
+
+/*
+ * Modify Power Limit and PsysPL devictree settings during ramstage.
+ * Note, this function must be called in front of calling variant_update_power_limits.
+ */
+void variant_update_psys_power_limits(const struct cpu_power_limits *limits,
+ const struct system_power_limits *sys_limits,
+ size_t num_entries,
+ const struct psys_config *config);
+
+void variant_init(void);
+void variant_finalize(void);
+
+#endif /*__BASEBOARD_VARIANTS_H__ */
diff --git a/src/mainboard/google/brox/variants/brox/Makefile.inc b/src/mainboard/google/brox/variants/brox/Makefile.inc
new file mode 100644
index 0000000000..4a7ff71e45
--- /dev/null
+++ b/src/mainboard/google/brox/variants/brox/Makefile.inc
@@ -0,0 +1,8 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+bootblock-y += gpio.c
+romstage-y += gpio.c
+ramstage-$(CONFIG_FW_CONFIG) += fw_config.c
+ramstage-$(CONFIG_FW_CONFIG) += variant.c
+ramstage-y += gpio.c
+ramstage-y += ramstage.c
diff --git a/src/mainboard/google/brox/variants/brox/data.vbt b/src/mainboard/google/brox/variants/brox/data.vbt
new file mode 100644
index 0000000000..716d09f557
--- /dev/null
+++ b/src/mainboard/google/brox/variants/brox/data.vbt
Binary files differ
diff --git a/src/mainboard/google/brox/variants/brox/fw_config.c b/src/mainboard/google/brox/variants/brox/fw_config.c
new file mode 100644
index 0000000000..d1bdc80901
--- /dev/null
+++ b/src/mainboard/google/brox/variants/brox/fw_config.c
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <bootstate.h>
+
+static void fw_config_handle(void *unused)
+{
+}
+BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, fw_config_handle, NULL);
diff --git a/src/mainboard/google/brox/variants/brox/gpio.c b/src/mainboard/google/brox/variants/brox/gpio.c
new file mode 100644
index 0000000000..444adc4fa9
--- /dev/null
+++ b/src/mainboard/google/brox/variants/brox/gpio.c
@@ -0,0 +1,218 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <baseboard/variants.h>
+#include <boardid.h>
+#include <soc/gpio.h>
+
+static const struct pad_config board_id0_1_overrides[] = {
+ /* B2 : VRALERT# ==> NC */
+ PAD_NC(GPP_B2, NONE),
+ /* B7 : ISH_12C1_SDA ==> PCH_I2C_TPM_SDA */
+ PAD_CFG_NF_LOCK(GPP_B7, NONE, NF2, LOCK_CONFIG),
+ /* B8 : ISH_12C1_SCL ==> PCH_I2C_TPM_SCL */
+ PAD_CFG_NF_LOCK(GPP_B8, NONE, NF2, LOCK_CONFIG),
+ /* B15 : TIME_SYNC0 ==> NC */
+ PAD_NC(GPP_B15, NONE),
+ /* C3 : SML0CLK ==> NC */
+ PAD_NC(GPP_C3, NONE),
+ /* C4 : SML0DATA ==> NC */
+ PAD_NC(GPP_C4, NONE),
+ /* D13 : ISH_UART0_RXD ==> PCH_I2C_CAM_SDA */
+ PAD_CFG_NF(GPP_D13, NONE, DEEP, NF3),
+ /* D14 : ISH_UART0_TXD ==> PCH_I2C_CAM_SCL */
+ PAD_CFG_NF(GPP_D14, NONE, DEEP, NF3),
+ /* F19 : SRCCLKREQ6# ==> WWAN_SIM1_DET_OD */
+ PAD_CFG_GPI(GPP_F19, UP_20K, DEEP),
+ /* F20 : EXT_PWR_GATE# ==> HPS_RST_R */
+ PAD_CFG_GPO(GPP_F20, 0, DEEP),
+ /* F21 : EXT_PWR_GATE2# ==> WAKE_ON_WWAN_ODL */
+ PAD_NC(GPP_F21, NONE),
+ /* H13 : I2C7_SCL ==> EN_PP3300_SD */
+ PAD_CFG_GPO(GPP_H13, 1, DEEP),
+ /* H21 : IMGCLKOUT2 ==> WLAN_INT_L */
+ PAD_CFG_GPI_APIC(GPP_H21, NONE, DEEP, EDGE_SINGLE, NONE),
+ /* GPD2: LAN_WAKE# ==> NC */
+ PAD_NC(GPD2, NONE),
+};
+
+/* Early pad configuration in bootblock for board id < 2 */
+static const struct pad_config early_gpio_table[] = {
+ /* A13 : PMC_I2C_SCL ==> GSC_PCH_INT_ODL */
+ PAD_CFG_GPI_APIC(GPP_A13, NONE, PLTRST, LEVEL, INVERT),
+ /* B7 : ISH_12C1_SDA ==> PCH_I2C_TPM_SDA */
+ PAD_CFG_NF(GPP_B7, NONE, DEEP, NF2),
+ /* B8 : ISH_12C1_SCL ==> PCH_I2C_TPM_SCL */
+ PAD_CFG_NF(GPP_B8, NONE, DEEP, NF2),
+ /*
+ * D1 : ISH_GP1 ==> FP_RST_ODL
+ * FP_RST_ODL comes out of reset as hi-z and does not have an external pull-down.
+ * To ensure proper power sequencing for the FPMCU device, reset signal is driven low
+ * early on in bootblock, followed by enabling of power. Reset signal is deasserted
+ * later on in ramstage. Since reset signal is asserted in bootblock, it results in
+ * FPMCU not working after a S3 resume. This is a known issue.
+ */
+ PAD_CFG_GPO(GPP_D1, 0, DEEP),
+ /* D2 : ISH_GP2 ==> EN_FP_PWR */
+ PAD_CFG_GPO(GPP_D2, 1, DEEP),
+ /* E0 : SATAXPCIE0 ==> WWAN_PERST_L (updated in ramstage) */
+ PAD_CFG_GPO(GPP_E0, 0, DEEP),
+ /* E13 : THC0_SPI1_IO2 ==> MEM_CH_SEL */
+ PAD_CFG_GPI(GPP_E13, NONE, DEEP),
+ /* E16 : RSVD_TP ==> WWAN_RST_L (updated in ramstage) */
+ PAD_CFG_GPO(GPP_E16, 0, DEEP),
+ /* E15 : RSVD_TP ==> PCH_WP_OD */
+ PAD_CFG_GPI_GPIO_DRIVER(GPP_E15, NONE, DEEP),
+ /* F18 : THC1_SPI2_INT# ==> EC_IN_RW_OD */
+ PAD_CFG_GPI(GPP_F18, NONE, DEEP),
+ /* F21 : EXT_PWR_GATE2# ==> NC */
+ PAD_NC(GPP_F21, NONE),
+ /* H10 : UART0_RXD ==> UART_PCH_RX_DBG_TX */
+ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2),
+ /* H11 : UART0_TXD ==> UART_PCH_TX_DBG_RX */
+ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2),
+ /* H13 : I2C7_SCL ==> EN_PP3300_SD */
+ PAD_CFG_GPO(GPP_H13, 1, DEEP),
+};
+
+/* Early pad configuration in bootblock for board id 2 */
+static const struct pad_config early_gpio_table_id2[] = {
+ /* A12 : SATAXPCIE1 ==> EN_PP3300_WWAN */
+ PAD_CFG_GPO(GPP_A12, 1, DEEP),
+ /* A13 : PMC_I2C_SCL ==> GSC_PCH_INT_ODL */
+ PAD_CFG_GPI_APIC(GPP_A13, NONE, PLTRST, LEVEL, INVERT),
+ /* B4 : PROC_GP3 ==> SSD_PERST_L */
+ PAD_CFG_GPO(GPP_B4, 0, DEEP),
+ /* B7 : ISH_12C1_SDA ==> PCH_I2C_TPM_SDA */
+ PAD_CFG_NF(GPP_B7, NONE, DEEP, NF2),
+ /* B8 : ISH_12C1_SCL ==> PCH_I2C_TPM_SCL */
+ PAD_CFG_NF(GPP_B8, NONE, DEEP, NF2),
+ /*
+ * D1 : ISH_GP1 ==> FP_RST_ODL
+ * FP_RST_ODL comes out of reset as hi-z and does not have an external pull-down.
+ * To ensure proper power sequencing for the FPMCU device, reset signal is driven low
+ * early on in bootblock, followed by enabling of power. Reset signal is deasserted
+ * later on in ramstage. Since reset signal is asserted in bootblock, it results in
+ * FPMCU not working after a S3 resume. This is a known issue.
+ */
+ PAD_CFG_GPO(GPP_D1, 0, DEEP),
+ /* D2 : ISH_GP2 ==> EN_FP_PWR */
+ PAD_CFG_GPO(GPP_D2, 1, DEEP),
+ /* D11 : ISH_SPI_MISO ==> EN_PP3300_SSD */
+ PAD_CFG_GPO(GPP_D11, 1, DEEP),
+ /* E0 : SATAXPCIE0 ==> WWAN_PERST_L (updated in ramstage) */
+ PAD_CFG_GPO(GPP_E0, 0, DEEP),
+ /* E13 : THC0_SPI1_IO2 ==> MEM_CH_SEL */
+ PAD_CFG_GPI(GPP_E13, NONE, DEEP),
+ /* E16 : RSVD_TP ==> WWAN_RST_L (updated in ramstage) */
+ PAD_CFG_GPO(GPP_E16, 0, DEEP),
+ /* E15 : RSVD_TP ==> PCH_WP_OD */
+ PAD_CFG_GPI_GPIO_DRIVER(GPP_E15, NONE, DEEP),
+ /* F18 : THC1_SPI2_INT# ==> EC_IN_RW_OD */
+ PAD_CFG_GPI(GPP_F18, NONE, DEEP),
+ /* F21 : EXT_PWR_GATE2# ==> WWAN_FCPO_L (updated in romstage) */
+ PAD_CFG_GPO(GPP_F21, 0, DEEP),
+ /* H10 : UART0_RXD ==> UART_PCH_RX_DBG_TX */
+ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2),
+ /* H11 : UART0_TXD ==> UART_PCH_TX_DBG_RX */
+ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2),
+ /* H13 : I2C7_SCL ==> EN_PP3300_SD */
+ PAD_NC(GPP_H13, UP_20K),
+};
+
+/* Early pad configuration in bootblock for board id 4 */
+static const struct pad_config early_gpio_table_id4[] = {
+ /* A12 : SATAXPCIE1 ==> EN_PP3300_WWAN */
+ PAD_CFG_GPO(GPP_A12, 1, DEEP),
+ /* A13 : PMC_I2C_SCL ==> GSC_PCH_INT_ODL */
+ PAD_CFG_GPI_APIC(GPP_A13, NONE, PLTRST, LEVEL, INVERT),
+ /* B4 : PROC_GP3 ==> SSD_PERST_L */
+ PAD_CFG_GPO(GPP_B4, 0, DEEP),
+ /* H6 : ISH_12C1_SDA ==> PCH_I2C_TPM_SDA */
+ PAD_CFG_NF(GPP_H6, NONE, DEEP, NF1),
+ /* H7 : ISH_12C1_SCL ==> PCH_I2C_TPM_SCL */
+ PAD_CFG_NF(GPP_H7, NONE, DEEP, NF1),
+ /*
+ * D1 : ISH_GP1 ==> FP_RST_ODL
+ * FP_RST_ODL comes out of reset as hi-z and does not have an external
+ * pull-down. To ensure proper power sequencing for the FPMCU device,
+ * reset signal is driven low early on in bootblock, followed by
+ * enabling of power. Reset signal is deasserted later on in ramstage.
+ * Since reset signal is asserted in bootblock, it results in FPMCU not
+ * working after a S3 resume. This is a known issue.
+ */
+ PAD_CFG_GPO(GPP_D1, 0, DEEP),
+ /* D2 : ISH_GP2 ==> EN_FP_PWR */
+ PAD_CFG_GPO(GPP_D2, 1, DEEP),
+ /* D11 : ISH_SPI_MISO ==> EN_PP3300_SSD */
+ PAD_CFG_GPO(GPP_D11, 1, DEEP),
+ /* E0 : SATAXPCIE0 ==> WWAN_PERST_L (updated in ramstage) */
+ PAD_CFG_GPO(GPP_E0, 0, DEEP),
+ /* E13 : THC0_SPI1_IO2 ==> MEM_CH_SEL */
+ PAD_CFG_GPI(GPP_E13, NONE, DEEP),
+ /* E16 : RSVD_TP ==> WWAN_RST_L (updated in ramstage) */
+ PAD_CFG_GPO(GPP_E16, 0, DEEP),
+ /* E15 : RSVD_TP ==> PCH_WP_OD */
+ PAD_CFG_GPI_GPIO_DRIVER(GPP_E15, NONE, DEEP),
+ /* F18 : THC1_SPI2_INT# ==> EC_IN_RW_OD */
+ PAD_CFG_GPI(GPP_F18, NONE, DEEP),
+ /* F21 : EXT_PWR_GATE2# ==> WWAN_FCPO_L (updated in romstage) */
+ PAD_CFG_GPO(GPP_F21, 0, DEEP),
+ /* H10 : UART0_RXD ==> UART_PCH_RX_DBG_TX */
+ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2),
+ /* H11 : UART0_TXD ==> UART_PCH_TX_DBG_RX */
+ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2),
+ /* H13 : I2C7_SCL ==> EN_PP3300_SD */
+ PAD_NC(GPP_H13, UP_20K),
+};
+
+static const struct pad_config romstage_gpio_table[] = {
+ /* B4 : PROC_GP3 ==> SSD_PERST_L */
+ PAD_CFG_GPO(GPP_B4, 1, DEEP),
+
+ /* Enable touchscreen, hold in reset */
+ /* C0 : SMBCLK ==> EN_PP3300_TCHSCR */
+ PAD_CFG_GPO(GPP_C0, 1, DEEP),
+ /* C1 : SMBDATA ==> USI_RST_L */
+ PAD_CFG_GPO(GPP_C1, 0, DEEP),
+
+ /* D1 : ISH_GP1 ==> FP_RST_ODL */
+ PAD_CFG_GPO(GPP_D1, 0, DEEP),
+ /* D2 : ISH_GP2 ==> EN_FP_PWR */
+ PAD_CFG_GPO(GPP_D2, 0, DEEP),
+
+ /* F21 : EXT_PWR_GATE2# ==> WWAN_FCPO_L (set here for correct power sequencing) */
+ PAD_CFG_GPO(GPP_F21, 1, DEEP),
+};
+
+const struct pad_config *variant_gpio_override_table(size_t *num)
+{
+ const uint32_t id = board_id();
+ if (id == BOARD_ID_UNKNOWN || id < 2) {
+ *num = ARRAY_SIZE(board_id0_1_overrides);
+ return board_id0_1_overrides;
+ }
+
+ *num = 0;
+ return NULL;
+}
+
+const struct pad_config *variant_early_gpio_table(size_t *num)
+{
+ const uint32_t id = board_id();
+ if (id == BOARD_ID_UNKNOWN || id < 2) {
+ *num = ARRAY_SIZE(early_gpio_table);
+ return early_gpio_table;
+ } else if (id >= 4) {
+ *num = ARRAY_SIZE(early_gpio_table_id4);
+ return early_gpio_table_id4;
+ }
+
+ *num = ARRAY_SIZE(early_gpio_table_id2);
+ return early_gpio_table_id2;
+}
+
+const struct pad_config *variant_romstage_gpio_table(size_t *num)
+{
+ *num = ARRAY_SIZE(romstage_gpio_table);
+ return romstage_gpio_table;
+}
diff --git a/src/mainboard/google/brox/variants/brox/include/variant/ec.h b/src/mainboard/google/brox/variants/brox/include/variant/ec.h
new file mode 100644
index 0000000000..4fc0622f15
--- /dev/null
+++ b/src/mainboard/google/brox/variants/brox/include/variant/ec.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef MAINBOARD_EC_H
+#define MAINBOARD_EC_H
+
+#include <baseboard/ec.h>
+
+#endif /* MAINBOARD_GPIO_H */
diff --git a/src/mainboard/google/brox/variants/brox/include/variant/gpio.h b/src/mainboard/google/brox/variants/brox/include/variant/gpio.h
new file mode 100644
index 0000000000..3179c6fc1f
--- /dev/null
+++ b/src/mainboard/google/brox/variants/brox/include/variant/gpio.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef __MAINBOARD_GPIO_H__
+#define __MAINBOARD_GPIO_H__
+
+#include <baseboard/gpio.h>
+
+#define T1_OFF_MS 16
+#define T2_OFF_MS 2
+#define WWAN_FCPO GPP_F21
+#define WWAN_RST GPP_E16
+#define WWAN_PERST GPP_E0
+
+#endif /* __MAINBOARD_GPIO_H__ */
diff --git a/src/mainboard/google/brox/variants/brox/memory/Makefile.inc b/src/mainboard/google/brox/variants/brox/memory/Makefile.inc
new file mode 100644
index 0000000000..3b4cd12477
--- /dev/null
+++ b/src/mainboard/google/brox/variants/brox/memory/Makefile.inc
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# This is an auto-generated file. Do not edit!!
+# Generated by:
+# ./util/spd_tools/bin/part_id_gen ADL lp5 src/mainboard/google/brox/variants/brox/memory src/mainboard/google/brox/variants/brox/memory/mem_parts_used.txt
+
+SPD_SOURCES =
+SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 0(0b0000) Parts = MT62F512M32D2DR-031 WT:B
diff --git a/src/mainboard/google/brox/variants/brox/memory/dram_id.generated.txt b/src/mainboard/google/brox/variants/brox/memory/dram_id.generated.txt
new file mode 100644
index 0000000000..4699178726
--- /dev/null
+++ b/src/mainboard/google/brox/variants/brox/memory/dram_id.generated.txt
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# This is an auto-generated file. Do not edit!!
+# Generated by:
+# ./util/spd_tools/bin/part_id_gen ADL lp5 src/mainboard/google/brox/variants/brox/memory src/mainboard/google/brox/variants/brox/memory/mem_parts_used.txt
+
+DRAM Part Name ID to assign
+MT62F512M32D2DR-031 WT:B 0 (0000)
diff --git a/src/mainboard/google/brox/variants/brox/memory/mem_parts_used.txt b/src/mainboard/google/brox/variants/brox/memory/mem_parts_used.txt
new file mode 100644
index 0000000000..cbae2e1f51
--- /dev/null
+++ b/src/mainboard/google/brox/variants/brox/memory/mem_parts_used.txt
@@ -0,0 +1 @@
+MT62F512M32D2DR-031 WT:B
diff --git a/src/mainboard/google/brox/variants/brox/overridetree.cb b/src/mainboard/google/brox/variants/brox/overridetree.cb
new file mode 100644
index 0000000000..a5e2217fef
--- /dev/null
+++ b/src/mainboard/google/brox/variants/brox/overridetree.cb
@@ -0,0 +1,4 @@
+chip soc/intel/alderlake
+ device domain 0 on
+ end
+end
diff --git a/src/mainboard/google/brox/variants/brox/ramstage.c b/src/mainboard/google/brox/variants/brox/ramstage.c
new file mode 100644
index 0000000000..b468320356
--- /dev/null
+++ b/src/mainboard/google/brox/variants/brox/ramstage.c
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <baseboard/variants.h>
+#include <device/pci_ids.h>
+
+const struct cpu_power_limits limits[] = {
+ /* SKU_ID, TDP (Watts), pl1_min, pl1_max, pl2_min, pl2_max, pl4 */
+ /* All values are for performance config as per document #686872 */
+ { PCI_DID_INTEL_RPL_P_ID_1, 45, 18000, 45000, 115000, 115000, 210000 },
+ { PCI_DID_INTEL_RPL_P_ID_2, 28, 10000, 28000, 64000, 64000, 126000 },
+ { PCI_DID_INTEL_RPL_P_ID_3, 15, 6000, 15000, 55000, 55000, 114000 },
+};
+
+void variant_devtree_update(void)
+{
+ size_t total_entries = ARRAY_SIZE(limits);
+ variant_update_power_limits(limits, total_entries);
+}
diff --git a/src/mainboard/google/brox/variants/brox/variant.c b/src/mainboard/google/brox/variants/brox/variant.c
new file mode 100644
index 0000000000..acb5b66f6c
--- /dev/null
+++ b/src/mainboard/google/brox/variants/brox/variant.c
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <chip.h>
+#include <fw_config.h>
+#include <baseboard/variants.h>
+
+void variant_update_soc_chip_config(struct soc_intel_alderlake_config *config)
+{
+}
diff --git a/src/mainboard/google/brox/wwan_power.asl b/src/mainboard/google/brox/wwan_power.asl
new file mode 100644
index 0000000000..f19a5ef4e9
--- /dev/null
+++ b/src/mainboard/google/brox/wwan_power.asl
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <variant/gpio.h>
+
+Method (MPTS, 1)
+{
+#if CONFIG(HAVE_PCIE_WWAN)
+ \_SB.PCI0.CTXS(WWAN_PERST);
+ Sleep(T1_OFF_MS)
+#endif
+ \_SB.PCI0.CTXS(WWAN_RST);
+ Sleep(T2_OFF_MS)
+ \_SB.PCI0.CTXS(WWAN_FCPO);
+}