Skip to content

Commit 16f8091

Browse files
kaneche1ij-intel
authored andcommitted
platform/x86/intel/pmc: Improve PKGC residency counters debug
The current code only prints PKGC-10 residency when the PKGC-10 is not reached in previous 'freeze' attempt. To debug PKGC-10 issues, we also need to know other PKGC residency counters to better triage issues. Ex: 1. When system is stuck in PC2, it can be caused short LTR from device. 2. When system is stuck in PC8, it can be caused by display engine. To better triage issues, all PKGC residency are needed when issues happen. Example log: CPU did not enter Package C10!!! (Package C10 cnt=0x0) Prev Package C2 cnt = 0x2191a325de, Current Package C2 cnt = 0x21aba30724 Prev Package C3 cnt = 0x0, Current Package C3 cnt = 0x0 Prev Package C6 cnt = 0x0, Current Package C6 cnt = 0x0 Prev Package C7 cnt = 0x0, Current Package C7 cnt = 0x0 Prev Package C8 cnt = 0x0, Current Package C8 cnt = 0x0 Prev Package C9 cnt = 0x0, Current Package C9 cnt = 0x0 Prev Package C10 cnt = 0x0, Current Package C10 cnt = 0x0 With this log, we can know whether it's a stuck PC2 issue, and we can check whether the short LTR from device causes the issue. Signed-off-by: Kane Chen <[email protected]> Reviewed-by: Ilpo Järvinen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ilpo Järvinen <[email protected]>
1 parent f7b7066 commit 16f8091

File tree

2 files changed

+41
-13
lines changed

2 files changed

+41
-13
lines changed

drivers/platform/x86/intel/pmc/core.c

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,15 @@ static int pmc_core_probe(struct platform_device *pdev)
13891389
return -ENOMEM;
13901390
pmcdev->pmcs[PMC_IDX_MAIN] = primary_pmc;
13911391

1392+
/* The last element in msr_map is empty */
1393+
pmcdev->num_of_pkgc = ARRAY_SIZE(msr_map) - 1;
1394+
pmcdev->pkgc_res_cnt = devm_kcalloc(&pdev->dev,
1395+
pmcdev->num_of_pkgc,
1396+
sizeof(*pmcdev->pkgc_res_cnt),
1397+
GFP_KERNEL);
1398+
if (!pmcdev->pkgc_res_cnt)
1399+
return -ENOMEM;
1400+
13921401
/*
13931402
* Coffee Lake has CPU ID of Kaby Lake and Cannon Lake PCH. So here
13941403
* Sunrisepoint PCH regmap can't be used. Use Cannon Lake PCH regmap
@@ -1432,6 +1441,7 @@ static __maybe_unused int pmc_core_suspend(struct device *dev)
14321441
{
14331442
struct pmc_dev *pmcdev = dev_get_drvdata(dev);
14341443
struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
1444+
unsigned int i;
14351445

14361446
if (pmcdev->suspend)
14371447
pmcdev->suspend(pmcdev);
@@ -1440,9 +1450,11 @@ static __maybe_unused int pmc_core_suspend(struct device *dev)
14401450
if (pm_suspend_via_firmware())
14411451
return 0;
14421452

1443-
/* Save PC10 residency for checking later */
1444-
if (rdmsrl_safe(MSR_PKG_C10_RESIDENCY, &pmcdev->pc10_counter))
1445-
return -EIO;
1453+
/* Save PKGC residency for checking later */
1454+
for (i = 0; i < pmcdev->num_of_pkgc; i++) {
1455+
if (rdmsrl_safe(msr_map[i].bit_mask, &pmcdev->pkgc_res_cnt[i]))
1456+
return -EIO;
1457+
}
14461458

14471459
/* Save S0ix residency for checking later */
14481460
if (pmc_core_dev_state_get(pmc, &pmcdev->s0ix_counter))
@@ -1451,14 +1463,15 @@ static __maybe_unused int pmc_core_suspend(struct device *dev)
14511463
return 0;
14521464
}
14531465

1454-
static inline bool pmc_core_is_pc10_failed(struct pmc_dev *pmcdev)
1466+
static inline bool pmc_core_is_deepest_pkgc_failed(struct pmc_dev *pmcdev)
14551467
{
1456-
u64 pc10_counter;
1468+
u32 deepest_pkgc_msr = msr_map[pmcdev->num_of_pkgc - 1].bit_mask;
1469+
u64 deepest_pkgc_residency;
14571470

1458-
if (rdmsrl_safe(MSR_PKG_C10_RESIDENCY, &pc10_counter))
1471+
if (rdmsrl_safe(deepest_pkgc_msr, &deepest_pkgc_residency))
14591472
return false;
14601473

1461-
if (pc10_counter == pmcdev->pc10_counter)
1474+
if (deepest_pkgc_residency == pmcdev->pkgc_res_cnt[pmcdev->num_of_pkgc - 1])
14621475
return true;
14631476

14641477
return false;
@@ -1497,10 +1510,22 @@ int pmc_core_resume_common(struct pmc_dev *pmcdev)
14971510
if (!warn_on_s0ix_failures)
14981511
return 0;
14991512

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);
1513+
if (pmc_core_is_deepest_pkgc_failed(pmcdev)) {
1514+
/* S0ix failed because of deepest PKGC entry failure */
1515+
dev_info(dev, "CPU did not enter %s!!! (%s cnt=0x%llx)\n",
1516+
msr_map[pmcdev->num_of_pkgc - 1].name,
1517+
msr_map[pmcdev->num_of_pkgc - 1].name,
1518+
pmcdev->pkgc_res_cnt[pmcdev->num_of_pkgc - 1]);
1519+
1520+
for (i = 0; i < pmcdev->num_of_pkgc; i++) {
1521+
u64 pc_cnt;
1522+
1523+
if (!rdmsrl_safe(msr_map[i].bit_mask, &pc_cnt)) {
1524+
dev_info(dev, "Prev %s cnt = 0x%llx, Current %s cnt = 0x%llx\n",
1525+
msr_map[i].name, pmcdev->pkgc_res_cnt[i],
1526+
msr_map[i].name, pc_cnt);
1527+
}
1528+
}
15041529
return 0;
15051530
}
15061531

drivers/platform/x86/intel/pmc/core.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,8 @@ struct pmc {
385385
* @pmc_xram_read_bit: flag to indicate whether PMC XRAM shadow registers
386386
* used to read MPHY PG and PLL status are available
387387
* @mutex_lock: mutex to complete one transcation
388-
* @pc10_counter: PC10 residency counter
388+
* @pkgc_res_cnt: Array of PKGC residency counters
389+
* @num_of_pkgc: Number of PKGC
389390
* @s0ix_counter: S0ix residency (step adjusted)
390391
* @num_lpm_modes: Count of enabled modes
391392
* @lpm_en_modes: Array of enabled modes from lowest to highest priority
@@ -403,13 +404,15 @@ struct pmc_dev {
403404
int pmc_xram_read_bit;
404405
struct mutex lock; /* generic mutex lock for PMC Core */
405406

406-
u64 pc10_counter;
407407
u64 s0ix_counter;
408408
int num_lpm_modes;
409409
int lpm_en_modes[LPM_MAX_NUM_MODES];
410410
void (*suspend)(struct pmc_dev *pmcdev);
411411
int (*resume)(struct pmc_dev *pmcdev);
412412

413+
u64 *pkgc_res_cnt;
414+
u8 num_of_pkgc;
415+
413416
bool has_die_c6;
414417
u32 die_c6_offset;
415418
struct telem_endpoint *punit_ep;

0 commit comments

Comments
 (0)