@@ -252,7 +252,7 @@ static int pmc_core_lpm_get_arr_size(const struct pmc_bit_map **maps)
252252}
253253
254254static 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 ,
256256 const char * str ,
257257 const struct pmc_bit_map * * maps )
258258{
@@ -271,19 +271,19 @@ static void pmc_core_lpm_display(struct pmc *pmc, struct device *dev,
271271
272272 for (idx = 0 ; idx < arr_size ; idx ++ ) {
273273 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 ,
275275 lpm_regs [idx ]);
276276 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 ,
278278 lpm_regs [idx ]);
279279 for (index = 0 ; maps [idx ][index ].name && index < len ; index ++ ) {
280280 bit_mask = maps [idx ][index ].bit_mask ;
281281 if (dev )
282- dev_info (dev , "% -30s %-30d\n" ,
282+ dev_info (dev , "PMC%d:% -30s %-30d\n" , pmc_index ,
283283 maps [idx ][index ].name ,
284284 lpm_regs [idx ] & bit_mask ? 1 : 0 );
285285 if (s )
286- seq_printf (s , "% -30s %-30d\n" ,
286+ seq_printf (s , "PMC%d:% -30s %-30d\n" , pmc_index ,
287287 maps [idx ][index ].name ,
288288 lpm_regs [idx ] & bit_mask ? 1 : 0 );
289289 }
@@ -300,32 +300,40 @@ static inline u8 pmc_core_reg_read_byte(struct pmc *pmc, int offset)
300300}
301301
302302static 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 )
304304{
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 ,
307307 pf_map [idx ][index ].bit_mask & pf_reg ? "Off" : "On" );
308308}
309309
310310static int pmc_core_ppfear_show (struct seq_file * s , void * unused )
311311{
312312 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 ;
317323
318- iter = pmc -> map -> ppfear0_offset ;
324+ maps = pmc -> map -> pfear_sts ;
325+ iter = pmc -> map -> ppfear0_offset ;
319326
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 );
323330
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+ }
329337 }
330338
331339 return 0 ;
@@ -454,26 +462,48 @@ DEFINE_SHOW_ATTRIBUTE(pmc_core_pll);
454462
455463int pmc_core_send_ltr_ignore (struct pmc_dev * pmcdev , u32 value )
456464{
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 ;
459467 u32 reg ;
460- int err = 0 ;
468+ int pmc_index , ltr_index ;
461469
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 ];
463477
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 ;
467491 }
468492
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+
469500 reg = pmc_core_reg_read (pmc , map -> ltr_ignore_offset );
470- reg |= BIT (value );
501+ reg |= BIT (ltr_index );
471502 pmc_core_reg_write (pmc , map -> ltr_ignore_offset , reg );
472503
473- out_unlock :
474504 mutex_unlock (& pmcdev -> lock );
475505
476- return err ;
506+ return 0 ;
477507}
478508
479509static ssize_t pmc_core_ltr_ignore_write (struct file * file ,
@@ -586,36 +616,44 @@ static u32 convert_ltr_scale(u32 val)
586616
587617static int pmc_core_ltr_show (struct seq_file * s , void * unused )
588618{
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 ;
591620 u64 decoded_snoop_ltr , decoded_non_snoop_ltr ;
592621 u32 ltr_raw_data , scale , val ;
593622 u16 snoop_ltr , nonsnoop_ltr ;
594- int index ;
623+ int i , index , ltr_index = 0 ;
595624
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 ;
608628
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+ }
614650
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+ }
619657 }
620658 return 0 ;
621659}
@@ -651,11 +689,19 @@ DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_res);
651689static int pmc_core_substate_sts_regs_show (struct seq_file * s , void * unused )
652690{
653691 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 ;
657698
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+ }
659705
660706 return 0 ;
661707}
@@ -664,11 +710,19 @@ DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_sts_regs);
664710static int pmc_core_substate_l_sts_regs_show (struct seq_file * s , void * unused )
665711{
666712 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 ;
670719
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+ }
672726
673727 return 0 ;
674728}
@@ -1005,7 +1059,7 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
10051059 debugfs_create_file ("ltr_ignore" , 0644 , dir , pmcdev ,
10061060 & pmc_core_ltr_ignore_ops );
10071061
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 );
10091063
10101064 debugfs_create_file ("package_cstate_show" , 0444 , dir , primary_pmc ,
10111065 & pmc_core_pkgc_fops );
@@ -1264,6 +1318,7 @@ int pmc_core_resume_common(struct pmc_dev *pmcdev)
12641318 struct pmc * pmc = pmcdev -> pmcs [PMC_IDX_MAIN ];
12651319 const struct pmc_bit_map * * maps = pmc -> map -> lpm_sts ;
12661320 int offset = pmc -> map -> lpm_status_offset ;
1321+ int i ;
12671322
12681323 /* Check if the syspend used S0ix */
12691324 if (pm_suspend_via_firmware ())
@@ -1285,10 +1340,18 @@ int pmc_core_resume_common(struct pmc_dev *pmcdev)
12851340 /* The real interesting case - S0ix failed - lets ask PMC why. */
12861341 dev_warn (dev , "CPU did not enter SLP_S0!!! (S0ix cnt=%llu)\n" ,
12871342 pmcdev -> s0ix_counter );
1343+
12881344 if (pmc -> map -> slps0_dbg_maps )
12891345 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+ }
12921355
12931356 return 0 ;
12941357}
0 commit comments