Tim Wawrzynczak has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/62931 )
Change subject: mb/google/brya/: Add PEG and initial Nvidia dGPU ASL support ......................................................................
mb/google/brya/: Add PEG and initial Nvidia dGPU ASL support
Some brya variants will use a GN20 series Nvidia GPU, which requires quite a bit of ACPI support code to be written for it. This patch lands a decent bit of the initial code for it on the brya platform, including:
1) PEG RTD3 methods 2) DGPU power operations (RTD3 and GCOFF, NVJT _DSM and other Methods) 3) NVOP _DSM method
There will be more support to come later, this is all written to specifications from the Nvidia Software Design Guide for GN20.
BUG=b:214581763 TEST=build patch train
Signed-off-by: Tim Wawrzynczak twawrzynczak@chromium.org Change-Id: Ifce1610210e9636e87dda4b55c8287334adfcc42 --- M src/mainboard/google/brya/Kconfig A src/mainboard/google/brya/acpi/gpu_top.asl A src/mainboard/google/brya/acpi/nvjt.asl A src/mainboard/google/brya/acpi/nvop.asl A src/mainboard/google/brya/acpi/peg.asl A src/mainboard/google/brya/acpi/power.asl A src/mainboard/google/brya/acpi/utility.asl M src/mainboard/google/brya/dsdt.asl 8 files changed, 713 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/31/62931/1
diff --git a/src/mainboard/google/brya/Kconfig b/src/mainboard/google/brya/Kconfig index 1d29b6f..a7435b9 100644 --- a/src/mainboard/google/brya/Kconfig +++ b/src/mainboard/google/brya/Kconfig @@ -252,4 +252,9 @@ config HAVE_SLP_S0_GATE def_bool n
+config INCLUDE_NVIDIA_GPU_ASL + def_bool n + help + Select this if the variant has an Nvidia GN20 GPU attached to PEG1 + endif # BOARD_GOOGLE_BRYA_COMMON diff --git a/src/mainboard/google/brya/acpi/gpu_top.asl b/src/mainboard/google/brya/acpi/gpu_top.asl new file mode 100644 index 0000000..b893ed5 --- /dev/null +++ b/src/mainboard/google/brya/acpi/gpu_top.asl @@ -0,0 +1,81 @@ +/* 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 + +#define UUID_NVOP "a486d8f8-0bda-471b-a72b-6042a6b5bee0" +#define UUID_NVJT "cbeca351-067b-4924-9cbd-b46b00b86f34" + +#define REVISION_MIN_NVOP 0x100 +#define REVISION_MIN_NVJT 0x100 + +#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 + +Scope (_SB.PCI0.PEG1) +{ + Device (PEGP) + { + Name (_ADR, 0x0) + OperationRegion (PCIC, PCI_Config, 0x00, 0x100) + Field (PCIC, DWordAcc, NoLock, Preserve) + { + VGAR, 2048, /* VGA Registers */ + } + + #include "utility.asl" + #include "power.asl" + #include "nvop.asl" + #include "nvjt.asl" + + 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)) + } + } + + Return (NV_ERROR_UNSUPPORTED) + } + } + + #include "peg.asl" +} diff --git a/src/mainboard/google/brya/acpi/nvjt.asl b/src/mainboard/google/brya/acpi/nvjt.asl new file mode 100644 index 0000000..200bcc3 --- /dev/null +++ b/src/mainboard/google/brya/acpi/nvjt.asl @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#define JT_FUNC_SUPPORT 0 +#define JT_FUNC_CAPS 1 +#define JT_FUNC_POWERCONTROL 2 +#define JT_FUNC_PLATPOLICY 3 + +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 */ + (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 */ + + 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 (GC6E == GC6_STATE_ENTERED) + { + /* GC6 */ + CGPS = 1 + CGCS = 1 + } + Else + { + CGPS = 0 + CGCS = 3 + } + } + Case (NVJT_GPC_EGNS) + { + /* Enter GC6; no self-refresh */ + GC6I() + CPSS = 1 + } + Case (NVJT_GPC_EGIS) + { + /* Enter GC6; enable self-refresh */ + GC6I() + If (ToInteger (PPC) == 0) + { + CPSS = 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/brya/acpi/nvop.asl b/src/mainboard/google/brya/acpi/nvop.asl new file mode 100644 index 0000000..cd1bdbd --- /dev/null +++ b/src/mainboard/google/brya/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 (_SB.PCI0.PEG1.PGPR._STA == 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/brya/acpi/peg.asl b/src/mainboard/google/brya/acpi/peg.asl new file mode 100644 index 0000000..e6c4d73 --- /dev/null +++ b/src/mainboard/google/brya/acpi/peg.asl @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +External (_SB.PCI0.DGPU, DeviceObj) + +OperationRegion (PCIC, PCI_Config, 0x00, 0xff) +Field (PCIC, AnyAcc, NoLock, Preserve) +{ + Offset (0x52), + , 13, + LASX, 1, /* Link Active Status */ + 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 (16) + 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 (16) + Local0-- + } + + NCB7 = 0 + Local0 = 8 + While (Local0 > 0) + { + If (LASX == 1) + { + Break + } + + Sleep (16) + Local0-- + } +} + +/* PEG Power Resource */ +PowerResource (PGPR, 0, 0) +{ + Method (_ON, 0, Serialized) + { + /* Power up GPU from GCOFF (or GC6 exit if deferred) */ + _SB.PCI0.PEG1.PEGP._ON() + _STA = 1 + } + Method (_OFF, 0, Serialized) + { + /* Power down GPU to GCOFF (or GC6 entry if deferred) */ + _STA = 0 + _SB.PCI0.PEG1.PEGP._ON() + } + Name (_STA, 0) +} + +Name (_PR0, Package() { PGPR }) +Name (_PR2, Package() { PGPR }) +Name (_PR3, Package() { PGPR }) diff --git a/src/mainboard/google/brya/acpi/power.asl b/src/mainboard/google/brya/acpi/power.asl new file mode 100644 index 0000000..cd36e80 --- /dev/null +++ b/src/mainboard/google/brya/acpi/power.asl @@ -0,0 +1,304 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* Misc. power sequencing GPU signals */ +#define GPIO_GPU_PERST_L 3 /* GPP_B3 */ +#define GPIO_GPU_NVVDD_EN 59 /* GPP_A17 */ +#define GPIO_GPU_ALLRAILS_PG 355 /* GPP_E5 */ + +/* Voltage rail control signals */ +#define GPIO_1V8_PWR_EN 368 /* GPP_E18 */ +#define GPIO_1V8_PG 370 /* GPP_E20 */ +#define GPIO_NV33_PWR_EN 63 /* GPP_A21 */ +#define GPIO_NV33_PG 64 /* GPP_A22 */ +#define GPIO_NVVDD_PWR_EN 350 /* GPP_E0 */ +#define GPIO_NVVDD_PG 366 /* GPP_E16 */ +#define GPIO_PEXVDD_PWR_EN 360 /* GPP_E10 */ +#define GPIO_PEXVDD_PG 367 /* GPP_E17 */ +#define GPIO_FBVDD_PWR_EN 61 /* GPP_A19 */ +#define GPIO_FBVDD_PG 354 /* GPP_E4 */ + +#define GC6_DEFER_TYPE_EXIT_GC6 3 + +/* Optimus Power Control State */ +Name (OPCS, OPTIMUS_POWER_CONTROL_DISABLE) + +/* PCI configuration space Owner */ +Name (PCIO, PCI_OWNER_SBIOS) + +/* 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) + +/* 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) + +/* "GC6 In", i.e. GC6 Entry Sequence */ +Method (GC6I, 0, Serialized) +{ + GC6E = GC6_STATE_TRANSITION + + /* Put PCIe link into L2/3 */ + _SB.PCI0.PEG1.DL23() + + /* Assert GPU_PERST_L */ + _SB.PCI0.STXS (GPIO_GPU_PERST_L) + + /* Deassert PG_GPU_ALLRAILS */ + _SB.PCI0.CTXS (GPIO_GPU_ALLRAILS_PG) + + /* Deassert EN_PP0950_GPU_X */ + _SB.PCI0.CTXS (GPIO_PEXVDD_PWR_EN) + + /* Wait for de-assertion of PG_PP0950_GPU */ + GPPL (GPIO_PEXVDD_PG, 0, 20) + + /* Deassert EN_PPVAR_GPU_NVVDD */ + _SB.PCI0.CTXS (GPIO_NVVDD_PWR_EN) + + /* Wait for de-assertion of PG_PPVAR_GPU_NVVDD */ + GPPL (GPIO_NVVDD_PG, 0, 20) + + /* Deassert EN_PCH_PPVAR_GPU_FBVDDQ */ + _SB.PCI0.CTXS (GPIO_FBVDD_PWR_EN) + + /* Deassert EN_PP3300_GPU */ + _SB.PCI0.CTXS (GPIO_NV33_PWR_EN) + + /* Wait for de-assertion of PG_PP3300_GPU */ + GPPL (GPIO_NV33_PG, 0, 20) + + GC6E = GC6_STATE_ENTERED +} + +/* "GC6 Out", i.e. GC6 Exit Sequence */ +Method (GC6O, 0, Serialized) +{ + GC6E = GC6_STATE_TRANSITION + + /* Assert EN_PP3300_GPU */ + _SB.PCI0.STXS (GPIO_NV33_PWR_EN) + + /* Wait for assertion of PG_PP3300_GPU */ + GPPL (GPIO_NV33_PG, 1, 20) + + /* Deassert GPU_PERST_L */ + _SB.PCI0.CTXS (GPIO_GPU_PERST_L) + + /* Put PCIe link into L0 state */ + _SB.PCI0.PEG1.LD23() + + /* Wait for GPU to assert GPU_NVVDD_EN */ + GPPL (GPIO_GPU_NVVDD_EN, 1, 20) + + /* + * There is a 4ms window once the GPU asserts GPU_NVVDD_EN to + * perform the following: + * 1. Enable GPU_NVVDD + * 2. Enable GPU_PEX + * 3. Wait for all PG + * 4. Assert FBVDD + * At the end of the 4ms window, the GPU will deassert its + * GPIO1_GC6_FB_EN signal that is used to keep the FBVDD + * rail up during GC6. + */ + _SB.PCI0.STXS (GPIO_NVVDD_PWR_EN) + Stall (20) + _SB.PCI0.STXS (GPIO_PEXVDD_PWR_EN) + GPPL (GPIO_NVVDD_PG, 1, 4) + GPPL (GPIO_PEXVDD_PG, 1, 4) + _SB.PCI0.STXS (GPIO_FBVDD_PWR_EN) + + /* Assert PG_GPU_ALLRAILS */ + _SB.PCI0.STXS (GPIO_GPU_ALLRAILS_PG) + + GC6E = GC6_STATE_EXITED +} + +/* GCOFF exit sequence */ +Method (PGON, 0, Serialized) +{ + /* Assert PERST# */ + _SB.PCI0.CTXS (GPIO_GPU_PERST_L) + + /* Ramp up 1.8V rail */ + _SB.PCI0.STXS (GPIO_1V8_PWR_EN) + GPPL (GPIO_1V8_PG, 1, 20) + + /* Ramp up NV33 rail */ + _SB.PCI0.STXS (GPIO_NV33_PWR_EN) + GPPL (GPIO_NV33_PG, 1, 20) + + /* Ramp up NVVDD rail */ + _SB.PCI0.STXS (GPIO_NVVDD_PWR_EN) + GPPL (GPIO_NVVDD_PG, 1, 5) + + /* Ramp up PEXVDD rail */ + _SB.PCI0.STXS (GPIO_PEXVDD_PWR_EN) + GPPL (GPIO_PEXVDD_PG, 1, 5) + + /* Ramp up FBVDD rail */ + _SB.PCI0.STXS (GPIO_FBVDD_PWR_EN) + GPPL (GPIO_FBVDD_PG, 1, 5) + + /* All rails are good */ + _SB.PCI0.STXS (GPIO_GPU_ALLRAILS_PG) + Sleep (1) + + /* Deassert PERST# */ + _SB.PCI0.STXS (GPIO_GPU_PERST_L) +} + +/* GCOFF entry sequence */ +Method (PGOF, 0, Serialized) +{ + /* Assert PERST# */ + _SB.PCI0.CTXS (GPIO_GPU_PERST_L) + Sleep (5) + + /* All rails are about to go down */ + _SB.PCI0.CTXS (GPIO_GPU_ALLRAILS_PG) + + /* Ramp down FBVDD */ + _SB.PCI0.CTXS (GPIO_FBVDD_PWR_EN) + GPPL (GPIO_FBVDD_PG, 0, 20) + + /* Ramp down PEXVDD */ + _SB.PCI0.CTXS (GPIO_PEXVDD_PWR_EN) + GPPL (GPIO_PEXVDD_PG, 0, 20) + + /* Ramp down NVVDD */ + _SB.PCI0.CTXS (GPIO_NVVDD_PWR_EN) + GPPL (GPIO_NVVDD_PG, 0, 20) + + /* Ramp down NV33 */ + _SB.PCI0.CTXS (GPIO_NV33_PWR_EN) + GPPL (GPIO_NV33_PG, 0, 20) + + /* Ramp down 1.8V */ + _SB.PCI0.CTXS (GPIO_1V8_PWR_EN) + GPPL (GPIO_1V8_PG, 0, 20) +} + +/* Handle deferred GC6 vs. poweron request */ +Method (NPON, 0, Serialized) +{ + If (DFEN == GC6_DEFER_ENABLE) /* 1 */ + { + If (DFCO == GC6_DEFER_TYPE_EXIT_GC6) /* 3 */ + { + GC6O() + } + + DFEN = GC6_DEFER_DISABLE + } + Else + { + PGON() + } +} + +/* Handle deferred GC6 vs. poweroff request */ +Method (NPOF, 0, Serialized) +{ + If (DFEN == GC6_DEFER_ENABLE) + { + /* Deferred GC6 entry */ + If (DFCI == NVJT_GPC_EGNS || DFCI == NVJT_GPC_EGIS) + { + GC6I() + } + + DFEN = GC6_DEFER_DISABLE + } + Else + { + PGOF() + } +} + + + +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) + { + Local0 = VGAR + CreateField(Local0, 40, 2008, VGAS) /* VGA Registers to Save */ + VGAS = VGAB + VGAR = Local0 + } + + /* 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) + { + Local0 = VGAR + CreateField(Local0, 40, 2008, VGAS) /* VGA Registers to Save */ + VGAB = VGAS + } + + /* Poweroff or deferred GC6 entry */ + NPOF() + + /* Because _PS3 ran _OFF, _PS0 must run _ON */ + OPS0 = OPTIMUS_CONTROL_RUN_PS0 + + /* OPCS is one-shot, so reset it */ + OPCS = OPTIMUS_POWER_CONTROL_DISABLE + } +} + +/* + * Normally, _ON and _OFF of the power resources listed in _PRx will be + * evaluated before entering D0/D3. However, for Optimus, the package + * should refer to the PCIe controller itself, not a dependent device. + */ +Name (_PR0, Package() { _SB.PCI0.PEG1 }) +Name (_PR3, Package() { _SB.PCI0.PEG1 }) + +Method (_STA, 0, Serialized) +{ + If (GC6E == GC6_STATE_EXITED && + _SB.PCI0.GTXS(GPIO_GPU_ALLRAILS_PG) == 1) + { + Return (0xF) + } + Else + { + Return (0) + } +} diff --git a/src/mainboard/google/brya/acpi/utility.asl b/src/mainboard/google/brya/acpi/utility.asl new file mode 100644 index 0000000..4fc03e8 --- /dev/null +++ b/src/mainboard/google/brya/acpi/utility.asl @@ -0,0 +1,30 @@ +/* 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 = GRXS (Arg0) + Local7 = Arg2 * 10000 + Local7 = Timer + Local7 + While (Local0 != Arg1 && Timer < Local7) + { + Stall (10) + Local0 = _SB.PCI0.GRXS (Arg0) + } +} + +/* 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) +} diff --git a/src/mainboard/google/brya/dsdt.asl b/src/mainboard/google/brya/dsdt.asl index 82cafcf..f86b289 100644 --- a/src/mainboard/google/brya/dsdt.asl +++ b/src/mainboard/google/brya/dsdt.asl @@ -44,4 +44,8 @@ /* ACPI code for EC functions */ #include <ec/google/chromeec/acpi/ec.asl> } + +#if CONFIG(INCLUDE_NVIDIA_GPU_ASL) + #include "acpi/gpu_top.asl" +#endif }