diff options
author | Ashutosh Dixit <ashutosh.dixit@intel.com> | 2023-02-27 20:43:34 -0800 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2023-03-01 11:25:36 -0500 |
commit | 12e8ed969852c11503216115952c84f7c2f4c6b5 (patch) | |
tree | 1f4dab73fb9619cb62a240764c302f6c48cc69fa /drivers/gpu/drm/i915/i915_hwmon.c | |
parent | 30c35a4ba9cd91e07825da8e2846887cb000114c (diff) |
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/7754
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Reviewed-by: Badal Nilawar <badal.nilawar@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230228044334.3630391-1-ashutosh.dixit@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/i915_hwmon.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_hwmon.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/i915_hwmon.c b/drivers/gpu/drm/i915/i915_hwmon.c index 7c20a6f47b92..596dd2c07010 100644 --- a/drivers/gpu/drm/i915/i915_hwmon.c +++ b/drivers/gpu/drm/i915/i915_hwmon.c @@ -218,11 +218,15 @@ hwm_power1_max_interval_store(struct device *dev, /* val in hw units */ val = DIV_ROUND_CLOSEST_ULL((u64)val << hwmon->scl_shift_time, SF_TIME); /* Convert to 1.x * power(2,y) */ - if (!val) - return -EINVAL; - y = ilog2(val); - /* x = (val - (1 << y)) >> (y - 2); */ - x = (val - (1ul << y)) << x_w >> y; + if (!val) { + /* Avoid ilog2(0) */ + y = 0; + x = 0; + } 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); |