Commit 12e8ed96 authored by Ashutosh Dixit's avatar Ashutosh Dixit Committed by Rodrigo Vivi

drm/i915/hwmon: Accept writes of value 0 to power1_max_interval

The value shown by power1_max_interval in millisec is essentially:
	((1.x * power(2,y)) * 1000) >> 10
Where x and y are read from a HW register. On ATSM, x and y are 0 on
power-up so the value shown is 0.

Writes of 0 to power1_max_interval had previously been disallowed to avoid
computing ilog2(0) but this resulted in the corner-case bug
below. Therefore allow writes of 0 now but special case that write to
x = y = 0.

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/7754Signed-off-by: default avatarAshutosh Dixit <ashutosh.dixit@intel.com>
Reviewed-by: default avatarBadal Nilawar <badal.nilawar@intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230228044334.3630391-1-ashutosh.dixit@intel.com
parent 30c35a4b
...@@ -218,11 +218,15 @@ hwm_power1_max_interval_store(struct device *dev, ...@@ -218,11 +218,15 @@ hwm_power1_max_interval_store(struct device *dev,
/* val in hw units */ /* val in hw units */
val = DIV_ROUND_CLOSEST_ULL((u64)val << hwmon->scl_shift_time, SF_TIME); val = DIV_ROUND_CLOSEST_ULL((u64)val << hwmon->scl_shift_time, SF_TIME);
/* Convert to 1.x * power(2,y) */ /* Convert to 1.x * power(2,y) */
if (!val) if (!val) {
return -EINVAL; /* Avoid ilog2(0) */
y = ilog2(val); y = 0;
/* x = (val - (1 << y)) >> (y - 2); */ x = 0;
x = (val - (1ul << y)) << x_w >> y; } else {
y = ilog2(val);
/* x = (val - (1 << y)) >> (y - 2); */
x = (val - (1ul << y)) << x_w >> y;
}
rxy = REG_FIELD_PREP(PKG_PWR_LIM_1_TIME_X, x) | REG_FIELD_PREP(PKG_PWR_LIM_1_TIME_Y, y); rxy = REG_FIELD_PREP(PKG_PWR_LIM_1_TIME_X, x) | REG_FIELD_PREP(PKG_PWR_LIM_1_TIME_Y, y);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment