On Mon, 23 May 2022 04:08:40 -0700, Badal Nilawar wrote: > > diff --git a/drivers/gpu/drm/i915/i915_hwmon.c b/drivers/gpu/drm/i915/i915_hwmon.c > index b94c11f2517f..b35c4de73f30 100644 > --- a/drivers/gpu/drm/i915/i915_hwmon.c > +++ b/drivers/gpu/drm/i915/i915_hwmon.c > @@ -18,8 +18,10 @@ > /* > * SF_* - scale factors for particular quantities according to hwmon spec. > * - power - microwatts > + * - energy - microjoules > */ > #define SF_POWER 1000000 > +#define SF_ENERGY 1000000 > > #define FIELD_SHIFT(__mask) \ > (BUILD_BUG_ON_ZERO(!__builtin_constant_p(__mask)) + \ > @@ -94,6 +96,136 @@ _field_scale_and_write(struct i915_hwmon_drvdata *ddat, i915_reg_t rgadr, > bits_to_clear, bits_to_set); > } > > +/* > + * _i915_energy1_input_sub - A custom function to obtain energy1_input. > + * Use a custom function instead of the usual hwmon helpers in order to > + * guarantee 64-bits of result to user-space. We need to look into whether energy needs to be a custom interface or can it just be the standard interface. The justification for custom interface is that energy needs to be a u64 but the standard interface is already a long which is at least 63 bits already. So the question is is that extra bit needed which justifies a custom interface? > + * Units are microjoules. > + * > + * The underlying hardware register is 32-bits and is subject to overflow. > + * This function compensates for overflow of the 32-bit register by detecting > + * wrap-around and incrementing an overflow counter. > + * This only works if the register is sampled often enough to avoid > + * missing an instance of overflow - achieved either by repeated > + * queries through the API, or via a possible timer (future - TBD) that > + * ensures values are read often enough to catch all overflows. > + * > + * How long before overflow? For example, with an example scaling bit > + * shift of 14 bits (see register *PACKAGE_POWER_SKU_UNIT) and a power draw of > + * 1000 watts, the 32-bit counter will overflow in approximately 4.36 minutes. > + * > + * Examples: > + * 1 watt: (2^32 >> 14) / 1 W / (60 * 60 * 24) secs/day -> 3 days > + * 1000 watts: (2^32 >> 14) / 1000 W / 60 secs/min -> 4.36 minutes We need to "sample" the energy often enough to avoid 32 bit counter overflow. But that can be a later patch.