Skip to content

Commit e35fb6b

Browse files
committed
Merge: platform/x86:intel/pmc: Updates
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1513 Description: updates for platform/x86:intel/pmc JIRA: https://issues.redhat.com/browse/RHEL-110838 Build Info: 69007676 Tested: Successful platform test results on Intel (intel-pantherlake-h-03) system. Signed-off-by: Steve Best <sbest@redhat.com> Approved-by: Tony Camuso <tcamuso@redhat.com> Approved-by: Lenny Szubowicz <lszubowi@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Approved-by: Eder Zulian <ezulian@redhat.com> Merged-by: Scott Weaver <scweaver@redhat.com>
2 parents 13e2502 + 5176458 commit e35fb6b

File tree

11 files changed

+509
-373
lines changed

11 files changed

+509
-373
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 core_ssram.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/arl.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
#include <linux/pci.h>
1212
#include "core.h"
13-
#include "../pmt/telemetry.h"
1413

1514
/* PMC SSRAM PMT Telemetry GUID */
1615
#define IOEP_LPM_REQ_GUID 0x5077612
@@ -651,29 +650,25 @@ static const struct pmc_reg_map arl_pchs_reg_map = {
651650
.etr3_offset = ETR3_OFFSET,
652651
};
653652

654-
#define PMC_DEVID_SOCM 0x777f
655-
#define PMC_DEVID_SOCS 0xae7f
656-
#define PMC_DEVID_IOEP 0x7ecf
657-
#define PMC_DEVID_PCHS 0x7f27
658653
static struct pmc_info arl_pmc_info_list[] = {
659654
{
660655
.guid = IOEP_LPM_REQ_GUID,
661-
.devid = PMC_DEVID_IOEP,
656+
.devid = PMC_DEVID_ARL_IOEP,
662657
.map = &mtl_ioep_reg_map,
663658
},
664659
{
665660
.guid = SOCS_LPM_REQ_GUID,
666-
.devid = PMC_DEVID_SOCS,
661+
.devid = PMC_DEVID_ARL_SOCS,
667662
.map = &arl_socs_reg_map,
668663
},
669664
{
670665
.guid = PCHS_LPM_REQ_GUID,
671-
.devid = PMC_DEVID_PCHS,
666+
.devid = PMC_DEVID_ARL_PCHS,
672667
.map = &arl_pchs_reg_map,
673668
},
674669
{
675670
.guid = SOCM_LPM_REQ_GUID,
676-
.devid = PMC_DEVID_SOCM,
671+
.devid = PMC_DEVID_ARL_SOCM,
677672
.map = &mtl_socm_reg_map,
678673
},
679674
{}

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

Lines changed: 228 additions & 13 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 */
@@ -1345,6 +1346,198 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
13451346
}
13461347
}
13471348

