diff --git a/modules/default.nix b/modules/default.nix index 84ccb1a..5263bd7 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1,6 +1,7 @@ { - # Add your NixOS modules here - # - # my-module = ./my-module; + amdgpu-common = ./services/hardware/amdgpu-common.nix; + amdgpu-fan = ./services/hardware/amdgpu-fan.nix; + amdgpu-pwm = ./services/hardware/amdgpu-pwm.nix; + radeon-profile-daemon = ./services/hardware/radeon-profile-daemon.nix; } diff --git a/modules/services/hardware/amdgpu-common.nix b/modules/services/hardware/amdgpu-common.nix new file mode 100644 index 0000000..572d70a --- /dev/null +++ b/modules/services/hardware/amdgpu-common.nix @@ -0,0 +1,17 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + options.services.amdgpu = { + cards = mkOption { + type = types.listOf types.str; + default = [ "card0" ]; + example = literalExample ''[ "card0" ]''; + description = '' + A list of cards to enable fan configuration for. The identifiers for + each device can be found in /sys/class/drm/ as card0, card1, etc. + ''; + }; + }; +} diff --git a/modules/services/hardware/amdgpu-fan.nix b/modules/services/hardware/amdgpu-fan.nix new file mode 100644 index 0000000..3e810de --- /dev/null +++ b/modules/services/hardware/amdgpu-fan.nix @@ -0,0 +1,71 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + acfg = config.services.amdgpu; + cfg = config.services.amdgpu.fan; + +in + +{ + options.services.amdgpu.fan = { + enable = mkEnableOption "amdgpu-fan"; + + speedMatrix = mkOption { + type = with types; listOf (listOf int); + # Translated from upstream default config. Since it tries to write the + # config if it's not found, we want some kind of default. + default = [ + [ 0 0 ] + [ 30 33 ] + [ 45 50 ] + [ 60 66 ] + [ 65 69 ] + [ 70 75 ] + [ 75 89 ] + [ 80 100 ] + ]; + example = literalExample '' + [ + [ 0 0 ] + [ 40 30 ] + [ 60 50 ] + [ 80 100 ] + ] + ''; + description = '' + A list of temperature-fan speed pairs. The temperature is specified in + degrees celcius, and speed is specified in %. + ''; + }; + }; + + config = mkIf cfg.enable { + assertions = singleton { + assertion = all (speeds: length speeds == 2) cfg.speedMatrix; + message = "services.amdgpu-fan.speedMatrix must be a list of paired lists"; + }; + + environment.etc."amdgpu-fan.yml".text = builtins.toJSON { + speed_matrix = cfg.speedMatrix; + cards = acfg.cards; + }; + + powerManagement.resumeCommands = "${pkgs.systemd}/bin/systemctl try-restart amdgpu-fan"; + + # Translated from the upstream service file. + systemd.services = { + amdgpu-fan = { + description = "amdgpu fan controller"; + wantedBy = [ "default.target" ]; + after = [ "enable-manual-amdgpu-fan.service" ]; + serviceConfig = { + ExecStart = "${pkgs.amdgpu-fan}/bin/amdgpu-fan"; + Restart = "always"; + }; + }; + }; + }; +} diff --git a/modules/services/hardware/amdgpu-pwm.nix b/modules/services/hardware/amdgpu-pwm.nix new file mode 100644 index 0000000..5849f5b --- /dev/null +++ b/modules/services/hardware/amdgpu-pwm.nix @@ -0,0 +1,29 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + acfg = config.services.amdgpu; + cfg = config.services.amdgpu.pwm; + +in + +{ + options.services.amdgpu.pwm = { + enable = mkEnableOption "amdgpu-pwm"; + }; + + config = mkIf cfg.enable { + systemd.services.amdgpu-pwm = { + description = "enable manual configuration of AMDGPU fans"; + wantedBy = [ "default.target" ]; + script = + let + enablePwm = card: "echo 1 > /sys/class/drm/${card}/device/hwmon/hwmon1/pwm1_enable"; + in + lib.concatStringsSep "\n" (map enablePwm acfg.cards); + serviceConfig.Type = "oneshot"; + }; + }; +} diff --git a/modules/services/hardware/radeon-profile-daemon.nix b/modules/services/hardware/radeon-profile-daemon.nix new file mode 100644 index 0000000..4d4b90b --- /dev/null +++ b/modules/services/hardware/radeon-profile-daemon.nix @@ -0,0 +1,29 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.radeon-profile-daemon; + +in + +{ + options.services.radeon-profile-daemon = { + enable = mkEnableOption "radeon-profile-daemon"; + }; + + config = mkIf cfg.enable { + systemd.services = { + radeon-profile-daemon = { + description = "radeon-profile daemon"; + wantedBy = [ "multi-user.target" ]; + after = [ "enable-manual-amdgpu-fan.service" ]; + serviceConfig = { + Type = "simple"; + ExecStart = "${pkgs.radeon-profile-daemon}/bin/radeon-profile-daemon"; + }; + }; + }; + }; +}