[PATCH v3] drm/xe/hwmon: Add SW clamp for power limits writes
Riana Tauro
riana.tauro at intel.com
Fri Aug 8 05:37:31 UTC 2025
Hi Karthik
On 8/7/2025 7:36 PM, Karthik Poosa wrote:
> 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)
>
> Signed-off-by: Karthik Poosa <karthik.poosa at intel.com>
> Fixes: 92d44a422d0d ("drm/xe/hwmon: Expose card reactive critical power")
> Fixes: fb1b70607f73 ("drm/xe/hwmon: Expose power attributes")
> ---
> drivers/gpu/drm/xe/xe_hwmon.c | 29 +++++++++++++++++++++++++++++
> 1 file changed, 29 insertions(+)
>
> diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c
> index f08fc4377d25..a43bc8b91fea 100644
> --- a/drivers/gpu/drm/xe/xe_hwmon.c
> +++ b/drivers/gpu/drm/xe/xe_hwmon.c
> @@ -332,6 +332,7 @@ static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, u32 attr, int channe
> int ret = 0;
> u32 reg_val, max;
> struct xe_reg rapl_limit;
> + u64 max_mbx_power_limit = 0;
>
> mutex_lock(&hwmon->hwmon_lock);
>
> @@ -356,6 +357,20 @@ static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, u32 attr, int channe
> goto unlock;
> }
>
> + /*
> + * If the sysfs value exceeds the pcode mailbox cmd WRITE_PSYSGPU/PACKAGE_POWER_LIMIT
> + * max supported value, clamp it to the command's max (U12.3 format).
> + * This is to avoid truncation during reg_val calculation below and ensure the valid
> + * power limit is sent for pcode which would clamp it to card-supported value.
> + */
> + max_mbx_power_limit = ((PWR_LIM_VAL) >> hwmon->scl_shift_power) * SF_POWER;
> + if (value > max_mbx_power_limit) {
> + value = max_mbx_power_limit;
> + drm_info(&hwmon->xe->drm,
> + "Sysfs value for ch %d %s exceeds limit; clamped to supported maximum\n",
> + channel, PWR_ATTR_TO_STR(attr));
Why semicolon here?
Expand ch to channel. Unnecessary to mention "Sysfs"
With the above changes
Reviewed-by: Riana Tauro <riana.tauro at intel.com>
> + }
> +
> /* Computation in 64-bits to avoid overflow. Round to nearest. */
> reg_val = DIV_ROUND_CLOSEST_ULL((u64)value << hwmon->scl_shift_power, SF_POWER);
>
> @@ -739,9 +754,23 @@ static int xe_hwmon_power_curr_crit_write(struct xe_hwmon *hwmon, int channel,
> {
> int ret;
> u32 uval;
> + u64 max_crit_power_curr = 0;
>
> mutex_lock(&hwmon->hwmon_lock);
>
> + /*
> + * If the sysfs value exceeds the pcode mailbox cmd POWER_SETUP_SUBCOMMAND_WRITE_I1
> + * max supported value, clamp it to the command's max (U10.6 format).
> + * This is to avoid truncation during uval calculation below and ensure the valid power
> + * limit is sent for pcode which would clamp it to card-supported value.
> + */
> + max_crit_power_curr = (POWER_SETUP_I1_DATA_MASK >> POWER_SETUP_I1_SHIFT) * scale_factor;
> + if (value > max_crit_power_curr) {
> + value = max_crit_power_curr;
> + drm_info(&hwmon->xe->drm,
> + "Sysfs value for ch %d exceeds limit; clamped to supported maximum\n",
> + channel);
> + }
> uval = DIV_ROUND_CLOSEST_ULL(value << POWER_SETUP_I1_SHIFT, scale_factor);
> ret = xe_hwmon_pcode_write_i1(hwmon, uval);
>
More information about the Intel-xe
mailing list