mbox series

[v1,0/1] drm/i915/dg1: Add HWMON power sensor support

Message ID 20210413212203.793-1-dale.b.stimson@intel.com (mailing list archive)
Headers show
Series drm/i915/dg1: Add HWMON power sensor support | expand

Message

Stimson, Dale B April 13, 2021, 9:22 p.m. UTC
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@intel.com>

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@intel.com>

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.