* [PATCH 1/7] platform/x86:intel/pmc: Remove SSRAM support from PMC Core
2024-08-09 20:46 [PATCH 0/7] Create Intel PMC SSRAM Telemetry driver Xi Pardee
@ 2024-08-09 20:46 ` Xi Pardee
2024-08-09 20:46 ` [PATCH 2/7] platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Xi Pardee @ 2024-08-09 20:46 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel
From: Xi Pardee <xi.pardee@intel.com>
Remove SSRAM support code from PMC Core driver. That includes removing
support to discover PMCs through SSRAM device and achieve LPM requirement
data from telemetry endpoints. A separate Intel SSRAM Telemetry driver
will be added later in this series to be responsible for the SSRAM device.
Currently PMC Core driver gets PWRMBASE address and devid for each PMC from
the SSRAM device and also registers telemetry endpoints through intel_vsec
driver. PMC Core probe function returns -EPROBE_DEFER when getting LPM
requirement data from a telem endpoint that is not available yet. This
setup may result in an infinite loop of .probe() calls as -EPROBE_DEFER
is returned after a child device has been registered. Creating a new Intel
SSRAM Telemetry driver prevents the infinite loop possibility.
Signed-off-by: Xi Pardee <xi.pardee@intel.com>
---
drivers/platform/x86/intel/pmc/Makefile | 4 +-
drivers/platform/x86/intel/pmc/arl.c | 58 +---
drivers/platform/x86/intel/pmc/core.c | 6 +-
drivers/platform/x86/intel/pmc/core.h | 5 -
drivers/platform/x86/intel/pmc/core_ssram.c | 326 --------------------
drivers/platform/x86/intel/pmc/mtl.c | 59 +---
6 files changed, 12 insertions(+), 446 deletions(-)
delete mode 100644 drivers/platform/x86/intel/pmc/core_ssram.c
diff --git a/drivers/platform/x86/intel/pmc/Makefile b/drivers/platform/x86/intel/pmc/Makefile
index 389e5419dadf..6b682be0ec5a 100644
--- a/drivers/platform/x86/intel/pmc/Makefile
+++ b/drivers/platform/x86/intel/pmc/Makefile
@@ -3,8 +3,8 @@
# Intel x86 Platform-Specific Drivers
#
-intel_pmc_core-y := core.o core_ssram.o spt.o cnp.o \
- icl.o tgl.o adl.o mtl.o arl.o lnl.o
+intel_pmc_core-y := core.o spt.o cnp.o icl.o \
+ tgl.o adl.o mtl.o arl.o lnl.o
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o
intel_pmc_core_pltdrv-y := pltdrv.o
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core_pltdrv.o
diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c
index e10527c4e3e0..4b824612f355 100644
--- a/drivers/platform/x86/intel/pmc/arl.c
+++ b/drivers/platform/x86/intel/pmc/arl.c
@@ -10,14 +10,6 @@
#include <linux/pci.h>
#include "core.h"
-#include "../pmt/telemetry.h"
-
-/* PMC SSRAM PMT Telemetry GUID */
-#define IOEP_LPM_REQ_GUID 0x5077612
-#define SOCS_LPM_REQ_GUID 0x8478657
-#define PCHS_LPM_REQ_GUID 0x9684572
-
-static const u8 ARL_LPM_REG_INDEX[] = {0, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20};
const struct pmc_bit_map arl_socs_ltr_show_map[] = {
{"SOUTHPORT_A", CNP_PMC_LTR_SPA},
@@ -277,7 +269,6 @@ const struct pmc_reg_map arl_socs_reg_map = {
.lpm_sts_latch_en_offset = MTL_LPM_STATUS_LATCH_EN_OFFSET,
.lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET,
.lpm_num_maps = ADL_LPM_NUM_MAPS,
- .lpm_reg_index = ARL_LPM_REG_INDEX,
.etr3_offset = ETR3_OFFSET,
.pson_residency_offset = TGL_PSON_RESIDENCY_OFFSET,
.pson_residency_counter_step = TGL_PSON_RES_COUNTER_STEP,
@@ -646,32 +637,9 @@ const struct pmc_reg_map arl_pchs_reg_map = {
.lpm_sts_latch_en_offset = MTL_LPM_STATUS_LATCH_EN_OFFSET,
.lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET,
.lpm_num_maps = ADL_LPM_NUM_MAPS,
- .lpm_reg_index = ARL_LPM_REG_INDEX,
.etr3_offset = ETR3_OFFSET,
};
-#define PMC_DEVID_SOCS 0xae7f
-#define PMC_DEVID_IOEP 0x7ecf
-#define PMC_DEVID_PCHS 0x7f27
-static struct pmc_info arl_pmc_info_list[] = {
- {
- .guid = IOEP_LPM_REQ_GUID,
- .devid = PMC_DEVID_IOEP,
- .map = &mtl_ioep_reg_map,
- },
- {
- .guid = SOCS_LPM_REQ_GUID,
- .devid = PMC_DEVID_SOCS,
- .map = &arl_socs_reg_map,
- },
- {
- .guid = PCHS_LPM_REQ_GUID,
- .devid = PMC_DEVID_PCHS,
- .map = &arl_pchs_reg_map,
- },
- {}
-};
-
#define ARL_NPU_PCI_DEV 0xad1d
#define ARL_GNA_PCI_DEV 0xae4c
/*
@@ -696,36 +664,18 @@ int arl_core_init(struct pmc_dev *pmcdev)
{
struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC];
int ret;
- int func = 0;
- bool ssram_init = true;
arl_d3_fixup();
pmcdev->suspend = cnl_suspend;
pmcdev->resume = arl_resume;
- pmcdev->regmap_list = arl_pmc_info_list;
- /*
- * If ssram init fails use legacy method to at least get the
- * primary PMC
- */
- ret = pmc_core_ssram_init(pmcdev, func);
- if (ret) {
- ssram_init = false;
- pmc->map = &arl_socs_reg_map;
-
- ret = get_primary_reg_base(pmc);
- if (ret)
- return ret;
- }
+ pmc->map = &arl_socs_reg_map;
+ ret = get_primary_reg_base(pmc);
+ if (ret)
+ return ret;
pmc_core_get_low_power_modes(pmcdev);
pmc_core_punit_pmt_init(pmcdev, ARL_PMT_DMU_GUID);
- if (ssram_init) {
- ret = pmc_core_ssram_get_lpm_reqs(pmcdev);
- if (ret)
- return ret;
- }
-
return 0;
}
diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
index 01ae71c6df59..5ecf55176734 100644
--- a/drivers/platform/x86/intel/pmc/core.c
+++ b/drivers/platform/x86/intel/pmc/core.c
@@ -1386,11 +1386,6 @@ static void pmc_core_clean_structure(struct platform_device *pdev)
iounmap(pmc->regbase);
}
- if (pmcdev->ssram_pcidev) {
- pci_dev_put(pmcdev->ssram_pcidev);
- pci_disable_device(pmcdev->ssram_pcidev);
- }
-
if (pmcdev->punit_ep)
pmt_telem_unregister_endpoint(pmcdev->punit_ep);
@@ -1623,5 +1618,6 @@ static struct platform_driver pmc_core_driver = {
module_platform_driver(pmc_core_driver);
+MODULE_IMPORT_NS(INTEL_PMT_TELEMETRY);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel PMC Core Driver");
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index ea04de7eb9e8..b0c66df8cd98 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -386,7 +386,6 @@ struct pmc {
* struct pmc_dev - pmc device structure
* @devs: pointer to an array of pmc pointers
* @pdev: pointer to platform_device struct
- * @ssram_pcidev: pointer to pci device struct for the PMC SSRAM
* @crystal_freq: crystal frequency from cpuid
* @dbgfs_dir: path to debugfs interface
* @pmc_xram_read_bit: flag to indicate whether PMC XRAM shadow registers
@@ -406,7 +405,6 @@ struct pmc_dev {
struct pmc *pmcs[MAX_NUM_PMC];
struct dentry *dbgfs_dir;
struct platform_device *pdev;
- struct pci_dev *ssram_pcidev;
unsigned int crystal_freq;
int pmc_xram_read_bit;
struct mutex lock; /* generic mutex lock for PMC Core */
@@ -579,7 +577,6 @@ extern const struct pmc_bit_map *arl_pchs_lpm_maps[];
extern const struct pmc_reg_map arl_pchs_reg_map;
extern void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev);
-extern int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev);
int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value, int ignore);
int pmc_core_resume_common(struct pmc_dev *pmcdev);
@@ -588,8 +585,6 @@ extern void pmc_core_get_low_power_modes(struct pmc_dev *pmcdev);
extern void pmc_core_punit_pmt_init(struct pmc_dev *pmcdev, u32 guid);
extern void pmc_core_set_device_d3(unsigned int device);
-extern int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func);
-
int spt_core_init(struct pmc_dev *pmcdev);
int cnp_core_init(struct pmc_dev *pmcdev);
int icl_core_init(struct pmc_dev *pmcdev);
diff --git a/drivers/platform/x86/intel/pmc/core_ssram.c b/drivers/platform/x86/intel/pmc/core_ssram.c
deleted file mode 100644
index 1bde86c54eb9..000000000000
--- a/drivers/platform/x86/intel/pmc/core_ssram.c
+++ /dev/null
@@ -1,326 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * This file contains functions to handle discovery of PMC metrics located
- * in the PMC SSRAM PCI device.
- *
- * Copyright (c) 2023, Intel Corporation.
- * All Rights Reserved.
- *
- */
-
-#include <linux/cleanup.h>
-#include <linux/pci.h>
-#include <linux/io-64-nonatomic-lo-hi.h>
-
-#include "core.h"
-#include "../vsec.h"
-#include "../pmt/telemetry.h"
-
-#define SSRAM_HDR_SIZE 0x100
-#define SSRAM_PWRM_OFFSET 0x14
-#define SSRAM_DVSEC_OFFSET 0x1C
-#define SSRAM_DVSEC_SIZE 0x10
-#define SSRAM_PCH_OFFSET 0x60
-#define SSRAM_IOE_OFFSET 0x68
-#define SSRAM_DEVID_OFFSET 0x70
-
-/* PCH query */
-#define LPM_HEADER_OFFSET 1
-#define LPM_REG_COUNT 28
-#define LPM_MODE_OFFSET 1
-
-DEFINE_FREE(pmc_core_iounmap, void __iomem *, iounmap(_T));
-
-static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *map)
-{
- for (; list->map; ++list)
- if (list->map == map)
- return list->guid;
-
- return 0;
-}
-
-static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
-{
- struct telem_endpoint *ep;
- const u8 *lpm_indices;
- int num_maps, mode_offset = 0;
- int ret, mode, i;
- int lpm_size;
- u32 guid;
-
- lpm_indices = pmc->map->lpm_reg_index;
- num_maps = pmc->map->lpm_num_maps;
- lpm_size = LPM_MAX_NUM_MODES * num_maps;
-
- guid = pmc_core_find_guid(pmcdev->regmap_list, pmc->map);
- if (!guid)
- return -ENXIO;
-
- ep = pmt_telem_find_and_register_endpoint(pmcdev->ssram_pcidev, guid, 0);
- if (IS_ERR(ep)) {
- dev_dbg(&pmcdev->pdev->dev, "couldn't get telem endpoint %ld",
- PTR_ERR(ep));
- return -EPROBE_DEFER;
- }
-
- pmc->lpm_req_regs = devm_kzalloc(&pmcdev->pdev->dev,
- lpm_size * sizeof(u32),
- GFP_KERNEL);
- if (!pmc->lpm_req_regs) {
- ret = -ENOMEM;
- goto unregister_ep;
- }
-
- /*
- * PMC Low Power Mode (LPM) table
- *
- * In telemetry space, the LPM table contains a 4 byte header followed
- * by 8 consecutive mode blocks (one for each LPM mode). Each block
- * has a 4 byte header followed by a set of registers that describe the
- * IP state requirements for the given mode. The IP mapping is platform
- * specific but the same for each block, making for easy analysis.
- * Platforms only use a subset of the space to track the requirements
- * for their IPs. Callers provide the requirement registers they use as
- * a list of indices. Each requirement register is associated with an
- * IP map that's maintained by the caller.
- *
- * Header
- * +----+----------------------------+----------------------------+
- * | 0 | REVISION | ENABLED MODES |
- * +----+--------------+-------------+-------------+--------------+
- *
- * Low Power Mode 0 Block
- * +----+--------------+-------------+-------------+--------------+
- * | 1 | SUB ID | SIZE | MAJOR | MINOR |
- * +----+--------------+-------------+-------------+--------------+
- * | 2 | LPM0 Requirements 0 |
- * +----+---------------------------------------------------------+
- * | | ... |
- * +----+---------------------------------------------------------+
- * | 29 | LPM0 Requirements 27 |
- * +----+---------------------------------------------------------+
- *
- * ...
- *
- * Low Power Mode 7 Block
- * +----+--------------+-------------+-------------+--------------+
- * | | SUB ID | SIZE | MAJOR | MINOR |
- * +----+--------------+-------------+-------------+--------------+
- * | 60 | LPM7 Requirements 0 |
- * +----+---------------------------------------------------------+
- * | | ... |
- * +----+---------------------------------------------------------+
- * | 87 | LPM7 Requirements 27 |
- * +----+---------------------------------------------------------+
- *
- */
- mode_offset = LPM_HEADER_OFFSET + LPM_MODE_OFFSET;
- pmc_for_each_mode(i, mode, pmcdev) {
- u32 *req_offset = pmc->lpm_req_regs + (mode * num_maps);
- int m;
-
- for (m = 0; m < num_maps; m++) {
- u8 sample_id = lpm_indices[m] + mode_offset;
-
- ret = pmt_telem_read32(ep, sample_id, req_offset, 1);
- if (ret) {
- dev_err(&pmcdev->pdev->dev,
- "couldn't read Low Power Mode requirements: %d\n", ret);
- devm_kfree(&pmcdev->pdev->dev, pmc->lpm_req_regs);
- goto unregister_ep;
- }
- ++req_offset;
- }
- mode_offset += LPM_REG_COUNT + LPM_MODE_OFFSET;
- }
-
-unregister_ep:
- pmt_telem_unregister_endpoint(ep);
-
- return ret;
-}
-
-int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev)
-{
- int ret, i;
-
- if (!pmcdev->ssram_pcidev)
- return -ENODEV;
-
- for (i = 0; i < ARRAY_SIZE(pmcdev->pmcs); ++i) {
- if (!pmcdev->pmcs[i])
- continue;
-
- ret = pmc_core_get_lpm_req(pmcdev, pmcdev->pmcs[i]);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static void
-pmc_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram)
-{
- struct pci_dev *pcidev = pmcdev->ssram_pcidev;
- struct intel_vsec_platform_info info = {};
- struct intel_vsec_header *headers[2] = {};
- struct intel_vsec_header header;
- void __iomem *dvsec;
- u32 dvsec_offset;
- u32 table, hdr;
-
- ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
- if (!ssram)
- return;
-
- dvsec_offset = readl(ssram + SSRAM_DVSEC_OFFSET);
- iounmap(ssram);
-
- dvsec = ioremap(ssram_base + dvsec_offset, SSRAM_DVSEC_SIZE);
- if (!dvsec)
- return;
-
- hdr = readl(dvsec + PCI_DVSEC_HEADER1);
- header.id = readw(dvsec + PCI_DVSEC_HEADER2);
- header.rev = PCI_DVSEC_HEADER1_REV(hdr);
- header.length = PCI_DVSEC_HEADER1_LEN(hdr);
- header.num_entries = readb(dvsec + INTEL_DVSEC_ENTRIES);
- header.entry_size = readb(dvsec + INTEL_DVSEC_SIZE);
-
- table = readl(dvsec + INTEL_DVSEC_TABLE);
- header.tbir = INTEL_DVSEC_TABLE_BAR(table);
- header.offset = INTEL_DVSEC_TABLE_OFFSET(table);
- iounmap(dvsec);
-
- headers[0] = &header;
- info.caps = VSEC_CAP_TELEMETRY;
- info.headers = headers;
- info.base_addr = ssram_base;
- info.parent = &pmcdev->pdev->dev;
-
- intel_vsec_register(pcidev, &info);
-}
-
-static const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
-{
- for (; list->map; ++list)
- if (devid == list->devid)
- return list->map;
-
- return NULL;
-}
-
-static inline u64 get_base(void __iomem *addr, u32 offset)
-{
- return lo_hi_readq(addr + offset) & GENMASK_ULL(63, 3);
-}
-
-static int
-pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
- const struct pmc_reg_map *reg_map, int pmc_index)
-{
- struct pmc *pmc = pmcdev->pmcs[pmc_index];
-
- if (!pwrm_base)
- return -ENODEV;
-
- /* Memory for primary PMC has been allocated in core.c */
- if (!pmc) {
- pmc = devm_kzalloc(&pmcdev->pdev->dev, sizeof(*pmc), GFP_KERNEL);
- if (!pmc)
- return -ENOMEM;
- }
-
- pmc->map = reg_map;
- pmc->base_addr = pwrm_base;
- pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length);
-
- if (!pmc->regbase) {
- devm_kfree(&pmcdev->pdev->dev, pmc);
- return -ENOMEM;
- }
-
- pmcdev->pmcs[pmc_index] = pmc;
-
- return 0;
-}
-
-static int
-pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, int pmc_idx, u32 offset)
-{
- struct pci_dev *ssram_pcidev = pmcdev->ssram_pcidev;
- void __iomem __free(pmc_core_iounmap) *tmp_ssram = NULL;
- void __iomem __free(pmc_core_iounmap) *ssram = NULL;
- const struct pmc_reg_map *map;
- u64 ssram_base, pwrm_base;
- u16 devid;
-
- if (!pmcdev->regmap_list)
- return -ENOENT;
-
- ssram_base = ssram_pcidev->resource[0].start;
- tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
-
- if (pmc_idx != PMC_IDX_MAIN) {
- /*
- * The secondary PMC BARS (which are behind hidden PCI devices)
- * are read from fixed offsets in MMIO of the primary PMC BAR.
- */
- ssram_base = get_base(tmp_ssram, offset);
- ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
- if (!ssram)
- return -ENOMEM;
-
- } else {
- ssram = no_free_ptr(tmp_ssram);
- }
-
- pwrm_base = get_base(ssram, SSRAM_PWRM_OFFSET);
- devid = readw(ssram + SSRAM_DEVID_OFFSET);
-
- /* Find and register and PMC telemetry entries */
- pmc_add_pmt(pmcdev, ssram_base, ssram);
-
- map = pmc_core_find_regmap(pmcdev->regmap_list, devid);
- if (!map)
- return -ENODEV;
-
- return pmc_core_pmc_add(pmcdev, pwrm_base, map, pmc_idx);
-}
-
-int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func)
-{
- struct pci_dev *pcidev;
- int ret;
-
- pcidev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(20, func));
- if (!pcidev)
- return -ENODEV;
-
- ret = pcim_enable_device(pcidev);
- if (ret)
- goto release_dev;
-
- pmcdev->ssram_pcidev = pcidev;
-
- ret = pmc_core_ssram_get_pmc(pmcdev, PMC_IDX_MAIN, 0);
- if (ret)
- goto disable_dev;
-
- pmc_core_ssram_get_pmc(pmcdev, PMC_IDX_IOE, SSRAM_IOE_OFFSET);
- pmc_core_ssram_get_pmc(pmcdev, PMC_IDX_PCH, SSRAM_PCH_OFFSET);
-
- return 0;
-
-disable_dev:
- pmcdev->ssram_pcidev = NULL;
- pci_disable_device(pcidev);
-release_dev:
- pci_dev_put(pcidev);
-
- return ret;
-}
-MODULE_IMPORT_NS(INTEL_VSEC);
-MODULE_IMPORT_NS(INTEL_PMT_TELEMETRY);
diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
index c7d15d864039..0b9efab21d60 100644
--- a/drivers/platform/x86/intel/pmc/mtl.c
+++ b/drivers/platform/x86/intel/pmc/mtl.c
@@ -10,14 +10,6 @@
#include <linux/pci.h>
#include "core.h"
-#include "../pmt/telemetry.h"
-
-/* PMC SSRAM PMT Telemetry GUIDS */
-#define SOCP_LPM_REQ_GUID 0x2625030
-#define IOEM_LPM_REQ_GUID 0x4357464
-#define IOEP_LPM_REQ_GUID 0x5077612
-
-static const u8 MTL_LPM_REG_INDEX[] = {0, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20};
/*
* Die Mapping to Product.
@@ -473,7 +465,6 @@ const struct pmc_reg_map mtl_socm_reg_map = {
.lpm_sts = mtl_socm_lpm_maps,
.lpm_status_offset = MTL_LPM_STATUS_OFFSET,
.lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET,
- .lpm_reg_index = MTL_LPM_REG_INDEX,
};
const struct pmc_bit_map mtl_ioep_pfear_map[] = {
@@ -797,7 +788,6 @@ const struct pmc_reg_map mtl_ioep_reg_map = {
.lpm_priority_offset = MTL_LPM_PRI_OFFSET,
.lpm_en_offset = MTL_LPM_EN_OFFSET,
.lpm_sts_latch_en_offset = MTL_LPM_STATUS_LATCH_EN_OFFSET,
- .lpm_reg_index = MTL_LPM_REG_INDEX,
};
const struct pmc_bit_map mtl_ioem_pfear_map[] = {
@@ -944,29 +934,6 @@ const struct pmc_reg_map mtl_ioem_reg_map = {
.lpm_en_offset = MTL_LPM_EN_OFFSET,
.lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2,
.lpm_residency_offset = MTL_LPM_RESIDENCY_OFFSET,
- .lpm_reg_index = MTL_LPM_REG_INDEX,
-};
-
-#define PMC_DEVID_SOCM 0x7e7f
-#define PMC_DEVID_IOEP 0x7ecf
-#define PMC_DEVID_IOEM 0x7ebf
-static struct pmc_info mtl_pmc_info_list[] = {
- {
- .guid = SOCP_LPM_REQ_GUID,
- .devid = PMC_DEVID_SOCM,
- .map = &mtl_socm_reg_map,
- },
- {
- .guid = IOEP_LPM_REQ_GUID,
- .devid = PMC_DEVID_IOEP,
- .map = &mtl_ioep_reg_map,
- },
- {
- .guid = IOEM_LPM_REQ_GUID,
- .devid = PMC_DEVID_IOEM,
- .map = &mtl_ioem_reg_map
- },
- {}
};
#define MTL_GNA_PCI_DEV 0x7e4c
@@ -995,35 +962,19 @@ int mtl_core_init(struct pmc_dev *pmcdev)
{
struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC];
int ret;
- int func = 2;
- bool ssram_init = true;
mtl_d3_fixup();
pmcdev->suspend = cnl_suspend;
pmcdev->resume = mtl_resume;
- pmcdev->regmap_list = mtl_pmc_info_list;
-
- /*
- * If ssram init fails use legacy method to at least get the
- * primary PMC
- */
- ret = pmc_core_ssram_init(pmcdev, func);
- if (ret) {
- ssram_init = false;
- dev_warn(&pmcdev->pdev->dev,
- "ssram init failed, %d, using legacy init\n", ret);
- pmc->map = &mtl_socm_reg_map;
- ret = get_primary_reg_base(pmc);
- if (ret)
- return ret;
- }
+
+ pmc->map = &mtl_socm_reg_map;
+ ret = get_primary_reg_base(pmc);
+ if (ret)
+ return ret;
pmc_core_get_low_power_modes(pmcdev);
pmc_core_punit_pmt_init(pmcdev, MTL_PMT_DMU_GUID);
- if (ssram_init)
- return pmc_core_ssram_get_lpm_reqs(pmcdev);
-
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 2/7] platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver
2024-08-09 20:46 [PATCH 0/7] Create Intel PMC SSRAM Telemetry driver Xi Pardee
2024-08-09 20:46 ` [PATCH 1/7] platform/x86:intel/pmc: Remove SSRAM support from PMC Core Xi Pardee
@ 2024-08-09 20:46 ` Xi Pardee
2024-08-09 20:46 ` [PATCH 3/7] platform/x86:intel/pmc: Add support to get PMC information from SSRAM Xi Pardee
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Xi Pardee @ 2024-08-09 20:46 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel
From: Xi Pardee <xi.pardee@intel.com>
Create Intel PMC SSRAM Telemetry driver for SSRAM device. The driver binds
to 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@intel.com>
---
drivers/platform/x86/intel/pmc/Kconfig | 10 +
drivers/platform/x86/intel/pmc/Makefile | 4 +
drivers/platform/x86/intel/pmc/core.h | 10 +
.../platform/x86/intel/pmc/ssram_telemetry.c | 184 ++++++++++++++++++
.../platform/x86/intel/pmc/ssram_telemetry.h | 45 +++++
5 files changed, 253 insertions(+)
create mode 100644 drivers/platform/x86/intel/pmc/ssram_telemetry.c
create mode 100644 drivers/platform/x86/intel/pmc/ssram_telemetry.h
diff --git a/drivers/platform/x86/intel/pmc/Kconfig b/drivers/platform/x86/intel/pmc/Kconfig
index d2f651fbec2c..fe33348cd7e2 100644
--- a/drivers/platform/x86/intel/pmc/Kconfig
+++ b/drivers/platform/x86/intel/pmc/Kconfig
@@ -24,3 +24,13 @@ config INTEL_PMC_CORE
- SLPS0 Debug registers (Cannonlake/Icelake PCH)
- Low Power Mode registers (Tigerlake and beyond)
- PMC quirks as needed to enable SLPS0/S0ix
+
+config INTEL_PMC_SSRAM_TELEMETRY
+ tristate "Intel PMC SSRAM Telemetry driver"
+ depends on INTEL_VSEC
+ help
+ The PMC SSRAM device contains counters structured in Intel Platform
+ Monitoring Techology (PMT) telemetry regions. This driver looks for
+ and register these telemetry regions so they would be available for
+ read through sysfs and Intel PMT API. The driver also provides API to
+ expose information of PMCs available in the platform.
diff --git a/drivers/platform/x86/intel/pmc/Makefile b/drivers/platform/x86/intel/pmc/Makefile
index 6b682be0ec5a..8352c6d66f2b 100644
--- a/drivers/platform/x86/intel/pmc/Makefile
+++ b/drivers/platform/x86/intel/pmc/Makefile
@@ -8,3 +8,7 @@ intel_pmc_core-y := core.o spt.o cnp.o icl.o \
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o
intel_pmc_core_pltdrv-y := pltdrv.o
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core_pltdrv.o
+
+# Intel PMC SSRAM driver
+intel_pmc_ssram_telemetry-y += ssram_telemetry.o
+obj-$(CONFIG_INTEL_PMC_SSRAM_TELEMETRY) += intel_pmc_ssram_telemetry.o
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index b0c66df8cd98..1e5726745394 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -285,6 +285,16 @@ enum ppfear_regs {
#define LNL_PPFEAR_NUM_ENTRIES 12
#define LNL_S0IX_BLOCKER_OFFSET 0x2004
+/* SSRAM PMC Device ID*/
+/* ARL */
+#define PMC_DEVID_ARL_SOCS 0xae7f
+
+/* MTL */
+#define PMC_DEVID_MTL_SOCM 0x7e7f
+
+/* LNL */
+#define PMC_DEVID_LNL_SOCM 0xa87f
+
extern const char *pmc_lpm_modes[];
struct pmc_bit_map {
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
new file mode 100644
index 000000000000..25f6e07c15be
--- /dev/null
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel PMC SSRAM TELEMETRY PCI Driver
+ *
+ * Copyright (c) 2024, Intel Corporation.
+ * All Rights Reserved.
+ *
+ */
+
+#include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+
+#include "../vsec.h"
+#include "core.h"
+#include "ssram_telemetry.h"
+
+#define SSRAM_HDR_SIZE 0x100
+#define SSRAM_PWRM_OFFSET 0x14
+#define SSRAM_DVSEC_OFFSET 0x1C
+#define SSRAM_DVSEC_SIZE 0x10
+#define SSRAM_PCH_OFFSET 0x60
+#define SSRAM_IOE_OFFSET 0x68
+#define SSRAM_DEVID_OFFSET 0x70
+
+static struct pmc_ssram_telemetry *pmc_ssram_telems;
+static bool device_probed;
+
+DEFINE_FREE(pmc_ssram_telemetry_iounmap, void __iomem *, iounmap(_T));
+
+static void pmc_ssram_telemetry_add_pmt(struct pci_dev *pdev, u64 ssram_base, void __iomem *ssram)
+{
+ struct intel_vsec_platform_info info = {};
+ struct intel_vsec_header *headers[2] = {};
+ struct intel_vsec_header header;
+ void __iomem *dvsec;
+ u32 dvsec_offset;
+ u32 table, hdr;
+
+ dvsec_offset = readl(ssram + SSRAM_DVSEC_OFFSET);
+ dvsec = ioremap(ssram_base + dvsec_offset, SSRAM_DVSEC_SIZE);
+ if (!dvsec)
+ return;
+
+ hdr = readl(dvsec + PCI_DVSEC_HEADER1);
+ header.id = readw(dvsec + PCI_DVSEC_HEADER2);
+ header.rev = PCI_DVSEC_HEADER1_REV(hdr);
+ header.length = PCI_DVSEC_HEADER1_LEN(hdr);
+ header.num_entries = readb(dvsec + INTEL_DVSEC_ENTRIES);
+ header.entry_size = readb(dvsec + INTEL_DVSEC_SIZE);
+
+ table = readl(dvsec + INTEL_DVSEC_TABLE);
+ header.tbir = INTEL_DVSEC_TABLE_BAR(table);
+ header.offset = INTEL_DVSEC_TABLE_OFFSET(table);
+ iounmap(dvsec);
+
+ headers[0] = &header;
+ info.caps = VSEC_CAP_TELEMETRY;
+ info.headers = headers;
+ info.base_addr = ssram_base;
+ info.parent = &pdev->dev;
+
+ intel_vsec_register(pdev, &info);
+}
+
+static inline u64 get_base(void __iomem *addr, u32 offset)
+{
+ return lo_hi_readq(addr + offset) & GENMASK_ULL(63, 3);
+}
+
+static int pmc_ssram_telemetry_get_pmc(struct pci_dev *pdev, unsigned int pmc_idx, u32 offset)
+{
+ void __iomem __free(pmc_ssram_telemetry_iounmap) * tmp_ssram = NULL;
+ void __iomem __free(pmc_ssram_telemetry_iounmap) * ssram = NULL;
+ u64 ssram_base, pwrm_base;
+ u16 devid;
+
+ ssram_base = pdev->resource[0].start;
+ tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
+
+ if (!tmp_ssram)
+ return -ENOMEM;
+
+ if (pmc_idx != PMC_IDX_MAIN) {
+ /*
+ * The secondary PMC BARS (which are behind hidden PCI devices)
+ * are read from fixed offsets in MMIO of the primary PMC BAR.
+ */
+ ssram_base = get_base(tmp_ssram, offset);
+ if (!ssram_base)
+ return -ENODEV;
+
+ ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
+ if (!ssram)
+ return -ENOMEM;
+ } else
+ ssram = no_free_ptr(tmp_ssram);
+
+ /* Find and register and PMC telemetry entries */
+ pmc_ssram_telemetry_add_pmt(pdev, ssram_base, ssram);
+
+ pwrm_base = get_base(ssram, SSRAM_PWRM_OFFSET);
+ if (!pwrm_base)
+ return -ENODEV;
+ devid = readw(ssram + SSRAM_DEVID_OFFSET);
+
+ pmc_ssram_telems[pmc_idx].devid = devid;
+ pmc_ssram_telems[pmc_idx].base_addr = pwrm_base;
+
+ return 0;
+}
+
+int pmc_ssram_telemetry_get_pmc_info(unsigned int pmc_idx,
+ struct pmc_ssram_telemetry *pmc_ssram_telemetry)
+{
+ /*
+ * PMCs are discovered in probe function. If this function is called before
+ * probe function complete, the result would be invalid. Use device_probed
+ * variable to avoid this case. Return -EAGAIN to inform the user to call
+ * again later.
+ */
+ if (!device_probed)
+ return -EAGAIN;
+
+ if (pmc_idx >= MAX_NUM_PMC)
+ return -EINVAL;
+
+ if (!pmc_ssram_telems || !pmc_ssram_telems[pmc_idx].devid)
+ return -ENODEV;
+
+ pmc_ssram_telemetry->devid = pmc_ssram_telems[pmc_idx].devid;
+ pmc_ssram_telemetry->base_addr = pmc_ssram_telems[pmc_idx].base_addr;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pmc_ssram_telemetry_get_pmc_info);
+
+static int intel_pmc_ssram_telemetry_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ int ret;
+
+ pmc_ssram_telems = devm_kzalloc(&pdev->dev, sizeof(*pmc_ssram_telems) * MAX_NUM_PMC,
+ GFP_KERNEL);
+ if (!pmc_ssram_telems) {
+ ret = -ENOMEM;
+ goto probe_finish;
+ }
+
+ ret = pcim_enable_device(pdev);
+ if (ret) {
+ dev_dbg(&pdev->dev, "failed to enable PMC SSRAM device\n");
+ goto probe_finish;
+ }
+
+ ret = pmc_ssram_telemetry_get_pmc(pdev, PMC_IDX_MAIN, 0);
+ if (ret)
+ goto probe_finish;
+
+ pmc_ssram_telemetry_get_pmc(pdev, PMC_IDX_IOE, SSRAM_IOE_OFFSET);
+ pmc_ssram_telemetry_get_pmc(pdev, PMC_IDX_PCH, SSRAM_PCH_OFFSET);
+
+probe_finish:
+ device_probed = true;
+ return ret;
+}
+
+static const struct pci_device_id intel_pmc_ssram_telemetry_pci_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_MTL_SOCM) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_LNL_SOCM) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCS) },
+ { }
+};
+MODULE_DEVICE_TABLE(pci, intel_pmc_ssram_telemetry_pci_ids);
+
+static struct pci_driver intel_pmc_ssram_telemetry_driver = {
+ .name = "intel_pmc_ssram_telemetry",
+ .id_table = intel_pmc_ssram_telemetry_pci_ids,
+ .probe = intel_pmc_ssram_telemetry_probe,
+};
+module_pci_driver(intel_pmc_ssram_telemetry_driver);
+
+MODULE_IMPORT_NS(INTEL_VSEC);
+MODULE_AUTHOR("Xi Pardee <xi.pardee@intel.com>");
+MODULE_DESCRIPTION("Intel PMC SSRAM TELEMETRY driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.h b/drivers/platform/x86/intel/pmc/ssram_telemetry.h
new file mode 100644
index 000000000000..938d0baf50be
--- /dev/null
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Intel PMC SSRAM TELEMETRY PCI Driver Header File
+ *
+ * Copyright (c) 2024, Intel Corporation.
+ * All Rights Reserved.
+ *
+ */
+
+#ifndef PMC_SSRAM_H
+#define PMC_SSRAM_H
+
+/**
+ * struct pmc_ssram_telemetry - Structure to keep pmc info in ssram device
+ * @devid: device id of the pmc device
+ * @base_addr: contains PWRM base address
+ */
+struct pmc_ssram_telemetry {
+ u16 devid;
+ u64 base_addr;
+};
+
+#if IS_REACHABLE(CONFIG_INTEL_PMC_SSRAM_TELEMETRY)
+/**
+ * pmc_ssram_telemetry_get_pmc_info() - Get a PMC devid and base_addr information
+ * @pmc_idx: Index of the PMC
+ * @pmc_ssram_telemetry: pmc_ssram_telemetry structure to store the PMC information
+ *
+ * Return:
+ * * 0 - Success
+ * * -EAGAIN - Probe function has not finished yet. Try again.
+ * * -EINVAL - Invalid pmc_idx
+ * * -ENODEV - PMC device is not available
+ */
+int pmc_ssram_telemetry_get_pmc_info(unsigned int pmc_idx,
+ struct pmc_ssram_telemetry *pmc_ssram_telemetry);
+#else /* !CONFIG_INTEL_PMC_SSRAM_TELEMETRY */
+static inline int pmc_ssram_telemetry_get_pmc_info(int pmc_idx,
+ struct pmc_ssram_telemetry *pmc_ssram_telemetry)
+{
+ return -ENODEV;
+}
+#endif /* CONFIG_INTEL_PMC_SSRAM_TELEMETRY */
+
+#endif /* PMC_SSRAM_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 3/7] platform/x86:intel/pmc: Add support to get PMC information from SSRAM
2024-08-09 20:46 [PATCH 0/7] Create Intel PMC SSRAM Telemetry driver Xi Pardee
2024-08-09 20:46 ` [PATCH 1/7] platform/x86:intel/pmc: Remove SSRAM support from PMC Core Xi Pardee
2024-08-09 20:46 ` [PATCH 2/7] platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver Xi Pardee
@ 2024-08-09 20:46 ` Xi Pardee
2024-08-09 20:46 ` [PATCH 4/7] platform/x86:intel/pmt: Get PMC from SSRAM for available platforms Xi Pardee
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Xi Pardee @ 2024-08-09 20:46 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel
PWRMBASE address and devid for PMCs are available through API of
Intel PMC SSRAM Telemetry driver. Add support to discover and achieve
the information for each available PMC. Use PMC devid to find and
assign the corresponding register map.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/Kconfig | 1 +
drivers/platform/x86/intel/pmc/core.c | 64 ++++++++++++++++++++++++++
drivers/platform/x86/intel/pmc/core.h | 1 +
3 files changed, 66 insertions(+)
diff --git a/drivers/platform/x86/intel/pmc/Kconfig b/drivers/platform/x86/intel/pmc/Kconfig
index fe33348cd7e2..56c6d3650bf7 100644
--- a/drivers/platform/x86/intel/pmc/Kconfig
+++ b/drivers/platform/x86/intel/pmc/Kconfig
@@ -7,6 +7,7 @@ config INTEL_PMC_CORE
tristate "Intel PMC Core driver"
depends on PCI
depends on ACPI
+ depends on INTEL_PMC_SSRAM_TELEMETRY || !INTEL_PMC_SSRAM_TELEMETRY
depends on INTEL_PMT_TELEMETRY
help
The Intel Platform Controller Hub for Intel Core SoCs provides access
diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
index 5ecf55176734..634b4d939ed2 100644
--- a/drivers/platform/x86/intel/pmc/core.c
+++ b/drivers/platform/x86/intel/pmc/core.c
@@ -28,6 +28,7 @@
#include <asm/tsc.h>
#include "core.h"
+#include "ssram_telemetry.h"
#include "../pmt/telemetry.h"
/* Maximum number of modes supported by platfoms that has low power mode capability */
@@ -1146,6 +1147,69 @@ int get_primary_reg_base(struct pmc *pmc)
return 0;
}
+static const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
+{
+ for (; list->map; ++list)
+ if (devid == list->devid)
+ return list->map;
+
+ return NULL;
+}
+
+static int pmc_core_ssram_pmc_add(struct pmc_dev *pmcdev, int pmc_idx)
+{
+ const struct pmc_reg_map *map;
+ struct pmc_ssram_telemetry pmc_ssram_telemetry;
+ struct pmc *pmc;
+ int ret;
+
+ ret = pmc_ssram_telemetry_get_pmc_info(pmc_idx, &pmc_ssram_telemetry);
+ if (ret)
+ return ret;
+
+ map = pmc_core_find_regmap(pmcdev->regmap_list, pmc_ssram_telemetry.devid);
+ if (!map)
+ return -ENODEV;
+
+ pmc = pmcdev->pmcs[pmc_idx];
+ /* Memory for primary PMC has been allocated in core.c */
+ if (!pmc) {
+ pmc = devm_kzalloc(&pmcdev->pdev->dev, sizeof(*pmc), GFP_KERNEL);
+ if (!pmc)
+ return -ENOMEM;
+ }
+
+ pmc->map = map;
+ pmc->base_addr = pmc_ssram_telemetry.base_addr;
+ pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length);
+
+ if (!pmc->regbase) {
+ devm_kfree(&pmcdev->pdev->dev, pmc);
+ return -ENOMEM;
+ }
+
+ pmcdev->pmcs[pmc_idx] = pmc;
+
+ return 0;
+}
+
+int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev)
+{
+ int ret;
+
+ if (!pmcdev->regmap_list)
+ return -ENOENT;
+
+ ret = pmc_core_ssram_pmc_add(pmcdev, PMC_IDX_MAIN);
+ if (ret)
+ return ret;
+
+ pmc_core_ssram_pmc_add(pmcdev, PMC_IDX_IOE);
+ pmc_core_ssram_pmc_add(pmcdev, PMC_IDX_PCH);
+
+ return 0;
+}
+
void pmc_core_punit_pmt_init(struct pmc_dev *pmcdev, u32 guid)
{
struct telem_endpoint *ep;
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index 1e5726745394..890caf558307 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -591,6 +591,7 @@ int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value, int ignore);
int pmc_core_resume_common(struct pmc_dev *pmcdev);
int get_primary_reg_base(struct pmc *pmc);
+extern int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev);
extern void pmc_core_get_low_power_modes(struct pmc_dev *pmcdev);
extern void pmc_core_punit_pmt_init(struct pmc_dev *pmcdev, u32 guid);
extern void pmc_core_set_device_d3(unsigned int device);
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 4/7] platform/x86:intel/pmt: Get PMC from SSRAM for available platforms
2024-08-09 20:46 [PATCH 0/7] Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (2 preceding siblings ...)
2024-08-09 20:46 ` [PATCH 3/7] platform/x86:intel/pmc: Add support to get PMC information from SSRAM Xi Pardee
@ 2024-08-09 20:46 ` Xi Pardee
2024-08-09 20:46 ` [PATCH 5/7] platform/x86:intel/pmt: Create inline version for telemetry functions Xi Pardee
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Xi Pardee @ 2024-08-09 20:46 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel
Add support to discover and achieve PMC information from Intel
SSRAM Telemetry driver for Meteor Lake, Lunar Lake and Arror Lake
platforms.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/arl.c | 34 +++++++++++++++++++++++----
drivers/platform/x86/intel/pmc/core.h | 3 +++
drivers/platform/x86/intel/pmc/lnl.c | 26 ++++++++++++++++----
drivers/platform/x86/intel/pmc/mtl.c | 34 +++++++++++++++++++++++----
4 files changed, 85 insertions(+), 12 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c
index 4b824612f355..7a340b8c7b6a 100644
--- a/drivers/platform/x86/intel/pmc/arl.c
+++ b/drivers/platform/x86/intel/pmc/arl.c
@@ -640,6 +640,22 @@ const struct pmc_reg_map arl_pchs_reg_map = {
.etr3_offset = ETR3_OFFSET,
};
+static struct pmc_info arl_pmc_info_list[] = {
+ {
+ .devid = PMC_DEVID_MTL_IOEP,
+ .map = &mtl_ioep_reg_map,
+ },
+ {
+ .devid = PMC_DEVID_ARL_SOCS,
+ .map = &arl_socs_reg_map,
+ },
+ {
+ .devid = PMC_DEVID_ARL_PCHS,
+ .map = &arl_pchs_reg_map,
+ },
+ {}
+};
+
#define ARL_NPU_PCI_DEV 0xad1d
#define ARL_GNA_PCI_DEV 0xae4c
/*
@@ -669,10 +685,20 @@ int arl_core_init(struct pmc_dev *pmcdev)
pmcdev->suspend = cnl_suspend;
pmcdev->resume = arl_resume;
- pmc->map = &arl_socs_reg_map;
- ret = get_primary_reg_base(pmc);
- if (ret)
- return ret;
+ pmcdev->regmap_list = arl_pmc_info_list;
+ ret = pmc_core_ssram_get_reg_base(pmcdev);
+
+ /* Try again later after Intel PMC SSRAM Telemetry driver finishes probe */
+ if (ret == -EAGAIN)
+ return -EPROBE_DEFER;
+
+ /* If regbase not assigned, set map and discover using legacy method */
+ if (ret) {
+ pmc->map = &arl_socs_reg_map;
+ ret = get_primary_reg_base(pmc);
+ if (ret)
+ return ret;
+ }
pmc_core_get_low_power_modes(pmcdev);
pmc_core_punit_pmt_init(pmcdev, ARL_PMT_DMU_GUID);
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index 890caf558307..07f8c3070ab9 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -288,9 +288,12 @@ enum ppfear_regs {
/* SSRAM PMC Device ID*/
/* ARL */
#define PMC_DEVID_ARL_SOCS 0xae7f
+#define PMC_DEVID_ARL_PCHS 0x7f27
/* MTL */
#define PMC_DEVID_MTL_SOCM 0x7e7f
+#define PMC_DEVID_MTL_IOEP 0x7ecf
+#define PMC_DEVID_MTL_IOEM 0x7ebf
/* LNL */
#define PMC_DEVID_LNL_SOCM 0xa87f
diff --git a/drivers/platform/x86/intel/pmc/lnl.c b/drivers/platform/x86/intel/pmc/lnl.c
index e7a8077d1a3e..109b08d43fc8 100644
--- a/drivers/platform/x86/intel/pmc/lnl.c
+++ b/drivers/platform/x86/intel/pmc/lnl.c
@@ -13,6 +13,14 @@
#include "core.h"
+static struct pmc_info lnl_pmc_info_list[] = {
+ {
+ .devid = PMC_DEVID_LNL_SOCM,
+ .map = &lnl_socm_reg_map,
+ },
+ {}
+};
+
const struct pmc_bit_map lnl_ltr_show_map[] = {
{"SOUTHPORT_A", CNP_PMC_LTR_SPA},
{"SOUTHPORT_B", CNP_PMC_LTR_SPB},
@@ -561,10 +569,20 @@ int lnl_core_init(struct pmc_dev *pmcdev)
pmcdev->suspend = cnl_suspend;
pmcdev->resume = lnl_resume;
- pmc->map = &lnl_socm_reg_map;
- ret = get_primary_reg_base(pmc);
- if (ret)
- return ret;
+ pmcdev->regmap_list = lnl_pmc_info_list;
+ ret = pmc_core_ssram_get_reg_base(pmcdev);
+
+ /* Try again later after Intel PMC SSRAM Telemetry driver finishes probe */
+ if (ret == -EAGAIN)
+ return -EPROBE_DEFER;
+
+ /* If regbase not assigned, set map and discover using legacy method */
+ if (ret) {
+ pmc->map = &lnl_socm_reg_map;
+ ret = get_primary_reg_base(pmc);
+ if (ret)
+ return ret;
+ }
pmc_core_get_low_power_modes(pmcdev);
diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
index 0b9efab21d60..86f8c2a24825 100644
--- a/drivers/platform/x86/intel/pmc/mtl.c
+++ b/drivers/platform/x86/intel/pmc/mtl.c
@@ -936,6 +936,22 @@ const struct pmc_reg_map mtl_ioem_reg_map = {
.lpm_residency_offset = MTL_LPM_RESIDENCY_OFFSET,
};
+static struct pmc_info mtl_pmc_info_list[] = {
+ {
+ .devid = PMC_DEVID_MTL_SOCM,
+ .map = &mtl_socm_reg_map,
+ },
+ {
+ .devid = PMC_DEVID_MTL_IOEP,
+ .map = &mtl_ioep_reg_map,
+ },
+ {
+ .devid = PMC_DEVID_MTL_IOEM,
+ .map = &mtl_ioem_reg_map
+ },
+ {}
+};
+
#define MTL_GNA_PCI_DEV 0x7e4c
#define MTL_IPU_PCI_DEV 0x7d19
#define MTL_VPU_PCI_DEV 0x7d1d
@@ -968,10 +984,20 @@ int mtl_core_init(struct pmc_dev *pmcdev)
pmcdev->suspend = cnl_suspend;
pmcdev->resume = mtl_resume;
- pmc->map = &mtl_socm_reg_map;
- ret = get_primary_reg_base(pmc);
- if (ret)
- return ret;
+ pmcdev->regmap_list = mtl_pmc_info_list;
+ ret = pmc_core_ssram_get_reg_base(pmcdev);
+
+ /* Try again later after Intel PMC SSRAM Telemetry driver finishes probe */
+ if (ret == -EAGAIN)
+ return -EPROBE_DEFER;
+
+ /* If regbase not assigned, set map and discover using legacy method */
+ if (ret) {
+ pmc->map = &mtl_socm_reg_map;
+ ret = get_primary_reg_base(pmc);
+ if (ret)
+ return ret;
+ }
pmc_core_get_low_power_modes(pmcdev);
pmc_core_punit_pmt_init(pmcdev, MTL_PMT_DMU_GUID);
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 5/7] platform/x86:intel/pmt: Create inline version for telemetry functions
2024-08-09 20:46 [PATCH 0/7] Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (3 preceding siblings ...)
2024-08-09 20:46 ` [PATCH 4/7] platform/x86:intel/pmt: Get PMC from SSRAM for available platforms Xi Pardee
@ 2024-08-09 20:46 ` Xi Pardee
2024-08-09 20:46 ` [PATCH 6/7] platform/x86:intel/pmc: Add support to Retrieve LPM information Xi Pardee
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Xi Pardee @ 2024-08-09 20:46 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel
Create inline versions of functions in Intel PMT Telemetry driver when
config option is not set. Drivers that imports the INTEL_PMT_TELEMETRY
namespace could compile when CONFIG_INTEL_PMT_TELEMETRY option is not set.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmt/telemetry.h | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/platform/x86/intel/pmt/telemetry.h b/drivers/platform/x86/intel/pmt/telemetry.h
index d45af5512b4e..6798a900042a 100644
--- a/drivers/platform/x86/intel/pmt/telemetry.h
+++ b/drivers/platform/x86/intel/pmt/telemetry.h
@@ -21,6 +21,7 @@ struct telem_endpoint_info {
struct telem_header header;
};
+#if IS_REACHABLE(CONFIG_INTEL_PMT_TELEMETRY)
/**
* pmt_telem_get_next_endpoint() - Get next device id for a telemetry endpoint
* @start: starting devid to look from
@@ -123,4 +124,20 @@ int pmt_telem_read(struct telem_endpoint *ep, u32 id, u64 *data, u32 count);
*/
int pmt_telem_read32(struct telem_endpoint *ep, u32 id, u32 *data, u32 count);
-#endif
+#else /* !CONFIG_INTEL_PMT_TELEMETRY */
+static inline unsigned long pmt_telem_get_next_endpoint(unsigned long start) { return 0; }
+static inline struct telem_endpoint *pmt_telem_register_endpoint(int devid)
+{ return ERR_PTR(-ENODEV); }
+static inline void pmt_telem_unregister_endpoint(struct telem_endpoint *ep) {}
+static inline int pmt_telem_get_endpoint_info(int devid, struct telem_endpoint_info *info)
+{ return -ENODEV; }
+static inline struct telem_endpoint *pmt_telem_find_and_register_endpoint(struct pci_dev *pcidev,
+ u32 guid, u16 pos)
+{ return ERR_PTR(-ENODEV); }
+static inline int pmt_telem_read(struct telem_endpoint *ep, u32 id, u64 *data, u32 count)
+{ return -ENODEV; }
+static inline int pmt_telem_read32(struct telem_endpoint *ep, u32 id, u32 *data, u32 count)
+{ return -ENODEV; }
+#endif /* CONFIG_INTEL_PMT_TELEMETRY */
+
+#endif /* _TELEMETRY_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 6/7] platform/x86:intel/pmc: Add support to Retrieve LPM information
2024-08-09 20:46 [PATCH 0/7] Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (4 preceding siblings ...)
2024-08-09 20:46 ` [PATCH 5/7] platform/x86:intel/pmt: Create inline version for telemetry functions Xi Pardee
@ 2024-08-09 20:46 ` Xi Pardee
2024-08-09 20:46 ` [PATCH 7/7] platform/x86:intel/pmc: Get LPM information for available platforms Xi Pardee
2024-08-13 16:01 ` [PATCH 0/7] Create Intel PMC SSRAM Telemetry driver Ilpo Järvinen
7 siblings, 0 replies; 10+ messages in thread
From: Xi Pardee @ 2024-08-09 20:46 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel
On supported platforms, the low power mode (LPM) requirements for entering
each idle substate are described in Platform Monitoring Technology (PMT)
telemetry entries. Add support to find and read the requirements from the
telemetry entries.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/Kconfig | 2 +-
drivers/platform/x86/intel/pmc/core.c | 146 +++++++++++++++++++++++++
drivers/platform/x86/intel/pmc/core.h | 6 +
3 files changed, 153 insertions(+), 1 deletion(-)
diff --git a/drivers/platform/x86/intel/pmc/Kconfig b/drivers/platform/x86/intel/pmc/Kconfig
index 56c6d3650bf7..b77f1fb84b4d 100644
--- a/drivers/platform/x86/intel/pmc/Kconfig
+++ b/drivers/platform/x86/intel/pmc/Kconfig
@@ -8,7 +8,7 @@ config INTEL_PMC_CORE
depends on PCI
depends on ACPI
depends on INTEL_PMC_SSRAM_TELEMETRY || !INTEL_PMC_SSRAM_TELEMETRY
- depends on INTEL_PMT_TELEMETRY
+ depends on INTEL_PMT_TELEMETRY || !INTEL_PMT_TELEMETRY
help
The Intel Platform Controller Hub for Intel Core SoCs provides access
to Power Management Controller registers via various interfaces. This
diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
index 634b4d939ed2..379676d08136 100644
--- a/drivers/platform/x86/intel/pmc/core.c
+++ b/drivers/platform/x86/intel/pmc/core.c
@@ -785,6 +785,152 @@ static int pmc_core_substate_l_sts_regs_show(struct seq_file *s, void *unused)
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_l_sts_regs);
+static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *map)
+{
+ for (; list->map; ++list)
+ if (list->map == map)
+ return list->guid;
+
+ return 0;
+}
+
+static int pmc_core_pmt_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc, int func)
+{
+ struct telem_endpoint *ep;
+ const u8 *lpm_indices;
+ int num_maps, mode_offset = 0;
+ struct pci_dev *pcidev;
+ int ret, mode, i;
+ int lpm_size;
+ u32 guid;
+
+ lpm_indices = pmc->map->lpm_reg_index;
+ num_maps = pmc->map->lpm_num_maps;
+ lpm_size = LPM_MAX_NUM_MODES * num_maps;
+
+ guid = pmc_core_find_guid(pmcdev->regmap_list, pmc->map);
+ if (!guid)
+ return -ENXIO;
+
+ pcidev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(20, func));
+ if (!pcidev)
+ return -ENODEV;
+
+ ep = pmt_telem_find_and_register_endpoint(pcidev, guid, 0);
+ if (IS_ERR(ep)) {
+ dev_dbg(&pmcdev->pdev->dev, "couldn't get telem endpoint %ld",
+ PTR_ERR(ep));
+ ret = -EPROBE_DEFER;
+ goto release_dev;
+ }
+
+ pmc->lpm_req_regs = devm_kzalloc(&pmcdev->pdev->dev,
+ lpm_size * sizeof(u32),
+ GFP_KERNEL);
+ if (!pmc->lpm_req_regs) {
+ ret = -ENOMEM;
+ goto unregister_ep;
+ }
+
+ /*
+ * PMC Low Power Mode (LPM) table
+ *
+ * In telemetry space, the LPM table contains a 4 byte header followed
+ * by 8 consecutive mode blocks (one for each LPM mode). Each block
+ * has a 4 byte header followed by a set of registers that describe the
+ * IP state requirements for the given mode. The IP mapping is platform
+ * specific but the same for each block, making for easy analysis.
+ * Platforms only use a subset of the space to track the requirements
+ * for their IPs. Callers provide the requirement registers they use as
+ * a list of indices. Each requirement register is associated with an
+ * IP map that's maintained by the caller.
+ *
+ * Header
+ * +----+----------------------------+----------------------------+
+ * | 0 | REVISION | ENABLED MODES |
+ * +----+--------------+-------------+-------------+--------------+
+ *
+ * Low Power Mode 0 Block
+ * +----+--------------+-------------+-------------+--------------+
+ * | 1 | SUB ID | SIZE | MAJOR | MINOR |
+ * +----+--------------+-------------+-------------+--------------+
+ * | 2 | LPM0 Requirements 0 |
+ * +----+---------------------------------------------------------+
+ * | | ... |
+ * +----+---------------------------------------------------------+
+ * | 29 | LPM0 Requirements 27 |
+ * +----+---------------------------------------------------------+
+ *
+ * ...
+ *
+ * Low Power Mode 7 Block
+ * +----+--------------+-------------+-------------+--------------+
+ * | | SUB ID | SIZE | MAJOR | MINOR |
+ * +----+--------------+-------------+-------------+--------------+
+ * | 60 | LPM7 Requirements 0 |
+ * +----+---------------------------------------------------------+
+ * | | ... |
+ * +----+---------------------------------------------------------+
+ * | 87 | LPM7 Requirements 27 |
+ * +----+---------------------------------------------------------+
+ *
+ */
+ mode_offset = LPM_HEADER_OFFSET + LPM_MODE_OFFSET;
+ pmc_for_each_mode(i, mode, pmcdev) {
+ u32 *req_offset = pmc->lpm_req_regs + (mode * num_maps);
+ int m;
+
+ for (m = 0; m < num_maps; m++) {
+ u8 sample_id = lpm_indices[m] + mode_offset;
+
+ ret = pmt_telem_read32(ep, sample_id, req_offset, 1);
+ if (ret) {
+ dev_err(&pmcdev->pdev->dev,
+ "couldn't read Low Power Mode requirements: %d\n", ret);
+ devm_kfree(&pmcdev->pdev->dev, pmc->lpm_req_regs);
+ pmc->lpm_req_regs = NULL;
+ goto unregister_ep;
+ }
+ ++req_offset;
+ }
+ mode_offset += LPM_REG_COUNT + LPM_MODE_OFFSET;
+ }
+
+unregister_ep:
+ pmt_telem_unregister_endpoint(ep);
+release_dev:
+ pci_dev_put(pcidev);
+
+ return ret;
+}
+
+int pmc_core_get_lpm_reqs(struct pmc_dev *pmcdev, int func)
+{
+ unsigned int i;
+ int ret;
+
+ if (!IS_REACHABLE(CONFIG_INTEL_PMC_SSRAM_TELEMETRY)) {
+ dev_dbg(&pmcdev->pdev->dev, "INTEL PMC SSRAM device driver is not reachable");
+ return 0;
+ }
+
+ if (!IS_REACHABLE(CONFIG_INTEL_PMT_TELEMETRY)) {
+ dev_dbg(&pmcdev->pdev->dev, "INTEL PMT TELEMETRY driver is not reachable");
+ return 0;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(pmcdev->pmcs); ++i) {
+ if (!pmcdev->pmcs[i])
+ continue;
+
+ ret = pmc_core_pmt_get_lpm_req(pmcdev, pmcdev->pmcs[i], func);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static void pmc_core_substate_req_header_show(struct seq_file *s, int pmc_index)
{
struct pmc_dev *pmcdev = s->private;
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index 07f8c3070ab9..3dc640405590 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -24,6 +24,11 @@ struct telem_endpoint;
#define MAX_NUM_PMC 3
#define S0IX_BLK_SIZE 4
+/* PCH query */
+#define LPM_HEADER_OFFSET 1
+#define LPM_REG_COUNT 28
+#define LPM_MODE_OFFSET 1
+
/* Sunrise Point Power Management Controller PCI Device ID */
#define SPT_PMC_PCI_DEVICE_ID 0x9d21
#define SPT_PMC_BASE_ADDR_OFFSET 0x48
@@ -590,6 +595,7 @@ extern const struct pmc_bit_map *arl_pchs_lpm_maps[];
extern const struct pmc_reg_map arl_pchs_reg_map;
extern void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev);
+extern int pmc_core_get_lpm_reqs(struct pmc_dev *pmcdev, int func);
int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value, int ignore);
int pmc_core_resume_common(struct pmc_dev *pmcdev);
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 7/7] platform/x86:intel/pmc: Get LPM information for available platforms
2024-08-09 20:46 [PATCH 0/7] Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (5 preceding siblings ...)
2024-08-09 20:46 ` [PATCH 6/7] platform/x86:intel/pmc: Add support to Retrieve LPM information Xi Pardee
@ 2024-08-09 20:46 ` Xi Pardee
2024-08-13 16:01 ` [PATCH 0/7] Create Intel PMC SSRAM Telemetry driver Ilpo Järvinen
7 siblings, 0 replies; 10+ messages in thread
From: Xi Pardee @ 2024-08-09 20:46 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel
Add support to find and read the requirements from the telemetry
entries for Meteor Lake, Lunar Lake and Arror Lake platforms.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/arl.c | 16 ++++++++++++++--
drivers/platform/x86/intel/pmc/lnl.c | 10 ++++++++--
drivers/platform/x86/intel/pmc/mtl.c | 17 +++++++++++++++--
3 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c
index 7a340b8c7b6a..0db16deacf85 100644
--- a/drivers/platform/x86/intel/pmc/arl.c
+++ b/drivers/platform/x86/intel/pmc/arl.c
@@ -11,6 +11,13 @@
#include <linux/pci.h>
#include "core.h"
+/* PMC SSRAM PMT Telemetry GUID */
+#define IOEP_LPM_REQ_GUID 0x5077612
+#define SOCS_LPM_REQ_GUID 0x8478657
+#define PCHS_LPM_REQ_GUID 0x9684572
+
+static const u8 ARL_LPM_REG_INDEX[] = {0, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20};
+
const struct pmc_bit_map arl_socs_ltr_show_map[] = {
{"SOUTHPORT_A", CNP_PMC_LTR_SPA},
{"SOUTHPORT_B", CNP_PMC_LTR_SPB},
@@ -269,6 +276,7 @@ const struct pmc_reg_map arl_socs_reg_map = {
.lpm_sts_latch_en_offset = MTL_LPM_STATUS_LATCH_EN_OFFSET,
.lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET,
.lpm_num_maps = ADL_LPM_NUM_MAPS,
+ .lpm_reg_index = ARL_LPM_REG_INDEX,
.etr3_offset = ETR3_OFFSET,
.pson_residency_offset = TGL_PSON_RESIDENCY_OFFSET,
.pson_residency_counter_step = TGL_PSON_RES_COUNTER_STEP,
@@ -637,19 +645,23 @@ const struct pmc_reg_map arl_pchs_reg_map = {
.lpm_sts_latch_en_offset = MTL_LPM_STATUS_LATCH_EN_OFFSET,
.lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET,
.lpm_num_maps = ADL_LPM_NUM_MAPS,
+ .lpm_reg_index = ARL_LPM_REG_INDEX,
.etr3_offset = ETR3_OFFSET,
};
static struct pmc_info arl_pmc_info_list[] = {
{
+ .guid = IOEP_LPM_REQ_GUID,
.devid = PMC_DEVID_MTL_IOEP,
.map = &mtl_ioep_reg_map,
},
{
+ .guid = SOCS_LPM_REQ_GUID,
.devid = PMC_DEVID_ARL_SOCS,
.map = &arl_socs_reg_map,
},
{
+ .guid = PCHS_LPM_REQ_GUID,
.devid = PMC_DEVID_ARL_PCHS,
.map = &arl_pchs_reg_map,
},
@@ -679,7 +691,7 @@ static int arl_resume(struct pmc_dev *pmcdev)
int arl_core_init(struct pmc_dev *pmcdev)
{
struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC];
- int ret;
+ int ret, func = 0;
arl_d3_fixup();
pmcdev->suspend = cnl_suspend;
@@ -703,5 +715,5 @@ int arl_core_init(struct pmc_dev *pmcdev)
pmc_core_get_low_power_modes(pmcdev);
pmc_core_punit_pmt_init(pmcdev, ARL_PMT_DMU_GUID);
- return 0;
+ return pmc_core_get_lpm_reqs(pmcdev, func);
}
diff --git a/drivers/platform/x86/intel/pmc/lnl.c b/drivers/platform/x86/intel/pmc/lnl.c
index 109b08d43fc8..66e4d39d0493 100644
--- a/drivers/platform/x86/intel/pmc/lnl.c
+++ b/drivers/platform/x86/intel/pmc/lnl.c
@@ -13,8 +13,13 @@
#include "core.h"
+#define SOCM_LPM_REQ_GUID 0x15099748
+
+static const u8 LNL_LPM_REG_INDEX[] = {0, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20};
+
static struct pmc_info lnl_pmc_info_list[] = {
{
+ .guid = SOCM_LPM_REQ_GUID,
.devid = PMC_DEVID_LNL_SOCM,
.map = &lnl_socm_reg_map,
},
@@ -536,6 +541,7 @@ const struct pmc_reg_map lnl_socm_reg_map = {
.lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET,
.s0ix_blocker_maps = lnl_blk_maps,
.s0ix_blocker_offset = LNL_S0IX_BLOCKER_OFFSET,
+ .lpm_reg_index = LNL_LPM_REG_INDEX,
};
#define LNL_NPU_PCI_DEV 0x643e
@@ -561,7 +567,7 @@ static int lnl_resume(struct pmc_dev *pmcdev)
int lnl_core_init(struct pmc_dev *pmcdev)
{
- int ret;
+ int ret, func = 2;
struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC];
lnl_d3_fixup();
@@ -586,5 +592,5 @@ int lnl_core_init(struct pmc_dev *pmcdev)
pmc_core_get_low_power_modes(pmcdev);
- return 0;
+ return pmc_core_get_lpm_reqs(pmcdev, func);
}
diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
index 86f8c2a24825..20bcb1b7029b 100644
--- a/drivers/platform/x86/intel/pmc/mtl.c
+++ b/drivers/platform/x86/intel/pmc/mtl.c
@@ -11,6 +11,13 @@
#include <linux/pci.h>
#include "core.h"
+/* PMC SSRAM PMT Telemetry GUIDS */
+#define SOCP_LPM_REQ_GUID 0x2625030
+#define IOEM_LPM_REQ_GUID 0x4357464
+#define IOEP_LPM_REQ_GUID 0x5077612
+
+static const u8 MTL_LPM_REG_INDEX[] = {0, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20};
+
/*
* Die Mapping to Product.
* Product SOCDie IOEDie PCHDie
@@ -465,6 +472,7 @@ const struct pmc_reg_map mtl_socm_reg_map = {
.lpm_sts = mtl_socm_lpm_maps,
.lpm_status_offset = MTL_LPM_STATUS_OFFSET,
.lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET,
+ .lpm_reg_index = MTL_LPM_REG_INDEX,
};
const struct pmc_bit_map mtl_ioep_pfear_map[] = {
@@ -788,6 +796,7 @@ const struct pmc_reg_map mtl_ioep_reg_map = {
.lpm_priority_offset = MTL_LPM_PRI_OFFSET,
.lpm_en_offset = MTL_LPM_EN_OFFSET,
.lpm_sts_latch_en_offset = MTL_LPM_STATUS_LATCH_EN_OFFSET,
+ .lpm_reg_index = MTL_LPM_REG_INDEX,
};
const struct pmc_bit_map mtl_ioem_pfear_map[] = {
@@ -934,18 +943,22 @@ const struct pmc_reg_map mtl_ioem_reg_map = {
.lpm_en_offset = MTL_LPM_EN_OFFSET,
.lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2,
.lpm_residency_offset = MTL_LPM_RESIDENCY_OFFSET,
+ .lpm_reg_index = MTL_LPM_REG_INDEX,
};
static struct pmc_info mtl_pmc_info_list[] = {
{
+ .guid = SOCP_LPM_REQ_GUID,
.devid = PMC_DEVID_MTL_SOCM,
.map = &mtl_socm_reg_map,
},
{
+ .guid = IOEP_LPM_REQ_GUID,
.devid = PMC_DEVID_MTL_IOEP,
.map = &mtl_ioep_reg_map,
},
{
+ .guid = IOEM_LPM_REQ_GUID,
.devid = PMC_DEVID_MTL_IOEM,
.map = &mtl_ioem_reg_map
},
@@ -977,7 +990,7 @@ static int mtl_resume(struct pmc_dev *pmcdev)
int mtl_core_init(struct pmc_dev *pmcdev)
{
struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC];
- int ret;
+ int ret, func = 2;
mtl_d3_fixup();
@@ -1002,5 +1015,5 @@ int mtl_core_init(struct pmc_dev *pmcdev)
pmc_core_get_low_power_modes(pmcdev);
pmc_core_punit_pmt_init(pmcdev, MTL_PMT_DMU_GUID);
- return 0;
+ return pmc_core_get_lpm_reqs(pmcdev, func);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 0/7] Create Intel PMC SSRAM Telemetry driver
2024-08-09 20:46 [PATCH 0/7] Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (6 preceding siblings ...)
2024-08-09 20:46 ` [PATCH 7/7] platform/x86:intel/pmc: Get LPM information for available platforms Xi Pardee
@ 2024-08-13 16:01 ` Ilpo Järvinen
2024-08-13 23:01 ` Xi Pardee
7 siblings, 1 reply; 10+ messages in thread
From: Ilpo Järvinen @ 2024-08-13 16:01 UTC (permalink / raw)
To: Xi Pardee
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML
On Fri, 9 Aug 2024, Xi Pardee wrote:
> This patch series removes the SSRAM support from Intel PMC Core driver
> and creates a separate PCI driver for SSRAM device. The new Intel PMC
> SSRAM driver provides the following functionalities:
>
> 1. Search and store the PMC information in a structure, including PWRMBASE
> address and devid for each available PMC. Then Intel PMC Core driver
> achieves the PMC information using the API provided by the new driver.
>
> 2. Search and register Intel Platform Monitoring Techology telemetry
> regions so they would by available for read through sysfs and Intel PMT
> API. Intel PMC Core driver can achieve Low Power Mode requirement
> information from a telemetry region registered by the new driver.
> The above functionalities was previously handled by Intel PMC Core
> driver. Intel PMC Core driver returns -EPROBE_DEFER when trying to read
> data from a telem region that is not available yet. This setup may
> result in an infinite loop of .probe() calls as Intel PMC Core driver
> creates child devices. Creating a separate PCI driver avoids the infinite
> loop possibility.
>
> Xi Pardee (7):
> platform/x86:intel/pmc: Remove SSRAM support from PMC Core
> platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver
> platform/x86:intel/pmc: Add support to get PMC information from SSRAM
> platform/x86:intel/pmt: Get PMC from SSRAM for available platforms
> platform/x86:intel/pmt: Create inline version for telemetry functions
> platform/x86:intel/pmc: Add support to Retrieve LPM information
> platform/x86:intel/pmc: Get LPM information for available platforms
Hi,
I don't see why the removal first, then re-add approach would be justified
here. You're basically adding the same code back later in many cases with
only very minimal changes, and some changes are entirely pointless such as
pmc_idx -> pmc_index parameter rename. This is just a big pain to review.
I'd suggest you move functions in first patch into core.c. Try to
avoid logic/code changes other than making making the necessary functions
non-static and adding the prototypes for them into a header (temporarily).
Then rename the ssram file to its new name in the second change.
Then do the rework on top of that (and make things back static again).
Try to split the rework into sensible chunks, anything that can be taken
away from the main rework change is less lines to review in that patch.
If you e.g. want to do pcidev -> pdev renames, put them into own separate
change (and do it consistently then, not just for some of the cases like
currently :-/).
The move patches are nearly trivial to review and take large chunk of
diff away from the actual rework itself which doesn't seem that
complicated to review once the 1:1 move bits and trivial rename churn is
eliminated from the diff.
> drivers/platform/x86/intel/pmc/Kconfig | 13 +-
> drivers/platform/x86/intel/pmc/Makefile | 8 +-
> drivers/platform/x86/intel/pmc/arl.c | 36 +-
> drivers/platform/x86/intel/pmc/core.c | 216 +++++++++++-
> drivers/platform/x86/intel/pmc/core.h | 25 +-
> drivers/platform/x86/intel/pmc/core_ssram.c | 326 ------------------
> drivers/platform/x86/intel/pmc/lnl.c | 36 +-
> drivers/platform/x86/intel/pmc/mtl.c | 34 +-
> .../platform/x86/intel/pmc/ssram_telemetry.c | 184 ++++++++++
> .../platform/x86/intel/pmc/ssram_telemetry.h | 45 +++
> drivers/platform/x86/intel/pmt/telemetry.h | 19 +-
> 11 files changed, 550 insertions(+), 392 deletions(-)
> delete mode 100644 drivers/platform/x86/intel/pmc/core_ssram.c
> create mode 100644 drivers/platform/x86/intel/pmc/ssram_telemetry.c
> create mode 100644 drivers/platform/x86/intel/pmc/ssram_telemetry.h
>
>
--
i.
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 0/7] Create Intel PMC SSRAM Telemetry driver
2024-08-13 16:01 ` [PATCH 0/7] Create Intel PMC SSRAM Telemetry driver Ilpo Järvinen
@ 2024-08-13 23:01 ` Xi Pardee
0 siblings, 0 replies; 10+ messages in thread
From: Xi Pardee @ 2024-08-13 23:01 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML
On 8/13/2024 9:01 AM, Ilpo Järvinen wrote:
> On Fri, 9 Aug 2024, Xi Pardee wrote:
>
>> This patch series removes the SSRAM support from Intel PMC Core driver
>> and creates a separate PCI driver for SSRAM device. The new Intel PMC
>> SSRAM driver provides the following functionalities:
>>
>> 1. Search and store the PMC information in a structure, including PWRMBASE
>> address and devid for each available PMC. Then Intel PMC Core driver
>> achieves the PMC information using the API provided by the new driver.
>>
>> 2. Search and register Intel Platform Monitoring Techology telemetry
>> regions so they would by available for read through sysfs and Intel PMT
>> API. Intel PMC Core driver can achieve Low Power Mode requirement
>> information from a telemetry region registered by the new driver.
>> The above functionalities was previously handled by Intel PMC Core
>> driver. Intel PMC Core driver returns -EPROBE_DEFER when trying to read
>> data from a telem region that is not available yet. This setup may
>> result in an infinite loop of .probe() calls as Intel PMC Core driver
>> creates child devices. Creating a separate PCI driver avoids the infinite
>> loop possibility.
>>
>> Xi Pardee (7):
>> platform/x86:intel/pmc: Remove SSRAM support from PMC Core
>> platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver
>> platform/x86:intel/pmc: Add support to get PMC information from SSRAM
>> platform/x86:intel/pmt: Get PMC from SSRAM for available platforms
>> platform/x86:intel/pmt: Create inline version for telemetry functions
>> platform/x86:intel/pmc: Add support to Retrieve LPM information
>> platform/x86:intel/pmc: Get LPM information for available platforms
> Hi,
>
> I don't see why the removal first, then re-add approach would be justified
> here. You're basically adding the same code back later in many cases with
> only very minimal changes, and some changes are entirely pointless such as
> pmc_idx -> pmc_index parameter rename. This is just a big pain to review.
>
> I'd suggest you move functions in first patch into core.c. Try to
> avoid logic/code changes other than making making the necessary functions
> non-static and adding the prototypes for them into a header (temporarily).
>
> Then rename the ssram file to its new name in the second change.
>
> Then do the rework on top of that (and make things back static again).
>
> Try to split the rework into sensible chunks, anything that can be taken
> away from the main rework change is less lines to review in that patch.
> If you e.g. want to do pcidev -> pdev renames, put them into own separate
> change (and do it consistently then, not just for some of the cases like
> currently :-/).
>
> The move patches are nearly trivial to review and take large chunk of
> diff away from the actual rework itself which doesn't seem that
> complicated to review once the 1:1 move bits and trivial rename churn is
> eliminated from the diff.
Hi,
Thanks for reviewing the patches. I will rearrange the code in next version.
Xi
>> drivers/platform/x86/intel/pmc/Kconfig | 13 +-
>> drivers/platform/x86/intel/pmc/Makefile | 8 +-
>> drivers/platform/x86/intel/pmc/arl.c | 36 +-
>> drivers/platform/x86/intel/pmc/core.c | 216 +++++++++++-
>> drivers/platform/x86/intel/pmc/core.h | 25 +-
>> drivers/platform/x86/intel/pmc/core_ssram.c | 326 ------------------
>> drivers/platform/x86/intel/pmc/lnl.c | 36 +-
>> drivers/platform/x86/intel/pmc/mtl.c | 34 +-
>> .../platform/x86/intel/pmc/ssram_telemetry.c | 184 ++++++++++
>> .../platform/x86/intel/pmc/ssram_telemetry.h | 45 +++
>> drivers/platform/x86/intel/pmt/telemetry.h | 19 +-
>> 11 files changed, 550 insertions(+), 392 deletions(-)
>> delete mode 100644 drivers/platform/x86/intel/pmc/core_ssram.c
>> create mode 100644 drivers/platform/x86/intel/pmc/ssram_telemetry.c
>> create mode 100644 drivers/platform/x86/intel/pmc/ssram_telemetry.h
>>
>>
^ permalink raw reply [flat|nested] 10+ messages in thread