Compare commits
	
		
			3 Commits
		
	
	
		
			system76-4
			...
			wip/nvidia
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2d743165e7 | ||
| 
						 | 
					75468a84c0 | ||
| 
						 | 
					865292a883 | 
							
								
								
									
										37
									
								
								src/drivers/gfx/nvidia/acpi/advanced_optimus.asl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/drivers/gfx/nvidia/acpi/advanced_optimus.asl
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										83
									
								
								src/drivers/gfx/nvidia/acpi/boost.asl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/drivers/gfx/nvidia/acpi/boost.asl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0-only */
 | 
			
		||||
 | 
			
		||||
// NVIDIA GPU Boost for Notebook and All-In-One-Projects
 | 
			
		||||
 | 
			
		||||
#define GPS_FUNC_SUPPORT		0
 | 
			
		||||
#define GPS_FUNC_GETOBJBYTYPE		16
 | 
			
		||||
#define GPS_FUNC_GETALLOBJS		17
 | 
			
		||||
#define GPS_FUNC_GETCALLBACKS		19
 | 
			
		||||
#define GPS_FUNC_PCONTROL		28
 | 
			
		||||
#define GPS_FUNC_PSHARESTATUS		32
 | 
			
		||||
#define GPS_FUNC_PSHAREPARAMS		42
 | 
			
		||||
 | 
			
		||||
