From 0ee30eebe63b3d175d1c307aca7729778761d550 Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Sun, 28 Jan 2024 19:55:20 -0500 Subject: [PATCH] Add dev driver --- backend/limits_core/src/json_v2/base.rs | 34 +++ .../limits_core/src/json_v2/battery_limit.rs | 25 ++ backend/limits_core/src/json_v2/cpu_limit.rs | 39 ++++ backend/limits_core/src/json_v2/gpu_limit.rs | 46 +++- backend/src/persist/driver.rs | 2 + backend/src/settings/detect/auto_detect.rs | 30 +++ backend/src/settings/dev_mode/battery.rs | 146 ++++++++++++ backend/src/settings/dev_mode/cpu.rs | 221 ++++++++++++++++++ backend/src/settings/dev_mode/gpu.rs | 141 +++++++++++ backend/src/settings/dev_mode/mod.rs | 15 ++ backend/src/settings/driver.rs | 1 + backend/src/settings/mod.rs | 3 +- 12 files changed, 701 insertions(+), 2 deletions(-) create mode 100644 backend/src/settings/dev_mode/battery.rs create mode 100644 backend/src/settings/dev_mode/cpu.rs create mode 100644 backend/src/settings/dev_mode/gpu.rs create mode 100644 backend/src/settings/dev_mode/mod.rs diff --git a/backend/limits_core/src/json_v2/base.rs b/backend/limits_core/src/json_v2/base.rs index 57abec8..7733759 100644 --- a/backend/limits_core/src/json_v2/base.rs +++ b/backend/limits_core/src/json_v2/base.rs @@ -16,6 +16,30 @@ impl Default for Base { fn default() -> Self { Base { configs: vec![ + super::Config { + name: "Devs mode best mode".to_owned(), + conditions: super::Conditions { + dmi: None, + cpuinfo: None, + os: None, + command: None, + file_exists: Some("/etc/powertools_dev_mode".into()), + }, + limits: super::Limits { + cpu: super::Limit { + provider: super::CpuLimitType::DevMode, + limits: super::GenericCpusLimit::default_for(super::CpuLimitType::DevMode), + }, + gpu: super::Limit { + provider: super::GpuLimitType::DevMode, + limits: super::GenericGpuLimit::default_for(super::GpuLimitType::DevMode), + }, + battery: super::Limit { + provider: super::BatteryLimitType::DevMode, + limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::DevMode), + }, + } + }, super::Config { name: "Steam Deck".to_owned(), conditions: super::Conditions { @@ -83,8 +107,10 @@ impl Default for Base { clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(3700) }), clock_step: Some(100), skip_resume_reclock: false, + ..Default::default() }; 4], global_governors: true, + experiments: false, } }, gpu: super::GpuLimit { @@ -125,8 +151,10 @@ impl Default for Base { clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(4000) }), clock_step: Some(100), skip_resume_reclock: false, + ..Default::default() }; 12], // 6 cores with SMTx2 global_governors: true, + experiments: false, } }, gpu: super::GpuLimit { @@ -167,8 +195,10 @@ impl Default for Base { clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(4500) }), clock_step: Some(100), skip_resume_reclock: false, + ..Default::default() }; 16], // 8 cores with SMTx2 global_governors: true, + experiments: false, } }, gpu: super::GpuLimit { @@ -209,8 +239,10 @@ impl Default for Base { clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(4700) }), clock_step: Some(100), skip_resume_reclock: false, + ..Default::default() }; 16], // 8 cores with SMTx2 global_governors: true, + experiments: false, } }, gpu: super::GpuLimit { @@ -251,8 +283,10 @@ impl Default for Base { clock_max: Some(super::RangeLimit { min: Some(400), max: Some(5100) }), clock_step: Some(100), skip_resume_reclock: false, + ..Default::default() }; 16], // 8 cores with SMTx2 global_governors: true, + experiments: false, } }, gpu: super::GpuLimit { diff --git a/backend/limits_core/src/json_v2/battery_limit.rs b/backend/limits_core/src/json_v2/battery_limit.rs index 4986283..d0d4890 100644 --- a/backend/limits_core/src/json_v2/battery_limit.rs +++ b/backend/limits_core/src/json_v2/battery_limit.rs @@ -10,6 +10,7 @@ pub enum BatteryLimitType { SteamDeckAdvance, Generic, Unknown, + DevMode, } #[derive(Serialize, Deserialize, Debug, Clone, Default)] @@ -18,12 +19,14 @@ pub struct GenericBatteryLimit { pub charge_modes: Vec, pub charge_limit: Option>, // battery charge % pub extra_readouts: bool, + pub experiments: bool, } impl GenericBatteryLimit { pub fn default_for(t: BatteryLimitType) -> Self { match t { BatteryLimitType::SteamDeck | BatteryLimitType::SteamDeckAdvance => Self::default_steam_deck(), + BatteryLimitType::DevMode => Self::default_dev_mode(), _t => Self::default(), } } @@ -44,6 +47,27 @@ impl GenericBatteryLimit { max: Some(90.0), }), extra_readouts: false, + experiments: false, + } + } + + fn default_dev_mode() -> Self { + Self { + charge_rate: Some(RangeLimit { + min: Some(0), + max: Some(1_000), + }), + charge_modes: vec![ + "normal".to_owned(), + "discharge".to_owned(), + "idle".to_owned(), + ], + charge_limit: Some(RangeLimit { + min: Some(1.0), + max: Some(99.0), + }), + extra_readouts: true, + experiments: true, } } @@ -67,5 +91,6 @@ impl GenericBatteryLimit { } } self.extra_readouts = limit_override.extra_readouts; + self.experiments = limit_override.experiments; } } diff --git a/backend/limits_core/src/json_v2/cpu_limit.rs b/backend/limits_core/src/json_v2/cpu_limit.rs index b2621d7..e391078 100644 --- a/backend/limits_core/src/json_v2/cpu_limit.rs +++ b/backend/limits_core/src/json_v2/cpu_limit.rs @@ -12,12 +12,14 @@ pub enum CpuLimitType { Generic, GenericAMD, Unknown, + DevMode, } #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct GenericCpusLimit { pub cpus: Vec, pub global_governors: bool, + pub experiments: bool, } impl GenericCpusLimit { @@ -27,6 +29,14 @@ impl GenericCpusLimit { Self { cpus: [(); 8].iter().enumerate().map(|(i, _)| GenericCpuLimit::default_for(&t, i)).collect(), global_governors: true, + experiments: false, + } + }, + CpuLimitType::DevMode => { + Self { + cpus: [(); 11].iter().enumerate().map(|(i, _)| GenericCpuLimit::default_for(&t, i)).collect(), + global_governors: true, + experiments: true, } }, t => { @@ -38,6 +48,7 @@ impl GenericCpusLimit { Self { cpus, global_governors: true, + experiments: false, } } } @@ -65,6 +76,7 @@ impl GenericCpusLimit { .for_each(|(cpu, limit_override)| cpu.apply_override(limit_override)); } self.global_governors = limit_override.global_governors; + self.experiments = limit_override.experiments; } } @@ -73,18 +85,39 @@ pub struct GenericCpuLimit { pub clock_min: Option>, pub clock_max: Option>, pub clock_step: Option, + pub tdp: Option>, + pub tdp_boost: Option>, + pub tdp_divisor: Option, + pub tdp_step: Option, pub skip_resume_reclock: bool, + pub experiments: bool, } impl GenericCpuLimit { pub fn default_for(t: &CpuLimitType, _index: usize) -> Self { match t { CpuLimitType::SteamDeck | CpuLimitType::SteamDeckAdvance => Self::default_steam_deck(), + CpuLimitType::DevMode => Self { + clock_min: Some(RangeLimit { min: Some(100), max: Some(5000) }), + clock_max: Some(RangeLimit { min: Some(100), max: Some(4800) }), + clock_step: Some(100), + tdp: Some(RangeLimit { min: Some(1_000_000), max: Some(100_000_000) }), + tdp_boost: Some(RangeLimit { min: Some(1_000_000), max: Some(110_000_000) }), + tdp_divisor: Some(1_000_000), + tdp_step: Some(1), + skip_resume_reclock: false, + experiments: true, + }, _ => Self { clock_min: None, clock_max: None, clock_step: Some(100), + tdp: None, + tdp_boost: None, + tdp_divisor: None, + tdp_step: None, skip_resume_reclock: false, + experiments: false, }, } } @@ -100,7 +133,12 @@ impl GenericCpuLimit { max: Some(3500), }), clock_step: Some(100), + tdp: None, + tdp_boost: None, + tdp_divisor: None, + tdp_step: None, skip_resume_reclock: false, + experiments: false, } } @@ -124,5 +162,6 @@ impl GenericCpuLimit { } self.clock_step = limit_override.clock_step; self.skip_resume_reclock = limit_override.skip_resume_reclock; + self.experiments = limit_override.experiments; } } diff --git a/backend/limits_core/src/json_v2/gpu_limit.rs b/backend/limits_core/src/json_v2/gpu_limit.rs index 39643ff..1662149 100644 --- a/backend/limits_core/src/json_v2/gpu_limit.rs +++ b/backend/limits_core/src/json_v2/gpu_limit.rs @@ -8,11 +8,12 @@ pub enum GpuLimitType { SteamDeck, #[serde(rename = "GabeBoyAdvance", alias = "SteamDeckAdvance")] SteamDeckAdvance, - #[serde(rename = "GabeBoy101", alias = "SteamDeckOLED")] + #[serde(rename = "GabeBoySP", alias = "SteamDeckOLED")] SteamDeckOLED, Generic, GenericAMD, Unknown, + DevMode, } #[derive(Serialize, Deserialize, Debug, Clone, Default)] @@ -25,6 +26,7 @@ pub struct GenericGpuLimit { pub ppt_step: Option, pub tdp: Option>, pub tdp_boost: Option>, + pub tdp_divisor: Option, pub tdp_step: Option, pub clock_min: Option>, pub clock_max: Option>, @@ -32,6 +34,7 @@ pub struct GenericGpuLimit { pub memory_clock: Option>, pub memory_clock_step: Option, pub skip_resume_reclock: bool, + pub experiments: bool, } impl GenericGpuLimit { @@ -39,6 +42,7 @@ impl GenericGpuLimit { match t { GpuLimitType::SteamDeck | GpuLimitType::SteamDeckAdvance => Self::default_steam_deck(), GpuLimitType::SteamDeckOLED => Self::default_steam_deck_oled(), + GpuLimitType::DevMode => Self::default_dev_mode(), _t => Self::default(), } } @@ -59,6 +63,7 @@ impl GenericGpuLimit { ppt_step: Some(1), tdp: None, tdp_boost: None, + tdp_divisor: None, tdp_step: None, clock_min: Some(RangeLimit { min: Some(400), @@ -78,6 +83,7 @@ impl GenericGpuLimit { memory_clock: None, memory_clock_step: None, skip_resume_reclock: false, + experiments: false, } } @@ -87,6 +93,43 @@ impl GenericGpuLimit { sd } + fn default_dev_mode() -> Self { + Self { + fast_ppt: Some(RangeLimit { + min: Some(3_000_000), + max: Some(11_000_000), + }), + fast_ppt_default: Some(10_000_000), + slow_ppt: Some(RangeLimit { + min: Some(7_000_000), + max: Some(11_000_000), + }), + slow_ppt_default: Some(10_000_000), + ppt_divisor: Some(1_000_000), + ppt_step: Some(1), + tdp: Some(RangeLimit { min: Some(1_000_000), max: Some(100_000_000) }), + tdp_boost: Some(RangeLimit { min: Some(1_000_000), max: Some(110_000_000) }), + tdp_divisor: Some(1_000_000), + tdp_step: Some(1), + clock_min: Some(RangeLimit { + min: Some(100), + max: Some(1000), + }), + clock_max: Some(RangeLimit { + min: Some(100), + max: Some(1100), + }), + clock_step: Some(100), + memory_clock: Some(RangeLimit { + min: Some(100), + max: Some(1100), + }), + memory_clock_step: Some(100), + skip_resume_reclock: false, + experiments: true, + } + } + pub fn apply_override(&mut self, limit_override: Self) { if let Some(range) = limit_override.fast_ppt { if range.min.is_none() && range.max.is_none() { @@ -149,5 +192,6 @@ impl GenericGpuLimit { self.clock_step = Some(val); } self.skip_resume_reclock = limit_override.skip_resume_reclock; + self.experiments = limit_override.experiments; } } diff --git a/backend/src/persist/driver.rs b/backend/src/persist/driver.rs index 1a774bd..56f50d6 100644 --- a/backend/src/persist/driver.rs +++ b/backend/src/persist/driver.rs @@ -17,4 +17,6 @@ pub enum DriverJson { #[default] #[serde(rename = "auto")] AutoDetect, + #[serde(rename = "indev")] + DevMode, } diff --git a/backend/src/settings/detect/auto_detect.rs b/backend/src/settings/detect/auto_detect.rs index d21e502..a9f8b92 100644 --- a/backend/src/settings/detect/auto_detect.rs +++ b/backend/src/settings/detect/auto_detect.rs @@ -185,6 +185,13 @@ pub fn auto_detect0( settings.version, relevant_limits.cpu.limits, )) + }, + CpuLimitType::DevMode => { + Box::new(crate::settings::dev_mode::Cpus::from_json_and_limits( + settings.cpus.clone(), + settings.version, + relevant_limits.cpu.limits, + )) } }; @@ -230,6 +237,13 @@ pub fn auto_detect0( settings.version, relevant_limits.gpu.limits, )) + }, + GpuLimitType::DevMode => { + Box::new(crate::settings::dev_mode::Gpu::from_json_and_limits( + settings.gpu.clone(), + settings.version, + relevant_limits.gpu.limits, + )) } }; let battery_driver: Box = match relevant_limits.battery.provider { @@ -260,6 +274,13 @@ pub fn auto_detect0( settings.version, relevant_limits.battery.limits, )) + }, + BatteryLimitType::DevMode => { + Box::new(crate::settings::dev_mode::Battery::from_json_and_limits( + settings.battery.clone(), + settings.version, + relevant_limits.battery.limits, + )) } }; @@ -288,6 +309,9 @@ pub fn auto_detect0( CpuLimitType::Unknown => { Box::new(crate::settings::unknown::Cpus::from_limits(relevant_limits.cpu.limits)) } + CpuLimitType::DevMode => { + Box::new(crate::settings::dev_mode::Cpus::from_limits(relevant_limits.cpu.limits)) + } }; let gpu_driver: Box = match relevant_limits.gpu.provider { GpuLimitType::SteamDeck => { @@ -308,6 +332,9 @@ pub fn auto_detect0( GpuLimitType::Unknown => { Box::new(crate::settings::unknown::Gpu::from_limits(relevant_limits.gpu.limits)) } + GpuLimitType::DevMode => { + Box::new(crate::settings::dev_mode::Gpu::from_limits(relevant_limits.gpu.limits)) + } }; let battery_driver: Box = match relevant_limits.battery.provider { BatteryLimitType::SteamDeck => { @@ -322,6 +349,9 @@ pub fn auto_detect0( BatteryLimitType::Unknown => { Box::new(crate::settings::unknown::Battery::from_limits(relevant_limits.battery.limits)) } + BatteryLimitType::DevMode => { + Box::new(crate::settings::dev_mode::Battery::from_limits(relevant_limits.battery.limits)) + } }; return Driver { general: general_driver, diff --git a/backend/src/settings/dev_mode/battery.rs b/backend/src/settings/dev_mode/battery.rs new file mode 100644 index 0000000..ac7cf79 --- /dev/null +++ b/backend/src/settings/dev_mode/battery.rs @@ -0,0 +1,146 @@ +use std::convert::Into; + +use limits_core::json_v2::GenericBatteryLimit; + +use crate::persist::BatteryJson; +use crate::settings::{TBattery, ProviderBuilder}; +use crate::settings::{OnResume, OnSet, SettingError}; + +#[derive(Clone)] +pub struct Battery { + persist: BatteryJson, + version: u64, + limits: GenericBatteryLimit, + charge_limit: Option, +} + +impl std::fmt::Debug for Battery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("dev_mode_Battery") + //.field("persist", &self.persist) + .field("version", &self.version) + .field("limits", &self.limits) + .finish_non_exhaustive() + } +} + +impl Into for Battery { + #[inline] + fn into(self) -> BatteryJson { + self.persist + } +} + +impl ProviderBuilder for Battery { + fn from_json_and_limits(persist: BatteryJson, version: u64, limits: GenericBatteryLimit) -> Self { + Battery { + persist, + version, + limits, + charge_limit: None, + } + } + + fn from_limits(limits: GenericBatteryLimit) -> Self { + Battery { + persist: BatteryJson { charge_rate: None, charge_mode: None, events: vec![], root: None }, + version: 0, + limits, + charge_limit: None, + } + } +} + +impl OnSet for Battery { + fn on_set(&mut self) -> Result<(), Vec> { + log::debug!("dev_mode_Battery::on_set(self)"); + Ok(()) + } +} + +impl OnResume for Battery { + fn on_resume(&self) -> Result<(), Vec> { + log::debug!("dev_mode_Battery::on_resume(self)"); + Ok(()) + } +} + +impl crate::settings::OnPowerEvent for Battery {} + +impl TBattery for Battery { + fn limits(&self) -> crate::api::BatteryLimits { + log::debug!("dev_mode_Battery::limits(self) -> {{...}}"); + crate::api::BatteryLimits { + charge_current: self.limits.charge_rate.map(|lim| crate::api::RangeLimit { min: lim.min.unwrap_or(11), max: lim.max.unwrap_or(1111) }), + charge_current_step: 10, + charge_modes: self.limits.charge_modes.clone(), + charge_limit: self.limits.charge_limit.map(|lim| crate::api::RangeLimit { min: lim.min.unwrap_or(2.0), max: lim.max.unwrap_or(98.0) }), + charge_limit_step: 1.0, + } + } + + fn json(&self) -> crate::persist::BatteryJson { + log::debug!("dev_mode_Battery::json(self) -> {{...}}"); + self.clone().into() + } + + fn charge_rate(&mut self, rate: Option) { + log::debug!("dev_mode_Battery::charge_rate(self, {:?})", rate); + self.persist.charge_rate = rate; + } + + fn get_charge_rate(&self) -> Option { + log::debug!("dev_mode_Battery::get_charge_rate(self) -> {:?}", self.persist.charge_rate); + self.persist.charge_rate + } + + fn charge_mode(&mut self, rate: Option) { + log::debug!("dev_mode_Battery::charge_mode(self, {:?})", rate); + self.persist.charge_mode = rate; + } + + fn get_charge_mode(&self) -> Option { + log::debug!("dev_mode_Battery::get_charge_mode(self) -> {:?}", self.persist.charge_mode); + self.persist.charge_mode.clone() + } + + fn read_charge_full(&self) -> Option { + log::debug!("dev_mode_Battery::read_charge_full(self) -> None"); + None + } + + fn read_charge_now(&self) -> Option { + log::debug!("dev_mode_Battery::read_charge_now(self) -> None"); + None + } + + fn read_charge_design(&self) -> Option { + log::debug!("dev_mode_Battery::read_charge_design(self) -> None"); + None + } + + fn read_current_now(&self) -> Option { + log::debug!("dev_mode_Battery::read_current_now(self) -> None"); + None + } + + fn read_charge_power(&self) -> Option { + log::debug!("dev_mode_Battery::read_charge_power(self) -> None"); + None + } + + fn charge_limit(&mut self, limit: Option) { + log::debug!("dev_mode_Battery::charge_limit(self, {:?})", limit); + self.charge_limit = limit; + } + + fn get_charge_limit(&self) -> Option { + log::debug!("dev_mode_Battery::get_charge_limit(self) -> {:?}", self.charge_limit); + self.charge_limit + } + + fn provider(&self) -> crate::persist::DriverJson { + log::debug!("dev_mode_Battery::provider(self) -> DevMode"); + crate::persist::DriverJson::DevMode + } +} diff --git a/backend/src/settings/dev_mode/cpu.rs b/backend/src/settings/dev_mode/cpu.rs new file mode 100644 index 0000000..c278fe1 --- /dev/null +++ b/backend/src/settings/dev_mode/cpu.rs @@ -0,0 +1,221 @@ +use std::convert::Into; + +use limits_core::json_v2::{GenericCpusLimit, GenericCpuLimit}; + +use crate::persist::CpuJson; +use crate::settings::MinMax; +use crate::settings::{OnResume, OnSet, SettingError}; +use crate::settings::{TCpu, TCpus, ProviderBuilder}; + +#[derive(Debug, Clone)] +pub struct Cpus { + cpus: Vec, + #[allow(dead_code)] + version: u64, + smt_enabled: bool, + #[allow(dead_code)] + limits: GenericCpusLimit, +} + +impl OnSet for Cpus { + fn on_set(&mut self) -> Result<(), Vec> { + log::debug!("dev_mode_Cpus::on_set(self)"); + for cpu in self.cpus.iter_mut() { + cpu.on_set()?; + } + Ok(()) + } +} + +impl OnResume for Cpus { + fn on_resume(&self) -> Result<(), Vec> { + log::debug!("dev_mode_Cpus::on_resume(self)"); + for cpu in self.cpus.iter() { + cpu.on_resume()?; + } + Ok(()) + } +} + +impl crate::settings::OnPowerEvent for Cpus {} + +impl ProviderBuilder, GenericCpusLimit> for Cpus { + fn from_json_and_limits(persistent: Vec, version: u64, limits: GenericCpusLimit) -> Self { + let mut cpus = Vec::with_capacity(persistent.len()); + for (i, cpu) in persistent.iter().enumerate() { + cpus.push(Cpu::from_json_and_limits(cpu.to_owned(), version, i, limits.cpus.get(i).map(|x| x.to_owned()).unwrap_or_else(|| { + log::warn!("No cpu limit for index {}, using default", i); + Default::default() + }))); + } + let smt_guess = crate::settings::util::guess_smt(&persistent); + Self { + cpus, + version, + smt_enabled: smt_guess, + limits, + } + } + + fn from_limits(limits: GenericCpusLimit) -> Self { + let mut cpus = Vec::with_capacity(limits.cpus.len()); + for (i, cpu) in limits.cpus.iter().enumerate() { + cpus.push(Cpu::from_limits(i, cpu.to_owned())); + } + Self { + cpus, + version: 0, + smt_enabled: true, + limits, + } + } +} + +impl TCpus for Cpus { + fn limits(&self) -> crate::api::CpusLimits { + log::debug!("dev_mode_Cpus::limits(self) -> {{...}}"); + crate::api::CpusLimits { + cpus: self.cpus.iter().map(|x| x.limits()).collect(), + count: self.cpus.len(), + smt_capable: true, + governors: vec!["this".to_owned(), "is".to_owned(), "dev".to_owned(), "mode".to_owned()], + } + } + + fn json(&self) -> Vec { + log::debug!("dev_mode_Cpus::json(self) -> {{...}}"); + self.cpus.iter().map(|x| x.to_owned().into()).collect() + } + + fn cpus(&mut self) -> Vec<&mut dyn TCpu> { + log::debug!("dev_mode_Cpus::cpus(self) -> {{...}}"); + self.cpus.iter_mut().map(|x| x as &mut dyn TCpu).collect() + } + + fn len(&self) -> usize { + log::debug!("dev_mode_Cpus::len(self) -> {}", self.cpus.len()); + self.cpus.len() + } + + fn smt(&mut self) -> &'_ mut bool { + log::debug!("dev_mode_Cpus::smt(self) -> {}", self.smt_enabled); + &mut self.smt_enabled + } + + fn provider(&self) -> crate::persist::DriverJson { + log::debug!("dev_mode_Cpus::provider(self) -> DevMode"); + crate::persist::DriverJson::DevMode + } +} + +#[derive(Clone)] +pub struct Cpu { + persist: CpuJson, + version: u64, + index: usize, + limits: GenericCpuLimit, + clock_limits: Option>, +} + +impl std::fmt::Debug for Cpu { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("dev_mode_Cpu") + //.field("persist", &self.persist) + .field("version", &self.version) + .field("index", &self.index) + .field("limits", &self.limits) + .finish_non_exhaustive() + } +} + +impl Cpu { + #[inline] + pub fn from_json_and_limits(other: CpuJson, version: u64, i: usize, limits: GenericCpuLimit) -> Self { + let clock_limits = other.clock_limits.clone().map(|lim| MinMax { min: lim.min, max: lim.max }); + match version { + 0 => Self { + persist: other, + version, + index: i, + limits, + clock_limits, + }, + _ => Self { + persist: other, + version, + index: i, + limits, + clock_limits, + }, + } + } + + #[inline] + pub fn from_limits(i: usize, limits: GenericCpuLimit) -> Self { + Self { + persist: CpuJson { online: true, clock_limits: None, governor: "".to_owned(), root: None }, + version: 0, + index: i, + limits, + clock_limits: None, + } + } + + fn limits(&self) -> crate::api::CpuLimits { + crate::api::CpuLimits { + clock_min_limits: self.limits.clock_min.map(|lim| crate::api::RangeLimit { min: lim.min.unwrap_or(1100), max: lim.max.unwrap_or(6900) }), + clock_max_limits: self.limits.clock_max.map(|lim| crate::api::RangeLimit { min: lim.min.unwrap_or(4200), max: lim.max.unwrap_or(4300) }), + clock_step: self.limits.clock_step.unwrap_or(11), + governors: vec!["this".to_owned(), "is".to_owned(), "dev".to_owned(), "mode".to_owned()], + } + } +} + +impl Into for Cpu { + #[inline] + fn into(self) -> CpuJson { + self.persist + } +} + +impl OnSet for Cpu { + fn on_set(&mut self) -> Result<(), Vec> { + log::debug!("dev_mode_Cpu::on_set(self)"); + Ok(()) + } +} + +impl OnResume for Cpu { + fn on_resume(&self) -> Result<(), Vec> { + log::debug!("dev_mode_Cpu::on_resume(self)"); + Ok(()) + } +} + +impl TCpu for Cpu { + fn online(&mut self) -> &mut bool { + log::debug!("dev_mode_Cpu::online(self) -> {}", self.persist.online); + &mut self.persist.online + } + + fn governor(&mut self, governor: String) { + log::debug!("dev_mode_Cpu::governor(self, {})", governor); + self.persist.governor = governor; + } + + fn get_governor(&self) -> &'_ str { + log::debug!("dev_mode_Cpu::governor(self) -> {}", self.persist.governor); + &self.persist.governor + } + + fn clock_limits(&mut self, limits: Option>) { + log::debug!("dev_mode_Cpu::clock_limits(self, {:?})", limits); + self.clock_limits = limits; + self.persist.clock_limits = self.clock_limits.clone().map(|lim| crate::persist::MinMaxJson { max: lim.max, min: lim.min }); + } + + fn get_clock_limits(&self) -> Option<&MinMax> { + log::debug!("dev_mode_Cpu::get_clock_limits(self) -> {:?}", self.clock_limits.as_ref()); + self.clock_limits.as_ref() + } +} diff --git a/backend/src/settings/dev_mode/gpu.rs b/backend/src/settings/dev_mode/gpu.rs new file mode 100644 index 0000000..b9f6e76 --- /dev/null +++ b/backend/src/settings/dev_mode/gpu.rs @@ -0,0 +1,141 @@ +use std::convert::Into; + +use limits_core::json_v2::GenericGpuLimit; + +use crate::persist::GpuJson; +use crate::settings::MinMax; +use crate::settings::{TGpu, ProviderBuilder}; +use crate::settings::{OnResume, OnSet, SettingError}; + +#[derive(Clone)] +pub struct Gpu { + persist: GpuJson, + version: u64, + limits: GenericGpuLimit, + clock_limits: Option>, +} + +impl std::fmt::Debug for Gpu { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("dev_mode_Gpu") + //.field("persist", &self.persist) + .field("version", &self.version) + .field("limits", &self.limits) + .finish_non_exhaustive() + } +} + +impl ProviderBuilder for Gpu { + fn from_json_and_limits(persist: GpuJson, version: u64, limits: GenericGpuLimit) -> Self { + let clock_limits = persist.clock_limits.clone().map(|lim| MinMax { min: lim.min, max: lim.max }); + Self { + persist, + version, + limits, + clock_limits, + } + } + + fn from_limits(limits: GenericGpuLimit) -> Self { + Self { + persist: GpuJson { + fast_ppt: None, + slow_ppt: None, + tdp: None, + tdp_boost: None, + clock_limits: None, + memory_clock: None, + root: None, + }, + version: 0, + limits, + clock_limits: None, + } + } +} + +impl Into for Gpu { + #[inline] + fn into(self) -> GpuJson { + self.persist + } +} + +impl OnSet for Gpu { + fn on_set(&mut self) -> Result<(), Vec> { + log::debug!("dev_mode_Gpu::on_set(self)"); + Ok(()) + } +} + +impl OnResume for Gpu { + fn on_resume(&self) -> Result<(), Vec> { + log::debug!("dev_mode_Gpu::on_resume(self)"); + Ok(()) + } +} + +impl crate::settings::OnPowerEvent for Gpu {} + +impl TGpu for Gpu { + fn limits(&self) -> crate::api::GpuLimits { + log::debug!("dev_mode_Gpu::limits(self) -> {{...}}"); + let ppt_divisor = self.limits.ppt_divisor.unwrap_or(1_000_000); + let tdp_divisor = self.limits.tdp_divisor.unwrap_or(1_000_000); + crate::api::GpuLimits { + fast_ppt_limits: self.limits.fast_ppt.map(|lim| crate::api::RangeLimit { min: lim.min.unwrap_or(11_000_000) / ppt_divisor, max: lim.max.unwrap_or(42_000_000) / ppt_divisor }), + slow_ppt_limits: self.limits.slow_ppt.map(|lim| crate::api::RangeLimit { min: lim.min.unwrap_or(7_000_000) / ppt_divisor, max: lim.max.unwrap_or(69_000_000) / ppt_divisor }), + ppt_step: self.limits.ppt_step.unwrap_or(1), + tdp_limits: self.limits.tdp.map(|lim| crate::api::RangeLimit { min: lim.min.unwrap_or(11_000_000) / tdp_divisor, max: lim.max.unwrap_or(69_000_000) / tdp_divisor }), + tdp_boost_limits: self.limits.tdp_boost.map(|lim| crate::api::RangeLimit { min: lim.min.unwrap_or(7_000_000) / tdp_divisor, max: lim.max.unwrap_or(69_000_000) / tdp_divisor }), + tdp_step: self.limits.tdp_step.unwrap_or(1), + clock_min_limits: self.limits.clock_min.map(|lim| crate::api::RangeLimit { min: lim.min.unwrap_or(1100), max: lim.max.unwrap_or(6900) }), + clock_max_limits: self.limits.clock_max.map(|lim| crate::api::RangeLimit { min: lim.min.unwrap_or(1100), max: lim.max.unwrap_or(4200) }), + clock_step: self.limits.clock_step.unwrap_or(100), + memory_control: self.limits.memory_clock.map(|lim| crate::api::RangeLimit { min: lim.min.unwrap_or(100), max: lim.max.unwrap_or(1100) }), + memory_step: self.limits.memory_clock_step.unwrap_or(400), + } + } + + fn json(&self) -> crate::persist::GpuJson { + log::debug!("dev_mode_Gpu::json(self) -> {{...}}"); + self.clone().into() + } + + fn ppt(&mut self, fast: Option, slow: Option) { + log::debug!("dev_mode_Gpu::ppt(self, fast: {:?}, slow: {:?})", fast, slow); + self.persist.fast_ppt = fast; + self.persist.slow_ppt = slow; + } + + fn get_ppt(&self) -> (Option, Option) { + log::debug!("dev_mode_Gpu::get_ppt(self) -> (fast: {:?}, slow: {:?})", self.persist.fast_ppt, self.persist.slow_ppt); + (self.persist.fast_ppt, self.persist.slow_ppt) + } + + fn clock_limits(&mut self, limits: Option>) { + log::debug!("dev_mode_Gpu::clock_limits(self, {:?})", limits); + self.clock_limits = limits; + self.persist.clock_limits = self.clock_limits.clone().map(|lim| crate::persist::MinMaxJson { max: lim.max, min: lim.min }); + } + + fn get_clock_limits(&self) -> Option<&MinMax> { + log::debug!("dev_mode_Gpu::get_clock_limits(self) -> {:?}", self.clock_limits.as_ref()); + self.clock_limits.as_ref() + } + + fn memory_clock(&mut self, speed: Option) { + log::debug!("dev_mode_Gpu::memory_clock(self, {:?})", speed); + self.persist.memory_clock = speed; + } + + fn get_memory_clock(&self) -> Option { + log::debug!("dev_mode_Gpu::memory_clock(self) -> {:?}", self.persist.memory_clock); + self.persist.memory_clock + } + + fn provider(&self) -> crate::persist::DriverJson { + log::debug!("dev_mode_Gpu::provider(self) -> DevMode"); + crate::persist::DriverJson::DevMode + } +} diff --git a/backend/src/settings/dev_mode/mod.rs b/backend/src/settings/dev_mode/mod.rs new file mode 100644 index 0000000..200c1ea --- /dev/null +++ b/backend/src/settings/dev_mode/mod.rs @@ -0,0 +1,15 @@ +mod battery; +mod cpu; +mod gpu; + +pub use battery::Battery; +pub use cpu::Cpus; +pub use gpu::Gpu; + +fn _impl_checker() { + fn impl_provider_builder, J, L>() {} + + impl_provider_builder::(); + impl_provider_builder::, limits_core::json_v2::GenericCpusLimit>(); + impl_provider_builder::(); +} diff --git a/backend/src/settings/driver.rs b/backend/src/settings/driver.rs index 6f94fff..73eb1f1 100644 --- a/backend/src/settings/driver.rs +++ b/backend/src/settings/driver.rs @@ -37,5 +37,6 @@ pub fn maybe_do_button() { } DriverJson::Unknown => log::warn!("Can't do button activities on unknown platform"), DriverJson::AutoDetect => log::warn!("WTF, why is auto_detect detecting AutoDetect???"), + DriverJson::DevMode => log::error!("Hello dev world!"), } } diff --git a/backend/src/settings/mod.rs b/backend/src/settings/mod.rs index 5bcb3f4..e18fa4b 100644 --- a/backend/src/settings/mod.rs +++ b/backend/src/settings/mod.rs @@ -10,6 +10,7 @@ pub mod generic; pub mod generic_amd; pub mod steam_deck; pub mod unknown; +pub mod dev_mode; pub use detect::{auto_detect0, auto_detect_provider, limits_worker::spawn as limits_worker_spawn, get_dev_messages}; pub use driver::Driver; @@ -23,7 +24,7 @@ pub use traits::{OnPowerEvent, OnResume, OnSet, PowerMode, TBattery, TCpu, TCpus mod tests { #[test] fn system_defaults_test() { - let settings = super::Settings::system_default("idc".into(), "Cool name".into(), 0, "Variant 0".into()); + let settings = super::Settings::system_default("idc".into(), 0, "Cool name".into(), 0, "Variant 0".into()); println!("Loaded system settings: {:?}", settings); } }