Refactor steam_deck to modularize system interactions

This commit is contained in:
NGnius (Graham) 2023-05-25 21:03:13 -04:00
parent 23d6e49491
commit f8ea999604
21 changed files with 329 additions and 280 deletions

2
backend/Cargo.lock generated
View file

@ -799,7 +799,7 @@ dependencies = [
[[package]] [[package]]
name = "limits_core" name = "limits_core"
version = "1.0.0" version = "2.0.0"
dependencies = [ dependencies = [
"serde", "serde",
"serde_json", "serde_json",

View file

@ -25,7 +25,7 @@ log = "0.4"
simplelog = "0.12" simplelog = "0.12"
# limits & driver functionality # limits & driver functionality
limits_core = { version = "1.0.0", path = "./limits_core" } limits_core = { version = "2", path = "./limits_core" }
regex = "1" regex = "1"
libryzenadj = { version = "0.12" } libryzenadj = { version = "0.12" }
# ureq's tls feature does not like musl targets # ureq's tls feature does not like musl targets

View file

@ -10,7 +10,7 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]] [[package]]
name = "limits_core" name = "limits_core"
version = "1.0.0" version = "2.0.0"
dependencies = [ dependencies = [
"serde", "serde",
"serde_json", "serde_json",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "limits_core" name = "limits_core"
version = "1.0.0" version = "2.0.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -57,16 +57,16 @@ impl Default for Base {
}, },
limits: vec![ limits: vec![
super::Limits::Cpu(super::CpuLimit::GenericAMD(super::GenericCpuLimit { super::Limits::Cpu(super::CpuLimit::GenericAMD(super::GenericCpuLimit {
clock_min: Some(super::RangeLimit { min: 1000, max: 3700 }), clock_min: Some(super::RangeLimit { min: Some(1000), max: Some(3700) }),
clock_max: Some(super::RangeLimit { min: 1000, max: 3700 }), clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(3700) }),
clock_step: 100, clock_step: 100,
})), })),
super::Limits::Gpu(super::GpuLimit::GenericAMD(super::GenericGpuLimit { super::Limits::Gpu(super::GpuLimit::GenericAMD(super::GenericGpuLimit {
fast_ppt: Some(super::RangeLimit { min: 1_000_000, max: 25_000_000 }), fast_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(25_000_000) }),
slow_ppt: Some(super::RangeLimit { min: 1_000_000, max: 25_000_000 }), slow_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(25_000_000) }),
ppt_step: Some(1_000_000), ppt_step: Some(1_000_000),
clock_min: Some(super::RangeLimit { min: 400, max: 1100 }), clock_min: Some(super::RangeLimit { min: Some(400), max: Some(1100) }),
clock_max: Some(super::RangeLimit { min: 400, max: 1100 }), clock_max: Some(super::RangeLimit { min: Some(400), max: Some(1100) }),
clock_step: Some(100), clock_step: Some(100),
..Default::default() ..Default::default()
})), })),
@ -84,16 +84,16 @@ impl Default for Base {
}, },
limits: vec![ limits: vec![
super::Limits::Cpu(super::CpuLimit::GenericAMD(super::GenericCpuLimit { super::Limits::Cpu(super::CpuLimit::GenericAMD(super::GenericCpuLimit {
clock_min: Some(super::RangeLimit { min: 1000, max: 4000 }), clock_min: Some(super::RangeLimit { min: Some(1000), max: Some(4000) }),
clock_max: Some(super::RangeLimit { min: 1000, max: 4000 }), clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(4000) }),
clock_step: 100, clock_step: 100,
})), })),
super::Limits::Gpu(super::GpuLimit::GenericAMD(super::GenericGpuLimit { super::Limits::Gpu(super::GpuLimit::GenericAMD(super::GenericGpuLimit {
fast_ppt: Some(super::RangeLimit { min: 1_000_000, max: 25_000_000 }), fast_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(25_000_000) }),
slow_ppt: Some(super::RangeLimit { min: 1_000_000, max: 25_000_000 }), slow_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(25_000_000) }),
ppt_step: Some(1_000_000), ppt_step: Some(1_000_000),
clock_min: Some(super::RangeLimit { min: 400, max: 1600 }), clock_min: Some(super::RangeLimit { min: Some(400), max: Some(1600) }),
clock_max: Some(super::RangeLimit { min: 400, max: 1600 }), clock_max: Some(super::RangeLimit { min: Some(400), max: Some(1600) }),
clock_step: Some(100), clock_step: Some(100),
..Default::default() ..Default::default()
})), })),
@ -111,16 +111,16 @@ impl Default for Base {
}, },
limits: vec![ limits: vec![
super::Limits::Cpu(super::CpuLimit::GenericAMD(super::GenericCpuLimit { super::Limits::Cpu(super::CpuLimit::GenericAMD(super::GenericCpuLimit {
clock_min: Some(super::RangeLimit { min: 1000, max: 4500 }), clock_min: Some(super::RangeLimit { min: Some(1000), max: Some(4500) }),
clock_max: Some(super::RangeLimit { min: 1000, max: 4500 }), clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(4500) }),
clock_step: 100, clock_step: 100,
})), })),
super::Limits::Gpu(super::GpuLimit::GenericAMD(super::GenericGpuLimit { super::Limits::Gpu(super::GpuLimit::GenericAMD(super::GenericGpuLimit {
fast_ppt: Some(super::RangeLimit { min: 1_000_000, max: 25_000_000 }), fast_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(25_000_000) }),
slow_ppt: Some(super::RangeLimit { min: 1_000_000, max: 25_000_000 }), slow_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(25_000_000) }),
ppt_step: Some(1_000_000), ppt_step: Some(1_000_000),
clock_min: Some(super::RangeLimit { min: 400, max: 2000 }), clock_min: Some(super::RangeLimit { min: Some(400), max: Some(2000) }),
clock_max: Some(super::RangeLimit { min: 400, max: 2000 }), clock_max: Some(super::RangeLimit { min: Some(400), max: Some(2000) }),
clock_step: Some(100), clock_step: Some(100),
..Default::default() ..Default::default()
})), })),
@ -138,16 +138,16 @@ impl Default for Base {
}, },
limits: vec![ limits: vec![
super::Limits::Cpu(super::CpuLimit::Generic(super::GenericCpuLimit { super::Limits::Cpu(super::CpuLimit::Generic(super::GenericCpuLimit {
clock_min: Some(super::RangeLimit { min: 1000, max: 4700 }), clock_min: Some(super::RangeLimit { min: Some(1000), max: Some(4700) }),
clock_max: Some(super::RangeLimit { min: 1000, max: 4700 }), clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(4700) }),
clock_step: 100, clock_step: 100,
})), })),
super::Limits::Gpu(super::GpuLimit::Generic(super::GenericGpuLimit { super::Limits::Gpu(super::GpuLimit::Generic(super::GenericGpuLimit {
fast_ppt: Some(super::RangeLimit { min: 1_000_000, max: 28_000_000 }), fast_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(28_000_000) }),
slow_ppt: Some(super::RangeLimit { min: 1_000_000, max: 28_000_000 }), slow_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(28_000_000) }),
ppt_step: Some(1_000_000), ppt_step: Some(1_000_000),
clock_min: Some(super::RangeLimit { min: 400, max: 2200 }), clock_min: Some(super::RangeLimit { min: Some(400), max: Some(2200) }),
clock_max: Some(super::RangeLimit { min: 400, max: 2200 }), clock_max: Some(super::RangeLimit { min: Some(400), max: Some(2200) }),
clock_step: Some(100), clock_step: Some(100),
..Default::default() ..Default::default()
})), })),

