forked from NG-SD-Plugins/PowerTools
Refactor steam_deck to modularize system interactions
This commit is contained in:
parent
23d6e49491
commit
f8ea999604
21 changed files with 329 additions and 280 deletions
2
backend/Cargo.lock
generated
2
backend/Cargo.lock
generated
|
@ -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",
|
||||||
|
|
|
@ -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
|
||||||
|
|
2
backend/limits_core/Cargo.lock
generated
2
backend/limits_core/Cargo.lock
generated
|
@ -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",
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
})),
|
})),
|
||||||
|
|
|
@ -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>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
}
|
}
|
||||||
|
|
|
@ -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])
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(())
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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";
|
||||||
|
|
Loading…
Reference in a new issue