Skip to content

Instantly share code, notes, and snippets.

@gulafaran
Last active November 5, 2021 09:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gulafaran/d87e05d940f909ae0beb1863ebfbfb68 to your computer and use it in GitHub Desktop.
Save gulafaran/d87e05d940f909ae0beb1863ebfbfb68 to your computer and use it in GitHub Desktop.

Disclaimer: Please follow this guide being aware of the fact that I'm not an expert regarding the things outlined below, however I made my best attempt.

NVIDIA driver since version 435.17 supports this method. xf86-video-modesetting, xf86-video-amdgpu (450.57), and xf86-video-intel (455.38) are officially supported as iGPU drivers.

For Turing generation cards with Intel Coffee Lake or above CPUs (as well as the Ryzen 5800H Acer Nitro 5 that im using maybe other ryzens too?), it is possible to fully power down the GPU when not in use.

nvidia gpus 1650 and up is supposedly working with this?.

Hardware

Acer Nitro 5 AN515-45:

  • AMD Ryzen 7 5800H
  • AMD ATI 06:00.0 Cezanne
  • NVIDIA GeForce RTX 3060 Mobile
  • Intel Corporation Wi-Fi 6 AX200
  • Realtek Semiconductor Co., Ltd. Device 2600
  • 2x8GB (16GB) Micron Technology 4ATF1G64HZ-3G2B2

PRIME Offloading

Installation

im using archlinux, so all the packages exist in the repos.

pacman -S nvidia-dkms nvidia-utils nvidia-prime

Configuration

we have to mark the nvidia gpu as Inactive to get it listed in xrandr --listproviders and get the hdmi output showing aswell. also to remedy certain opengl/vulkan application barfing about X BadAlloc errors. probably race to finish and trying to output to a non existant display.

im also using "IgnoreABI" because nvidia fails to load without it on xorg-git which i compile.

the BusID's need to be tweaked for your system. can be grabbed from lspci. https://unix.stackexchange.com/a/585911

/etc/X11/xorg.conf.d/02-amdgpu.conf

Section "ServerFlags"
  Option "IgnoreABI" "1"
  Option "AutoAddGPU" "false"
  Option "AutoBindGPU" "false"
EndSection

Section "ServerLayout"
  Identifier "default"
  Screen 0 "amdgpu"
  Inactive "nvidia"
  Option "AllowNVIDIAGPUScreens"
EndSection

Section "Device"
  Identifier "amdgpu"
  Driver     "amdgpu"
  BusID "PCI:6:0:0"
  Option "TearFree" "true"
  Option "DRI" "3"
  Option "VariableRefresh" "true"
EndSection

Section "Device"
  Identifier "nvidia"
  Driver     "nvidia"
  BusID   "PCI:1:0:0"
  Option  "SidebandSocketPath" "/var/run/nvidia-xdriver"
  Option "ProbeAllGpus" "false"
EndSection

Section "Screen"
  Identifier "amdgpu"
  Device     "amdgpu"
EndSection

we also need a few environment variables set to not iterate over the nvidia gpu in certain tasks to activate it randomly for a few moments. in one of the various ways to set them, .pam_environment / .bash_profile / .zprofile etc.

to get the MESA_VK_DEVICE_SELECT id, just run MESA_VK_DEVICE_SELECT=list vkcube in a terminal.

VK_ICD_FILENAMES="/usr/share/vulkan/icd.d/radeon_icd.i686.json:/usr/share/vulkan/icd.d/radeon_icd.x86_64.json"
DXVK_FILTER_DEVICE_NAME="AMD"
VKD3D_FILTER_DEVICE_NAME="AMD"
MESA_VK_DEVICE_SELECT="1002:1638"
__GLX_VENDOR_LIBRARY_NAME="mesa"
__EGL_VENDOR_LIBRARY_FILENAMES="/usr/share/glvnd/egl_vendor.d/50_mesa.json"

then modify your /usr/bin/prime-run so it uses nvidia with those env vars.

_EGL_VENDOR_LIBRARY_FILENAMES="/usr/share/glvnd/egl_vendor.d/10_nvidia.json" DXVK_FILTER_DEVICE_NAME="NVIDIA" VKD3D_FILTER_DEVICE_NAME="NVIDIA" VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json __NV_PRIME_RENDER_OFFLOAD=1 __VK_LAYER_NV_optimus=NVIDIA_only __GLX_VENDOR_LIBRARY_NAME=nvidia "$@"

then you need udev rules to setup appropiate paths in /dev and just because nvidia sucks.

/etc/udev/rules.d/70-nvidia_uvm.rules

ACTION=="add", DEVPATH=="/bus/pci/drivers/nvidia", RUN+="/usr/bin/nvidia-modprobe -c0 -u"

to get PRIME synchronisation working. https://us.download.nvidia.com/XFree86/Linux-x86_64/470.63.01/README/randr14.html

/etc/modprobed.d/nvidia-prime.conf

options nvidia-drm modeset=1

Enabling PCI-Express Runtime D3 (RTD3) Power Management for NVIDIA dGPU

This makes the dGPU power on/off when the nvidia driver detects usage on the gpu. i mainly use it with prime-run <application> and it powers on/off upon exit.

now we can enable the powermanagement option in the nvidia driver. set NVreg_DynamicPowerManagement=0x02 with a modprobe.d/nvidia.conf

/etc/modprobed.d/nvidia.conf

options nvidia "NVreg_DynamicPowerManagement=0x02"

now we can make an udev rule to enable power management, as according to nvidia readme.

/etc/udev/rules.d/80-nvidia_pm.rules

# Remove NVIDIA USB xHCI Host Controller devices, if present
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c0330", ATTR{remove}="1"

# Remove NVIDIA USB Type-C UCSI devices, if present
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c8000", ATTR{remove}="1"

# Remove NVIDIA Audio devices, if present
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x040300", ATTR{remove}="1"

# Enable runtime PM for NVIDIA VGA/3D controller devices on driver bind
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="auto"

# Disable runtime PM for NVIDIA VGA/3D controller devices on driver unbind
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="on"
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="on"

we also need nvidia-persistenced to run to not make the "kernel tear down the device state whenever the NVIDIA device resources are no longer in use". More information here https://download.nvidia.com/XFree86/Linux-x86_64/396.51/README/nvidia-persistenced.html

systemctl enable nvidia-persistenced

reboot and we are good to go.

to check the nvidia gpu state you can cat /proc/driver/nvidia/gpus/0000:01:00.0/power

if its powered off and everything is working as intended you get an output like this.

Runtime D3 status:          Enabled (fine-grained)
Video Memory:               Off

GPU Hardware Support:
 Video Memory Self Refresh: Supported
 Video Memory Off:          Supported

Power Limits:
 Default:                   N/A milliwatts
 GPU Boost:                 N/A milliwatts

and when its powered on you get an output like this.

Runtime D3 status:          Enabled (fine-grained)
Video Memory:               Active

GPU Hardware Support:
 Video Memory Self Refresh: Supported
 Video Memory Off:          Supported

Power Limits:
 Default:                   80000 milliwatts
 GPU Boost:                 4294967295 milliwatts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment