Commit f8572bb6 authored by Riana Tauro's avatar Riana Tauro Committed by Anshuman Gupta

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: default avatarRiana Tauro <riana.tauro@intel.com>
Signed-off-by: default avatarBadal Nilawar <badal.nilawar@intel.com>
Signed-off-by: default avatarAshutosh Dixit <ashutosh.dixit@intel.com>
Acked-by: default avatarGuenter Roeck <linux@roeck-us.net>
Reviewed-by: default avatarAshutosh Dixit <ashutosh.dixit@intel.com>
Reviewed-by: default avatarAnshuman Gupta <anshuman.gupta@intel.com>
Signed-off-by: default avatarAnshuman Gupta <anshuman.gupta@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221013154526.2105579-3-ashutosh.dixit@intel.com
parent b3b088e2
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.
...@@ -10140,6 +10140,7 @@ Q: http://patchwork.freedesktop.org/project/intel-gfx/ ...@@ -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 B: https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs
C: irc://irc.oftc.net/intel-gfx C: irc://irc.oftc.net/intel-gfx
T: git git://anongit.freedesktop.org/drm-intel T: git git://anongit.freedesktop.org/drm-intel
F: Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
F: Documentation/gpu/i915.rst F: Documentation/gpu/i915.rst
F: drivers/gpu/drm/i915/ F: drivers/gpu/drm/i915/
F: include/drm/i915* F: include/drm/i915*
......
...@@ -1516,6 +1516,9 @@ ...@@ -1516,6 +1516,9 @@
#define VLV_RENDER_C0_COUNT _MMIO(0x138118) #define VLV_RENDER_C0_COUNT _MMIO(0x138118)
#define VLV_MEDIA_C0_COUNT _MMIO(0x13811c) #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_GT_INTR_DW(x) _MMIO(0x190018 + ((x) * 4))
#define GEN11_CSME (31) #define GEN11_CSME (31)
#define GEN11_GUNIT (28) #define GEN11_GUNIT (28)
......
...@@ -11,8 +11,16 @@ ...@@ -11,8 +11,16 @@
#include "i915_hwmon.h" #include "i915_hwmon.h"
#include "i915_reg.h" #include "i915_reg.h"
#include "intel_mchbar_regs.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 { struct hwm_reg {
i915_reg_t gt_perf_status;
}; };
struct hwm_drvdata { struct hwm_drvdata {
...@@ -29,14 +37,51 @@ struct i915_hwmon { ...@@ -29,14 +37,51 @@ struct i915_hwmon {
}; };
static const struct hwmon_channel_info *hwm_info[] = { static const struct hwmon_channel_info *hwm_info[] = {
HWMON_CHANNEL_INFO(in, HWMON_I_INPUT),
NULL 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 static umode_t
hwm_is_visible(const void *drvdata, enum hwmon_sensor_types type, hwm_is_visible(const void *drvdata, enum hwmon_sensor_types type,
u32 attr, int channel) u32 attr, int channel)
{ {
struct hwm_drvdata *ddat = (struct hwm_drvdata *)drvdata;
switch (type) { switch (type) {
case hwmon_in:
return hwm_in_is_visible(ddat, attr);
default: default:
return 0; return 0;
} }
...@@ -46,7 +91,11 @@ static int ...@@ -46,7 +91,11 @@ static int
hwm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, hwm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
int channel, long *val) int channel, long *val)
{ {
struct hwm_drvdata *ddat = dev_get_drvdata(dev);
switch (type) { switch (type) {
case hwmon_in:
return hwm_in_read(ddat, attr, val);
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -76,6 +125,10 @@ static const struct hwmon_chip_info hwm_chip_info = { ...@@ -76,6 +125,10 @@ static const struct hwmon_chip_info hwm_chip_info = {
static void static void
hwm_get_preregistration_info(struct drm_i915_private *i915) 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) void i915_hwmon_register(struct drm_i915_private *i915)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment