diff --git a/src/performance/gpu/asus/asus_wmi.rs b/src/performance/gpu/asus/asus_wmi.rs index fb4988e..b2a14b0 100644 --- a/src/performance/gpu/asus/asus_wmi.rs +++ b/src/performance/gpu/asus/asus_wmi.rs @@ -1,6 +1,10 @@ use crate::performance::gpu::tdp::{TDPError, TDPResult}; -use rog_platform::{error::PlatformError, platform::RogPlatform}; +use rog_platform::{ + error::PlatformError, + firmware_attributes::{AttrValue, FirmwareAttributes}, + platform::RogPlatform, +}; impl From for TDPError { fn from(value: PlatformError) -> Self { @@ -11,6 +15,7 @@ impl From for TDPError { /// Implementation of asus-wmi sysfs /// See https://www.kernel.org/doc/html/v6.8-rc4/admin-guide/abi-testing.html#abi-sys-devices-platform-platform-ppt-apu-sppt pub struct AsusWmi { + attributes: FirmwareAttributes, platform: RogPlatform, } @@ -20,7 +25,11 @@ impl AsusWmi { match RogPlatform::new() { Ok(platform) => { log::info!("Module asus-wmi found"); - Some(Self { platform }) + let attributes = FirmwareAttributes::new(); + Some(Self { + attributes, + platform, + }) } Err(err) => { log::info!("Module asus-wmi not found: {err:?}"); @@ -31,7 +40,25 @@ impl AsusWmi { /// Returns the currently set STAPM value pub async fn tdp(&self) -> TDPResult { - Ok(self.platform.get_ppt_pl1_spl()? as f64) + let attr = self + .attributes + .attributes() + .iter() + .find(|a| a.name() == "ppt_pl1_spl"); + let Some(attr) = attr else { + return Ok(self.platform.get_ppt_pl1_spl()? as f64); + }; + + match attr.current_value() { + Ok(attr_value) => match attr_value { + AttrValue::Integer(value) => Ok(value as f64), + _ => Err(TDPError::FailedOperation("Failed to read SPL.".to_string())), + }, + Err(e) => { + let err = format!("Failed to read SPL: {e:?}"); + Err(TDPError::FailedOperation(err)) + } + } } /// Sets STAPM to the given value and adjusts the SPPT/FPPT to maintaing the current boost @@ -47,7 +74,27 @@ impl AsusWmi { let boost = self.boost().await?; // Set the STAPM value to the given TDP value - self.platform.set_ppt_pl1_spl(value as u8)?; + let attr = self + .attributes + .attributes() + .iter() + .find(|a| a.name() == "ppt_pl1_spl"); + + if let Some(attr) = attr { + let val = AttrValue::Integer(value as i32); + match attr.set_current_value(val) { + Ok(_) => { + log::info!("Set SPL to {value}"); + } + Err(e) => { + return Err(TDPError::FailedOperation(format!( + "Failed to set SPL: {e:?}" + ))); + } + } + } else { + self.platform.set_ppt_pl1_spl(value as u8)?; + } // Set the boost back to the expected value with the new TDP self.set_boost(boost).await?; @@ -63,10 +110,38 @@ impl AsusWmi { return Err(e); } }; - let slow_ppt = self.platform.get_ppt_platform_sppt()? as f64; + + let attr = self + .attributes + .attributes() + .iter() + .find(|a| a.name() == "ppt_platform_sppt"); + + let slow_ppt = { + if let Some(attr) = attr { + match attr.current_value() { + Ok(attr_value) => match attr_value { + AttrValue::Integer(value) => value as f64, + _ => { + return Err(TDPError::FailedOperation( + "Failed to read SPPT.".to_string(), + )) + } + }, + Err(_) => { + return Err(TDPError::FailedOperation( + "Failed to read SPPT.".to_string(), + )) + } + } + // + } else { + self.platform.get_ppt_platform_sppt()? as f64 + } + }; + let boost = slow_ppt - stapm; log::info!("Found current boost: {boost}"); - Ok(boost) } @@ -83,10 +158,29 @@ impl AsusWmi { "Combined TDP + Boost value must be between 1 and 255".to_string(), )); } - let boost = (stapm + value) as u8; + let sppt_val = (stapm + value) as i32; // ppt_platform_sppt will set sppt to value and fppt to value + 25% - self.platform.set_ppt_platform_sppt(boost)?; + let attr = self + .attributes + .attributes() + .iter() + .find(|a| a.name() == "ppt_platform_sppt"); + let Some(attr) = attr else { + return Ok(self.platform.set_ppt_platform_sppt(sppt_val as u8)?); + }; + + let boost = AttrValue::Integer(sppt_val); + match attr.set_current_value(boost) { + Ok(_) => { + log::info!("Set SPPT to {value}"); + } + Err(e) => { + return Err(TDPError::FailedOperation(format!( + "Failed to set SPPT: {e:?}" + ))); + } + } Ok(()) }