From c5d2996a30366f366f5b0969fc4f420ca0bb59d2 Mon Sep 17 00:00:00 2001 From: Ilya Zlobintsev Date: Sat, 11 Jan 2025 11:07:41 +0200 Subject: [PATCH] feat: numerous i915 additions --- lact-daemon/src/server/gpu_controller/amd.rs | 3 +- .../src/server/gpu_controller/intel.rs | 322 +++++++++++++----- .../src/tests/data/intel/a380-i915/card1/dev | 1 + .../a380-i915/card1/device/current_link_speed | 1 + .../a380-i915/card1/device/current_link_width | 1 + .../card1/device/hwmon/hwmon1/energy1_input | 1 + .../card1/device/hwmon/hwmon1/fan1_input | 1 + .../card1/device/hwmon/hwmon1/in0_input | 1 + .../a380-i915/card1/device/hwmon/hwmon1/name | 1 + .../card1/device/hwmon/hwmon1/power/control | 1 + .../hwmon/hwmon1/power/runtime_active_time | 1 + .../device/hwmon/hwmon1/power/runtime_status | 1 + .../hwmon/hwmon1/power/runtime_suspended_time | 1 + .../card1/device/hwmon/hwmon1/power1_max | 1 + .../device/hwmon/hwmon1/power1_max_interval | 1 + .../device/hwmon/hwmon1/power1_rated_max | 1 + .../card1/device/hwmon/hwmon1/temp1_input | 1 + .../card1/device/hwmon/hwmon1/uevent | 0 .../data/intel/a380-i915/card1/device/uevent | 6 + .../data/intel/a380-i915/card1/device/vendor | 1 + .../tests/data/intel/a380-i915/card1/error | 1 + .../gt/gt0/.defaults/rps_down_threshold_pct | 1 + .../card1/gt/gt0/.defaults/rps_max_freq_mhz | 1 + .../card1/gt/gt0/.defaults/rps_min_freq_mhz | 1 + .../gt/gt0/.defaults/rps_up_threshold_pct | 1 + .../data/intel/a380-i915/card1/gt/gt0/id | 1 + .../a380-i915/card1/gt/gt0/media_RP0_freq_mhz | 1 + .../a380-i915/card1/gt/gt0/media_RPn_freq_mhz | 1 + .../a380-i915/card1/gt/gt0/media_freq_factor | 1 + .../card1/gt/gt0/media_freq_factor.scale | 1 + .../a380-i915/card1/gt/gt0/punit_req_freq_mhz | 1 + .../intel/a380-i915/card1/gt/gt0/rc6_enable | 1 + .../a380-i915/card1/gt/gt0/rc6_residency_ms | 1 + .../a380-i915/card1/gt/gt0/rps_RP0_freq_mhz | 1 + .../a380-i915/card1/gt/gt0/rps_RP1_freq_mhz | 1 + .../a380-i915/card1/gt/gt0/rps_RPn_freq_mhz | 1 + .../a380-i915/card1/gt/gt0/rps_act_freq_mhz | 1 + .../a380-i915/card1/gt/gt0/rps_boost_freq_mhz | 1 + .../a380-i915/card1/gt/gt0/rps_cur_freq_mhz | 1 + .../a380-i915/card1/gt/gt0/rps_max_freq_mhz | 1 + .../a380-i915/card1/gt/gt0/rps_min_freq_mhz | 1 + .../card1/gt/gt0/slpc_ignore_eff_freq | 1 + .../card1/gt/gt0/throttle_reason_pl1 | 1 + .../card1/gt/gt0/throttle_reason_pl2 | 1 + .../card1/gt/gt0/throttle_reason_pl4 | 1 + .../card1/gt/gt0/throttle_reason_prochot | 1 + .../card1/gt/gt0/throttle_reason_ratl | 1 + .../card1/gt/gt0/throttle_reason_status | 1 + .../card1/gt/gt0/throttle_reason_thermal | 1 + .../card1/gt/gt0/throttle_reason_vr_tdc | 1 + .../gt/gt0/throttle_reason_vr_thermalert | 1 + .../intel/a380-i915/card1/gt_RP0_freq_mhz | 1 + .../intel/a380-i915/card1/gt_RP1_freq_mhz | 1 + .../intel/a380-i915/card1/gt_RPn_freq_mhz | 1 + .../intel/a380-i915/card1/gt_act_freq_mhz | 1 + .../intel/a380-i915/card1/gt_boost_freq_mhz | 1 + .../intel/a380-i915/card1/gt_cur_freq_mhz | 1 + .../intel/a380-i915/card1/gt_max_freq_mhz | 1 + .../intel/a380-i915/card1/gt_min_freq_mhz | 1 + .../tests/data/intel/a380-i915/card1/uevent | 4 + .../lact_daemon__tests__intel__a380-i915.snap | 92 +++++ .../lact_daemon__tests__intel__cometlake.snap | 4 +- .../lact_daemon__tests__intel__tigerlake.snap | 4 +- .../app/pages/oc_page/gpu_stats_section.rs | 6 +- .../app/pages/oc_page/power_cap_section.rs | 4 + lact-schema/src/lib.rs | 10 +- 66 files changed, 409 insertions(+), 101 deletions(-) create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/dev create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/current_link_speed create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/current_link_width create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/energy1_input create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/fan1_input create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/in0_input create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/name create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/control create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/runtime_active_time create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/runtime_status create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/runtime_suspended_time create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power1_max create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power1_max_interval create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power1_rated_max create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/temp1_input create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/uevent create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/uevent create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/device/vendor create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/error create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_down_threshold_pct create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_max_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_min_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_up_threshold_pct create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/id create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_RP0_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_RPn_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_freq_factor create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_freq_factor.scale create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/punit_req_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rc6_enable create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rc6_residency_ms create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_RP0_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_RP1_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_RPn_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_act_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_boost_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_cur_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_max_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_min_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/slpc_ignore_eff_freq create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_pl1 create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_pl2 create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_pl4 create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_prochot create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_ratl create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_status create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_thermal create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_vr_tdc create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_vr_thermalert create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt_RP0_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt_RP1_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt_RPn_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt_act_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt_boost_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt_cur_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt_max_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/gt_min_freq_mhz create mode 100644 lact-daemon/src/tests/data/intel/a380-i915/card1/uevent create mode 100644 lact-daemon/src/tests/snapshots/lact_daemon__tests__intel__a380-i915.snap diff --git a/lact-daemon/src/server/gpu_controller/amd.rs b/lact-daemon/src/server/gpu_controller/amd.rs index 3c226fa3..13b1a89b 100644 --- a/lact-daemon/src/server/gpu_controller/amd.rs +++ b/lact-daemon/src/server/gpu_controller/amd.rs @@ -377,11 +377,12 @@ impl AmdGpuController { .context("GPU has no hardware monitor") } - fn get_current_gfxclk(&self) -> Option { + fn get_current_gfxclk(&self) -> Option { self.drm_handle .as_ref() .and_then(|drm_handle| drm_handle.get_gpu_metrics().ok()) .and_then(|metrics| metrics.get_current_gfxclk()) + .map(u64::from) } fn get_full_vbios_version(&self) -> Option { diff --git a/lact-daemon/src/server/gpu_controller/intel.rs b/lact-daemon/src/server/gpu_controller/intel.rs index 6e27f4a1..e9980b77 100644 --- a/lact-daemon/src/server/gpu_controller/intel.rs +++ b/lact-daemon/src/server/gpu_controller/intel.rs @@ -1,14 +1,15 @@ use super::{CommonControllerInfo, GpuController}; use crate::{bindings::intel::IntelDrm, config, server::vulkan::get_vulkan_info}; -use amdgpu_sysfs::gpu_handle::power_profile_mode::PowerProfileModesTable; +use amdgpu_sysfs::{gpu_handle::power_profile_mode::PowerProfileModesTable, hw_mon::Temperature}; use anyhow::{anyhow, Context}; use futures::future::LocalBoxFuture; use lact_schema::{ ClocksInfo, ClocksTable, ClockspeedStats, DeviceInfo, DeviceStats, DrmInfo, IntelClocksTable, - IntelDrmInfo, LinkInfo, PowerStates, VramStats, + IntelDrmInfo, LinkInfo, PowerStates, PowerStats, VoltageStats, VramStats, }; use std::{ cell::Cell, + collections::{BTreeMap, HashMap}, fmt::Display, fs, io::{BufRead, BufReader}, @@ -20,6 +21,7 @@ use std::{ }; use tracing::{debug, error, info, trace, warn}; +#[derive(Clone, Copy)] enum DriverType { I915, Xe, @@ -29,9 +31,12 @@ pub struct IntelGpuController { driver_type: DriverType, common: CommonControllerInfo, tile_gts: Vec, + hwmon_path: Option, drm_file: fs::File, drm: Rc, last_gpu_busy: Cell>, + last_energy_value: Cell>, + initial_power_cap: Option, } impl IntelGpuController { @@ -86,14 +91,29 @@ impl IntelGpuController { fs::File::open("/dev/null").unwrap() }; - Ok(Self { + let hwmon_path = fs::read_dir(common.sysfs_path.join("hwmon")) + .ok() + .and_then(|mut read_dir| read_dir.next()) + .and_then(Result::ok) + .map(|entry| entry.path()); + debug!("Initialized hwmon: {hwmon_path:?}"); + + let mut controller = Self { common, driver_type, tile_gts, + hwmon_path, drm_file, drm, last_gpu_busy: Cell::new(None), - }) + last_energy_value: Cell::new(None), + initial_power_cap: None, + }; + + let stats = controller.get_stats(None); + controller.initial_power_cap = stats.power.cap_current.filter(|cap| *cap != 0.0); + + Ok(controller) } } @@ -130,32 +150,25 @@ impl GpuController for IntelGpuController { } } + #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] fn apply_config<'a>( &'a self, config: &'a config::Gpu, ) -> LocalBoxFuture<'a, anyhow::Result<()>> { Box::pin(async { - match self.driver_type { - DriverType::Xe => { - if let Some(max_clock) = config.clocks_configuration.max_core_clock { - self.write_gt_file("freq0/max_freq", &max_clock.to_string()) - .context("Could not set max clock")?; - } - if let Some(min_clock) = config.clocks_configuration.min_core_clock { - self.write_gt_file("freq0/min_freq", &min_clock.to_string()) - .context("Could not set min clock")?; - } - } - DriverType::I915 => { - if let Some(max_clock) = config.clocks_configuration.max_core_clock { - self.write_file("../gt_max_freq_mhz", &max_clock.to_string()) - .context("Could not set max clock")?; - } - if let Some(min_clock) = config.clocks_configuration.min_core_clock { - self.write_file("../gt_min_freq_mhz", &min_clock.to_string()) - .context("Could not set min clock")?; - } - } + if let Some(max_clock) = config.clocks_configuration.max_core_clock { + self.write_freq(FrequencyType::Max, max_clock) + .context("Could not set max clock")?; + } + + if let Some(min_clock) = config.clocks_configuration.min_core_clock { + self.write_freq(FrequencyType::Min, min_clock) + .context("Could not set min clock")?; + } + + if let Some(cap) = config.power_cap { + self.write_hwmon_file("power1_max", &((cap * 1_000_000.0) as u64).to_string()) + .context("Could not set power cap")?; } Ok(()) @@ -163,22 +176,11 @@ impl GpuController for IntelGpuController { } fn get_stats(&self, _gpu_config: Option<&config::Gpu>) -> DeviceStats { - let current_gfxclk; - let gpu_clockspeed; - - match self.driver_type { - DriverType::Xe => { - current_gfxclk = self.read_gt_file("freq0/cur_freq"); - gpu_clockspeed = self - .read_gt_file("freq0/act_freq") - .filter(|freq| *freq != 0) - .or_else(|| current_gfxclk.map(u64::from)); - } - DriverType::I915 => { - current_gfxclk = self.read_file("../gt_cur_freq_mhz"); - gpu_clockspeed = self.read_file("../gt_act_freq_mhz"); - } - } + let current_gfxclk = self.read_freq(FrequencyType::Cur); + let gpu_clockspeed = self + .read_freq(FrequencyType::Act) + .filter(|value| *value != 0) + .or(current_gfxclk); let clockspeed = ClockspeedStats { gpu_clockspeed, @@ -186,37 +188,56 @@ impl GpuController for IntelGpuController { vram_clockspeed: None, }; + let cap_current = self + .read_hwmon_file("power1_max") + .map(|value: f64| value / 1_000_000.0) + .map(|cap| if cap == 0.0 { 100.0 } else { cap }); // Placeholder max value + + let power = PowerStats { + average: None, + current: self.get_power_usage(), + cap_current, + cap_min: Some(0.0), + cap_max: self + .read_hwmon_file::("power1_rated_max") + .filter(|max| *max != 0.0) + .map(|cap| cap / 1_000_000.0) + .or_else(|| cap_current.map(|current| current * 2.0)), + cap_default: self.initial_power_cap, + }; + + let voltage = VoltageStats { + gpu: self.read_hwmon_file("in0_input"), + northbridge: None, + }; + + let vram = VramStats { + total: self + .drm_try_2(IntelDrm::drm_intel_get_aperture_sizes) + .map(|(_, total)| total as u64), + used: None, + }; + DeviceStats { clockspeed, - vram: VramStats { - total: self - .drm_try_2(IntelDrm::drm_intel_get_aperture_sizes) - .map(|(_, total)| total as u64), - used: None, - }, + vram, busy_percent: self.get_busy_percent(), + power, + temps: self.get_temperatures(), + voltage, + throttle_info: self.get_throttle_info(), ..Default::default() } } fn get_clocks_info(&self) -> anyhow::Result { - let clocks_table = match self.driver_type { - DriverType::Xe => IntelClocksTable { - gt_freq: self - .read_gt_file("freq0/min_freq") - .zip(self.read_gt_file("freq0/max_freq")), - rp0_freq: self.read_gt_file("freq0/rp0_freq"), - rpe_freq: self.read_gt_file("freq0/rpe_freq"), - rpn_freq: self.read_gt_file("freq0/rpn_freq"), - }, - DriverType::I915 => IntelClocksTable { - gt_freq: self - .read_file("../gt_min_freq_mhz") - .zip(self.read_file("../gt_max_freq_mhz")), - rpn_freq: self.read_file("../gt_RPn_freq_mhz"), - rpe_freq: self.read_file("../gt_RP1_freq_mhz"), - rp0_freq: self.read_file("../gt_RP0_freq_mhz"), - }, + let clocks_table = IntelClocksTable { + gt_freq: self + .read_freq(FrequencyType::Min) + .zip(self.read_freq(FrequencyType::Max)), + rp0_freq: self.read_freq(FrequencyType::Rp0), + rpe_freq: self.read_freq(FrequencyType::Rpe), + rpn_freq: self.read_freq(FrequencyType::Rpn), }; let table = if clocks_table == IntelClocksTable::default() { @@ -237,7 +258,20 @@ impl GpuController for IntelGpuController { fn reset_pmfw_settings(&self) {} + #[allow(clippy::cast_possible_truncation)] fn cleanup_clocks(&self) -> anyhow::Result<()> { + if let Some(rp0) = self.read_freq(FrequencyType::Rp0) { + if let Err(err) = self.write_freq(FrequencyType::Max, rp0 as i32) { + warn!("could not reset max clock: {err:#}"); + } + } + + if let Some(rpn) = self.read_freq(FrequencyType::Rpn) { + if let Err(err) = self.write_freq(FrequencyType::Min, rpn as i32) { + warn!("could not reset min clock: {err:#}"); + } + } + Ok(()) } @@ -264,29 +298,12 @@ impl IntelGpuController { self.tile_gts.first().map(PathBuf::as_ref) } - /// Based on the input path, this has the following behaviour: - /// - Basic relative paths are resolved relative to the sysfs device - /// - Parent paths (starting with (../) are resolved on the sysfs card entry, without resolving device symlink - fn sysfs_file_path(&self, path: impl AsRef) -> PathBuf { - let path = path.as_ref(); - - match path.strip_prefix("../") { - Ok(path_relative_to_parent) => self - .common - .sysfs_path - .parent() - .expect("Device path has no parent") - .join(path_relative_to_parent), - Err(_) => self.common.sysfs_path.join(path), - } - } - fn read_file(&self, path: impl AsRef) -> Option where T: FromStr, T::Err: Display, { - let file_path = self.sysfs_file_path(path); + let file_path = self.common.sysfs_path.join(path); trace!("reading file from '{}'", file_path.display()); @@ -310,7 +327,7 @@ impl IntelGpuController { } fn write_file(&self, path: impl AsRef, contents: &str) -> anyhow::Result<()> { - let file_path = self.sysfs_file_path(path); + let file_path = self.common.sysfs_path.join(path); if file_path.exists() { fs::write(&file_path, contents) @@ -321,23 +338,24 @@ impl IntelGpuController { } } - fn read_gt_file(&self, file_name: &str) -> Option + fn read_hwmon_file(&self, file_name: &str) -> Option where T: FromStr, T::Err: Display, { - self.first_tile_gt().and_then(|gt_path| { - let file_path = gt_path.join(file_name); + self.hwmon_path.as_ref().and_then(|hwmon_path| { + let file_path = hwmon_path.join(file_name); self.read_file(file_path) }) } - fn write_gt_file(&self, file_name: &str, contents: &str) -> anyhow::Result<()> { - if let Some(gt_path) = self.first_tile_gt() { - let file_path = gt_path.join(file_name); + fn write_hwmon_file(&self, file_name: &str, contents: &str) -> anyhow::Result<()> { + debug!("writing value '{contents}' to '{file_name}'"); + if let Some(hwmon_path) = &self.hwmon_path { + let file_path = hwmon_path.join(file_name); self.write_file(file_path, contents) } else { - Err(anyhow!("No GTs available")) + Err(anyhow!("No hwmon available")) } } @@ -426,4 +444,128 @@ impl IntelGpuController { None } + + #[allow(clippy::cast_precision_loss, clippy::cast_possible_truncation)] + fn get_power_usage(&self) -> Option { + self.read_hwmon_file::("power1_input") + .or_else(|| { + let energy = self.read_hwmon_file("energy1_input")?; + let timestamp = Instant::now(); + + match self.last_energy_value.replace(Some((timestamp, energy))) { + Some((last_timestamp, last_energy)) => { + let time_delta = timestamp - last_timestamp; + let energy_delta = energy - last_energy; + + Some(energy_delta / time_delta.as_millis() as u64 * 1000) + } + None => None, + } + }) + .map(|value| value as f64 / 1_000_000.0) + } + + fn get_temperatures(&self) -> HashMap { + self.read_hwmon_file::("temp1_input") + .into_iter() + .map(|temp| { + let key = "gpu".to_owned(); + let temperature = Temperature { + current: Some(temp / 1000.0), + crit: None, + crit_hyst: None, + }; + (key, temperature) + }) + .collect() + } + + fn read_freq(&self, freq: FrequencyType) -> Option { + self.freq_path(freq).and_then(|path| self.read_file(&path)) + } + + fn write_freq(&self, freq: FrequencyType, value: i32) -> anyhow::Result<()> { + let path = self.freq_path(freq).context("Frequency info not found")?; + self.write_file(path, &value.to_string()) + .context("Could not write frequency")?; + Ok(()) + } + + fn freq_path(&self, freq: FrequencyType) -> Option { + let path = &self.common.sysfs_path; + + match self.driver_type { + DriverType::I915 => { + let card_path = path.parent().expect("Device has no parent path"); + + let infix = match freq { + FrequencyType::Cur => "cur", + FrequencyType::Act => "act", + FrequencyType::Min => "min", + FrequencyType::Max => "max", + FrequencyType::Rp0 => "RP0", + FrequencyType::Rpe => "RP1", + FrequencyType::Rpn => "RPn", + }; + Some(card_path.join(format!("gt_{infix}_freq_mhz"))) + } + DriverType::Xe => self.first_tile_gt().map(|gt_path| { + let prefix = match freq { + FrequencyType::Cur => "cur", + FrequencyType::Act => "act", + FrequencyType::Min => "min", + FrequencyType::Max => "max", + FrequencyType::Rp0 => "rp0", + FrequencyType::Rpe => "rpe", + FrequencyType::Rpn => "rpn", + }; + gt_path.join("freq0").join(format!("{prefix}_freq")) + }), + } + } + + fn get_throttle_info(&self) -> Option>> { + match self.driver_type { + DriverType::I915 => { + let mut reasons = BTreeMap::new(); + + let card_path = self + .common + .sysfs_path + .parent() + .expect("Device has no parent path"); + let gt_path = card_path.join("gt").join("gt0"); + let gt_files = fs::read_dir(gt_path).ok()?; + for file in gt_files.flatten() { + if let Some(name) = file.file_name().to_str() { + if let Some(reason) = name.strip_prefix("throttle_reason_") { + if reason == "status" { + continue; + } + + if let Some(value) = self.read_file::(file.path()) { + if value != 0 { + reasons.insert(reason.to_owned(), vec![]); + } + } + } + } + } + + Some(reasons) + } + DriverType::Xe => None, + } + } +} + +#[derive(Clone, Copy)] +enum FrequencyType { + Cur, + Act, + Min, + Max, + Rp0, + Rpe, + Rpn, } diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/dev b/lact-daemon/src/tests/data/intel/a380-i915/card1/dev new file mode 100644 index 00000000..fdd256a9 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/dev @@ -0,0 +1 @@ +226:1 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/current_link_speed b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/current_link_speed new file mode 100644 index 00000000..73f5ba31 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/current_link_speed @@ -0,0 +1 @@ +2.5 GT/s PCIe diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/current_link_width b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/current_link_width new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/current_link_width @@ -0,0 +1 @@ +1 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/energy1_input b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/energy1_input new file mode 100644 index 00000000..8aac16f6 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/energy1_input @@ -0,0 +1 @@ +25637161804 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/fan1_input b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/fan1_input new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/fan1_input @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/in0_input b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/in0_input new file mode 100644 index 00000000..4b1e299f --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/in0_input @@ -0,0 +1 @@ +603 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/name b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/name new file mode 100644 index 00000000..03e2c070 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/name @@ -0,0 +1 @@ +i915 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/control b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/control new file mode 100644 index 00000000..865faf10 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/control @@ -0,0 +1 @@ +auto diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/runtime_active_time b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/runtime_active_time new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/runtime_active_time @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/runtime_status b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/runtime_status new file mode 100644 index 00000000..ad7ccf7a --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/runtime_status @@ -0,0 +1 @@ +unsupported diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/runtime_suspended_time b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/runtime_suspended_time new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power/runtime_suspended_time @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power1_max b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power1_max new file mode 100644 index 00000000..efe3c46d --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power1_max @@ -0,0 +1 @@ +55000000 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power1_max_interval b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power1_max_interval new file mode 100644 index 00000000..a3f7bcee --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power1_max_interval @@ -0,0 +1 @@ +28000 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power1_rated_max b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power1_rated_max new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/power1_rated_max @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/temp1_input b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/temp1_input new file mode 100644 index 00000000..2ef4768d --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/temp1_input @@ -0,0 +1 @@ +55000 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/uevent b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/hwmon/hwmon1/uevent new file mode 100644 index 00000000..e69de29b diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/uevent b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/uevent new file mode 100644 index 00000000..5c85f98b --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/uevent @@ -0,0 +1,6 @@ +DRIVER=i915 +PCI_CLASS=30000 +PCI_ID=8086:56A5 +PCI_SUBSYS_ID=1849:6004 +PCI_SLOT_NAME=0000:0b:00.0 +MODALIAS=pci:v00008086d000056A5sv00001849sd00006004bc03sc00i00 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/device/vendor b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/vendor new file mode 100644 index 00000000..ce6dc4da --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/device/vendor @@ -0,0 +1 @@ +0x8086 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/error b/lact-daemon/src/tests/data/intel/a380-i915/card1/error new file mode 100644 index 00000000..a0bde5ef --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/error @@ -0,0 +1 @@ +No error state collected diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_down_threshold_pct b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_down_threshold_pct new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_down_threshold_pct @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_max_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_max_freq_mhz new file mode 100644 index 00000000..343526e3 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_max_freq_mhz @@ -0,0 +1 @@ +2450 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_min_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_min_freq_mhz new file mode 100644 index 00000000..697cb3a2 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_min_freq_mhz @@ -0,0 +1 @@ +300 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_up_threshold_pct b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_up_threshold_pct new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/.defaults/rps_up_threshold_pct @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/id b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/id new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/id @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_RP0_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_RP0_freq_mhz new file mode 100644 index 00000000..50989ffe --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_RP0_freq_mhz @@ -0,0 +1 @@ +1400 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_RPn_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_RPn_freq_mhz new file mode 100644 index 00000000..50989ffe --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_RPn_freq_mhz @@ -0,0 +1 @@ +1400 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_freq_factor b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_freq_factor new file mode 100644 index 00000000..a949a93d --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_freq_factor @@ -0,0 +1 @@ +128 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_freq_factor.scale b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_freq_factor.scale new file mode 100644 index 00000000..f4c20d98 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/media_freq_factor.scale @@ -0,0 +1 @@ +0.00390625 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/punit_req_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/punit_req_freq_mhz new file mode 100644 index 00000000..e9f960cf --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/punit_req_freq_mhz @@ -0,0 +1 @@ +600 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rc6_enable b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rc6_enable new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rc6_enable @@ -0,0 +1 @@ +1 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rc6_residency_ms b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rc6_residency_ms new file mode 100644 index 00000000..65e24a52 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rc6_residency_ms @@ -0,0 +1 @@ +6534 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_RP0_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_RP0_freq_mhz new file mode 100644 index 00000000..343526e3 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_RP0_freq_mhz @@ -0,0 +1 @@ +2450 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_RP1_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_RP1_freq_mhz new file mode 100644 index 00000000..e9f960cf --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_RP1_freq_mhz @@ -0,0 +1 @@ +600 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_RPn_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_RPn_freq_mhz new file mode 100644 index 00000000..697cb3a2 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_RPn_freq_mhz @@ -0,0 +1 @@ +300 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_act_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_act_freq_mhz new file mode 100644 index 00000000..e9f960cf --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_act_freq_mhz @@ -0,0 +1 @@ +600 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_boost_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_boost_freq_mhz new file mode 100644 index 00000000..343526e3 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_boost_freq_mhz @@ -0,0 +1 @@ +2450 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_cur_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_cur_freq_mhz new file mode 100644 index 00000000..e9f960cf --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_cur_freq_mhz @@ -0,0 +1 @@ +600 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_max_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_max_freq_mhz new file mode 100644 index 00000000..343526e3 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_max_freq_mhz @@ -0,0 +1 @@ +2450 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_min_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_min_freq_mhz new file mode 100644 index 00000000..697cb3a2 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/rps_min_freq_mhz @@ -0,0 +1 @@ +300 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/slpc_ignore_eff_freq b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/slpc_ignore_eff_freq new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/slpc_ignore_eff_freq @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_pl1 b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_pl1 new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_pl1 @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_pl2 b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_pl2 new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_pl2 @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_pl4 b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_pl4 new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_pl4 @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_prochot b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_prochot new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_prochot @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_ratl b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_ratl new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_ratl @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_status b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_status new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_status @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_thermal b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_thermal new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_thermal @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_vr_tdc b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_vr_tdc new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_vr_tdc @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_vr_thermalert b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_vr_thermalert new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt/gt0/throttle_reason_vr_thermalert @@ -0,0 +1 @@ +0 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_RP0_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_RP0_freq_mhz new file mode 100644 index 00000000..343526e3 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_RP0_freq_mhz @@ -0,0 +1 @@ +2450 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_RP1_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_RP1_freq_mhz new file mode 100644 index 00000000..e9f960cf --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_RP1_freq_mhz @@ -0,0 +1 @@ +600 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_RPn_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_RPn_freq_mhz new file mode 100644 index 00000000..697cb3a2 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_RPn_freq_mhz @@ -0,0 +1 @@ +300 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_act_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_act_freq_mhz new file mode 100644 index 00000000..e9f960cf --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_act_freq_mhz @@ -0,0 +1 @@ +600 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_boost_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_boost_freq_mhz new file mode 100644 index 00000000..343526e3 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_boost_freq_mhz @@ -0,0 +1 @@ +2450 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_cur_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_cur_freq_mhz new file mode 100644 index 00000000..e9f960cf --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_cur_freq_mhz @@ -0,0 +1 @@ +600 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_max_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_max_freq_mhz new file mode 100644 index 00000000..343526e3 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_max_freq_mhz @@ -0,0 +1 @@ +2450 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_min_freq_mhz b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_min_freq_mhz new file mode 100644 index 00000000..697cb3a2 --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/gt_min_freq_mhz @@ -0,0 +1 @@ +300 diff --git a/lact-daemon/src/tests/data/intel/a380-i915/card1/uevent b/lact-daemon/src/tests/data/intel/a380-i915/card1/uevent new file mode 100644 index 00000000..96ce9f7f --- /dev/null +++ b/lact-daemon/src/tests/data/intel/a380-i915/card1/uevent @@ -0,0 +1,4 @@ +MAJOR=226 +MINOR=1 +DEVNAME=dri/card1 +DEVTYPE=drm_minor diff --git a/lact-daemon/src/tests/snapshots/lact_daemon__tests__intel__a380-i915.snap b/lact-daemon/src/tests/snapshots/lact_daemon__tests__intel__a380-i915.snap new file mode 100644 index 00000000..0309a307 --- /dev/null +++ b/lact-daemon/src/tests/snapshots/lact_daemon__tests__intel__a380-i915.snap @@ -0,0 +1,92 @@ +--- +source: lact-daemon/src/tests/mod.rs +expression: device_info +--- +{ + "clocks_info": { + "table": { + "type": "intel", + "value": { + "gt_freq": [ + 300, + 2450 + ], + "rp0_freq": 2450, + "rpe_freq": 600, + "rpn_freq": 300 + } + } + }, + "info": { + "driver": "i915", + "drm_info": { + "vram_clock_ratio": 1.0 + }, + "link_info": {}, + "pci_info": { + "device_pci_info": { + "model": "DG2 [Arc A380]", + "model_id": "56A5", + "vendor": "Intel Corporation", + "vendor_id": "8086" + }, + "subsystem_pci_info": { + "model_id": "6004", + "vendor": "ASRock Incorporation", + "vendor_id": "1849" + } + }, + "vulkan_info": { + "api_version": "", + "device_name": "", + "driver": { + "version": 0 + }, + "enabled_layers": [], + "extensions": {}, + "features": {} + } + }, + "pci_info": { + "device_pci_info": { + "model": "DG2 [Arc A380]", + "model_id": "56A5", + "vendor": "Intel Corporation", + "vendor_id": "8086" + }, + "subsystem_pci_info": { + "model_id": "6004", + "vendor": "ASRock Incorporation", + "vendor_id": "1849" + } + }, + "power_profile_modes": null, + "stats": { + "clockspeed": { + "current_gfxclk": 600, + "gpu_clockspeed": 600 + }, + "fan": { + "control_enabled": false, + "pmfw_info": {} + }, + "power": { + "cap_current": 55.0, + "cap_default": 55.0, + "cap_max": 110.0, + "cap_min": 0.0, + "current": 0.0 + }, + "temps": { + "gpu": { + "crit": null, + "crit_hyst": null, + "current": 55.0 + } + }, + "voltage": { + "gpu": 603 + }, + "vram": {} + } +} diff --git a/lact-daemon/src/tests/snapshots/lact_daemon__tests__intel__cometlake.snap b/lact-daemon/src/tests/snapshots/lact_daemon__tests__intel__cometlake.snap index 5d50a3a3..2ab58415 100644 --- a/lact-daemon/src/tests/snapshots/lact_daemon__tests__intel__cometlake.snap +++ b/lact-daemon/src/tests/snapshots/lact_daemon__tests__intel__cometlake.snap @@ -70,7 +70,9 @@ expression: device_info "control_enabled": false, "pmfw_info": {} }, - "power": {}, + "power": { + "cap_min": 0.0 + }, "temps": {}, "voltage": {}, "vram": {} diff --git a/lact-daemon/src/tests/snapshots/lact_daemon__tests__intel__tigerlake.snap b/lact-daemon/src/tests/snapshots/lact_daemon__tests__intel__tigerlake.snap index f131d96f..84caecb4 100644 --- a/lact-daemon/src/tests/snapshots/lact_daemon__tests__intel__tigerlake.snap +++ b/lact-daemon/src/tests/snapshots/lact_daemon__tests__intel__tigerlake.snap @@ -70,7 +70,9 @@ expression: device_info "control_enabled": false, "pmfw_info": {} }, - "power": {}, + "power": { + "cap_min": 0.0 + }, "temps": {}, "voltage": {}, "vram": {} diff --git a/lact-gui/src/app/pages/oc_page/gpu_stats_section.rs b/lact-gui/src/app/pages/oc_page/gpu_stats_section.rs index a5f4a696..934e965f 100644 --- a/lact-gui/src/app/pages/oc_page/gpu_stats_section.rs +++ b/lact-gui/src/app/pages/oc_page/gpu_stats_section.rs @@ -169,14 +169,14 @@ fn format_clockspeed(value: Option, ratio: f64) -> String { format!("{:.3} GHz", value.unwrap_or(0) as f64 / 1000.0 * ratio) } -fn format_current_gfxclk(value: Option) -> String { +fn format_current_gfxclk(value: Option) -> String { if let Some(v) = value { // if the APU/GPU dose not acually support current_gfxclk, // the value will be `u16::MAX (65535)` - if v == u16::MAX { + if v >= u16::MAX as u64 || v == 0 { "N/A".to_string() } else { - format_clockspeed(Some(v as u64), 1.0) + format_clockspeed(Some(v), 1.0) } } else { "N/A".to_string() diff --git a/lact-gui/src/app/pages/oc_page/power_cap_section.rs b/lact-gui/src/app/pages/oc_page/power_cap_section.rs index a778dd7b..5690c2de 100644 --- a/lact-gui/src/app/pages/oc_page/power_cap_section.rs +++ b/lact-gui/src/app/pages/oc_page/power_cap_section.rs @@ -89,6 +89,10 @@ mod imp { let text = format!("{}/{} W", section.current_value(), section.max_value()); section.set_value_text(text); }); + obj.connect_max_value_notify(move |section| { + let text = format!("{}/{} W", section.current_value(), section.max_value()); + section.set_value_text(text); + }); self.reset_button.connect_clicked(clone!( #[strong] diff --git a/lact-schema/src/lib.rs b/lact-schema/src/lib.rs index b0fbb761..24406dff 100644 --- a/lact-schema/src/lib.rs +++ b/lact-schema/src/lib.rs @@ -169,13 +169,13 @@ pub struct NvidiaClocksTable { #[skip_serializing_none] #[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq)] pub struct IntelClocksTable { - pub gt_freq: Option<(u32, u32)>, + pub gt_freq: Option<(u64, u64)>, /// - rpn_freq: The Render Performance (RP) N level, which is the minimal one. - pub rpn_freq: Option, + pub rpn_freq: Option, /// - rpe_freq: The Render Performance (RP) E level, which is the efficient one. - pub rpe_freq: Option, + pub rpe_freq: Option, /// - rp0_freq: The Render Performance (RP) 0 level, which is the maximum one. - pub rp0_freq: Option, + pub rp0_freq: Option, } #[derive(Serialize, Deserialize, Default, Debug, Clone)] @@ -288,7 +288,7 @@ pub struct PmfwInfo { pub struct ClockspeedStats { pub gpu_clockspeed: Option, /// Target clock - pub current_gfxclk: Option, + pub current_gfxclk: Option, pub vram_clockspeed: Option, }