linux/drivers/gpu/drm/i915/i915_hwmon.c

// SPDX-License-Identifier: MIT
/*
 * Copyright © 2022 Intel Corporation
 */

#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/jiffies.h>
#include <linux/types.h>

#include "i915_drv.h"
#include "i915_hwmon.h"
#include "i915_reg.h"
#include "intel_mchbar_regs.h"
#include "intel_pcode.h"
#include "gt/intel_gt.h"
#include "gt/intel_gt_regs.h"

/*
 * SF_* - scale factors for particular quantities according to hwmon spec.
 * - voltage  - millivolts
 * - power  - microwatts
 * - curr   - milliamperes
 * - energy - microjoules
 * - time   - milliseconds
 */
#define SF_VOLTAGE
#define SF_POWER
#define SF_CURR
#define SF_ENERGY
#define SF_TIME

struct hwm_reg {};

struct hwm_energy_info {};

struct hwm_fan_info {};

struct hwm_drvdata {};

struct i915_hwmon {};

static void
hwm_locked_with_pm_intel_uncore_rmw(struct hwm_drvdata *ddat,
				    i915_reg_t reg, u32 clear, u32 set)
{}

/*
 * This function's return type of u64 allows for the case where the scaling
 * of the field taken from the 32-bit register value might cause a result to
 * exceed 32 bits.
 */
static u64
hwm_field_read_and_scale(struct hwm_drvdata *ddat, i915_reg_t rgadr,
			 u32 field_msk, int nshift, u32 scale_factor)
{}

/*
 * hwm_energy - Obtain energy value
 *
 * The underlying energy hardware register is 32-bits and is subject to
 * overflow. How long before overflow? For example, with an example
 * scaling bit shift of 14 bits (see register *PACKAGE_POWER_SKU_UNIT) and
 * a power draw of 1000 watts, the 32-bit counter will overflow in
 * approximately 4.36 minutes.
 *
 * Examples:
 *    1 watt:  (2^32 >> 14) /    1 W / (60 * 60 * 24) secs/day -> 3 days
 * 1000 watts: (2^32 >> 14) / 1000 W / 60             secs/min -> 4.36 minutes
 *
 * The function significantly increases overflow duration (from 4.36
 * minutes) by accumulating the energy register into a 'long' as allowed by
 * the hwmon API. Using x86_64 128 bit arithmetic (see mul_u64_u32_shr()),
 * a 'long' of 63 bits, SF_ENERGY of 1e6 (~20 bits) and
 * hwmon->scl_shift_energy of 14 bits we have 57 (63 - 20 + 14) bits before
 * energy1_input overflows. This at 1000 W is an overflow duration of 278 years.
 */
static void
hwm_energy(struct hwm_drvdata *ddat, long *energy)
{}

static ssize_t
hwm_power1_max_interval_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{}

static ssize_t
hwm_power1_max_interval_store(struct device *dev,
			      struct device_attribute *attr,
			      const char *buf, size_t count)
{}

static SENSOR_DEVICE_ATTR(power1_max_interval, 0664,
			  hwm_power1_max_interval_show,
			  hwm_power1_max_interval_store, 0);

static struct attribute *hwm_attributes[] =;

static umode_t hwm_attributes_visible(struct kobject *kobj,
				      struct attribute *attr, int index)
{}

static const struct attribute_group hwm_attrgroup =;

static const struct attribute_group *hwm_groups[] =;

static const struct hwmon_channel_info * const hwm_info[] =;

static const struct hwmon_channel_info * const hwm_gt_info[] =;

/* I1 is exposed as power_crit or as curr_crit depending on bit 31 */
static int hwm_pcode_read_i1(struct drm_i915_private *i915, u32 *uval)
{}

static int hwm_pcode_write_i1(struct drm_i915_private *i915, u32 uval)
{}

static umode_t
hwm_in_is_visible(const struct hwm_drvdata *ddat, u32 attr)
{}

static int
hwm_in_read(struct hwm_drvdata *ddat, u32 attr, long *val)
{}

static umode_t
hwm_power_is_visible(const struct hwm_drvdata *ddat, u32 attr, int chan)
{}

#define PL1_DISABLE

/*
 * 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. Write/read I1 also follows the same pattern.
 */
static int
hwm_power_max_read(struct hwm_drvdata *ddat, long *val)
{}

static int
hwm_power_max_write(struct hwm_drvdata *ddat, long val)
{}

static int
hwm_power_read(struct hwm_drvdata *ddat, u32 attr, int chan, long *val)
{}

static int
hwm_power_write(struct hwm_drvdata *ddat, u32 attr, int chan, long val)
{}

void i915_hwmon_power_max_disable(struct drm_i915_private *i915, bool *old)
{}

void i915_hwmon_power_max_restore(struct drm_i915_private *i915, bool old)
{}

static umode_t
hwm_energy_is_visible(const struct hwm_drvdata *ddat, u32 attr)
{}

static int
hwm_energy_read(struct hwm_drvdata *ddat, u32 attr, long *val)
{}

static umode_t
hwm_curr_is_visible(const struct hwm_drvdata *ddat, u32 attr)
{}

static int
hwm_curr_read(struct hwm_drvdata *ddat, u32 attr, long *val)
{}

static int
hwm_curr_write(struct hwm_drvdata *ddat, u32 attr, long val)
{}

static umode_t
hwm_fan_is_visible(const struct hwm_drvdata *ddat, u32 attr)
{}

static int
hwm_fan_input_read(struct hwm_drvdata *ddat, long *val)
{}

static int
hwm_fan_read(struct hwm_drvdata *ddat, u32 attr, long *val)
{}

static umode_t
hwm_is_visible(const void *drvdata, enum hwmon_sensor_types type,
	       u32 attr, int channel)
{}

static int
hwm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
	 int channel, long *val)
{}

static int
hwm_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
	  int channel, long val)
{}

static const struct hwmon_ops hwm_ops =;

static const struct hwmon_chip_info hwm_chip_info =;

static umode_t
hwm_gt_is_visible(const void *drvdata, enum hwmon_sensor_types type,
		  u32 attr, int channel)
{}

static int
hwm_gt_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
	    int channel, long *val)
{}

static const struct hwmon_ops hwm_gt_ops =;

static const struct hwmon_chip_info hwm_gt_chip_info =;

static void
hwm_get_preregistration_info(struct drm_i915_private *i915)
{}

void i915_hwmon_register(struct drm_i915_private *i915)
{}

void i915_hwmon_unregister(struct drm_i915_private *i915)
{}