Skip to content

Commit 2bcef45

Browse files
xpardee-createjwrdegoede
authored andcommitted
platform/x86:intel/pmc: Enable debugfs multiple PMC support
Enable debugfs support for multiple PMC. These debugfs attributes show information for all enabled PMCs. pch_ip_power_gating_status substate_status_registers substate_live_status_registers ltr_show ltr_ignore Signed-off-by: Xi Pardee <xi.pardee@intel.com> Signed-off-by: Rajvi Jingar <rajvi.jingar@linux.intel.com> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Link: https://lore.kernel.org/r/20230613225347.2720665-5-rajvi.jingar@linux.intel.com Signed-off-by: Hans de Goede <hdegoede@redhat.com>
1 parent 1c709ae commit 2bcef45

File tree

1 file changed

+129
-66
lines changed
  • drivers/platform/x86/intel/pmc

1 file changed

+129
-66
lines changed

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

Lines changed: 129 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ static int pmc_core_lpm_get_arr_size(const struct pmc_bit_map **maps)
252252
}
253253

254254
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,
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

302302
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)
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

310310
static 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

455463
int 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

479509
static ssize_t pmc_core_ltr_ignore_write(struct file *file,
@@ -586,36 +616,44 @@ static u32 convert_ltr_scale(u32 val)
586616

587617
static 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);
651689
static 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);
664710
static 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

Comments
 (0)