Skip to content

Commit

Permalink
feat: support for voltage offset in od range
Browse files Browse the repository at this point in the history
RDNA3 GPUs now provide a voltage offset range in OD_RANGE.
Also added a `.set_voltage_offset` method for setting the voltage with a
range check.
  • Loading branch information
ilya-zlobintsev committed Jan 13, 2024
1 parent 1a29bde commit 5ec9704
Show file tree
Hide file tree
Showing 68 changed files with 203 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "amdgpu-sysfs"
version = "0.12.10"
version = "0.13.0"
authors = ["Ilya Zlobintsev <[email protected]>"]
edition = "2021"
license = "GPL-3.0"
Expand Down
5 changes: 5 additions & 0 deletions src/gpu_handle/overdrive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,11 @@ impl Range {
max: None,
}
}

/// Tries to convert the current range into a (min, max) pair.
pub fn into_full(self) -> Option<(i32, i32)> {
self.min.zip(self.max)
}
}

impl TryFrom<Range> for (i32, i32) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ od_range:
max: 1075
curve_sclk_points: []
curve_voltage_points: []
voltage_offset: ~

Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ od_range:
max: 1075
curve_sclk_points: []
curve_voltage_points: []
voltage_offset: ~

Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ od_range:
max: 1075
curve_sclk_points: []
curve_voltage_points: []
voltage_offset: ~

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
source: src/gpu_handle/overdrive/vega20.rs
expression: table
---
current_sclk_range:
min: 500
max: 2660
current_mclk_range:
min: 97
max: 1219
vddc_curve: []
voltage_offset: 0
od_range:
sclk:
min: 500
max: 5000
mclk:
min: 97
max: 1500
curve_sclk_points: []
curve_voltage_points: []
voltage_offset:
min: -450
max: 0

Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ od_range:
max: 1500
curve_sclk_points: []
curve_voltage_points: []
voltage_offset:
min: -450
max: 0

Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ od_range:
curve_voltage_points:
- min: -450
max: 0
voltage_offset: ~

42 changes: 41 additions & 1 deletion src/gpu_handle/overdrive/vega20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub struct Table {
pub vddc_curve: Vec<ClocksLevel>,
/// Voltage offset(in mV) applied on target voltage calculation.
/// This is available for Sienna Cichlid, Navy Flounder and Dimgrey Cavefish.
///
/// Note: editing this value directly does not check if it's in the allowed range!
pub voltage_offset: Option<i32>,
/// The allowed ranges for clockspeeds and voltages.
pub od_range: OdRange,
Expand Down Expand Up @@ -158,6 +160,24 @@ impl ClocksTable for Table {
}
}

impl Table {
/// Sets the voltage offset, checking if it's in range if the GPU provided one
///
/// Note: RDNA2 GPUs use a voltage offset but do not provide a range
pub fn set_voltage_offset(&mut self, offset: i32) -> Result<()> {
if let Some(offset_range) = self.od_range.voltage_offset {
if let Some((min, max)) = offset_range.into_full() {
if !(min..=max).contains(&offset) {
return Err(Error::not_allowed(format!("Provided voltage offset {offset} is out of range, should be between {min} and {max}")));
}
}
}

self.voltage_offset = Some(offset);
Ok(())
}
}

