summary refs log tree commit diff
path: root/nixos/modules/services/hardware/undervolt.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/services/hardware/undervolt.nix')
-rw-r--r--nixos/modules/services/hardware/undervolt.nix100
1 files changed, 58 insertions, 42 deletions
diff --git a/nixos/modules/services/hardware/undervolt.nix b/nixos/modules/services/hardware/undervolt.nix
index e5ef0601de3..054ffa35050 100644
--- a/nixos/modules/services/hardware/undervolt.nix
+++ b/nixos/modules/services/hardware/undervolt.nix
@@ -1,18 +1,35 @@
 { config, pkgs, lib, ... }:
 
 with lib;
-
 let
   cfg = config.services.undervolt;
-in {
+  cliArgs = lib.cli.toGNUCommandLineShell {} {
+    inherit (cfg)
+      verbose
+      temp
+      ;
+    # `core` and `cache` are both intentionally set to `cfg.coreOffset` as according to the undervolt docs:
+    #
+    #     Core or Cache offsets have no effect. It is not possible to set different offsets for
+    #     CPU Core and Cache. The CPU will take the smaller of the two offsets, and apply that to
+    #     both CPU and Cache. A warning message will be displayed if you attempt to set different offsets.
+    core = cfg.coreOffset;
+    cache = cfg.coreOffset;
+    gpu = cfg.gpuOffset;
+    uncore = cfg.uncoreOffset;
+    analogio = cfg.analogioOffset;
+
+    temp-bat = cfg.tempBat;
+    temp-ac = cfg.tempAc;
+  };
+in
+{
   options.services.undervolt = {
-    enable = mkOption {
-      type = types.bool;
-      default = false;
-      description = ''
-        Whether to undervolt intel cpus.
-      '';
-    };
+    enable = mkEnableOption ''
+       Undervolting service for Intel CPUs.
+
+       Warning: This service is not endorsed by Intel and may permanently damage your hardware. Use at your own risk!
+    '';
 
     verbose = mkOption {
       type = types.bool;
@@ -32,58 +49,69 @@ in {
     };
 
     coreOffset = mkOption {
-      type = types.nullOr types.str;
+      type = types.nullOr types.int;
       default = null;
       description = ''
-        The amount of voltage to offset the CPU cores by. Accepts a floating point number.
+        The amount of voltage in mV to offset the CPU cores by.
       '';
     };
 
     gpuOffset = mkOption {
-      type = types.nullOr types.str;
+      type = types.nullOr types.int;
       default = null;
       description = ''
-        The amount of voltage to offset the GPU by. Accepts a floating point number.
+        The amount of voltage in mV to offset the GPU by.
       '';
     };
 
     uncoreOffset = mkOption {
-      type = types.nullOr types.str;
+      type = types.nullOr types.int;
       default = null;
       description = ''
-        The amount of voltage to offset uncore by. Accepts a floating point number.
+        The amount of voltage in mV to offset uncore by.
       '';
     };
 
     analogioOffset = mkOption {
-      type = types.nullOr types.str;
+      type = types.nullOr types.int;
       default = null;
       description = ''
-        The amount of voltage to offset analogio by. Accepts a floating point number.
+        The amount of voltage in mV to offset analogio by.
       '';
     };
 
     temp = mkOption {
-      type = types.nullOr types.str;
+      type = types.nullOr types.int;
       default = null;
       description = ''
-        The temperature target. Accepts a floating point number.
+        The temperature target in Celsius degrees.
       '';
     };
 
     tempAc = mkOption {
-      type = types.nullOr types.str;
+      type = types.nullOr types.int;
       default = null;
       description = ''
-        The temperature target on AC power. Accepts a floating point number.
+        The temperature target on AC power in Celsius degrees.
       '';
     };
 
     tempBat = mkOption {
-      type = types.nullOr types.str;
+      type = types.nullOr types.int;
       default = null;
       description = ''
-        The temperature target on battery power. Accepts a floating point number.
+        The temperature target on battery power in Celsius degrees.
+      '';
+    };
+
+    useTimer = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Whether to set a timer that applies the undervolt settings every 30s.
+        This will cause spam in the journal but might be required for some
+        hardware under specific conditions.
+        Enable this if your undervolt settings don't hold.
       '';
     };
   };
@@ -97,31 +125,19 @@ in {
       path = [ pkgs.undervolt ];
 
       description = "Intel Undervolting Service";
+
+      # Apply undervolt on boot, nixos generation switch and resume
+      wantedBy = [ "multi-user.target" "post-resume.target" ];
+      after = [ "post-resume.target" ]; # Not sure why but it won't work without this
+
       serviceConfig = {
         Type = "oneshot";
         Restart = "no";
-
-        # `core` and `cache` are both intentionally set to `cfg.coreOffset` as according to the undervolt docs:
-        #
-        #     Core or Cache offsets have no effect. It is not possible to set different offsets for
-        #     CPU Core and Cache. The CPU will take the smaller of the two offsets, and apply that to
-        #     both CPU and Cache. A warning message will be displayed if you attempt to set different offsets.
-        ExecStart = ''
-          ${pkgs.undervolt}/bin/undervolt \
-            ${optionalString cfg.verbose "--verbose"} \
-            ${optionalString (cfg.coreOffset != null) "--core ${cfg.coreOffset}"} \
-            ${optionalString (cfg.coreOffset != null) "--cache ${cfg.coreOffset}"} \
-            ${optionalString (cfg.gpuOffset != null) "--gpu ${cfg.gpuOffset}"} \
-            ${optionalString (cfg.uncoreOffset != null) "--uncore ${cfg.uncoreOffset}"} \
-            ${optionalString (cfg.analogioOffset != null) "--analogio ${cfg.analogioOffset}"} \
-            ${optionalString (cfg.temp != null) "--temp ${cfg.temp}"} \
-            ${optionalString (cfg.tempAc != null) "--temp-ac ${cfg.tempAc}"} \
-            ${optionalString (cfg.tempBat != null) "--temp-bat ${cfg.tempBat}"}
-        '';
+        ExecStart = "${pkgs.undervolt}/bin/undervolt ${cliArgs}";
       };
     };
 
-    systemd.timers.undervolt = {
+    systemd.timers.undervolt = mkIf cfg.useTimer {
       description = "Undervolt timer to ensure voltage settings are always applied";
       partOf = [ "undervolt.service" ];
       wantedBy = [ "multi-user.target" ];