As part of the System Managemenent Interface (SMI), use the HWMON subsystem to display power utilization. The following standard HWMON power sensors are currently supported (and appropriately scaled): /sys/class/drm/card0/device/hwmon/hwmon<i> - energy1_input - power1_cap - power1_max Some non-standard HWMON power information is also provided, such as enable bits and intervals. --------------------- V2 Rename local function parameter field_mask to field_msk in order to avoid shadowing the name of function field_mask() from include/linux/bitfield.h. V2 Change a comment introduction from "/**" to "/*", as it is not intended to match a pattern that triggers documentation. Reported-by: kernel test robot <lkp@xxxxxxxxx> V2 Slight movement of calls: - i915_hwmon_init slightly later, after call to i915_setup_sysfs() - i915_hwmon_fini slightly earlier, before i915_teardown_sysfs() V2 Fixed some strong typing issues with le32 functions. Detected by sparse in a run by kernel test robot: Reported-by: kernel test robot <lkp@xxxxxxxxx> Dale B Stimson (1): drm/i915/dg1: Add HWMON power sensor support drivers/gpu/drm/i915/Kconfig | 1 + drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_drv.c | 9 + drivers/gpu/drm/i915/i915_drv.h | 3 + drivers/gpu/drm/i915/i915_hwmon.c | 788 ++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_hwmon.h | 41 ++ drivers/gpu/drm/i915/i915_reg.h | 53 ++ 7 files changed, 896 insertions(+) create mode 100644 drivers/gpu/drm/i915/i915_hwmon.c create mode 100644 drivers/gpu/drm/i915/i915_hwmon.h Range-diff against v1: 1: 34631511e00c1 ! 1: 25117970961b4 drm/i915/dg1: Add HWMON power sensor support @@ drivers/gpu/drm/i915/i915_hwmon.c (new) + +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> ++#include <linux/types.h> + +#include "i915_drv.h" +#include "gt/intel_gt.h" @@ drivers/gpu/drm/i915/i915_hwmon.c (new) + */ +static __always_inline u64 +_field_read_and_scale(struct intel_uncore *uncore, i915_reg_t rgadr, -+ u32 field_mask, int nshift, unsigned int scale_factor) ++ u32 field_msk, int nshift, unsigned int scale_factor) +{ + intel_wakeref_t wakeref; + u32 reg_value; @@ drivers/gpu/drm/i915/i915_hwmon.c (new) + with_intel_runtime_pm(uncore->rpm, wakeref) + reg_value = intel_uncore_read(uncore, rgadr); + -+ reg_value = le32_get_bits(reg_value, field_mask); ++ reg_value = le32_get_bits(cpu_to_le32(reg_value), field_msk); + scaled_val = mul_u32_u32(scale_factor, reg_value); + + /* Shift, rounding to nearest */ @@ drivers/gpu/drm/i915/i915_hwmon.c (new) + */ +static __always_inline u64 +_field_read64_and_scale(struct intel_uncore *uncore, i915_reg_t rgadr, -+ u64 field_mask, int nshift, unsigned int scale_factor) ++ u64 field_msk, int nshift, unsigned int scale_factor) +{ + intel_wakeref_t wakeref; + u64 reg_value; @@ drivers/gpu/drm/i915/i915_hwmon.c (new) + with_intel_runtime_pm(uncore->rpm, wakeref) + reg_value = intel_uncore_read64(uncore, rgadr); + -+ reg_value = le64_get_bits(reg_value, field_mask); ++ reg_value = le64_get_bits(cpu_to_le64(reg_value), field_msk); + scaled_val = scale_factor * reg_value; + + /* Shift, rounding to nearest */ @@ drivers/gpu/drm/i915/i915_hwmon.c (new) +static __always_inline void +_field_scale_and_write(struct intel_uncore *uncore, + i915_reg_t rgadr, -+ u32 field_mask, int nshift, ++ u32 field_msk, int nshift, + unsigned int scale_factor, long lval) +{ + u32 nval; @@ drivers/gpu/drm/i915/i915_hwmon.c (new) + /* Computation in 64-bits to avoid overflow. Round to nearest. */ + nval = DIV_ROUND_CLOSEST_ULL((u64)lval << nshift, scale_factor); + -+ bits_to_clear = field_mask; -+ bits_to_set = le32_encode_bits(nval, field_mask); ++ bits_to_clear = field_msk; ++ bits_to_set = le32_to_cpu(le32_encode_bits(nval, field_msk)); + + _locked_with_pm_intel_uncore_rmw(uncore, rgadr, + bits_to_clear, bits_to_set); @@ drivers/gpu/drm/i915/i915_hwmon.c (new) + struct intel_uncore *uncore = &i915->uncore; + intel_wakeref_t wakeref; + u32 val_sku_unit; ++ __le32 le_sku_unit; + + if (IS_DG1(i915)) { + hwmon->rg.pkg_power_sku_unit = PCU_PACKAGE_POWER_SKU_UNIT; @@ drivers/gpu/drm/i915/i915_hwmon.c (new) + + intel_runtime_pm_put(uncore->rpm, wakeref); + -+ hwmon->scl_shift_power = le32_get_bits(val_sku_unit, PKG_PWR_UNIT); -+ hwmon->scl_shift_energy = le32_get_bits(val_sku_unit, PKG_ENERGY_UNIT); -+ hwmon->scl_shift_time = le32_get_bits(val_sku_unit, PKG_TIME_UNIT); ++ le_sku_unit = cpu_to_le32(val_sku_unit); ++ hwmon->scl_shift_power = le32_get_bits(le_sku_unit, PKG_PWR_UNIT); ++ hwmon->scl_shift_energy = le32_get_bits(le_sku_unit, PKG_ENERGY_UNIT); ++ hwmon->scl_shift_time = le32_get_bits(le_sku_unit, PKG_TIME_UNIT); + + /* + * There is no direct way to obtain the power default_limit. -- 2.31.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx