summaryrefslogtreecommitdiff
path: root/src/mainboard/google/brox/acpi
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/brox/acpi
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/brox/acpi')
-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
11 files changed, 1203 insertions, 0 deletions
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)
+}