@@ -26,9 +26,9 @@ enum xe_hwmon_reg {
2626};
2727
2828enum xe_hwmon_reg_operation {
29- REG_READ ,
30- REG_WRITE ,
31- REG_RMW ,
29+ REG_READ32 ,
30+ REG_RMW32 ,
31+ REG_READ64 ,
3232};
3333
3434/*
@@ -39,18 +39,32 @@ enum xe_hwmon_reg_operation {
3939#define SF_VOLTAGE 1000 /* millivolts */
4040#define SF_ENERGY 1000000 /* microjoules */
4141
42+ /**
43+ * struct xe_hwmon_energy_info - to accumulate energy
44+ */
4245struct xe_hwmon_energy_info {
46+ /** @reg_val_prev: previous energy reg val */
4347 u32 reg_val_prev ;
44- long accum_energy ; /* Accumulated energy for energy1_input */
48+ /** @accum_energy: accumulated energy */
49+ long accum_energy ;
4550};
4651
52+ /**
53+ * struct xe_hwmon - xe hwmon data structure
54+ */
4755struct xe_hwmon {
56+ /** @hwmon_dev: hwmon device for xe */
4857 struct device * hwmon_dev ;
58+ /** @gt: primary gt */
4959 struct xe_gt * gt ;
50- struct mutex hwmon_lock ; /* rmw operations*/
60+ /** @hwmon_lock: lock for rmw operations */
61+ struct mutex hwmon_lock ;
62+ /** @scl_shift_power: pkg power unit */
5163 int scl_shift_power ;
64+ /** @scl_shift_energy: pkg energy unit */
5265 int scl_shift_energy ;
53- struct xe_hwmon_energy_info ei ; /* Energy info for energy1_input */
66+ /** @ei: Energy info for energy1_input */
67+ struct xe_hwmon_energy_info ei ;
5468};
5569
5670static u32 xe_hwmon_get_reg (struct xe_hwmon * hwmon , enum xe_hwmon_reg hwmon_reg )
@@ -95,49 +109,34 @@ static u32 xe_hwmon_get_reg(struct xe_hwmon *hwmon, enum xe_hwmon_reg hwmon_reg)
95109 return reg .raw ;
96110}
97111
98- static int xe_hwmon_process_reg (struct xe_hwmon * hwmon , enum xe_hwmon_reg hwmon_reg ,
99- enum xe_hwmon_reg_operation operation , u32 * value ,
100- u32 clr , u32 set )
112+ static void xe_hwmon_process_reg (struct xe_hwmon * hwmon , enum xe_hwmon_reg hwmon_reg ,
113+ enum xe_hwmon_reg_operation operation , u64 * value ,
114+ u32 clr , u32 set )
101115{
102116 struct xe_reg reg ;
103117
104118 reg .raw = xe_hwmon_get_reg (hwmon , hwmon_reg );
105119
106120 if (!reg .raw )
107- return - EOPNOTSUPP ;
121+ return ;
108122
109123 switch (operation ) {
110- case REG_READ :
124+ case REG_READ32 :
111125 * value = xe_mmio_read32 (hwmon -> gt , reg );
112- return 0 ;
113- case REG_WRITE :
114- xe_mmio_write32 (hwmon -> gt , reg , * value );
115- return 0 ;
116- case REG_RMW :
126+ break ;
127+ case REG_RMW32 :
117128 * value = xe_mmio_rmw32 (hwmon -> gt , reg , clr , set );
118- return 0 ;
129+ break ;
130+ case REG_READ64 :
131+ * value = xe_mmio_read64_2x32 (hwmon -> gt , reg );
132+ break ;
119133 default :
120134 drm_warn (& gt_to_xe (hwmon -> gt )-> drm , "Invalid xe hwmon reg operation: %d\n" ,
121135 operation );
122- return - EOPNOTSUPP ;
136+ break ;
123137 }
124138}
125139
126- static int xe_hwmon_process_reg_read64 (struct xe_hwmon * hwmon ,
127- enum xe_hwmon_reg hwmon_reg , u64 * value )
128- {
129- struct xe_reg reg ;
130-
131- reg .raw = xe_hwmon_get_reg (hwmon , hwmon_reg );
132-
133- if (!reg .raw )
134- return - EOPNOTSUPP ;
135-
136- * value = xe_mmio_read64_2x32 (hwmon -> gt , reg );
137-
138- return 0 ;
139- }
140-
141140#define PL1_DISABLE 0
142141
143142/*
@@ -146,42 +145,39 @@ static int xe_hwmon_process_reg_read64(struct xe_hwmon *hwmon,
146145 * same pattern for sysfs, allow arbitrary PL1 limits to be set but display
147146 * clamped values when read.
148147 */
149- static int xe_hwmon_power_max_read (struct xe_hwmon * hwmon , long * value )
148+ static void xe_hwmon_power_max_read (struct xe_hwmon * hwmon , long * value )
150149{
151- u32 reg_val ;
152- u64 reg_val64 , min , max ;
150+ u64 reg_val , min , max ;
153151
154- xe_hwmon_process_reg (hwmon , REG_PKG_RAPL_LIMIT , REG_READ , & reg_val , 0 , 0 );
152+ xe_hwmon_process_reg (hwmon , REG_PKG_RAPL_LIMIT , REG_READ32 , & reg_val , 0 , 0 );
155153 /* Check if PL1 limit is disabled */
156154 if (!(reg_val & PKG_PWR_LIM_1_EN )) {
157155 * value = PL1_DISABLE ;
158- return 0 ;
156+ return ;
159157 }
160158
161159 reg_val = REG_FIELD_GET (PKG_PWR_LIM_1 , reg_val );
162160 * value = mul_u64_u32_shr (reg_val , SF_POWER , hwmon -> scl_shift_power );
163161
164- xe_hwmon_process_reg_read64 (hwmon , REG_PKG_POWER_SKU , & reg_val64 );
165- min = REG_FIELD_GET (PKG_MIN_PWR , reg_val64 );
162+ xe_hwmon_process_reg (hwmon , REG_PKG_POWER_SKU , REG_READ64 , & reg_val , 0 , 0 );
163+ min = REG_FIELD_GET (PKG_MIN_PWR , reg_val );
166164 min = mul_u64_u32_shr (min , SF_POWER , hwmon -> scl_shift_power );
167- max = REG_FIELD_GET (PKG_MAX_PWR , reg_val64 );
165+ max = REG_FIELD_GET (PKG_MAX_PWR , reg_val );
168166 max = mul_u64_u32_shr (max , SF_POWER , hwmon -> scl_shift_power );
169167
170168 if (min && max )
171169 * value = clamp_t (u64 , * value , min , max );
172-
173- return 0 ;
174170}
175171
176172static int xe_hwmon_power_max_write (struct xe_hwmon * hwmon , long value )
177173{
178- u32 reg_val ;
174+ u64 reg_val ;
179175
180176 /* Disable PL1 limit and verify, as limit cannot be disabled on all platforms */
181177 if (value == PL1_DISABLE ) {
182- xe_hwmon_process_reg (hwmon , REG_PKG_RAPL_LIMIT , REG_RMW , & reg_val ,
178+ xe_hwmon_process_reg (hwmon , REG_PKG_RAPL_LIMIT , REG_RMW32 , & reg_val ,
183179 PKG_PWR_LIM_1_EN , 0 );
184- xe_hwmon_process_reg (hwmon , REG_PKG_RAPL_LIMIT , REG_READ , & reg_val ,
180+ xe_hwmon_process_reg (hwmon , REG_PKG_RAPL_LIMIT , REG_READ32 , & reg_val ,
185181 PKG_PWR_LIM_1_EN , 0 );
186182
187183 if (reg_val & PKG_PWR_LIM_1_EN )
@@ -192,21 +188,19 @@ static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, long value)
192188 reg_val = DIV_ROUND_CLOSEST_ULL ((u64 )value << hwmon -> scl_shift_power , SF_POWER );
193189 reg_val = PKG_PWR_LIM_1_EN | REG_FIELD_PREP (PKG_PWR_LIM_1 , reg_val );
194190
195- xe_hwmon_process_reg (hwmon , REG_PKG_RAPL_LIMIT , REG_RMW , & reg_val ,
191+ xe_hwmon_process_reg (hwmon , REG_PKG_RAPL_LIMIT , REG_RMW32 , & reg_val ,
196192 PKG_PWR_LIM_1_EN | PKG_PWR_LIM_1 , reg_val );
197193
198194 return 0 ;
199195}
200196
201- static int xe_hwmon_power_rated_max_read (struct xe_hwmon * hwmon , long * value )
197+ static void xe_hwmon_power_rated_max_read (struct xe_hwmon * hwmon , long * value )
202198{
203- u32 reg_val ;
199+ u64 reg_val ;
204200
205- xe_hwmon_process_reg (hwmon , REG_PKG_POWER_SKU , REG_READ , & reg_val , 0 , 0 );
201+ xe_hwmon_process_reg (hwmon , REG_PKG_POWER_SKU , REG_READ32 , & reg_val , 0 , 0 );
206202 reg_val = REG_FIELD_GET (PKG_TDP , reg_val );
207203 * value = mul_u64_u32_shr (reg_val , SF_POWER , hwmon -> scl_shift_power );
208-
209- return 0 ;
210204}
211205
212206/*
@@ -233,13 +227,11 @@ static void
233227xe_hwmon_energy_get (struct xe_hwmon * hwmon , long * energy )
234228{
235229 struct xe_hwmon_energy_info * ei = & hwmon -> ei ;
236- u32 reg_val ;
237-
238- xe_device_mem_access_get (gt_to_xe (hwmon -> gt ));
230+ u64 reg_val ;
239231
240232 mutex_lock (& hwmon -> hwmon_lock );
241233
242- xe_hwmon_process_reg (hwmon , REG_PKG_ENERGY_STATUS , REG_READ ,
234+ xe_hwmon_process_reg (hwmon , REG_PKG_ENERGY_STATUS , REG_READ32 ,
243235 & reg_val , 0 , 0 );
244236
245237 if (reg_val >= ei -> reg_val_prev )
@@ -253,8 +245,6 @@ xe_hwmon_energy_get(struct xe_hwmon *hwmon, long *energy)
253245 hwmon -> scl_shift_energy );
254246
255247 mutex_unlock (& hwmon -> hwmon_lock );
256-
257- xe_device_mem_access_put (gt_to_xe (hwmon -> gt ));
258248}
259249
260250static const struct hwmon_channel_info * hwmon_info [] = {
@@ -284,16 +274,39 @@ static int xe_hwmon_pcode_write_i1(struct xe_gt *gt, u32 uval)
284274 uval );
285275}
286276
287- static int xe_hwmon_get_voltage (struct xe_hwmon * hwmon , long * value )
277+ static int xe_hwmon_power_curr_crit_read (struct xe_hwmon * hwmon , long * value , u32 scale_factor )
288278{
289- u32 reg_val ;
279+ int ret ;
280+ u32 uval ;
281+
282+ ret = xe_hwmon_pcode_read_i1 (hwmon -> gt , & uval );
283+ if (ret )
284+ return ret ;
285+
286+ * value = mul_u64_u32_shr (REG_FIELD_GET (POWER_SETUP_I1_DATA_MASK , uval ),
287+ scale_factor , POWER_SETUP_I1_SHIFT );
288+ return ret ;
289+ }
290+
291+ static int xe_hwmon_power_curr_crit_write (struct xe_hwmon * hwmon , long value , u32 scale_factor )
292+ {
293+ int ret ;
294+ u32 uval ;
295+
296+ uval = DIV_ROUND_CLOSEST_ULL (value << POWER_SETUP_I1_SHIFT , scale_factor );
297+ ret = xe_hwmon_pcode_write_i1 (hwmon -> gt , uval );
298+
299+ return ret ;
300+ }
301+
302+ static void xe_hwmon_get_voltage (struct xe_hwmon * hwmon , long * value )
303+ {
304+ u64 reg_val ;
290305
291306 xe_hwmon_process_reg (hwmon , REG_GT_PERF_STATUS ,
292- REG_READ , & reg_val , 0 , 0 );
307+ REG_READ32 , & reg_val , 0 , 0 );
293308 /* HW register value in units of 2.5 millivolt */
294309 * value = DIV_ROUND_CLOSEST (REG_FIELD_GET (VOLTAGE_MASK , reg_val ) * 2500 , SF_VOLTAGE );
295-
296- return 0 ;
297310}
298311
299312static umode_t
@@ -317,23 +330,15 @@ xe_hwmon_power_is_visible(struct xe_hwmon *hwmon, u32 attr, int chan)
317330static int
318331xe_hwmon_power_read (struct xe_hwmon * hwmon , u32 attr , int chan , long * val )
319332{
320- int ret ;
321- u32 uval ;
322-
323333 switch (attr ) {
324334 case hwmon_power_max :
325- return xe_hwmon_power_max_read (hwmon , val );
335+ xe_hwmon_power_max_read (hwmon , val );
336+ return 0 ;
326337 case hwmon_power_rated_max :
327- return xe_hwmon_power_rated_max_read (hwmon , val );
328- case hwmon_power_crit :
329- ret = xe_hwmon_pcode_read_i1 (hwmon -> gt , & uval );
330- if (ret )
331- return ret ;
332- if (!(uval & POWER_SETUP_I1_WATTS ))
333- return - ENODEV ;
334- * val = mul_u64_u32_shr (REG_FIELD_GET (POWER_SETUP_I1_DATA_MASK , uval ),
335- SF_POWER , POWER_SETUP_I1_SHIFT );
338+ xe_hwmon_power_rated_max_read (hwmon , val );
336339 return 0 ;
340+ case hwmon_power_crit :
341+ return xe_hwmon_power_curr_crit_read (hwmon , val , SF_POWER );
337342 default :
338343 return - EOPNOTSUPP ;
339344 }
@@ -342,14 +347,11 @@ xe_hwmon_power_read(struct xe_hwmon *hwmon, u32 attr, int chan, long *val)
342347static int
343348xe_hwmon_power_write (struct xe_hwmon * hwmon , u32 attr , int chan , long val )
344349{
345- u32 uval ;
346-
347350 switch (attr ) {
348351 case hwmon_power_max :
349352 return xe_hwmon_power_max_write (hwmon , val );
350353 case hwmon_power_crit :
351- uval = DIV_ROUND_CLOSEST_ULL (val << POWER_SETUP_I1_SHIFT , SF_POWER );
352- return xe_hwmon_pcode_write_i1 (hwmon -> gt , uval );
354+ return xe_hwmon_power_curr_crit_write (hwmon , val , SF_POWER );
353355 default :
354356 return - EOPNOTSUPP ;
355357 }
@@ -372,19 +374,9 @@ xe_hwmon_curr_is_visible(const struct xe_hwmon *hwmon, u32 attr)
372374static int
373375xe_hwmon_curr_read (struct xe_hwmon * hwmon , u32 attr , long * val )
374376{
375- int ret ;
376- u32 uval ;
377-
378377 switch (attr ) {
379378 case hwmon_curr_crit :
380- ret = xe_hwmon_pcode_read_i1 (hwmon -> gt , & uval );
381- if (ret )
382- return ret ;
383- if (uval & POWER_SETUP_I1_WATTS )
384- return - ENODEV ;
385- * val = mul_u64_u32_shr (REG_FIELD_GET (POWER_SETUP_I1_DATA_MASK , uval ),
386- SF_CURR , POWER_SETUP_I1_SHIFT );
387- return 0 ;
379+ return xe_hwmon_power_curr_crit_read (hwmon , val , SF_CURR );
388380 default :
389381 return - EOPNOTSUPP ;
390382 }
@@ -393,12 +385,9 @@ xe_hwmon_curr_read(struct xe_hwmon *hwmon, u32 attr, long *val)
393385static int
394386xe_hwmon_curr_write (struct xe_hwmon * hwmon , u32 attr , long val )
395387{
396- u32 uval ;
397-
398388 switch (attr ) {
399389 case hwmon_curr_crit :
400- uval = DIV_ROUND_CLOSEST_ULL (val << POWER_SETUP_I1_SHIFT , SF_CURR );
401- return xe_hwmon_pcode_write_i1 (hwmon -> gt , uval );
390+ return xe_hwmon_power_curr_crit_write (hwmon , val , SF_CURR );
402391 default :
403392 return - EOPNOTSUPP ;
404393 }
@@ -418,21 +407,13 @@ xe_hwmon_in_is_visible(struct xe_hwmon *hwmon, u32 attr)
418407static int
419408xe_hwmon_in_read (struct xe_hwmon * hwmon , u32 attr , long * val )
420409{
421- int ret ;
422-
423- xe_device_mem_access_get (gt_to_xe (hwmon -> gt ));
424-
425410 switch (attr ) {
426411 case hwmon_in_input :
427- ret = xe_hwmon_get_voltage (hwmon , val );
428- break ;
412+ xe_hwmon_get_voltage (hwmon , val );
413+ return 0 ;
429414 default :
430- ret = - EOPNOTSUPP ;
415+ return - EOPNOTSUPP ;
431416 }
432-
433- xe_device_mem_access_put (gt_to_xe (hwmon -> gt ));
434-
435- return ret ;
436417}
437418
438419static umode_t
@@ -564,15 +545,15 @@ xe_hwmon_get_preregistration_info(struct xe_device *xe)
564545{
565546 struct xe_hwmon * hwmon = xe -> hwmon ;
566547 long energy ;
567- u32 val_sku_unit = 0 ;
568- int ret ;
548+ u64 val_sku_unit = 0 ;
569549
570- ret = xe_hwmon_process_reg (hwmon , REG_PKG_POWER_SKU_UNIT , REG_READ , & val_sku_unit , 0 , 0 );
571550 /*
572551 * The contents of register PKG_POWER_SKU_UNIT do not change,
573552 * so read it once and store the shift values.
574553 */
575- if (!ret ) {
554+ if (xe_hwmon_get_reg (hwmon , REG_PKG_POWER_SKU_UNIT )) {
555+ xe_hwmon_process_reg (hwmon , REG_PKG_POWER_SKU_UNIT ,
556+ REG_READ32 , & val_sku_unit , 0 , 0 );
576557 hwmon -> scl_shift_power = REG_FIELD_GET (PKG_PWR_UNIT , val_sku_unit );
577558 hwmon -> scl_shift_energy = REG_FIELD_GET (PKG_ENERGY_UNIT , val_sku_unit );
578559 }
0 commit comments