Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Badal Nilawar <badal.nilawar@intel.com>
To: intel-xe@lists.freedesktop.org, linux-hwmon@vger.kernel.org
Cc: linux@roeck-us.net
Subject: [Intel-xe] [PATCH v2 2/6] drm/xe/hwmon: Expose power attributes
Date: Wed, 28 Jun 2023 00:00:39 +0530	[thread overview]
Message-ID: <20230627183043.2024530-3-badal.nilawar@intel.com> (raw)
In-Reply-To: <20230627183043.2024530-1-badal.nilawar@intel.com>

Expose power_max (pl1) and power_rated_max (tdp) attributes.
This is port from i915 hwmon.

v2:
  - Move rpm calls (xe_device_mem_access_get/put) to hwmon functions from
    process_hwmon_reg to avoid multiple rpm entry exits during consecutive
    reg accesses
  - Fix review comments (Riana)

Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
---
 .../ABI/testing/sysfs-driver-intel-xe-hwmon   |  22 ++
 drivers/gpu/drm/xe/regs/xe_gt_regs.h          |   4 +
 drivers/gpu/drm/xe/regs/xe_mchbar_regs.h      |  34 ++
 drivers/gpu/drm/xe/xe_hwmon.c                 | 372 +++++++++++++++++-
 drivers/gpu/drm/xe/xe_hwmon.h                 |   4 +
 drivers/gpu/drm/xe/xe_uc.c                    |   6 +
 6 files changed, 435 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon
 create mode 100644 drivers/gpu/drm/xe/regs/xe_mchbar_regs.h

diff --git a/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon b/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon
new file mode 100644
index 000000000000..ff3465195870
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon
@@ -0,0 +1,22 @@
+What:		/sys/devices/.../hwmon/hwmon<i>/power1_max
+Date:		July 2023
+KernelVersion:	6.3
+Contact:	intel-gfx@lists.freedesktop.org
+Description:	RW. Card reactive sustained  (PL1/Tau) power limit in microwatts.
+
+		The power controller will throttle the operating frequency
+		if the power averaged over a window (typically seconds)
+		exceeds this limit. A read value of 0 means that the PL1
+		power limit is disabled, writing 0 disables the
+		limit. Writing values > 0 will enable the power limit.
+
+		Only supported for particular Intel xe graphics platforms.
+
+What:		/sys/devices/.../hwmon/hwmon<i>/power1_rated_max
+Date:		July 2023
+KernelVersion:	6.3
+Contact:	intel-gfx@lists.freedesktop.org
+Description:	RO. Card default power limit (default TDP setting).
+
+		Only supported for particular Intel xe graphics platforms.
+
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
index d654f3311351..eb7210afbd2c 100644
--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
@@ -397,4 +397,8 @@
 #define XEHPC_BCS5_BCS6_INTR_MASK		XE_REG(0x190118)
 #define XEHPC_BCS7_BCS8_INTR_MASK		XE_REG(0x19011c)
 
+#define PVC_GT0_PACKAGE_RAPL_LIMIT		XE_REG(0x281008)
+#define PVC_GT0_PACKAGE_POWER_SKU_UNIT		XE_REG(0x281068)
+#define PVC_GT0_PACKAGE_POWER_SKU		XE_REG(0x281080)
+
 #endif
diff --git a/drivers/gpu/drm/xe/regs/xe_mchbar_regs.h b/drivers/gpu/drm/xe/regs/xe_mchbar_regs.h
new file mode 100644
index 000000000000..cb2d49b5c8a9
--- /dev/null
+++ b/drivers/gpu/drm/xe/regs/xe_mchbar_regs.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef _XE_MCHBAR_REGS_H__
+#define _XE_MCHBAR_REGS_H_
+
+#include "regs/xe_reg_defs.h"
+
+/*
+ * MCHBAR mirror.
+ *
+ * This mirrors the MCHBAR MMIO space whose location is determined by
+ * device 0 function 0's pci config register 0x44 or 0x48 and matches it in
+ * every way.
+ */
+
+#define MCHBAR_MIRROR_BASE_SNB			0x140000
+
+#define PCU_CR_PACKAGE_POWER_SKU		XE_REG(MCHBAR_MIRROR_BASE_SNB + 0x5930)
+#define   PKG_PKG_TDP				GENMASK_ULL(14, 0)
+#define   PKG_MIN_PWR				GENMASK_ULL(30, 16)
+#define   PKG_MAX_PWR				GENMASK_ULL(46, 32)
+
+#define PCU_CR_PACKAGE_POWER_SKU_UNIT		XE_REG(MCHBAR_MIRROR_BASE_SNB + 0x5938)
+#define   PKG_PWR_UNIT				REG_GENMASK(3, 0)
+
+#define PCU_CR_PACKAGE_RAPL_LIMIT		XE_REG(MCHBAR_MIRROR_BASE_SNB + 0x59a0)
+#define   PKG_PWR_LIM_1				REG_GENMASK(14, 0)
+#define   PKG_PWR_LIM_1_EN			REG_BIT(15)
+
+#endif
+
diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c
index 8f653fdf4ad5..a4fba29d5d5a 100644
--- a/drivers/gpu/drm/xe/xe_hwmon.c
+++ b/drivers/gpu/drm/xe/xe_hwmon.c
@@ -5,53 +5,394 @@
 
 #include <linux/hwmon.h>
 
