Skip to content

Commit 5e1b057

Browse files
committed
platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver
JIRA: https://issues.redhat.com/browse/RHEL-110838 commit b5d4653 Author: Xi Pardee <xi.pardee@linux.intel.com> Date: Fri Apr 25 12:52:30 2025 -0700 platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver Convert ssram device related functionalities to a new driver named Intel PMC SSRAM Telemetry driver. Modify PMC Core driver to use API exported by the driver to discover and achieve devid and PWRMBASE address information for each available PMC. PMC Core driver needs to get PCI device when reading from telemetry regions. The new SSRAM driver binds to the SSRAM device and provides the following functionalities: 1. Look for and register telemetry regions available in SSRAM device. 2. Provide devid and PWRMBASE address information for the corresponding PMCs. Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com> Link: https://lore.kernel.org/r/20250425195237.493129-3-xi.pardee@linux.intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Steve Best <sbest@redhat.com>
1 parent 362ed0a commit 5e1b057

File tree

6 files changed

+185
-78
lines changed

6 files changed

+185
-78
lines changed

drivers/platform/x86/intel/pmc/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ config INTEL_PMC_CORE
88
depends on PCI
99
depends on ACPI
1010
depends on INTEL_PMT_TELEMETRY
11+
select INTEL_PMC_SSRAM_TELEMETRY
1112
help
1213
The Intel Platform Controller Hub for Intel Core SoCs provides access
1314
to Power Management Controller registers via various interfaces. This
@@ -24,3 +25,6 @@ config INTEL_PMC_CORE
2425
- SLPS0 Debug registers (Cannonlake/Icelake PCH)
2526
- Low Power Mode registers (Tigerlake and beyond)
2627
- PMC quirks as needed to enable SLPS0/S0ix
28+
29+
config INTEL_PMC_SSRAM_TELEMETRY
30+
tristate

drivers/platform/x86/intel/pmc/Makefile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
# Intel x86 Platform-Specific Drivers
44
#
55

6-
intel_pmc_core-y := core.o ssram_telemetry.o spt.o cnp.o \
7-
icl.o tgl.o adl.o mtl.o arl.o lnl.o ptl.o
6+
intel_pmc_core-y := core.o spt.o cnp.o icl.o \
7+
tgl.o adl.o mtl.o arl.o lnl.o ptl.o
88
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o
99
intel_pmc_core_pltdrv-y := pltdrv.o
1010
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core_pltdrv.o
11+
12+
# Intel PMC SSRAM driver
13+
intel_pmc_ssram_telemetry-y += ssram_telemetry.o
14+
obj-$(CONFIG_INTEL_PMC_SSRAM_TELEMETRY) += intel_pmc_ssram_telemetry.o

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

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <asm/tsc.h>
3030

3131
#include "core.h"
32+
#include "ssram_telemetry.h"
3233
#include "../pmt/telemetry.h"
3334

3435
/* Maximum number of modes supported by platfoms that has low power mode capability */
@@ -1354,7 +1355,7 @@ static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *m
13541355
return 0;
13551356
}
13561357

1357-
static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
1358+
static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc, struct pci_dev *pcidev)
13581359
{
13591360
struct telem_endpoint *ep;
13601361
const u8 *lpm_indices;
@@ -1371,7 +1372,7 @@ static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
13711372
if (!guid)
13721373
return -ENXIO;
13731374

1374-
ep = pmt_telem_find_and_register_endpoint(pmcdev->ssram_pcidev, guid, 0);
1375+
ep = pmt_telem_find_and_register_endpoint(pcidev, guid, 0);
13751376
if (IS_ERR(ep)) {
13761377
dev_dbg(&pmcdev->pdev->dev, "couldn't get telem endpoint %ld",
13771378
PTR_ERR(ep));
@@ -1455,27 +1456,29 @@ static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
14551456
return ret;
14561457
}
14571458

1458-
static int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev)
1459+
static int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev, int func)
14591460
{
1461+
struct pci_dev *pcidev __free(pci_dev_put) = NULL;
14601462
unsigned int i;
14611463
int ret;
14621464

1463-
if (!pmcdev->ssram_pcidev)
1465+
pcidev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(20, func));
1466+
if (!pcidev)
14641467
return -ENODEV;
14651468

14661469
for (i = 0; i < ARRAY_SIZE(pmcdev->pmcs); ++i) {
14671470
if (!pmcdev->pmcs[i])
14681471
continue;
14691472

1470-
ret = pmc_core_get_lpm_req(pmcdev, pmcdev->pmcs[i]);
1473+
ret = pmc_core_get_lpm_req(pmcdev, pmcdev->pmcs[i], pcidev);
14711474
if (ret)
14721475
return ret;
14731476
}
14741477

14751478
return 0;
14761479
}
14771480

1478-
const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
1481+
static const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
14791482
{
14801483
for (; list->map; ++list)
14811484
if (devid == list->devid)
@@ -1484,23 +1487,32 @@ const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
14841487
return NULL;
14851488
}
14861489

