xref: /linux/drivers/gpu/drm/i915/i915_hwmon.c (revision b3b088e28183b84080b7f0a0b8da84ec42b4b0e8)
1*b3b088e2SDale B Stimson // SPDX-License-Identifier: MIT
2*b3b088e2SDale B Stimson /*
3*b3b088e2SDale B Stimson  * Copyright © 2022 Intel Corporation
4*b3b088e2SDale B Stimson  */
5*b3b088e2SDale B Stimson 
6*b3b088e2SDale B Stimson #include <linux/hwmon.h>
7*b3b088e2SDale B Stimson #include <linux/hwmon-sysfs.h>
8*b3b088e2SDale B Stimson #include <linux/types.h>
9*b3b088e2SDale B Stimson 
10*b3b088e2SDale B Stimson #include "i915_drv.h"
11*b3b088e2SDale B Stimson #include "i915_hwmon.h"
12*b3b088e2SDale B Stimson #include "i915_reg.h"
13*b3b088e2SDale B Stimson #include "intel_mchbar_regs.h"
14*b3b088e2SDale B Stimson 
15*b3b088e2SDale B Stimson struct hwm_reg {
16*b3b088e2SDale B Stimson };
17*b3b088e2SDale B Stimson 
18*b3b088e2SDale B Stimson struct hwm_drvdata {
19*b3b088e2SDale B Stimson 	struct i915_hwmon *hwmon;
20*b3b088e2SDale B Stimson 	struct intel_uncore *uncore;
21*b3b088e2SDale B Stimson 	struct device *hwmon_dev;
22*b3b088e2SDale B Stimson 	char name[12];
23*b3b088e2SDale B Stimson };
24*b3b088e2SDale B Stimson 
25*b3b088e2SDale B Stimson struct i915_hwmon {
26*b3b088e2SDale B Stimson 	struct hwm_drvdata ddat;
27*b3b088e2SDale B Stimson 	struct mutex hwmon_lock;		/* counter overflow logic and rmw */
28*b3b088e2SDale B Stimson 	struct hwm_reg rg;
29*b3b088e2SDale B Stimson };
30*b3b088e2SDale B Stimson 
31*b3b088e2SDale B Stimson static const struct hwmon_channel_info *hwm_info[] = {
32*b3b088e2SDale B Stimson 	NULL
33*b3b088e2SDale B Stimson };
34*b3b088e2SDale B Stimson 
35*b3b088e2SDale B Stimson static umode_t
36*b3b088e2SDale B Stimson hwm_is_visible(const void *drvdata, enum hwmon_sensor_types type,
37*b3b088e2SDale B Stimson 	       u32 attr, int channel)
38*b3b088e2SDale B Stimson {
39*b3b088e2SDale B Stimson 	switch (type) {
40*b3b088e2SDale B Stimson 	default:
41*b3b088e2SDale B Stimson 		return 0;
42*b3b088e2SDale B Stimson 	}
43*b3b088e2SDale B Stimson }
44*b3b088e2SDale B Stimson 
45*b3b088e2SDale B Stimson static int
46*b3b088e2SDale B Stimson hwm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
47*b3b088e2SDale B Stimson 	 int channel, long *val)
48*b3b088e2SDale B Stimson {
49*b3b088e2SDale B Stimson 	switch (type) {
50*b3b088e2SDale B Stimson 	default:
51*b3b088e2SDale B Stimson 		return -EOPNOTSUPP;
52*b3b088e2SDale B Stimson 	}
53*b3b088e2SDale B Stimson }
54*b3b088e2SDale B Stimson 
55*b3b088e2SDale B Stimson static int
56*b3b088e2SDale B Stimson hwm_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
57*b3b088e2SDale B Stimson 	  int channel, long val)
58*b3b088e2SDale B Stimson {
59*b3b088e2SDale B Stimson 	switch (type) {
60*b3b088e2SDale B Stimson 	default:
61*b3b088e2SDale B Stimson 		return -EOPNOTSUPP;
62*b3b088e2SDale B Stimson 	}
63*b3b088e2SDale B Stimson }
64*b3b088e2SDale B Stimson 
65*b3b088e2SDale B Stimson static const struct hwmon_ops hwm_ops = {
66*b3b088e2SDale B Stimson 	.is_visible = hwm_is_visible,
67*b3b088e2SDale B Stimson 	.read = hwm_read,
68*b3b088e2SDale B Stimson 	.write = hwm_write,
69*b3b088e2SDale B Stimson };
70*b3b088e2SDale B Stimson 
71*b3b088e2SDale B Stimson static const struct hwmon_chip_info hwm_chip_info = {
72*b3b088e2SDale B Stimson 	.ops = &hwm_ops,
73*b3b088e2SDale B Stimson 	.info = hwm_info,
74*b3b088e2SDale B Stimson };
75*b3b088e2SDale B Stimson 
76*b3b088e2SDale B Stimson static void
77*b3b088e2SDale B Stimson hwm_get_preregistration_info(struct drm_i915_private *i915)
78*b3b088e2SDale B Stimson {
79*b3b088e2SDale B Stimson }
80*b3b088e2SDale B Stimson 
81*b3b088e2SDale B Stimson void i915_hwmon_register(struct drm_i915_private *i915)
82*b3b088e2SDale B Stimson {
83*b3b088e2SDale B Stimson 	struct device *dev = i915->drm.dev;
84*b3b088e2SDale B Stimson 	struct i915_hwmon *hwmon;
85*b3b088e2SDale B Stimson 	struct device *hwmon_dev;
86*b3b088e2SDale B Stimson 	struct hwm_drvdata *ddat;
87*b3b088e2SDale B Stimson 
88*b3b088e2SDale B Stimson 	/* hwmon is available only for dGfx */
89*b3b088e2SDale B Stimson 	if (!IS_DGFX(i915))
90*b3b088e2SDale B Stimson 		return;
91*b3b088e2SDale B Stimson 
92*b3b088e2SDale B Stimson 	hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL);
93*b3b088e2SDale B Stimson 	if (!hwmon)
94*b3b088e2SDale B Stimson 		return;
95*b3b088e2SDale B Stimson 
96*b3b088e2SDale B Stimson 	i915->hwmon = hwmon;
97*b3b088e2SDale B Stimson 	mutex_init(&hwmon->hwmon_lock);
98*b3b088e2SDale B Stimson 	ddat = &hwmon->ddat;
99*b3b088e2SDale B Stimson 
100*b3b088e2SDale B Stimson 	ddat->hwmon = hwmon;
101*b3b088e2SDale B Stimson 	ddat->uncore = &i915->uncore;
102*b3b088e2SDale B Stimson 	snprintf(ddat->name, sizeof(ddat->name), "i915");
103*b3b088e2SDale B Stimson 
104*b3b088e2SDale B Stimson 	hwm_get_preregistration_info(i915);
105*b3b088e2SDale B Stimson 
106*b3b088e2SDale B Stimson 	/*  hwmon_dev points to device hwmon<i> */
107*b3b088e2SDale B Stimson 	hwmon_dev = devm_hwmon_device_register_with_info(dev, ddat->name,
108*b3b088e2SDale B Stimson 							 ddat,
109*b3b088e2SDale B Stimson 							 &hwm_chip_info,
110*b3b088e2SDale B Stimson 							 NULL);
111*b3b088e2SDale B Stimson 	if (IS_ERR(hwmon_dev)) {
112*b3b088e2SDale B Stimson 		i915->hwmon = NULL;
113*b3b088e2SDale B Stimson 		return;
114*b3b088e2SDale B Stimson 	}
115*b3b088e2SDale B Stimson 
116*b3b088e2SDale B Stimson 	ddat->hwmon_dev = hwmon_dev;
117*b3b088e2SDale B Stimson }
118*b3b088e2SDale B Stimson 
119*b3b088e2SDale B Stimson void i915_hwmon_unregister(struct drm_i915_private *i915)
120*b3b088e2SDale B Stimson {
121*b3b088e2SDale B Stimson 	fetch_and_zero(&i915->hwmon);
122*b3b088e2SDale B Stimson }
123