drm/i915/hwmon: Add HWMON current voltage support

Use i915 HWMON subsystem to display current input voltage.

v2:
  - Updated date and kernel version in feature description
  - Fixed review comments (Ashutosh)
v3: Use macro HWMON_CHANNEL_INFO to define hwmon channel (Guenter)
v4:
  - Fixed review comments (Ashutosh)
  - Use hwm_ prefix for static functions (Ashutosh)
v5: Added unit of voltage as millivolts (Ashutosh)
v6: KernelVersion: 6.2, Date: February 2023 in doc (Tvrtko)
v7: Change contact to intel-gfx (Rodrigo)
    GEN12_RPSTAT1 is available for all Gen12+ (Andi)
    Added Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
    to MAINTAINERS

Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Anshuman Gupta <anshuman.gupta@intel.com>
Signed-off-by: Riana Tauro <riana.tauro@intel.com>
Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@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>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221013154526.2105579-3-ashutosh.dixit@intel.com
This commit is contained in:
Riana Tauro 2022-10-13 08:45:21 -07:00 committed by Anshuman Gupta
parent b3b088e281
commit f8572bb675
4 changed files with 64 additions and 0 deletions

View file

@ -0,0 +1,7 @@
What: /sys/devices/.../hwmon/hwmon<i>/in0_input
Date: February 2023
KernelVersion: 6.2
Contact: intel-gfx@lists.freedesktop.org
Description: RO. Current Voltage in millivolt.
Only supported for particular Intel i915 graphics platforms.

View file

@ -10140,6 +10140,7 @@ Q: http://patchwork.freedesktop.org/project/intel-gfx/
B: https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs
C: irc://irc.oftc.net/intel-gfx
T: git git://anongit.freedesktop.org/drm-intel
F: Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
F: Documentation/gpu/i915.rst
F: drivers/gpu/drm/i915/
F: include/drm/i915*

View file

@ -1516,6 +1516,9 @@
#define VLV_RENDER_C0_COUNT _MMIO(0x138118)
#define VLV_MEDIA_C0_COUNT _MMIO(0x13811c)
#define GEN12_RPSTAT1 _MMIO(0x1381b4)
#define GEN12_VOLTAGE_MASK REG_GENMASK(10, 0)
#define GEN11_GT_INTR_DW(x) _MMIO(0x190018 + ((x) * 4))
#define GEN11_CSME (31)
#define GEN11_GUNIT (28)

View file

@ -11,8 +11,16 @@
#include "i915_hwmon.h"
#include "i915_reg.h"
#include "intel_mchbar_regs.h"
#include "gt/intel_gt_regs.h"
/*
* SF_* - scale factors for particular quantities according to hwmon spec.
* - voltage - millivolts
*/
#define SF_VOLTAGE 1000
struct hwm_reg {
i915_reg_t gt_perf_status;
};
struct hwm_drvdata {
@ -29,14 +37,51 @@ struct i915_hwmon {
};
static const struct hwmon_channel_info *hwm_info[] = {
HWMON_CHANNEL_INFO(in, HWMON_I_INPUT),
NULL
};
static umode_t
hwm_in_is_visible(const struct hwm_drvdata *ddat, u32 attr)
{
struct drm_i915_private *i915 = ddat->uncore->i915;
switch (attr) {
case hwmon_in_input:
return IS_DG1(i915) || IS_DG2(i915) ? 0444 : 0;
default:
return 0;
}
}
static int
hwm_in_read(struct hwm_drvdata *ddat, u32 attr, long *val)
{
struct i915_hwmon *hwmon = ddat->hwmon;
intel_wakeref_t wakeref;
u32 reg_value;
switch (attr) {
case hwmon_in_input:
with_intel_runtime_pm(ddat->uncore->rpm, wakeref)
reg_value = intel_uncore_read(ddat->uncore, hwmon->rg.gt_perf_status);
/* HW register value in units of 2.5 millivolt */
*val = DIV_ROUND_CLOSEST(REG_FIELD_GET(GEN12_VOLTAGE_MASK, reg_value) * 25, 10);
return 0;
default:
return -EOPNOTSUPP;
}
}
static umode_t
hwm_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_in:
return hwm_in_is_visible(ddat, attr);
default:
return 0;
}
@ -46,7 +91,11 @@ static int
hwm_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_in:
return hwm_in_read(ddat, attr, val);
default:
return -EOPNOTSUPP;
}
@ -76,6 +125,10 @@ static const struct hwmon_chip_info hwm_chip_info = {
static void
hwm_get_preregistration_info(struct drm_i915_private *i915)
{
struct i915_hwmon *hwmon = i915->hwmon;
/* Available for all Gen12+/dGfx */
hwmon->rg.gt_perf_status = GEN12_RPSTAT1;
}
void i915_hwmon_register(struct drm_i915_private *i915)