1487-
int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
1488-
const struct pmc_reg_map *reg_map, unsigned int pmc_index)
1490+
static int pmc_core_pmc_add(struct pmc_dev *pmcdev, unsigned int pmc_index)
1491+
14891492
{
1490-
struct pmc *pmc = pmcdev->pmcs[pmc_index];
1493+
struct pmc_ssram_telemetry pmc_ssram_telemetry;
1494+
const struct pmc_reg_map *map;
1495+
struct pmc *pmc;
1496+
int ret;
1497+
1498+
ret = pmc_ssram_telemetry_get_pmc_info(pmc_index, &pmc_ssram_telemetry);
1499+
if (ret)
1500+
return ret;
14911501

1492-
if (!pwrm_base)
1502+
map = pmc_core_find_regmap(pmcdev->regmap_list, pmc_ssram_telemetry.devid);
1503+
if (!map)
14931504
return -ENODEV;
14941505

1495-
/* Memory for primary PMC has been allocated in core.c */
1506+
pmc = pmcdev->pmcs[pmc_index];
1507+
/* Memory for primary PMC has been allocated */
14961508
if (!pmc) {
14971509
pmc = devm_kzalloc(&pmcdev->pdev->dev, sizeof(*pmc), GFP_KERNEL);
14981510
if (!pmc)
14991511
return -ENOMEM;
15001512
}
15011513

1502-
pmc->map = reg_map;
1503-
pmc->base_addr = pwrm_base;
1514+
pmc->map = map;
1515+
pmc->base_addr = pmc_ssram_telemetry.base_addr;
15041516
pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length);
15051517

15061518
if (!pmc->regbase) {
@@ -1513,6 +1525,20 @@ int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
15131525
return 0;
15141526
}
15151527

1528+
static int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev)
1529+
{
1530+
int ret;
1531+
1532+
ret = pmc_core_pmc_add(pmcdev, PMC_IDX_MAIN);
1533+
if (ret)
1534+
return ret;
1535+
1536+
pmc_core_pmc_add(pmcdev, PMC_IDX_IOE);
1537+
pmc_core_pmc_add(pmcdev, PMC_IDX_PCH);
1538+
1539+
return 0;
1540+
}
1541+
15161542
/*
15171543
* When supported, ssram init is used to achieve all available PMCs.
15181544
* If ssram init fails, this function uses legacy method to at least get the
@@ -1530,10 +1556,18 @@ int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
15301556
ssram = pmc_dev_info->regmap_list != NULL;
15311557
if (ssram) {
15321558
pmcdev->regmap_list = pmc_dev_info->regmap_list;
1533-
ret = pmc_core_ssram_init(pmcdev, pmc_dev_info->pci_func);
1559+
ret = pmc_core_ssram_get_reg_base(pmcdev);
1560+
/*
1561+
* EAGAIN error code indicates Intel PMC SSRAM Telemetry driver
1562+
* has not finished probe and PMC info is not available yet. Try
1563+
* again later.
1564+
*/
1565+
if (ret == -EAGAIN)
1566+
return -EPROBE_DEFER;
1567+
15341568
if (ret) {
15351569
dev_warn(&pmcdev->pdev->dev,
1536-
"ssram init failed, %d, using legacy init\n", ret);
1570+
"Failed to get PMC info from SSRAM, %d, using legacy init\n", ret);
15371571
ssram = false;
15381572
}
15391573
}
@@ -1550,7 +1584,7 @@ int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
15501584
pmc_core_punit_pmt_init(pmcdev, pmc_dev_info->dmu_guid);
15511585

15521586
if (ssram)
1553-
return pmc_core_ssram_get_lpm_reqs(pmcdev);
1587+
return pmc_core_ssram_get_lpm_reqs(pmcdev, pmc_dev_info->pci_func);
15541588

15551589
return 0;
15561590
}
@@ -1639,15 +1673,10 @@ static void pmc_core_clean_structure(struct platform_device *pdev)
16391673
for (i = 0; i < ARRAY_SIZE(pmcdev->pmcs); ++i) {
16401674
struct pmc *pmc = pmcdev->pmcs[i];
16411675

1642-
if (pmc)
1676+
if (pmc && pmc->regbase)
16431677
iounmap(pmc->regbase);
16441678
}
16451679

1646-
if (pmcdev->ssram_pcidev) {
1647-
pci_dev_put(pmcdev->ssram_pcidev);
1648-
pci_disable_device(pmcdev->ssram_pcidev);
1649-
}
1650-
16511680
if (pmcdev->punit_ep)
16521681
pmt_telem_unregister_endpoint(pmcdev->punit_ep);
16531682

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

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,6 @@ struct pmc {
413413
* struct pmc_dev - pmc device structure
414414
* @devs: pointer to an array of pmc pointers
415415
* @pdev: pointer to platform_device struct
416-
* @ssram_pcidev: pointer to pci device struct for the PMC SSRAM
417416
* @crystal_freq: crystal frequency from cpuid
418417
* @dbgfs_dir: path to debugfs interface
419418
* @pmc_xram_read_bit: flag to indicate whether PMC XRAM shadow registers
@@ -433,7 +432,6 @@ struct pmc_dev {
433432
struct pmc *pmcs[MAX_NUM_PMC];
434433
struct dentry *dbgfs_dir;
435434
struct platform_device *pdev;
436-
struct pci_dev *ssram_pcidev;
437435
unsigned int crystal_freq;
438436
int pmc_xram_read_bit;
439437
struct mutex lock; /* generic mutex lock for PMC Core */
@@ -510,12 +508,7 @@ void pmc_core_get_low_power_modes(struct pmc_dev *pmcdev);
510508
void pmc_core_punit_pmt_init(struct pmc_dev *pmcdev, u32 guid);
511509
void pmc_core_set_device_d3(unsigned int device);
512510

513-
int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func);
514-
515511
int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info);
516-
const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid);
517-
int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
518-
const struct pmc_reg_map *reg_map, unsigned int pmc_index);
519512

520513
extern struct pmc_dev_info spt_pmc_dev;
521514
extern struct pmc_dev_info cnp_pmc_dev;

0 commit comments

Comments
 (0)