From 2d743165e70383d58bbe5968ae7107786fe2a787 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Tue, 21 Dec 2021 13:32:33 -0700 Subject: [PATCH] drivers/gfx/nvidia: acpi: Skeleton code for NBCI Signed-off-by: Tim Crawford Change-Id: I5fbc8e1480670457586885c6099c19d73ca06c45 --- .../gfx/nvidia/acpi/advanced_optimus.asl | 37 ++++++++ src/drivers/gfx/nvidia/acpi/boost.asl | 2 +- src/drivers/gfx/nvidia/acpi/gpu.asl | 40 ++++++++- .../gfx/nvidia/acpi/low_power_states.asl | 60 ++++++++++++- src/drivers/gfx/nvidia/acpi/nbci.asl | 90 +++++++++++++++++++ 5 files changed, 223 insertions(+), 6 deletions(-) create mode 100644 src/drivers/gfx/nvidia/acpi/advanced_optimus.asl create mode 100644 src/drivers/gfx/nvidia/acpi/nbci.asl diff --git a/src/drivers/gfx/nvidia/acpi/advanced_optimus.asl b/src/drivers/gfx/nvidia/acpi/advanced_optimus.asl new file mode 100644 index 0000000000..192c2fc13d --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/advanced_optimus.asl @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +// NVIDIA Advanced Optimus + +#define NVOP_FUNC_SUPPORT 0 +#define NVOP_FUNC_DISPLAYSTATUS 5 +#define NVOP_FUNC_MDTL 6 +#define NVOP_FUNC_GETOBJBYTYPE 16 +#define NVOP_FUNC_GETALLOBJS 17 +#define NVOP_FUNC_OPTIMUSCAPS 26 +#define NVOP_FUNC_OPTIMUSFLAGS 27 + +Method (NVOP, 2, Serialized) +{ + Printf("NVOP {") + Local0 = NVIDIA_ERROR_UNSUPPORTED + + Switch (ToInteger(Arg0)) { + Case (NVOP_FUNC_SUPPORT) { + } + + Case (NVOP_FUNC_OPTIMUSCAPS) { + CreateField (Arg1, 0, 1, FLGS) // Flag updates + CreateField (Arg1, 1, 1, PCOT) // PCIe Configuration Space Owner Target + CreateField (Arg1, 2, 1, PCOW) // PCIe Configuration Space Owner Write + CreateField (Arg1, 24, 2, OPCE) // Optimus Power Control Enable + } + + Default { + Printf(" Unsupported NVOP_FUNC: %o", ToInteger(Arg0)) + Local0 = NVIDIA_ERROR_UNSUPPORTED + } + } + + Printf("} NVOP") + Return(Local0) +} diff --git a/src/drivers/gfx/nvidia/acpi/boost.asl b/src/drivers/gfx/nvidia/acpi/boost.asl index 8a88955a52..2acba8cead 100644 --- a/src/drivers/gfx/nvidia/acpi/boost.asl +++ b/src/drivers/gfx/nvidia/acpi/boost.asl @@ -78,6 +78,6 @@ Method (GPS, 2, Serialized) } } - Printf("}") + Printf("} GPS") Return(Local0) } diff --git a/src/drivers/gfx/nvidia/acpi/gpu.asl b/src/drivers/gfx/nvidia/acpi/gpu.asl index 5c24bc749b..7266ac386d 100644 --- a/src/drivers/gfx/nvidia/acpi/gpu.asl +++ b/src/drivers/gfx/nvidia/acpi/gpu.asl @@ -43,6 +43,7 @@ Device (\_SB.PCI0.PEG0) } Name (_PR0, Package () { PWRR }) + Name (_PR2, Package () { PWRR }) Name (_PR3, Package () { PWRR }) } @@ -54,10 +55,23 @@ Device (\_SB.PCI0.PEG0.DGPU) Name (GPWR, 0) // GPU Power Name (GCST, 6) // GCx State + Name (DPC, 0) // Deferred power control + Name (DPCX, 0) // Deferred power control on exit + + + Name (NVID, 0x00000000) + + OperationRegion (PCIM, SystemMemory, 0x0E010000, 0xF0) + Field (PCIM, AnyAcc, Lock, Preserve) + { + Offset(0x2c), + SSID, 32, + } + // For supporting Hybrid Graphics, the package refers to the PCIe controller // itself, which leverages GC6 Control methods under the dGPU namespace. - Name (_PR0, Package() { \_SB.PCI0.PEG0.PWRR }) - Name (_PR3, Package() { \_SB.PCI0.PEG0.PWRR }) + Name (_PR0, Package() { \_SB.PCI0.PEG0 }) + Name (_PR3, Package() { \_SB.PCI0.PEG0 }) Method (_STA) { @@ -89,11 +103,32 @@ Device (\_SB.PCI0.PEG0.DGPU) GPWR = 1 GCST = 0 + + /* + // TODO: Actually check link status + Printf("Wait for PCIe link") + Sleep(100) + + Printf("Restore SSID: %o", NVID) + SSID = NVID + */ + Printf("} DGPU._ON") } Method (_OFF) { + Printf("DGPU._OFF {") + + /* + Printf("Save SSID: %o", SSID) + NVID = SSID + + // TODO: Actually check link status + Printf("Wait for PCIe link") + Sleep(100) + */ + Printf("DGPU._OFF {") Printf(" Put GPU in reset") CTXS(DGPU_RST_N) @@ -101,7 +136,6 @@ Device (\_SB.PCI0.PEG0.DGPU) Printf(" Disable GPU power") CTXS(DGPU_PWR_EN) - Sleep(10) GPWR = 0 GCST = 6 diff --git a/src/drivers/gfx/nvidia/acpi/low_power_states.asl b/src/drivers/gfx/nvidia/acpi/low_power_states.asl index 7648f64e07..55c47b9ef6 100644 --- a/src/drivers/gfx/nvidia/acpi/low_power_states.asl +++ b/src/drivers/gfx/nvidia/acpi/low_power_states.asl @@ -10,6 +10,7 @@ Method (NVJT, 2, Serialized) { Printf("NVJT {") + Switch (ToInteger(Arg0)) { Case (JT_FUNC_SUPPORT) { Printf(" JT_FUNC_SUPPORT"); @@ -84,9 +85,64 @@ Method (NVJT, 2, Serialized) } Case (JT_FUNC_POWERCONTROL) { - Printf(" JT_FUNC_POWERCONTROL: Unimplemented!"); + Printf(" JT_FUNC_POWERCONTROL: %o", ToHexString(Arg1)); // TODO Local0 = NVIDIA_ERROR_UNSUPPORTED + + /* + CreateField (Arg1, 0, 3, GPC) // GPU Power Control + CreateField (Arg1, 3, 1, GGP) // Global GPU Power + CreateField (Arg1, 4, 1, PPC) // Panel Power Control + CreateField (Arg1, 6, 2, NOC) // Notify on complete + CreateField (Arg1, 8, 2, PRGX) // PCIe Root Power GC6 Exit Sequence + CreateField (Arg1, 10, 2, PRGE) // PCIe Root Power GC6 Entry Sequence + CreateField (Arg1, 12, 1, PRPC) // Poll for Root Port Completion + CreateField (Arg1, 13, 1, PLON) // PCIe Root Port Control + CreateField (Arg1, 14, 2, DFGC) // Defer GC6 Enter/Exit until D3cold + CreateField (Arg1, 16, 3, GPCX) // Deferred GC6 Exit Control + CreateField (Arg1, 19, 1, EGEI) // Enable GC6 Exit ISR + CreateField (Arg1, 20, 2, PLCM) // PCIe Root Port Control Method for PLON + + Local0 = Buffer(4) {0, 0, 0, 0} + CreateField (Local0, 0, 3, GCS) // GC State + CreateField (Local0, 3, 1, GPS) // GPU Power Status + CreateField (Local0, 7, 1, PSS) // Panel and SRC State + */ + + /* + * DFGC + * 0: Perform request immediately + * 1: Defer GPC and GPCX to be processed when setting Device Power State + * 2: Clear any pending deferred requests + */ + /* + If (DFGC == 2) { + DPC = 0 + DPCX = 0 + } + */ + + /* + * GPC + * 0 GSS) Get current GPU GCx Sleep Status + * 1 EGNS: Entery GC6 only. No SMI trap, No Self-Refresh. Panel + * and GPU will be powred down as normal. FB will remain powered. + * 2 EGIS: Enter GC6, keep Panel in Self-Refresh. Enable SMI trap on + * VGA I/O regiters. Control of screen is transitioned to the SRC and + * then the GPU is powered down. Panel and FB remain powered while + * the GPU is off. + * 3 XGXS: Exit GC6. Exit Panel Self-Refresh (Sparse). GPU is powered on. + * Disable SMI traps. + * 4 XGIS: Exit GC6 for Self-Refresh Update (Burst). GPU is powered on, but + * the SRC continues to retain control of screen refresh, while the + * GPU sends an update to SRC for display. Disable SMI traps. + * 5 EGIN: Enter GC6, keep Pnael in Self-Refresh. No SMI trap on VGA I/O + * registers. Control of screen is transitioned to SRC and then + * GPU is powred down. Panel and FB remain powered while the GPU is off. + * 6 XCLM: Trigger GPU_EVENT only. GPU_EVENT would be assered and de-asserted, + * regardless of GPU power state, without waiting for any GPU-side + * signaling. No change in GPU power state is made. SMI traps disabled. + */ } Case (JT_FUNC_PLATPOLICY) { @@ -108,6 +164,6 @@ Method (NVJT, 2, Serialized) } } - Printf("}") + Printf("} NVJT") Return(Local0) } diff --git a/src/drivers/gfx/nvidia/acpi/nbci.asl b/src/drivers/gfx/nvidia/acpi/nbci.asl new file mode 100644 index 0000000000..4150f1335d --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/nbci.asl @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +// Notebook Common Interface + +#define NBCI_FUNC_SUPPORT 0 +#define NBCI_FUNC_PLATCAPS 1 +#define NBCI_FUNC_PLATPOLICY 4 +#define NBCI_FUNC_DISPLAYSTATUS 5 +#define NBCI_FUNC_GETOBJBYTYPE 16 +#define NBCI_FUNC_GETALLOBJS 17 +#define NBCI_FUNC_GETEVENTLIST 18 +#define NBCI_FUNC_CALLBACKS 29 +#define NBCI_FUNC_GETBACKLIGHT 20 +#define NBCI_FUNC_GETLICENSE 22 +#define NBCI_FUNC_GETEFITABLE 23 + +Scope (\_SB.PCI0.PEG0.DGPU) +{ + Method (NBCI, 2, NotSerialized) + { + Printf("NBCI {") + Local0 = NVIDIA_ERROR_UNSUPPORTED + + Switch (ToInteger(Arg0)) { + // Bit list of supported functions + Case (NBCI_FUNC_SUPPORT) { + // Supported functions: 0 + Local0 = Buffer() {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + } + + // Query Plaform Capabilities + Case (NBCI_FUNC_PLATCAPS) { + Printf(" NBCI_FUNC_PLATCAPS: Unimplemented!") + } + + // Query Platform Policies + Case (NBCI_FUNC_PLATPOLICY) { + Printf(" NBCI_FUNC_PLATPOLICY: Unimplemented!") + } + + // Query Display status + Case (NBCI_FUNC_DISPLAYSTATUS) { + Printf(" NBCI_FUNC_DISPLAYSTATUS: Unimplemented!") + } + + // Fetch and specific Object by Type + Case (NBCI_FUNC_GETOBJBYTYPE) { + Printf(" NBCI_FUNC_GETOBJBYTYPE: Unimplemented!") + } + + // Fetch all Objects + Case (NBCI_FUNC_GETALLOBJS) { + Printf(" NBCI_FUNC_GETALLOBJS: Unimplemented!") + } + + // Get list of Notify events and their meaning + Case (NBCI_FUNC_GETEVENTLIST) { + Printf(" NBCI_FUNC_GETEVENTLIST: Unimplemented!") + } + + // Get list of system-required callbacks + Case (NBCI_FUNC_CALLBACKS) { + Printf(" NBCI_FUNC_CALLBACKS: Unimplemented!") + } + + // Get the Backlight setup settings + Case (NBCI_FUNC_GETBACKLIGHT) { + Printf(" NBCI_FUNC_GETBACKLIGHT: Unimplemented!") + } + + // Get Software License Number + Case (NBCI_FUNC_GETLICENSE) { + Printf(" NBCI_FUNC_GETLICENSE: Unimplemented!") + } + + // Get EFI System Table + Case (NBCI_FUNC_GETEFITABLE) { + Printf(" NBCI_FUNC_GETEFITABLE: Unimplemented!") + } + + Default { + Printf(" Unsupported NBCI_FUNC: %o", ToInteger(Arg0)) + Local0 = NVIDIA_ERROR_UNSUPPORTED + } + } + + Printf("} NBCI") + Return(Local0) + } +}