Implement RyzenAdj driver for AMD
This commit is contained in:
parent
5614937012
commit
500fde964c
7 changed files with 189 additions and 19 deletions
|
@ -169,12 +169,12 @@ pub struct Cpu {
|
|||
state: crate::state::steam_deck::Cpu,
|
||||
}
|
||||
|
||||
impl Cpu {
|
||||
/*impl Cpu {
|
||||
#[inline]
|
||||
pub fn index(&self) -> usize {
|
||||
self.index
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
impl AsRef<Cpu> for Cpu {
|
||||
#[inline]
|
||||
|
|
|
@ -9,10 +9,10 @@ use crate::persist::GpuJson;
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Gpu {
|
||||
slow_memory: bool,
|
||||
fast_ppt: Option<u64>,
|
||||
slow_ppt: Option<u64>,
|
||||
clock_limits: Option<MinMax<u64>>,
|
||||
pub slow_memory: bool,
|
||||
pub fast_ppt: Option<u64>,
|
||||
pub slow_ppt: Option<u64>,
|
||||
pub clock_limits: Option<MinMax<u64>>,
|
||||
limits: GenericGpuLimit,
|
||||
}
|
||||
|
||||
|
@ -101,11 +101,11 @@ impl TGpu for Gpu {
|
|||
}
|
||||
|
||||
fn ppt(&mut self, fast: Option<u64>, slow: Option<u64>) {
|
||||
if self.limits.fast_ppt.is_some() {
|
||||
self.fast_ppt = fast;
|
||||
if let Some(fast_lims) = &self.limits.fast_ppt {
|
||||
self.fast_ppt = fast.map(|x| x.clamp(fast_lims.min, fast_lims.max));
|
||||
}
|
||||
if self.limits.slow_ppt.is_some() {
|
||||
self.slow_ppt = slow;
|
||||
if let Some(slow_lims) = &self.limits.slow_ppt {
|
||||
self.slow_ppt = slow.map(|x| x.clamp(slow_lims.min, slow_lims.max));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,8 +114,14 @@ impl TGpu for Gpu {
|
|||
}
|
||||
|
||||
fn clock_limits(&mut self, limits: Option<MinMax<u64>>) {
|
||||
if self.limits.clock_min.is_some() && self.limits.clock_max.is_some() {
|
||||
self.clock_limits = limits;
|
||||
if let Some(clock_min) = &self.limits.clock_min {
|
||||
if let Some(clock_max) = &self.limits.clock_max {
|
||||
self.clock_limits = limits.map(|mut x| {
|
||||
x.min = x.min.clamp(clock_min.min, clock_min.max);
|
||||
x.max = x.max.clamp(clock_max.max, clock_max.max);
|
||||
x
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -123,8 +123,9 @@ impl TCpu for Cpu {
|
|||
self.generic.get_governor()
|
||||
}
|
||||
|
||||
fn clock_limits(&mut self, limits: Option<MinMax<u64>>) {
|
||||
self.generic.clock_limits(limits)
|
||||
fn clock_limits(&mut self, _limits: Option<MinMax<u64>>) {
|
||||
//self.generic.clock_limits(limits)
|
||||
// TODO: support this
|
||||
}
|
||||
|
||||
fn get_clock_limits(&self) -> Option<&MinMax<u64>> {
|
||||
|
|
|
@ -1,39 +1,182 @@
|
|||
use std::sync::Mutex;
|
||||
use ryzenadj_rs::RyzenAccess;
|
||||
|
||||
use crate::persist::GpuJson;
|
||||
use crate::settings::MinMax;
|
||||
use crate::settings::generic::Gpu as GenericGpu;
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
use crate::settings::{OnResume, OnSet, SettingError, SettingVariant};
|
||||
use crate::settings::TGpu;
|
||||
|
||||
fn ryzen_adj_or_log() -> Option<Mutex<RyzenAccess>> {
|
||||
match RyzenAccess::new() {
|
||||
Ok(x) => Some(Mutex::new(x)),
|
||||
Err(e) => {
|
||||
log::error!("RyzenAdj init error: {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Gpu {
|
||||
generic: GenericGpu,
|
||||
implementor: Option<Mutex<RyzenAccess>>,
|
||||
state: crate::state::generic::Gpu, // NOTE this is re-used for simplicity
|
||||
}
|
||||
|
||||
impl Gpu {
|
||||
pub fn from_limits(limits: limits_core::json::GenericGpuLimit) -> Self {
|
||||
Self {
|
||||
generic: GenericGpu::from_limits(limits),
|
||||
implementor: ryzen_adj_or_log(),
|
||||
state: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_json_and_limits(other: GpuJson, version: u64, limits: limits_core::json::GenericGpuLimit) -> Self {
|
||||
Self {
|
||||
generic: GenericGpu::from_json_and_limits(other, version, limits),
|
||||
implementor: ryzen_adj_or_log(),
|
||||
state: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_all(&mut self) -> Result<(), SettingError> {
|
||||
let mutex = match &self.implementor {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
return Err(SettingError {
|
||||
msg: "RyzenAdj unavailable".to_owned(),
|
||||
setting: SettingVariant::Gpu,
|
||||
});
|
||||
}
|
||||
};
|
||||
let lock = match mutex.lock() {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
return Err(SettingError {
|
||||
msg: format!("RyzenAdj lock acquire failed: {}", e),
|
||||
setting: SettingVariant::Gpu,
|
||||
});
|
||||
}
|
||||
};
|
||||
if let Some(fast_ppt) = &self.generic.fast_ppt {
|
||||
if self.state.old_fast_ppt.is_none() {
|
||||
self.state.old_fast_ppt = Some(lock.get_fast_value() as _);
|
||||
}
|
||||
lock.set_fast_limit(*fast_ppt as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})?;
|
||||
} else if let Some(fast_ppt) = &self.state.old_fast_ppt {
|
||||
lock.set_fast_limit(*fast_ppt as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})?;
|
||||
self.state.old_fast_ppt = None;
|
||||
}
|
||||
if let Some(slow_ppt) = &self.generic.slow_ppt {
|
||||
if self.state.old_slow_ppt.is_none() {
|
||||
self.state.old_slow_ppt = Some(lock.get_slow_value() as _);
|
||||
}
|
||||
lock.set_slow_limit(*slow_ppt as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})?;
|
||||
} else if let Some(slow_ppt) = &self.state.old_slow_ppt {
|
||||
lock.set_slow_limit(*slow_ppt as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})?;
|
||||
self.state.old_slow_ppt = None;
|
||||
}
|
||||
if let Some(clock_limits) = &self.generic.clock_limits {
|
||||
self.state.clock_limits_set = true;
|
||||
lock.set_max_gfxclk_freq(clock_limits.max as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", clock_limits.max, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})?;
|
||||
lock.set_min_gfxclk_freq(clock_limits.min as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", clock_limits.min, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})?;
|
||||
} else if self.state.clock_limits_set {
|
||||
self.state.clock_limits_set = false;
|
||||
let limits = self.generic.limits();
|
||||
if let Some(min_limits) = limits.clock_min_limits {
|
||||
if let Some(max_limits) = limits.clock_max_limits {
|
||||
lock.set_max_gfxclk_freq(max_limits.max as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", max_limits.max, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})?;
|
||||
lock.set_min_gfxclk_freq(min_limits.min as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", min_limits.min, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn resume_all(&self) -> Result<(), SettingError> {
|
||||
// like set_all() but without updating state
|
||||
// -- assumption: state is already up to date
|
||||
let mutex = match &self.implementor {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
return Err(SettingError {
|
||||
msg: "RyzenAdj unavailable".to_owned(),
|
||||
setting: SettingVariant::Gpu,
|
||||
});
|
||||
}
|
||||
};
|
||||
let lock = match mutex.lock() {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
return Err(SettingError {
|
||||
msg: format!("RyzenAdj lock acquire failed: {}", e),
|
||||
setting: SettingVariant::Gpu,
|
||||
});
|
||||
}
|
||||
};
|
||||
if let Some(fast_ppt) = &self.generic.fast_ppt {
|
||||
lock.set_fast_limit(*fast_ppt as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})?;
|
||||
}
|
||||
if let Some(slow_ppt) = &self.generic.slow_ppt {
|
||||
lock.set_slow_limit(*slow_ppt as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})?;
|
||||
}
|
||||
if let Some(clock_limits) = &self.generic.clock_limits {
|
||||
lock.set_max_gfxclk_freq(clock_limits.max as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", clock_limits.max, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})?;
|
||||
lock.set_min_gfxclk_freq(clock_limits.min as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", clock_limits.min, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl OnResume for Gpu {
|
||||
fn on_resume(&self) -> Result<(), SettingError> {
|
||||
self.generic.on_resume()
|
||||
// TODO
|
||||
self.generic.on_resume()?;
|
||||
self.resume_all()
|
||||
}
|
||||
}
|
||||
|
||||
impl OnSet for Gpu {
|
||||
fn on_set(&mut self) -> Result<(), SettingError> {
|
||||
self.generic.on_set()
|
||||
// TODO
|
||||
self.generic.on_set()?;
|
||||
self.set_all()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
16
backend/src/state/generic/gpu.rs
Normal file
16
backend/src/state/generic/gpu.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct Gpu {
|
||||
pub clock_limits_set: bool,
|
||||
pub old_fast_ppt: Option<u64>,
|
||||
pub old_slow_ppt: Option<u64>,
|
||||
}
|
||||
|
||||
impl std::default::Default for Gpu {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
clock_limits_set: false,
|
||||
old_fast_ppt: None,
|
||||
old_slow_ppt: None,
|
||||
}
|
||||
}
|
||||
}
|
3
backend/src/state/generic/mod.rs
Normal file
3
backend/src/state/generic/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
mod gpu;
|
||||
|
||||
pub use gpu::Gpu;
|
|
@ -1,6 +1,7 @@
|
|||
mod error;
|
||||
mod traits;
|
||||
|
||||
pub mod generic;
|
||||
pub mod steam_deck;
|
||||
|
||||
pub use error::StateError;
|
||||
|
|
Loading…
Reference in a new issue