55
66#include <linux/hwmon-sysfs.h>
77#include <linux/hwmon.h>
8+ #include <linux/jiffies.h>
89#include <linux/types.h>
910#include <linux/units.h>
1011
@@ -27,6 +28,7 @@ enum xe_hwmon_reg {
2728 REG_PKG_POWER_SKU_UNIT ,
2829 REG_GT_PERF_STATUS ,
2930 REG_PKG_ENERGY_STATUS ,
31+ REG_FAN_SPEED ,
3032};
3133
3234enum xe_hwmon_reg_operation {
@@ -42,6 +44,13 @@ enum xe_hwmon_channel {
4244 CHANNEL_MAX ,
4345};
4446
47+ enum xe_fan_channel {
48+ FAN_1 ,
49+ FAN_2 ,
50+ FAN_3 ,
51+ FAN_MAX ,
52+ };
53+
4554/*
4655 * SF_* - scale factors for particular quantities according to hwmon spec.
4756 */
@@ -61,6 +70,16 @@ struct xe_hwmon_energy_info {
6170 long accum_energy ;
6271};
6372
73+ /**
74+ * struct xe_hwmon_fan_info - to cache previous fan reading
75+ */
76+ struct xe_hwmon_fan_info {
77+ /** @reg_val_prev: previous fan reg val */
78+ u32 reg_val_prev ;
79+ /** @time_prev: previous timestamp */
80+ u64 time_prev ;
81+ };
82+
6483/**
6584 * struct xe_hwmon - xe hwmon data structure
6685 */
@@ -79,6 +98,8 @@ struct xe_hwmon {
7998 int scl_shift_time ;
8099 /** @ei: Energy info for energyN_input */
81100 struct xe_hwmon_energy_info ei [CHANNEL_MAX ];
101+ /** @fi: Fan info for fanN_input */
102+ struct xe_hwmon_fan_info fi [FAN_MAX ];
82103};
83104
84105static struct xe_reg xe_hwmon_get_reg (struct xe_hwmon * hwmon , enum xe_hwmon_reg hwmon_reg ,
@@ -144,6 +165,14 @@ static struct xe_reg xe_hwmon_get_reg(struct xe_hwmon *hwmon, enum xe_hwmon_reg
144165 return PCU_CR_PACKAGE_ENERGY_STATUS ;
145166 }
146167 break ;
168+ case REG_FAN_SPEED :
169+ if (channel == FAN_1 )
170+ return BMG_FAN_1_SPEED ;
171+ else if (channel == FAN_2 )
172+ return BMG_FAN_2_SPEED ;
173+ else if (channel == FAN_3 )
174+ return BMG_FAN_3_SPEED ;
175+ break ;
147176 default :
148177 drm_warn (& xe -> drm , "Unknown xe hwmon reg id: %d\n" , hwmon_reg );
149178 break ;
@@ -454,6 +483,7 @@ static const struct hwmon_channel_info * const hwmon_info[] = {
454483 HWMON_CHANNEL_INFO (curr , HWMON_C_LABEL , HWMON_C_CRIT | HWMON_C_LABEL ),
455484 HWMON_CHANNEL_INFO (in , HWMON_I_INPUT | HWMON_I_LABEL , HWMON_I_INPUT | HWMON_I_LABEL ),
456485 HWMON_CHANNEL_INFO (energy , HWMON_E_INPUT | HWMON_E_LABEL , HWMON_E_INPUT | HWMON_E_LABEL ),
486+ HWMON_CHANNEL_INFO (fan , HWMON_F_INPUT , HWMON_F_INPUT , HWMON_F_INPUT ),
457487 NULL
458488};
459489
@@ -480,6 +510,19 @@ static int xe_hwmon_pcode_write_i1(const struct xe_hwmon *hwmon, u32 uval)
480510 (uval & POWER_SETUP_I1_DATA_MASK ));
481511}
482512
513+ static int xe_hwmon_pcode_read_fan_control (const struct xe_hwmon * hwmon , u32 subcmd , u32 * uval )
514+ {
515+ struct xe_tile * root_tile = xe_device_get_root_tile (hwmon -> xe );
516+
517+ /* Platforms that don't return correct value */
518+ if (hwmon -> xe -> info .platform == XE_DG2 && subcmd == FSC_READ_NUM_FANS ) {
519+ * uval = 2 ;
520+ return 0 ;
521+ }
522+
523+ return xe_pcode_read (root_tile , PCODE_MBOX (FAN_SPEED_CONTROL , subcmd , 0 ), uval , NULL );
524+ }
525+
483526static int xe_hwmon_power_curr_crit_read (struct xe_hwmon * hwmon , int channel ,
484527 long * value , u32 scale_factor )
485528{
@@ -705,6 +748,75 @@ xe_hwmon_energy_read(struct xe_hwmon *hwmon, u32 attr, int channel, long *val)
705748 }
706749}
707750
751+ static umode_t
752+ xe_hwmon_fan_is_visible (struct xe_hwmon * hwmon , u32 attr , int channel )
753+ {
754+ u32 uval ;
755+
756+ if (!hwmon -> xe -> info .has_fan_control )
757+ return 0 ;
758+
759+ switch (attr ) {
760+ case hwmon_fan_input :
761+ if (xe_hwmon_pcode_read_fan_control (hwmon , FSC_READ_NUM_FANS , & uval ))
762+ return 0 ;
763+
764+ return channel < uval ? 0444 : 0 ;
765+ default :
766+ return 0 ;
767+ }
768+ }
769+
770+ static int
771+ xe_hwmon_fan_input_read (struct xe_hwmon * hwmon , int channel , long * val )
772+ {
773+ struct xe_mmio * mmio = xe_root_tile_mmio (hwmon -> xe );
774+ struct xe_hwmon_fan_info * fi = & hwmon -> fi [channel ];
775+ u64 rotations , time_now , time ;
776+ u32 reg_val ;
777+ int ret = 0 ;
778+
779+ mutex_lock (& hwmon -> hwmon_lock );
780+
781+ reg_val = xe_mmio_read32 (mmio , xe_hwmon_get_reg (hwmon , REG_FAN_SPEED , channel ));
782+ time_now = get_jiffies_64 ();
783+
784+ /*
785+ * HW register value is accumulated count of pulses from PWM fan with the scale
786+ * of 2 pulses per rotation.
787+ */
788+ rotations = (reg_val - fi -> reg_val_prev ) / 2 ;
789+
790+ time = jiffies_delta_to_msecs (time_now - fi -> time_prev );
791+ if (unlikely (!time )) {
792+ ret = - EAGAIN ;
793+ goto unlock ;
794+ }
795+
796+ /*
797+ * Calculate fan speed in RPM by time averaging two subsequent readings in minutes.
798+ * RPM = number of rotations * msecs per minute / time in msecs
799+ */
800+ * val = DIV_ROUND_UP_ULL (rotations * (MSEC_PER_SEC * 60 ), time );
801+
802+ fi -> reg_val_prev = reg_val ;
803+ fi -> time_prev = time_now ;
804+ unlock :
805+ mutex_unlock (& hwmon -> hwmon_lock );
806+ return ret ;
807+ }
808+
809+ static int
810+ xe_hwmon_fan_read (struct xe_hwmon * hwmon , u32 attr , int channel , long * val )
811+ {
812+ switch (attr ) {
813+ case hwmon_fan_input :
814+ return xe_hwmon_fan_input_read (hwmon , channel , val );
815+ default :
816+ return - EOPNOTSUPP ;
817+ }
818+ }
819+
708820static umode_t
709821xe_hwmon_is_visible (const void * drvdata , enum hwmon_sensor_types type ,
710822 u32 attr , int channel )
@@ -730,6 +842,9 @@ xe_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type,
730842 case hwmon_energy :
731843 ret = xe_hwmon_energy_is_visible (hwmon , attr , channel );
732844 break ;
845+ case hwmon_fan :
846+ ret = xe_hwmon_fan_is_visible (hwmon , attr , channel );
847+ break ;
733848 default :
734849 ret = 0 ;
735850 break ;
@@ -765,6 +880,9 @@ xe_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
765880 case hwmon_energy :
766881 ret = xe_hwmon_energy_read (hwmon , attr , channel , val );
767882 break ;
883+ case hwmon_fan :
884+ ret = xe_hwmon_fan_read (hwmon , attr , channel , val );
885+ break ;
768886 default :
769887 ret = - EOPNOTSUPP ;
770888 break ;
@@ -842,7 +960,7 @@ static void
842960xe_hwmon_get_preregistration_info (struct xe_hwmon * hwmon )
843961{
844962 struct xe_mmio * mmio = xe_root_tile_mmio (hwmon -> xe );
845- long energy ;
963+ long energy , fan_speed ;
846964 u64 val_sku_unit = 0 ;
847965 int channel ;
848966 struct xe_reg pkg_power_sku_unit ;
@@ -866,6 +984,11 @@ xe_hwmon_get_preregistration_info(struct xe_hwmon *hwmon)
866984 for (channel = 0 ; channel < CHANNEL_MAX ; channel ++ )
867985 if (xe_hwmon_is_visible (hwmon , hwmon_energy , hwmon_energy_input , channel ))
868986 xe_hwmon_energy_get (hwmon , channel , & energy );
987+
988+ /* Initialize 'struct xe_hwmon_fan_info' with initial fan register reading. */
989+ for (channel = 0 ; channel < FAN_MAX ; channel ++ )
990+ if (xe_hwmon_is_visible (hwmon , hwmon_fan , hwmon_fan_input , channel ))
991+ xe_hwmon_fan_input_read (hwmon , channel , & fan_speed );
869992}
870993
871994static void xe_hwmon_mutex_destroy (void * arg )
0 commit comments