Skip to content

Commit

Permalink
fix(AsusWMI): Use both WMI methods
Browse files Browse the repository at this point in the history
- Remove dangerous unwraps from firmware_attributes usage.
- Use FirmwareAttributes as an Option, add RogPlatform as fallback.
  • Loading branch information
pastaq authored and ShadowApex committed Dec 24, 2024
1 parent 80b8a76 commit b717402
Showing 1 changed file with 103 additions and 75 deletions.
178 changes: 103 additions & 75 deletions src/performance/gpu/asus/asus_wmi.rs
Original file line number Diff line number Diff line change
@@ -1,82 +1,100 @@
use crate::performance::gpu::tdp::{TDPError, TDPResult};

use rog_platform::{
error::PlatformError,
firmware_attributes::{AttrValue, FirmwareAttributes},
platform::RogPlatform,
};

impl From<PlatformError> for TDPError {
fn from(value: PlatformError) -> Self {
Self::FailedOperation(value.to_string())
}
}

/// 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,
attributes: Option<FirmwareAttributes>,
platform: RogPlatform,
}

impl AsusWmi {
/// test if we are in an asus system with asus-wmi loaded
pub async fn new() -> Option<Self> {
match RogPlatform::new() {
Ok(_) => {
Ok(platform) => {
log::info!("Module asus-wmi found");
let attributes: Option<FirmwareAttributes> = Some(FirmwareAttributes::new());
Some(Self {
attributes: FirmwareAttributes::new(),
attributes,
platform,
})
}
Err(err) => {
log::info!("Module asus-wmi not found: {}", err);
log::info!("Module asus-wmi not found: {err:?}");
None
}
}
}

/// Returns the currently set STAPM value
pub async fn tdp(&self) -> TDPResult<f64> {
match self
.attributes
.attributes()
.iter()
.find(|a| a.name() == "ppt_pl1_spl")
.unwrap()
.current_value()
{
Ok(attr_value) => match attr_value {
AttrValue::Integer(value) => {
log::info!("Found STAPM value: {value}");
Ok(value as f64)
}
_ => Err(TDPError::FailedOperation(
"Failed to read STAPM value".to_string(),
)),
},
Err(e) => Err(TDPError::FailedOperation(format!(
"Failed to read STAPM Value: {e:?}"
))),
if let Some(firmware_attributes) = &self.attributes {
match firmware_attributes
.attributes()
.iter()
.find(|a| a.name() == "ppt_pl1_spl")
{
Some(attribute) => match attribute.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(_) => Err(TDPError::FailedOperation("Failed to read SPL.".to_string())),
},
None => Err(TDPError::FailedOperation("Failed to read SPL.".to_string())),
}
} else {
Ok(self.platform.get_ppt_pl1_spl()? as f64)
}
}

/// Sets STAPM to the given value and adjusts the SPPT/FPPT to maintaing the current boost
/// ratio
pub async fn set_tdp(&mut self, value: f64) -> TDPResult<()> {
if value < 1.0 || value > u8::MAX as f64 {
return Err(TDPError::InvalidArgument(
"Value must be between 1 and 255".to_string(),
));
}

// Get the current Boost value
let boost = self.boost().await?;

// Set the STAPM value to the given TDP value
let val = AttrValue::Integer(value as i32);
match self
.attributes
.attributes_mut()
.iter()
.find(|a| a.name() == "ppt_pl1_spl")
.unwrap()
.set_current_value(val)
{
Ok(_) => {
log::info!("Set STAPM value to {value}");
}
Err(e) => {
return Err(TDPError::FailedOperation(format!(
"Failed to set STAPM value: {e:}"
)));
if let Some(firmware_attributes) = &self.attributes {
match firmware_attributes
.attributes()
.iter()
.find(|a| a.name() == "ppt_pl1_spl")
{
Some(attribute) => match attribute.set_current_value(val) {
Ok(_) => {
log::info!("Set SPL to {value}");
}
Err(e) => {
return Err(TDPError::FailedOperation(format!(
"Failed to set SPL: {e:}"
)));
}
},

None => return Err(TDPError::FailedOperation("Failed to set SPL.".to_string())),
}
} else {
self.platform.set_ppt_pl1_spl(value as u8)?;
}

// Set the boost back to the expeted value with the new TDP
Expand All @@ -94,30 +112,35 @@ impl AsusWmi {
}
};

let slow_ppt = match self
.attributes
.attributes()
.iter()
.find(|a| a.name() == "ppt_platform_sppt")
.unwrap()
.current_value()
{
Ok(attr_value) => match attr_value {
AttrValue::Integer(value) => {
log::info!("Found Slow PPT value: {value}");
value as f64
}
_ => {
let slow_ppt = if let Some(firmware_attributes) = &self.attributes {
match firmware_attributes
.attributes()
.iter()
.find(|a| a.name() == "ppt_platform_sppt")
{
Some(attribute) => match attribute.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(),
))
}
},
None => {
return Err(TDPError::FailedOperation(
"Failed to read Slow PPT value".to_string(),
"Failed to read SPPT.".to_string(),
))
}
},
Err(e) => {
return Err(TDPError::FailedOperation(format!(
"Failed to read Slow PPT value: {e:?}"
)))
}
} else {
self.platform.get_ppt_platform_sppt()? as f64
};

let boost = slow_ppt - stapm;
Expand All @@ -138,23 +161,28 @@ impl AsusWmi {
let boost = AttrValue::Integer(sppt_val);

// ppt_platform_sppt will set sppt to value and fppt to value + 25%
match self
.attributes
.attributes_mut()
.iter()
.find(|a| a.name() == "ppt_platform_sppt")
.unwrap()
.set_current_value(boost)
{
Ok(_) => {
log::info!("Set Slow PPT to {sppt_val}");
}
Err(e) => {
return Err(TDPError::FailedOperation(format!(
"Failed to set Slow PPT: {e:?}"
)))
if let Some(firmware_attributes) = &self.attributes {
match firmware_attributes
.attributes()
.iter()
.find(|a| a.name() == "ppt_platform_sppt")
{
Some(attribute) => match attribute.set_current_value(boost) {
Ok(_) => {
log::info!("Set SPPT to {value}");
}
Err(e) => {
return Err(TDPError::FailedOperation(format!(
"Failed to set SPPT: {e:}"
)));
}
},

None => return Err(TDPError::FailedOperation("Failed to set SPPT.".to_string())),
}
};
} else {
self.platform.set_ppt_platform_sppt(sppt_val as u8)?;
}

Ok(())
}
Expand Down

0 comments on commit b717402

Please sign in to comment.