mirror of
https://gitlab.steamos.cloud/holo/steamos-manager.git
synced 2025-07-12 17:32:21 -04:00
manager: Implement new API
This commit is contained in:
parent
6a5e693e5b
commit
69e6477053
5 changed files with 419 additions and 196 deletions
82
src/power.rs
82
src/power.rs
|
@ -5,7 +5,8 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
use anyhow::{bail, ensure, Result};
|
||||
use anyhow::{anyhow, bail, ensure, Error, Result};
|
||||
use std::str::FromStr;
|
||||
use tokio::fs::{self, File};
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tracing::error;
|
||||
|
@ -18,22 +19,81 @@ const GPU_PERFORMANCE_LEVEL_PATH: &str =
|
|||
"/sys/class/drm/card0/device/power_dpm_force_performance_level";
|
||||
const GPU_CLOCKS_PATH: &str = "/sys/class/drm/card0/device/pp_od_clk_voltage";
|
||||
|
||||
pub async fn set_gpu_performance_level(level: i32) -> Result<()> {
|
||||
// Set given GPU 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"];
|
||||
ensure!(
|
||||
level >= 0 && level < levels.len() as i32,
|
||||
"Invalid performance level"
|
||||
);
|
||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||
#[repr(u32)]
|
||||
pub enum GPUPerformanceLevel {
|
||||
UnsupportedFeature = 0,
|
||||
Auto = 1,
|
||||
Low = 2,
|
||||
High = 3,
|
||||
Manual = 4,
|
||||
ProfilePeak = 5,
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for GPUPerformanceLevel {
|
||||
type Error = &'static str;
|
||||
fn try_from(v: u32) -> Result<Self, Self::Error> {
|
||||
match v {
|
||||
x if x == GPUPerformanceLevel::UnsupportedFeature as u32 => {
|
||||
Ok(GPUPerformanceLevel::UnsupportedFeature)
|
||||
}
|
||||
x if x == GPUPerformanceLevel::Auto as u32 => Ok(GPUPerformanceLevel::Auto),
|
||||
x if x == GPUPerformanceLevel::Low as u32 => Ok(GPUPerformanceLevel::Low),
|
||||
x if x == GPUPerformanceLevel::High as u32 => Ok(GPUPerformanceLevel::High),
|
||||
x if x == GPUPerformanceLevel::Manual as u32 => Ok(GPUPerformanceLevel::Manual),
|
||||
x if x == GPUPerformanceLevel::ProfilePeak as u32 => {
|
||||
Ok(GPUPerformanceLevel::ProfilePeak)
|
||||
}
|
||||
_ => Err("No enum match for value {v}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for GPUPerformanceLevel {
|
||||
type Err = Error;
|
||||
fn from_str(input: &str) -> Result<GPUPerformanceLevel, Self::Err> {
|
||||
match input {
|
||||
"auto" => Ok(GPUPerformanceLevel::Auto),
|
||||
"low" => Ok(GPUPerformanceLevel::Low),
|
||||
"high" => Ok(GPUPerformanceLevel::High),
|
||||
"manual" => Ok(GPUPerformanceLevel::Manual),
|
||||
"peak_performance" => Ok(GPUPerformanceLevel::ProfilePeak),
|
||||
v => Err(anyhow!("No enum match for value {v}")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryInto<String> for GPUPerformanceLevel {
|
||||
type Error = Error;
|
||||
fn try_into(self) -> Result<String, Self::Error> {
|
||||
Ok(String::from(match self {
|
||||
GPUPerformanceLevel::Auto => "auto",
|
||||
GPUPerformanceLevel::Low => "low",
|
||||
GPUPerformanceLevel::High => "high",
|
||||
GPUPerformanceLevel::Manual => "manual",
|
||||
GPUPerformanceLevel::ProfilePeak => "peak_performance",
|
||||
GPUPerformanceLevel::UnsupportedFeature => bail!("No valid string representation"),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_gpu_performance_level() -> Result<GPUPerformanceLevel> {
|
||||
let level = fs::read_to_string(GPU_PERFORMANCE_LEVEL_PATH)
|
||||
.await
|
||||
.inspect_err(|message| error!("Error opening sysfs file for reading: {message}"))?;
|
||||
|
||||
GPUPerformanceLevel::from_str(level.as_ref())
|
||||
}
|
||||
|
||||
pub async fn set_gpu_performance_level(level: GPUPerformanceLevel) -> Result<()> {
|
||||
let mut myfile = File::create(GPU_PERFORMANCE_LEVEL_PATH)
|
||||
.await
|
||||
.inspect_err(|message| error!("Error opening sysfs file for writing: {message}"))?;
|
||||
|
||||
let level: String = level.try_into()?;
|
||||
|
||||
myfile
|
||||
.write_all(levels[level as usize].as_bytes())
|
||||
.write_all(level.as_bytes())
|
||||
.await
|
||||
.inspect_err(|message| error!("Error writing to sysfs file: {message}"))?;
|
||||
Ok(())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue