Implement set_gpu_performance_level.

Use an enum of values for level:
0 - auto
1 - low
2 - high
3 - manual
4 - peak_performance

If any out of range are given, return an false. If unable to write
or open for writing, return false. May change to give an err type
instead later if that helps client side.
This commit is contained in:
Jeremy Whiting 2023-10-11 13:20:53 -06:00
parent 05a716b3b1
commit 0a49fdaf1f
2 changed files with 32 additions and 4 deletions

View file

@ -137,15 +137,13 @@
<!-- <!--
SetGPUPerformanceLevel: SetGPUPerformanceLevel:
@level: The level to use (TODO: Fill in range here and also check it in code?) @level: The level to use 0 - auto, 1 - low, 2 - high, 3 - manual, 4 - profile_peak
@auto: True if we should set back to auto. False to use level above.
@success: True on success. False otherwise. @success: True on success. False otherwise.
Set the GPU performance level to the given value. Set the GPU performance level to the given value.
--> -->
<method name="SetGPUPerformanceLevel"> <method name="SetGPUPerformanceLevel">
<arg type="i" name="level" direction="in"/> <arg type="i" name="level" direction="in"/>
<arg type="b" name="auto" direction="in"/>
<arg type="b" name="success" direction="out"/> <arg type="b" name="success" direction="out"/>
</method> </method>

View file

@ -24,7 +24,7 @@
*/ */
use std::{ffi::OsStr}; use std::{ffi::OsStr};
use tokio::process::Command; use tokio::{process::Command, fs::File, io::AsyncWriteExt};
use zbus_macros::dbus_interface; use zbus_macros::dbus_interface;
pub struct SMManager { pub struct SMManager {
} }
@ -132,6 +132,36 @@ impl SMManager {
run_script("format sdcard", "/usr/bin/steamos-polkit-helpers/steamos-format-sdcard", &[""]).await run_script("format sdcard", "/usr/bin/steamos-polkit-helpers/steamos-format-sdcard", &[""]).await
} }
async fn set_gpu_performance_level(&self, level: i32) -> bool {
// Set given level to sysfs path /sys/class/drm/card0/device/power_dpm_force_performance_level
// Levels are defined below
// return true if able to write, false otherwise or if level is out of range, etc.
let levels = [
"auto",
"low",
"high",
"manual",
"peak_performance"
];
if level < 0 || level >= levels.len() as i32 {
return false;
}
// Open sysfs file
let result = File::create("/sys/class/drm/card0/device/power_dpm_force_performance_level").await;
let mut myfile;
match result {
Ok(f) => myfile = f,
Err(message) => { println!("Error opening sysfs file for writing {message}"); return false; }
};
// write value
let result = myfile.write_all(levels[level as usize].as_bytes()).await;
match result {
Ok(_worked) => true,
Err(message) => { println!("Error writing to sysfs file {message}"); false }
}
}
/// A version property. /// A version property.
#[dbus_interface(property)] #[dbus_interface(property)]