+#include "regs/xe_mchbar_regs.h"
 #include "regs/xe_gt_regs.h"
 #include "xe_device.h"
 #include "xe_hwmon.h"
+#include "xe_mmio.h"
+#include "xe_gt.h"
+
+enum hwm_reg_name {
+	pkg_rapl_limit,
+	pkg_power_sku,
+	pkg_power_sku_unit,
+};
+
+enum hwm_reg_operation {
+	reg_read,
+	reg_write,
+	reg_rmw,
+};
+
+/*
+ * SF_* - scale factors for particular quantities according to hwmon spec.
+ * - power  - microwatts
+ */
+#define SF_POWER	1000000
 
 struct hwm_drvdata {
 	struct xe_hwmon *hwmon;
 	struct device *hwmon_dev;
+	struct xe_gt *gt;
 	char name[12];
+	bool reset_in_progress;
+	wait_queue_head_t waitq;
 };
 
 struct xe_hwmon {
 	struct hwm_drvdata ddat;
 	struct mutex hwmon_lock;
+	int scl_shift_power;
 };
 
+struct xe_reg hwm_get_reg(struct hwm_drvdata *ddat, enum hwm_reg_name reg_name)
+{
+	struct xe_device *xe = gt_to_xe(ddat->gt);
+
+	switch (reg_name) {
+	case pkg_rapl_limit:
+		if (xe->info.platform == XE_DG2)
+			return PCU_CR_PACKAGE_RAPL_LIMIT;
+		else if (xe->info.platform == XE_PVC)
+			return PVC_GT0_PACKAGE_RAPL_LIMIT;
+		break;
+	case pkg_power_sku:
+		if (xe->info.platform == XE_DG2)
+			return PCU_CR_PACKAGE_POWER_SKU;
+		else if (xe->info.platform == XE_PVC)
+			return PVC_GT0_PACKAGE_POWER_SKU;
+		break;
+	case pkg_power_sku_unit:
+		if (xe->info.platform == XE_DG2)
+			return PCU_CR_PACKAGE_POWER_SKU_UNIT;
+		else if (xe->info.platform == XE_PVC)
+			return PVC_GT0_PACKAGE_POWER_SKU_UNIT;
+		break;
+	default:
+		break;
+	}
+
+	return XE_REG(0);
+}
+
+int process_hwmon_reg(struct hwm_drvdata *ddat, enum hwm_reg_name reg_name,
+		      enum hwm_reg_operation operation, u32 *value,
+		      u32 clr, u32 set)
+{
+	struct xe_reg reg;
+	int ret = 0;
+
+	reg = hwm_get_reg(ddat, reg_name);
+
+	if (!reg.raw)
+		return -EOPNOTSUPP;
+
+	switch (operation) {
+	case reg_read:
+		*value = xe_mmio_read32(ddat->gt, reg);
+		break;
+	case reg_write:
+		xe_mmio_write32(ddat->gt, reg, *value);
+		break;
+	case reg_rmw:
+		*value = xe_mmio_rmw32(ddat->gt, reg, clr, set);
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+	}
+
+	return ret;
+}
+
+int process_hwmon_reg_read64(struct hwm_drvdata *ddat, enum hwm_reg_name reg_name, u64 *value)
+{
+	struct xe_reg reg;
+
+	reg = hwm_get_reg(ddat, reg_name);
+
+	if (!reg.raw)
+		return -EOPNOTSUPP;
+
+	xe_device_mem_access_get(gt_to_xe(ddat->gt));
+
+	*value = xe_mmio_read64(ddat->gt, reg);
+
+	xe_device_mem_access_put(gt_to_xe(ddat->gt));
+
+	return 0;
+}
+
+#define PL1_DISABLE 0
+
+/*
+ * HW allows arbitrary PL1 limits to be set but silently clamps these values to
+ * "typical but not guaranteed" min/max values in rg.pkg_power_sku. Follow the
+ * same pattern for sysfs, allow arbitrary PL1 limits to be set but display
+ * clamped values when read.
+ */
+static int hwm_power_max_read(struct hwm_drvdata *ddat, long *value)
+{
+	struct xe_hwmon *hwmon = ddat->hwmon;
+	u32 reg_val;
+	u64 r, min, max;
+
+	xe_device_mem_access_get(gt_to_xe(ddat->gt));
+
+	process_hwmon_reg(ddat, pkg_rapl_limit, reg_read, &reg_val, 0, 0);
+	/* Check if PL1 limit is disabled */
+	if (!(reg_val & PKG_PWR_LIM_1_EN)) {
+		*value = PL1_DISABLE;
+		xe_device_mem_access_put(gt_to_xe(ddat->gt));
+		return 0;
+	}
+
+	reg_val = REG_FIELD_GET(PKG_PWR_LIM_1, reg_val);
+	*value = mul_u64_u32_shr(reg_val, SF_POWER, hwmon->scl_shift_power);
+
+	process_hwmon_reg_read64(ddat, pkg_power_sku, &r);
+	min = REG_FIELD_GET(PKG_MIN_PWR, r);
+	min = mul_u64_u32_shr(min, SF_POWER, hwmon->scl_shift_power);
+	max = REG_FIELD_GET(PKG_MAX_PWR, r);
+	max = mul_u64_u32_shr(max, SF_POWER, hwmon->scl_shift_power);
+
+	if (min && max)
+		*value = clamp_t(u64, *value, min, max);
+
+	xe_device_mem_access_put(gt_to_xe(ddat->gt));
+	return 0;
+}
+
+static int hwm_power_max_write(struct hwm_drvdata *ddat, long value)
+{
+	struct xe_hwmon *hwmon = ddat->hwmon;
+	DEFINE_WAIT(wait);
+	int ret = 0;
+	u32 nval;
+
+	/* Block waiting for GuC reset to complete when needed */
+	for (;;) {
+		mutex_lock(&hwmon->hwmon_lock);
+
+		prepare_to_wait(&ddat->waitq, &wait, TASK_INTERRUPTIBLE);
+
+		if (!hwmon->ddat.reset_in_progress)
+			break;
+
+		if (signal_pending(current)) {
+			ret = -EINTR;
+			break;
+		}
+
+		mutex_unlock(&hwmon->hwmon_lock);
+
+		schedule();
+	}
+	finish_wait(&ddat->waitq, &wait);
+	if (ret)
+		goto unlock;
+
+	xe_device_mem_access_get(gt_to_xe(ddat->gt));
+
+	/* Disable PL1 limit and verify, as limit cannot be disabled on all platforms */
+	if (value == PL1_DISABLE) {
+		process_hwmon_reg(ddat, pkg_rapl_limit, reg_rmw, &nval,
+				  PKG_PWR_LIM_1_EN, 0);
+		process_hwmon_reg(ddat, pkg_rapl_limit, reg_read, &nval,
+				  PKG_PWR_LIM_1_EN, 0);
+
+		if (nval & PKG_PWR_LIM_1_EN)
+			ret = -ENODEV;
+		goto exit;
+	}
+
+	/* Computation in 64-bits to avoid overflow. Round to nearest. */
+	nval = DIV_ROUND_CLOSEST_ULL((u64)value << hwmon->scl_shift_power, SF_POWER);
+	nval = PKG_PWR_LIM_1_EN | REG_FIELD_PREP(PKG_PWR_LIM_1, nval);
+
+	process_hwmon_reg(ddat, pkg_rapl_limit, reg_rmw, &nval,
+			  PKG_PWR_LIM_1_EN | PKG_PWR_LIM_1, nval);
+exit:
+	xe_device_mem_access_put(gt_to_xe(ddat->gt));
+unlock:
+	mutex_unlock(&hwmon->hwmon_lock);
+
+	return 0;
+}
+
+static int hwm_power_rated_max_read(struct hwm_drvdata *ddat, long *value)
+{
+	struct xe_hwmon *hwmon = ddat->hwmon;
+	u32 reg_val;
+
+	process_hwmon_reg(ddat, pkg_power_sku, reg_read, &reg_val, 0, 0);
+	reg_val = REG_FIELD_GET(PKG_PKG_TDP, reg_val);
+	*value = mul_u64_u32_shr(reg_val, SF_POWER, hwmon->scl_shift_power);
+
+	return 0;
+}
+
 static const struct hwmon_channel_info *hwm_info[] = {
+	HWMON_CHANNEL_INFO(power, HWMON_P_MAX | HWMON_P_RATED_MAX),
 	NULL
 };
 
