1
0
Fork 0

Merge pull request #601 from superm1/superm1/amdgpu

Add a plugin for amdgpu tuning of the `panel_power_savings` attribute
This commit is contained in:
Jaroslav Škarvada 2024-05-23 18:16:22 +02:00 committed by GitHub
commit 95738a5c54
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 83 additions and 12 deletions

View file

@ -62,3 +62,6 @@ sched_min_granularity_ns = 10000000
# and reduces their over-scheduling. Synchronous workloads will still
# have immediate wakeup/sleep latencies.
sched_wakeup_granularity_ns = 15000000
[video]
panel_power_savings=0

View file

@ -22,6 +22,7 @@ timeout=10
[video]
radeon_powersave=dpm-balanced, auto
panel_power_savings=0
[disk]
# Comma separated list of devices, all devices if commented out.

View file

@ -35,3 +35,6 @@ vm.dirty_background_ratio=3
# 100 tells the kernel to aggressively swap processes out of physical memory
# and move them to swap cache
vm.swappiness=10
[video]
panel_power_savings=0

View file

@ -22,6 +22,7 @@ timeout=10
[video]
radeon_powersave=dpm-battery, auto
panel_power_savings=3
[disk]
# Comma separated list of devices, all devices if commented out.

View file

@ -73,3 +73,6 @@ type=sysctl
uname_regex=aarch64
cpuinfo_regex=${thunderx_cpuinfo_regex}
kernel.numa_balancing=0
[video]
panel_power_savings=0

View file

@ -11,9 +11,10 @@ log = tuned.logs.get()
class VideoPlugin(base.Plugin):
"""
`video`::
Sets various powersave levels on video cards. Currently, only the
Radeon cards are supported. The powersave level can be specified
Sets various power saving features on video cards.
Radeon cards are supported.
The powersave level can be specified
by using the [option]`radeon_powersave` option. Supported values are:
+
--
@ -40,17 +41,27 @@ class VideoPlugin(base.Plugin):
radeon_powersave=high
----
====
Mobile hardware with amdgpu driven eDP panels can be configured
with the [option]`panel_power_savings` option.
This accepts a value range from 0 to 4, where 4 is the highest power savings
but will trade off color accuracy.
"""
def __init__(self, *args, **kwargs):
super(VideoPlugin, self).__init__(*args, **kwargs)
def _init_devices(self):
self._devices_supported = True
self._free_devices = set()
self._assigned_devices = set()
# FIXME: this is a blind shot, needs testing
for device in self._hardware_inventory.get_devices("drm").match_sys_name("card*").match_property("DEVTYPE", "drm_minor"):
self._free_devices.add(device.sys_name)
# Add any radeon and amdgpu hardware with /any/ supported attributes present
for device in self._hardware_inventory.get_devices("drm").match_sys_name("card*-*"):
attrs = self._files(device.sys_name)
for attr in attrs:
if os.path.exists(attrs[attr]):
self._free_devices.add(device.sys_name)
self._cmd = commands()
def _get_device_objects(self, devices):
@ -60,6 +71,7 @@ class VideoPlugin(base.Plugin):
def _get_config_options(self):
return {
"radeon_powersave" : None,
"panel_power_savings": None,
}
def _instance_init(self, instance):
@ -69,20 +81,42 @@ class VideoPlugin(base.Plugin):
def _instance_cleanup(self, instance):
pass
def _radeon_powersave_files(self, device):
def _files(self, device):
return {
"method" : "/sys/class/drm/%s/device/power_method" % device,
"profile": "/sys/class/drm/%s/device/power_profile" % device,
"dpm_state": "/sys/class/drm/%s/device/power_dpm_state" % device
"dpm_state": "/sys/class/drm/%s/device/power_dpm_state" % device,
"panel_power_savings": "/sys/class/drm/%s/amdgpu/panel_power_savings" % device,
}
def apply_panel_power_saving_target(self, device, target, sim=False):
"""Apply the target value to the panel_power_savings file if it doesn't already have it"""
# if we don't have the file, we might be radeon not amdgpu
if not os.path.exists(self._files(device)["panel_power_savings"]):
return None
# make sure the value is different (avoids unnecessary kernel modeset)
current = int(self._get_panel_power_savings(device))
if current == target:
log.info(
"panel_power_savings for %s already %s" % (device, target)
)
return target
# flush it out
log.info("%s panel_power_savings -> %s" % (device, target))
if sim or self._cmd.write_to_file(self._files(device)["panel_power_savings"], target):
return target
return None
@command_set("radeon_powersave", per_device=True)
def _set_radeon_powersave(self, value, device, sim, remove):
sys_files = self._radeon_powersave_files(device)
sys_files = self._files(device)
va = str(re.sub(r"(\s*:\s*)|(\s+)|(\s*;\s*)|(\s*,\s*)", " ", value)).split()
if not os.path.exists(sys_files["method"]):
if not sim:
log.warn("radeon_powersave is not supported on '%s'" % device)
log.debug("radeon_powersave is not supported on '%s'" % device)
return None
for v in va:
if v in ["default", "auto", "low", "mid", "high"]:
@ -114,7 +148,10 @@ class VideoPlugin(base.Plugin):
@command_get("radeon_powersave")
def _get_radeon_powersave(self, device, ignore_missing = False):
sys_files = self._radeon_powersave_files(device)
sys_files = self._files(device)
if not os.path.exists(sys_files["method"]):
log.debug("radeon_powersave is not supported on '%s'" % device)
return None
method = self._cmd.read_file(sys_files["method"], no_error=ignore_missing).strip()
if method == "profile":
return self._cmd.read_file(sys_files["profile"]).strip()
@ -124,3 +161,26 @@ class VideoPlugin(base.Plugin):
return "dpm-" + self._cmd.read_file(sys_files["dpm_state"]).strip()
else:
return None
@command_set("panel_power_savings", per_device=True)
def _set_panel_power_savings(self, value, device, sim, remove):
"""Set the panel_power_savings value"""
try:
value = int(value, 10)
except ValueError:
log.warn("Invalid value %s for panel_power_savings" % value)
return None
if value in range(0, 5):
return self.apply_panel_power_saving_target(device, value, sim)
else:
log.warn("Invalid value %s for panel_power_savings" % value)
return None
@command_get("panel_power_savings")
def _get_panel_power_savings(self, device, ignore_missing=False):
"""Get the current panel_power_savings value"""
if not os.path.exists(self._files(device)["panel_power_savings"]):
log.debug("panel_power_savings is not supported on '%s'" % device)
return None
fname = self._files(device)["panel_power_savings"]
return self._cmd.read_file(fname, no_error=ignore_missing).strip()