Skip to content

Instantly share code, notes, and snippets.

@coderofsalvation
Last active December 19, 2023 08:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coderofsalvation/bff3c02c2184c58e9013d1e34285817c to your computer and use it in GitHub Desktop.
Save coderofsalvation/bff3c02c2184c58e9013d1e34285817c to your computer and use it in GitHub Desktop.
NixOS Lenovo ideapad s540 nvidia GTX1650 powersave

Welcome ideapad s540 GTX1650 Nix-friends (good news ahead)

I've spend way too long to get the NVIDIA-driver to work, as well as taming the overheating problem which has haunted my ideapad forever. I hope this config can save somebody else lots of time (please comment!), as I experienced weird catch22 scenarios because of the dual-video driver.

note: if you laptop still overheats, lower the CPU_SCALING_MAX_FREQ variables.

You can now run apps on the NVIDIA GPU by creating this nvidia-run shellscript-wrapper:

#!/bin/sh
export __NV_PRIME_RENDER_OFFLOAD=1
export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0
export __GLX_VENDOR_LIBRARY_NAME=nvidia
export __VK_LAYER_NV_optimus=NVIDIA_only
exec "$@"

Demo:

$ nix-shell -p glxinfo --run glxinfo| grep 'OpenGL vendor'
OpenGL vendor string: Intel

$ ./nvidia-run nix-shell -p glxinfo --run glxinfo| grep 'OpenGL vendor'
OpenGL vendor string: NVIDIA Corporation
{ config, pkgs, ... }:
{
imports =
[
/path/to/hardware-configuration.nix
];
# all your other stuff
}
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[
(modulesPath + "/installer/scan/not-detected.nix")
./nvidia.nix
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" "fuse" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-label/nixos";
fsType = "ext4";
};
swapDevices = [ { device = "/dev/disk/by-label/swap" ; } ];
#networking.hostName = "ideapad";
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
# pinned kernel version, change with commented latest version if needed
boot.kernelPackages = pkgs.linuxPackages_6_1; # pkgs.linuxPackages_latest;
boot.kernelParams = ["intel_pstate=disable"];
# prevent overheating
services.tlp = {
#config.services.tlp.settings = {
enable = true;
extraConfig = ''
START_CHARGE_THRESH_BAT0=75
STOP_CHARGE_THRESH_BAT0=80
#CPU_SCALING_GOVERNOR_ON_AC=schedutil
#CPU_SCALING_GOVERNOR_ON_BAT=schedutil
## ideapad s540: scaling_available_frequencies = 2001000 2000000 1900000 1800000 1700000 1500000 1400000 1300000 1200000 1100000 1000000 800000 700000 600000 500000 400000 [kHz]
#CPU_SCALING_MIN_FREQ_ON_AC=400000 # see tlp-stat -p for min/max
#CPU_SCALING_MAX_FREQ_ON_AC=1900000
#CPU_SCALING_MIN_FREQ_ON_BAT=400000
#CPU_SCALING_MAX_FREQ_ON_BAT=1900000
CPU_SCALING_GOVERNOR_ON_AC = "performance";
CPU_SCALING_GOVERNOR_ON_BAT = "powersave";
CPU_ENERGY_PERF_POLICY_ON_BAT = "power";
CPU_ENERGY_PERF_POLICY_ON_AC = "performance";
CPU_MIN_PERF_ON_AC = 0;
CPU_MAX_PERF_ON_AC = 100;
CPU_MIN_PERF_ON_BAT = 0;
CPU_MAX_PERF_ON_BAT = 20;
# uncomment this to always run in battery mode (when laptop keeps runing too hot in AC mode)
#TLP_DEFAULT_MODE = "BAT";
#TLP_PERSISTENT_DEFAULT = 1;
# Enable audio power saving for Intel HDA, AC97 devices (timeout in secs).
# A value of 0 disables, >=1 enables power saving (recommended: 1).
# Default: 0 (AC), 1 (BAT)
SOUND_POWER_SAVE_ON_AC=0
SOUND_POWER_SAVE_ON_BAT=1
# Runtime Power Management for PCI(e) bus devices: on=disable, auto=enable.
# Default: on (AC), auto (BAT)
#RUNTIME_PM_ON_AC=on
#RUNTIME_PM_ON_BAT=auto
# Battery feature drivers: 0=disable, 1=enable
# Default: 1 (all)
NATACPI_ENABLE=1
TPACPI_ENABLE=1
TPSMAPI_ENABLE=1
'';
};
}
{ pkgs, ... }:
{
nixpkgs.config.allowUnfree = true;
## Make sure opengl is enabled
hardware.opengl = {
enable = true;
driSupport = true;
driSupport32Bit = true;
};
## Tell Xorg to use the nvidia driver (also valid for Wayland)
services.xserver.videoDrivers = ["nvidia"];
hardware.nvidia.prime = {
offload = {
enable = true;
enableOffloadCmd = true;
};
sync.enable = false;
# Bus ID of the Intel GPU. You can find it using lspci, either under 3D or VGA
intelBusId = "PCI:0:02:0";
# Bus ID of the NVIDIA GPU. You can find it using lspci, either under 3D or VGA
nvidiaBusId = "PCI:2:00:0";
};
hardware.nvidia = {
## Modesetting is needed for most Wayland compositors
modesetting.enable = true;
# Use the open source version of the kernel module
# Only available on driver 515.43.04+
open = false;
# Enable the nvidia settings menu
nvidiaSettings = true;
package = pkgs.linuxPackages.nvidia_x11;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment