From 3031a1c9bfa8e06b3f15ba189fc654f1b6d2b44b Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Sat, 31 Dec 2022 16:28:37 -0500 Subject: [PATCH] Groundwork for RyzenAdj and fix some system defaults --- backend/limits_core/src/json/conditions.rs | 6 +- backend/limits_core/src/json/cpu_limit.rs | 7 +- backend/limits_core/src/json/gpu_limit.rs | 12 +- backend/limits_core/src/json/mod.rs | 2 + backend/limits_core/src/json/range.rs | 8 ++ backend/src/api/api_types.rs | 7 + backend/src/persist/driver.rs | 2 + backend/src/settings/detect/auto_detect.rs | 4 + backend/src/settings/driver.rs | 14 +- backend/src/settings/generic/battery.rs | 19 ++- backend/src/settings/generic/cpu.rs | 130 ++++++++++--------- backend/src/settings/generic/gpu.rs | 32 +++-- backend/src/settings/generic_amd/cpu.rs | 91 +++++++++++++ backend/src/settings/generic_amd/gpu.rs | 72 ++++++++++ backend/src/settings/generic_amd/mod.rs | 5 + backend/src/settings/min_max.rs | 21 ++- backend/src/settings/mod.rs | 3 +- backend/src/settings/steam_deck/cpu.rs | 17 ++- backend/src/settings/steam_deck/gpu.rs | 6 +- backend/src/settings/steam_deck/oc_limits.rs | 35 +++-- backend/src/settings/unknown/cpu.rs | 7 +- 21 files changed, 356 insertions(+), 144 deletions(-) create mode 100644 backend/limits_core/src/json/range.rs create mode 100644 backend/src/settings/generic_amd/cpu.rs create mode 100644 backend/src/settings/generic_amd/gpu.rs create mode 100644 backend/src/settings/generic_amd/mod.rs diff --git a/backend/limits_core/src/json/conditions.rs b/backend/limits_core/src/json/conditions.rs index e584c4a..be08a1c 100644 --- a/backend/limits_core/src/json/conditions.rs +++ b/backend/limits_core/src/json/conditions.rs @@ -17,6 +17,10 @@ pub struct Conditions { impl Conditions { 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() } } diff --git a/backend/limits_core/src/json/cpu_limit.rs b/backend/limits_core/src/json/cpu_limit.rs index d413cda..053ef29 100644 --- a/backend/limits_core/src/json/cpu_limit.rs +++ b/backend/limits_core/src/json/cpu_limit.rs @@ -1,15 +1,20 @@ use serde::{Deserialize, Serialize}; +use super::RangeLimit; + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(tag = "target")] pub enum CpuLimit { SteamDeck, SteamDeckAdvance, Generic(GenericCpuLimit), + GenericAMD(GenericCpuLimit), Unknown, } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct GenericCpuLimit { - /* TODO */ + pub clock_min: Option>, + pub clock_max: Option>, + pub clock_step: u64, } diff --git a/backend/limits_core/src/json/gpu_limit.rs b/backend/limits_core/src/json/gpu_limit.rs index 712b8b1..be77676 100644 --- a/backend/limits_core/src/json/gpu_limit.rs +++ b/backend/limits_core/src/json/gpu_limit.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use super::RangeLimit; #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(tag = "target")] @@ -6,10 +7,19 @@ pub enum GpuLimit { SteamDeck, SteamDeckAdvance, Generic(GenericGpuLimit), + GenericAMD(GenericGpuLimit), Unknown, } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct GenericGpuLimit { - /* TODO */ + pub fast_ppt: Option>, + pub slow_ppt: Option>, + pub ppt_step: Option, + pub tdp: Option>, + pub tdp_boost: Option>, + pub tdp_step: Option, + pub clock_min: Option>, + pub clock_max: Option>, + pub clock_step: Option, } diff --git a/backend/limits_core/src/json/mod.rs b/backend/limits_core/src/json/mod.rs index 250e218..73047bc 100644 --- a/backend/limits_core/src/json/mod.rs +++ b/backend/limits_core/src/json/mod.rs @@ -5,6 +5,7 @@ mod config; mod cpu_limit; mod gpu_limit; mod limits; +mod range; mod target; pub use base::Base; @@ -14,4 +15,5 @@ pub use cpu_limit::{CpuLimit, GenericCpuLimit}; pub use gpu_limit::{GpuLimit, GenericGpuLimit}; pub use config::Config; pub use limits::Limits; +pub use range::RangeLimit; pub use target::Target; diff --git a/backend/limits_core/src/json/range.rs b/backend/limits_core/src/json/range.rs new file mode 100644 index 0000000..2ea3718 --- /dev/null +++ b/backend/limits_core/src/json/range.rs @@ -0,0 +1,8 @@ +use serde::{Deserialize, Serialize}; + +/// Base JSON limits information +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct RangeLimit { + pub min: T, + pub max: T, +} diff --git a/backend/src/api/api_types.rs b/backend/src/api/api_types.rs index 0be7136..f70c69a 100644 --- a/backend/src/api/api_types.rs +++ b/backend/src/api/api_types.rs @@ -6,6 +6,13 @@ pub struct RangeLimit { pub max: T, } +impl From> for RangeLimit { + #[inline] + fn from(other: limits_core::json::RangeLimit) -> Self { + RangeLimit { min: other.min, max: other.max } + } +} + #[derive(Serialize, Deserialize)] pub struct SettingsLimits { pub battery: BatteryLimits, diff --git a/backend/src/persist/driver.rs b/backend/src/persist/driver.rs index f1486b5..1a774bd 100644 --- a/backend/src/persist/driver.rs +++ b/backend/src/persist/driver.rs @@ -10,6 +10,8 @@ pub enum DriverJson { SteamDeckAdvance, #[serde(rename = "generic")] Generic, + #[serde(rename = "generic-amd")] + GenericAMD, #[serde(rename = "unknown")] Unknown, #[default] diff --git a/backend/src/settings/detect/auto_detect.rs b/backend/src/settings/detect/auto_detect.rs index 5306d78..e7fb679 100644 --- a/backend/src/settings/detect/auto_detect.rs +++ b/backend/src/settings/detect/auto_detect.rs @@ -98,6 +98,7 @@ pub fn auto_detect0(settings_opt: Option, json_path: std::path::Pa 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::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)), }; builder.cpus = Some(cpu_driver); @@ -107,6 +108,7 @@ pub fn auto_detect0(settings_opt: Option, json_path: std::path::Pa 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::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)), }; builder.gpu = Some(driver); @@ -130,6 +132,7 @@ pub fn auto_detect0(settings_opt: Option, json_path: std::path::Pa CpuLimit::SteamDeck => 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::GenericAMD(x) => Box::new(crate::settings::generic_amd::Cpus::from_limits(x)), CpuLimit::Unknown => Box::new(crate::settings::unknown::Cpus::system_default()), }; builder.cpus = Some(cpu_driver); @@ -139,6 +142,7 @@ pub fn auto_detect0(settings_opt: Option, json_path: std::path::Pa GpuLimit::SteamDeck => 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::GenericAMD(x) => Box::new(crate::settings::generic_amd::Gpu::from_limits(x)), GpuLimit::Unknown => Box::new(crate::settings::unknown::Gpu::system_default()), }; builder.gpu = Some(driver); diff --git a/backend/src/settings/driver.rs b/backend/src/settings/driver.rs index e1d1b0e..59deec3 100644 --- a/backend/src/settings/driver.rs +++ b/backend/src/settings/driver.rs @@ -52,17 +52,7 @@ impl Driver { 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)), }), - DriverJson::Generic => Ok(Self { - 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::Generic | DriverJson::GenericAMD => 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)), } @@ -83,7 +73,7 @@ pub fn maybe_do_button() { DriverJson::SteamDeck | DriverJson::SteamDeckAdvance => { 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::AutoDetect => log::warn!("WTF, why is auto_detect detecting AutoDetect???") } diff --git a/backend/src/settings/generic/battery.rs b/backend/src/settings/generic/battery.rs index bd300b7..1ca4cc6 100644 --- a/backend/src/settings/generic/battery.rs +++ b/backend/src/settings/generic/battery.rs @@ -1,11 +1,16 @@ use std::convert::Into; +use limits_core::json::GenericBatteryLimit; + use crate::settings::{OnResume, OnSet, SettingError}; use crate::settings::TBattery; use crate::persist::BatteryJson; #[derive(Debug, Clone)] -pub struct Battery; +pub struct Battery { + #[allow(dead_code)] + limits: GenericBatteryLimit, +} impl Into for Battery { #[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 - 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 - Self + Self { + limits + } } } diff --git a/backend/src/settings/generic/cpu.rs b/backend/src/settings/generic/cpu.rs index 568b40f..f1df70e 100644 --- a/backend/src/settings/generic/cpu.rs +++ b/backend/src/settings/generic/cpu.rs @@ -1,5 +1,7 @@ use std::convert::Into; +use limits_core::json::GenericCpuLimit; + use crate::settings::MinMax; use crate::settings::{OnResume, OnSet, SettingError}; 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() { - 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()?; } Ok(()) @@ -79,69 +81,26 @@ impl Cpus { } } - pub fn system_default() -> Self { - if let Some(max_cpu) = Self::cpu_count() { - 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, version: u64) -> Self { + pub fn from_limits(limits: limits_core::json::GenericCpuLimit) -> Self { + let cpu_count = Self::cpu_count().unwrap_or(8); let (_, can_smt) = Self::system_smt_capabilities(); - let mut result = Vec::with_capacity(other.len()); - let max_cpus = Self::cpu_count(); - for (i, cpu) in other.drain(..).enumerate() { - // prevent having more CPUs than available - 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)); - } - } + let mut new_cpus = Vec::with_capacity(cpu_count); + for i in 0..cpu_count { + let new_cpu = Cpu::from_limits(i, limits.clone()); + new_cpus.push(new_cpu); } Self { - cpus: result, + cpus: new_cpus, smt: true, smt_capable: can_smt, } } - pub fn from_limits(_limits: limits_core::json::GenericCpuLimit) -> Self { - // TODO - Self { - cpus: vec![], - smt: false, - smt_capable: false, - } - } - - pub fn from_json_and_limits(mut other: Vec, version: u64, _limits: limits_core::json::GenericCpuLimit) -> Self { + pub fn from_json_and_limits(mut other: Vec, version: u64, limits: limits_core::json::GenericCpuLimit) -> Self { let (_, can_smt) = Self::system_smt_capabilities(); let mut result = Vec::with_capacity(other.len()); let max_cpus = Self::cpu_count(); + let mut smt_disabled = false; for (i, cpu) in other.drain(..).enumerate() { // prevent having more CPUs than available if let Some(max_cpus) = max_cpus { @@ -149,11 +108,13 @@ impl Cpus { 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 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() { result.push(sys_cpus.cpus.remove(i)); } @@ -161,7 +122,7 @@ impl Cpus { } Self { cpus: result, - smt: true, + smt: !smt_disabled, smt_capable: can_smt, } } @@ -201,6 +162,7 @@ impl TCpus for Cpus { pub struct Cpu { pub online: bool, pub governor: String, + limits: GenericCpuLimit, index: usize, state: crate::state::steam_deck::Cpu, } @@ -208,17 +170,30 @@ pub struct Cpu { impl Cpu { #[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 { 0 => Self { online: other.online, governor: other.governor, + limits, index: i, state: crate::state::steam_deck::Cpu::default(), }, _ => Self { online: other.online, governor: other.governor, + limits, index: i, state: crate::state::steam_deck::Cpu::default(), }, @@ -253,7 +228,7 @@ impl Cpu { Ok(()) } - fn from_sys(cpu_index: usize) -> Self { + /*fn from_sys(cpu_index: usize) -> Self { Self { 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)) @@ -261,14 +236,31 @@ impl Cpu { index: cpu_index, state: crate::state::steam_deck::Cpu::default(), } + }*/ + + fn governors(&self) -> Vec { + // 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 { crate::api::CpuLimits { - clock_min_limits: None, - clock_max_limits: None, - clock_step: 100, - governors: vec![], // TODO + clock_min_limits: self.limits.clock_min.clone().map(|x| x.into()), + clock_max_limits: self.limits.clock_max.clone().map(|x| x.into()), + clock_step: self.limits.clock_step, + governors: self.governors(), } } } @@ -312,11 +304,13 @@ impl TCpu for Cpu { &self.governor } - fn clock_limits(&mut self, _limits: Option>) { + fn clock_limits(&mut self, limits: Option>) { + self.limits.clock_min = limits.clone(); + self.limits.clock_max = limits.clone(); } fn get_clock_limits(&self) -> Option<&MinMax> { - None + self.limits.clock_max.as_ref() } } @@ -332,3 +326,11 @@ fn cpu_governor_path(index: usize) -> String { index ) } + +#[inline] +fn cpu_available_governors_path(index: usize) -> String { + format!( + "/sys/devices/system/cpu/cpu{}/cpufreq/scaling_available_governors", + index + ) +} diff --git a/backend/src/settings/generic/gpu.rs b/backend/src/settings/generic/gpu.rs index 3344915..5a92bfd 100644 --- a/backend/src/settings/generic/gpu.rs +++ b/backend/src/settings/generic/gpu.rs @@ -1,5 +1,7 @@ use std::convert::Into; +use limits_core::json::GenericGpuLimit; + use crate::settings::MinMax; use crate::settings::{OnResume, OnSet, SettingError}; use crate::settings::TGpu; @@ -8,15 +10,16 @@ use crate::persist::GpuJson; #[derive(Debug, Clone)] pub struct Gpu { slow_memory: bool, // ignored + limits: GenericGpuLimit, } impl Gpu { - #[inline] + /*#[inline] pub fn from_json(_other: GpuJson, _version: u64) -> Self { Self { slow_memory: false, } - } + }*/ /*pub fn system_default() -> Self { Self { @@ -24,16 +27,17 @@ impl Gpu { } }*/ - pub fn from_limits(_limits: limits_core::json::GenericGpuLimit) -> Self { - // TODO + pub fn from_limits(limits: limits_core::json::GenericGpuLimit) -> Self { Self { 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 { slow_memory: false, + limits, } } } @@ -65,15 +69,15 @@ impl OnResume for Gpu { impl TGpu for Gpu { fn limits(&self) -> crate::api::GpuLimits { crate::api::GpuLimits { - fast_ppt_limits: None, - slow_ppt_limits: None, - ppt_step: 1_000_000, - tdp_limits: None, - tdp_boost_limits: None, - tdp_step: 42, - clock_min_limits: None, - clock_max_limits: None, - clock_step: 100, + fast_ppt_limits: self.limits.fast_ppt.clone().map(|x| x.into()), + slow_ppt_limits: self.limits.slow_ppt.clone().map(|x| x.into()), + ppt_step: self.limits.ppt_step.unwrap_or(1_000_000), + tdp_limits: self.limits.tdp.clone().map(|x| x.into()), + tdp_boost_limits: self.limits.tdp_boost.clone().map(|x| x.into()), + tdp_step: self.limits.tdp_step.unwrap_or(42), + clock_min_limits: self.limits.clock_min.clone().map(|x| x.into()), + clock_max_limits: self.limits.clock_max.clone().map(|x| x.into()), + clock_step: self.limits.clock_step.unwrap_or(100), memory_control_capable: false, } } diff --git a/backend/src/settings/generic_amd/cpu.rs b/backend/src/settings/generic_amd/cpu.rs new file mode 100644 index 0000000..312f8e3 --- /dev/null +++ b/backend/src/settings/generic_amd/cpu.rs @@ -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, 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 { + 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>) { + self.generic.clock_limits(limits) // TODO + } + + fn get_clock_limits(&self) -> Option<&MinMax> { + self.generic.get_clock_limits() // TODO + } +} diff --git a/backend/src/settings/generic_amd/gpu.rs b/backend/src/settings/generic_amd/gpu.rs new file mode 100644 index 0000000..18f8b94 --- /dev/null +++ b/backend/src/settings/generic_amd/gpu.rs @@ -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, slow: Option) { + // TODO + } + + fn get_ppt(&self) -> (Option, Option) { + self.generic.get_ppt() // TODO + } + + fn clock_limits(&mut self, limits: Option>) { + // TODO + } + + fn get_clock_limits(&self) -> Option<&MinMax> { + 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 + } +} diff --git a/backend/src/settings/generic_amd/mod.rs b/backend/src/settings/generic_amd/mod.rs new file mode 100644 index 0000000..6a8e412 --- /dev/null +++ b/backend/src/settings/generic_amd/mod.rs @@ -0,0 +1,5 @@ +mod cpu; +mod gpu; + +pub use cpu::{Cpu, Cpus}; +pub use gpu::Gpu; diff --git a/backend/src/settings/min_max.rs b/backend/src/settings/min_max.rs index 00ea8fd..c1c9563 100644 --- a/backend/src/settings/min_max.rs +++ b/backend/src/settings/min_max.rs @@ -1,24 +1,19 @@ use std::convert::Into; +use limits_core::json::RangeLimit; + use crate::persist::MinMaxJson; -#[derive(Debug, Clone)] -pub struct MinMax { - pub max: T, - pub min: T, -} +pub type MinMax = RangeLimit; -impl MinMax { - #[inline] - pub fn from_json>(other: MinMaxJson, _version: u64) -> Self { - Self { - max: other.max.into(), - min: other.min.into(), - } +pub fn min_max_from_json>(other: MinMaxJson, _version: u64) -> MinMax { + MinMax { + max: other.max.into(), + min: other.min.into(), } } -impl, Y> Into> for MinMax { +impl, Y> Into> for RangeLimit { #[inline] fn into(self) -> MinMaxJson { MinMaxJson { diff --git a/backend/src/settings/mod.rs b/backend/src/settings/mod.rs index 22a591f..a24b57e 100644 --- a/backend/src/settings/mod.rs +++ b/backend/src/settings/mod.rs @@ -6,13 +6,14 @@ mod min_max; mod traits; pub mod generic; +pub mod generic_amd; pub mod steam_deck; pub mod unknown; pub use detect::{auto_detect0, auto_detect_provider, limits_worker::spawn as limits_worker_spawn}; pub use driver::Driver; 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 traits::{OnResume, OnSet, SettingsRange, TGeneral, TGpu, TCpus, TBattery, TCpu}; diff --git a/backend/src/settings/steam_deck/cpu.rs b/backend/src/settings/steam_deck/cpu.rs index 9b78d62..f1b33b8 100644 --- a/backend/src/settings/steam_deck/cpu.rs +++ b/backend/src/settings/steam_deck/cpu.rs @@ -1,7 +1,7 @@ use std::convert::Into; 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::{TCpus, TCpu}; use crate::persist::CpuJson; @@ -90,10 +90,10 @@ impl Cpus { 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())); } - let (smt_status, can_smt) = Self::system_smt_capabilities(); + let (_, can_smt) = Self::system_smt_capabilities(); Self { cpus: sys_cpus, - smt: smt_status, + smt: true, smt_capable: can_smt, limits: oc_limits, } @@ -113,6 +113,7 @@ impl Cpus { let (_, can_smt) = Self::system_smt_capabilities(); let mut result = Vec::with_capacity(other.len()); let max_cpus = Self::cpu_count(); + let mut smt_disabled = false; for (i, cpu) in other.drain(..).enumerate() { // prevent having more CPUs than available if let Some(max_cpus) = max_cpus { @@ -120,7 +121,9 @@ impl Cpus { 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 result.len() != max_cpus { @@ -132,7 +135,7 @@ impl Cpus { } Self { cpus: result, - smt: true, + smt: !smt_disabled, smt_capable: can_smt, limits: oc_limits, } @@ -188,7 +191,7 @@ impl Cpu { match version { 0 => Self { 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, limits: oc_limits, index: i, @@ -196,7 +199,7 @@ impl Cpu { }, _ => Self { 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, limits: oc_limits, index: i, diff --git a/backend/src/settings/steam_deck/gpu.rs b/backend/src/settings/steam_deck/gpu.rs index 99fce9c..9e77ba8 100644 --- a/backend/src/settings/steam_deck/gpu.rs +++ b/backend/src/settings/steam_deck/gpu.rs @@ -1,7 +1,7 @@ use std::convert::Into; 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::TGpu; use crate::persist::GpuJson; @@ -33,7 +33,7 @@ impl Gpu { 0 => Self { fast_ppt: other.fast_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, limits: oc_limits, state: crate::state::steam_deck::Gpu::default(), @@ -41,7 +41,7 @@ impl Gpu { _ => Self { fast_ppt: other.fast_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, limits: oc_limits, state: crate::state::steam_deck::Gpu::default(), diff --git a/backend/src/settings/steam_deck/oc_limits.rs b/backend/src/settings/steam_deck/oc_limits.rs index f81bde1..9712831 100644 --- a/backend/src/settings/steam_deck/oc_limits.rs +++ b/backend/src/settings/steam_deck/oc_limits.rs @@ -1,10 +1,5 @@ use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Clone, Debug)] -pub(super) struct MinMaxLimits { - pub min: T, - pub max: T, -} +use crate::settings::MinMax; const OC_LIMITS_FILEPATH: &str = "./pt_oc.json"; @@ -56,13 +51,13 @@ impl OverclockLimits { #[derive(Serialize, Deserialize, Clone, Debug)] pub(super) struct BatteryLimits { - pub charge_rate: MinMaxLimits, + pub charge_rate: MinMax, } impl Default for BatteryLimits { fn default() -> 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)] pub(super) struct CpuLimits { - pub clock_min: MinMaxLimits, - pub clock_max: MinMaxLimits, + pub clock_min: MinMax, + pub clock_max: MinMax, } impl Default for CpuLimits { fn default() -> Self { Self { - clock_min: MinMaxLimits { min: 1400, max: 3500 }, - clock_max: MinMaxLimits { min: 500, max: 3500 } + clock_min: MinMax { min: 1400, max: 3500 }, + clock_max: MinMax { min: 500, max: 3500 } } } } #[derive(Serialize, Deserialize, Clone, Debug)] pub(super) struct GpuLimits { - pub fast_ppt: MinMaxLimits, - pub slow_ppt: MinMaxLimits, - pub clock_min: MinMaxLimits, - pub clock_max: MinMaxLimits, + pub fast_ppt: MinMax, + pub slow_ppt: MinMax, + pub clock_min: MinMax, + pub clock_max: MinMax, } impl Default for GpuLimits { fn default() -> Self { Self { - fast_ppt: MinMaxLimits { min: 1000000, max: 30_000_000 }, - slow_ppt: MinMaxLimits { min: 1000000, max: 29_000_000 }, - clock_min: MinMaxLimits { min: 200, max: 1600 }, - clock_max: MinMaxLimits { min: 200, max: 1600 } + fast_ppt: MinMax { min: 1000000, max: 30_000_000 }, + slow_ppt: MinMax { min: 1000000, max: 29_000_000 }, + clock_min: MinMax { min: 200, max: 1600 }, + clock_max: MinMax { min: 200, max: 1600 } } } } diff --git a/backend/src/settings/unknown/cpu.rs b/backend/src/settings/unknown/cpu.rs index 2e677ba..76982f4 100644 --- a/backend/src/settings/unknown/cpu.rs +++ b/backend/src/settings/unknown/cpu.rs @@ -105,6 +105,7 @@ impl Cpus { let (_, can_smt) = Self::system_smt_capabilities(); let mut result = Vec::with_capacity(other.len()); let max_cpus = Self::cpu_count(); + let mut smt_disabled = false; for (i, cpu) in other.drain(..).enumerate() { // prevent having more CPUs than available if let Some(max_cpus) = max_cpus { @@ -112,7 +113,9 @@ impl Cpus { 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 result.len() != max_cpus { @@ -124,7 +127,7 @@ impl Cpus { } Self { cpus: result, - smt: true, + smt: !smt_disabled, smt_capable: can_smt, } }