mirror of
https://gitlab.steamos.cloud/holo/steamos-manager.git
synced 2025-07-08 15:40:34 -04:00
power: Use VID:PID combination to get GPU clock ranges
This commit is contained in:
parent
f31d76ea53
commit
8c52189d98
2 changed files with 48 additions and 5 deletions
|
@ -33,10 +33,6 @@ systemd = "jupiter-fan-control.service"
|
||||||
min = 3
|
min = 3
|
||||||
max = 15
|
max = 15
|
||||||
|
|
||||||
[gpu_clocks]
|
|
||||||
min = 200
|
|
||||||
max = 1600
|
|
||||||
|
|
||||||
[battery_charge_limit]
|
[battery_charge_limit]
|
||||||
suggested_minimum_limit = 10
|
suggested_minimum_limit = 10
|
||||||
hwmon_name = "steamdeck_hwmon"
|
hwmon_name = "steamdeck_hwmon"
|
||||||
|
|
49
src/power.rs
49
src/power.rs
|
@ -9,6 +9,7 @@ use anyhow::{anyhow, bail, ensure, Result};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use num_enum::TryFromPrimitive;
|
use num_enum::TryFromPrimitive;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use strum::{Display, EnumString};
|
use strum::{Display, EnumString};
|
||||||
|
@ -44,6 +45,12 @@ lazy_static! {
|
||||||
Regex::new(r"^\s*(?<value>[0-9]+)\s+(?<name>[0-9A-Za-z_]+)(?<active>\*)?").unwrap();
|
Regex::new(r"^\s*(?<value>[0-9]+)\s+(?<name>[0-9A-Za-z_]+)(?<active>\*)?").unwrap();
|
||||||
static ref GPU_CLOCK_LEVELS_REGEX: Regex =
|
static ref GPU_CLOCK_LEVELS_REGEX: Regex =
|
||||||
Regex::new(r"^\s*(?<index>[0-9]+): (?<value>[0-9]+)Mhz").unwrap();
|
Regex::new(r"^\s*(?<index>[0-9]+): (?<value>[0-9]+)Mhz").unwrap();
|
||||||
|
static ref GPU_CLOCK_RANGES: HashMap<&'static str, (u32, u32)> = HashMap::from([
|
||||||
|
("1002:1435", (200, 1600)), // Sephiroth (Steam Deck OLED)
|
||||||
|
("1002:15bf", (800, 2700)), // Phoenix1 (Ryzen Z1 Extreme)
|
||||||
|
("1002:15c8", (800, 2799)), // Phoenix2 (Ryzen Z1/Radeon 740M Graphics)
|
||||||
|
("1002:163f", (200, 1600)), // VanGogh (Steam Deck)
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Display, EnumString, PartialEq, Debug, Copy, Clone, TryFromPrimitive)]
|
#[derive(Display, EnumString, PartialEq, Debug, Copy, Clone, TryFromPrimitive)]
|
||||||
|
@ -263,6 +270,18 @@ pub(crate) async fn get_gpu_clocks_range() -> Result<(u32, u32)> {
|
||||||
{
|
{
|
||||||
return Ok((range.min, range.max));
|
return Ok((range.min, range.max));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let vid = read_gpu_sysfs_contents("device/vendor").await?;
|
||||||
|
let pid = read_gpu_sysfs_contents("device/device").await?;
|
||||||
|
if let (Some(vid), Some(pid)) = (
|
||||||
|
vid.trim_end().strip_prefix("0x"),
|
||||||
|
pid.trim_end().strip_prefix("0x"),
|
||||||
|
) {
|
||||||
|
if let Some(range) = GPU_CLOCK_RANGES.get(format!("{vid}:{pid}").as_str()) {
|
||||||
|
return Ok(*range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let contents = read_gpu_sysfs_contents(GPU_CLOCK_LEVELS_SUFFIX).await?;
|
let contents = read_gpu_sysfs_contents(GPU_CLOCK_LEVELS_SUFFIX).await?;
|
||||||
let lines = contents.lines();
|
let lines = contents.lines();
|
||||||
let mut min = 1_000_000;
|
let mut min = 1_000_000;
|
||||||
|
@ -715,7 +734,7 @@ CCLK_RANGE in Core0:
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_get_gpu_clocks_range() {
|
async fn test_get_gpu_clocks_range_parse() {
|
||||||
let _h = testing::start();
|
let _h = testing::start();
|
||||||
|
|
||||||
setup().await.expect("setup");
|
setup().await.expect("setup");
|
||||||
|
@ -727,6 +746,12 @@ CCLK_RANGE in Core0:
|
||||||
|
|
||||||
assert!(get_gpu_clocks_range().await.is_err());
|
assert!(get_gpu_clocks_range().await.is_err());
|
||||||
|
|
||||||
|
write(base.join("device/vendor"), b"0x1002\n")
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
write(base.join("device/device"), b"0xffff\n")
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
write(filename.as_path(), &[] as &[u8; 0])
|
write(filename.as_path(), &[] as &[u8; 0])
|
||||||
.await
|
.await
|
||||||
.expect("write");
|
.expect("write");
|
||||||
|
@ -745,6 +770,28 @@ CCLK_RANGE in Core0:
|
||||||
assert_eq!(get_gpu_clocks_range().await.unwrap(), (200, 1600));
|
assert_eq!(get_gpu_clocks_range().await.unwrap(), (200, 1600));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_gpu_clocks_range_vid_pid() {
|
||||||
|
let _h = testing::start();
|
||||||
|
|
||||||
|
setup().await.expect("setup");
|
||||||
|
let base = find_hwmon(GPU_HWMON_NAME).await.unwrap();
|
||||||
|
let filename = base.join(GPU_CLOCK_LEVELS_SUFFIX);
|
||||||
|
create_dir_all(filename.parent().unwrap())
|
||||||
|
.await
|
||||||
|
.expect("create_dir_all");
|
||||||
|
|
||||||
|
assert!(get_gpu_clocks_range().await.is_err());
|
||||||
|
|
||||||
|
write(base.join("device/vendor"), b"0x1002\n")
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
write(base.join("device/device"), b"0x1435\n")
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(get_gpu_clocks_range().await.unwrap(), (200, 1600));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn gpu_power_profile_roundtrip() {
|
fn gpu_power_profile_roundtrip() {
|
||||||
enum_roundtrip!(GPUPowerProfile {
|
enum_roundtrip!(GPUPowerProfile {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue