power: Expose TDP limit range as platform config

This commit is contained in:
Vicki Pfau 2024-08-27 21:57:50 -07:00
parent 36e88484a4
commit 7c3f2baa05
5 changed files with 46 additions and 7 deletions

View file

@ -19,3 +19,7 @@ no_validate_flag = "--skip-validation"
[fan_control] [fan_control]
systemd = "jupiter-fan-control.service" systemd = "jupiter-fan-control.service"
[tdp_limit]
min = 3
max = 15

View file

@ -369,6 +369,7 @@ pub mod test {
fan_control: Some(ServiceConfig::Systemd(String::from( fan_control: Some(ServiceConfig::Systemd(String::from(
"jupiter-fan-control.service", "jupiter-fan-control.service",
))), ))),
tdp_limit: None,
})); }));
let fan_control = FanControl::new(connection); let fan_control = FanControl::new(connection);

View file

@ -27,6 +27,7 @@ use crate::power::{
get_available_cpu_scaling_governors, get_available_gpu_performance_levels, get_available_cpu_scaling_governors, get_available_gpu_performance_levels,
get_available_gpu_power_profiles, get_cpu_scaling_governor, get_gpu_clocks, get_available_gpu_power_profiles, get_cpu_scaling_governor, get_gpu_clocks,
get_gpu_clocks_range, get_gpu_performance_level, get_gpu_power_profile, get_tdp_limit, get_gpu_clocks_range, get_gpu_performance_level, get_gpu_power_profile, get_tdp_limit,
get_tdp_limit_range,
}; };
use crate::wifi::{get_wifi_backend, get_wifi_power_management_state, list_wifi_interfaces}; use crate::wifi::{get_wifi_backend, get_wifi_power_management_state, list_wifi_interfaces};
use crate::API_VERSION; use crate::API_VERSION;
@ -418,8 +419,8 @@ impl Storage1 {
#[interface(name = "com.steampowered.SteamOSManager1.TdpLimit1")] #[interface(name = "com.steampowered.SteamOSManager1.TdpLimit1")]
impl TdpLimit1 { impl TdpLimit1 {
#[zbus(property(emits_changed_signal = "false"))] #[zbus(property(emits_changed_signal = "false"))]
async fn tdp_limit(&self) -> fdo::Result<u32> { async fn tdp_limit(&self) -> u32 {
get_tdp_limit().await.map_err(to_zbus_fdo_error) get_tdp_limit().await.unwrap_or(0)
} }
#[zbus(property)] #[zbus(property)]
@ -429,14 +430,18 @@ impl TdpLimit1 {
#[zbus(property(emits_changed_signal = "const"))] #[zbus(property(emits_changed_signal = "const"))]
async fn tdp_limit_min(&self) -> u32 { async fn tdp_limit_min(&self) -> u32 {
// TODO: Can this be queried from somewhere? get_tdp_limit_range()
3 .await
.and_then(|(min, _)| Ok(min))
.unwrap_or(0)
} }
#[zbus(property(emits_changed_signal = "const"))] #[zbus(property(emits_changed_signal = "const"))]
async fn tdp_limit_max(&self) -> u32 { async fn tdp_limit_max(&self) -> u32 {
// TODO: Can this be queried from somewhere? get_tdp_limit_range()
15 .await
.and_then(|(_, max)| Ok(max))
.unwrap_or(0)
} }
} }
@ -661,7 +666,9 @@ mod test {
use crate::daemon::user::UserContext; use crate::daemon::user::UserContext;
use crate::hardware::test::fake_model; use crate::hardware::test::fake_model;
use crate::hardware::HardwareVariant; use crate::hardware::HardwareVariant;
use crate::platform::{PlatformConfig, ScriptConfig, ServiceConfig, StorageConfig}; use crate::platform::{
PlatformConfig, RangeConfig, ScriptConfig, ServiceConfig, StorageConfig,
};
use crate::systemd::test::{MockManager, MockUnit}; use crate::systemd::test::{MockManager, MockUnit};
use crate::{power, testing}; use crate::{power, testing};
@ -684,6 +691,7 @@ mod test {
fan_control: Some(ServiceConfig::Systemd(String::from( fan_control: Some(ServiceConfig::Systemd(String::from(
"jupiter-fan-control.service", "jupiter-fan-control.service",
))), ))),
tdp_limit: Some(RangeConfig::new(3, 15)),
}) })
} }

View file

@ -26,8 +26,17 @@ pub(crate) struct PlatformConfig {
pub update_dock: Option<ScriptConfig>, pub update_dock: Option<ScriptConfig>,
pub storage: Option<StorageConfig>, pub storage: Option<StorageConfig>,
pub fan_control: Option<ServiceConfig>, pub fan_control: Option<ServiceConfig>,
pub tdp_limit: Option<RangeConfig<u32>>,
} }
#[derive(Clone, Deserialize, Debug)]
pub(crate) struct RangeConfig<T: Clone> {
pub min: T,
pub max: T,
}
impl<T> Copy for RangeConfig<T> where T: Copy {}
#[derive(Clone, Default, Deserialize, Debug)] #[derive(Clone, Default, Deserialize, Debug)]
pub(crate) struct ScriptConfig { pub(crate) struct ScriptConfig {
pub script: PathBuf, pub script: PathBuf,
@ -67,6 +76,13 @@ pub(crate) struct FormatDeviceConfig {
pub no_validate_flag: Option<String>, pub no_validate_flag: Option<String>,
} }
impl<T: Clone> RangeConfig<T> {
#[allow(unused)]
pub(crate) fn new(min: T, max: T) -> RangeConfig<T> {
RangeConfig { min, max }
}
}
impl PlatformConfig { impl PlatformConfig {
#[cfg(not(test))] #[cfg(not(test))]
async fn load() -> Result<Option<PlatformConfig>> { async fn load() -> Result<Option<PlatformConfig>> {

View file

@ -16,6 +16,7 @@ use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
use tracing::{error, warn}; use tracing::{error, warn};
use crate::hardware::is_deck; use crate::hardware::is_deck;
use crate::platform::platform_config;
use crate::{path, write_synced}; use crate::{path, write_synced};
const GPU_HWMON_PREFIX: &str = "/sys/class/hwmon"; const GPU_HWMON_PREFIX: &str = "/sys/class/hwmon";
@ -397,6 +398,15 @@ pub(crate) async fn set_tdp_limit(limit: u32) -> Result<()> {
Ok(()) Ok(())
} }
pub(crate) async fn get_tdp_limit_range() -> Result<(u32, u32)> {
let range = platform_config()
.await?
.as_ref()
.and_then(|config| config.tdp_limit)
.ok_or(anyhow!("No TDP limit range configured"))?;
Ok((range.min, range.max))
}
#[cfg(test)] #[cfg(test)]
pub(crate) mod test { pub(crate) mod test {
use super::*; use super::*;