diff --git a/src/drivers/gfx/nvidia/Kconfig b/src/drivers/gfx/nvidia/Kconfig index 7eb7023f78..4535445fed 100644 --- a/src/drivers/gfx/nvidia/Kconfig +++ b/src/drivers/gfx/nvidia/Kconfig @@ -8,3 +8,38 @@ config DRIVERS_GFX_NVIDIA_BRIDGE hex "PCI bridge for the GPU device" default 0x01 depends on DRIVERS_GFX_NVIDIA + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + depends on DRIVERS_GFX_NVIDIA + bool + default n + help + Support for NVIDIA Dynamic Boost + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_BASELINE + int "Baseline TGP offset from static TGP in watts" + default 0 + depends on DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + help + This adds additional power to the GPU by default + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP + int "Total processor power offset from baseline TGP in watts" + default 45 + depends on DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + help + This identifies the available power for the CPU or GPU boost + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MIN + int "Minimum TGP offset from baseline TGP in watts" + default 0 + depends on DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + help + This is used to transfer power from the GPU to the CPU + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX + int "Maximum TGP offset from baseline TGP in watts" + default 0 + depends on DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + help + This is used to transfer power from the CPU to the GPU diff --git a/src/drivers/gfx/nvidia/acpi/common/dsm.asl b/src/drivers/gfx/nvidia/acpi/common/dsm.asl index dc29579942..ad440b58b7 100644 --- a/src/drivers/gfx/nvidia/acpi/common/dsm.asl +++ b/src/drivers/gfx/nvidia/acpi/common/dsm.asl @@ -4,6 +4,7 @@ #define NV_ERROR_UNSPECIFIED 0x80000001 #define NV_ERROR_UNSUPPORTED 0x80000002 +#include "gps.asl" #include "nvjt.asl" Method (_DSM, 4, Serialized) { @@ -15,6 +16,13 @@ Method (_DSM, 4, Serialized) { Printf(" Unsupported JT revision: %o", SFST(Arg1)) Return (NV_ERROR_UNSUPPORTED) } + } ElseIf (Arg0 == ToUUID (GPS_DSM_GUID)) { + If (ToInteger(Arg1) == GPS_REVISION_ID) { + Return (GPS(Arg2, Arg3)) + } Else { + Printf(" Unsupported GPS revision: %o", SFST(Arg1)) + Return (NV_ERROR_UNSUPPORTED) + } } Else { Printf(" Unsupported GUID: %o", IDST(Arg0)) Return (NV_ERROR_UNSPECIFIED) diff --git a/src/drivers/gfx/nvidia/acpi/common/gps.asl b/src/drivers/gfx/nvidia/acpi/common/gps.asl new file mode 100644 index 0000000000..1076cefea7 --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/gps.asl @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define GPS_DSM_GUID "A3132D01-8CDA-49BA-A52E-BC9D46DF6B81" +#define GPS_REVISION_ID 0x00000200 +#define GPS_FUNC_SUPPORT 0x00000000 +#define GPS_FUNC_PSHARESTATUS 0x00000020 +#define GPS_FUNC_PSHAREPARAMS 0x0000002A + +Method(GPS, 2, Serialized) { + Printf(" GPU GPS") + Switch(ToInteger(Arg0)) { + Case(GPS_FUNC_SUPPORT) { + Printf(" Supported Functions") + Return(ITOB( + (1 << GPS_FUNC_SUPPORT) | + (1 << GPS_FUNC_PSHARESTATUS) | + (1 << GPS_FUNC_PSHAREPARAMS) + )) + } + Case(GPS_FUNC_PSHARESTATUS) { + Printf(" Power Share Status") + Return(ITOB(0)) + } + Case(GPS_FUNC_PSHAREPARAMS) { + Printf(" Power Share Parameters") + + CreateField(Arg1, 0, 4, QTYP) // Query type + + Name(GPSP, Buffer(36) { 0x00 }) + CreateDWordField(GPSP, 0, RSTS) // Response status + CreateDWordField(GPSP, 4, VERS) // Version + + // Set query type of response + RSTS = QTYP + // Set version of response + VERS = 0x00010000 + + Switch(ToInteger(QTYP)) { + Case(0) { + Printf(" Request Current Information") + // No required information + Return(GPSP) + } + Case(1) { + Printf(" Request Supported Fields") + // Support GPU temperature field + RSTS |= (1 << 8) + Return(GPSP) + } + Case(2) { + Printf(" Request Current Limits") + // No required limits + Return(GPSP) + } + Default { + Printf(" Unknown Query: %o", SFST(QTYP)) + Return(NV_ERROR_UNSUPPORTED) + } + } + } + Default { + Printf(" Unsupported function: %o", SFST(Arg0)) + Return(NV_ERROR_UNSUPPORTED) + } + } +} diff --git a/src/drivers/gfx/nvidia/acpi/common/gpu.asl b/src/drivers/gfx/nvidia/acpi/common/gpu.asl index d8b793533f..49e5c47285 100644 --- a/src/drivers/gfx/nvidia/acpi/common/gpu.asl +++ b/src/drivers/gfx/nvidia/acpi/common/gpu.asl @@ -7,3 +7,12 @@ Device (DEV0) { #include "dsm.asl" #include "power.asl" } + +#if CONFIG(DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST) +Scope (\_SB) { + Device(NPCF) { + #include "utility.asl" + #include "nvpcf.asl" + } +} +#endif diff --git a/src/drivers/gfx/nvidia/acpi/common/nvpcf.asl b/src/drivers/gfx/nvidia/acpi/common/nvpcf.asl new file mode 100644 index 0000000000..9510376c61 --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/nvpcf.asl @@ -0,0 +1,132 @@ +#define NVPCF_DSM_GUID "36b49710-2483-11e7-9598-0800200c9a66" +#define NVPCF_REVISION_ID 0x00000200 +#define NVPCF_ERROR_SUCCESS 0x0 +#define NVPCF_ERROR_GENERIC 0x80000001 +#define NVPCF_ERROR_UNSUPPORTED 0x80000002 +#define NVPCF_FUNC_GET_SUPPORTED 0x00000000 +#define NVPCF_FUNC_GET_STATIC_CONFIG_TABLES 0x00000001 +#define NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS 0x00000002 + +Name(CDIS, 0) + +Method(_HID) { + CDIS = 0 + Return("NVDA0820") +} + +Name(_UID, "NPCF") + +Method(_DIS) { + CDIS = 1 +} + +Method(_STA) { + If (CDIS == 1) { + Return(0x0D) + } Else { + Return(0x0F) + } +} + +Method(_DSM, 4, Serialized) { + Printf("NVPCF _DSM") + If (Arg0 == ToUUID(NVPCF_DSM_GUID)) { + If (ToInteger(Arg1) == NVPCF_REVISION_ID) { + Return(NPCF(Arg2, Arg3)) + } Else { + Printf(" Unsupported NVPCF revision: %o", SFST(Arg1)) + Return(NVPCF_ERROR_GENERIC) + } + } Else { + Printf(" Unsupported GUID: %o", IDST(Arg0)) + } +} + +Method(NPCF, 2, Serialized) { + Printf(" NVPCF NPCF") + Switch(ToInteger(Arg0)) { + Case(NVPCF_FUNC_GET_SUPPORTED) { + Printf(" Supported Functions") + Return(ITOB( + (1 << NVPCF_FUNC_GET_SUPPORTED) | + (1 << NVPCF_FUNC_GET_STATIC_CONFIG_TABLES) | + (1 << NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS) + )) + } + Case(NVPCF_FUNC_GET_STATIC_CONFIG_TABLES) { + Printf(" Get Static Config") + Return(Buffer(14) { + // Device table header + 0x20, 0x03, 0x01, + // Intel + NVIDIA + 0x00, + // Controller table header + 0x23, 0x04, 0x05, 0x01, + // Dynamic boost controller + 0x01, + // Supports DC + 0x01, + // Reserved + 0x00, 0x00, 0x00, + // Checksum + 0xAD + }) + } + Case(NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS) { + Printf(" Update Dynamic Boost") + + CreateField(Arg1, 0x28, 2, ICMD) // Input command + + Name(PCFP, Buffer(49) { + // Table version + 0x23, + // Table header size + 0x05, + // Size of common status in bytes + 0x10, + // Size of controller entry in bytes + 0x1C, + // Other fields filled in later + }) + CreateByteField(PCFP, 0x04, CCNT) // Controller count + CreateWordField(PCFP, 0x05, ATGP) // AC TGP offset + CreateWordField(PCFP, 0x07, DTGP) // DC TGP offset (unused) + CreateWordField(PCFP, 0x19, ATPP) // AC TPP offset + CreateWordField(PCFP, 0x1B, DTPP) // DC TPP offset (unused) + CreateWordField(PCFP, 0x1D, AMXP) // AC maximum TGP offset + CreateWordField(PCFP, 0x21, AMNP) // AC minimum TGP offset + + Switch(ToInteger(ICMD)) { + Case(0) { + Printf(" Get Controller Params") + // Number of controllers + CCNT = 1 + // AC configurable TGP baseline offset in 1/8 watt units + ATGP = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_BASELINE << 3) + // AC total processor power offset from baseline in 1/8 watt units + ATPP = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP << 3) + // AC maximum TGP offset from baseline in 1/8 watt units + AMXP = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX << 3) + // AC minimum TGP offset from baseline in 1/8 watt units + AMNP = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MIN << 3) + Printf("PCFP: %o", SFST(PCFP)) + Return(PCFP) + } + Case(1) { + Printf(" Set Controller Status") + //TODO + Printf("PCFP: %o", SFST(PCFP)) + Return(PCFP) + } + Default { + Printf(" Unknown Input Command: %o", SFST(ICMD)) + Return(NV_ERROR_UNSUPPORTED) + } + } + } + Default { + Printf(" Unsupported function: %o", SFST(Arg0)) + Return(NVPCF_ERROR_UNSUPPORTED) + } + } +} diff --git a/src/mainboard/system76/rpl/Kconfig b/src/mainboard/system76/rpl/Kconfig index 9fb46b384e..397fb3ee21 100644 --- a/src/mainboard/system76/rpl/Kconfig +++ b/src/mainboard/system76/rpl/Kconfig @@ -25,6 +25,7 @@ config BOARD_SYSTEM76_ADDW3 def_bool n select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_COLOR_KEYBOARD select EC_SYSTEM76_EC_DGPU select MAINBOARD_USES_IFD_GBE_REGION @@ -35,6 +36,7 @@ config BOARD_SYSTEM76_BONW15 def_bool n select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_COLOR_KEYBOARD select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG @@ -44,6 +46,7 @@ config BOARD_SYSTEM76_GAZE18 def_bool n select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_COLOR_KEYBOARD select EC_SYSTEM76_EC_DGPU select SOC_INTEL_ALDERLAKE_PCH_P @@ -53,6 +56,7 @@ config BOARD_SYSTEM76_ORYP11 def_bool n select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_COLOR_KEYBOARD select EC_SYSTEM76_EC_DGPU select SOC_INTEL_ALDERLAKE_PCH_P @@ -62,6 +66,7 @@ config BOARD_SYSTEM76_SERW13 def_bool n select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_COLOR_KEYBOARD select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG @@ -109,6 +114,20 @@ config CONSOLE_POST config DIMM_SPD_SIZE default 512 +config DRIVERS_GFX_NVIDIA_BRIDGE + default 0x02 if BOARD_SYSTEM76_BONW15 + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_BASELINE + default 10 if BOARD_SYSTEM76_GAZE18 + default 25 if BOARD_SYSTEM76_BONW15 + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP + default 55 if BOARD_SYSTEM76_ADDW3 || BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_SERW13 + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX + default 15 if BOARD_SYSTEM76_GAZE18 + default 25 if BOARD_SYSTEM76_ADDW3 || BOARD_SYSTEM76_ORYP11 || BOARD_SYSTEM76_SERW13 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" @@ -133,10 +152,3 @@ config USE_PM_ACPI_TIMER default n endif - -if BOARD_SYSTEM76_BONW15 - -config DRIVERS_GFX_NVIDIA_BRIDGE - default 0x02 - -endif