diff --git a/modules/nixos/ryzenadj.nix b/modules/nixos/ryzenadj.nix index 35000f6..a0600ab 100644 --- a/modules/nixos/ryzenadj.nix +++ b/modules/nixos/ryzenadj.nix @@ -3,7 +3,132 @@ pkgs, lib, ... -}: { +}: let + ryzenadj-service = + pkgs.writers.writePython3Bin "ryzenadj-service" { + libraries = [pkgs.ryzenadj]; + flakeIgnore = ["E501" "F405" "F403" "E265"]; + } '' + #!/bin/env python3 + + import argparse + import os + import sys + import time + from ctypes import * + + lib_path = os.path.dirname(os.path.abspath(__file__)) + os.chdir(lib_path) + + lib = cdll.LoadLibrary("${pkgs.ryzenadj}/lib/libryzenadj.so") + + # define ctype mappings for types which can not be mapped automatically + # ryzenadj tables + lib.init_ryzenadj.restype = c_void_p + lib.refresh_table.argtypes = [c_void_p] + # Stapm value and limit + lib.get_stapm_limit.restype = c_float + lib.get_stapm_limit.argtypes = [c_void_p] + # Slow limit and value + lib.get_slow_limit.restype = c_float + lib.get_slow_limit.argtypes = [c_void_p] + # Fast limit and value + lib.get_fast_limit.restype = c_float + lib.get_fast_limit.argtypes = [c_void_p] + # Slow time and value + lib.get_slow_time.restype = c_float + lib.get_slow_time.argtypes = [c_void_p] + # stapm time and value + lib.get_stapm_time.restype = c_float + lib.get_stapm_time.argtypes = [c_void_p] + # Vrm Max Current and value + lib.get_vrmmax_current.restype = c_float + lib.get_vrmmax_current.argtypes = [c_void_p] + # Tctl cpu temp + lib.get_tctl_temp.restype = c_float + lib.get_tctl_temp.argtypes = [c_void_p] + + ry = lib.init_ryzenadj() + + if not ry: + sys.exit("RyzenAdj could not get initialized") + + error_messages = { + -1: "{:s} is not supported on this family\n", + -3: "{:s} is not supported on this SMU\n", + -4: "{:s} is rejected by SMU\n", + } + + + def adjust(field, value): + function_name = "set_" + field + adjust_func = lib.__getattr__(function_name) + adjust_func.argtypes = [c_void_p, c_ulong] + res = adjust_func(ry, value) + if res: + error = error_messages.get(res, "{:s} did fail with {:d}\n") + sys.stderr.write(error.format(function_name, res)) + else: + print(f"Succesfully set {field} to {value}") + + + def enable(field): + function_name = "set_" + field + adjust_func = lib.__getattr__(function_name) + adjust_func.argtypes = [c_void_p] + res = adjust_func(ry) + if res: + error = error_messages.get(res, "{:s} did fail with {:d}\n") + sys.stderr.write(error.format(function_name, res)) + else: + print(f"Sucessfully enable {field}") + + + def set(args): + adjust("stapm_limit", args.stapm_limit) + adjust("fast_limit", args.fast_limit) + adjust("slow_limit", args.slow_limit) + adjust("slow_time", args.slow_time) + adjust("stapm_time", args.stapm_time) + adjust("tctl_temp", args.tctl_temp) + adjust("vrmmax_current", args.vrmmax_current) + enable("max_performance") + + + def loop(args): + set(args) + while True: + lib.refresh_table(ry) + current = round(lib.get_tctl_temp(ry)) + if current != 85: + set(args) + time.sleep(3) + + + def parse_args(): + parser = argparse.ArgumentParser( + prog="Ryzenadj Service", + description="Simple Ryzenadj python service to keep values set", + ) + parser.add_argument("--stapm-limit", action="store", required=True, type=int) + parser.add_argument("--fast-limit", action="store", required=True, type=int) + parser.add_argument("--slow-limit", action="store", required=True, type=int) + parser.add_argument("--slow-time", action="store", required=True, type=int) + parser.add_argument("--stapm-time", action="store", required=True, type=int) + parser.add_argument("--tctl-temp", action="store", required=True, type=int) + parser.add_argument("--vrmmax-current", action="store", required=True, type=int) + return parser.parse_args() + + + def main(): + args = parse_args() + loop(args) + + + if __name__ == "__main__": + main() + ''; +in { options = { crony.ryzenadj.enable = lib.mkEnableOption "Enable ryzenadj and customize it for my system."; }; @@ -21,9 +146,8 @@ systemd.services.ryzenadj = { enable = true; description = "Set my cpu power usage power to something more manageable."; - serviceConfig.Type = "oneshot"; wantedBy = ["multi-user.target"]; - script = "${pkgs.ryzenadj}/bin/ryzenadj --stapm-limit 30000 --fast-limit 30000 --slow-limit 30000 --slow-time 60 --stapm-time 1000 --tctl-temp 85 --vrmmax-current 46000"; + script = "${ryzenadj-service}/bin/ryzenadj-service --stapm-limit 35000 --fast-limit 35000 --slow-limit 35000 --slow-time 60 --stapm-time 1000 --tctl-temp 90 --vrmmax-current 59000"; }; }; }