drm/i915/hwmon: Add HWMON infrastructure
authorDale B Stimson <dale.b.stimson@intel.com>
Thu, 13 Oct 2022 15:45:20 +0000 (08:45 -0700)
committerAnshuman Gupta <anshuman.gupta@intel.com>
Mon, 17 Oct 2022 09:19:29 +0000 (14:49 +0530)
The i915 HWMON module will be used to expose voltage, power and energy
values for dGfx. Here we set up i915 hwmon infrastructure including i915
hwmon registration, basic data structures and functions.

v2:
  - Create HWMON infra patch (Ashutosh)
  - Fixed review comments (Jani)
  - Remove "select HWMON" from i915/Kconfig (Jani)
v3: Use hwm_ prefix for static functions (Ashutosh)
v4: s/#ifdef CONFIG_HWMON/#if IS_REACHABLE(CONFIG_HWMON)/ since the former
    doesn't work if hwmon is compiled as a module (Guenter)
v5: Fixed review comments (Jani)
v6: s/kzalloc/devm_kzalloc/ (Andi)
v7: s/hwmon_device_register_with_info/
      devm_hwmon_device_register_with_info/ (Ashutosh)

Cc: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Dale B Stimson <dale.b.stimson@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: Riana Tauro <riana.tauro@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-2-ashutosh.dixit@intel.com
drivers/gpu/drm/i915/Makefile
drivers/gpu/drm/i915/i915_driver.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_hwmon.c [new file with mode: 0644]
drivers/gpu/drm/i915/i915_hwmon.h [new file with mode: 0644]

index f8cc1eb52626ef56217fb806cac27cf733c01bb1..2535593ab379e7c181836b6c4a4fcdcd7ccfab7a 100644 (file)
@@ -209,6 +209,9 @@ i915-y += gt/uc/intel_uc.o \
 # graphics system controller (GSC) support
 i915-y += gt/intel_gsc.o
 
+# graphics hardware monitoring (HWMON) support
+i915-$(CONFIG_HWMON) += i915_hwmon.o
+
 # modesetting core code
 i915-y += \
        display/hsw_ips.o \
index 9d1fc2477f80d9c3c2f9c43564028cb266b8bb72..ae0414037625caf6d232a4d468c54aae1c6b7047 100644 (file)
@@ -81,6 +81,7 @@
 #include "i915_drm_client.h"
 #include "i915_drv.h"
 #include "i915_getparam.h"
+#include "i915_hwmon.h"
 #include "i915_ioc32.h"
 #include "i915_ioctl.h"
 #include "i915_irq.h"
@@ -763,6 +764,8 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
        for_each_gt(gt, dev_priv, i)
                intel_gt_driver_register(gt);
 
+       i915_hwmon_register(dev_priv);
+
        intel_display_driver_register(dev_priv);
 
        intel_power_domains_enable(dev_priv);
@@ -795,6 +798,8 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv)
        for_each_gt(gt, dev_priv, i)
                intel_gt_driver_unregister(gt);
 
+       i915_hwmon_unregister(dev_priv);
+
        i915_perf_unregister(dev_priv);
        i915_pmu_unregister(dev_priv);
 
index e390da969be55d4573d1a733546318002fff64a8..74a1a646878b736a665ca2c5ffec7022217848a9 100644 (file)
@@ -352,6 +352,8 @@ struct drm_i915_private {
 
        struct i915_perf perf;
 
+       struct i915_hwmon *hwmon;
+
        /* Abstract the submission mechanism (legacy ringbuffer or execlists) away */
        struct intel_gt gt0;
 
diff --git a/drivers/gpu/drm/i915/i915_hwmon.c b/drivers/gpu/drm/i915/i915_hwmon.c
new file mode 100644 (file)
index 0000000..231552f
--- /dev/null
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/types.h>
+
+#include "i915_drv.h"
+#include "i915_hwmon.h"
+#include "i915_reg.h"
+#include "intel_mchbar_regs.h"
+
+struct hwm_reg {
+};
+
+struct hwm_drvdata {
+       struct i915_hwmon *hwmon;
+       struct intel_uncore *uncore;
+       struct device *hwmon_dev;
+       char name[12];
+};
+
+struct i915_hwmon {
+       struct hwm_drvdata ddat;
+       struct mutex hwmon_lock;                /* counter overflow logic and rmw */
+       struct hwm_reg rg;
+};
+
+static const struct hwmon_channel_info *hwm_info[] = {
+       NULL
+};
+
+static umode_t
+hwm_is_visible(const void *drvdata, enum hwmon_sensor_types type,
+              u32 attr, int channel)
+{
+       switch (type) {
+       default:
+               return 0;
+       }
+}
+
+static int
+hwm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
+        int channel, long *val)
+{
+       switch (type) {
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static int
+hwm_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
+         int channel, long val)
+{
+       switch (type) {
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static const struct hwmon_ops hwm_ops = {
+       .is_visible = hwm_is_visible,
+       .read = hwm_read,
+       .write = hwm_write,
+};
+
+static const struct hwmon_chip_info hwm_chip_info = {
+       .ops = &hwm_ops,
+       .info = hwm_info,
+};
+
+static void
+hwm_get_preregistration_info(struct drm_i915_private *i915)
+{
+}
+
+void i915_hwmon_register(struct drm_i915_private *i915)
+{
+       struct device *dev = i915->drm.dev;
+       struct i915_hwmon *hwmon;
+       struct device *hwmon_dev;
+       struct hwm_drvdata *ddat;
+
+       /* hwmon is available only for dGfx */
+       if (!IS_DGFX(i915))
+               return;
+
+       hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL);
+       if (!hwmon)
+               return;
+
+       i915->hwmon = hwmon;
+       mutex_init(&hwmon->hwmon_lock);
+       ddat = &hwmon->ddat;
+
+       ddat->hwmon = hwmon;
+       ddat->uncore = &i915->uncore;
+       snprintf(ddat->name, sizeof(ddat->name), "i915");
+
+       hwm_get_preregistration_info(i915);
+
+       /*  hwmon_dev points to device hwmon<i> */
+       hwmon_dev = devm_hwmon_device_register_with_info(dev, ddat->name,
+                                                        ddat,
+                                                        &hwm_chip_info,
+                                                        NULL);
+       if (IS_ERR(hwmon_dev)) {
+               i915->hwmon = NULL;
+               return;
+       }
+
+       ddat->hwmon_dev = hwmon_dev;
+}
+
+void i915_hwmon_unregister(struct drm_i915_private *i915)
+{
+       fetch_and_zero(&i915->hwmon);
+}
diff --git a/drivers/gpu/drm/i915/i915_hwmon.h b/drivers/gpu/drm/i915/i915_hwmon.h
new file mode 100644 (file)
index 0000000..7ca9cf2
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: MIT */
+
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#ifndef __I915_HWMON_H__
+#define __I915_HWMON_H__
+
+struct drm_i915_private;
+
+#if IS_REACHABLE(CONFIG_HWMON)
+void i915_hwmon_register(struct drm_i915_private *i915);
+void i915_hwmon_unregister(struct drm_i915_private *i915);
+#else
+static inline void i915_hwmon_register(struct drm_i915_private *i915) { };
+static inline void i915_hwmon_unregister(struct drm_i915_private *i915) { };
+#endif
+
+#endif /* __I915_HWMON_H__ */