Skip to content

Commit

Permalink
drm/i915/hwmon: Extend power/energy for XEHPSDV
Browse files Browse the repository at this point in the history
Extend hwmon power/energy for XEHPSDV especially per gt level energy
usage.

v2: Update to latest HWMON spec (Ashutosh)
v3: Fix review comments (Ashutosh)
v4: Fix review comments (Anshuman)
v5: s/hwmon_device_register_with_info/
    devm_hwmon_device_register_with_info/ (Ashutosh)
v6: Change contact to intel-gfx (Rodrigo)
    GEN12_RPSTAT1 is available for all Gen12+ (Andi)

Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: Dale B Stimson <dale.b.stimson@intel.com>
Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
Acked-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221013154526.2105579-8-ashutosh.dixit@intel.com
  • Loading branch information
Dale B Stimson authored and Anshuman Gupta committed Oct 17, 2022
1 parent 4c2572f commit a6a924a
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 3 deletions.
7 changes: 6 additions & 1 deletion Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ What: /sys/devices/.../hwmon/hwmon<i>/energy1_input
Date: February 2023
KernelVersion: 6.2
Contact: intel-gfx@lists.freedesktop.org
Description: RO. Energy input of device in microjoules.
Description: RO. Energy input of device or gt in microjoules.

For i915 device level hwmon devices (name "i915") this
reflects energy input for the entire device. For gt level
hwmon devices (name "i915_gtN") this reflects energy input
for the gt.

Only supported for particular Intel i915 graphics platforms.
5 changes: 5 additions & 0 deletions drivers/gpu/drm/i915/gt/intel_gt_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,11 @@

#define GEN12_SFC_DONE(n) _MMIO(0x1cc000 + (n) * 0x1000)

#define GT0_PACKAGE_ENERGY_STATUS _MMIO(0x250004)
#define GT0_PACKAGE_RAPL_LIMIT _MMIO(0x250008)
#define GT0_PACKAGE_POWER_SKU_UNIT _MMIO(0x250068)
#define GT0_PLATFORM_ENERGY_STATUS _MMIO(0x25006c)

/*
* Standalone Media's non-engine GT registers are located at their regular GT
* offsets plus 0x380000. This extra offset is stored inside the intel_uncore
Expand Down
101 changes: 99 additions & 2 deletions drivers/gpu/drm/i915/i915_hwmon.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "i915_reg.h"
#include "intel_mchbar_regs.h"
#include "intel_pcode.h"
#include "gt/intel_gt.h"
#include "gt/intel_gt_regs.h"

/*
Expand All @@ -34,6 +35,7 @@ struct hwm_reg {
i915_reg_t pkg_power_sku;
i915_reg_t pkg_rapl_limit;
i915_reg_t energy_status_all;
i915_reg_t energy_status_tile;
};

struct hwm_energy_info {
Expand All @@ -47,10 +49,12 @@ struct hwm_drvdata {
struct device *hwmon_dev;
struct hwm_energy_info ei; /* Energy info for energy1_input */
char name[12];
int gt_n;
};

struct i915_hwmon {
struct hwm_drvdata ddat;
struct hwm_drvdata ddat_gt[I915_MAX_GT];
struct mutex hwmon_lock; /* counter overflow logic and rmw */
struct hwm_reg rg;
int scl_shift_power;
Expand Down Expand Up @@ -144,7 +148,10 @@ hwm_energy(struct hwm_drvdata *ddat, long *energy)
i915_reg_t rgaddr;
u32 reg_val;

rgaddr = hwmon->rg.energy_status_all;
if (ddat->gt_n >= 0)
rgaddr = hwmon->rg.energy_status_tile;
else
rgaddr = hwmon->rg.energy_status_all;

mutex_lock(&hwmon->hwmon_lock);

Expand Down Expand Up @@ -283,6 +290,11 @@ static const struct hwmon_channel_info *hwm_info[] = {
NULL
};

static const struct hwmon_channel_info *hwm_gt_info[] = {
HWMON_CHANNEL_INFO(energy, HWMON_E_INPUT),
NULL
};

/* I1 is exposed as power_crit or as curr_crit depending on bit 31 */
static int hwm_pcode_read_i1(struct drm_i915_private *i915, u32 *uval)
{
Expand Down Expand Up @@ -414,7 +426,10 @@ hwm_energy_is_visible(const struct hwm_drvdata *ddat, u32 attr)

switch (attr) {
case hwmon_energy_input:
rgaddr = hwmon->rg.energy_status_all;
if (ddat->gt_n >= 0)
rgaddr = hwmon->rg.energy_status_tile;
else
rgaddr = hwmon->rg.energy_status_all;
return i915_mmio_reg_valid(rgaddr) ? 0444 : 0;
default:
return 0;
Expand Down Expand Up @@ -550,6 +565,44 @@ static const struct hwmon_chip_info hwm_chip_info = {
.info = hwm_info,
};

static umode_t
hwm_gt_is_visible(const void *drvdata, enum hwmon_sensor_types type,
u32 attr, int channel)
{
struct hwm_drvdata *ddat = (struct hwm_drvdata *)drvdata;

switch (type) {
case hwmon_energy:
return hwm_energy_is_visible(ddat, attr);
default:
return 0;
}
}

static int
hwm_gt_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
int channel, long *val)
{
struct hwm_drvdata *ddat = dev_get_drvdata(dev);

switch (type) {
case hwmon_energy:
return hwm_energy_read(ddat, attr, val);
default:
return -EOPNOTSUPP;
}
}

static const struct hwmon_ops hwm_gt_ops = {
.is_visible = hwm_gt_is_visible,
.read = hwm_gt_read,
};

static const struct hwmon_chip_info hwm_gt_chip_info = {
.ops = &hwm_gt_ops,
.info = hwm_gt_info,
};

static void
hwm_get_preregistration_info(struct drm_i915_private *i915)
{
Expand All @@ -558,7 +611,9 @@ hwm_get_preregistration_info(struct drm_i915_private *i915)
struct hwm_drvdata *ddat = &hwmon->ddat;
intel_wakeref_t wakeref;
u32 val_sku_unit = 0;
struct intel_gt *gt;
long energy;
int i;

/* Available for all Gen12+/dGfx */
hwmon->rg.gt_perf_status = GEN12_RPSTAT1;
Expand All @@ -568,11 +623,19 @@ hwm_get_preregistration_info(struct drm_i915_private *i915)
hwmon->rg.pkg_power_sku = PCU_PACKAGE_POWER_SKU;
hwmon->rg.pkg_rapl_limit = PCU_PACKAGE_RAPL_LIMIT;
hwmon->rg.energy_status_all = PCU_PACKAGE_ENERGY_STATUS;
hwmon->rg.energy_status_tile = INVALID_MMIO_REG;
} else if (IS_XEHPSDV(i915)) {
hwmon->rg.pkg_power_sku_unit = GT0_PACKAGE_POWER_SKU_UNIT;
hwmon->rg.pkg_power_sku = INVALID_MMIO_REG;
hwmon->rg.pkg_rapl_limit = GT0_PACKAGE_RAPL_LIMIT;
hwmon->rg.energy_status_all = GT0_PLATFORM_ENERGY_STATUS;
hwmon->rg.energy_status_tile = GT0_PACKAGE_ENERGY_STATUS;
} else {
hwmon->rg.pkg_power_sku_unit = INVALID_MMIO_REG;
hwmon->rg.pkg_power_sku = INVALID_MMIO_REG;
hwmon->rg.pkg_rapl_limit = INVALID_MMIO_REG;
hwmon->rg.energy_status_all = INVALID_MMIO_REG;
hwmon->rg.energy_status_tile = INVALID_MMIO_REG;
}

with_intel_runtime_pm(uncore->rpm, wakeref) {
Expand All @@ -595,6 +658,10 @@ hwm_get_preregistration_info(struct drm_i915_private *i915)
*/
if (i915_mmio_reg_valid(hwmon->rg.energy_status_all))
hwm_energy(ddat, &energy);
if (i915_mmio_reg_valid(hwmon->rg.energy_status_tile)) {
for_each_gt(gt, i915, i)
hwm_energy(&hwmon->ddat_gt[i], &energy);
}
}

void i915_hwmon_register(struct drm_i915_private *i915)
Expand All @@ -603,6 +670,9 @@ void i915_hwmon_register(struct drm_i915_private *i915)
struct i915_hwmon *hwmon;
struct device *hwmon_dev;
struct hwm_drvdata *ddat;
struct hwm_drvdata *ddat_gt;
struct intel_gt *gt;
int i;

/* hwmon is available only for dGfx */
if (!IS_DGFX(i915))
Expand All @@ -619,6 +689,16 @@ void i915_hwmon_register(struct drm_i915_private *i915)
ddat->hwmon = hwmon;
ddat->uncore = &i915->uncore;
snprintf(ddat->name, sizeof(ddat->name), "i915");
ddat->gt_n = -1;

for_each_gt(gt, i915, i) {
ddat_gt = hwmon->ddat_gt + i;

ddat_gt->hwmon = hwmon;
ddat_gt->uncore = gt->uncore;
snprintf(ddat_gt->name, sizeof(ddat_gt->name), "i915_gt%u", i);
ddat_gt->gt_n = i;
}

hwm_get_preregistration_info(i915);

Expand All @@ -633,6 +713,23 @@ void i915_hwmon_register(struct drm_i915_private *i915)
}

ddat->hwmon_dev = hwmon_dev;

for_each_gt(gt, i915, i) {
ddat_gt = hwmon->ddat_gt + i;
/*
* Create per-gt directories only if a per-gt attribute is
* visible. Currently this is only energy
*/
if (!hwm_gt_is_visible(ddat_gt, hwmon_energy, hwmon_energy_input, 0))
continue;

hwmon_dev = devm_hwmon_device_register_with_info(dev, ddat_gt->name,
ddat_gt,
&hwm_gt_chip_info,
NULL);
if (!IS_ERR(hwmon_dev))
ddat_gt->hwmon_dev = hwmon_dev;
}
}

void i915_hwmon_unregister(struct drm_i915_private *i915)
Expand Down

0 comments on commit a6a924a

Please sign in to comment.