libdrm_amdgpu_sys/amdgpu/
power_cap.rs

1use crate::AMDGPU::DeviceHandle;
2use std::str::FromStr;
3use std::path::PathBuf;
4use super::parse_hwmon;
5
6impl DeviceHandle {
7    pub fn get_power_cap(&self) -> Option<PowerCap> {
8        let hwmon_path = self.get_hwmon_path()?;
9
10        PowerCap::from_hwmon_path(hwmon_path)
11    }
12}
13
14#[derive(Clone, Debug, PartialEq, Eq)]
15pub struct PowerCap {
16    pub type_: PowerCapType,
17    pub current: u32, // W
18    pub default: u32, // W
19    pub min: u32, // W
20    pub max: u32, // W
21}
22
23impl PowerCap {
24    pub fn from_hwmon_path<P: Into<PathBuf>>(path: P) -> Option<Self> {
25        let path = path.into();
26
27        let label = match std::fs::read_to_string(path.join("power1_label")) {
28            Ok(s) => s,
29            Err(_) => std::fs::read_to_string(path.join("power2_label")).ok()?,
30        };
31        let type_ = PowerCapType::from_str(label.as_str().trim_end()).ok()?;
32        let [current, default, min, max] = type_.file_names().map(|name| {
33            parse_hwmon::<u32, _>(path.join(name)).map(|v| v.saturating_div(1_000_000))
34        });
35
36        Some(Self {
37            type_,
38            current: current?,
39            default: default?,
40            min: min?,
41            max: max?,
42        })
43    }
44
45    /// ref: drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
46    /// ref: <https://github.com/RadeonOpenCompute/rocm_smi_lib/blob/master/python_smi_tools/rocm_smi.py>
47    pub fn check_if_secondary_die(&self) -> bool {
48        self.current == 0 && self.default == 0 && self.max == 0
49    }
50}
51
52#[derive(Clone, Debug, Eq, PartialEq)]
53pub enum PowerCapType {
54    PPT,
55    FastPPT,
56    SlowPPT,
57}
58
59impl PowerCapType {
60    const fn file_names(&self) -> [&str; 4] {
61        match self {
62            Self::PPT =>
63                ["power1_cap", "power1_cap_default", "power1_cap_min", "power1_cap_max"],
64            // for VanGogh APU
65            Self::FastPPT |
66            Self::SlowPPT =>
67                ["power2_cap", "power2_cap_default", "power2_cap_min", "power2_cap_max"],
68        }
69    }
70}
71
72use std::fmt;
73impl fmt::Display for PowerCapType {
74    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75        write!(f, "{:?}", self)
76    }
77}
78
79#[derive(Debug, PartialEq, Eq)]
80pub struct ParsePowerCapTypeError;
81
82impl FromStr for PowerCapType {
83    type Err = ParsePowerCapTypeError;
84
85    fn from_str(s: &str) -> Result<Self, Self::Err> {
86        match s {
87            "PPT" => Ok(Self::PPT),
88            "fastPPT" => Ok(Self::FastPPT),
89            "slowPPT" => Ok(Self::SlowPPT),
90            _ => Err(ParsePowerCapTypeError),
91        }
92    }
93}