View file

@ -3,6 +3,6 @@ use serde::{Deserialize, Serialize};
/// Base JSON limits information /// Base JSON limits information
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RangeLimit<T> { pub struct RangeLimit<T> {
pub min: T, pub min: Option<T>,
pub max: T, pub max: Option<T>,
} }

View file

@ -1,12 +1,12 @@
[package] [package]
name = "limits_srv" name = "limits_srv"
version = "1.0.0" version = "2.0.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
limits_core = { version = "1.0.0", path = "../limits_core" } limits_core = { version = "2.0.0", path = "../limits_core" }
chrono = { version = "0.4" } chrono = { version = "0.4" }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"

View file

@ -1,18 +1,14 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct RangeLimit<T> { pub struct RangeLimit<T> {
pub min: T, pub min: T,
pub max: T, pub max: T,
} }
impl<T> From<limits_core::json::RangeLimit<T>> for RangeLimit<T> { impl<T> RangeLimit<T> {
#[inline] pub fn new(min: T, max: T) -> Self {
fn from(other: limits_core::json::RangeLimit<T>) -> Self { Self { min, max }
RangeLimit {
min: other.min,
max: other.max,
}
} }
} }

View file

@ -6,6 +6,7 @@ use usdpl_back::AsyncCallable;
use crate::settings::{MinMax, SettingError, SettingVariant}; use crate::settings::{MinMax, SettingError, SettingVariant};
//use crate::utility::{unwrap_lock, unwrap_maybe_fatal}; //use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
use super::handler::{ApiMessage, CpuMessage}; use super::handler::{ApiMessage, CpuMessage};
use super::utility::map_optional;
/// Available CPUs web method /// Available CPUs web method
pub fn max_cpus(_: super::ApiParameterType) -> super::ApiParameterType { pub fn max_cpus(_: super::ApiParameterType) -> super::ApiParameterType {
@ -205,8 +206,8 @@ pub fn set_clock_limits(
setter( setter(
index as usize, index as usize,
MinMax { MinMax {
min: safe_min as u64, min: Some(safe_min as u64),
max: safe_max as u64, max: Some(safe_max as u64),
}, },
); );
vec![safe_min.into(), safe_max.into()] vec![safe_min.into(), safe_max.into()]
@ -220,6 +221,7 @@ pub fn set_clock_limits(
vec!["set_clock_limits missing parameter 0".into()] vec!["set_clock_limits missing parameter 0".into()]
} }
} }
// TODO allow param 0 and/or 1 to be Primitive::Empty
} }
pub fn get_clock_limits( pub fn get_clock_limits(
@ -245,7 +247,7 @@ pub fn get_clock_limits(
move |params_in: super::ApiParameterType| { move |params_in: super::ApiParameterType| {
if let Some(&Primitive::F64(index)) = params_in.get(0) { if let Some(&Primitive::F64(index)) = params_in.get(0) {
if let Some(min_max) = getter(index as usize) { if let Some(min_max) = getter(index as usize) {
vec![min_max.min.into(), min_max.max.into()] vec![map_optional(min_max.min), map_optional(min_max.max)]
} else { } else {
vec![Primitive::Empty, Primitive::Empty] vec![Primitive::Empty, Primitive::Empty]
} }

View file

@ -3,6 +3,7 @@ use std::sync::{Arc, Mutex};
use usdpl_back::core::serdes::Primitive; use usdpl_back::core::serdes::Primitive;
use usdpl_back::AsyncCallable; use usdpl_back::AsyncCallable;
use super::utility::map_optional;
use crate::settings::MinMax; use crate::settings::MinMax;
//use crate::utility::{unwrap_lock, unwrap_maybe_fatal}; //use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
use super::handler::{ApiMessage, GpuMessage}; use super::handler::{ApiMessage, GpuMessage};
@ -94,8 +95,8 @@ pub fn set_clock_limits(
let safe_max = if max < min { min } else { max }; let safe_max = if max < min { min } else { max };
let safe_min = if min > max { max } else { min }; let safe_min = if min > max { max } else { min };
setter(MinMax { setter(MinMax {
min: safe_min as _, min: Some(safe_min as _),
max: safe_max as _, max: Some(safe_max as _),
}); });
vec![(safe_min as u64).into(), (safe_max as u64).into()] vec![(safe_min as u64).into(), (safe_max as u64).into()]
} else { } else {
@ -105,6 +106,7 @@ pub fn set_clock_limits(
vec!["set_clock_limits missing parameter 0".into()] vec!["set_clock_limits missing parameter 0".into()]
} }
} }
// TODO allow param 0 and/or 1 to be Primitive::Empty
} }
pub fn get_clock_limits(sender: Sender<ApiMessage>) -> impl AsyncCallable { pub fn get_clock_limits(sender: Sender<ApiMessage>) -> impl AsyncCallable {
@ -131,7 +133,7 @@ pub fn get_clock_limits(sender: Sender<ApiMessage>) -> impl AsyncCallable {
set_get: getter, set_get: getter,
trans_getter: |clocks: Option<MinMax<u64>>| { trans_getter: |clocks: Option<MinMax<u64>>| {
clocks clocks
.map(|x| vec![x.min.into(), x.max.into()]) .map(|x| vec![map_optional(x.min), map_optional(x.max)])
.unwrap_or_else(|| vec![Primitive::Empty, Primitive::Empty]) .unwrap_or_else(|| vec![Primitive::Empty, Primitive::Empty])
}, },
} }

View file

@ -268,7 +268,9 @@ impl ApiMessageHandler {
while let Ok(msg) = self.intake.try_recv() { while let Ok(msg) = self.intake.try_recv() {
dirty |= self.process(settings, msg); dirty |= self.process(settings, msg);
} }
if dirty /*|| dirty_echo */ { if dirty
/*|| dirty_echo */
{
//dirty_echo = dirty; // echo only once //dirty_echo = dirty; // echo only once
// run on_set // run on_set

View file

@ -19,10 +19,7 @@ pub fn map_optional_result<T: Into<Primitive>>(
result: Result<Option<T>, SettingError>, result: Result<Option<T>, SettingError>,
) -> super::ApiParameterType { ) -> super::ApiParameterType {
match result { match result {
Ok(val) => match val { Ok(val) => vec![map_optional(val)],
Some(val) => vec![val.into()],
None => vec![Primitive::Empty],
},
Err(e) => { Err(e) => {
log::debug!("Mapping error to primitive: {}", e); log::debug!("Mapping error to primitive: {}", e);
vec![e.msg.into()] vec![e.msg.into()]
@ -30,6 +27,13 @@ pub fn map_optional_result<T: Into<Primitive>>(
} }
} }
pub fn map_optional<T: Into<Primitive>>(option: Option<T>) -> Primitive {
match option {
Some(val) => val.into(),
None => Primitive::Empty,
}
}
/*#[inline] /*#[inline]
pub fn map_empty_result<T: Into<Primitive>>( pub fn map_empty_result<T: Into<Primitive>>(
result: Result<(), SettingError>, result: Result<(), SettingError>,

View file

@ -58,6 +58,6 @@ impl SettingsJson {
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
pub struct MinMaxJson<T> { pub struct MinMaxJson<T> {
pub max: T, pub max: Option<T>,
pub min: T, pub min: Option<T>,
} }

View file

@ -3,6 +3,7 @@ use std::convert::{AsMut, AsRef, Into};
use limits_core::json::GenericCpuLimit; use limits_core::json::GenericCpuLimit;
use super::FromGenericCpuInfo; use super::FromGenericCpuInfo;
use crate::api::RangeLimit;
use crate::persist::CpuJson; use crate::persist::CpuJson;
use crate::settings::{min_max_from_json, MinMax}; use crate::settings::{min_max_from_json, MinMax};
use crate::settings::{OnResume, OnSet, SettingError}; use crate::settings::{OnResume, OnSet, SettingError};
@ -330,8 +331,16 @@ impl Cpu {
fn limits(&self) -> crate::api::CpuLimits { fn limits(&self) -> crate::api::CpuLimits {
crate::api::CpuLimits { crate::api::CpuLimits {
clock_min_limits: self.limits.clock_min.clone().map(|x| x.into()), clock_min_limits: self
clock_max_limits: self.limits.clock_max.clone().map(|x| x.into()), .limits
.clock_min
.clone()
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(5_000))),
clock_max_limits: self
.limits
.clock_max
.clone()
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(5_000))),
clock_step: self.limits.clock_step, clock_step: self.limits.clock_step,
governors: self.governors(), governors: self.governors(),
} }

View file

@ -2,6 +2,7 @@ use std::convert::Into;
use limits_core::json::GenericGpuLimit; use limits_core::json::GenericGpuLimit;
use crate::api::RangeLimit;
use crate::persist::GpuJson; use crate::persist::GpuJson;
use crate::settings::TGpu; use crate::settings::TGpu;
use crate::settings::{min_max_from_json, MinMax}; use crate::settings::{min_max_from_json, MinMax};
@ -97,14 +98,38 @@ impl crate::settings::OnPowerEvent for Gpu {}
impl TGpu for Gpu { impl TGpu for Gpu {
fn limits(&self) -> crate::api::GpuLimits { fn limits(&self) -> crate::api::GpuLimits {
crate::api::GpuLimits { crate::api::GpuLimits {
fast_ppt_limits: self.limits.fast_ppt.clone().map(|x| x.into()), fast_ppt_limits: self
slow_ppt_limits: self.limits.slow_ppt.clone().map(|x| x.into()), .limits
.fast_ppt
.clone()
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(15_000_000))),
slow_ppt_limits: self
.limits
.slow_ppt
.clone()
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(15_000_000))),
ppt_step: self.limits.ppt_step.unwrap_or(1_000_000), ppt_step: self.limits.ppt_step.unwrap_or(1_000_000),
tdp_limits: self.limits.tdp.clone().map(|x| x.into()), tdp_limits: self
tdp_boost_limits: self.limits.tdp_boost.clone().map(|x| x.into()), .limits
.tdp
.clone()
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(15_000_000))),
tdp_boost_limits: self
.limits
.tdp_boost
.clone()
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(15_000_000))),
tdp_step: self.limits.tdp_step.unwrap_or(42), tdp_step: self.limits.tdp_step.unwrap_or(42),
clock_min_limits: self.limits.clock_min.clone().map(|x| x.into()), clock_min_limits: self
clock_max_limits: self.limits.clock_max.clone().map(|x| x.into()), .limits
.clock_min
.clone()
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(3_000))),
clock_max_limits: self
.limits
.clock_max
.clone()
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(3_000))),
clock_step: self.limits.clock_step.unwrap_or(100), clock_step: self.limits.clock_step.unwrap_or(100),
memory_control_capable: false, memory_control_capable: false,
} }
@ -116,10 +141,20 @@ impl TGpu for Gpu {
fn ppt(&mut self, fast: Option<u64>, slow: Option<u64>) { fn ppt(&mut self, fast: Option<u64>, slow: Option<u64>) {
if let Some(fast_lims) = &self.limits.fast_ppt { if let Some(fast_lims) = &self.limits.fast_ppt {
self.fast_ppt = fast.map(|x| x.clamp(fast_lims.min, fast_lims.max)); self.fast_ppt = fast.map(|x| {
x.clamp(
fast_lims.min.unwrap_or(0),
fast_lims.max.unwrap_or(u64::MAX),
)
});
} }
if let Some(slow_lims) = &self.limits.slow_ppt { if let Some(slow_lims) = &self.limits.slow_ppt {
self.slow_ppt = slow.map(|x| x.clamp(slow_lims.min, slow_lims.max)); self.slow_ppt = slow.map(|x| {
x.clamp(
slow_lims.min.unwrap_or(0),
slow_lims.max.unwrap_or(u64::MAX),
)
});
} }
} }

View file

@ -128,24 +128,22 @@ impl Gpu {
} }
if let Some(clock_limits) = &self.generic.clock_limits { if let Some(clock_limits) = &self.generic.clock_limits {
self.state.clock_limits_set = true; self.state.clock_limits_set = true;
lock.set_max_gfxclk_freq(clock_limits.max as _) if let Some(max) = clock_limits.max {
.map_err(|e| SettingError { lock.set_max_gfxclk_freq(max as _)
msg: format!( .map_err(|e| SettingError {
"RyzenAdj set_max_gfxclk_freq({}) err: {}", msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", max, e),
clock_limits.max, e setting: SettingVariant::Gpu,
), })
setting: SettingVariant::Gpu, .unwrap_or_else(|e| errors.push(e));
}) }
.unwrap_or_else(|e| errors.push(e)); if let Some(min) = clock_limits.min {
lock.set_min_gfxclk_freq(clock_limits.min as _) lock.set_min_gfxclk_freq(min as _)
.map_err(|e| SettingError { .map_err(|e| SettingError {
msg: format!( msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", min, e),
"RyzenAdj set_min_gfxclk_freq({}) err: {}", setting: SettingVariant::Gpu,
clock_limits.min, e })
), .unwrap_or_else(|e| errors.push(e));
setting: SettingVariant::Gpu, }
})
.unwrap_or_else(|e| errors.push(e));
} else if self.state.clock_limits_set { } else if self.state.clock_limits_set {
self.state.clock_limits_set = false; self.state.clock_limits_set = false;
let limits = self.generic.limits(); let limits = self.generic.limits();
@ -218,24 +216,22 @@ impl Gpu {
.unwrap_or_else(|e| errors.push(e)); .unwrap_or_else(|e| errors.push(e));
} }
if let Some(clock_limits) = &self.generic.clock_limits { if let Some(clock_limits) = &self.generic.clock_limits {
lock.set_max_gfxclk_freq(clock_limits.max as _) if let Some(max) = clock_limits.max {
.map_err(|e| SettingError { lock.set_max_gfxclk_freq(max as _)
msg: format!( .map_err(|e| SettingError {
"RyzenAdj set_max_gfxclk_freq({}) err: {}", msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", max, e),
clock_limits.max, e setting: SettingVariant::Gpu,
), })
setting: SettingVariant::Gpu, .unwrap_or_else(|e| errors.push(e));
}) }
.unwrap_or_else(|e| errors.push(e)); if let Some(min) = clock_limits.min {
lock.set_min_gfxclk_freq(clock_limits.min as _) lock.set_min_gfxclk_freq(min as _)
.map_err(|e| SettingError { .map_err(|e| SettingError {
msg: format!( msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", min, e),
"RyzenAdj set_min_gfxclk_freq({}) err: {}", setting: SettingVariant::Gpu,
clock_limits.min, e })
), .unwrap_or_else(|e| errors.push(e));
setting: SettingVariant::Gpu, }
})
.unwrap_or_else(|e| errors.push(e));
} }
Ok(()) Ok(())
} }

View file

@ -8,8 +8,8 @@ pub type MinMax<T> = RangeLimit<T>;
pub fn min_max_from_json<T, X: Into<T>>(other: MinMaxJson<X>, _version: u64) -> MinMax<T> { pub fn min_max_from_json<T, X: Into<T>>(other: MinMaxJson<X>, _version: u64) -> MinMax<T> {
MinMax { MinMax {
max: other.max.into(), max: other.max.map(|x| x.into()),
min: other.min.into(), min: other.min.map(|x| x.into()),
} }
} }
@ -17,8 +17,8 @@ impl<X: Into<Y>, Y> Into<MinMaxJson<Y>> for RangeLimit<X> {
#[inline] #[inline]
fn into(self) -> MinMaxJson<Y> { fn into(self) -> MinMaxJson<Y> {
MinMaxJson { MinMaxJson {
max: self.max.into(), max: self.max.map(|x| x.into()),
min: self.min.into(), min: self.min.map(|x| x.into()),
} }
} }
} }

View file

@ -99,12 +99,12 @@ impl EventInstruction {
.trim_start_matches('>') .trim_start_matches('>')
.parse::<f64>() .parse::<f64>()
.ok() .ok()
.map(|x| EventTrigger::BatteryAbove(x/100.0)), .map(|x| EventTrigger::BatteryAbove(x / 100.0)),
s if s.starts_with('<') => s s if s.starts_with('<') => s
.trim_start_matches('<') .trim_start_matches('<')
.parse::<f64>() .parse::<f64>()
.ok() .ok()
.map(|x| EventTrigger::BatteryBelow(x/100.0)), .map(|x| EventTrigger::BatteryBelow(x / 100.0)),
_ => None, _ => None,
} }
} }
@ -244,6 +244,30 @@ impl Battery {
} }
} }
fn set_charge_rate(&mut self) -> Result<(), SettingError> {
if let Some(charge_rate) = self.charge_rate {
self.state.charge_rate_set = true;
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate).map_err(
|e| SettingError {
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
setting: crate::settings::SettingVariant::Battery,
},
)
} else if self.state.charge_rate_set {
self.state.charge_rate_set = false;
usdpl_back::api::files::write_single(
BATTERY_CHARGE_RATE_PATH,
self.limits.charge_rate.max,
)
.map_err(|e| SettingError {
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
setting: crate::settings::SettingVariant::Battery,
})
} else {
Ok(())
}
}
fn set_charge_mode(&mut self) -> Result<(), SettingError> { fn set_charge_mode(&mut self) -> Result<(), SettingError> {
if let Some(charge_mode) = self.charge_mode { if let Some(charge_mode) = self.charge_mode {
self.state.charge_mode_set = true; self.state.charge_mode_set = true;
@ -268,26 +292,7 @@ impl Battery {
fn set_all(&mut self) -> Result<(), Vec<SettingError>> { fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new(); let mut errors = Vec::new();
if let Some(charge_rate) = self.charge_rate { self.set_charge_rate().unwrap_or_else(|e| errors.push(e));
self.state.charge_rate_set = true;
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate)
.map_err(|e| SettingError {
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
setting: crate::settings::SettingVariant::Battery,
})
.unwrap_or_else(|e| errors.push(e));
} else if self.state.charge_rate_set {
self.state.charge_rate_set = false;
usdpl_back::api::files::write_single(
BATTERY_CHARGE_RATE_PATH,
self.limits.charge_rate.max,
)
.map_err(|e| SettingError {
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
setting: crate::settings::SettingVariant::Battery,
})
.unwrap_or_else(|e| errors.push(e));
}
self.set_charge_mode().unwrap_or_else(|e| errors.push(e)); self.set_charge_mode().unwrap_or_else(|e| errors.push(e));
if errors.is_empty() { if errors.is_empty() {
Ok(()) Ok(())

View file

@ -234,6 +234,11 @@ pub struct Cpu {
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";
enum ClockType {
Min = 0,
Max = 1,
}
impl Cpu { impl Cpu {
#[inline] #[inline]
fn from_json(other: CpuJson, version: u64, i: usize, oc_limits: CpuLimits) -> Self { fn from_json(other: CpuJson, version: u64, i: usize, oc_limits: CpuLimits) -> Self {
@ -257,86 +262,91 @@ impl Cpu {
} }
} }
fn set_force_performance_related(&mut self) -> Result<(), Vec<SettingError>> { fn set_clock_limit(index: usize, speed: u64, mode: ClockType) -> Result<(), SettingError> {
let mut errors = Vec::new(); let payload = format!("p {} {} {}\n", index / 2, mode as u8, speed);
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload).map_err(|e| {
SettingError {
msg: format!(
"Failed to write `{}` to `{}`: {}",
&payload, CPU_CLOCK_LIMITS_PATH, e
),
setting: crate::settings::SettingVariant::Cpu,
}
})
}
// set clock limits fn set_clock_limits(&mut self) -> Result<(), Vec<SettingError>> {
//log::debug!("Setting {} to manual", CPU_FORCE_LIMITS_PATH); let mut errors = Vec::new();
//let mode: String = usdpl_back::api::files::read_single(CPU_FORCE_LIMITS_PATH.to_owned()).unwrap();
if let Some(clock_limits) = &self.clock_limits { if let Some(clock_limits) = &self.clock_limits {
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(true, self.index); POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(true, self.index);
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?; POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
log::debug!( log::debug!(
"Setting CPU {} (min, max) clockspeed to ({}, {})", "Setting CPU {} (min, max) clockspeed to ({:?}, {:?})",
self.index, self.index,
clock_limits.min, clock_limits.min,
clock_limits.max clock_limits.max
); );
self.state.clock_limits_set = true; self.state.clock_limits_set = true;
// max clock // max clock
let payload_max = format!("p {} 1 {}\n", self.index / 2, clock_limits.max); if let Some(max) = clock_limits.max {
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max) Self::set_clock_limit(self.index, max, ClockType::Max)
.map_err(|e| SettingError { .unwrap_or_else(|e| errors.push(e));
msg: format!( }
"Failed to write `{}` to `{}`: {}",
&payload_max, CPU_CLOCK_LIMITS_PATH, e
),
setting: crate::settings::SettingVariant::Cpu,
})
.unwrap_or_else(|e| errors.push(e));
// min clock // min clock
let valid_min = if clock_limits.min < self.limits.clock_min.min { if let Some(min) = clock_limits.min {
self.limits.clock_min.min let valid_min = if min < self.limits.clock_min.min {
self.limits.clock_min.min
} else {
min
};
Self::set_clock_limit(self.index, valid_min, ClockType::Min)
.unwrap_or_else(|e| errors.push(e));
}
if errors.is_empty() {
Ok(())
} else { } else {
clock_limits.min Err(errors)
}; }
let payload_min = format!("p {} 0 {}\n", self.index / 2, valid_min);
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min)
.map_err(|e| SettingError {
msg: format!(
"Failed to write `{}` to `{}`: {}",
&payload_min, CPU_CLOCK_LIMITS_PATH, e
),
setting: crate::settings::SettingVariant::Cpu,
})
.unwrap_or_else(|e| errors.push(e));
} else if self.state.clock_limits_set } else if self.state.clock_limits_set
|| (self.state.is_resuming && !self.limits.skip_resume_reclock) || (self.state.is_resuming && !self.limits.skip_resume_reclock)
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() || POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual()
{ {
let mut errors = Vec::new();
self.state.clock_limits_set = false; self.state.clock_limits_set = false;
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(false, self.index);
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() { if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?; POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
// disable manual clock limits // disable manual clock limits
log::debug!("Setting CPU {} to default clockspeed", self.index); log::debug!("Setting CPU {} to default clockspeed", self.index);
// max clock // max clock
let payload_max = format!("p {} 1 {}\n", self.index / 2, self.limits.clock_max.max); Self::set_clock_limit(self.index, self.limits.clock_max.max, ClockType::Max)
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max)
.map_err(|e| SettingError {
msg: format!(
"Failed to write `{}` to `{}`: {}",
&payload_max, CPU_CLOCK_LIMITS_PATH, e
),
setting: crate::settings::SettingVariant::Cpu,
})
.unwrap_or_else(|e| errors.push(e)); .unwrap_or_else(|e| errors.push(e));
// min clock // min clock
let payload_min = format!("p {} 0 {}\n", self.index / 2, self.limits.clock_min.min); Self::set_clock_limit(self.index, self.limits.clock_min.min, ClockType::Min)
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min)
.map_err(|e| SettingError {
msg: format!(
"Failed to write `{}` to `{}`: {}",
&payload_min, CPU_CLOCK_LIMITS_PATH, e
),
setting: crate::settings::SettingVariant::Cpu,
})
.unwrap_or_else(|e| errors.push(e)); .unwrap_or_else(|e| errors.push(e));
} }
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(false, self.index);
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
.enforce_level() .enforce_level()
.unwrap_or_else(|mut e| errors.append(&mut e)); .unwrap_or_else(|mut e| errors.append(&mut e));
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
} else {
Ok(())
} }
}
fn set_force_performance_related(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
// set clock limits
//log::debug!("Setting {} to manual", CPU_FORCE_LIMITS_PATH);
//let mode: String = usdpl_back::api::files::read_single(CPU_FORCE_LIMITS_PATH.to_owned()).unwrap();
self.set_clock_limits()
.unwrap_or_else(|mut e| errors.append(&mut e));
// commit changes (if no errors have already occured) // commit changes (if no errors have already occured)
if errors.is_empty() { if errors.is_empty() {
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() { if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
@ -354,6 +364,23 @@ impl Cpu {
} }
} }
fn set_governor(&self) -> Result<(), SettingError> {
if self.index == 0 || self.online {
let governor_path = cpu_governor_path(self.index);
usdpl_back::api::files::write_single(&governor_path, &self.governor).map_err(|e| {
SettingError {
msg: format!(
"Failed to write `{}` to `{}`: {}",
&self.governor, &governor_path, e
),
setting: crate::settings::SettingVariant::Cpu,
}
})
} else {
Ok(())
}
}
fn set_all(&mut self) -> Result<(), Vec<SettingError>> { fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new(); let mut errors = Vec::new();
// set cpu online/offline // set cpu online/offline
@ -371,19 +398,8 @@ impl Cpu {
self.set_force_performance_related() self.set_force_performance_related()
.unwrap_or_else(|mut e| errors.append(&mut e)); .unwrap_or_else(|mut e| errors.append(&mut e));
// set governor self.set_governor().unwrap_or_else(|e| errors.push(e));
if self.index == 0 || self.online {
let governor_path = cpu_governor_path(self.index);
usdpl_back::api::files::write_single(&governor_path, &self.governor)
.map_err(|e| SettingError {
msg: format!(
"Failed to write `{}` to `{}`: {}",
&self.governor, &governor_path, e
),
setting: crate::settings::SettingVariant::Cpu,
})
.unwrap_or_else(|e| errors.push(e));
}
if errors.is_empty() { if errors.is_empty() {
Ok(()) Ok(())
} else { } else {
@ -393,12 +409,14 @@ impl Cpu {
fn clamp_all(&mut self) { fn clamp_all(&mut self) {
if let Some(clock_limits) = &mut self.clock_limits { if let Some(clock_limits) = &mut self.clock_limits {
clock_limits.min = clock_limits if let Some(min) = clock_limits.min {
.min clock_limits.min =
.clamp(self.limits.clock_min.min, self.limits.clock_min.max); Some(min.clamp(self.limits.clock_min.min, self.limits.clock_min.max));
clock_limits.max = clock_limits }
.max if let Some(max) = clock_limits.max {
.clamp(self.limits.clock_max.min, self.limits.clock_max.max); clock_limits.max =
Some(max.clamp(self.limits.clock_max.min, self.limits.clock_max.max));
}
} }
} }

View file

@ -26,6 +26,11 @@ pub struct Gpu {
const GPU_CLOCK_LIMITS_PATH: &str = "/sys/class/drm/card0/device/pp_od_clk_voltage"; const GPU_CLOCK_LIMITS_PATH: &str = "/sys/class/drm/card0/device/pp_od_clk_voltage";
const GPU_MEMORY_DOWNCLOCK_PATH: &str = "/sys/class/drm/card0/device/pp_dpm_fclk"; const GPU_MEMORY_DOWNCLOCK_PATH: &str = "/sys/class/drm/card0/device/pp_dpm_fclk";
enum ClockType {
Min = 0,
Max = 1,
}
impl Gpu { impl Gpu {
#[inline] #[inline]
pub fn from_json(other: GpuJson, version: u64) -> Self { pub fn from_json(other: GpuJson, version: u64) -> Self {
@ -57,6 +62,28 @@ impl Gpu {
} }
} }
fn set_clock_limit(speed: u64, mode: ClockType) -> Result<(), SettingError> {
let payload = format!("s {} {}\n", mode as u8, speed);
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload).map_err(|e| {
SettingError {
msg: format!(
"Failed to write `{}` to `{}`: {}",
&payload, GPU_CLOCK_LIMITS_PATH, e
),
setting: crate::settings::SettingVariant::Gpu,
}
})
}
fn set_confirm() -> Result<(), SettingError> {
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").map_err(|e| {
SettingError {
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e),
setting: crate::settings::SettingVariant::Gpu,
}
})
}
fn set_clocks(&mut self) -> Result<(), Vec<SettingError>> { fn set_clocks(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new(); let mut errors = Vec::new();
if let Some(clock_limits) = &self.clock_limits { if let Some(clock_limits) = &self.clock_limits {
@ -65,81 +92,37 @@ impl Gpu {
// set clock limits // set clock limits
self.state.clock_limits_set = true; self.state.clock_limits_set = true;
// max clock // max clock
let payload_max = format!("s 1 {}\n", clock_limits.max); if let Some(max) = clock_limits.max {
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max) Self::set_clock_limit(max, ClockType::Max).unwrap_or_else(|e| errors.push(e));
.map_err(|e| SettingError { }
msg: format!(
"Failed to write `{}` to `{}`: {}",
&payload_max, GPU_CLOCK_LIMITS_PATH, e
),
setting: crate::settings::SettingVariant::Gpu,
})
.unwrap_or_else(|e| errors.push(e));
// min clock // min clock
let payload_min = format!("s 0 {}\n", clock_limits.min); if let Some(min) = clock_limits.min {
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min) Self::set_clock_limit(min, ClockType::Min).unwrap_or_else(|e| errors.push(e));
.map_err(|e| SettingError { }
msg: format!(
"Failed to write `{}` to `{}`: {}", Self::set_confirm().unwrap_or_else(|e| errors.push(e));
&payload_min, GPU_CLOCK_LIMITS_PATH, e
),
setting: crate::settings::SettingVariant::Gpu,
})
.unwrap_or_else(|e| errors.push(e));
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(
|e| {
errors.push(SettingError {
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e),
setting: crate::settings::SettingVariant::Gpu,
})
},
);
} else if self.state.clock_limits_set } else if self.state.clock_limits_set
|| (self.state.is_resuming && !self.limits.skip_resume_reclock) || (self.state.is_resuming && !self.limits.skip_resume_reclock)
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() || POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual()
{ {
self.state.clock_limits_set = false; self.state.clock_limits_set = false;
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.slow_memory);
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() { if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?; POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
// disable manual clock limits // disable manual clock limits
// max clock // max clock
let payload_max = format!("s 1 {}\n", self.limits.clock_max.max); Self::set_clock_limit(self.limits.clock_max.max, ClockType::Max)
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max)
.map_err(|e| SettingError {
msg: format!(
"Failed to write `{}` to `{}`: {}",
&payload_max, GPU_CLOCK_LIMITS_PATH, e
),
setting: crate::settings::SettingVariant::Gpu,
})
.unwrap_or_else(|e| errors.push(e)); .unwrap_or_else(|e| errors.push(e));
// min clock // min clock
let payload_min = format!("s 0 {}\n", self.limits.clock_min.min); Self::set_clock_limit(self.limits.clock_min.min, ClockType::Min)
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min)
.map_err(|e| SettingError {
msg: format!(
"Failed to write `{}` to `{}`: {}",
&payload_min, GPU_CLOCK_LIMITS_PATH, e
),
setting: crate::settings::SettingVariant::Gpu,
})
.unwrap_or_else(|e| errors.push(e)); .unwrap_or_else(|e| errors.push(e));
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(
|e| { Self::set_confirm().unwrap_or_else(|e| errors.push(e));
errors.push(SettingError { } else {
msg: format!( POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
"Failed to write `c` to `{}`: {}", .enforce_level()
GPU_CLOCK_LIMITS_PATH, e .unwrap_or_else(|mut e| errors.append(&mut e));
),
setting: crate::settings::SettingVariant::Gpu,
})
},
);
} }
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.slow_memory);
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
.enforce_level()
.unwrap_or_else(|mut e| errors.append(&mut e));
} }
if errors.is_empty() { if errors.is_empty() {
Ok(()) Ok(())
@ -148,6 +131,15 @@ impl Gpu {
} }
} }
fn set_slow_memory(slow: bool) -> Result<(), SettingError> {
usdpl_back::api::files::write_single(GPU_MEMORY_DOWNCLOCK_PATH, slow as u8).map_err(|e| {
SettingError {
msg: format!("Failed to write to `{}`: {}", GPU_MEMORY_DOWNCLOCK_PATH, e),
setting: crate::settings::SettingVariant::Gpu,
}
})
}
fn set_force_performance_related(&mut self) -> Result<(), Vec<SettingError>> { fn set_force_performance_related(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new(); let mut errors = Vec::new();
// enable/disable downclock of GPU memory (to 400Mhz?) // enable/disable downclock of GPU memory (to 400Mhz?)
@ -156,21 +148,9 @@ impl Gpu {
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
.enforce_level() .enforce_level()
.unwrap_or_else(|mut e| errors.append(&mut e)); .unwrap_or_else(|mut e| errors.append(&mut e));
usdpl_back::api::files::write_single(GPU_MEMORY_DOWNCLOCK_PATH, self.slow_memory as u8) Self::set_slow_memory(self.slow_memory).unwrap_or_else(|e| errors.push(e));
.unwrap_or_else(|e| {
errors.push(SettingError {
msg: format!("Failed to write to `{}`: {}", GPU_MEMORY_DOWNCLOCK_PATH, e),
setting: crate::settings::SettingVariant::Gpu,
});
});
} else if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() { } else if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
usdpl_back::api::files::write_single(GPU_MEMORY_DOWNCLOCK_PATH, self.slow_memory as u8) Self::set_slow_memory(self.slow_memory).unwrap_or_else(|e| errors.push(e));
.unwrap_or_else(|e| {
errors.push(SettingError {
msg: format!("Failed to write to `{}`: {}", GPU_MEMORY_DOWNCLOCK_PATH, e),
setting: crate::settings::SettingVariant::Gpu,
});
});
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.clock_limits.is_some()); POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.clock_limits.is_some());
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
.enforce_level() .enforce_level()
@ -181,11 +161,9 @@ impl Gpu {
// commit changes (if no errors have already occured) // commit changes (if no errors have already occured)
if errors.is_empty() { if errors.is_empty() {
if self.slow_memory || self.clock_limits.is_some() { if self.slow_memory || self.clock_limits.is_some() {
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").map_err(|e| { Self::set_confirm().map_err(|e| {
vec![SettingError { errors.push(e);
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e), errors
setting: crate::settings::SettingVariant::Gpu,
}]
}) })
} else { } else {
Ok(()) Ok(())
@ -276,12 +254,14 @@ impl Gpu {
*slow_ppt = (*slow_ppt).clamp(self.limits.slow_ppt.min, self.limits.slow_ppt.max); *slow_ppt = (*slow_ppt).clamp(self.limits.slow_ppt.min, self.limits.slow_ppt.max);
} }
if let Some(clock_limits) = &mut self.clock_limits { if let Some(clock_limits) = &mut self.clock_limits {
clock_limits.min = clock_limits if let Some(min) = clock_limits.min {
.min clock_limits.min =
.clamp(self.limits.clock_min.min, self.limits.clock_min.max); Some(min.clamp(self.limits.clock_min.min, self.limits.clock_min.max));
clock_limits.max = clock_limits }
.max if let Some(max) = clock_limits.max {
.clamp(self.limits.clock_max.min, self.limits.clock_max.max); clock_limits.max =
Some(max.clamp(self.limits.clock_max.min, self.limits.clock_max.max));
}
} }
} }

View file

@ -1,4 +1,4 @@
use crate::settings::MinMax; use crate::api::RangeLimit as MinMax;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
const OC_LIMITS_FILEPATH: &str = "pt_oc.json"; const OC_LIMITS_FILEPATH: &str = "pt_oc.json";