@@ -678,6 +678,41 @@ static int pmc_core_ltr_show(struct seq_file *s, void *unused)
678678}
679679DEFINE_SHOW_ATTRIBUTE (pmc_core_ltr );
680680
681+ static int pmc_core_s0ix_blocker_show (struct seq_file * s , void * unused )
682+ {
683+ struct pmc_dev * pmcdev = s -> private ;
684+ unsigned int pmcidx ;
685+
686+ for (pmcidx = 0 ; pmcidx < ARRAY_SIZE (pmcdev -> pmcs ); pmcidx ++ ) {
687+ const struct pmc_bit_map * * maps ;
688+ unsigned int arr_size , r_idx ;
689+ u32 offset , counter ;
690+ struct pmc * pmc ;
691+
692+ pmc = pmcdev -> pmcs [pmcidx ];
693+ if (!pmc )
694+ continue ;
695+ maps = pmc -> map -> s0ix_blocker_maps ;
696+ offset = pmc -> map -> s0ix_blocker_offset ;
697+ arr_size = pmc_core_lpm_get_arr_size (maps );
698+
699+ for (r_idx = 0 ; r_idx < arr_size ; r_idx ++ ) {
700+ const struct pmc_bit_map * map ;
701+
702+ for (map = maps [r_idx ]; map -> name ; map ++ ) {
703+ if (!map -> blk )
704+ continue ;
705+ counter = pmc_core_reg_read (pmc , offset );
706+ seq_printf (s , "PMC%d:%-30s %-30d\n" , pmcidx ,
707+ map -> name , counter );
708+ offset += map -> blk * S0IX_BLK_SIZE ;
709+ }
710+ }
711+ }
712+ return 0 ;
713+ }
714+ DEFINE_SHOW_ATTRIBUTE (pmc_core_s0ix_blocker );
715+
681716static inline u64 adjust_lpm_residency (struct pmc * pmc , u32 offset ,
682717 const int lpm_adj_x2 )
683718{
@@ -1197,6 +1232,9 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
11971232
11981233 debugfs_create_file ("ltr_show" , 0444 , dir , pmcdev , & pmc_core_ltr_fops );
11991234
1235+ if (primary_pmc -> map -> s0ix_blocker_maps )
1236+ debugfs_create_file ("s0ix_blocker" , 0444 , dir , pmcdev , & pmc_core_s0ix_blocker_fops );
1237+
12001238 debugfs_create_file ("package_cstate_show" , 0444 , dir , primary_pmc ,
12011239 & pmc_core_pkgc_fops );
12021240
@@ -1389,6 +1427,15 @@ static int pmc_core_probe(struct platform_device *pdev)
13891427 return - ENOMEM ;
13901428 pmcdev -> pmcs [PMC_IDX_MAIN ] = primary_pmc ;
13911429
1430+ /* The last element in msr_map is empty */
1431+ pmcdev -> num_of_pkgc = ARRAY_SIZE (msr_map ) - 1 ;
1432+ pmcdev -> pkgc_res_cnt = devm_kcalloc (& pdev -> dev ,
1433+ pmcdev -> num_of_pkgc ,
1434+ sizeof (* pmcdev -> pkgc_res_cnt ),
1435+ GFP_KERNEL );
1436+ if (!pmcdev -> pkgc_res_cnt )
1437+ return - ENOMEM ;
1438+
13921439 /*
13931440 * Coffee Lake has CPU ID of Kaby Lake and Cannon Lake PCH. So here
13941441 * Sunrisepoint PCH regmap can't be used. Use Cannon Lake PCH regmap
@@ -1432,6 +1479,7 @@ static __maybe_unused int pmc_core_suspend(struct device *dev)
14321479{
14331480 struct pmc_dev * pmcdev = dev_get_drvdata (dev );
14341481 struct pmc * pmc = pmcdev -> pmcs [PMC_IDX_MAIN ];
1482+ unsigned int i ;
14351483
14361484 if (pmcdev -> suspend )
14371485 pmcdev -> suspend (pmcdev );
@@ -1440,9 +1488,11 @@ static __maybe_unused int pmc_core_suspend(struct device *dev)
14401488 if (pm_suspend_via_firmware ())
14411489 return 0 ;
14421490
1443- /* Save PC10 residency for checking later */
1444- if (rdmsrl_safe (MSR_PKG_C10_RESIDENCY , & pmcdev -> pc10_counter ))
1445- return - EIO ;
1491+ /* Save PKGC residency for checking later */
1492+ for (i = 0 ; i < pmcdev -> num_of_pkgc ; i ++ ) {
1493+ if (rdmsrl_safe (msr_map [i ].bit_mask , & pmcdev -> pkgc_res_cnt [i ]))
1494+ return - EIO ;
1495+ }
14461496
14471497 /* Save S0ix residency for checking later */
14481498 if (pmc_core_dev_state_get (pmc , & pmcdev -> s0ix_counter ))
@@ -1451,14 +1501,15 @@ static __maybe_unused int pmc_core_suspend(struct device *dev)
14511501 return 0 ;
14521502}
14531503
1454- static inline bool pmc_core_is_pc10_failed (struct pmc_dev * pmcdev )
1504+ static inline bool pmc_core_is_deepest_pkgc_failed (struct pmc_dev * pmcdev )
14551505{
1456- u64 pc10_counter ;
1506+ u32 deepest_pkgc_msr = msr_map [pmcdev -> num_of_pkgc - 1 ].bit_mask ;
1507+ u64 deepest_pkgc_residency ;
14571508
1458- if (rdmsrl_safe (MSR_PKG_C10_RESIDENCY , & pc10_counter ))
1509+ if (rdmsrl_safe (deepest_pkgc_msr , & deepest_pkgc_residency ))
14591510 return false;
14601511
1461- if (pc10_counter == pmcdev -> pc10_counter )
1512+ if (deepest_pkgc_residency == pmcdev -> pkgc_res_cnt [ pmcdev -> num_of_pkgc - 1 ] )
14621513 return true;
14631514
14641515 return false;
@@ -1497,10 +1548,22 @@ int pmc_core_resume_common(struct pmc_dev *pmcdev)
14971548 if (!warn_on_s0ix_failures )
14981549 return 0 ;
14991550
1500- if (pmc_core_is_pc10_failed (pmcdev )) {
1501- /* S0ix failed because of PC10 entry failure */
1502- dev_info (dev , "CPU did not enter PC10!!! (PC10 cnt=0x%llx)\n" ,
1503- pmcdev -> pc10_counter );
1551+ if (pmc_core_is_deepest_pkgc_failed (pmcdev )) {
1552+ /* S0ix failed because of deepest PKGC entry failure */
1553+ dev_info (dev , "CPU did not enter %s!!! (%s cnt=0x%llx)\n" ,
1554+ msr_map [pmcdev -> num_of_pkgc - 1 ].name ,
1555+ msr_map [pmcdev -> num_of_pkgc - 1 ].name ,
1556+ pmcdev -> pkgc_res_cnt [pmcdev -> num_of_pkgc - 1 ]);
1557+
1558+ for (i = 0 ; i < pmcdev -> num_of_pkgc ; i ++ ) {
1559+ u64 pc_cnt ;
1560+
1561+ if (!rdmsrl_safe (msr_map [i ].bit_mask , & pc_cnt )) {
1562+ dev_info (dev , "Prev %s cnt = 0x%llx, Current %s cnt = 0x%llx\n" ,
1563+ msr_map [i ].name , pmcdev -> pkgc_res_cnt [i ],
1564+ msr_map [i ].name , pc_cnt );
1565+ }
1566+ }
15041567 return 0 ;
15051568 }
15061569
0 commit comments