@@ -252,7 +252,7 @@ static int pmc_core_lpm_get_arr_size(const struct pmc_bit_map **maps)
252
252
}
253
253
254
254
static void pmc_core_lpm_display (struct pmc * pmc , struct device * dev ,
255
- struct seq_file * s , u32 offset ,
255
+ struct seq_file * s , u32 offset , int pmc_index ,
256
256
const char * str ,
257
257
const struct pmc_bit_map * * maps )
258
258
{
@@ -271,19 +271,19 @@ static void pmc_core_lpm_display(struct pmc *pmc, struct device *dev,
271
271
272
272
for (idx = 0 ; idx < arr_size ; idx ++ ) {
273
273
if (dev )
274
- dev_info (dev , "\nLPM_% s_%d:\t0x%x\n" , str , idx ,
274
+ dev_info (dev , "\nPMC%d:LPM_% s_%d:\t0x%x\n" , pmc_index , str , idx ,
275
275
lpm_regs [idx ]);
276
276
if (s )
277
- seq_printf (s , "\nLPM_% s_%d:\t0x%x\n" , str , idx ,
277
+ seq_printf (s , "\nPMC%d:LPM_% s_%d:\t0x%x\n" , pmc_index , str , idx ,
278
278
lpm_regs [idx ]);
279
279
for (index = 0 ; maps [idx ][index ].name && index < len ; index ++ ) {
280
280
bit_mask = maps [idx ][index ].bit_mask ;
281
281
if (dev )
282
- dev_info (dev , "% -30s %-30d\n" ,
282
+ dev_info (dev , "PMC%d:% -30s %-30d\n" , pmc_index ,
283
283
maps [idx ][index ].name ,
284
284
lpm_regs [idx ] & bit_mask ? 1 : 0 );
285
285
if (s )
286
- seq_printf (s , "% -30s %-30d\n" ,
286
+ seq_printf (s , "PMC%d:% -30s %-30d\n" , pmc_index ,
287
287
maps [idx ][index ].name ,
288
288
lpm_regs [idx ] & bit_mask ? 1 : 0 );
289
289
}
@@ -300,32 +300,40 @@ static inline u8 pmc_core_reg_read_byte(struct pmc *pmc, int offset)
300
300
}
301
301
302
302
static void pmc_core_display_map (struct seq_file * s , int index , int idx , int ip ,
303
- u8 pf_reg , const struct pmc_bit_map * * pf_map )
303
+ int pmc_index , u8 pf_reg , const struct pmc_bit_map * * pf_map )
304
304
{
305
- seq_printf (s , "PCH IP: %-2d - %-32s\tState: %s\n" ,
306
- ip , pf_map [idx ][index ].name ,
305
+ seq_printf (s , "PMC%d: PCH IP: %-2d - %-32s\tState: %s\n" ,
306
+ pmc_index , ip , pf_map [idx ][index ].name ,
307
307
pf_map [idx ][index ].bit_mask & pf_reg ? "Off" : "On" );
308
308
}
309
309
310
310
static int pmc_core_ppfear_show (struct seq_file * s , void * unused )
311
311
{
312
312
struct pmc_dev * pmcdev = s -> private ;
313
- struct pmc * pmc = pmcdev -> pmcs [PMC_IDX_MAIN ];
314
- const struct pmc_bit_map * * maps = pmc -> map -> pfear_sts ;
315
- u8 pf_regs [PPFEAR_MAX_NUM_ENTRIES ];
316
- int index , iter , idx , ip = 0 ;
313
+ int i ;
314
+
315
+ for (i = 0 ; i < ARRAY_SIZE (pmcdev -> pmcs ); ++ i ) {
316
+ struct pmc * pmc = pmcdev -> pmcs [i ];
317
+ const struct pmc_bit_map * * maps ;
318
+ u8 pf_regs [PPFEAR_MAX_NUM_ENTRIES ];
319
+ int index , iter , idx , ip = 0 ;
320
+
321
+ if (!pmc )
322
+ continue ;
317
323
318
- iter = pmc -> map -> ppfear0_offset ;
324
+ maps = pmc -> map -> pfear_sts ;
325
+ iter = pmc -> map -> ppfear0_offset ;
319
326
320
- for (index = 0 ; index < pmc -> map -> ppfear_buckets &&
321
- index < PPFEAR_MAX_NUM_ENTRIES ; index ++ , iter ++ )
322
- pf_regs [index ] = pmc_core_reg_read_byte (pmc , iter );
327
+ for (index = 0 ; index < pmc -> map -> ppfear_buckets &&
328
+ index < PPFEAR_MAX_NUM_ENTRIES ; index ++ , iter ++ )
329
+ pf_regs [index ] = pmc_core_reg_read_byte (pmc , iter );
323
330
324
- for (idx = 0 ; maps [idx ]; idx ++ ) {
325
- for (index = 0 ; maps [idx ][index ].name &&
326
- index < pmc -> map -> ppfear_buckets * 8 ; ip ++ , index ++ )
327
- pmc_core_display_map (s , index , idx , ip ,
328
- pf_regs [index / 8 ], maps );
331
+ for (idx = 0 ; maps [idx ]; idx ++ ) {
332
+ for (index = 0 ; maps [idx ][index ].name &&
333
+ index < pmc -> map -> ppfear_buckets * 8 ; ip ++ , index ++ )
334
+ pmc_core_display_map (s , index , idx , ip , i ,
335
+ pf_regs [index / 8 ], maps );
336
+ }
329
337
}
330
338
331
339
return 0 ;
@@ -454,26 +462,48 @@ DEFINE_SHOW_ATTRIBUTE(pmc_core_pll);
454
462
455
463
int pmc_core_send_ltr_ignore (struct pmc_dev * pmcdev , u32 value )
456
464
{
457
- struct pmc * pmc = pmcdev -> pmcs [ PMC_IDX_MAIN ] ;
458
- const struct pmc_reg_map * map = pmc -> map ;
465
+ struct pmc * pmc ;
466
+ const struct pmc_reg_map * map ;
459
467
u32 reg ;
460
- int err = 0 ;
468
+ int pmc_index , ltr_index ;
461
469
462
- mutex_lock (& pmcdev -> lock );
470
+ ltr_index = value ;
471
+ /* For platforms with multiple pmcs, ltr index value given by user
472
+ * is based on the contiguous indexes from ltr_show output.
473
+ * pmc index and ltr index needs to be calculated from it.
474
+ */
475
+ for (pmc_index = 0 ; pmc_index < ARRAY_SIZE (pmcdev -> pmcs ) && ltr_index > 0 ; pmc_index ++ ) {
476
+ pmc = pmcdev -> pmcs [pmc_index ];
463
477
464
- if (value > map -> ltr_ignore_max ) {
465
- err = - EINVAL ;
466
- goto out_unlock ;
478
+ if (!pmc )
479
+ continue ;
480
+
481
+ map = pmc -> map ;
482
+ if (ltr_index <= map -> ltr_ignore_max )
483
+ break ;
484
+
485
+ /* Along with IP names, ltr_show map includes CURRENT_PLATFORM
486
+ * and AGGREGATED_SYSTEM values per PMC. Take these two index
487
+ * values into account in ltr_index calculation. Also, to start
488
+ * ltr index from zero for next pmc, subtract it by 1.
489
+ */
490
+ ltr_index = ltr_index - (map -> ltr_ignore_max + 2 ) - 1 ;
467
491
}
468
492
493
+ if (pmc_index >= ARRAY_SIZE (pmcdev -> pmcs ) || ltr_index < 0 )
494
+ return - EINVAL ;
495
+
496
+ pr_debug ("ltr_ignore for pmc%d: ltr_index:%d\n" , pmc_index , ltr_index );
497
+
498
+ mutex_lock (& pmcdev -> lock );
499
+
469
500
reg = pmc_core_reg_read (pmc , map -> ltr_ignore_offset );
470
- reg |= BIT (value );
501
+ reg |= BIT (ltr_index );
471
502
pmc_core_reg_write (pmc , map -> ltr_ignore_offset , reg );
472
503
473
- out_unlock :
474
504
mutex_unlock (& pmcdev -> lock );
475
505
476
- return err ;
506
+ return 0 ;
477
507
}
478
508
479
509
static ssize_t pmc_core_ltr_ignore_write (struct file * file ,
@@ -586,36 +616,44 @@ static u32 convert_ltr_scale(u32 val)
586
616
587
617
static int pmc_core_ltr_show (struct seq_file * s , void * unused )
588
618
{
589
- struct pmc * pmc = s -> private ;
590
- const struct pmc_bit_map * map = pmc -> map -> ltr_show_sts ;
619
+ struct pmc_dev * pmcdev = s -> private ;
591
620
u64 decoded_snoop_ltr , decoded_non_snoop_ltr ;
592
621
u32 ltr_raw_data , scale , val ;
593
622
u16 snoop_ltr , nonsnoop_ltr ;
594
- int index ;
623
+ int i , index , ltr_index = 0 ;
595
624
596
- for (index = 0 ; map [index ].name ; index ++ ) {
597
- decoded_snoop_ltr = decoded_non_snoop_ltr = 0 ;
598
- ltr_raw_data = pmc_core_reg_read (pmc ,
599
- map [index ].bit_mask );
600
- snoop_ltr = ltr_raw_data & ~MTPMC_MASK ;
601
- nonsnoop_ltr = (ltr_raw_data >> 0x10 ) & ~MTPMC_MASK ;
602
-
603
- if (FIELD_GET (LTR_REQ_NONSNOOP , ltr_raw_data )) {
604
- scale = FIELD_GET (LTR_DECODED_SCALE , nonsnoop_ltr );
605
- val = FIELD_GET (LTR_DECODED_VAL , nonsnoop_ltr );
606
- decoded_non_snoop_ltr = val * convert_ltr_scale (scale );
607
- }
625
+ for (i = 0 ; i < ARRAY_SIZE (pmcdev -> pmcs ); ++ i ) {
626
+ struct pmc * pmc = pmcdev -> pmcs [i ];
627
+ const struct pmc_bit_map * map ;
608
628
609
- if (FIELD_GET (LTR_REQ_SNOOP , ltr_raw_data )) {
610
- scale = FIELD_GET (LTR_DECODED_SCALE , snoop_ltr );
611
- val = FIELD_GET (LTR_DECODED_VAL , snoop_ltr );
612
- decoded_snoop_ltr = val * convert_ltr_scale (scale );
613
- }
629
+ if (!pmc )
630
+ continue ;
631
+
632
+ map = pmc -> map -> ltr_show_sts ;
633
+ for (index = 0 ; map [index ].name ; index ++ ) {
634
+ decoded_snoop_ltr = decoded_non_snoop_ltr = 0 ;
635
+ ltr_raw_data = pmc_core_reg_read (pmc ,
636
+ map [index ].bit_mask );
637
+ snoop_ltr = ltr_raw_data & ~MTPMC_MASK ;
638
+ nonsnoop_ltr = (ltr_raw_data >> 0x10 ) & ~MTPMC_MASK ;
639
+
640
+ if (FIELD_GET (LTR_REQ_NONSNOOP , ltr_raw_data )) {
641
+ scale = FIELD_GET (LTR_DECODED_SCALE , nonsnoop_ltr );
642
+ val = FIELD_GET (LTR_DECODED_VAL , nonsnoop_ltr );
643
+ decoded_non_snoop_ltr = val * convert_ltr_scale (scale );
644
+ }
645
+ if (FIELD_GET (LTR_REQ_SNOOP , ltr_raw_data )) {
646
+ scale = FIELD_GET (LTR_DECODED_SCALE , snoop_ltr );
647
+ val = FIELD_GET (LTR_DECODED_VAL , snoop_ltr );
648
+ decoded_snoop_ltr = val * convert_ltr_scale (scale );
649
+ }
614
650
615
- seq_printf (s , "%-32s\tLTR: RAW: 0x%-16x\tNon-Snoop(ns): %-16llu\tSnoop(ns): %-16llu\n" ,
616
- map [index ].name , ltr_raw_data ,
617
- decoded_non_snoop_ltr ,
618
- decoded_snoop_ltr );
651
+ seq_printf (s , "%d\tPMC%d:%-32s\tLTR: RAW: 0x%-16x\tNon-Snoop(ns): %-16llu\tSnoop(ns): %-16llu\n" ,
652
+ ltr_index , i , map [index ].name , ltr_raw_data ,
653
+ decoded_non_snoop_ltr ,
654
+ decoded_snoop_ltr );
655
+ ltr_index ++ ;
656
+ }
619
657
}
620
658
return 0 ;
621
659
}
@@ -651,11 +689,19 @@ DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_res);
651
689
static int pmc_core_substate_sts_regs_show (struct seq_file * s , void * unused )
652
690
{
653
691
struct pmc_dev * pmcdev = s -> private ;
654
- struct pmc * pmc = pmcdev -> pmcs [PMC_IDX_MAIN ];
655
- const struct pmc_bit_map * * maps = pmc -> map -> lpm_sts ;
656
- u32 offset = pmc -> map -> lpm_status_offset ;
692
+ int i ;
693
+
694
+ for (i = 0 ; i < ARRAY_SIZE (pmcdev -> pmcs ); ++ i ) {
695
+ struct pmc * pmc = pmcdev -> pmcs [i ];
696
+ const struct pmc_bit_map * * maps ;
697
+ u32 offset ;
657
698
658
- pmc_core_lpm_display (pmc , NULL , s , offset , "STATUS" , maps );
699
+ if (!pmc )
700
+ continue ;
701
+ maps = pmc -> map -> lpm_sts ;
702
+ offset = pmc -> map -> lpm_status_offset ;
703
+ pmc_core_lpm_display (pmc , NULL , s , offset , i , "STATUS" , maps );
704
+ }
659
705
660
706
return 0 ;
661
707
}
@@ -664,11 +710,19 @@ DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_sts_regs);
664
710
static int pmc_core_substate_l_sts_regs_show (struct seq_file * s , void * unused )
665
711
{
666
712
struct pmc_dev * pmcdev = s -> private ;
667
- struct pmc * pmc = pmcdev -> pmcs [PMC_IDX_MAIN ];
668
- const struct pmc_bit_map * * maps = pmc -> map -> lpm_sts ;
669
- u32 offset = pmc -> map -> lpm_live_status_offset ;
713
+ int i ;
714
+
715
+ for (i = 0 ; i < ARRAY_SIZE (pmcdev -> pmcs ); ++ i ) {
716
+ struct pmc * pmc = pmcdev -> pmcs [i ];
717
+ const struct pmc_bit_map * * maps ;
718
+ u32 offset ;
670
719
671
- pmc_core_lpm_display (pmc , NULL , s , offset , "LIVE_STATUS" , maps );
720
+ if (!pmc )
721
+ continue ;
722
+ maps = pmc -> map -> lpm_sts ;
723
+ offset = pmc -> map -> lpm_live_status_offset ;
724
+ pmc_core_lpm_display (pmc , NULL , s , offset , i , "LIVE_STATUS" , maps );
725
+ }
672
726
673
727
return 0 ;
674
728
}
@@ -1005,7 +1059,7 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
1005
1059
debugfs_create_file ("ltr_ignore" , 0644 , dir , pmcdev ,
1006
1060
& pmc_core_ltr_ignore_ops );
1007
1061
1008
- debugfs_create_file ("ltr_show" , 0444 , dir , primary_pmc , & pmc_core_ltr_fops );
1062
+ debugfs_create_file ("ltr_show" , 0444 , dir , pmcdev , & pmc_core_ltr_fops );
1009
1063
1010
1064
debugfs_create_file ("package_cstate_show" , 0444 , dir , primary_pmc ,
1011
1065
& pmc_core_pkgc_fops );
@@ -1264,6 +1318,7 @@ int pmc_core_resume_common(struct pmc_dev *pmcdev)
1264
1318
struct pmc * pmc = pmcdev -> pmcs [PMC_IDX_MAIN ];
1265
1319
const struct pmc_bit_map * * maps = pmc -> map -> lpm_sts ;
1266
1320
int offset = pmc -> map -> lpm_status_offset ;
1321
+ int i ;
1267
1322
1268
1323
/* Check if the syspend used S0ix */
1269
1324
if (pm_suspend_via_firmware ())
@@ -1285,10 +1340,18 @@ int pmc_core_resume_common(struct pmc_dev *pmcdev)
1285
1340
/* The real interesting case - S0ix failed - lets ask PMC why. */
1286
1341
dev_warn (dev , "CPU did not enter SLP_S0!!! (S0ix cnt=%llu)\n" ,
1287
1342
pmcdev -> s0ix_counter );
1343
+
1288
1344
if (pmc -> map -> slps0_dbg_maps )
1289
1345
pmc_core_slps0_display (pmc , dev , NULL );
1290
- if (pmc -> map -> lpm_sts )
1291
- pmc_core_lpm_display (pmc , dev , NULL , offset , "STATUS" , maps );
1346
+
1347
+ for (i = 0 ; i < ARRAY_SIZE (pmcdev -> pmcs ); ++ i ) {
1348
+ struct pmc * pmc = pmcdev -> pmcs [i ];
1349
+
1350
+ if (!pmc )
1351
+ continue ;
1352
+ if (pmc -> map -> lpm_sts )
1353
+ pmc_core_lpm_display (pmc , dev , NULL , offset , i , "STATUS" , maps );
1354
+ }
1292
1355
1293
1356
return 0 ;
1294
1357
}
0 commit comments