Groundwork for RyzenAdj and fix some system defaults

This commit is contained in:
NGnius (Graham) 2022-12-31 16:28:37 -05:00
parent 1dc0acca8e
commit 3031a1c9bf
21 changed files with 356 additions and 144 deletions

View file

@ -17,6 +17,10 @@ pub struct Conditions {
impl Conditions { impl Conditions {
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.dmi.is_none() && self.cpuinfo.is_none() && self.os.is_none() && self.command.is_none() self.dmi.is_none()
&& self.cpuinfo.is_none()
&& self.os.is_none()
&& self.command.is_none()
&& self.file_exists.is_none()
} }
} }

View file

@ -1,15 +1,20 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::RangeLimit;
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "target")] #[serde(tag = "target")]
pub enum CpuLimit { pub enum CpuLimit {
SteamDeck, SteamDeck,
SteamDeckAdvance, SteamDeckAdvance,
Generic(GenericCpuLimit), Generic(GenericCpuLimit),
GenericAMD(GenericCpuLimit),
Unknown, Unknown,
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct GenericCpuLimit { pub struct GenericCpuLimit {
/* TODO */ pub clock_min: Option<RangeLimit<u64>>,
pub clock_max: Option<RangeLimit<u64>>,
pub clock_step: u64,
} }

View file

@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::RangeLimit;
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "target")] #[serde(tag = "target")]
@ -6,10 +7,19 @@ pub enum GpuLimit {
SteamDeck, SteamDeck,
SteamDeckAdvance, SteamDeckAdvance,
Generic(GenericGpuLimit), Generic(GenericGpuLimit),
GenericAMD(GenericGpuLimit),
Unknown, Unknown,
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct GenericGpuLimit { pub struct GenericGpuLimit {
/* TODO */ pub fast_ppt: Option<RangeLimit<u64>>,
pub slow_ppt: Option<RangeLimit<u64>>,
pub ppt_step: Option<u64>,
pub tdp: Option<RangeLimit<u64>>,
pub tdp_boost: Option<RangeLimit<u64>>,
pub tdp_step: Option<u64>,
pub clock_min: Option<RangeLimit<u64>>,
pub clock_max: Option<RangeLimit<u64>>,
pub clock_step: Option<u64>,
} }

View file

@ -5,6 +5,7 @@ mod config;
mod cpu_limit; mod cpu_limit;
mod gpu_limit; mod gpu_limit;
mod limits; mod limits;
mod range;
mod target; mod target;
pub use base::Base; pub use base::Base;
@ -14,4 +15,5 @@ pub use cpu_limit::{CpuLimit, GenericCpuLimit};
pub use gpu_limit::{GpuLimit, GenericGpuLimit}; pub use gpu_limit::{GpuLimit, GenericGpuLimit};
pub use config::Config; pub use config::Config;
pub use limits::Limits; pub use limits::Limits;
pub use range::RangeLimit;
pub use target::Target; pub use target::Target;

View file

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

View file

@ -6,6 +6,13 @@ pub struct RangeLimit<T> {
pub max: T, pub max: T,
} }
impl<T> From<limits_core::json::RangeLimit<T>> for RangeLimit<T> {
#[inline]
fn from(other: limits_core::json::RangeLimit<T>) -> Self {
RangeLimit { min: other.min, max: other.max }
}
}
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct SettingsLimits { pub struct SettingsLimits {
pub battery: BatteryLimits, pub battery: BatteryLimits,

View file

@ -10,6 +10,8 @@ pub enum DriverJson {
SteamDeckAdvance, SteamDeckAdvance,
#[serde(rename = "generic")] #[serde(rename = "generic")]
Generic, Generic,
#[serde(rename = "generic-amd")]
GenericAMD,
#[serde(rename = "unknown")] #[serde(rename = "unknown")]
Unknown, Unknown,
#[default] #[default]

View file

@ -98,6 +98,7 @@ pub fn auto_detect0(settings_opt: Option<SettingsJson>, json_path: std::path::Pa
CpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Cpus::from_json(settings.cpus.clone(), settings.version)), CpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Cpus::from_json(settings.cpus.clone(), settings.version)),
CpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Cpus::from_json(settings.cpus.clone(), settings.version)), CpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Cpus::from_json(settings.cpus.clone(), settings.version)),
CpuLimit::Generic(x) => Box::new(crate::settings::generic::Cpus::from_json_and_limits(settings.cpus.clone(), settings.version, x)), CpuLimit::Generic(x) => Box::new(crate::settings::generic::Cpus::from_json_and_limits(settings.cpus.clone(), settings.version, x)),
CpuLimit::GenericAMD(x) => Box::new(crate::settings::generic_amd::Cpus::from_json_and_limits(settings.cpus.clone(), settings.version, x)),
CpuLimit::Unknown => Box::new(crate::settings::unknown::Cpus::from_json(settings.cpus.clone(), settings.version)), CpuLimit::Unknown => Box::new(crate::settings::unknown::Cpus::from_json(settings.cpus.clone(), settings.version)),
}; };
builder.cpus = Some(cpu_driver); builder.cpus = Some(cpu_driver);
@ -107,6 +108,7 @@ pub fn auto_detect0(settings_opt: Option<SettingsJson>, json_path: std::path::Pa
GpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Gpu::from_json(settings.gpu.clone(), settings.version)), GpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Gpu::from_json(settings.gpu.clone(), settings.version)),
GpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Gpu::from_json(settings.gpu.clone(), settings.version)), GpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Gpu::from_json(settings.gpu.clone(), settings.version)),
GpuLimit::Generic(x) => Box::new(crate::settings::generic::Gpu::from_json_and_limits(settings.gpu.clone(), settings.version, x)), GpuLimit::Generic(x) => Box::new(crate::settings::generic::Gpu::from_json_and_limits(settings.gpu.clone(), settings.version, x)),
GpuLimit::GenericAMD(x) => Box::new(crate::settings::generic_amd::Gpu::from_json_and_limits(settings.gpu.clone(), settings.version, x)),
GpuLimit::Unknown => Box::new(crate::settings::unknown::Gpu::from_json(settings.gpu.clone(), settings.version)), GpuLimit::Unknown => Box::new(crate::settings::unknown::Gpu::from_json(settings.gpu.clone(), settings.version)),
}; };
builder.gpu = Some(driver); builder.gpu = Some(driver);
@ -130,6 +132,7 @@ pub fn auto_detect0(settings_opt: Option<SettingsJson>, json_path: std::path::Pa
CpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Cpus::system_default()), CpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Cpus::system_default()),
CpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Cpus::system_default()), CpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Cpus::system_default()),
CpuLimit::Generic(x) => Box::new(crate::settings::generic::Cpus::from_limits(x)), CpuLimit::Generic(x) => Box::new(crate::settings::generic::Cpus::from_limits(x)),
CpuLimit::GenericAMD(x) => Box::new(crate::settings::generic_amd::Cpus::from_limits(x)),
CpuLimit::Unknown => Box::new(crate::settings::unknown::Cpus::system_default()), CpuLimit::Unknown => Box::new(crate::settings::unknown::Cpus::system_default()),
}; };
builder.cpus = Some(cpu_driver); builder.cpus = Some(cpu_driver);
@ -139,6 +142,7 @@ pub fn auto_detect0(settings_opt: Option<SettingsJson>, json_path: std::path::Pa
GpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Gpu::system_default()), GpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Gpu::system_default()),
GpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Gpu::system_default()), GpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Gpu::system_default()),
GpuLimit::Generic(x) => Box::new(crate::settings::generic::Gpu::from_limits(x)), GpuLimit::Generic(x) => Box::new(crate::settings::generic::Gpu::from_limits(x)),
GpuLimit::GenericAMD(x) => Box::new(crate::settings::generic_amd::Gpu::from_limits(x)),
GpuLimit::Unknown => Box::new(crate::settings::unknown::Gpu::system_default()), GpuLimit::Unknown => Box::new(crate::settings::unknown::Gpu::system_default()),
}; };
builder.gpu = Some(driver); builder.gpu = Some(driver);

View file

@ -52,17 +52,7 @@ impl Driver {
gpu: Box::new(super::steam_deck::Gpu::from_json(settings.gpu, settings.version)), gpu: Box::new(super::steam_deck::Gpu::from_json(settings.gpu, settings.version)),
battery: Box::new(super::steam_deck::Battery::from_json(settings.battery, settings.version)), battery: Box::new(super::steam_deck::Battery::from_json(settings.battery, settings.version)),
}), }),
DriverJson::Generic => Ok(Self { DriverJson::Generic | DriverJson::GenericAMD => Ok(super::detect::auto_detect0(Some(settings), json_path)),
general: Box::new(General {
persistent: settings.persistent,
path: json_path,
name: settings.name,
driver: DriverJson::Unknown,
}),
cpus: Box::new(super::generic::Cpus::from_json(settings.cpus, settings.version)),
gpu: Box::new(super::generic::Gpu::from_json(settings.gpu, settings.version)),
battery: Box::new(super::generic::Battery),
}),
DriverJson::Unknown => Ok(super::detect::auto_detect0(Some(settings), json_path)), DriverJson::Unknown => Ok(super::detect::auto_detect0(Some(settings), json_path)),
DriverJson::AutoDetect => Ok(super::detect::auto_detect0(Some(settings), json_path)), DriverJson::AutoDetect => Ok(super::detect::auto_detect0(Some(settings), json_path)),
} }
@ -83,7 +73,7 @@ pub fn maybe_do_button() {
DriverJson::SteamDeck | DriverJson::SteamDeckAdvance => { DriverJson::SteamDeck | DriverJson::SteamDeckAdvance => {
crate::settings::steam_deck::flash_led(); crate::settings::steam_deck::flash_led();
}, },
DriverJson::Generic => log::warn!("You need to come up with something fun on generic"), DriverJson::Generic | DriverJson::GenericAMD => log::warn!("You need to come up with something fun on generic"),
DriverJson::Unknown => log::warn!("Can't do button activities on unknown platform"), DriverJson::Unknown => log::warn!("Can't do button activities on unknown platform"),
DriverJson::AutoDetect => log::warn!("WTF, why is auto_detect detecting AutoDetect???") DriverJson::AutoDetect => log::warn!("WTF, why is auto_detect detecting AutoDetect???")
} }

View file

@ -1,11 +1,16 @@
use std::convert::Into; use std::convert::Into;
use limits_core::json::GenericBatteryLimit;
use crate::settings::{OnResume, OnSet, SettingError}; use crate::settings::{OnResume, OnSet, SettingError};
use crate::settings::TBattery; use crate::settings::TBattery;
use crate::persist::BatteryJson; use crate::persist::BatteryJson;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Battery; pub struct Battery {
#[allow(dead_code)]
limits: GenericBatteryLimit,
}
impl Into<BatteryJson> for Battery { impl Into<BatteryJson> for Battery {
#[inline] #[inline]
@ -39,14 +44,18 @@ impl Battery {
} }
} }
pub fn from_limits(_limits: limits_core::json::GenericBatteryLimit) -> Self { pub fn from_limits(limits: limits_core::json::GenericBatteryLimit) -> Self {
// TODO // TODO
Self Self {
limits
}
} }
pub fn from_json_and_limits(_other: BatteryJson, _version: u64, _limits: limits_core::json::GenericBatteryLimit) -> Self { pub fn from_json_and_limits(_other: BatteryJson, _version: u64, limits: limits_core::json::GenericBatteryLimit) -> Self {
// TODO // TODO
Self Self {
limits
}
} }
} }

View file

@ -1,5 +1,7 @@
use std::convert::Into; use std::convert::Into;
use limits_core::json::GenericCpuLimit;
use crate::settings::MinMax; use crate::settings::MinMax;
use crate::settings::{OnResume, OnSet, SettingError}; use crate::settings::{OnResume, OnSet, SettingError};
use crate::settings::{TCpus, TCpu}; use crate::settings::{TCpus, TCpu};
@ -42,7 +44,7 @@ impl OnSet for Cpus {
} }
} }
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() { for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
cpu.state.do_set_online = self.smt || i % 2 == 0; cpu.state.do_set_online = self.smt || i % 2 == 0 || !self.smt_capable;
cpu.on_set()?; cpu.on_set()?;
} }
Ok(()) Ok(())
@ -79,69 +81,26 @@ impl Cpus {
} }
} }
pub fn system_default() -> Self { pub fn from_limits(limits: limits_core::json::GenericCpuLimit) -> Self {
if let Some(max_cpu) = Self::cpu_count() { let cpu_count = Self::cpu_count().unwrap_or(8);
let mut sys_cpus = Vec::with_capacity(max_cpu);
for i in 0..max_cpu {
sys_cpus.push(Cpu::from_sys(i));
}
let (smt_status, can_smt) = Self::system_smt_capabilities();
Self {
cpus: sys_cpus,
smt: smt_status,
smt_capable: can_smt,
}
} else {
Self {
cpus: vec![],
smt: false,
smt_capable: false,
}
}
}
#[inline]
pub fn from_json(mut other: Vec<CpuJson>, version: u64) -> Self {
let (_, can_smt) = Self::system_smt_capabilities(); let (_, can_smt) = Self::system_smt_capabilities();
let mut result = Vec::with_capacity(other.len()); let mut new_cpus = Vec::with_capacity(cpu_count);
let max_cpus = Self::cpu_count(); for i in 0..cpu_count {
for (i, cpu) in other.drain(..).enumerate() { let new_cpu = Cpu::from_limits(i, limits.clone());
// prevent having more CPUs than available new_cpus.push(new_cpu);
if let Some(max_cpus) = max_cpus {
if i == max_cpus {
break;
}
}
result.push(Cpu::from_json(cpu, version, i));
}
if let Some(max_cpus) = max_cpus {
if result.len() != max_cpus {
let mut sys_cpus = Cpus::system_default();
for i in result.len()..sys_cpus.cpus.len() {
result.push(sys_cpus.cpus.remove(i));
}
}
} }
Self { Self {
cpus: result, cpus: new_cpus,
smt: true, smt: true,
smt_capable: can_smt, smt_capable: can_smt,
} }
} }
pub fn from_limits(_limits: limits_core::json::GenericCpuLimit) -> Self { pub fn from_json_and_limits(mut other: Vec<CpuJson>, version: u64, limits: limits_core::json::GenericCpuLimit) -> Self {
// TODO
Self {
cpus: vec![],
smt: false,
smt_capable: false,
}
}
pub fn from_json_and_limits(mut other: Vec<CpuJson>, version: u64, _limits: limits_core::json::GenericCpuLimit) -> Self {
let (_, can_smt) = Self::system_smt_capabilities(); let (_, can_smt) = Self::system_smt_capabilities();
let mut result = Vec::with_capacity(other.len()); let mut result = Vec::with_capacity(other.len());
let max_cpus = Self::cpu_count(); let max_cpus = Self::cpu_count();
let mut smt_disabled = false;
for (i, cpu) in other.drain(..).enumerate() { for (i, cpu) in other.drain(..).enumerate() {
// prevent having more CPUs than available // prevent having more CPUs than available
if let Some(max_cpus) = max_cpus { if let Some(max_cpus) = max_cpus {
@ -149,11 +108,13 @@ impl Cpus {
break; break;
} }
} }
result.push(Cpu::from_json(cpu, version, i)); let new_cpu = Cpu::from_json_and_limits(cpu, version, i, limits.clone());
smt_disabled &= new_cpu.online as usize != i % 2;
result.push(new_cpu);
} }
if let Some(max_cpus) = max_cpus { if let Some(max_cpus) = max_cpus {
if result.len() != max_cpus { if result.len() != max_cpus {
let mut sys_cpus = Cpus::system_default(); let mut sys_cpus = Cpus::from_limits(limits.clone());
for i in result.len()..sys_cpus.cpus.len() { for i in result.len()..sys_cpus.cpus.len() {
result.push(sys_cpus.cpus.remove(i)); result.push(sys_cpus.cpus.remove(i));
} }
@ -161,7 +122,7 @@ impl Cpus {
} }
Self { Self {
cpus: result, cpus: result,
smt: true, smt: !smt_disabled,
smt_capable: can_smt, smt_capable: can_smt,
} }
} }
@ -201,6 +162,7 @@ impl TCpus for Cpus {
pub struct Cpu { pub struct Cpu {
pub online: bool, pub online: bool,
pub governor: String, pub governor: String,
limits: GenericCpuLimit,
index: usize, index: usize,
state: crate::state::steam_deck::Cpu, state: crate::state::steam_deck::Cpu,
} }
@ -208,17 +170,30 @@ pub struct Cpu {
impl Cpu { impl Cpu {
#[inline] #[inline]
pub fn from_json(other: CpuJson, version: u64, i: usize) -> Self { pub fn from_limits(cpu_index: usize, limits: GenericCpuLimit) -> Self {
Self {
online: true,
governor: "schedutil".to_owned(),
limits,
index: cpu_index,
state: crate::state::steam_deck::Cpu::default(),
}
}
#[inline]
pub fn from_json_and_limits(other: CpuJson, version: u64, i: usize, limits: GenericCpuLimit) -> Self {
match version { match version {
0 => Self { 0 => Self {
online: other.online, online: other.online,
governor: other.governor, governor: other.governor,
limits,
index: i, index: i,
state: crate::state::steam_deck::Cpu::default(), state: crate::state::steam_deck::Cpu::default(),
}, },
_ => Self { _ => Self {
online: other.online, online: other.online,
governor: other.governor, governor: other.governor,
limits,
index: i, index: i,
state: crate::state::steam_deck::Cpu::default(), state: crate::state::steam_deck::Cpu::default(),
}, },
@ -253,7 +228,7 @@ impl Cpu {
Ok(()) Ok(())
} }
fn from_sys(cpu_index: usize) -> Self { /*fn from_sys(cpu_index: usize) -> Self {
Self { Self {
online: usdpl_back::api::files::read_single(cpu_online_path(cpu_index)).unwrap_or(1u8) != 0, online: usdpl_back::api::files::read_single(cpu_online_path(cpu_index)).unwrap_or(1u8) != 0,
governor: usdpl_back::api::files::read_single(cpu_governor_path(cpu_index)) governor: usdpl_back::api::files::read_single(cpu_governor_path(cpu_index))
@ -261,14 +236,31 @@ impl Cpu {
index: cpu_index, index: cpu_index,
state: crate::state::steam_deck::Cpu::default(), state: crate::state::steam_deck::Cpu::default(),
} }
}*/
fn governors(&self) -> Vec<String> {
// NOTE: this eats errors
let gov_str: String = match usdpl_back::api::files::read_single(cpu_available_governors_path(self.index)) {
Ok(s) => s,
Err((Some(e), None)) => {
log::warn!("Error getting available CPU governors: {}", e);
return vec![];
},
Err((None, Some(e))) => {
log::warn!("Error getting available CPU governors: {}", e);
return vec![];
},
Err(_) => return vec![],
};
gov_str.split(' ').map(|s| s.to_owned()).collect()
} }
fn limits(&self) -> crate::api::CpuLimits { fn limits(&self) -> crate::api::CpuLimits {
crate::api::CpuLimits { crate::api::CpuLimits {
clock_min_limits: None, clock_min_limits: self.limits.clock_min.clone().map(|x| x.into()),
clock_max_limits: None, clock_max_limits: self.limits.clock_max.clone().map(|x| x.into()),
clock_step: 100, clock_step: self.limits.clock_step,
governors: vec![], // TODO governors: self.governors(),
} }
} }
} }
@ -312,11 +304,13 @@ impl TCpu for Cpu {
&self.governor &self.governor
} }
fn clock_limits(&mut self, _limits: Option<MinMax<u64>>) { fn clock_limits(&mut self, limits: Option<MinMax<u64>>) {
self.limits.clock_min = limits.clone();
self.limits.clock_max = limits.clone();
} }
fn get_clock_limits(&self) -> Option<&MinMax<u64>> { fn get_clock_limits(&self) -> Option<&MinMax<u64>> {
None self.limits.clock_max.as_ref()
} }
} }
@ -332,3 +326,11 @@ fn cpu_governor_path(index: usize) -> String {
index index
) )
} }
#[inline]
fn cpu_available_governors_path(index: usize) -> String {
format!(
"/sys/devices/system/cpu/cpu{}/cpufreq/scaling_available_governors",
index
)
}

View file

@ -1,5 +1,7 @@
use std::convert::Into; use std::convert::Into;
use limits_core::json::GenericGpuLimit;
use crate::settings::MinMax; use crate::settings::MinMax;
use crate::settings::{OnResume, OnSet, SettingError}; use crate::settings::{OnResume, OnSet, SettingError};
use crate::settings::TGpu; use crate::settings::TGpu;
@ -8,15 +10,16 @@ use crate::persist::GpuJson;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Gpu { pub struct Gpu {
slow_memory: bool, // ignored slow_memory: bool, // ignored
limits: GenericGpuLimit,
} }
impl Gpu { impl Gpu {
#[inline] /*#[inline]
pub fn from_json(_other: GpuJson, _version: u64) -> Self { pub fn from_json(_other: GpuJson, _version: u64) -> Self {
Self { Self {
slow_memory: false, slow_memory: false,
} }
} }*/
/*pub fn system_default() -> Self { /*pub fn system_default() -> Self {
Self { Self {
@ -24,16 +27,17 @@ impl Gpu {
} }
}*/ }*/
pub fn from_limits(_limits: limits_core::json::GenericGpuLimit) -> Self { pub fn from_limits(limits: limits_core::json::GenericGpuLimit) -> Self {
// TODO
Self { Self {
slow_memory: false, slow_memory: false,
limits,
} }
} }
pub fn from_json_and_limits(_other: GpuJson, _version: u64, _limits: limits_core::json::GenericGpuLimit) -> Self { pub fn from_json_and_limits(_other: GpuJson, _version: u64, limits: limits_core::json::GenericGpuLimit) -> Self {
Self { Self {
slow_memory: false, slow_memory: false,
limits,
} }
} }
} }
@ -65,15 +69,15 @@ impl OnResume 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: None, fast_ppt_limits: self.limits.fast_ppt.clone().map(|x| x.into()),
slow_ppt_limits: None, slow_ppt_limits: self.limits.slow_ppt.clone().map(|x| x.into()),
ppt_step: 1_000_000, ppt_step: self.limits.ppt_step.unwrap_or(1_000_000),
tdp_limits: None, tdp_limits: self.limits.tdp.clone().map(|x| x.into()),
tdp_boost_limits: None, tdp_boost_limits: self.limits.tdp_boost.clone().map(|x| x.into()),
tdp_step: 42, tdp_step: self.limits.tdp_step.unwrap_or(42),
clock_min_limits: None, clock_min_limits: self.limits.clock_min.clone().map(|x| x.into()),
clock_max_limits: None, clock_max_limits: self.limits.clock_max.clone().map(|x| x.into()),
clock_step: 100, clock_step: self.limits.clock_step.unwrap_or(100),
memory_control_capable: false, memory_control_capable: false,
} }
} }

View file

@ -0,0 +1,91 @@
use crate::persist::CpuJson;
use crate::settings::MinMax;
use crate::settings::generic::{Cpu as GenericCpu, Cpus as GenericCpus};
use crate::settings::{OnResume, OnSet, SettingError};
use crate::settings::{TCpus, TCpu};
#[derive(Debug)]
pub struct Cpus {
generic: GenericCpus,
}
impl Cpus {
pub fn from_limits(limits: limits_core::json::GenericCpuLimit) -> Self {
Self {
generic: GenericCpus::from_limits(limits),
}
}
pub fn from_json_and_limits(other: Vec<CpuJson>, version: u64, limits: limits_core::json::GenericCpuLimit) -> Self {
Self {
generic: GenericCpus::from_json_and_limits(other, version, limits),
}
}
}
impl OnResume for Cpus {
fn on_resume(&self) -> Result<(), SettingError> {
self.generic.on_resume()
// TODO
}
}
impl OnSet for Cpus {
fn on_set(&mut self) -> Result<(), SettingError> {
self.generic.on_set()
// TODO
}
}
impl TCpus for Cpus {
fn limits(&self) -> crate::api::CpusLimits {
self.generic.limits()
}
fn json(&self) -> Vec<crate::persist::CpuJson> {
self.generic.json() // TODO
}
fn cpus(&mut self) -> Vec<&mut dyn TCpu> {
self.generic.cpus() // TODO
}
fn len(&self) -> usize {
self.generic.len() // TODO
}
fn smt(&mut self) -> &'_ mut bool {
self.generic.smt()
}
fn provider(&self) -> crate::persist::DriverJson {
crate::persist::DriverJson::GenericAMD
}
}
#[derive(Debug)]
pub struct Cpu {
generic: GenericCpu,
}
impl TCpu for Cpu {
fn online(&mut self) -> &mut bool {
self.generic.online()
}
fn governor(&mut self, governor: String) {
self.generic.governor(governor)
}
fn get_governor(&self) -> &'_ str {
self.generic.get_governor()
}
fn clock_limits(&mut self, limits: Option<MinMax<u64>>) {
self.generic.clock_limits(limits) // TODO
}
fn get_clock_limits(&self) -> Option<&MinMax<u64>> {
self.generic.get_clock_limits() // TODO
}
}

View file

@ -0,0 +1,72 @@
use crate::persist::GpuJson;
use crate::settings::MinMax;
use crate::settings::generic::Gpu as GenericGpu;
use crate::settings::{OnResume, OnSet, SettingError};
use crate::settings::TGpu;
#[derive(Debug)]
pub struct Gpu {
generic: GenericGpu,
}
impl Gpu {
pub fn from_limits(limits: limits_core::json::GenericGpuLimit) -> Self {
Self {
generic: GenericGpu::from_limits(limits),
}
}
pub fn from_json_and_limits(other: GpuJson, version: u64, limits: limits_core::json::GenericGpuLimit) -> Self {
Self {
generic: GenericGpu::from_json_and_limits(other, version, limits),
}
}
}
impl OnResume for Gpu {
fn on_resume(&self) -> Result<(), SettingError> {
self.generic.on_resume()
// TODO
}
}
impl OnSet for Gpu {
fn on_set(&mut self) -> Result<(), SettingError> {
self.generic.on_set()
// TODO
}
}
impl TGpu for Gpu {
fn limits(&self) -> crate::api::GpuLimits {
self.generic.limits()
}
fn json(&self) -> crate::persist::GpuJson {
self.generic.json()
}
fn ppt(&mut self, fast: Option<u64>, slow: Option<u64>) {
// TODO
}
fn get_ppt(&self) -> (Option<u64>, Option<u64>) {
self.generic.get_ppt() // TODO
}
fn clock_limits(&mut self, limits: Option<MinMax<u64>>) {
// TODO
}
fn get_clock_limits(&self) -> Option<&MinMax<u64>> {
self.generic.get_clock_limits()
}
fn slow_memory(&mut self) -> &mut bool {
self.generic.slow_memory()
}
fn provider(&self) -> crate::persist::DriverJson {
crate::persist::DriverJson::GenericAMD
}
}

View file

@ -0,0 +1,5 @@
mod cpu;
mod gpu;
pub use cpu::{Cpu, Cpus};
pub use gpu::Gpu;

View file

@ -1,24 +1,19 @@
use std::convert::Into; use std::convert::Into;
use limits_core::json::RangeLimit;
use crate::persist::MinMaxJson; use crate::persist::MinMaxJson;
#[derive(Debug, Clone)] pub type MinMax<T> = RangeLimit<T>;
pub struct MinMax<T> {
pub max: T,
pub min: T,
}
impl<T> MinMax<T> { pub fn min_max_from_json<T, X: Into<T>>(other: MinMaxJson<X>, _version: u64) -> MinMax<T> {
#[inline] MinMax {
pub fn from_json<X: Into<T>>(other: MinMaxJson<X>, _version: u64) -> Self { max: other.max.into(),
Self { min: other.min.into(),
max: other.max.into(),
min: other.min.into(),
}
} }
} }
impl<X: Into<Y>, Y> Into<MinMaxJson<Y>> for MinMax<X> { 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 {

View file

@ -6,13 +6,14 @@ mod min_max;
mod traits; mod traits;
pub mod generic; pub mod generic;
pub mod generic_amd;
pub mod steam_deck; pub mod steam_deck;
pub mod unknown; pub mod unknown;
pub use detect::{auto_detect0, auto_detect_provider, limits_worker::spawn as limits_worker_spawn}; pub use detect::{auto_detect0, auto_detect_provider, limits_worker::spawn as limits_worker_spawn};
pub use driver::Driver; pub use driver::Driver;
pub use general::{SettingVariant, Settings, General}; pub use general::{SettingVariant, Settings, General};
pub use min_max::MinMax; pub use min_max::{MinMax, min_max_from_json};
pub use error::SettingError; pub use error::SettingError;
pub use traits::{OnResume, OnSet, SettingsRange, TGeneral, TGpu, TCpus, TBattery, TCpu}; pub use traits::{OnResume, OnSet, SettingsRange, TGeneral, TGpu, TCpus, TBattery, TCpu};

View file

@ -1,7 +1,7 @@
use std::convert::Into; use std::convert::Into;
use crate::api::RangeLimit; use crate::api::RangeLimit;
use crate::settings::MinMax; use crate::settings::{MinMax, min_max_from_json};
use crate::settings::{OnResume, OnSet, SettingError}; use crate::settings::{OnResume, OnSet, SettingError};
use crate::settings::{TCpus, TCpu}; use crate::settings::{TCpus, TCpu};
use crate::persist::CpuJson; use crate::persist::CpuJson;
@ -90,10 +90,10 @@ impl Cpus {
for i in 0..max_cpu { for i in 0..max_cpu {
sys_cpus.push(Cpu::from_sys(i, oc_limits.cpus.get(i).map(|x| x.to_owned()).unwrap_or_default())); sys_cpus.push(Cpu::from_sys(i, oc_limits.cpus.get(i).map(|x| x.to_owned()).unwrap_or_default()));
} }
let (smt_status, can_smt) = Self::system_smt_capabilities(); let (_, can_smt) = Self::system_smt_capabilities();
Self { Self {
cpus: sys_cpus, cpus: sys_cpus,
smt: smt_status, smt: true,
smt_capable: can_smt, smt_capable: can_smt,
limits: oc_limits, limits: oc_limits,
} }
@ -113,6 +113,7 @@ impl Cpus {
let (_, can_smt) = Self::system_smt_capabilities(); let (_, can_smt) = Self::system_smt_capabilities();
let mut result = Vec::with_capacity(other.len()); let mut result = Vec::with_capacity(other.len());
let max_cpus = Self::cpu_count(); let max_cpus = Self::cpu_count();
let mut smt_disabled = false;
for (i, cpu) in other.drain(..).enumerate() { for (i, cpu) in other.drain(..).enumerate() {
// prevent having more CPUs than available // prevent having more CPUs than available
if let Some(max_cpus) = max_cpus { if let Some(max_cpus) = max_cpus {
@ -120,7 +121,9 @@ impl Cpus {
break; break;
} }
} }
result.push(Cpu::from_json(cpu, version, i, oc_limits.cpus.get(i).map(|x| x.to_owned()).unwrap_or_default())); let new_cpu = Cpu::from_json(cpu, version, i, oc_limits.cpus.get(i).map(|x| x.to_owned()).unwrap_or_default());
smt_disabled &= new_cpu.online as usize != i % 2;
result.push(new_cpu);
} }
if let Some(max_cpus) = max_cpus { if let Some(max_cpus) = max_cpus {
if result.len() != max_cpus { if result.len() != max_cpus {
@ -132,7 +135,7 @@ impl Cpus {
} }
Self { Self {
cpus: result, cpus: result,
smt: true, smt: !smt_disabled,
smt_capable: can_smt, smt_capable: can_smt,
limits: oc_limits, limits: oc_limits,
} }
@ -188,7 +191,7 @@ impl Cpu {
match version { match version {
0 => Self { 0 => Self {
online: other.online, online: other.online,
clock_limits: other.clock_limits.map(|x| MinMax::from_json(x, version)), clock_limits: other.clock_limits.map(|x| min_max_from_json(x, version)),
governor: other.governor, governor: other.governor,
limits: oc_limits, limits: oc_limits,
index: i, index: i,
@ -196,7 +199,7 @@ impl Cpu {
}, },
_ => Self { _ => Self {
online: other.online, online: other.online,
clock_limits: other.clock_limits.map(|x| MinMax::from_json(x, version)), clock_limits: other.clock_limits.map(|x| min_max_from_json(x, version)),
governor: other.governor, governor: other.governor,
limits: oc_limits, limits: oc_limits,
index: i, index: i,

View file

@ -1,7 +1,7 @@
use std::convert::Into; use std::convert::Into;
use crate::api::RangeLimit; use crate::api::RangeLimit;
use crate::settings::MinMax; use crate::settings::{MinMax, min_max_from_json};
use crate::settings::{OnResume, OnSet, SettingError}; use crate::settings::{OnResume, OnSet, SettingError};
use crate::settings::TGpu; use crate::settings::TGpu;
use crate::persist::GpuJson; use crate::persist::GpuJson;
@ -33,7 +33,7 @@ impl Gpu {
0 => Self { 0 => Self {
fast_ppt: other.fast_ppt, fast_ppt: other.fast_ppt,
slow_ppt: other.slow_ppt, slow_ppt: other.slow_ppt,
clock_limits: other.clock_limits.map(|x| MinMax::from_json(x, version)), clock_limits: other.clock_limits.map(|x| min_max_from_json(x, version)),
slow_memory: other.slow_memory, slow_memory: other.slow_memory,
limits: oc_limits, limits: oc_limits,
state: crate::state::steam_deck::Gpu::default(), state: crate::state::steam_deck::Gpu::default(),
@ -41,7 +41,7 @@ impl Gpu {
_ => Self { _ => Self {
fast_ppt: other.fast_ppt, fast_ppt: other.fast_ppt,
slow_ppt: other.slow_ppt, slow_ppt: other.slow_ppt,
clock_limits: other.clock_limits.map(|x| MinMax::from_json(x, version)), clock_limits: other.clock_limits.map(|x| min_max_from_json(x, version)),
slow_memory: other.slow_memory, slow_memory: other.slow_memory,
limits: oc_limits, limits: oc_limits,
state: crate::state::steam_deck::Gpu::default(), state: crate::state::steam_deck::Gpu::default(),

View file

@ -1,10 +1,5 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::settings::MinMax;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub(super) struct MinMaxLimits<T> {
pub min: T,
pub max: T,
}
const OC_LIMITS_FILEPATH: &str = "./pt_oc.json"; const OC_LIMITS_FILEPATH: &str = "./pt_oc.json";
@ -56,13 +51,13 @@ impl OverclockLimits {
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub(super) struct BatteryLimits { pub(super) struct BatteryLimits {
pub charge_rate: MinMaxLimits<u64>, pub charge_rate: MinMax<u64>,
} }
impl Default for BatteryLimits { impl Default for BatteryLimits {
fn default() -> Self { fn default() -> Self {
Self { Self {
charge_rate: MinMaxLimits { min: 250, max: 2500 }, charge_rate: MinMax { min: 250, max: 2500 },
} }
} }
} }
@ -82,34 +77,34 @@ impl Default for CpusLimits {
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub(super) struct CpuLimits { pub(super) struct CpuLimits {
pub clock_min: MinMaxLimits<u64>, pub clock_min: MinMax<u64>,
pub clock_max: MinMaxLimits<u64>, pub clock_max: MinMax<u64>,
} }
impl Default for CpuLimits { impl Default for CpuLimits {
fn default() -> Self { fn default() -> Self {
Self { Self {
clock_min: MinMaxLimits { min: 1400, max: 3500 }, clock_min: MinMax { min: 1400, max: 3500 },
clock_max: MinMaxLimits { min: 500, max: 3500 } clock_max: MinMax { min: 500, max: 3500 }
} }
} }
} }
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub(super) struct GpuLimits { pub(super) struct GpuLimits {
pub fast_ppt: MinMaxLimits<u64>, pub fast_ppt: MinMax<u64>,
pub slow_ppt: MinMaxLimits<u64>, pub slow_ppt: MinMax<u64>,
pub clock_min: MinMaxLimits<u64>, pub clock_min: MinMax<u64>,
pub clock_max: MinMaxLimits<u64>, pub clock_max: MinMax<u64>,
} }
impl Default for GpuLimits { impl Default for GpuLimits {
fn default() -> Self { fn default() -> Self {
Self { Self {
fast_ppt: MinMaxLimits { min: 1000000, max: 30_000_000 }, fast_ppt: MinMax { min: 1000000, max: 30_000_000 },
slow_ppt: MinMaxLimits { min: 1000000, max: 29_000_000 }, slow_ppt: MinMax { min: 1000000, max: 29_000_000 },
clock_min: MinMaxLimits { min: 200, max: 1600 }, clock_min: MinMax { min: 200, max: 1600 },
clock_max: MinMaxLimits { min: 200, max: 1600 } clock_max: MinMax { min: 200, max: 1600 }
} }
} }
} }

View file

@ -105,6 +105,7 @@ impl Cpus {
let (_, can_smt) = Self::system_smt_capabilities(); let (_, can_smt) = Self::system_smt_capabilities();
let mut result = Vec::with_capacity(other.len()); let mut result = Vec::with_capacity(other.len());
let max_cpus = Self::cpu_count(); let max_cpus = Self::cpu_count();
let mut smt_disabled = false;
for (i, cpu) in other.drain(..).enumerate() { for (i, cpu) in other.drain(..).enumerate() {
// prevent having more CPUs than available // prevent having more CPUs than available
if let Some(max_cpus) = max_cpus { if let Some(max_cpus) = max_cpus {
@ -112,7 +113,9 @@ impl Cpus {
break; break;
} }
} }
result.push(Cpu::from_json(cpu, version, i)); let new_cpu = Cpu::from_json(cpu, version, i);
smt_disabled &= new_cpu.online as usize != i % 2;
result.push(new_cpu);
} }
if let Some(max_cpus) = max_cpus { if let Some(max_cpus) = max_cpus {
if result.len() != max_cpus { if result.len() != max_cpus {
@ -124,7 +127,7 @@ impl Cpus {
} }
Self { Self {
cpus: result, cpus: result,
smt: true, smt: !smt_disabled,
smt_capable: can_smt, smt_capable: can_smt,
} }
} }