[Intel-xe] [RFC PATCH 4/6] drm/xe/hwmon: Expose input voltage attribute
Riana Tauro
riana.tauro at intel.com
Wed Jun 14 08:08:27 UTC 2023
Hi Badal
On 6/6/2023 6:20 PM, Badal Nilawar wrote:
> Use Xe HWMON subsystem to display the input voltage.
>
> Co-developed-by: Riana Tauro <riana.tauro at intel.com>
> Signed-off-by: Badal Nilawar <badal.nilawar at intel.com>
> ---
> .../ABI/testing/sysfs-driver-intel-xe-hwmon | 6 ++
> drivers/gpu/drm/xe/regs/xe_gt_regs.h | 3 +
> drivers/gpu/drm/xe/xe_hwmon.c | 70 +++++++++++++++++--
> 3 files changed, 75 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon b/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon
> index fcc2aedb2aac..aa064e0c5751 100644
> --- a/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon
> +++ b/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon
> @@ -44,5 +44,11 @@ Description: RW. Card reactive critical (I1) power limit in milliamperes.
> the operating frequency if the power averaged over a window
> exceeds this limit.
>
> +What: /sys/devices/.../hwmon/hwmon<i>/in0_input
> +Date: June 2023
> +KernelVersion: 6.3
> +Contact: intel-gfx at lists.freedesktop.org
> +Description: RO. Current Voltage in millivolt.
> +
> 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 9d888aae907e..fe00c42ff29d 100644
> --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> @@ -349,6 +349,9 @@
> #define GT_GFX_RC6_LOCKED XE_REG(0x138104)
> #define GT_GFX_RC6 XE_REG(0x138108)
>
> +#define GT_PERF_STATUS XE_REG(0x1381b4)
> +#define VOLTAGE_MASK REG_GENMASK(10, 0)
> +
> #define GT_INTR_DW(x) XE_REG(0x190018 + ((x) * 4))
>
> #define GUC_SG_INTR_ENABLE XE_REG(0x190038)
> diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c
> index b07ea53fdbc6..a86d2d8218d5 100644
> --- a/drivers/gpu/drm/xe/xe_hwmon.c
> +++ b/drivers/gpu/drm/xe/xe_hwmon.c
> @@ -3,8 +3,8 @@
> * Copyright © 2023 Intel Corporation
> */
>
> -#include <linux/hwmon.h>
> #include <linux/hwmon-sysfs.h>
> +#include <linux/hwmon.h>
> #include <linux/types.h>
>
> #include "regs/xe_mchbar_regs.h"
> @@ -26,6 +26,7 @@ enum hwm_reg_name {
> pkg_rapl_limit,
> pkg_power_sku,
> pkg_power_sku_unit,
> + gt_perf_status,
> };
>
> enum hwm_reg_operation {
> @@ -36,13 +37,13 @@ enum hwm_reg_operation {
>
> /*
> * SF_* - scale factors for particular quantities according to hwmon spec.
> - * - voltage - millivolts
> * - power - microwatts
> * - curr - milliamperes
> + * - voltage - millivolts
> */
> -#define SF_VOLTAGE 1000
> #define SF_POWER 1000000
> #define SF_CURR 1000
> +#define SF_VOLTAGE 1000
>
> struct hwm_drvdata {
> struct xe_hwmon *hwmon;
> @@ -86,6 +87,11 @@ struct xe_reg hwm_get_reg(struct hwm_drvdata *ddat, enum hwm_reg_name reg_name)
> else
> return XE_REG(0);
> break;
> + case gt_perf_status:
> + if (IS_DG2(gt_to_xe(ddat->gt)))
> + return GT_PERF_STATUS;
> + else
> + return XE_REG(0);
> default:
> break;
> }
> @@ -254,9 +260,9 @@ static int hwm_power_rated_max_read(struct hwm_drvdata *ddat, long *value)
> }
>
> static const struct hwmon_channel_info *hwm_info[] = {
> - HWMON_CHANNEL_INFO(power, HWMON_P_MAX | HWMON_P_RATED_MAX),
> HWMON_CHANNEL_INFO(power, HWMON_P_MAX | HWMON_P_RATED_MAX | HWMON_P_CRIT),
> HWMON_CHANNEL_INFO(curr, HWMON_C_CRIT),
> + HWMON_CHANNEL_INFO(in, HWMON_I_INPUT),
> NULL
> };
>
> @@ -279,6 +285,22 @@ static int hwm_pcode_write_i1(struct xe_gt *gt, u32 uval)
> uval);
> }
>
> +static int hwm_get_vltg(struct hwm_drvdata *ddat, long *value)
hwm_get_voltage?
> +{
> + u32 reg_val;
> +
> + if (IS_DG2(gt_to_xe(ddat->gt))) {
This check is not required here if is_visible checks if reg raw is valid
> + process_hwmon_reg(ddat, gt_perf_status,
> + reg_read, ®_val, 0, 0);
> + /* HW register value in units of 2.5 millivolt */
> + *value = DIV_ROUND_CLOSEST(REG_FIELD_GET(VOLTAGE_MASK, reg_val) * 25, 10);
Since we are adding a scale factor to this patch. We need to use it here
> +
> + return 0;
> + }
> +
> + return -EOPNOTSUPP;
> +}
> +
> static umode_t
> hwm_power_is_visible(struct hwm_drvdata *ddat, u32 attr, int chan)
> {
> @@ -432,6 +454,39 @@ hwm_curr_write(struct hwm_drvdata *ddat, u32 attr, long val)
> }
> }
>
> +static umode_t
> +hwm_in_is_visible(struct hwm_drvdata *ddat, u32 attr)
> +{
> + long val;
> +
> + switch (attr) {
> + case hwmon_in_input:
> + return hwm_get_vltg(ddat, &val) ? 0 : 0444;
> + default:
> + return 0;
> + }
> +}
> +
> +static int
> +hwm_in_read(struct hwm_drvdata *ddat, u32 attr, long *val)
> +{
> + int ret;
> +
> + xe_device_mem_access_get(gt_to_xe(ddat->gt));
> +
> + switch (attr) {
> + case hwmon_in_input:
> + ret = hwm_get_vltg(ddat, val);
> + break;
> + default:
> + ret = -EOPNOTSUPP;
> + }
> +
> + xe_device_mem_access_put(gt_to_xe(ddat->gt));
> +
> + return ret;
> +}
> +
> static umode_t
> hwm_is_visible(const void *drvdata, enum hwmon_sensor_types type,
> u32 attr, int channel)
> @@ -445,6 +500,8 @@ hwm_is_visible(const void *drvdata, enum hwmon_sensor_types type,
> break;
> case hwmon_curr:
> return hwm_curr_is_visible(ddat, attr);
> + case hwmon_in:
> + return hwm_in_is_visible(ddat, attr);
> default:
> ret = 0;
> }
> @@ -463,6 +520,8 @@ hwm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
> return hwm_power_read(ddat, attr, channel, val);
> case hwmon_curr:
> return hwm_curr_read(ddat, attr, val);
> + case hwmon_in:
> + return hwm_in_read(ddat, attr, val);
> default:
> return -EOPNOTSUPP;
> }
> @@ -530,6 +589,9 @@ 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;
This had to be added in second patch
Thanks
Riana
> +
> ddat->hwmon = hwmon;
> snprintf(ddat->name, sizeof(ddat->name), "xe");
>
More information about the Intel-xe
mailing list