12
12
#include <asm/amd_hsmp.h>
13
13
14
14
#include <linux/acpi.h>
15
+ #include <linux/array_size.h>
16
+ #include <linux/bits.h>
17
+ #include <linux/bitfield.h>
15
18
#include <linux/device.h>
16
19
#include <linux/dev_printk.h>
17
20
#include <linux/ioport.h>
36
39
37
40
static struct hsmp_plat_device * hsmp_pdev ;
38
41
42
+ struct hsmp_sys_attr {
43
+ struct device_attribute dattr ;
44
+ u32 msg_id ;
45
+ };
46
+
39
47
static int amd_hsmp_acpi_rdwr (struct hsmp_socket * sock , u32 offset ,
40
48
u32 * value , bool write )
41
49
{
@@ -243,6 +251,215 @@ static umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
243
251
return 0 ;
244
252
}
245
253
254
+ static umode_t hsmp_is_sock_dev_attr_visible (struct kobject * kobj ,
255
+ struct attribute * attr , int id )
256
+ {
257
+ return attr -> mode ;
258
+ }
259
+
260
+ #define to_hsmp_sys_attr (_attr ) container_of(_attr, struct hsmp_sys_attr, dattr)
261
+
262
+ static ssize_t hsmp_msg_resp32_show (struct device * dev , struct device_attribute * attr ,
263
+ char * buf )
264
+ {
265
+ struct hsmp_sys_attr * hattr = to_hsmp_sys_attr (attr );
266
+ struct hsmp_socket * sock = dev_get_drvdata (dev );
267
+ u32 data ;
268
+ int ret ;
269
+
270
+ ret = hsmp_msg_get_nargs (sock -> sock_ind , hattr -> msg_id , & data , 1 );
271
+ if (ret )
272
+ return ret ;
273
+
274
+ return sysfs_emit (buf , "%u\n" , data );
275
+ }
276
+
277
+ #define DDR_MAX_BW_MASK GENMASK(31, 20)
278
+ #define DDR_UTIL_BW_MASK GENMASK(19, 8)
279
+ #define DDR_UTIL_BW_PERC_MASK GENMASK(7, 0)
280
+ #define FW_VER_MAJOR_MASK GENMASK(23, 16)
281
+ #define FW_VER_MINOR_MASK GENMASK(15, 8)
282
+ #define FW_VER_DEBUG_MASK GENMASK(7, 0)
283
+ #define FMAX_MASK GENMASK(31, 16)
284
+ #define FMIN_MASK GENMASK(15, 0)
285
+ #define FREQ_LIMIT_MASK GENMASK(31, 16)
286
+ #define FREQ_SRC_IND_MASK GENMASK(15, 0)
287
+
288
+ static ssize_t hsmp_ddr_max_bw_show (struct device * dev , struct device_attribute * attr ,
289
+ char * buf )
290
+ {
291
+ struct hsmp_sys_attr * hattr = to_hsmp_sys_attr (attr );
292
+ struct hsmp_socket * sock = dev_get_drvdata (dev );
293
+ u32 data ;
294
+ int ret ;
295
+
296
+ ret = hsmp_msg_get_nargs (sock -> sock_ind , hattr -> msg_id , & data , 1 );
297
+ if (ret )
298
+ return ret ;
299
+
300
+ return sysfs_emit (buf , "%lu\n" , FIELD_GET (DDR_MAX_BW_MASK , data ));
301
+ }
302
+
303
+ static ssize_t hsmp_ddr_util_bw_show (struct device * dev , struct device_attribute * attr ,
304
+ char * buf )
305
+ {
306
+ struct hsmp_sys_attr * hattr = to_hsmp_sys_attr (attr );
307
+ struct hsmp_socket * sock = dev_get_drvdata (dev );
308
+ u32 data ;
309
+ int ret ;
310
+
311
+ ret = hsmp_msg_get_nargs (sock -> sock_ind , hattr -> msg_id , & data , 1 );
312
+ if (ret )
313
+ return ret ;
314
+
315
+ return sysfs_emit (buf , "%lu\n" , FIELD_GET (DDR_UTIL_BW_MASK , data ));
316
+ }
317
+
318
+ static ssize_t hsmp_ddr_util_bw_perc_show (struct device * dev , struct device_attribute * attr ,
319
+ char * buf )
320
+ {
321
+ struct hsmp_sys_attr * hattr = to_hsmp_sys_attr (attr );
322
+ struct hsmp_socket * sock = dev_get_drvdata (dev );
323
+ u32 data ;
324
+ int ret ;
325
+
326
+ ret = hsmp_msg_get_nargs (sock -> sock_ind , hattr -> msg_id , & data , 1 );
327
+ if (ret )
328
+ return ret ;
329
+
330
+ return sysfs_emit (buf , "%lu\n" , FIELD_GET (DDR_UTIL_BW_PERC_MASK , data ));
331
+ }
332
+
333
+ static ssize_t hsmp_msg_fw_ver_show (struct device * dev , struct device_attribute * attr ,
334
+ char * buf )
335
+ {
336
+ struct hsmp_sys_attr * hattr = to_hsmp_sys_attr (attr );
337
+ struct hsmp_socket * sock = dev_get_drvdata (dev );
338
+ u32 data ;
339
+ int ret ;
340
+
341
+ ret = hsmp_msg_get_nargs (sock -> sock_ind , hattr -> msg_id , & data , 1 );
342
+ if (ret )
343
+ return ret ;
344
+
345
+ return sysfs_emit (buf , "%lu.%lu.%lu\n" ,
346
+ FIELD_GET (FW_VER_MAJOR_MASK , data ),
347
+ FIELD_GET (FW_VER_MINOR_MASK , data ),
348
+ FIELD_GET (FW_VER_DEBUG_MASK , data ));
349
+ }
350
+
351
+ static ssize_t hsmp_fclk_show (struct device * dev , struct device_attribute * attr ,
352
+ char * buf )
353
+ {
354
+ struct hsmp_sys_attr * hattr = to_hsmp_sys_attr (attr );
355
+ struct hsmp_socket * sock = dev_get_drvdata (dev );
356
+ u32 data [2 ];
357
+ int ret ;
358
+
359
+ ret = hsmp_msg_get_nargs (sock -> sock_ind , hattr -> msg_id , data , 2 );
360
+ if (ret )
361
+ return ret ;
362
+
363
+ return sysfs_emit (buf , "%u\n" , data [0 ]);
364
+ }
365
+
366
+ static ssize_t hsmp_mclk_show (struct device * dev , struct device_attribute * attr ,
367
+ char * buf )
368
+ {
369
+ struct hsmp_sys_attr * hattr = to_hsmp_sys_attr (attr );
370
+ struct hsmp_socket * sock = dev_get_drvdata (dev );
371
+ u32 data [2 ];
372
+ int ret ;
373
+
374
+ ret = hsmp_msg_get_nargs (sock -> sock_ind , hattr -> msg_id , data , 2 );
375
+ if (ret )
376
+ return ret ;
377
+
378
+ return sysfs_emit (buf , "%u\n" , data [1 ]);
379
+ }
380
+
381
+ static ssize_t hsmp_clk_fmax_show (struct device * dev , struct device_attribute * attr ,
382
+ char * buf )
383
+ {
384
+ struct hsmp_sys_attr * hattr = to_hsmp_sys_attr (attr );
385
+ struct hsmp_socket * sock = dev_get_drvdata (dev );
386
+ u32 data ;
387
+ int ret ;
388
+
389
+ ret = hsmp_msg_get_nargs (sock -> sock_ind , hattr -> msg_id , & data , 1 );
390
+ if (ret )
391
+ return ret ;
392
+
393
+ return sysfs_emit (buf , "%lu\n" , FIELD_GET (FMAX_MASK , data ));
394
+ }
395
+
396
+ static ssize_t hsmp_clk_fmin_show (struct device * dev , struct device_attribute * attr ,
397
+ char * buf )
398
+ {
399
+ struct hsmp_sys_attr * hattr = to_hsmp_sys_attr (attr );
400
+ struct hsmp_socket * sock = dev_get_drvdata (dev );
401
+ u32 data ;
402
+ int ret ;
403
+
404
+ ret = hsmp_msg_get_nargs (sock -> sock_ind , hattr -> msg_id , & data , 1 );
405
+ if (ret )
406
+ return ret ;
407
+
408
+ return sysfs_emit (buf , "%lu\n" , FIELD_GET (FMIN_MASK , data ));
409
+ }
410
+
411
+ static ssize_t hsmp_freq_limit_show (struct device * dev , struct device_attribute * attr ,
412
+ char * buf )
413
+ {
414
+ struct hsmp_sys_attr * hattr = to_hsmp_sys_attr (attr );
415
+ struct hsmp_socket * sock = dev_get_drvdata (dev );
416
+ u32 data ;
417
+ int ret ;
418
+
419
+ ret = hsmp_msg_get_nargs (sock -> sock_ind , hattr -> msg_id , & data , 1 );
420
+ if (ret )
421
+ return ret ;
422
+
423
+ return sysfs_emit (buf , "%lu\n" , FIELD_GET (FREQ_LIMIT_MASK , data ));
424
+ }
425
+
426
+ static const char * const freqlimit_srcnames [] = {
427
+ "cHTC-Active" ,
428
+ "PROCHOT" ,
429
+ "TDC limit" ,
430
+ "PPT Limit" ,
431
+ "OPN Max" ,
432
+ "Reliability Limit" ,
433
+ "APML Agent" ,
434
+ "HSMP Agent" ,
435
+ };
436
+
437
+ static ssize_t hsmp_freq_limit_source_show (struct device * dev , struct device_attribute * attr ,
438
+ char * buf )
439
+ {
440
+ struct hsmp_sys_attr * hattr = to_hsmp_sys_attr (attr );
441
+ struct hsmp_socket * sock = dev_get_drvdata (dev );
442
+ unsigned int index ;
443
+ int len = 0 ;
444
+ u16 src_ind ;
445
+ u32 data ;
446
+ int ret ;
447
+
448
+ ret = hsmp_msg_get_nargs (sock -> sock_ind , hattr -> msg_id , & data , 1 );
449
+ if (ret )
450
+ return ret ;
451
+
452
+ src_ind = FIELD_GET (FREQ_SRC_IND_MASK , data );
453
+ for (index = 0 ; index < ARRAY_SIZE (freqlimit_srcnames ); index ++ ) {
454
+ if (!src_ind )
455
+ break ;
456
+ if (src_ind & 1 )
457
+ len += sysfs_emit_at (buf , len , "%s\n" , freqlimit_srcnames [index ]);
458
+ src_ind >>= 1 ;
459
+ }
460
+ return len ;
461
+ }
462
+
246
463
static int init_acpi (struct device * dev )
247
464
{
248
465
u16 sock_ind ;
@@ -285,6 +502,8 @@ static int init_acpi(struct device *dev)
285
502
if (ret )
286
503
dev_err (dev , "Failed to register HSMP sensors with hwmon\n" );
287
504
505
+ dev_set_drvdata (dev , & hsmp_pdev -> sock [sock_ind ]);
506
+
288
507
return ret ;
289
508
}
290
509
@@ -299,9 +518,52 @@ static const struct bin_attribute *hsmp_attr_list[] = {
299
518
NULL
300
519
};
301
520
521
+ #define HSMP_DEV_ATTR (_name , _msg_id , _show , _mode ) \
522
+ static struct hsmp_sys_attr hattr_##_name = { \
523
+ .dattr = __ATTR(_name, _mode, _show, NULL), \
524
+ .msg_id = _msg_id, \
525
+ }
526
+
527
+ HSMP_DEV_ATTR (c0_residency_input , HSMP_GET_C0_PERCENT , hsmp_msg_resp32_show , 0444 );
528
+ HSMP_DEV_ATTR (prochot_status , HSMP_GET_PROC_HOT , hsmp_msg_resp32_show , 0444 );
529
+ HSMP_DEV_ATTR (smu_fw_version , HSMP_GET_SMU_VER , hsmp_msg_fw_ver_show , 0444 );
530
+ HSMP_DEV_ATTR (protocol_version , HSMP_GET_PROTO_VER , hsmp_msg_resp32_show , 0444 );
531
+ HSMP_DEV_ATTR (cclk_freq_limit_input , HSMP_GET_CCLK_THROTTLE_LIMIT , hsmp_msg_resp32_show , 0444 );
532
+ HSMP_DEV_ATTR (ddr_max_bw , HSMP_GET_DDR_BANDWIDTH , hsmp_ddr_max_bw_show , 0444 );
533
+ HSMP_DEV_ATTR (ddr_utilised_bw_input , HSMP_GET_DDR_BANDWIDTH , hsmp_ddr_util_bw_show , 0444 );
534
+ HSMP_DEV_ATTR (ddr_utilised_bw_perc_input , HSMP_GET_DDR_BANDWIDTH , hsmp_ddr_util_bw_perc_show , 0444 );
535
+ HSMP_DEV_ATTR (fclk_input , HSMP_GET_FCLK_MCLK , hsmp_fclk_show , 0444 );
536
+ HSMP_DEV_ATTR (mclk_input , HSMP_GET_FCLK_MCLK , hsmp_mclk_show , 0444 );
537
+ HSMP_DEV_ATTR (clk_fmax , HSMP_GET_SOCKET_FMAX_FMIN , hsmp_clk_fmax_show , 0444 );
538
+ HSMP_DEV_ATTR (clk_fmin , HSMP_GET_SOCKET_FMAX_FMIN , hsmp_clk_fmin_show , 0444 );
539
+ HSMP_DEV_ATTR (pwr_current_active_freq_limit , HSMP_GET_SOCKET_FREQ_LIMIT ,
540
+ hsmp_freq_limit_show , 0444 );
541
+ HSMP_DEV_ATTR (pwr_current_active_freq_limit_source , HSMP_GET_SOCKET_FREQ_LIMIT ,
542
+ hsmp_freq_limit_source_show , 0444 );
543
+
544
+ static struct attribute * hsmp_dev_attr_list [] = {
545
+ & hattr_c0_residency_input .dattr .attr ,
546
+ & hattr_prochot_status .dattr .attr ,
547
+ & hattr_smu_fw_version .dattr .attr ,
548
+ & hattr_protocol_version .dattr .attr ,
549
+ & hattr_cclk_freq_limit_input .dattr .attr ,
550
+ & hattr_ddr_max_bw .dattr .attr ,
551
+ & hattr_ddr_utilised_bw_input .dattr .attr ,
552
+ & hattr_ddr_utilised_bw_perc_input .dattr .attr ,
553
+ & hattr_fclk_input .dattr .attr ,
554
+ & hattr_mclk_input .dattr .attr ,
555
+ & hattr_clk_fmax .dattr .attr ,
556
+ & hattr_clk_fmin .dattr .attr ,
557
+ & hattr_pwr_current_active_freq_limit .dattr .attr ,
558
+ & hattr_pwr_current_active_freq_limit_source .dattr .attr ,
559
+ NULL
560
+ };
561
+
302
562
static const struct attribute_group hsmp_attr_grp = {
303
563
.bin_attrs_new = hsmp_attr_list ,
564
+ .attrs = hsmp_dev_attr_list ,
304
565
.is_bin_visible = hsmp_is_sock_attr_visible ,
566
+ .is_visible = hsmp_is_sock_dev_attr_visible ,
305
567
};
306
568
307
569
static const struct attribute_group * hsmp_groups [] = {
0 commit comments