1349+
static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *map)
1350+
{
1351+
for (; list->map; ++list)
1352+
if (list->map == map)
1353+
return list->guid;
1354+
1355+
return 0;
1356+
}
1357+
1358+
/*
1359+
* This function retrieves low power mode requirement data from PMC Low
1360+
* Power Mode (LPM) table.
1361+
*
1362+
* In telemetry space, the LPM table contains a 4 byte header followed
1363+
* by 8 consecutive mode blocks (one for each LPM mode). Each block
1364+
* has a 4 byte header followed by a set of registers that describe the
1365+
* IP state requirements for the given mode. The IP mapping is platform
1366+
* specific but the same for each block, making for easy analysis.
1367+
* Platforms only use a subset of the space to track the requirements
1368+
* for their IPs. Callers provide the requirement registers they use as
1369+
* a list of indices. Each requirement register is associated with an
1370+
* IP map that's maintained by the caller.
1371+
*
1372+
* Header
1373+
* +----+----------------------------+----------------------------+
1374+
* | 0 | REVISION | ENABLED MODES |
1375+
* +----+--------------+-------------+-------------+--------------+
1376+
*
1377+
* Low Power Mode 0 Block
1378+
* +----+--------------+-------------+-------------+--------------+
1379+
* | 1 | SUB ID | SIZE | MAJOR | MINOR |
1380+
* +----+--------------+-------------+-------------+--------------+
1381+
* | 2 | LPM0 Requirements 0 |
1382+
* +----+---------------------------------------------------------+
1383+
* | | ... |
1384+
* +----+---------------------------------------------------------+
1385+
* | 29 | LPM0 Requirements 27 |
1386+
* +----+---------------------------------------------------------+
1387+
*
1388+
* ...
1389+
*
1390+
* Low Power Mode 7 Block
1391+
* +----+--------------+-------------+-------------+--------------+
1392+
* | | SUB ID | SIZE | MAJOR | MINOR |
1393+
* +----+--------------+-------------+-------------+--------------+
1394+
* | 60 | LPM7 Requirements 0 |
1395+
* +----+---------------------------------------------------------+
1396+
* | | ... |
1397+
* +----+---------------------------------------------------------+
1398+
* | 87 | LPM7 Requirements 27 |
1399+
* +----+---------------------------------------------------------+
1400+
*
1401+
*/
1402+
static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc, struct pci_dev *pcidev)
1403+
{
1404+
struct telem_endpoint *ep;
1405+
const u8 *lpm_indices;
1406+
int num_maps, mode_offset = 0;
1407+
int ret, mode;
1408+
int lpm_size;
1409+
u32 guid;
1410+
1411+
lpm_indices = pmc->map->lpm_reg_index;
1412+
num_maps = pmc->map->lpm_num_maps;
1413+
lpm_size = LPM_MAX_NUM_MODES * num_maps;
1414+
1415+
guid = pmc_core_find_guid(pmcdev->regmap_list, pmc->map);
1416+
if (!guid)
1417+
return -ENXIO;
1418+
1419+
ep = pmt_telem_find_and_register_endpoint(pcidev, guid, 0);
1420+
if (IS_ERR(ep)) {
1421+
dev_dbg(&pmcdev->pdev->dev, "couldn't get telem endpoint %pe", ep);
1422+
return -EPROBE_DEFER;
1423+
}
1424+
1425+
pmc->lpm_req_regs = devm_kzalloc(&pmcdev->pdev->dev,
1426+
lpm_size * sizeof(u32),
1427+
GFP_KERNEL);
1428+
if (!pmc->lpm_req_regs) {
1429+
ret = -ENOMEM;
1430+
goto unregister_ep;
1431+
}
1432+
1433+
mode_offset = LPM_HEADER_OFFSET + LPM_MODE_OFFSET;
1434+
pmc_for_each_mode(mode, pmcdev) {
1435+
u32 *req_offset = pmc->lpm_req_regs + (mode * num_maps);
1436+
int m;
1437+
1438+
for (m = 0; m < num_maps; m++) {
1439+
u8 sample_id = lpm_indices[m] + mode_offset;
1440+
1441+
ret = pmt_telem_read32(ep, sample_id, req_offset, 1);
1442+
if (ret) {
1443+
dev_err(&pmcdev->pdev->dev,
1444+
"couldn't read Low Power Mode requirements: %d\n", ret);
1445+
goto unregister_ep;
1446+
}
1447+
++req_offset;
1448+
}
1449+
mode_offset += LPM_REG_COUNT + LPM_MODE_OFFSET;
1450+
}
1451+
1452+
unregister_ep:
1453+
pmt_telem_unregister_endpoint(ep);
1454+
1455+
return ret;
1456+
}
1457+
1458+
static int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev, int func)
1459+
{
1460+
struct pci_dev *pcidev __free(pci_dev_put) = NULL;
1461+
unsigned int i;
1462+
int ret;
1463+
1464+
pcidev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(20, func));
1465+
if (!pcidev)
1466+
return -ENODEV;
1467+
1468+
for (i = 0; i < ARRAY_SIZE(pmcdev->pmcs); ++i) {
1469+
if (!pmcdev->pmcs[i])
1470+
continue;
1471+
1472+
ret = pmc_core_get_lpm_req(pmcdev, pmcdev->pmcs[i], pcidev);
1473+
if (ret)
1474+
return ret;
1475+
}
1476+
1477+
return 0;
1478+
}
1479+
1480+
static const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
1481+
{
1482+
for (; list->map; ++list)
1483+
if (devid == list->devid)
1484+
return list->map;
1485+
1486+
return NULL;
1487+
}
1488+
1489+
static int pmc_core_pmc_add(struct pmc_dev *pmcdev, unsigned int pmc_index)
1490+
1491+
{
1492+
struct pmc_ssram_telemetry pmc_ssram_telemetry;
1493+
const struct pmc_reg_map *map;
1494+
struct pmc *pmc;
1495+
int ret;
1496+
1497+
ret = pmc_ssram_telemetry_get_pmc_info(pmc_index, &pmc_ssram_telemetry);
1498+
if (ret)
1499+
return ret;
1500+
1501+
map = pmc_core_find_regmap(pmcdev->regmap_list, pmc_ssram_telemetry.devid);
1502+
if (!map)
1503+
return -ENODEV;
1504+
1505+
pmc = pmcdev->pmcs[pmc_index];
1506+
/* Memory for primary PMC has been allocated */
1507+
if (!pmc) {
1508+
pmc = devm_kzalloc(&pmcdev->pdev->dev, sizeof(*pmc), GFP_KERNEL);
1509+
if (!pmc)
1510+
return -ENOMEM;
1511+
}
1512+
1513+
pmc->map = map;
1514+
pmc->base_addr = pmc_ssram_telemetry.base_addr;
1515+
pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length);
1516+
1517+
if (!pmc->regbase) {
1518+
devm_kfree(&pmcdev->pdev->dev, pmc);
1519+
return -ENOMEM;
1520+
}
1521+
1522+
pmcdev->pmcs[pmc_index] = pmc;
1523+
1524+
return 0;
1525+
}
1526+
1527+
static int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev)
1528+
{
1529+
int ret;
1530+
1531+
ret = pmc_core_pmc_add(pmcdev, PMC_IDX_MAIN);
1532+
if (ret)
1533+
return ret;
1534+
1535+
pmc_core_pmc_add(pmcdev, PMC_IDX_IOE);
1536+
pmc_core_pmc_add(pmcdev, PMC_IDX_PCH);
1537+
1538+
return 0;
1539+
}
1540+
13481541
/*
13491542
* When supported, ssram init is used to achieve all available PMCs.
13501543
* If ssram init fails, this function uses legacy method to at least get the
@@ -1362,10 +1555,18 @@ int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
13621555
ssram = pmc_dev_info->regmap_list != NULL;
13631556
if (ssram) {
13641557
pmcdev->regmap_list = pmc_dev_info->regmap_list;
1365-
ret = pmc_core_ssram_init(pmcdev, pmc_dev_info->pci_func);
1558+
ret = pmc_core_ssram_get_reg_base(pmcdev);
1559+
/*
1560+
* EAGAIN error code indicates Intel PMC SSRAM Telemetry driver
1561+
* has not finished probe and PMC info is not available yet. Try
1562+
* again later.
1563+
*/
1564+
if (ret == -EAGAIN)
1565+
return -EPROBE_DEFER;
1566+
13661567
if (ret) {
13671568
dev_warn(&pmcdev->pdev->dev,
1368-
"ssram init failed, %d, using legacy init\n", ret);
1569+
"Failed to get PMC info from SSRAM, %d, using legacy init\n", ret);
13691570
ssram = false;
13701571
}
13711572
}
@@ -1381,10 +1582,26 @@ int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
13811582
if (pmc_dev_info->dmu_guid)
13821583
pmc_core_punit_pmt_init(pmcdev, pmc_dev_info->dmu_guid);
13831584

1384-
if (ssram)
1385-
return pmc_core_ssram_get_lpm_reqs(pmcdev);
1585+
if (ssram) {
1586+
ret = pmc_core_ssram_get_lpm_reqs(pmcdev, pmc_dev_info->pci_func);
1587+
if (ret)
1588+
goto unmap_regbase;
1589+
}
13861590

13871591
return 0;
1592+
1593+
unmap_regbase:
1594+
for (unsigned int i = 0; i < ARRAY_SIZE(pmcdev->pmcs); ++i) {
1595+
struct pmc *pmc = pmcdev->pmcs[i];
1596+
1597+
if (pmc && pmc->regbase)
1598+
iounmap(pmc->regbase);
1599+
}
1600+
1601+
if (pmcdev->punit_ep)
1602+
pmt_telem_unregister_endpoint(pmcdev->punit_ep);
1603+
1604+
return ret;
13881605
}
13891606

13901607
static const struct x86_cpu_id intel_pmc_core_ids[] = {
@@ -1408,6 +1625,7 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = {
14081625
X86_MATCH_VFM(INTEL_RAPTORLAKE_P, &tgl_l_pmc_dev),
14091626
X86_MATCH_VFM(INTEL_RAPTORLAKE, &adl_pmc_dev),
14101627
X86_MATCH_VFM(INTEL_RAPTORLAKE_S, &adl_pmc_dev),
1628+
X86_MATCH_VFM(INTEL_BARTLETTLAKE, &adl_pmc_dev),
14111629
X86_MATCH_VFM(INTEL_METEORLAKE_L, &mtl_pmc_dev),
14121630
X86_MATCH_VFM(INTEL_ARROWLAKE, &arl_pmc_dev),
14131631
X86_MATCH_VFM(INTEL_ARROWLAKE_H, &arl_h_pmc_dev),
@@ -1471,20 +1689,14 @@ static void pmc_core_clean_structure(struct platform_device *pdev)
14711689
for (i = 0; i < ARRAY_SIZE(pmcdev->pmcs); ++i) {
14721690
struct pmc *pmc = pmcdev->pmcs[i];
14731691

1474-
if (pmc)
1692+
if (pmc && pmc->regbase)
14751693
iounmap(pmc->regbase);
14761694
}
14771695

1478-
if (pmcdev->ssram_pcidev) {
1479-
pci_dev_put(pmcdev->ssram_pcidev);
1480-
pci_disable_device(pmcdev->ssram_pcidev);
1481-
}
1482-
14831696
if (pmcdev->punit_ep)
14841697
pmt_telem_unregister_endpoint(pmcdev->punit_ep);
14851698

14861699
platform_set_drvdata(pdev, NULL);
1487-
mutex_destroy(&pmcdev->lock);
14881700
}
14891701

14901702
static int pmc_core_probe(struct platform_device *pdev)
@@ -1529,15 +1741,17 @@ static int pmc_core_probe(struct platform_device *pdev)
15291741
if (!pmcdev->pkgc_res_cnt)
15301742
return -ENOMEM;
15311743

1532-
mutex_init(&pmcdev->lock);
1744+
ret = devm_mutex_init(&pdev->dev, &pmcdev->lock);
1745+
if (ret)
1746+
return ret;
15331747

15341748
if (pmc_dev_info->init)
15351749
ret = pmc_dev_info->init(pmcdev, pmc_dev_info);
15361750
else
15371751
ret = generic_core_init(pmcdev, pmc_dev_info);
15381752

15391753
if (ret) {
1540-
pmc_core_clean_structure(pdev);
1754+
platform_set_drvdata(pdev, NULL);
15411755
return ret;
15421756
}
15431757

@@ -1719,5 +1933,6 @@ static struct platform_driver pmc_core_driver = {
17191933

17201934
module_platform_driver(pmc_core_driver);
17211935

1936+
MODULE_IMPORT_NS("INTEL_PMT_TELEMETRY");
17221937
MODULE_LICENSE("GPL v2");
17231938
MODULE_DESCRIPTION("Intel PMC Core Driver");

0 commit comments

Comments
 (0)