Skip to content

Commit 55d49f0

Browse files
kpoosarodrigovivi
authored andcommitted
drm/xe/hwmon: Add SW clamp for power limits writes
Clamp writes to power limits powerX_crit/currX_crit, powerX_cap, powerX_max, to the maximum supported by the pcode mailbox when sysfs-provided values exceed this limit. Although the pcode already performs clamping, values beyond the pcode mailbox's supported range get truncated, leading to incorrect critical power settings. This patch ensures proper clamping to prevent such truncation. v2: - Address below review comments. (Riana) - Split comments into multiple sentences. - Use local variables for readability. - Add a debug log. - Use u64 instead of unsigned long. v3: - Change drm_dbg logs to drm_info. (Badal) v4: - Rephrase the drm_info log. (Rodrigo, Riana) - Rename variable max_mbx_power_limit to max_supp_power_limit, as limit is same for platforms with and without mailbox power limit support. Signed-off-by: Karthik Poosa <[email protected]> Fixes: 92d44a4 ("drm/xe/hwmon: Expose card reactive critical power") Fixes: fb1b706 ("drm/xe/hwmon: Expose power attributes") Reviewed-by: Riana Tauro <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Rodrigo Vivi <[email protected]> (cherry picked from commit d301eb9) Signed-off-by: Rodrigo Vivi <[email protected]>
1 parent 2dd7a47 commit 55d49f0

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

drivers/gpu/drm/xe/xe_hwmon.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, u32 attr, int channe
332332
int ret = 0;
333333
u32 reg_val, max;
334334
struct xe_reg rapl_limit;
335+
u64 max_supp_power_limit = 0;
335336

336337
mutex_lock(&hwmon->hwmon_lock);
337338

@@ -356,6 +357,20 @@ static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, u32 attr, int channe
356357
goto unlock;
357358
}
358359

360+
/*
361+
* If the sysfs value exceeds the maximum pcode supported power limit value, clamp it to
362+
* the supported maximum (U12.3 format).
363+
* This is to avoid truncation during reg_val calculation below and ensure the valid
364+
* power limit is sent for pcode which would clamp it to card-supported value.
365+
*/
366+
max_supp_power_limit = ((PWR_LIM_VAL) >> hwmon->scl_shift_power) * SF_POWER;
367+
if (value > max_supp_power_limit) {
368+
value = max_supp_power_limit;
369+
drm_info(&hwmon->xe->drm,
370+
"Power limit clamped as selected %s exceeds channel %d limit\n",
371+
PWR_ATTR_TO_STR(attr), channel);
372+
}
373+
359374
/* Computation in 64-bits to avoid overflow. Round to nearest. */
360375
reg_val = DIV_ROUND_CLOSEST_ULL((u64)value << hwmon->scl_shift_power, SF_POWER);
361376

@@ -739,9 +754,23 @@ static int xe_hwmon_power_curr_crit_write(struct xe_hwmon *hwmon, int channel,
739754
{
740755
int ret;
741756
u32 uval;
757+
u64 max_crit_power_curr = 0;
742758

743759
mutex_lock(&hwmon->hwmon_lock);
744760

761+
/*
762+
* If the sysfs value exceeds the pcode mailbox cmd POWER_SETUP_SUBCOMMAND_WRITE_I1
763+
* max supported value, clamp it to the command's max (U10.6 format).
764+
* This is to avoid truncation during uval calculation below and ensure the valid power
765+
* limit is sent for pcode which would clamp it to card-supported value.
766+
*/
767+
max_crit_power_curr = (POWER_SETUP_I1_DATA_MASK >> POWER_SETUP_I1_SHIFT) * scale_factor;
768+
if (value > max_crit_power_curr) {
769+
value = max_crit_power_curr;
770+
drm_info(&hwmon->xe->drm,
771+
"Power limit clamped as selected exceeds channel %d limit\n",
772+
channel);
773+
}
745774
uval = DIV_ROUND_CLOSEST_ULL(value << POWER_SETUP_I1_SHIFT, scale_factor);
746775
ret = xe_hwmon_pcode_write_i1(hwmon, uval);
747776

0 commit comments

Comments
 (0)