impl FromStr for Table {
type Err = Error;

Expand All @@ -174,6 +194,7 @@ impl FromStr for Table {
let mut curve_voltage_points = Vec::with_capacity(3);

let mut voltage_offset = None;
let mut voltage_offset_range = None;

let mut i = 1;
for line in s
Expand All @@ -188,7 +209,6 @@ impl FromStr for Table {
"OD_VDDC_CURVE:" => current_section = Some(Section::VddcCurve),
"OD_VDDGFX_OFFSET:" => current_section = Some(Section::VddGfxOffset),
line => match current_section {
_ if line.starts_with("VDDGFX_OFFSET:") => continue,
// Voltage points will overwrite maximum clock info, with the last one taking priority
Some(Section::Range) if line.starts_with("VDDC_CURVE_SCLK") => {
let (range, _) = parse_range_line(line, i)?;
Expand All @@ -206,6 +226,7 @@ impl FromStr for Table {
match name {
"SCLK" => allowed_sclk_range = Some(range),
"MCLK" => allowed_mclk_range = Some(range),
"VDDGFX_OFFSET" => voltage_offset_range = Some(range),
other => {
return Err(ParseError {
msg: format!("Unexpected range item: {other}"),
Expand Down Expand Up @@ -247,6 +268,7 @@ impl FromStr for Table {
})?),
curve_sclk_points,
curve_voltage_points,
voltage_offset: voltage_offset_range,
};
let current_sclk_range = current_sclk_range.ok_or_else(|| ParseError {
msg: "No current sclk range found".to_owned(),
Expand Down Expand Up @@ -319,6 +341,8 @@ pub struct OdRange {
pub curve_sclk_points: Vec<Range>,
/// Ranges available at specific levels.
pub curve_voltage_points: Vec<Range>,
/// Allowed voltage offset range. Present on RDNA3+.
pub voltage_offset: Option<Range>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -402,6 +426,7 @@ mod tests {
const TABLE_6800: &str = include_table!("rx6800");
const TABLE_7900XTX: &str = include_table!("rx7900xtx");
const TABLE_7900XT: &str = include_table!("rx7900xt");
const TABLE_7800XT: &str = include_table!("rx7800xt");

#[test]
fn parse_5700xt_full() {
Expand Down Expand Up @@ -430,6 +455,7 @@ mod tests {
mclk: Some(Range::full(625, 950)),
curve_sclk_points,
curve_voltage_points,
voltage_offset: None,
};
assert_eq!(table.od_range, od_range);
}
Expand Down Expand Up @@ -532,6 +558,7 @@ mod tests {
mclk: None,
curve_sclk_points: Vec::new(),
curve_voltage_points: Vec::new(),
voltage_offset: None,
},
};

Expand Down Expand Up @@ -644,4 +671,17 @@ mod tests {
let table = Table::from_str(TABLE_7900XT).unwrap();
assert_yaml_snapshot!(table);
}

#[test]
fn parse_7800xt_full() {
let table = Table::from_str(TABLE_7800XT).unwrap();
assert_yaml_snapshot!(table);
}

#[test]
fn set_7800xt_voltage() {
let mut table = Table::from_str(TABLE_7800XT).unwrap();
table.set_voltage_offset(-300).unwrap();
table.set_voltage_offset(100).unwrap_err();
}
}
1 change: 1 addition & 0 deletions tests/data/rx7800xt/current_link_speed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
16.0 GT/s PCIe
1 change: 1 addition & 0 deletions tests/data/rx7800xt/current_link_width
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
16
1 change: 1 addition & 0 deletions tests/data/rx7800xt/gpu_busy_percent
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
OD_ACOUSTIC_LIMIT:
2450
OD_RANGE:
ACOUSTIC_LIMIT: 500 3100
ACOUSTIC_LIMIT: 500 3100
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
OD_ACOUSTIC_TARGET:
2200
OD_RANGE:
ACOUSTIC_TARGET: 500 3100
ACOUSTIC_TARGET: 500 3100
2 changes: 1 addition & 1 deletion tests/data/rx7800xt/gpu_od/fan_ctrl/fan_curve
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ OD_FAN_CURVE:
4: 0C 0%
OD_RANGE:
FAN_CURVE(hotspot temp): 25C 100C
FAN_CURVE(fan speed): 20% 100%
FAN_CURVE(fan speed): 20% 100%
4 changes: 2 additions & 2 deletions tests/data/rx7800xt/gpu_od/fan_ctrl/fan_minimum_pwm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FAN_MINIMUM_PWM:
20
97
OD_RANGE:
MINIMUM_PWM: 20 100
MINIMUM_PWM: 20 100
2 changes: 1 addition & 1 deletion tests/data/rx7800xt/gpu_od/fan_ctrl/fan_target_temperature
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FAN_TARGET_TEMPERATURE:
95
OD_RANGE:
TARGET_TEMPERATURE: 25 110
TARGET_TEMPERATURE: 25 110
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/fan1_enable
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/fan1_input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/fan1_max
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3100
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/fan1_min
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/fan1_target
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/freq1_input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/freq1_label
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sclk
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/freq2_input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
96000000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/freq2_label
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mclk
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/in0_input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
64
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/in0_label
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
vddgfx
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/power1_average
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
10000000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/power1_cap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
222000000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/power1_cap_default
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
212000000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/power1_cap_max
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
243000000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/power1_cap_min
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
190000000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/power1_label
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PPT
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/pwm1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/pwm1_enable
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/pwm1_max
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
255
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/pwm1_min
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp1_crit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
100000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp1_crit_hyst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-273150
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp1_emergency
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
105000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp1_input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
37000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp1_label
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
edge
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp2_crit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
110000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp2_crit_hyst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-273150
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp2_emergency
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
115000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp2_input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
43000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp2_label
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
junction
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp3_crit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
108000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp3_crit_hyst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-273150
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp3_emergency
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
113000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp3_input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
56000
1 change: 1 addition & 0 deletions tests/data/rx7800xt/hwmon/hwmon4/temp3_label
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mem
1 change: 1 addition & 0 deletions tests/data/rx7800xt/pp_cur_state
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
4 changes: 4 additions & 0 deletions tests/data/rx7800xt/pp_dpm_mclk
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
0: 96Mhz *
1: 456Mhz
2: 772Mhz
3: 1218Mhz
3 changes: 3 additions & 0 deletions tests/data/rx7800xt/pp_dpm_pcie
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0: 2.5GT/s, x1 78Mhz
1: 5.0GT/s, x4 156Mhz
2: 16.0GT/s, x16 623Mhz *
3 changes: 3 additions & 0 deletions tests/data/rx7800xt/pp_dpm_sclk
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0: 500Mhz
1: 0Mhz *
2: 2124Mhz
3 changes: 3 additions & 0 deletions tests/data/rx7800xt/pp_dpm_socclk
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0: 300Mhz
1: 750Mhz *
2: 1500Mhz
52 changes: 52 additions & 0 deletions tests/data/rx7800xt/pp_features
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
features high: 0x0003ebbc low: 0x71ffffff
No. Feature Bit : State
00. FW_DATA_READ ( 0) : enabled
01. DPM_GFXCLK ( 1) : enabled
02. DPM_GFX_POWER_OPTIMIZER ( 2) : enabled
03. DPM_UCLK ( 3) : enabled
04. DPM_FCLK ( 4) : enabled
05. DPM_SOCCLK ( 5) : enabled
06. DPM_MP0CLK ( 6) : enabled
07. DPM_LINK ( 7) : enabled
08. DPM_DCN ( 8) : enabled
09. VMEMP_SCALING ( 9) : enabled
10. VDDIO_MEM_SCALING (10) : enabled
11. DS_GFXCLK (11) : enabled
12. DS_SOCCLK (12) : enabled
13. DS_FCLK (13) : enabled
14. DS_LCLK (14) : enabled
15. DS_DCFCLK (15) : enabled
16. DS_UCLK (16) : enabled
17. GFX_ULV (17) : enabled
18. FW_DSTATE (18) : enabled
19. GFXOFF (19) : enabled
20. BACO (20) : enabled
21. MM_DPM (21) : enabled
22. SOC_MPCLK_DS (22) : enabled
23. BACO_MPCLK_DS (23) : enabled
24. THROTTLERS (24) : enabled
25. SMARTSHIFT (25) : disabled
26. GTHR (26) : disabled
27. ACDC (27) : disabled
28. VR0HOT (28) : enabled
29. FW_CTF (29) : enabled
30. FAN_CONTROL (30) : enabled
31. GFX_DCS (31) : disabled
32. GFX_READ_MARGIN (32) : disabled
33. LED_DISPLAY (33) : disabled
34. GFXCLK_SPREAD_SPECTRUM (34) : enabled
35. OUT_OF_BAND_MONITOR (35) : enabled
36. OPTIMIZED_VMIN (36) : enabled
37. GFX_IMU (37) : enabled
38. BOOT_TIME_CAL (38) : disabled
39. GFX_PCC_DFLL (39) : enabled
40. SOC_CG (40) : enabled
41. DF_CSTATE (41) : enabled
42. GFX_EDC (42) : disabled
43. BOOT_POWER_OPT (43) : enabled
44. CLOCK_POWER_DOWN_BYPASS (44) : disabled
45. DS_VCN (45) : enabled
46. BACO_CG (46) : enabled
47. MEM_TEMP_READ (47) : enabled
48. ATHUB_MMHUB_PG (48) : enabled
49. SOC_PCC (49) : enabled
1 change: 1 addition & 0 deletions tests/data/rx7800xt/pp_force_state
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

2 changes: 2 additions & 0 deletions tests/data/rx7800xt/pp_num_states
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
states: 1
0 default
Binary file added tests/data/rx7800xt/pp_od_clk_voltage
Binary file not shown.
2 changes: 1 addition & 1 deletion tests/data/rx7800xt/pp_power_profile_mode
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ PROFILE_INDEX(NAME) CLOCK_TYPE(NAME) FPS MinActiveFreqType MinActiveFreq Booster
0( GFXCLK) 0 2 1000 1 0 3932160 0 0
1( FCLK) 0 3 0 3 0 1310720 -6553 -6553
6 CUSTOM :
0( GFXCLK) 0 2 1000 1 0 3932160 0 0
0( GFXCLK) 0 0 1200 4 0 655360 -3276 -65536
1( FCLK) 0 3 0 3 0 1310720 -6553 -6553
7 WINDOW_3D :
0( GFXCLK) 0 0 1200 4 650 3932160 -3276 -65536
Expand Down
Binary file added tests/data/rx7800xt/pp_table
Binary file not shown.
Loading

0 comments on commit 5ec9704

Please sign in to comment.