+static umode_t
+hwm_power_is_visible(struct hwm_drvdata *ddat, u32 attr, int chan)
+{
+	u32 reg_val;
+
+	switch (attr) {
+	case hwmon_power_max:
+		return process_hwmon_reg(ddat, pkg_rapl_limit,
+					 reg_read, &reg_val, 0, 0) ? 0 : 0664;
+	case hwmon_power_rated_max:
+		return process_hwmon_reg(ddat, pkg_power_sku,
+					 reg_read, &reg_val, 0, 0) ? 0 : 0444;
+	default:
+		return 0;
+	}
+}
+
+static int
+hwm_power_read(struct hwm_drvdata *ddat, u32 attr, int chan, long *val)
+{
+	switch (attr) {
+	case hwmon_power_max:
+		return hwm_power_max_read(ddat, val);
+	case hwmon_power_rated_max:
+		return hwm_power_rated_max_read(ddat, val);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int
+hwm_power_write(struct hwm_drvdata *ddat, u32 attr, int chan, long val)
+{
+	switch (attr) {
+	case hwmon_power_max:
+		return hwm_power_max_write(ddat, val);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+void xe_hwmon_power_max_disable(struct xe_device *xe, bool *old)
+{
+	struct xe_hwmon *hwmon = xe->hwmon;
+	struct hwm_drvdata *ddat = &hwmon->ddat;
+	u32 r;
+
+	xe_device_mem_access_get(gt_to_xe(ddat->gt));
+
+	if (!hwmon || process_hwmon_reg(ddat, pkg_rapl_limit,
+					reg_read, &r, 0, 0))
+		return;
+
+	mutex_lock(&hwmon->hwmon_lock);
+
+	hwmon->ddat.reset_in_progress = true;
+
+	process_hwmon_reg(ddat, pkg_rapl_limit, reg_rmw, &r,
+			  PKG_PWR_LIM_1_EN, 0);
+	*old = !!(r & PKG_PWR_LIM_1_EN);
+
+	mutex_unlock(&hwmon->hwmon_lock);
+
+	xe_device_mem_access_put(gt_to_xe(ddat->gt));
+}
+
+void xe_hwmon_power_max_restore(struct xe_device *xe, bool old)
+{
+	struct xe_hwmon *hwmon = xe->hwmon;
+	struct hwm_drvdata *ddat = &hwmon->ddat;
+	u32 r;
+
+	xe_device_mem_access_get(gt_to_xe(ddat->gt));
+
+	if (!hwmon || process_hwmon_reg(ddat, pkg_rapl_limit,
+					reg_read, &r, 0, 0))
+		return;
+
+	mutex_lock(&hwmon->hwmon_lock);
+
+	process_hwmon_reg(ddat, pkg_rapl_limit, reg_rmw, &r,
+			  PKG_PWR_LIM_1_EN, old ? PKG_PWR_LIM_1_EN : 0);
+
+	hwmon->ddat.reset_in_progress = false;
+	wake_up_all(&hwmon->ddat.waitq);
+
+	mutex_unlock(&hwmon->hwmon_lock);
+
+	xe_device_mem_access_put(gt_to_xe(ddat->gt));
+}
+
 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;
+	int ret;
+
+	xe_device_mem_access_get(gt_to_xe(ddat->gt));
+
 	switch (type) {
+	case hwmon_power:
+		ret = hwm_power_is_visible(ddat, attr, channel);
+		break;
 	default:
-		return 0;
+		ret = 0;
 	}
+
+	xe_device_mem_access_put(gt_to_xe(ddat->gt));
+
+	return ret;
 }
 
 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);
+	int ret;
+
+	xe_device_mem_access_get(gt_to_xe(ddat->gt));
+
 	switch (type) {
+	case hwmon_power:
+		ret = hwm_power_read(ddat, attr, channel, val);
+		break;
 	default:
-		return -EOPNOTSUPP;
+		ret = -EOPNOTSUPP;
+		break;
 	}
+
+	xe_device_mem_access_put(gt_to_xe(ddat->gt));
+
+	return ret;
 }
 
 static int
 hwm_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
 	  int channel, long val)
 {
+	struct hwm_drvdata *ddat = dev_get_drvdata(dev);
+	int ret;
+
+	xe_device_mem_access_get(gt_to_xe(ddat->gt));
+
 	switch (type) {
+	case hwmon_power:
+		ret = hwm_power_write(ddat, attr, channel, val);
+		break;
 	default:
-		return -EOPNOTSUPP;
+		ret = -EOPNOTSUPP;
+		break;
 	}
+
+	xe_device_mem_access_put(gt_to_xe(ddat->gt));
+
+	return ret;
 }
 
 static const struct hwmon_ops hwm_ops = {
@@ -66,8 +407,19 @@ static const struct hwmon_chip_info hwm_chip_info = {
 };
 
 static void
-hwm_get_preregistration_info(struct xe_device *xe)
+hwm_get_preregistration_info(struct hwm_drvdata *ddat)
 {
+	struct xe_hwmon *hwmon = ddat->hwmon;
+	u32 val_sku_unit = 0;
+	int ret;
+
+	ret = process_hwmon_reg(ddat, pkg_power_sku_unit, reg_read, &val_sku_unit, 0, 0);
+	/*
+	 * The contents of register pkg_power_sku_unit do not change,
+	 * so read it once and store the shift values.
+	 */
+	if (!ret)
+		hwmon->scl_shift_power = REG_FIELD_GET(PKG_PWR_UNIT, val_sku_unit);
 }
 
 void xe_hwmon_register(struct xe_device *xe)
@@ -89,18 +441,24 @@ void xe_hwmon_register(struct xe_device *xe)
 	mutex_init(&hwmon->hwmon_lock);
 	ddat = &hwmon->ddat;
 
+	/* primary GT to access device level properties */
+	ddat->gt = xe->tiles[0].primary_gt;
+
 	ddat->hwmon = hwmon;
 	snprintf(ddat->name, sizeof(ddat->name), "xe");
 
-	hwm_get_preregistration_info(xe);
+	init_waitqueue_head(&ddat->waitq);
 
-	drm_dbg(&xe->drm, "Register HWMON interface\n");
+	hwm_get_preregistration_info(ddat);
 
-	/*  hwmon_dev points to device hwmon<i> */
+	drm_dbg(&xe->drm, "Register xe hwmon interface\n");
+
+	/* 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)) {
 		drm_warn(&xe->drm, "Fail to register xe hwmon\n");
 		xe->hwmon = NULL;
diff --git a/drivers/gpu/drm/xe/xe_hwmon.h b/drivers/gpu/drm/xe/xe_hwmon.h
index a078eeb0a68b..a5dc693569c5 100644
--- a/drivers/gpu/drm/xe/xe_hwmon.h
+++ b/drivers/gpu/drm/xe/xe_hwmon.h
@@ -14,9 +14,13 @@ struct xe_device;
 #if IS_REACHABLE(CONFIG_HWMON)
 void xe_hwmon_register(struct xe_device *xe);
 void xe_hwmon_unregister(struct xe_device *xe);
+void xe_hwmon_power_max_disable(struct xe_device *xe, bool *old);
+void xe_hwmon_power_max_restore(struct xe_device *xe, bool old);
 #else
 static inline void xe_hwmon_register(struct xe_device *xe) { };
 static inline void xe_hwmon_unregister(struct xe_device *xe) { };
+static inline void xe_hwmon_power_max_disable(struct xe_device *xe, bool *old) { };
+static inline void xe_hwmon_power_max_restore(struct xe_device *xe, bool old) { };
 #endif
 
 #endif /* __XE_HWMON_H__ */
diff --git a/drivers/gpu/drm/xe/xe_uc.c b/drivers/gpu/drm/xe/xe_uc.c
index 70eabf567156..9df5a3a85dc3 100644
--- a/drivers/gpu/drm/xe/xe_uc.c
+++ b/drivers/gpu/drm/xe/xe_uc.c
@@ -13,6 +13,7 @@
 #include "xe_huc.h"
 #include "xe_uc_fw.h"
 #include "xe_wopcm.h"
+#include "xe_hwmon.h"
 
 static struct xe_gt *
 uc_to_gt(struct xe_uc *uc)
@@ -127,11 +128,15 @@ int xe_uc_init_hwconfig(struct xe_uc *uc)
 int xe_uc_init_hw(struct xe_uc *uc)
 {
 	int ret;
+	bool pl1en;
 
 	/* GuC submission not enabled, nothing to do */
 	if (!xe_device_guc_submission_enabled(uc_to_xe(uc)))
 		return 0;
 
+	/* Disable a potentially low PL1 power limit to allow freq to be raised */
+	xe_hwmon_power_max_disable(uc_to_xe(uc), &pl1en);
+
 	ret = xe_uc_sanitize_reset(uc);
 	if (ret)
 		return ret;
@@ -160,6 +165,7 @@ int xe_uc_init_hw(struct xe_uc *uc)
 	if (ret)
 		return ret;
 
+	xe_hwmon_power_max_restore(uc_to_xe(uc), pl1en);
 	/* We don't fail the driver load if HuC fails to auth, but let's warn */
 	ret = xe_huc_auth(&uc->huc);
 	XE_WARN_ON(ret);
-- 
2.25.1


  parent reply	other threads:[~2023-06-27 18:25 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-27 18:30 [Intel-xe] [PATCH v2 0/6] Add HWMON support for DGFX Badal Nilawar
2023-06-27 18:27 ` [Intel-xe] ✓ CI.Patch_applied: success for Add HWMON support for DGFX (rev2) Patchwork
2023-06-27 18:27 ` [Intel-xe] ✗ CI.checkpatch: warning " Patchwork
2023-06-27 18:29 ` [Intel-xe] ✓ CI.KUnit: success " Patchwork
2023-06-27 18:30 ` [Intel-xe] [PATCH v2 1/6] drm/xe/hwmon: Add HWMON infrastructure Badal Nilawar
2023-06-28 22:50   ` Matthew Brost
2023-07-05 18:30     ` Nilawar, Badal
2023-06-29 13:49   ` Andi Shyti
2023-07-07 14:23     ` Nilawar, Badal
2023-06-27 18:30 ` Badal Nilawar [this message]
2023-06-29  0:18   ` [Intel-xe] [PATCH v2 2/6] drm/xe/hwmon: Expose power attributes Matthew Brost
2023-06-29 14:09     ` Andi Shyti
2023-08-15 23:20       ` Dixit, Ashutosh
2023-08-18  4:03         ` Nilawar, Badal
2023-08-18 13:55         ` Andi Shyti
2023-07-06 10:36     ` Nilawar, Badal
2023-06-27 18:30 ` [Intel-xe] [PATCH v2 3/6] drm/xe/hwmon: Expose card reactive critical power Badal Nilawar
2023-06-28 15:52   ` Nilawar, Badal
2023-06-29 14:40   ` Andi Shyti
2023-07-06 19:05     ` Dixit, Ashutosh
2023-06-27 18:30 ` [Intel-xe] [PATCH v2 4/6] drm/xe/hwmon: Expose input voltage attribute Badal Nilawar
2023-06-29 14:58   ` Andi Shyti
2023-06-27 18:30 ` [Intel-xe] [PATCH v2 5/6] drm/xe/hwmon: Expose hwmon energy attribute Badal Nilawar
2023-06-29 15:09   ` Andi Shyti
2023-06-27 18:30 ` [Intel-xe] [PATCH v2 6/6] drm/xe/hwmon: Expose power1_max_interval Badal Nilawar
2023-06-27 18:32 ` [Intel-xe] ✓ CI.Build: success for Add HWMON support for DGFX (rev2) Patchwork
2023-06-27 18:33 ` [Intel-xe] ✗ CI.Hooks: failure " Patchwork
2023-07-02  1:31 ` [Intel-xe] [PATCH v2 0/6] Add HWMON support for DGFX Dixit, Ashutosh
2023-07-02  3:02   ` Guenter Roeck
2023-07-02 15:57     ` Dixit, Ashutosh
2023-07-02 17:01       ` Guenter Roeck
2023-07-02 20:29         ` Dixit, Ashutosh
2023-07-02 20:51           ` Guenter Roeck
2023-07-03  1:48             ` Dixit, Ashutosh
2023-07-03  2:37               ` Guenter Roeck
2023-07-14 20:21         ` Rodrigo Vivi
2023-07-14 22:26           ` Guenter Roeck
2023-07-19 17:01             ` Rodrigo Vivi
2023-07-03  8:55     ` Andi Shyti

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230627183043.2024530-3-badal.nilawar@intel.com \
    --to=badal.nilawar@intel.com \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux@roeck-us.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox