6
6
#include <linux/hwmon-sysfs.h>
7
7
#include <linux/hwmon.h>
8
8
#include <linux/types.h>
9
+ #include <linux/units.h>
9
10
10
11
#include <drm/drm_managed.h>
11
12
#include "regs/xe_gt_regs.h"
20
21
#include "xe_pm.h"
21
22
22
23
enum xe_hwmon_reg {
24
+ REG_TEMP ,
23
25
REG_PKG_RAPL_LIMIT ,
24
26
REG_PKG_POWER_SKU ,
25
27
REG_PKG_POWER_SKU_UNIT ,
@@ -36,6 +38,7 @@ enum xe_hwmon_reg_operation {
36
38
enum xe_hwmon_channel {
37
39
CHANNEL_CARD ,
38
40
CHANNEL_PKG ,
41
+ CHANNEL_VRAM ,
39
42
CHANNEL_MAX ,
40
43
};
41
44
@@ -84,6 +87,19 @@ static struct xe_reg xe_hwmon_get_reg(struct xe_hwmon *hwmon, enum xe_hwmon_reg
84
87
struct xe_device * xe = hwmon -> xe ;
85
88
86
89
switch (hwmon_reg ) {
90
+ case REG_TEMP :
91
+ if (xe -> info .platform == XE_BATTLEMAGE ) {
92
+ if (channel == CHANNEL_PKG )
93
+ return BMG_PACKAGE_TEMPERATURE ;
94
+ else if (channel == CHANNEL_VRAM )
95
+ return BMG_VRAM_TEMPERATURE ;
96
+ } else if (xe -> info .platform == XE_DG2 ) {
97
+ if (channel == CHANNEL_PKG )
98
+ return PCU_CR_PACKAGE_TEMPERATURE ;
99
+ else if (channel == CHANNEL_VRAM )
100
+ return BMG_VRAM_TEMPERATURE ;
101
+ }
102
+ break ;
87
103
case REG_PKG_RAPL_LIMIT :
88
104
if (xe -> info .platform == XE_BATTLEMAGE ) {
89
105
if (channel == CHANNEL_PKG )
@@ -431,6 +447,8 @@ static const struct attribute_group *hwmon_groups[] = {
431
447
};
432
448
433
449
static const struct hwmon_channel_info * const hwmon_info [] = {
450
+ HWMON_CHANNEL_INFO (temp , HWMON_T_LABEL , HWMON_T_INPUT | HWMON_T_LABEL ,
451
+ HWMON_T_INPUT | HWMON_T_LABEL ),
434
452
HWMON_CHANNEL_INFO (power , HWMON_P_MAX | HWMON_P_RATED_MAX | HWMON_P_LABEL ,
435
453
HWMON_P_MAX | HWMON_P_RATED_MAX | HWMON_P_CRIT | HWMON_P_LABEL ),
436
454
HWMON_CHANNEL_INFO (curr , HWMON_C_LABEL , HWMON_C_CRIT | HWMON_C_LABEL ),
@@ -506,6 +524,36 @@ static void xe_hwmon_get_voltage(struct xe_hwmon *hwmon, int channel, long *valu
506
524
* value = DIV_ROUND_CLOSEST (REG_FIELD_GET (VOLTAGE_MASK , reg_val ) * 2500 , SF_VOLTAGE );
507
525
}
508
526
527
+ static umode_t
528
+ xe_hwmon_temp_is_visible (struct xe_hwmon * hwmon , u32 attr , int channel )
529
+ {
530
+ switch (attr ) {
531
+ case hwmon_temp_input :
532
+ case hwmon_temp_label :
533
+ return xe_reg_is_valid (xe_hwmon_get_reg (hwmon , REG_TEMP , channel )) ? 0444 : 0 ;
534
+ default :
535
+ return 0 ;
536
+ }
537
+ }
538
+
539
+ static int
540
+ xe_hwmon_temp_read (struct xe_hwmon * hwmon , u32 attr , int channel , long * val )
541
+ {
542
+ struct xe_mmio * mmio = xe_root_tile_mmio (hwmon -> xe );
543
+ u64 reg_val ;
544
+
545
+ switch (attr ) {
546
+ case hwmon_temp_input :
547
+ reg_val = xe_mmio_read32 (mmio , xe_hwmon_get_reg (hwmon , REG_TEMP , channel ));
548
+
549
+ /* HW register value is in degrees Celsius, convert to millidegrees. */
550
+ * val = REG_FIELD_GET (TEMP_MASK , reg_val ) * MILLIDEGREE_PER_DEGREE ;
551
+ return 0 ;
552
+ default :
553
+ return - EOPNOTSUPP ;
554
+ }
555
+ }
556
+
509
557
static umode_t
510
558
xe_hwmon_power_is_visible (struct xe_hwmon * hwmon , u32 attr , int channel )
511
559
{
@@ -667,6 +715,9 @@ xe_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type,
667
715
xe_pm_runtime_get (hwmon -> xe );
668
716
669
717
switch (type ) {
718
+ case hwmon_temp :
719
+ ret = xe_hwmon_temp_is_visible (hwmon , attr , channel );
720
+ break ;
670
721
case hwmon_power :
671
722
ret = xe_hwmon_power_is_visible (hwmon , attr , channel );
672
723
break ;
@@ -699,6 +750,9 @@ xe_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
699
750
xe_pm_runtime_get (hwmon -> xe );
700
751
701
752
switch (type ) {
753
+ case hwmon_temp :
754
+ ret = xe_hwmon_temp_read (hwmon , attr , channel , val );
755
+ break ;
702
756
case hwmon_power :
703
757
ret = xe_hwmon_power_read (hwmon , attr , channel , val );
704
758
break ;
@@ -752,6 +806,12 @@ static int xe_hwmon_read_label(struct device *dev,
752
806
u32 attr , int channel , const char * * str )
753
807
{
754
808
switch (type ) {
809
+ case hwmon_temp :
810
+ if (channel == CHANNEL_PKG )
811
+ * str = "pkg" ;
812
+ else if (channel == CHANNEL_VRAM )
813
+ * str = "vram" ;
814
+ return 0 ;
755
815
case hwmon_power :
756
816
case hwmon_energy :
757
817
case hwmon_curr :
0 commit comments