forked from NG-SD-Plugins/PowerTools
Add Steam Deck max clock detection since OC can now be reported correctly
version 2.0.0-alpha3
This commit is contained in:
parent
1a4bfb9669
commit
3e3e9a68f4
9 changed files with 536 additions and 125 deletions
2
backend/Cargo.lock
generated
2
backend/Cargo.lock
generated
|
@ -1170,7 +1170,7 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "powertools"
|
name = "powertools"
|
||||||
version = "2.0.0-alpha2"
|
version = "2.0.0-alpha3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "powertools"
|
name = "powertools"
|
||||||
version = "2.0.0-alpha2"
|
version = "2.0.0-alpha3"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["NGnius (Graham) <ngniusness@gmail.com>"]
|
authors = ["NGnius (Graham) <ngniusness@gmail.com>"]
|
||||||
description = "Backend (superuser) functionality for PowerTools"
|
description = "Backend (superuser) functionality for PowerTools"
|
||||||
|
|
|
@ -77,16 +77,16 @@ impl Default for Base {
|
||||||
},
|
},
|
||||||
limits: super::Limits {
|
limits: super::Limits {
|
||||||
cpu: super::Limit {
|
cpu: super::Limit {
|
||||||
provider: super::CpuLimitType::SteamDeck,
|
provider: super::CpuLimitType::SteamDeckOLED,
|
||||||
limits: super::GenericCpusLimit::default_for(super::CpuLimitType::SteamDeck),
|
limits: super::GenericCpusLimit::default_for(super::CpuLimitType::SteamDeckOLED),
|
||||||
},
|
},
|
||||||
gpu: super::Limit {
|
gpu: super::Limit {
|
||||||
provider: super::GpuLimitType::SteamDeck,
|
provider: super::GpuLimitType::SteamDeckOLED,
|
||||||
limits: super::GenericGpuLimit::default_for(super::GpuLimitType::SteamDeckOLED),
|
limits: super::GenericGpuLimit::default_for(super::GpuLimitType::SteamDeckOLED),
|
||||||
},
|
},
|
||||||
battery: super::Limit {
|
battery: super::Limit {
|
||||||
provider: super::BatteryLimitType::SteamDeck,
|
provider: super::BatteryLimitType::SteamDeckOLED,
|
||||||
limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::SteamDeck),
|
limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::SteamDeckOLED),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -93,13 +93,14 @@ pub struct GenericCpuLimit {
|
||||||
pub tdp_divisor: Option<u64>,
|
pub tdp_divisor: Option<u64>,
|
||||||
pub tdp_step: Option<u64>,
|
pub tdp_step: Option<u64>,
|
||||||
pub skip_resume_reclock: bool,
|
pub skip_resume_reclock: bool,
|
||||||
pub experiments: bool,
|
pub extras: super::LimitExtras,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GenericCpuLimit {
|
impl GenericCpuLimit {
|
||||||
pub fn default_for(t: &CpuLimitType, _index: usize) -> Self {
|
pub fn default_for(t: &CpuLimitType, _index: usize) -> Self {
|
||||||
match t {
|
match t {
|
||||||
CpuLimitType::SteamDeck | CpuLimitType::SteamDeckOLED => Self::default_steam_deck(),
|
CpuLimitType::SteamDeck => Self::default_steam_deck(),
|
||||||
|
CpuLimitType::SteamDeckOLED => Self::default_steam_deck_oled(),
|
||||||
CpuLimitType::DevMode => Self {
|
CpuLimitType::DevMode => Self {
|
||||||
clock_min: Some(RangeLimit { min: Some(100), max: Some(5000) }),
|
clock_min: Some(RangeLimit { min: Some(100), max: Some(5000) }),
|
||||||
clock_max: Some(RangeLimit { min: Some(100), max: Some(4800) }),
|
clock_max: Some(RangeLimit { min: Some(100), max: Some(4800) }),
|
||||||
|
@ -109,7 +110,7 @@ impl GenericCpuLimit {
|
||||||
tdp_divisor: Some(1_000_000),
|
tdp_divisor: Some(1_000_000),
|
||||||
tdp_step: Some(1),
|
tdp_step: Some(1),
|
||||||
skip_resume_reclock: false,
|
skip_resume_reclock: false,
|
||||||
experiments: true,
|
extras: Default::default(),
|
||||||
},
|
},
|
||||||
_ => Self {
|
_ => Self {
|
||||||
clock_min: None,
|
clock_min: None,
|
||||||
|
@ -120,7 +121,7 @@ impl GenericCpuLimit {
|
||||||
tdp_divisor: None,
|
tdp_divisor: None,
|
||||||
tdp_step: None,
|
tdp_step: None,
|
||||||
skip_resume_reclock: false,
|
skip_resume_reclock: false,
|
||||||
experiments: false,
|
extras: Default::default(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,7 +142,32 @@ impl GenericCpuLimit {
|
||||||
tdp_divisor: None,
|
tdp_divisor: None,
|
||||||
tdp_step: None,
|
tdp_step: None,
|
||||||
skip_resume_reclock: false,
|
skip_resume_reclock: false,
|
||||||
experiments: false,
|
extras: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_steam_deck_oled() -> Self {
|
||||||
|
Self {
|
||||||
|
clock_min: Some(RangeLimit {
|
||||||
|
min: Some(1400),
|
||||||
|
max: Some(3500),
|
||||||
|
}),
|
||||||
|
clock_max: Some(RangeLimit {
|
||||||
|
min: Some(400),
|
||||||
|
max: Some(3500),
|
||||||
|
}),
|
||||||
|
clock_step: Some(100),
|
||||||
|
tdp: None,
|
||||||
|
tdp_boost: None,
|
||||||
|
tdp_divisor: None,
|
||||||
|
tdp_step: None,
|
||||||
|
skip_resume_reclock: false,
|
||||||
|
extras: super::LimitExtras {
|
||||||
|
experiments: false,
|
||||||
|
quirks: vec![
|
||||||
|
"clock-autodetect".to_owned(),
|
||||||
|
].into_iter().collect()
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,6 +191,6 @@ impl GenericCpuLimit {
|
||||||
}
|
}
|
||||||
self.clock_step = limit_override.clock_step;
|
self.clock_step = limit_override.clock_step;
|
||||||
self.skip_resume_reclock = limit_override.skip_resume_reclock;
|
self.skip_resume_reclock = limit_override.skip_resume_reclock;
|
||||||
self.experiments = limit_override.experiments;
|
self.extras = limit_override.extras;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,7 @@ impl GenericGpuLimit {
|
||||||
fn default_steam_deck_oled() -> Self {
|
fn default_steam_deck_oled() -> Self {
|
||||||
let mut sd = Self::default_steam_deck();
|
let mut sd = Self::default_steam_deck();
|
||||||
sd.memory_clock_step = Some(200);
|
sd.memory_clock_step = Some(200);
|
||||||
|
sd.extras.quirks.insert("clock-autodetect".to_owned());
|
||||||
sd
|
sd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -102,6 +102,9 @@ impl Cpus {
|
||||||
|
|
||||||
pub fn variant(mut self, model: super::Model) -> Self {
|
pub fn variant(mut self, model: super::Model) -> Self {
|
||||||
self.variant = model;
|
self.variant = model;
|
||||||
|
for cpu in self.cpus.iter_mut() {
|
||||||
|
cpu.variant(model)
|
||||||
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +128,12 @@ impl ProviderBuilder<Vec<CpuJson>, GenericCpusLimit> for Cpus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let new_cpu = if let Some(cpu_limit) = limits.cpus.get(i) {
|
let new_cpu = if let Some(cpu_limit) = limits.cpus.get(i) {
|
||||||
Cpu::from_json_and_limits(cpu, version, i, cpu_limit.to_owned())
|
let mut cpu_limit_clone = cpu_limit.to_owned();
|
||||||
|
for item in &limits.extras.quirks {
|
||||||
|
cpu_limit_clone.extras.quirks.insert(item.to_owned());
|
||||||
|
}
|
||||||
|
cpu_limit_clone.extras.experiments |= limits.extras.experiments;
|
||||||
|
Cpu::from_json_and_limits(cpu, version, i, cpu_limit_clone)
|
||||||
} else {
|
} else {
|
||||||
Cpu::from_json(cpu, version, i)
|
Cpu::from_json(cpu, version, i)
|
||||||
};
|
};
|
||||||
|
@ -262,6 +270,7 @@ pub struct Cpu {
|
||||||
index: usize,
|
index: usize,
|
||||||
state: crate::state::steam_deck::Cpu,
|
state: crate::state::steam_deck::Cpu,
|
||||||
sysfs: BasicEntityPath,
|
sysfs: BasicEntityPath,
|
||||||
|
variant: super::Model,
|
||||||
}
|
}
|
||||||
|
|
||||||
//const CPU_CLOCK_LIMITS_PATH: &str = "/sys/class/drm/card0/device/pp_od_clk_voltage";
|
//const CPU_CLOCK_LIMITS_PATH: &str = "/sys/class/drm/card0/device/pp_od_clk_voltage";
|
||||||
|
@ -289,6 +298,7 @@ impl Cpu {
|
||||||
index: i,
|
index: i,
|
||||||
state: crate::state::steam_deck::Cpu::default(),
|
state: crate::state::steam_deck::Cpu::default(),
|
||||||
sysfs: Self::find_card_sysfs(other.root),
|
sysfs: Self::find_card_sysfs(other.root),
|
||||||
|
variant: super::Model::LCD,
|
||||||
},
|
},
|
||||||
_ => Self {
|
_ => Self {
|
||||||
online: other.online,
|
online: other.online,
|
||||||
|
@ -298,6 +308,7 @@ impl Cpu {
|
||||||
index: i,
|
index: i,
|
||||||
state: crate::state::steam_deck::Cpu::default(),
|
state: crate::state::steam_deck::Cpu::default(),
|
||||||
sysfs: Self::find_card_sysfs(other.root),
|
sysfs: Self::find_card_sysfs(other.root),
|
||||||
|
variant: super::Model::LCD,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -341,6 +352,19 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_max_cpu_clock(&self) -> u64 {
|
||||||
|
if !(self.limits.extras.experiments || self.limits.extras.quirks.contains("clock-autodetect")) {
|
||||||
|
return MAX_CLOCK;
|
||||||
|
}
|
||||||
|
if let super::Model::OLED = self.variant {
|
||||||
|
if let Ok(freq_khz) = usdpl_back::api::files::read_single::<_, u64, _>(cpu_max_clock_path(self.index)) {
|
||||||
|
log::debug!("Detected CPU max clock of {}KHz", freq_khz);
|
||||||
|
return freq_khz / 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MAX_CLOCK
|
||||||
|
}
|
||||||
|
|
||||||
fn set_clock_limit(
|
fn set_clock_limit(
|
||||||
&self,
|
&self,
|
||||||
index: usize,
|
index: usize,
|
||||||
|
@ -591,6 +615,7 @@ impl Cpu {
|
||||||
index: cpu_index,
|
index: cpu_index,
|
||||||
state: crate::state::steam_deck::Cpu::default(),
|
state: crate::state::steam_deck::Cpu::default(),
|
||||||
sysfs: Self::find_card_sysfs(None::<&'static str>),
|
sysfs: Self::find_card_sysfs(None::<&'static str>),
|
||||||
|
variant: super::Model::LCD,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,14 +627,15 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn limits(&self) -> crate::api::CpuLimits {
|
fn limits(&self) -> crate::api::CpuLimits {
|
||||||
|
let max_cpu_clock = self.read_max_cpu_clock();
|
||||||
crate::api::CpuLimits {
|
crate::api::CpuLimits {
|
||||||
clock_min_limits: Some(RangeLimit {
|
clock_min_limits: Some(RangeLimit {
|
||||||
min: range_min_or_fallback(&self.limits.clock_max, MIN_MAX_CLOCK), // allows min to be set by max (it's weird, blame the kernel)
|
min: range_min_or_fallback(&self.limits.clock_max, MIN_MAX_CLOCK), // allows min to be set by max (it's weird, blame the kernel)
|
||||||
max: range_max_or_fallback(&self.limits.clock_min, MAX_CLOCK),
|
max: range_max_or_fallback(&self.limits.clock_min, max_cpu_clock),
|
||||||
}),
|
}),
|
||||||
clock_max_limits: Some(RangeLimit {
|
clock_max_limits: Some(RangeLimit {
|
||||||
min: range_min_or_fallback(&self.limits.clock_max, MIN_MAX_CLOCK),
|
min: range_min_or_fallback(&self.limits.clock_max, MIN_MAX_CLOCK),
|
||||||
max: range_max_or_fallback(&self.limits.clock_max, MAX_CLOCK),
|
max: range_max_or_fallback(&self.limits.clock_max, max_cpu_clock),
|
||||||
}),
|
}),
|
||||||
clock_step: self.limits.clock_step.unwrap_or(CLOCK_STEP),
|
clock_step: self.limits.clock_step.unwrap_or(CLOCK_STEP),
|
||||||
governors: self.governors(),
|
governors: self.governors(),
|
||||||
|
@ -628,6 +654,10 @@ impl Cpu {
|
||||||
};
|
};
|
||||||
gov_str.split(' ').map(|s| s.to_owned()).collect()
|
gov_str.split(' ').map(|s| s.to_owned()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn variant(&mut self, model: super::Model) {
|
||||||
|
self.variant = model;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<CpuJson> for Cpu {
|
impl Into<CpuJson> for Cpu {
|
||||||
|
@ -714,3 +744,8 @@ fn cpu_available_governors_path(index: usize) -> String {
|
||||||
index
|
index
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn cpu_max_clock_path(index: usize) -> String {
|
||||||
|
format!("/sys/devices/system/cpu/cpufreq/policy{}/cpuinfo_max_freq", index)
|
||||||
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ pub struct Gpu {
|
||||||
|
|
||||||
const GPU_CLOCK_LIMITS_ATTRIBUTE: &str = "device/pp_od_clk_voltage";
|
const GPU_CLOCK_LIMITS_ATTRIBUTE: &str = "device/pp_od_clk_voltage";
|
||||||
const GPU_MEMORY_DOWNCLOCK_ATTRIBUTE: &str = "device/pp_dpm_fclk";
|
const GPU_MEMORY_DOWNCLOCK_ATTRIBUTE: &str = "device/pp_dpm_fclk";
|
||||||
|
const GPU_CLOCK_READOUT_ATTRIBUTE: &str = "device/pp_dpm_sclk";
|
||||||
|
|
||||||
const CARD_EXTENSIONS: &[&'static str] = &[
|
const CARD_EXTENSIONS: &[&'static str] = &[
|
||||||
GPU_CLOCK_LIMITS_ATTRIBUTE,
|
GPU_CLOCK_LIMITS_ATTRIBUTE,
|
||||||
|
@ -141,6 +142,29 @@ impl Gpu {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_max_gpu_clock(&self) -> u64 {
|
||||||
|
if !(self.limits.extras.experiments || self.limits.extras.quirks.contains("clock-autodetect")) {
|
||||||
|
return MAX_CLOCK;
|
||||||
|
}
|
||||||
|
if let super::Model::OLED = self.variant {
|
||||||
|
if let Ok(f) = self
|
||||||
|
.sysfs_card
|
||||||
|
.read_value(GPU_CLOCK_READOUT_ATTRIBUTE.to_owned())
|
||||||
|
{
|
||||||
|
let options = parse_pp_dpm_sclk(&String::from_utf8_lossy(&f));
|
||||||
|
return options.get(options.len() - 1)
|
||||||
|
.map(|x| {
|
||||||
|
let x = x.1 as u64;
|
||||||
|
log::debug!("Detected GPU max clock of {}MHz", x);
|
||||||
|
x
|
||||||
|
|
||||||
|
})
|
||||||
|
.unwrap_or(MAX_CLOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MAX_CLOCK
|
||||||
|
}
|
||||||
|
|
||||||
fn is_memory_clock_maxed(&self) -> bool {
|
fn is_memory_clock_maxed(&self) -> bool {
|
||||||
if let Some(clock) = &self.memory_clock {
|
if let Some(clock) = &self.memory_clock {
|
||||||
if let Some(limit) = &self.limits.memory_clock {
|
if let Some(limit) = &self.limits.memory_clock {
|
||||||
|
@ -611,6 +635,7 @@ impl crate::settings::OnUnload for Gpu {
|
||||||
|
|
||||||
impl TGpu for Gpu {
|
impl TGpu for Gpu {
|
||||||
fn limits(&self) -> crate::api::GpuLimits {
|
fn limits(&self) -> crate::api::GpuLimits {
|
||||||
|
let max_gpu_clock = self.read_max_gpu_clock();
|
||||||
crate::api::GpuLimits {
|
crate::api::GpuLimits {
|
||||||
fast_ppt_limits: Some(RangeLimit {
|
fast_ppt_limits: Some(RangeLimit {
|
||||||
min: super::util::range_min_or_fallback(&self.limits.fast_ppt, MIN_FAST_PPT)
|
min: super::util::range_min_or_fallback(&self.limits.fast_ppt, MIN_FAST_PPT)
|
||||||
|
@ -630,11 +655,11 @@ impl TGpu for Gpu {
|
||||||
tdp_step: 42,
|
tdp_step: 42,
|
||||||
clock_min_limits: Some(RangeLimit {
|
clock_min_limits: Some(RangeLimit {
|
||||||
min: super::util::range_min_or_fallback(&self.limits.clock_min, MIN_CLOCK),
|
min: super::util::range_min_or_fallback(&self.limits.clock_min, MIN_CLOCK),
|
||||||
max: super::util::range_max_or_fallback(&self.limits.clock_min, MAX_CLOCK),
|
max: super::util::range_max_or_fallback(&self.limits.clock_min, max_gpu_clock),
|
||||||
}),
|
}),
|
||||||
clock_max_limits: Some(RangeLimit {
|
clock_max_limits: Some(RangeLimit {
|
||||||
min: super::util::range_min_or_fallback(&self.limits.clock_max, MIN_CLOCK),
|
min: super::util::range_min_or_fallback(&self.limits.clock_max, MIN_CLOCK),
|
||||||
max: super::util::range_max_or_fallback(&self.limits.clock_max, MAX_CLOCK),
|
max: super::util::range_max_or_fallback(&self.limits.clock_max, max_gpu_clock),
|
||||||
}),
|
}),
|
||||||
clock_step: self.limits.clock_step.unwrap_or(100),
|
clock_step: self.limits.clock_step.unwrap_or(100),
|
||||||
memory_control: Some(RangeLimit {
|
memory_control: Some(RangeLimit {
|
||||||
|
@ -693,7 +718,7 @@ impl TGpu for Gpu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_pp_dpm_fclk(s: &str) -> Vec<(usize, usize)> {
|
fn parse_sysfs_clk_selector_str(s: &str) -> Vec<(usize, usize)> {
|
||||||
// (value, MHz)
|
// (value, MHz)
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
for line in s.split('\n') {
|
for line in s.split('\n') {
|
||||||
|
@ -715,3 +740,13 @@ fn parse_pp_dpm_fclk(s: &str) -> Vec<(usize, usize)> {
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn parse_pp_dpm_fclk(s: &str) -> Vec<(usize, usize)> {
|
||||||
|
parse_sysfs_clk_selector_str(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn parse_pp_dpm_sclk(s: &str) -> Vec<(usize, usize)> {
|
||||||
|
parse_sysfs_clk_selector_str(s)
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "PowerTools",
|
"name": "PowerTools",
|
||||||
"version": "2.0.0-alpha2",
|
"version": "2.0.0-alpha3",
|
||||||
"description": "Power tweaks for power users",
|
"description": "Power tweaks for power users",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "shx rm -rf dist && rollup -c",
|
"build": "shx rm -rf dist && rollup -c",
|
||||||
|
|
Loading…
Reference in a new issue