Skip to content

Commit 1cf2970

Browse files
jackpot51crawfxrd
authored andcommitted
drivers/gfx/nvidia: Add driver for NVIDIA GPU
Add a driver for laptops with NVIDIA Optimus (hybrid) graphics. The driver provides ACPI support for dynamically powering on and off the GPU, NVIDIA Dynamic Boost support, and a function for enabling the GPU power in romstage. References: - DG-09845-001: NVIDIA GN20/QN20 Hardware Design Guide - DG-09954-001: NVIDIA GN20/QN20 Software Design Guide Change-Id: I2dec7aa2c8db7994f78a7cc1220502676e248465 Signed-off-by: Jeremy Soller <[email protected]> Signed-off-by: Tim Crawford <[email protected]>
1 parent f97ffca commit 1cf2970

File tree

15 files changed

+974
-0
lines changed

15 files changed

+974
-0
lines changed

src/drivers/gfx/nvidia/Kconfig

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
config DRIVERS_GFX_NVIDIA
2+
bool
3+
default n
4+
help
5+
Support for NVIDIA Optimus graphics
6+
7+
config DRIVERS_GFX_NVIDIA_BRIDGE
8+
hex "PCI bridge for the GPU device"
9+
default 0x01
10+
depends on DRIVERS_GFX_NVIDIA
11+
12+
config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST
13+
depends on DRIVERS_GFX_NVIDIA
14+
bool
15+
default n
16+
help
17+
Support for NVIDIA Dynamic Boost
18+
19+
config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP
20+
int "Total processor power offset from default TGP in watts"
21+
default 45
22+
depends on DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST
23+
help
24+
This identifies the available power for the CPU or GPU boost
25+
26+
config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MIN
27+
int "Minimum TGP offset from default TGP in watts"
28+
default 0
29+
depends on DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST
30+
help
31+
This is used to transfer power from the GPU to the CPU
32+
33+
config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX
34+
int "Maximum TGP offset from default TGP in watts"
35+
default 0
36+
depends on DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST
37+
help
38+
This is used to transfer power from the CPU to the GPU

src/drivers/gfx/nvidia/Makefile.inc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
3+
romstage-$(CONFIG_DRIVERS_GFX_NVIDIA) += romstage.c
4+
5+
ramstage-$(CONFIG_DRIVERS_GFX_NVIDIA) += nvidia.c
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/* NVIDIA GC6 on CFL and CML CPU PCIe ports */
3+
4+
// Memory mapped PCI express config space
5+
OperationRegion (PCIC, SystemMemory, CONFIG_ECAM_MMCONF_BASE_ADDRESS + (CONFIG_DRIVERS_GFX_NVIDIA_BRIDGE << 15), 0x1000)
6+
7+
Field (PCIC, ByteAcc, NoLock, Preserve) {
8+
PVID, 16,
9+
PDID, 16,
10+
11+
Offset (0x248),
12+
, 7,
13+
L23E, 1, /* L23_Rdy Entry Request */
14+
L23R, 1, /* L23_Rdy to Detect Transition */
15+
16+
Offset (0xC20),
17+
, 4,
18+
P0AP, 2, /* Additional power savings */
19+
20+
Offset (0xC38),
21+
, 3,
22+
P0RM, 1, /* Robust squelch mechanism */
23+
}
24+
25+
// Enter L23
26+
Method (DL23, 0, Serialized) {
27+
Printf(" GPU PORT DL23 START")
28+
29+
L23E = 1
30+
Sleep (16)
31+
Local0 = 0
32+
While (L23E) {
33+
If ((Local0 > 4)) {
34+
Break
35+
}
36+
37+
Sleep (16)
38+
Local0++
39+
}
40+
41+
P0RM = 1
42+
P0AP = 3
43+
44+
Printf(" GPU PORT DL23 FINISH")
45+
}
46+
47+
// Exit L23
48+
Method (L23D, 0, Serialized) {
49+
Printf(" GPU PORT L23D START")
50+
51+
L23R = 1
52+
Sleep (16)
53+
Local0 = 0
54+
While (L23R) {
55+
If ((Local0 > 4)) {
56+
Break
57+
}
58+
59+
Sleep (16)
60+
Local0++
61+
}
62+
63+
P0RM = 0
64+
P0AP = 0
65+
66+
Printf(" GPU PORT L23D FINISH")
67+
}
68+
69+
// Main power resource
70+
PowerResource (PWRR, 0, 0) {
71+
Name (_STA, 1)
72+
73+
Method (_ON, 0, Serialized) {
74+
Printf("GPU PORT PWRR._ON")
75+
76+
^^DEV0._ON()
77+
78+
_STA = 1
79+
}
80+
81+
Method (_OFF, 0, Serialized) {
82+
Printf("GPU PORT PWRR._OFF")
83+
84+
^^DEV0._OFF()
85+
86+
_STA = 0
87+
}
88+
}
89+
90+
// Power resources for entering D0
91+
Name (_PR0, Package () { PWRR })
92+
93+
// Power resources for entering D3
94+
Name (_PR3, Package () { PWRR })
95+
96+
#include "common/gpu.asl"
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
3+
#define NV_ERROR_SUCCESS 0x0
4+
#define NV_ERROR_UNSPECIFIED 0x80000001
5+
#define NV_ERROR_UNSUPPORTED 0x80000002
6+
7+
#include "gps.asl"
8+
#include "nvjt.asl"
9+
10+
Method (_DSM, 4, Serialized) {
11+
Printf("GPU _DSM")
12+
If (Arg0 == ToUUID (JT_DSM_GUID)) {
13+
If (ToInteger(Arg1) >= JT_REVISION_ID_MIN) {
14+
Return (NVJT(Arg2, Arg3))
15+
} Else {
16+
Printf(" Unsupported JT revision: %o", SFST(Arg1))
17+
Return (NV_ERROR_UNSUPPORTED)
18+
}
19+
} ElseIf (Arg0 == ToUUID (GPS_DSM_GUID)) {
20+
If (ToInteger(Arg1) == GPS_REVISION_ID) {
21+
Return (GPS(Arg2, Arg3))
22+
} Else {
23+
Printf(" Unsupported GPS revision: %o", SFST(Arg1))
24+
Return (NV_ERROR_UNSUPPORTED)
25+
}
26+
} Else {
27+
Printf(" Unsupported GUID: %o", IDST(Arg0))
28+
Return (NV_ERROR_UNSPECIFIED)
29+
}
30+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
3+
#define GPS_DSM_GUID "A3132D01-8CDA-49BA-A52E-BC9D46DF6B81"
4+
#define GPS_REVISION_ID 0x00000200
5+
#define GPS_FUNC_SUPPORT 0x00000000
6+
#define GPS_FUNC_PSHARESTATUS 0x00000020
7+
#define GPS_FUNC_PSHAREPARAMS 0x0000002A
8+
9+
Method(GPS, 2, Serialized) {
10+
Printf(" GPU GPS")
11+
Switch(ToInteger(Arg0)) {
12+
Case(GPS_FUNC_SUPPORT) {
13+
Printf(" Supported Functions")
14+
Return(ITOB(
15+
(1 << GPS_FUNC_SUPPORT) |
16+
(1 << GPS_FUNC_PSHARESTATUS) |
17+
(1 << GPS_FUNC_PSHAREPARAMS)
18+
))
19+
}
20+
Case(GPS_FUNC_PSHARESTATUS) {
21+
Printf(" Power Share Status")
22+
Return(ITOB(0))
23+
}
24+
Case(GPS_FUNC_PSHAREPARAMS) {
25+
Printf(" Power Share Parameters")
26+
27+
CreateField(Arg1, 0, 4, QTYP) // Query type
28+
29+
Name(GPSP, Buffer(36) { 0x00 })
30+
CreateDWordField(GPSP, 0, RSTS) // Response status
31+
CreateDWordField(GPSP, 4, VERS) // Version
32+
33+
// Set query type of response
34+
RSTS = QTYP
35+
// Set version of response
36+
VERS = 0x00010000
37+
38+
Switch(ToInteger(QTYP)) {
39+
Case(0) {
40+
Printf(" Request Current Information")
41+
// No required information
42+
Return(GPSP)
43+
}
44+
Case(1) {
45+
Printf(" Request Supported Fields")
46+
// Support GPU temperature field
47+
RSTS |= (1 << 8)
48+
Return(GPSP)
49+
}
50+
Case(2) {
51+
Printf(" Request Current Limits")
52+
// No required limits
53+
Return(GPSP)
54+
}
55+
Default {
56+
Printf(" Unknown Query: %o", SFST(QTYP))
57+
Return(NV_ERROR_UNSUPPORTED)
58+
}
59+
}
60+
}
61+
Default {
62+
Printf(" Unsupported function: %o", SFST(Arg0))
63+
Return(NV_ERROR_UNSUPPORTED)
64+
}
65+
}
66+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
3+
Device (DEV0) {
4+
Name(_ADR, 0x00000000)
5+
6+
#include "utility.asl"
7+
#include "dsm.asl"
8+
#include "power.asl"
9+
}
10+
11+
#if CONFIG(DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST)
12+
Scope (\_SB) {
13+
Device(NPCF) {
14+
#include "utility.asl"
15+
#include "nvpcf.asl"
16+
}
17+
}
18+
#endif

0 commit comments

Comments
 (0)