Per-AC/DC per-profile tunings enabled

This commit is contained in:
Luke D. Jones
2025-01-19 11:33:48 +13:00
parent a00808313e
commit f9cebf9221
7 changed files with 149 additions and 63 deletions

View File

@@ -2,6 +2,9 @@
## [Unreleased]
### Changed
- Per-AC/DC, per-profile tunings enabled (Battery vs AC power + platform profile)
## [v6.1.0-rc4]
### Changed

View File

@@ -1,4 +1,3 @@
use std::collections::HashMap;
use std::str::FromStr;
use std::sync::Arc;
@@ -7,6 +6,7 @@ use config_traits::StdConfig;
use log::{debug, error, info};
use rog_platform::asus_armoury::{AttrValue, Attribute, FirmwareAttribute, FirmwareAttributes};
use rog_platform::platform::{RogPlatform, ThrottlePolicy};
use rog_platform::power::AsusPower;
use serde::{Deserialize, Serialize};
use zbus::object_server::SignalEmitter;
use zbus::zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Type, Value};
@@ -33,15 +33,22 @@ pub struct AsusArmouryAttribute {
attr: Attribute,
config: Arc<Mutex<Config>>,
/// platform control required here for access to PPD or Throttle profile
platform: RogPlatform
platform: RogPlatform,
power: AsusPower
}
impl AsusArmouryAttribute {
pub fn new(attr: Attribute, platform: RogPlatform, config: Arc<Mutex<Config>>) -> Self {
pub fn new(
attr: Attribute,
platform: RogPlatform,
power: AsusPower,
config: Arc<Mutex<Config>>
) -> Self {
Self {
attr,
config,
platform
platform,
power
}
}
@@ -95,7 +102,20 @@ impl crate::Reloadable for AsusArmouryAttribute {
info!("Reloading {}", self.attr.name());
let profile: ThrottlePolicy =
ThrottlePolicy::from_str(self.platform.get_platform_profile()?.as_str())?;
if let Some(tunings) = self.config.lock().await.profile_tunings.get(&profile) {
let power_plugged = self
.power
.get_online()
.map_err(|e| {
error!("Could not get power status: {e:?}");
e
})
.unwrap_or_default();
let config = if power_plugged == 1 {
&self.config.lock().await.ac_profile_tunings
} else {
&self.config.lock().await.dc_profile_tunings
};
if let Some(tunings) = config.get(&profile) {
if let Some(tune) = tunings.get(&self.name()) {
self.attr
.set_current_value(AttrValue::Integer(*tune))
@@ -214,31 +234,23 @@ impl AsusArmouryAttribute {
let profile: ThrottlePolicy =
ThrottlePolicy::from_str(self.platform.get_platform_profile()?.as_str())?;
// var here to prevent async deadlock on else clause
let has_profile = self
.config
.lock()
.await
.profile_tunings
.contains_key(&profile);
if has_profile {
if let Some(tunings) = self.config.lock().await.profile_tunings.get_mut(&profile) {
let power_plugged = self
.power
.get_online()
.map_err(|e| {
error!("Could not get power status: {e:?}");
e
})
.unwrap_or_default();
let mut config = self.config.lock().await;
let tunings = config.select_tunings(power_plugged == 1, profile);
if let Some(tune) = tunings.get_mut(&self.name()) {
*tune = value;
} else {
tunings.insert(self.name(), value);
debug!("Set tuning config for {} = {:?}", self.attr.name(), value);
}
}
} else {
debug!("Adding tuning config for {}", profile);
self.config
.lock()
.await
.profile_tunings
.insert(profile, HashMap::from([(self.name(), value)]));
debug!("Set tuning config for {} = {:?}", self.attr.name(), value);
}
} else {
let has_attr = self
.config
@@ -274,10 +286,16 @@ impl AsusArmouryAttribute {
pub async fn start_attributes_zbus(
conn: &Connection,
platform: RogPlatform,
power: AsusPower,
config: Arc<Mutex<Config>>
) -> Result<(), RogError> {
for attr in FirmwareAttributes::new().attributes() {
let mut attr = AsusArmouryAttribute::new(attr.clone(), platform.clone(), config.clone());
let mut attr = AsusArmouryAttribute::new(
attr.clone(),
platform.clone(),
power.clone(),
config.clone()
);
attr.reload().await?;
let path = dbus_path_for_attr(attr.attr.name());
@@ -288,3 +306,41 @@ pub async fn start_attributes_zbus(
}
Ok(())
}
pub async fn set_config_or_default(
attrs: &FirmwareAttributes,
config: &mut Config,
power_plugged: bool,
profile: ThrottlePolicy
) {
for attr in attrs.attributes().iter() {
let name: FirmwareAttribute = attr.name().into();
if name.is_ppt() {
let tunings = config.select_tunings(power_plugged, profile);
if let Some(tune) = tunings.get(&name) {
attr.set_current_value(AttrValue::Integer(*tune))
.map_err(|e| {
error!("Failed to set {}: {e}", <&str>::from(name));
})
.ok();
} else {
let default = attr.default_value().clone();
attr.set_current_value(default.clone())
.map_err(|e| {
error!("Failed to set {}: {e}", <&str>::from(name));
})
.ok();
if let AttrValue::Integer(i) = default {
tunings.insert(name, i);
info!(
"Set default tuning config for {} = {:?}",
<&str>::from(name),
i
);
config.write();
}
}
}
}
}

View File

@@ -7,6 +7,7 @@ use rog_platform::platform::ThrottlePolicy;
use serde::{Deserialize, Serialize};
const CONFIG_FILE: &str = "asusd.ron";
type Tunings = HashMap<ThrottlePolicy, HashMap<FirmwareAttribute, i32>>;
#[derive(Deserialize, Serialize, PartialEq)]
pub struct Config {
@@ -37,13 +38,29 @@ pub struct Config {
pub throttle_balanced_epp: CPUEPP,
/// The energy_performance_preference for this throttle/platform profile
pub throttle_performance_epp: CPUEPP,
pub profile_tunings: HashMap<ThrottlePolicy, HashMap<FirmwareAttribute, i32>>,
pub ac_profile_tunings: Tunings,
pub dc_profile_tunings: Tunings,
pub armoury_settings: HashMap<FirmwareAttribute, i32>,
/// Temporary state for AC/Batt
#[serde(skip)]
pub last_power_plugged: u8
}
impl Config {
pub fn select_tunings(
&mut self,
power_plugged: bool,
profile: ThrottlePolicy
) -> &mut HashMap<FirmwareAttribute, i32> {
let config = if power_plugged {
&mut self.ac_profile_tunings
} else {
&mut self.dc_profile_tunings
};
config.entry(profile).or_insert_with(HashMap::new)
}
}
impl Default for Config {
fn default() -> Self {
Self {
@@ -60,7 +77,8 @@ impl Default for Config {
throttle_quiet_epp: CPUEPP::Power,
throttle_balanced_epp: CPUEPP::BalancePower,
throttle_performance_epp: CPUEPP::Performance,
profile_tunings: HashMap::default(),
ac_profile_tunings: HashMap::default(),
dc_profile_tunings: HashMap::default(),
armoury_settings: HashMap::default(),
last_power_plugged: Default::default()
}
@@ -148,7 +166,8 @@ impl From<Config601> for Config {
throttle_balanced_epp: c.throttle_balanced_epp,
throttle_performance_epp: c.throttle_performance_epp,
last_power_plugged: c.last_power_plugged,
profile_tunings: HashMap::default(),
ac_profile_tunings: HashMap::default(),
dc_profile_tunings: HashMap::default(),
armoury_settings: HashMap::default()
}
}

View File

@@ -5,7 +5,7 @@ use std::sync::Arc;
use config_traits::StdConfig;
use log::{debug, error, info, warn};
use rog_platform::asus_armoury::{AttrValue, FirmwareAttribute, FirmwareAttributes};
use rog_platform::asus_armoury::FirmwareAttributes;
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
use rog_platform::platform::{Properties, RogPlatform, ThrottlePolicy};
use rog_platform::power::AsusPower;
@@ -14,6 +14,7 @@ use zbus::fdo::Error as FdoErr;
use zbus::object_server::SignalEmitter;
use zbus::{interface, Connection};
use crate::asus_armoury::set_config_or_default;
use crate::config::Config;
use crate::error::RogError;
use crate::{task_watch_item, CtrlTask, ReloadAndNotify};
@@ -661,6 +662,24 @@ impl CtrlTask for CtrlPlatform {
if platform3.power.has_charge_control_end_threshold() && !power_plugged {
platform3.restore_charge_limit().await;
}
if let Ok(profile) = platform3
.platform
.get_throttle_thermal_policy()
.map(ThrottlePolicy::from)
.map_err(|e| {
error!("Platform: get_throttle_thermal_policy error: {e}");
})
{
let attrs = FirmwareAttributes::new();
set_config_or_default(
&attrs,
&mut *platform3.config.lock().await,
power_plugged,
profile
)
.await;
}
}
}
)
@@ -698,35 +717,21 @@ impl CtrlTask for CtrlPlatform {
ctrl.throttle_thermal_policy_changed(&signal_ctxt)
.await
.ok();
for attr in attrs.attributes().iter() {
let name: FirmwareAttribute = attr.name().into();
if name.is_ppt() {
let mut do_default = false;
if let Some(tunings) =
ctrl.config.lock().await.profile_tunings.get(&profile)
{
if let Some(tune) = tunings.get(&name) {
attr.set_current_value(AttrValue::Integer(*tune))
let power_plugged = ctrl
.power
.get_online()
.map_err(|e| {
error!("Failed to set {}: {e}", <&str>::from(name));
error!("Could not get power status: {e:?}");
e
})
.ok();
} else {
do_default = true;
}
} else {
do_default = true;
}
if do_default {
let default = attr.default_value().clone();
attr.set_current_value(default)
.map_err(|e| {
error!("Failed to set {}: {e}", <&str>::from(name));
})
.ok();
}
}
}
.unwrap_or_default();
set_config_or_default(
&attrs,
&mut *ctrl.config.lock().await,
power_plugged == 1,
profile
)
.await;
}
}
}

View File

@@ -13,6 +13,7 @@ use asusd::{print_board_info, start_tasks, CtrlTask, DBUS_NAME};
use config_traits::{StdConfig, StdConfigLoad1};
use log::{error, info};
use rog_platform::platform::RogPlatform;
use rog_platform::power::AsusPower;
use zbus::fdo::ObjectManager;
#[tokio::main]
@@ -67,7 +68,8 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
// supported.add_to_server(&mut connection).await;
let platform = RogPlatform::new()?; // TODO: maybe needs async mutex?
start_attributes_zbus(&server, platform, config.clone()).await?;
let power = AsusPower::new()?; // TODO: maybe needs async mutex?
start_attributes_zbus(&server, platform, power, config.clone()).await?;
match CtrlFanCurveZbus::new() {
Ok(ctrl) => {

View File

@@ -2,7 +2,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2025-01-18 10:11+0000\n"
"POT-Creation-Date: 2025-01-18 22:33+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"

View File

@@ -178,6 +178,7 @@ impl Attribute {
}
}
#[derive(Clone)]
pub struct FirmwareAttributes {
attrs: Vec<Attribute>
}