#!/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("/usr/lib64/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()