Method (GPS, 2, Serialized)
 | 
			
		||||
{
 | 
			
		||||
	Printf("GPS {")
 | 
			
		||||
 | 
			
		||||
	Switch (ToInteger(Arg0)) {
 | 
			
		||||
		// Bit list of supported functions
 | 
			
		||||
		Case (GPS_FUNC_SUPPORT) {
 | 
			
		||||
			Printf("  GPS_FUNC_SUPPORT")
 | 
			
		||||
			// Functions supported: 0, 32, 42
 | 
			
		||||
			Local0 = Buffer () {0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Get current platform status, thermal budget
 | 
			
		||||
		Case (GPS_FUNC_PSHARESTATUS) {
 | 
			
		||||
			Printf("  GPS_FUNC_PSHARESTATUS: %o", ToHexString(Arg1))
 | 
			
		||||
			Local0 = Buffer (4) { 0 }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Get GPU Boost platform parameters
 | 
			
		||||
		Case (GPS_FUNC_PSHAREPARAMS) {
 | 
			
		||||
			Printf("  GPS_FUNC_PSHAREPARAMS: %o", ToHexString(Arg1))
 | 
			
		||||
			CreateField (Arg1, 0, 3, QTYP)		// Query Type
 | 
			
		||||
			CreateField (Arg1, 8, 1, GTMP)		// GPU temperature status
 | 
			
		||||
			CreateField (Arg1, 9, 1, CTMP)		// CPU temperature status
 | 
			
		||||
 | 
			
		||||
			Local0 = Buffer (36) { 0 }
 | 
			
		||||
			CreateDWordField (Local0, 0, STAT)	// Status
 | 
			
		||||
			CreateDWordField (Local0, 4, VERS)	// Version
 | 
			
		||||
			CreateDWordField (Local0, 8, TGPU)	// GPU temperature (C)
 | 
			
		||||
			CreateDWordField (Local0, 12, PDTS)	// CPU package temperature (C)
 | 
			
		||||
 | 
			
		||||
			VERS = 0x00010000
 | 
			
		||||
			STAT = QTYP
 | 
			
		||||
 | 
			
		||||
			Printf("    Query Type = %o", ToInteger(QTYP))
 | 
			
		||||
 | 
			
		||||
			Switch (ToInteger(QTYP)) {
 | 
			
		||||
				// Get current status
 | 
			
		||||
				Case (0) {
 | 
			
		||||
					// TGPU must be 0.
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Get supported fields
 | 
			
		||||
				Case (1) {
 | 
			
		||||
					STAT |= 0x100
 | 
			
		||||
					// TGPU must be 0.
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Get current operating limits
 | 
			
		||||
				Case (2) {
 | 
			
		||||
					// GPU temperature status must be 1.
 | 
			
		||||
					STAT |= 0x100
 | 
			
		||||
					// TGPU should be 0. GPU will use its own default.
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Default {
 | 
			
		||||
					Printf("    Unsupported Query Type: %o", ToInteger(QTYP))
 | 
			
		||||
					Local0 = NVIDIA_ERROR_UNSUPPORTED
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Default {
 | 
			
		||||
			Printf("  Unsupported GPS_FUNC: %o", ToInteger(Arg0))
 | 
			
		||||
			Local0 = NVIDIA_ERROR_UNSUPPORTED
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Printf("} GPS")
 | 
			
		||||
	Return(Local0)
 | 
			
		||||
}
 | 
			
		||||
@@ -1,202 +1,197 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0-only */
 | 
			
		||||
 | 
			
		||||
Device (\_SB.PCI0.PEGP) {
 | 
			
		||||
#define NVIDIA_ERROR_UNSPECIFIED	0x80000001
 | 
			
		||||
#define NVIDIA_ERROR_UNSUPPORTED	0x80000002
 | 
			
		||||
 | 
			
		||||
#define NBCI_DSM_GUID		"D4A50B75-65C7-46F7-BFB7-41514CEA0244"
 | 
			
		||||
#define NBCI_REVISION_ID	0x102
 | 
			
		||||
 | 
			
		||||
#define GPS_DSM_GUID		"A3132D01-8CDA-49BA-A52E-BC9D46DF6B81"
 | 
			
		||||
#define GPS_REVISION_ID		0x200
 | 
			
		||||
 | 
			
		||||
#define JT_DSM_GUID		"CBECA351-067B-4924-9CBD-B46B00B86F34"
 | 
			
		||||
#define JT_REVISION_ID		0x103
 | 
			
		||||
 | 
			
		||||
#define NVOP_DSM_GUID		"A486D8F8-0BDA-471B-A72B-6042A6B5BEE0"
 | 
			
		||||
#define NVOP_REVISION_ID	0x100
 | 
			
		||||
 | 
			
		||||
// 00:01.0
 | 
			
		||||
Device (\_SB.PCI0.PEG0)
 | 
			
		||||
{
 | 
			
		||||
	Name (_ADR, CONFIG_DRIVERS_GFX_NVIDIA_BRIDGE << 16)
 | 
			
		||||
 | 
			
		||||
	PowerResource (PWRR, 0, 0) {
 | 
			
		||||
		Name (_STA, 1)
 | 
			
		||||
 | 
			
		||||
		Method (_ON) {
 | 
			
		||||
			Debug = "PEGP.PWRR._ON"
 | 
			
		||||
			If (_STA != 1) {
 | 
			
		||||
				\_SB.PCI0.PEGP.DEV0._ON ()
 | 
			
		||||
		Method (_ON)
 | 
			
		||||
		{
 | 
			
		||||
			Printf("PEG0._ON {")
 | 
			
		||||
			// TODO: Check for deferred GCx action
 | 
			
		||||
			\_SB.PCI0.PEG0.DGPU._ON()
 | 
			
		||||
			_STA = 1
 | 
			
		||||
			}
 | 
			
		||||
			Printf("} PEG0._ON")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Method (_OFF) {
 | 
			
		||||
			Debug = "PEGP.PWRR._OFF"
 | 
			
		||||
			If (_STA != 0) {
 | 
			
		||||
				\_SB.PCI0.PEGP.DEV0._OFF ()
 | 
			
		||||
		Method (_OFF)
 | 
			
		||||
		{
 | 
			
		||||
			Printf("PEG0._OFF {")
 | 
			
		||||
			// TODO: Check for deferred GCx action
 | 
			
		||||
			\_SB.PCI0.PEG0.DGPU._OFF()
 | 
			
		||||
			_STA = 0
 | 
			
		||||
			}
 | 
			
		||||
			Printf("} PEG0._OFF")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Name (_PR0, Package () { \_SB.PCI0.PEGP.PWRR })
 | 
			
		||||
	Name (_PR2, Package () { \_SB.PCI0.PEGP.PWRR })
 | 
			
		||||
	Name (_PR3, Package () { \_SB.PCI0.PEGP.PWRR })
 | 
			
		||||
	Name (_PR0, Package () { PWRR })
 | 
			
		||||
	Name (_PR2, Package () { PWRR })
 | 
			
		||||
	Name (_PR3, Package () { PWRR })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Device (\_SB.PCI0.PEGP.DEV0) {
 | 
			
		||||
// 01:00.0
 | 
			
		||||
Device (\_SB.PCI0.PEG0.DGPU)
 | 
			
		||||
{
 | 
			
		||||
	Name(_ADR, 0x00000000)
 | 
			
		||||
	Name (_STA, 0xF)
 | 
			
		||||
	Name (LTRE, 0)
 | 
			
		||||
 | 
			
		||||
	// Memory mapped PCI express registers
 | 
			
		||||
	// Not sure what this stuff is, but it is used to get into GC6
 | 
			
		||||
        // TODO: use GPU config to generate address
 | 
			
		||||
	OperationRegion (RPCX, SystemMemory, CONFIG_ECAM_MMCONF_BASE_ADDRESS + 0x8000, 0x1000)
 | 
			
		||||
	Field (RPCX, ByteAcc, NoLock, Preserve) {
 | 
			
		||||
		PVID,   16,
 | 
			
		||||
		PDID,   16,
 | 
			
		||||
		CMDR,   8,
 | 
			
		||||
		Offset (0x19),
 | 
			
		||||
		PRBN,   8,
 | 
			
		||||
		Offset (0x84),
 | 
			
		||||
		D0ST,   2,
 | 
			
		||||
		Offset (0xAA),
 | 
			
		||||
		CEDR,   1,
 | 
			
		||||
		Offset (0xAC),
 | 
			
		||||
			,   4,
 | 
			
		||||
		CMLW,   6,
 | 
			
		||||
		Offset (0xB0),
 | 
			
		||||
		ASPM,   2,
 | 
			
		||||
			,   2,
 | 
			
		||||
		P0LD,   1,
 | 
			
		||||
		RTLK,   1,
 | 
			
		||||
		Offset (0xC9),
 | 
			
		||||
			,   2,
 | 
			
		||||
		LREN,   1,
 | 
			
		||||
		Offset (0x11A),
 | 
			
		||||
			,   1,
 | 
			
		||||
		VCNP,   1,
 | 
			
		||||
		Offset (0x214),
 | 
			
		||||
		Offset (0x216),
 | 
			
		||||
		P0LS,   4,
 | 
			
		||||
		Offset (0x248),
 | 
			
		||||
			,   7,
 | 
			
		||||
		Q0L2,   1,
 | 
			
		||||
		Q0L0,   1,
 | 
			
		||||
		Offset (0x504),
 | 
			
		||||
		Offset (0x506),
 | 
			
		||||
		PCFG,   2,
 | 
			
		||||
		Offset (0x508),
 | 
			
		||||
		TREN,   1,
 | 
			
		||||
		Offset (0xC20),
 | 
			
		||||
			,   4,
 | 
			
		||||
		P0AP,   2,
 | 
			
		||||
		Offset (0xC38),
 | 
			
		||||
			,   3,
 | 
			
		||||
		P0RM,   1,
 | 
			
		||||
		Offset (0xC74),
 | 
			
		||||
		P0LT,   4,
 | 
			
		||||
		Offset (0xD0C),
 | 
			
		||||
			,   20,
 | 
			
		||||
		LREV,   1
 | 
			
		||||
	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,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Method (_ON) {
 | 
			
		||||
		Debug = "PEGP.DEV0._ON"
 | 
			
		||||
	// 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 })
 | 
			
		||||
	Name (_PR3, Package() { \_SB.PCI0.PEG0 })
 | 
			
		||||
 | 
			
		||||
		If (_STA != 0xF) {
 | 
			
		||||
			Debug = "  If DGPU_PWR_EN low"
 | 
			
		||||
			If (! GTXS (DGPU_PWR_EN)) {
 | 
			
		||||
				Debug = "    DGPU_PWR_EN high"
 | 
			
		||||
	Method (_STA)
 | 
			
		||||
	{
 | 
			
		||||
		Printf("DGPU._STA")
 | 
			
		||||
		/*
 | 
			
		||||
		 * Only return "On" when:
 | 
			
		||||
		 * - GPU power is good
 | 
			
		||||
		 * - GPU has completed return to GC0
 | 
			
		||||
		 *
 | 
			
		||||
		 * In all other cases, return "Off".
 | 
			
		||||
		 */
 | 
			
		||||
		If ((GPWR == 1) && (GCST == 0)) {
 | 
			
		||||
			Return (0xF)
 | 
			
		||||
		} Else {
 | 
			
		||||
			Return (0)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Method (_ON)
 | 
			
		||||
	{
 | 
			
		||||
		Printf("DGPU._ON {")
 | 
			
		||||
		Printf("  Enable GPU power")
 | 
			
		||||
		STXS(DGPU_PWR_EN)
 | 
			
		||||
		Sleep(10)
 | 
			
		||||
 | 
			
		||||
				Debug = "    Sleep 16"
 | 
			
		||||
				Sleep (16)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Debug = "  DGPU_RST_N high"
 | 
			
		||||
		Printf("  Take GPU out of reset")
 | 
			
		||||
		STXS(DGPU_RST_N)
 | 
			
		||||
 | 
			
		||||
			Debug = "  Sleep 10"
 | 
			
		||||
		Sleep(10)
 | 
			
		||||
 | 
			
		||||
			Debug = "  Q0L0 = 1"
 | 
			
		||||
			Q0L0 = 1
 | 
			
		||||
		GPWR = 1
 | 
			
		||||
		GCST = 0
 | 
			
		||||
 | 
			
		||||
			Debug = "  Sleep 16"
 | 
			
		||||
			Sleep (16)
 | 
			
		||||
		/*
 | 
			
		||||
		// TODO: Actually check link status
 | 
			
		||||
		Printf("Wait for PCIe link")
 | 
			
		||||
		Sleep(100)
 | 
			
		||||
 | 
			
		||||
			Debug = "  While Q0L0"
 | 
			
		||||
			Local0 = 0
 | 
			
		||||
			While (Q0L0) {
 | 
			
		||||
				If ((Local0 > 4)) {
 | 
			
		||||
					Debug = "    While Q0L0 timeout"
 | 
			
		||||
					Break
 | 
			
		||||
		Printf("Restore SSID: %o", NVID)
 | 
			
		||||
		SSID = NVID
 | 
			
		||||
		*/
 | 
			
		||||
 | 
			
		||||
		Printf("} DGPU._ON")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
				Sleep (16)
 | 
			
		||||
				Local0++
 | 
			
		||||
			}
 | 
			
		||||
	Method (_OFF)
 | 
			
		||||
	{
 | 
			
		||||
		Printf("DGPU._OFF {")
 | 
			
		||||
 | 
			
		||||
			Debug = "  P0RM = 0"
 | 
			
		||||
			P0RM = 0
 | 
			
		||||
		/*
 | 
			
		||||
		Printf("Save SSID: %o", SSID)
 | 
			
		||||
		NVID = SSID
 | 
			
		||||
 | 
			
		||||
			Debug = "  P0AP = 0"
 | 
			
		||||
			P0AP = 0
 | 
			
		||||
		// TODO: Actually check link status
 | 
			
		||||
		Printf("Wait for PCIe link")
 | 
			
		||||
		Sleep(100)
 | 
			
		||||
		*/
 | 
			
		||||
 | 
			
		||||
			Debug = Concatenate("  LREN = ", ToHexString(LTRE))
 | 
			
		||||
			LREN = LTRE
 | 
			
		||||
 | 
			
		||||
			Debug = "  CEDR = 1"
 | 
			
		||||
			CEDR = 1
 | 
			
		||||
 | 
			
		||||
			Debug = "  CMDR |= 7"
 | 
			
		||||
			CMDR |= 7
 | 
			
		||||
 | 
			
		||||
			Debug = "  _STA = 0xF"
 | 
			
		||||
			_STA = 0xF
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Method (_OFF) {
 | 
			
		||||
		Debug = "PEGP.DEV0._OFF"
 | 
			
		||||
 | 
			
		||||
		If (_STA != 0x5) {
 | 
			
		||||
			Debug = Concatenate("  LTRE = ", ToHexString(LREN))
 | 
			
		||||
			LTRE = LREN
 | 
			
		||||
 | 
			
		||||
			Debug = "  Q0L2 = 1"
 | 
			
		||||
			Q0L2 = 1
 | 
			
		||||
 | 
			
		||||
			Debug = "  Sleep 16"
 | 
			
		||||
			Sleep (16)
 | 
			
		||||
 | 
			
		||||
			Debug = "  While Q0L2"
 | 
			
		||||
			Local0 = Zero
 | 
			
		||||
			While (Q0L2) {
 | 
			
		||||
				If ((Local0 > 4)) {
 | 
			
		||||
					Debug = "    While Q0L2 timeout"
 | 
			
		||||
					Break
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Sleep (16)
 | 
			
		||||
				Local0++
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Debug = "  P0RM = 1"
 | 
			
		||||
			P0RM = 1
 | 
			
		||||
 | 
			
		||||
			Debug = "  P0AP = 3"
 | 
			
		||||
			P0AP = 3
 | 
			
		||||
 | 
			
		||||
			Debug = "  Sleep 10"
 | 
			
		||||
			Sleep (10)
 | 
			
		||||
 | 
			
		||||
			Debug = "  DGPU_RST_N low"
 | 
			
		||||
		Printf("DGPU._OFF {")
 | 
			
		||||
		Printf("  Put GPU in reset")
 | 
			
		||||
		CTXS(DGPU_RST_N)
 | 
			
		||||
		Sleep(10)
 | 
			
		||||
 | 
			
		||||
			Debug = "  While DGPU_GC6 low"
 | 
			
		||||
			Local0 = Zero
 | 
			
		||||
			While (! GRXS(DGPU_GC6)) {
 | 
			
		||||
				If ((Local0 > 4)) {
 | 
			
		||||
					Debug = "    While DGPU_GC6 low timeout"
 | 
			
		||||
 | 
			
		||||
					Debug = "    DGPU_PWR_EN low"
 | 
			
		||||
		Printf("  Disable GPU power")
 | 
			
		||||
		CTXS(DGPU_PWR_EN)
 | 
			
		||||
					Break
 | 
			
		||||
 | 
			
		||||
		GPWR = 0
 | 
			
		||||
		GCST = 6
 | 
			
		||||
		Printf("} DGPU._OFF")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
				Sleep (16)
 | 
			
		||||
				Local0++
 | 
			
		||||
	Method (_PS0)
 | 
			
		||||
	{
 | 
			
		||||
		// XGXS, XGIS, XCLM
 | 
			
		||||
		Printf("_PS0 {}")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
			Debug = "  _STA = 0x5"
 | 
			
		||||
			_STA = 0x5
 | 
			
		||||
	Method (_PS3)
 | 
			
		||||
	{
 | 
			
		||||
		// EGNS, EGIS, EGIN
 | 
			
		||||
		Printf("_PS3 {}")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Method (_DSM, 4, Serialized)
 | 
			
		||||
	{
 | 
			
		||||
		// Notebook Common Interface
 | 
			
		||||
		If (Arg0 == ToUUID(NBCI_DSM_GUID)) {
 | 
			
		||||
			Printf("NBCI_DSM_GUID")
 | 
			
		||||
			If (Arg1 <= NBCI_REVISION_ID) {
 | 
			
		||||
				Printf("  TODO: Unimplemented!")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// NVIDIA GPU Boost
 | 
			
		||||
		If (Arg0 == ToUUID(GPS_DSM_GUID)) {
 | 
			
		||||
			Printf("GPS_DSM_GUID")
 | 
			
		||||
			If (Arg1 <= GPS_REVISION_ID) {
 | 
			
		||||
				Return(GPS(Arg2, Arg3))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// NVIDIA Low Power States
 | 
			
		||||
		If (Arg0 == ToUUID(JT_DSM_GUID)) {
 | 
			
		||||
			Printf("JT_DSM_GUID")
 | 
			
		||||
			If (Arg1 <= JT_REVISION_ID) {
 | 
			
		||||
				Return(NVJT(Arg2, Arg3))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Advanced Optimus
 | 
			
		||||
		If (Arg0 == ToUUID(NVOP_DSM_GUID)) {
 | 
			
		||||
			Printf("NVOP_DSM_GUID")
 | 
			
		||||
			If (Arg1 <= NVOP_REVISION_ID) {
 | 
			
		||||
				Printf("  TODO: Unimplemented!")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Printf("Unsupported GUID: %o", ToHexString(Arg0))
 | 
			
		||||
		Return(NVIDIA_ERROR_UNSUPPORTED)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#include "boost.asl"
 | 
			
		||||
	#include "low_power_states.asl"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										169
									
								
								src/drivers/gfx/nvidia/acpi/low_power_states.asl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								src/drivers/gfx/nvidia/acpi/low_power_states.asl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,169 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0-only */
 | 
			
		||||
 | 
			
		||||
// NVIDIA Low Power States
 | 
			
		||||
 | 
			
		||||
#define JT_FUNC_SUPPORT		0
 | 
			
		||||
#define JT_FUNC_CAPS		1
 | 
			
		||||
#define JT_FUNC_POWERCONTROL	3
 | 
			
		||||
#define JT_FUNC_PLATPOLICY	4
 | 
			
		||||
 | 
			
		||||
Method (NVJT, 2, Serialized)
 | 
			
		||||
{
 | 
			
		||||
	Printf("NVJT {")
 | 
			
		||||
 | 
			
		||||
	Switch (ToInteger(Arg0)) {
 | 
			
		||||
		Case (JT_FUNC_SUPPORT) {
 | 
			
		||||
			Printf("  JT_FUNC_SUPPORT");
 | 
			
		||||
			// Functions supported: 0, 1, 3, 4
 | 
			
		||||
			//Local0 = Buffer() { 0x1B, 0, 0, 0 }
 | 
			
		||||
			Local0 = Buffer() { 0x13, 0, 0, 0 }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Case (JT_FUNC_CAPS) {
 | 
			
		||||
			Printf("  JT_FUNC_CAPS");
 | 
			
		||||
			Local0 = Buffer(4) { 0 }
 | 
			
		||||
 | 
			
		||||
			// G-SYNC NVSR Power Features
 | 
			
		||||
			CreateField (Local0, 0, 1, JTEN)
 | 
			
		||||
			JTEN = 0
 | 
			
		||||
 | 
			
		||||
			// NVSR
 | 
			
		||||
			CreateField (Local0, 1, 2, NVSE)
 | 
			
		||||
			NVSE = 1
 | 
			
		||||
 | 
			
		||||
			// Panel Power Rail
 | 
			
		||||
			CreateField (Local0, 3, 2, PPR)
 | 
			
		||||
			PPR = 2
 | 
			
		||||
 | 
			
		||||
			// Self-Refresh Control (SRC) Power Rail
 | 
			
		||||
			CreateField (Local0, 5, 1, SRPR)
 | 
			
		||||
			SRPR = 0
 | 
			
		||||
 | 
			
		||||
			// FB Power Rail
 | 
			
		||||
			CreateField (Local0, 6, 2, FBPR)
 | 
			
		||||
			FBPR = 0
 | 
			
		||||
 | 
			
		||||
			// GPU Power Rail
 | 
			
		||||
			CreateField (Local0, 8, 2, GPR)
 | 
			
		||||
			GPR = 0
 | 
			
		||||
 | 
			
		||||
			// GC6 ROM
 | 
			
		||||
			CreateField (Local0, 10, 1, GCR)
 | 
			
		||||
			GCR = 0
 | 
			
		||||
 | 
			
		||||
			// Panic Trap Handler
 | 
			
		||||
			CreateField (Local0, 11, 1, PTH)
 | 
			
		||||
			PTH = 1
 | 
			
		||||
 | 
			
		||||
			// Supports Notify
 | 
			
		||||
			CreateField (Local0, 12, 1, NOTS)
 | 
			
		||||
			NOTS = 0
 | 
			
		||||
 | 
			
		||||
			// MS Hybrid Support
 | 
			
		||||
			CreateField (Local0, 13, 1, MHYB)
 | 
			
		||||
			MHYB = 1
 | 
			
		||||
 | 
			
		||||
			// Root Port Control
 | 
			
		||||
			CreateField (Local0, 14, 1, RPC)
 | 
			
		||||
			RPC = 1
 | 
			
		||||
 | 
			
		||||
			// GC6 Version
 | 
			
		||||
			CreateField (Local0, 15, 2, GC6V)
 | 
			
		||||
			GC6V = 2
 | 
			
		||||
 | 
			
		||||
			// GC6 Exit ISR Support
 | 
			
		||||
			CreateField (Local0, 17, 1, GEI)
 | 
			
		||||
			GEI = 0
 | 
			
		||||
 | 
			
		||||
			// GC6 Self Wakeup Support
 | 
			
		||||
			CreateField (Local0, 18, 1, GSW)
 | 
			
		||||
			GSW = 0
 | 
			
		||||
 | 
			
		||||
			// Maximum Revision Supported
 | 
			
		||||
			CreateField (Local0, 20, 12, MXRV)
 | 
			
		||||
			MXRV = JT_REVISION_ID
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Case (JT_FUNC_POWERCONTROL) {
 | 
			
		||||
			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) {
 | 
			
		||||
			Printf("  JT_FUNC_PLATPOLICY: %o", ToHexString(Arg1));
 | 
			
		||||
			//CreateField (Arg1, 2, 1, AUD)		// Azalia Audio Device
 | 
			
		||||
			//CreateField (Arg1, 3, 1, ADM)		// Audio Disable Mask
 | 
			
		||||
			//CreateField (Arg1, 4, 4, DGS)		// Driver expected State Mask
 | 
			
		||||
 | 
			
		||||
			// TODO: Save policy settings to NV CMOS?
 | 
			
		||||
 | 
			
		||||
			Local0 = Buffer(4) { 0, 0, 0, 0 }
 | 
			
		||||
			//CreateField (Local0, 2, 1, AUD)		// Audio Device status
 | 
			
		||||
			//CreateField (Local0, 4, 3, GRE)		// SBIOS requested GPU state
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Default {
 | 
			
		||||
			Printf("  Unsupported JT_FUNC: %o", ToInteger(Arg0))
 | 
			
		||||
			Local0 = NVIDIA_ERROR_UNSUPPORTED
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Printf("} NVJT")
 | 
			
		||||
	Return(Local0)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										90
									
								
								src/drivers/gfx/nvidia/acpi/nbci.asl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/drivers/gfx/nvidia/acpi/nbci.asl
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -13,6 +13,7 @@ void mainboard_memory_init_params(FSPM_UPD *mupd)
 | 
			
		||||
		.topo = MEM_TOPO_MIXED,
 | 
			
		||||
		.cbfs_index = 0,
 | 
			
		||||
		.smbus = {
 | 
			
		||||
			[0] = { .addr_dimm[0] = 0x50, },
 | 
			
		||||
			[1] = { .addr_dimm[0] = 0x52, },
 | 
			
		||||
		},
 | 
			
		||||
	};
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@
 | 
			
		||||
#include <commonlib/region.h>
 | 
			
		||||
#include <spd_bin.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <types.h>
 | 
			
		||||
 | 
			
		||||
_Static_assert(CONFIG_MRC_CHANNEL_WIDTH > 0, "MRC channel width must be >0!");
 | 
			
		||||
_Static_assert(CONFIG_DATA_BUS_WIDTH > 0, "Data bus width must be >0!");
 | 
			
		||||
@@ -94,7 +93,7 @@ static void read_spd_md(const struct soc_mem_cfg *soc_mem_cfg, const struct mem_
 | 
			
		||||
 | 
			
		||||
#define CH_DIMM_OFFSET(ch, dimm)	((ch) * CONFIG_DIMMS_PER_CHANNEL + (dimm))
 | 
			
		||||
 | 
			
		||||
static bool read_spd_dimm(const struct soc_mem_cfg *soc_mem_cfg, const struct mem_spd *info,
 | 
			
		||||
static void read_spd_dimm(const struct soc_mem_cfg *soc_mem_cfg, const struct mem_spd *info,
 | 
			
		||||
			bool half_populated, struct mem_channel_data *channel_data,
 | 
			
		||||
			size_t *spd_len)
 | 
			
		||||
{
 | 
			
		||||
@@ -110,7 +109,7 @@ static bool read_spd_dimm(const struct soc_mem_cfg *soc_mem_cfg, const struct me
 | 
			
		||||
	uint32_t pop_mask = 0;
 | 
			
		||||
 | 
			
		||||
	if (!(info->topo & MEM_TOPO_DIMM_MODULE))
 | 
			
		||||
		return false;
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	for (ch = 0; ch < num_phys_ch; ch++) {
 | 
			
		||||
		for (dimm = 0; dimm < CONFIG_DIMMS_PER_CHANNEL; dimm++) {
 | 
			
		||||
@@ -138,8 +137,6 @@ static bool read_spd_dimm(const struct soc_mem_cfg *soc_mem_cfg, const struct me
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	channel_data->ch_population_flags |= populated_mask_to_flag(pop_mask, num_phys_ch);
 | 
			
		||||
 | 
			
		||||
	return pop_mask != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mem_populate_channel_data(const struct soc_mem_cfg *soc_mem_cfg,
 | 
			
		||||
@@ -148,12 +145,11 @@ void mem_populate_channel_data(const struct soc_mem_cfg *soc_mem_cfg,
 | 
			
		||||
				struct mem_channel_data *data)
 | 
			
		||||
{
 | 
			
		||||
	size_t spd_md_len = 0, spd_dimm_len = 0;
 | 
			
		||||
	bool have_dimms;
 | 
			
		||||
 | 
			
		||||
	memset(data, 0, sizeof(*data));
 | 
			
		||||
 | 
			
		||||
	read_spd_md(soc_mem_cfg, spd_info, half_populated, data, &spd_md_len);
 | 
			
		||||
	have_dimms = read_spd_dimm(soc_mem_cfg, spd_info, half_populated, data, &spd_dimm_len);
 | 
			
		||||
	read_spd_dimm(soc_mem_cfg, spd_info, half_populated, data, &spd_dimm_len);
 | 
			
		||||
 | 
			
		||||
	if (data->ch_population_flags == NO_CHANNEL_POPULATED)
 | 
			
		||||
		die("No channels are populated. Incorrect memory configuration!\n");
 | 
			
		||||
@@ -165,12 +161,11 @@ void mem_populate_channel_data(const struct soc_mem_cfg *soc_mem_cfg,
 | 
			
		||||
	} else {
 | 
			
		||||
		/*
 | 
			
		||||
		 * SPD lengths must match for CBFS and EEPROM SPD for mixed
 | 
			
		||||
		 * topology. Skip this check when no DIMMs are installed.
 | 
			
		||||
		 * topology.
 | 
			
		||||
		 */
 | 
			
		||||
		if (have_dimms && spd_md_len != spd_dimm_len)
 | 
			
		||||
		if (spd_md_len != spd_dimm_len)
 | 
			
		||||
			die("Length of SPD does not match for mixed topology!\n");
 | 
			
		||||
 | 
			
		||||
		/* Use memory-down SPD length in case there are no DIMMs installed */
 | 
			
		||||
		data->spd_len = spd_md_len;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user