* [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver
@ 2024-08-28 22:29 Xi Pardee
2024-08-28 22:29 ` [PATCH v2 01/11] platform/x86:intel/pmc: Move PMC Core related functions Xi Pardee
` (10 more replies)
0 siblings, 11 replies; 26+ messages in thread
From: Xi Pardee @ 2024-08-28 22:29 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel, linux-pm
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.
Changes in v2:
- Rearrange and restructure patches completely based on feedback from v1
- Here are the patches:
Preparation for the new SSRAM Telemetry driver:
platform/x86:intel/pmc: Move PMC Core related functions
platform/x86:intel/pmc: Rename core_ssram to ssram_telemetry
platform/x86:intel/pmc: Move PMC devid to core.h
Minor bug fix:
platform/x86:intel/pmc: Convert index variables to be unsigned
platform/x86:intel/pmc: Remove unneeded h file inclusion
platform/x86:intel/pmc: Remove unneeded io operations
platform/x86:intel/pmc: Check return value of ioremap
Create new driver and convert PMC Core to use the API:
platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver
Enable Lunar Lake platform:
platform/x86:intel/pmc: Add Lunar Lake SSRAM devid
platform/x86:intel/pmt: Get PMC from SSRAM for Lunar Lake
platform/x86:intel/pmc: Get LPM information for Lunar Lake
Xi Pardee (11):
platform/x86:intel/pmc: Move PMC Core related functions
platform/x86:intel/pmc: Rename core_ssram to ssram_telemetry
platform/x86:intel/pmc: Move PMC devid to core.h
platform/x86:intel/pmc: Convert index variables to be unsigned
platform/x86:intel/pmc: Remove unneeded h file inclusion
platform/x86:intel/pmc: Remove unneeded io operations
platform/x86:intel/pmc: Check return value of ioremap
platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver
platform/x86:intel/pmc: Add Lunar Lake SSRAM devid
platform/x86:intel/pmt: Get PMC from SSRAM for Lunar Lake
platform/x86:intel/pmc: Get LPM information for Lunar Lake
drivers/platform/x86/intel/pmc/Kconfig | 11 +
drivers/platform/x86/intel/pmc/Makefile | 8 +-
drivers/platform/x86/intel/pmc/arl.c | 24 +-
drivers/platform/x86/intel/pmc/core.c | 200 +++++++++++
drivers/platform/x86/intel/pmc/core.h | 23 +-
drivers/platform/x86/intel/pmc/core_ssram.c | 326 ------------------
drivers/platform/x86/intel/pmc/lnl.c | 41 ++-
drivers/platform/x86/intel/pmc/mtl.c | 24 +-
.../platform/x86/intel/pmc/ssram_telemetry.c | 183 ++++++++++
.../platform/x86/intel/pmc/ssram_telemetry.h | 45 +++
10 files changed, 525 insertions(+), 360 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
--
2.43.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 01/11] platform/x86:intel/pmc: Move PMC Core related functions
2024-08-28 22:29 [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver Xi Pardee
@ 2024-08-28 22:29 ` Xi Pardee
2024-08-29 10:49 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 02/11] platform/x86:intel/pmc: Rename core_ssram to ssram_telemetry Xi Pardee
` (9 subsequent siblings)
10 siblings, 1 reply; 26+ messages in thread
From: Xi Pardee @ 2024-08-28 22:29 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel, linux-pm
Move functions that implements PMC Core feature from core_ssram.c
to core.c. This patch is a preparation step to introduce a new
SSRAM Telemetry driver for the SSRAM device.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/core.c | 168 +++++++++++++++++++
drivers/platform/x86/intel/pmc/core.h | 8 +
drivers/platform/x86/intel/pmc/core_ssram.c | 173 --------------------
3 files changed, 176 insertions(+), 173 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
index 01ae71c6df59..630ce2087552 100644
--- a/drivers/platform/x86/intel/pmc/core.c
+++ b/drivers/platform/x86/intel/pmc/core.c
@@ -1604,6 +1604,173 @@ static const struct dev_pm_ops pmc_core_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(pmc_core_suspend, pmc_core_resume)
};
+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;
+}
+
+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;
+}
+
+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 const struct acpi_device_id pmc_core_acpi_ids[] = {
{"INT33A1", 0}, /* _HID for Intel Power Engine, _CID PNP0D80*/
{ }
@@ -1623,5 +1790,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..9a1cc01f31d9 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
@@ -589,6 +594,9 @@ 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);
+extern const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid);
+extern int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
+ const struct pmc_reg_map *reg_map, int pmc_index);
int spt_core_init(struct pmc_dev *pmcdev);
int cnp_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
index 1bde86c54eb9..0a2bfca5ff41 100644
--- a/drivers/platform/x86/intel/pmc/core_ssram.c
+++ b/drivers/platform/x86/intel/pmc/core_ssram.c
@@ -24,142 +24,8 @@
#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)
{
@@ -203,50 +69,11 @@ pmc_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram)
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)
{
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 02/11] platform/x86:intel/pmc: Rename core_ssram to ssram_telemetry
2024-08-28 22:29 [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver Xi Pardee
2024-08-28 22:29 ` [PATCH v2 01/11] platform/x86:intel/pmc: Move PMC Core related functions Xi Pardee
@ 2024-08-28 22:29 ` Xi Pardee
2024-08-29 10:50 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 03/11] platform/x86:intel/pmc: Move PMC devid to core.h Xi Pardee
` (8 subsequent siblings)
10 siblings, 1 reply; 26+ messages in thread
From: Xi Pardee @ 2024-08-28 22:29 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel, linux-pm
Rename core_ssram.c to ssram_telemetry.c. This patch is a
preparation step to introduce a new SSRAM Telemetry driver
for the SSRAM device.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/Makefile | 2 +-
.../platform/x86/intel/pmc/{core_ssram.c => ssram_telemetry.c} | 0
2 files changed, 1 insertion(+), 1 deletion(-)
rename drivers/platform/x86/intel/pmc/{core_ssram.c => ssram_telemetry.c} (100%)
diff --git a/drivers/platform/x86/intel/pmc/Makefile b/drivers/platform/x86/intel/pmc/Makefile
index 389e5419dadf..4dd9fa93f873 100644
--- a/drivers/platform/x86/intel/pmc/Makefile
+++ b/drivers/platform/x86/intel/pmc/Makefile
@@ -3,7 +3,7 @@
# Intel x86 Platform-Specific Drivers
#
-intel_pmc_core-y := core.o core_ssram.o spt.o cnp.o \
+intel_pmc_core-y := core.o ssram_telemetry.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
diff --git a/drivers/platform/x86/intel/pmc/core_ssram.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
similarity index 100%
rename from drivers/platform/x86/intel/pmc/core_ssram.c
rename to drivers/platform/x86/intel/pmc/ssram_telemetry.c
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 03/11] platform/x86:intel/pmc: Move PMC devid to core.h
2024-08-28 22:29 [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver Xi Pardee
2024-08-28 22:29 ` [PATCH v2 01/11] platform/x86:intel/pmc: Move PMC Core related functions Xi Pardee
2024-08-28 22:29 ` [PATCH v2 02/11] platform/x86:intel/pmc: Rename core_ssram to ssram_telemetry Xi Pardee
@ 2024-08-28 22:29 ` Xi Pardee
2024-08-29 10:52 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 04/11] platform/x86:intel/pmc: Convert index variables to be unsigned Xi Pardee
` (7 subsequent siblings)
10 siblings, 1 reply; 26+ messages in thread
From: Xi Pardee @ 2024-08-28 22:29 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel, linux-pm
Move PMC devid definition for each PMC of Arrow Lake and Meteor
Lake platforms to core.h. This patch is a preparation step to
introduce a new SSRAM Telemetry driver which will be using the
PMC devid.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/arl.c | 9 +++------
drivers/platform/x86/intel/pmc/core.h | 10 ++++++++++
drivers/platform/x86/intel/pmc/mtl.c | 9 +++------
3 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c
index e10527c4e3e0..870da98ceb41 100644
--- a/drivers/platform/x86/intel/pmc/arl.c
+++ b/drivers/platform/x86/intel/pmc/arl.c
@@ -650,23 +650,20 @@ const struct pmc_reg_map arl_pchs_reg_map = {
.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,
+ .devid = PMC_DEVID_MTL_IOEP,
.map = &mtl_ioep_reg_map,
},
{
.guid = SOCS_LPM_REQ_GUID,
- .devid = PMC_DEVID_SOCS,
+ .devid = PMC_DEVID_ARL_SOCS,
.map = &arl_socs_reg_map,
},
{
.guid = PCHS_LPM_REQ_GUID,
- .devid = PMC_DEVID_PCHS,
+ .devid = PMC_DEVID_ARL_PCHS,
.map = &arl_pchs_reg_map,
},
{}
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index 9a1cc01f31d9..6763e59180a4 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -290,6 +290,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
+#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
+
extern const char *pmc_lpm_modes[];
struct pmc_bit_map {
diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
index c7d15d864039..908b5f8bb6e5 100644
--- a/drivers/platform/x86/intel/pmc/mtl.c
+++ b/drivers/platform/x86/intel/pmc/mtl.c
@@ -947,23 +947,20 @@ const struct pmc_reg_map mtl_ioem_reg_map = {
.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,
+ .devid = PMC_DEVID_MTL_SOCM,
.map = &mtl_socm_reg_map,
},
{
.guid = IOEP_LPM_REQ_GUID,
- .devid = PMC_DEVID_IOEP,
+ .devid = PMC_DEVID_MTL_IOEP,
.map = &mtl_ioep_reg_map,
},
{
.guid = IOEM_LPM_REQ_GUID,
- .devid = PMC_DEVID_IOEM,
+ .devid = PMC_DEVID_MTL_IOEM,
.map = &mtl_ioem_reg_map
},
{}
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 04/11] platform/x86:intel/pmc: Convert index variables to be unsigned
2024-08-28 22:29 [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (2 preceding siblings ...)
2024-08-28 22:29 ` [PATCH v2 03/11] platform/x86:intel/pmc: Move PMC devid to core.h Xi Pardee
@ 2024-08-28 22:29 ` Xi Pardee
2024-08-29 10:54 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 05/11] platform/x86:intel/pmc: Remove unneeded h file inclusion Xi Pardee
` (6 subsequent siblings)
10 siblings, 1 reply; 26+ messages in thread
From: Xi Pardee @ 2024-08-28 22:29 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel, linux-pm
Convert the index variables type to be unsigned to avoid confusion
and error.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/core.c | 5 +++--
drivers/platform/x86/intel/pmc/core.h | 2 +-
drivers/platform/x86/intel/pmc/ssram_telemetry.c | 2 +-
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
index 630ce2087552..8984041f35f4 100644
--- a/drivers/platform/x86/intel/pmc/core.c
+++ b/drivers/platform/x86/intel/pmc/core.c
@@ -1716,7 +1716,8 @@ static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev)
{
- int ret, i;
+ unsigned int i;
+ int ret;
if (!pmcdev->ssram_pcidev)
return -ENODEV;
@@ -1743,7 +1744,7 @@ const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
}
int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
- const struct pmc_reg_map *reg_map, int pmc_index)
+ const struct pmc_reg_map *reg_map, unsigned int pmc_index)
{
struct pmc *pmc = pmcdev->pmcs[pmc_index];
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index 6763e59180a4..5af1d41a83f7 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -606,7 +606,7 @@ extern void pmc_core_set_device_d3(unsigned int device);
extern int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func);
extern const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid);
extern int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
- const struct pmc_reg_map *reg_map, int pmc_index);
+ const struct pmc_reg_map *reg_map, unsigned int pmc_index);
int spt_core_init(struct pmc_dev *pmcdev);
int cnp_core_init(struct pmc_dev *pmcdev);
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
index 0a2bfca5ff41..4b21d9cf310a 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -75,7 +75,7 @@ static inline u64 get_base(void __iomem *addr, u32 offset)
}
static int
-pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, int pmc_idx, u32 offset)
+pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset)
{
struct pci_dev *ssram_pcidev = pmcdev->ssram_pcidev;
void __iomem __free(pmc_core_iounmap) *tmp_ssram = NULL;
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 05/11] platform/x86:intel/pmc: Remove unneeded h file inclusion
2024-08-28 22:29 [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (3 preceding siblings ...)
2024-08-28 22:29 ` [PATCH v2 04/11] platform/x86:intel/pmc: Convert index variables to be unsigned Xi Pardee
@ 2024-08-28 22:29 ` Xi Pardee
2024-08-29 11:02 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 06/11] platform/x86:intel/pmc: Remove unneeded io operations Xi Pardee
` (5 subsequent siblings)
10 siblings, 1 reply; 26+ messages in thread
From: Xi Pardee @ 2024-08-28 22:29 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel, linux-pm
telemetry.h header file is not needed in arl.c or mtl.c. Remove
them to avoid confusion.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/arl.c | 1 -
drivers/platform/x86/intel/pmc/mtl.c | 1 -
2 files changed, 2 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c
index 870da98ceb41..0460715c58f4 100644
--- a/drivers/platform/x86/intel/pmc/arl.c
+++ b/drivers/platform/x86/intel/pmc/arl.c
@@ -10,7 +10,6 @@
#include <linux/pci.h>
#include "core.h"
-#include "../pmt/telemetry.h"
/* PMC SSRAM PMT Telemetry GUID */
#define IOEP_LPM_REQ_GUID 0x5077612
diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
index 908b5f8bb6e5..e7f5b650902d 100644
--- a/drivers/platform/x86/intel/pmc/mtl.c
+++ b/drivers/platform/x86/intel/pmc/mtl.c
@@ -10,7 +10,6 @@
#include <linux/pci.h>
#include "core.h"
-#include "../pmt/telemetry.h"
/* PMC SSRAM PMT Telemetry GUIDS */
#define SOCP_LPM_REQ_GUID 0x2625030
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 06/11] platform/x86:intel/pmc: Remove unneeded io operations
2024-08-28 22:29 [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (4 preceding siblings ...)
2024-08-28 22:29 ` [PATCH v2 05/11] platform/x86:intel/pmc: Remove unneeded h file inclusion Xi Pardee
@ 2024-08-28 22:29 ` Xi Pardee
2024-08-28 22:29 ` [PATCH v2 07/11] platform/x86:intel/pmc: Check return value of ioremap Xi Pardee
` (4 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Xi Pardee @ 2024-08-28 22:29 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel, linux-pm
Remove ioremap and iounmap operations that are not needed. ioremap
and iounmap operations are handled by the caller of the pmc_add_pmt
function.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/ssram_telemetry.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
index 4b21d9cf310a..73c727042ca6 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -37,13 +37,7 @@ pmc_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram)
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;
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 07/11] platform/x86:intel/pmc: Check return value of ioremap
2024-08-28 22:29 [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (5 preceding siblings ...)
2024-08-28 22:29 ` [PATCH v2 06/11] platform/x86:intel/pmc: Remove unneeded io operations Xi Pardee
@ 2024-08-28 22:29 ` Xi Pardee
2024-08-29 11:06 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 08/11] platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (3 subsequent siblings)
10 siblings, 1 reply; 26+ messages in thread
From: Xi Pardee @ 2024-08-28 22:29 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel, linux-pm
Check the return value of ioremap operation and return ENOMEM when
the operation fails for better error handling.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/ssram_telemetry.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
index 73c727042ca6..f625d39d1aa3 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -84,6 +84,9 @@ pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset)
ssram_base = ssram_pcidev->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)
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 08/11] platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver
2024-08-28 22:29 [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (6 preceding siblings ...)
2024-08-28 22:29 ` [PATCH v2 07/11] platform/x86:intel/pmc: Check return value of ioremap Xi Pardee
@ 2024-08-28 22:29 ` Xi Pardee
2024-08-29 12:02 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 09/11] platform/x86:intel/pmc: Add Lunar Lake SSRAM devid Xi Pardee
` (2 subsequent siblings)
10 siblings, 1 reply; 26+ messages in thread
From: Xi Pardee @ 2024-08-28 22:29 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel, linux-pm
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>
---
drivers/platform/x86/intel/pmc/Kconfig | 11 ++
drivers/platform/x86/intel/pmc/Makefile | 8 +-
drivers/platform/x86/intel/pmc/arl.c | 14 ++-
drivers/platform/x86/intel/pmc/core.c | 59 ++++++---
drivers/platform/x86/intel/pmc/core.h | 6 +-
drivers/platform/x86/intel/pmc/mtl.c | 14 ++-
.../platform/x86/intel/pmc/ssram_telemetry.c | 118 +++++++++++-------
.../platform/x86/intel/pmc/ssram_telemetry.h | 45 +++++++
8 files changed, 200 insertions(+), 75 deletions(-)
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..c2ccd48fe266 100644
--- a/drivers/platform/x86/intel/pmc/Kconfig
+++ b/drivers/platform/x86/intel/pmc/Kconfig
@@ -8,6 +8,7 @@ config INTEL_PMC_CORE
depends on PCI
depends on ACPI
depends on INTEL_PMT_TELEMETRY
+ depends on INTEL_PMC_SSRAM_TELEMETRY || !INTEL_PMC_SSRAM_TELEMETRY
help
The Intel Platform Controller Hub for Intel Core SoCs provides access
to Power Management Controller registers via various interfaces. This
@@ -24,3 +25,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.
\ No newline at end of file
diff --git a/drivers/platform/x86/intel/pmc/Makefile b/drivers/platform/x86/intel/pmc/Makefile
index 4dd9fa93f873..e935602af2a3 100644
--- a/drivers/platform/x86/intel/pmc/Makefile
+++ b/drivers/platform/x86/intel/pmc/Makefile
@@ -3,8 +3,12 @@
# Intel x86 Platform-Specific Drivers
#
-intel_pmc_core-y := core.o ssram_telemetry.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
+
+# Intel PMC SSRAM driver
+intel_pmc_ssram_telemetry-y += ssram_telemetry.o
+obj-$(CONFIG_INTEL_PMC_SSRAM_TELEMETRY) += intel_pmc_ssram_telemetry.o
\ No newline at end of file
diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c
index 0460715c58f4..25268b1fdf97 100644
--- a/drivers/platform/x86/intel/pmc/arl.c
+++ b/drivers/platform/x86/intel/pmc/arl.c
@@ -700,11 +700,13 @@ int arl_core_init(struct pmc_dev *pmcdev)
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);
+ 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) {
ssram_init = false;
pmc->map = &arl_socs_reg_map;
@@ -718,7 +720,7 @@ int arl_core_init(struct pmc_dev *pmcdev)
pmc_core_punit_pmt_init(pmcdev, ARL_PMT_DMU_GUID);
if (ssram_init) {
- ret = pmc_core_ssram_get_lpm_reqs(pmcdev);
+ ret = pmc_core_ssram_get_lpm_reqs(pmcdev, func);
if (ret)
return ret;
}
diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
index 8984041f35f4..19256c5570ab 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 */
@@ -1613,11 +1614,12 @@ static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *m
return 0;
}
-static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
+static int pmc_core_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;
@@ -1630,11 +1632,16 @@ static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
if (!guid)
return -ENXIO;
- ep = pmt_telem_find_and_register_endpoint(pmcdev->ssram_pcidev, guid, 0);
+ 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));
- return -EPROBE_DEFER;
+ ret = -EPROBE_DEFER;
+ goto release_dev;
}
pmc->lpm_req_regs = devm_kzalloc(&pmcdev->pdev->dev,
@@ -1710,23 +1717,22 @@ static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
unregister_ep:
pmt_telem_unregister_endpoint(ep);
+release_dev:
+ pci_dev_put(pcidev);
return ret;
}
-int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev)
+int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev, int func)
{
unsigned int i;
int ret;
- 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]);
+ ret = pmc_core_get_lpm_req(pmcdev, pmcdev->pmcs[i], func);
if (ret)
return ret;
}
@@ -1743,14 +1749,22 @@ const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
return NULL;
}
-int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
- const struct pmc_reg_map *reg_map, unsigned int pmc_index)
+static int pmc_core_pmc_add(struct pmc_dev *pmcdev, unsigned int pmc_index)
{
- struct pmc *pmc = pmcdev->pmcs[pmc_index];
+ struct pmc_ssram_telemetry pmc_ssram_telemetry;
+ const struct pmc_reg_map *map;
+ struct pmc *pmc;
+ int ret;
+
+ ret = pmc_ssram_telemetry_get_pmc_info(pmc_index, &pmc_ssram_telemetry);
+ if (ret)
+ return ret;
- if (!pwrm_base)
+ map = pmc_core_find_regmap(pmcdev->regmap_list, pmc_ssram_telemetry.devid);
+ if (!map)
return -ENODEV;
+ pmc = pmcdev->pmcs[pmc_index];
/* Memory for primary PMC has been allocated in core.c */
if (!pmc) {
pmc = devm_kzalloc(&pmcdev->pdev->dev, sizeof(*pmc), GFP_KERNEL);
@@ -1758,8 +1772,8 @@ int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
return -ENOMEM;
}
- pmc->map = reg_map;
- pmc->base_addr = pwrm_base;
+ pmc->map = map;
+ pmc->base_addr = pmc_ssram_telemetry.base_addr;
pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length);
if (!pmc->regbase) {
@@ -1772,6 +1786,23 @@ int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
return 0;
}
+int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev)
+{
+ int ret;
+
+ if (!pmcdev->regmap_list)
+ return -ENOENT;
+
+ ret = pmc_core_pmc_add(pmcdev, PMC_IDX_MAIN);
+ if (ret)
+ return ret;
+
+ pmc_core_pmc_add(pmcdev, PMC_IDX_IOE);
+ pmc_core_pmc_add(pmcdev, PMC_IDX_PCH);
+
+ return 0;
+}
+
static const struct acpi_device_id pmc_core_acpi_ids[] = {
{"INT33A1", 0}, /* _HID for Intel Power Engine, _CID PNP0D80*/
{ }
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index 5af1d41a83f7..2d62a71ec100 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -594,7 +594,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_ssram_get_lpm_reqs(struct pmc_dev *pmcdev);
+extern int pmc_core_ssram_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);
@@ -603,10 +603,8 @@ 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);
extern const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid);
-extern int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
- const struct pmc_reg_map *reg_map, unsigned int pmc_index);
+extern int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev);
int spt_core_init(struct pmc_dev *pmcdev);
int cnp_core_init(struct pmc_dev *pmcdev);
diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
index e7f5b650902d..6ac52625a029 100644
--- a/drivers/platform/x86/intel/pmc/mtl.c
+++ b/drivers/platform/x86/intel/pmc/mtl.c
@@ -1000,11 +1000,13 @@ int mtl_core_init(struct pmc_dev *pmcdev)
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);
+ 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) {
ssram_init = false;
dev_warn(&pmcdev->pdev->dev,
@@ -1019,7 +1021,7 @@ int mtl_core_init(struct pmc_dev *pmcdev)
pmc_core_punit_pmt_init(pmcdev, MTL_PMT_DMU_GUID);
if (ssram_init)
- return pmc_core_ssram_get_lpm_reqs(pmcdev);
+ return pmc_core_ssram_get_lpm_reqs(pmcdev, func);
return 0;
}
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
index f625d39d1aa3..1c6cc95bfefa 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -1,20 +1,19 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * This file contains functions to handle discovery of PMC metrics located
- * in the PMC SSRAM PCI device.
+ * Intel PMC SSRAM TELEMETRY PCI Driver
*
* Copyright (c) 2023, Intel Corporation.
* All Rights Reserved.
*
*/
-#include <linux/cleanup.h>
#include <linux/pci.h>
+#include <linux/types.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include "core.h"
+#include "ssram_telemetry.h"
#include "../vsec.h"
-#include "../pmt/telemetry.h"
#define SSRAM_HDR_SIZE 0x100
#define SSRAM_PWRM_OFFSET 0x14
@@ -24,12 +23,14 @@
#define SSRAM_IOE_OFFSET 0x68
#define SSRAM_DEVID_OFFSET 0x70
-DEFINE_FREE(pmc_core_iounmap, void __iomem *, iounmap(_T));
+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_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram)
+pmc_ssram_telemetry_add_pmt(struct pci_dev *pcidev, 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;
@@ -58,7 +59,7 @@ pmc_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram)
info.caps = VSEC_CAP_TELEMETRY;
info.headers = headers;
info.base_addr = ssram_base;
- info.parent = &pmcdev->pdev->dev;
+ info.parent = &pcidev->dev;
intel_vsec_register(pcidev, &info);
}
@@ -69,19 +70,14 @@ static inline u64 get_base(void __iomem *addr, u32 offset)
}
static int
-pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset)
+pmc_ssram_telemetry_get_pmc(struct pci_dev *pcidev, unsigned 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;
+ 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;
- if (!pmcdev->regmap_list)
- return -ENOENT;
-
- ssram_base = ssram_pcidev->resource[0].start;
+ ssram_base = pcidev->resource[0].start;
tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
if (!tmp_ssram)
@@ -105,46 +101,82 @@ pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset)
devid = readw(ssram + SSRAM_DEVID_OFFSET);
/* Find and register and PMC telemetry entries */
- pmc_add_pmt(pmcdev, ssram_base, ssram);
+ pmc_ssram_telemetry_add_pmt(pcidev, ssram_base, ssram);
+
+ pmc_ssram_telems[pmc_idx].devid = devid;
+ pmc_ssram_telems[pmc_idx].base_addr = pwrm_base;
+
+ return 0;
+}
- map = pmc_core_find_regmap(pmcdev->regmap_list, devid);
- if (!map)
+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;
- return pmc_core_pmc_add(pmcdev, pwrm_base, map, pmc_idx);
+ 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);
-int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func)
+static int intel_pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
{
- struct pci_dev *pcidev;
int ret;
- pcidev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(20, func));
- if (!pcidev)
- return -ENODEV;
+ pmc_ssram_telems = devm_kzalloc(&pcidev->dev, sizeof(*pmc_ssram_telems) * MAX_NUM_PMC,
+ GFP_KERNEL);
+ if (!pmc_ssram_telems) {
+ ret = -ENOMEM;
+ goto probe_finish;
+ }
ret = pcim_enable_device(pcidev);
- if (ret)
- goto release_dev;
-
- pmcdev->ssram_pcidev = pcidev;
+ if (ret) {
+ dev_dbg(&pcidev->dev, "failed to enable PMC SSRAM device\n");
+ goto probe_finish;
+ }
- ret = pmc_core_ssram_get_pmc(pmcdev, PMC_IDX_MAIN, 0);
+ ret = pmc_ssram_telemetry_get_pmc(pcidev, PMC_IDX_MAIN, 0);
if (ret)
- goto disable_dev;
+ goto probe_finish;
- 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);
+ pmc_ssram_telemetry_get_pmc(pcidev, PMC_IDX_IOE, SSRAM_IOE_OFFSET);
+ pmc_ssram_telemetry_get_pmc(pcidev, 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_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_IMPORT_NS(INTEL_PMT_TELEMETRY);
+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] 26+ messages in thread
* [PATCH v2 09/11] platform/x86:intel/pmc: Add Lunar Lake SSRAM devid
2024-08-28 22:29 [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (7 preceding siblings ...)
2024-08-28 22:29 ` [PATCH v2 08/11] platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver Xi Pardee
@ 2024-08-28 22:29 ` Xi Pardee
2024-08-29 12:03 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 10/11] platform/x86:intel/pmt: Get PMC from SSRAM for Lunar Lake Xi Pardee
2024-08-28 22:29 ` [PATCH v2 11/11] platform/x86:intel/pmc: Get LPM information " Xi Pardee
10 siblings, 1 reply; 26+ messages in thread
From: Xi Pardee @ 2024-08-28 22:29 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel, linux-pm
Enable SSRAM device Lunar Lake support by adding Lunar Lake SSRAM
devid to Intel SSRAM Telemetry driver.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/core.h | 3 +++
drivers/platform/x86/intel/pmc/ssram_telemetry.c | 1 +
2 files changed, 4 insertions(+)
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index 2d62a71ec100..25974f9d329e 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -300,6 +300,9 @@ enum ppfear_regs {
#define PMC_DEVID_MTL_IOEP 0x7ecf
#define PMC_DEVID_MTL_IOEM 0x7ebf
+/* 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
index 1c6cc95bfefa..025013b051c7 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -165,6 +165,7 @@ static int intel_pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct
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_ARL_SOCS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_LNL_SOCM) },
{ }
};
MODULE_DEVICE_TABLE(pci, intel_pmc_ssram_telemetry_pci_ids);
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 10/11] platform/x86:intel/pmt: Get PMC from SSRAM for Lunar Lake
2024-08-28 22:29 [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (8 preceding siblings ...)
2024-08-28 22:29 ` [PATCH v2 09/11] platform/x86:intel/pmc: Add Lunar Lake SSRAM devid Xi Pardee
@ 2024-08-28 22:29 ` Xi Pardee
2024-08-28 22:29 ` [PATCH v2 11/11] platform/x86:intel/pmc: Get LPM information " Xi Pardee
10 siblings, 0 replies; 26+ messages in thread
From: Xi Pardee @ 2024-08-28 22:29 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel, linux-pm
Add support to discover and achieve PMC information from Intel
SSRAM Telemetry driver for Lunar Lake platforms.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/lnl.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
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);
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 11/11] platform/x86:intel/pmc: Get LPM information for Lunar Lake
2024-08-28 22:29 [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver Xi Pardee
` (9 preceding siblings ...)
2024-08-28 22:29 ` [PATCH v2 10/11] platform/x86:intel/pmt: Get PMC from SSRAM for Lunar Lake Xi Pardee
@ 2024-08-28 22:29 ` Xi Pardee
2024-08-29 12:13 ` Ilpo Järvinen
10 siblings, 1 reply; 26+ messages in thread
From: Xi Pardee @ 2024-08-28 22:29 UTC (permalink / raw)
To: xi.pardee, irenic.rajneesh, david.e.box, hdegoede, ilpo.jarvinen,
platform-driver-x86, linux-kernel, linux-pm
Add support to find and read the requirements from the telemetry
entries for Lunar Lake platforms.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
drivers/platform/x86/intel/pmc/lnl.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/platform/x86/intel/pmc/lnl.c b/drivers/platform/x86/intel/pmc/lnl.c
index 109b08d43fc8..f5fee9e105e2 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,6 +567,8 @@ static int lnl_resume(struct pmc_dev *pmcdev)
int lnl_core_init(struct pmc_dev *pmcdev)
{
+ bool ssram_init = true;
+ int func = 2;
int ret;
struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC];
@@ -578,6 +586,7 @@ int lnl_core_init(struct pmc_dev *pmcdev)
/* If regbase not assigned, set map and discover using legacy method */
if (ret) {
+ ssram_init = false;
pmc->map = &lnl_socm_reg_map;
ret = get_primary_reg_base(pmc);
if (ret)
@@ -586,5 +595,11 @@ int lnl_core_init(struct pmc_dev *pmcdev)
pmc_core_get_low_power_modes(pmcdev);
+ if (ssram_init) {
+ ret = pmc_core_ssram_get_lpm_reqs(pmcdev, func);
+ if (ret)
+ return ret;
+ }
+
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v2 01/11] platform/x86:intel/pmc: Move PMC Core related functions
2024-08-28 22:29 ` [PATCH v2 01/11] platform/x86:intel/pmc: Move PMC Core related functions Xi Pardee
@ 2024-08-29 10:49 ` Ilpo Järvinen
0 siblings, 0 replies; 26+ messages in thread
From: Ilpo Järvinen @ 2024-08-29 10:49 UTC (permalink / raw)
To: Xi Pardee
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
[-- Attachment #1: Type: text/plain, Size: 14775 bytes --]
On Wed, 28 Aug 2024, Xi Pardee wrote:
> Move functions that implements PMC Core feature from core_ssram.c
> to core.c. This patch is a preparation step to introduce a new
> SSRAM Telemetry driver for the SSRAM device.
>
> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> ---
> drivers/platform/x86/intel/pmc/core.c | 168 +++++++++++++++++++
> drivers/platform/x86/intel/pmc/core.h | 8 +
> drivers/platform/x86/intel/pmc/core_ssram.c | 173 --------------------
> 3 files changed, 176 insertions(+), 173 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
> index 01ae71c6df59..630ce2087552 100644
> --- a/drivers/platform/x86/intel/pmc/core.c
> +++ b/drivers/platform/x86/intel/pmc/core.c
> @@ -1604,6 +1604,173 @@ static const struct dev_pm_ops pmc_core_pm_ops = {
> SET_LATE_SYSTEM_SLEEP_PM_OPS(pmc_core_suspend, pmc_core_resume)
> };
>
> +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;
> +}
> +
> +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;
> +}
> +
> +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 const struct acpi_device_id pmc_core_acpi_ids[] = {
> {"INT33A1", 0}, /* _HID for Intel Power Engine, _CID PNP0D80*/
> { }
> @@ -1623,5 +1790,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..9a1cc01f31d9 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
> @@ -589,6 +594,9 @@ 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);
> +extern const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid);
> +extern int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
> + const struct pmc_reg_map *reg_map, int pmc_index);
>
> int spt_core_init(struct pmc_dev *pmcdev);
> int cnp_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
> index 1bde86c54eb9..0a2bfca5ff41 100644
> --- a/drivers/platform/x86/intel/pmc/core_ssram.c
> +++ b/drivers/platform/x86/intel/pmc/core_ssram.c
> @@ -24,142 +24,8 @@
> #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)
> {
> @@ -203,50 +69,11 @@ pmc_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram)
> 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)
> {
>
--
i.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 02/11] platform/x86:intel/pmc: Rename core_ssram to ssram_telemetry
2024-08-28 22:29 ` [PATCH v2 02/11] platform/x86:intel/pmc: Rename core_ssram to ssram_telemetry Xi Pardee
@ 2024-08-29 10:50 ` Ilpo Järvinen
0 siblings, 0 replies; 26+ messages in thread
From: Ilpo Järvinen @ 2024-08-29 10:50 UTC (permalink / raw)
To: Xi Pardee
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
[-- Attachment #1: Type: text/plain, Size: 1460 bytes --]
On Wed, 28 Aug 2024, Xi Pardee wrote:
> Rename core_ssram.c to ssram_telemetry.c. This patch is a
> preparation step to introduce a new SSRAM Telemetry driver
> for the SSRAM device.
>
> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
--
i.
> ---
> drivers/platform/x86/intel/pmc/Makefile | 2 +-
> .../platform/x86/intel/pmc/{core_ssram.c => ssram_telemetry.c} | 0
> 2 files changed, 1 insertion(+), 1 deletion(-)
> rename drivers/platform/x86/intel/pmc/{core_ssram.c => ssram_telemetry.c} (100%)
>
> diff --git a/drivers/platform/x86/intel/pmc/Makefile b/drivers/platform/x86/intel/pmc/Makefile
> index 389e5419dadf..4dd9fa93f873 100644
> --- a/drivers/platform/x86/intel/pmc/Makefile
> +++ b/drivers/platform/x86/intel/pmc/Makefile
> @@ -3,7 +3,7 @@
> # Intel x86 Platform-Specific Drivers
> #
>
> -intel_pmc_core-y := core.o core_ssram.o spt.o cnp.o \
> +intel_pmc_core-y := core.o ssram_telemetry.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
> diff --git a/drivers/platform/x86/intel/pmc/core_ssram.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> similarity index 100%
> rename from drivers/platform/x86/intel/pmc/core_ssram.c
> rename to drivers/platform/x86/intel/pmc/ssram_telemetry.c
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 03/11] platform/x86:intel/pmc: Move PMC devid to core.h
2024-08-28 22:29 ` [PATCH v2 03/11] platform/x86:intel/pmc: Move PMC devid to core.h Xi Pardee
@ 2024-08-29 10:52 ` Ilpo Järvinen
2024-09-10 6:55 ` Xi Pardee
0 siblings, 1 reply; 26+ messages in thread
From: Ilpo Järvinen @ 2024-08-29 10:52 UTC (permalink / raw)
To: Xi Pardee
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
[-- Attachment #1: Type: text/plain, Size: 3229 bytes --]
On Wed, 28 Aug 2024, Xi Pardee wrote:
> Move PMC devid definition for each PMC of Arrow Lake and Meteor
> Lake platforms to core.h. This patch is a preparation step to
> introduce a new SSRAM Telemetry driver which will be using the
> PMC devid.
>
> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
> ---
> drivers/platform/x86/intel/pmc/arl.c | 9 +++------
> drivers/platform/x86/intel/pmc/core.h | 10 ++++++++++
> drivers/platform/x86/intel/pmc/mtl.c | 9 +++------
> 3 files changed, 16 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c
> index e10527c4e3e0..870da98ceb41 100644
> --- a/drivers/platform/x86/intel/pmc/arl.c
> +++ b/drivers/platform/x86/intel/pmc/arl.c
> @@ -650,23 +650,20 @@ const struct pmc_reg_map arl_pchs_reg_map = {
> .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,
> + .devid = PMC_DEVID_MTL_IOEP,
> .map = &mtl_ioep_reg_map,
> },
> {
> .guid = SOCS_LPM_REQ_GUID,
> - .devid = PMC_DEVID_SOCS,
> + .devid = PMC_DEVID_ARL_SOCS,
> .map = &arl_socs_reg_map,
> },
> {
> .guid = PCHS_LPM_REQ_GUID,
> - .devid = PMC_DEVID_PCHS,
> + .devid = PMC_DEVID_ARL_PCHS,
> .map = &arl_pchs_reg_map,
> },
> {}
> diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
> index 9a1cc01f31d9..6763e59180a4 100644
> --- a/drivers/platform/x86/intel/pmc/core.h
> +++ b/drivers/platform/x86/intel/pmc/core.h
> @@ -290,6 +290,16 @@ enum ppfear_regs {
> #define LNL_PPFEAR_NUM_ENTRIES 12
> #define LNL_S0IX_BLOCKER_OFFSET 0x2004
>
> +/* SSRAM PMC Device ID*/
Missing space.
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
--
i.
> +/* 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
> +
> extern const char *pmc_lpm_modes[];
>
> struct pmc_bit_map {
> diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
> index c7d15d864039..908b5f8bb6e5 100644
> --- a/drivers/platform/x86/intel/pmc/mtl.c
> +++ b/drivers/platform/x86/intel/pmc/mtl.c
> @@ -947,23 +947,20 @@ const struct pmc_reg_map mtl_ioem_reg_map = {
> .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,
> + .devid = PMC_DEVID_MTL_SOCM,
> .map = &mtl_socm_reg_map,
> },
> {
> .guid = IOEP_LPM_REQ_GUID,
> - .devid = PMC_DEVID_IOEP,
> + .devid = PMC_DEVID_MTL_IOEP,
> .map = &mtl_ioep_reg_map,
> },
> {
> .guid = IOEM_LPM_REQ_GUID,
> - .devid = PMC_DEVID_IOEM,
> + .devid = PMC_DEVID_MTL_IOEM,
> .map = &mtl_ioem_reg_map
> },
> {}
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 04/11] platform/x86:intel/pmc: Convert index variables to be unsigned
2024-08-28 22:29 ` [PATCH v2 04/11] platform/x86:intel/pmc: Convert index variables to be unsigned Xi Pardee
@ 2024-08-29 10:54 ` Ilpo Järvinen
0 siblings, 0 replies; 26+ messages in thread
From: Ilpo Järvinen @ 2024-08-29 10:54 UTC (permalink / raw)
To: Xi Pardee
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
[-- Attachment #1: Type: text/plain, Size: 2837 bytes --]
On Wed, 28 Aug 2024, Xi Pardee wrote:
> Convert the index variables type to be unsigned to avoid confusion
> and error.
>
> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
--
i.
> ---
> drivers/platform/x86/intel/pmc/core.c | 5 +++--
> drivers/platform/x86/intel/pmc/core.h | 2 +-
> drivers/platform/x86/intel/pmc/ssram_telemetry.c | 2 +-
> 3 files changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
> index 630ce2087552..8984041f35f4 100644
> --- a/drivers/platform/x86/intel/pmc/core.c
> +++ b/drivers/platform/x86/intel/pmc/core.c
> @@ -1716,7 +1716,8 @@ static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
>
> int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev)
> {
> - int ret, i;
> + unsigned int i;
> + int ret;
>
> if (!pmcdev->ssram_pcidev)
> return -ENODEV;
> @@ -1743,7 +1744,7 @@ const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
> }
>
> int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
> - const struct pmc_reg_map *reg_map, int pmc_index)
> + const struct pmc_reg_map *reg_map, unsigned int pmc_index)
> {
> struct pmc *pmc = pmcdev->pmcs[pmc_index];
>
> diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
> index 6763e59180a4..5af1d41a83f7 100644
> --- a/drivers/platform/x86/intel/pmc/core.h
> +++ b/drivers/platform/x86/intel/pmc/core.h
> @@ -606,7 +606,7 @@ extern void pmc_core_set_device_d3(unsigned int device);
> extern int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func);
> extern const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid);
> extern int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
> - const struct pmc_reg_map *reg_map, int pmc_index);
> + const struct pmc_reg_map *reg_map, unsigned int pmc_index);
>
> int spt_core_init(struct pmc_dev *pmcdev);
> int cnp_core_init(struct pmc_dev *pmcdev);
> diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> index 0a2bfca5ff41..4b21d9cf310a 100644
> --- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> +++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> @@ -75,7 +75,7 @@ static inline u64 get_base(void __iomem *addr, u32 offset)
> }
>
> static int
> -pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, int pmc_idx, u32 offset)
> +pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset)
> {
> struct pci_dev *ssram_pcidev = pmcdev->ssram_pcidev;
> void __iomem __free(pmc_core_iounmap) *tmp_ssram = NULL;
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 05/11] platform/x86:intel/pmc: Remove unneeded h file inclusion
2024-08-28 22:29 ` [PATCH v2 05/11] platform/x86:intel/pmc: Remove unneeded h file inclusion Xi Pardee
@ 2024-08-29 11:02 ` Ilpo Järvinen
2024-09-10 7:08 ` Xi Pardee
0 siblings, 1 reply; 26+ messages in thread
From: Ilpo Järvinen @ 2024-08-29 11:02 UTC (permalink / raw)
To: Xi Pardee
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
[-- Attachment #1: Type: text/plain, Size: 1485 bytes --]
On Wed, 28 Aug 2024, Xi Pardee wrote:
In the subject:
h file -> header
> telemetry.h header file is not needed in arl.c or mtl.c. Remove
> them to avoid confusion.
I'd also note this is cross directory/driver include, so perhaps something
along these lines:
telemetry.h from PMT is not needed in arl.c or mtl.c so remove
the cross-driver include.
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
--
i.
> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
> ---
> drivers/platform/x86/intel/pmc/arl.c | 1 -
> drivers/platform/x86/intel/pmc/mtl.c | 1 -
> 2 files changed, 2 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c
> index 870da98ceb41..0460715c58f4 100644
> --- a/drivers/platform/x86/intel/pmc/arl.c
> +++ b/drivers/platform/x86/intel/pmc/arl.c
> @@ -10,7 +10,6 @@
>
> #include <linux/pci.h>
> #include "core.h"
> -#include "../pmt/telemetry.h"
>
> /* PMC SSRAM PMT Telemetry GUID */
> #define IOEP_LPM_REQ_GUID 0x5077612
> diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
> index 908b5f8bb6e5..e7f5b650902d 100644
> --- a/drivers/platform/x86/intel/pmc/mtl.c
> +++ b/drivers/platform/x86/intel/pmc/mtl.c
> @@ -10,7 +10,6 @@
>
> #include <linux/pci.h>
> #include "core.h"
> -#include "../pmt/telemetry.h"
>
> /* PMC SSRAM PMT Telemetry GUIDS */
> #define SOCP_LPM_REQ_GUID 0x2625030
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 07/11] platform/x86:intel/pmc: Check return value of ioremap
2024-08-28 22:29 ` [PATCH v2 07/11] platform/x86:intel/pmc: Check return value of ioremap Xi Pardee
@ 2024-08-29 11:06 ` Ilpo Järvinen
2024-09-10 6:53 ` Xi Pardee
0 siblings, 1 reply; 26+ messages in thread
From: Ilpo Järvinen @ 2024-08-29 11:06 UTC (permalink / raw)
To: Xi Pardee
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
On Wed, 28 Aug 2024, Xi Pardee wrote:
> Check the return value of ioremap operation and return ENOMEM when
> the operation fails for better error handling.
>
> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
> ---
> drivers/platform/x86/intel/pmc/ssram_telemetry.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> index 73c727042ca6..f625d39d1aa3 100644
> --- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> +++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> @@ -84,6 +84,9 @@ pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset)
> ssram_base = ssram_pcidev->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)
Is this a fix to the current code? And should have Fixes tag and go
first because of that?
--
i.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 08/11] platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver
2024-08-28 22:29 ` [PATCH v2 08/11] platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver Xi Pardee
@ 2024-08-29 12:02 ` Ilpo Järvinen
2024-09-10 19:57 ` Xi Pardee
0 siblings, 1 reply; 26+ messages in thread
From: Ilpo Järvinen @ 2024-08-29 12:02 UTC (permalink / raw)
To: Xi Pardee
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
On Wed, 28 Aug 2024, Xi Pardee wrote:
> 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>
> ---
> drivers/platform/x86/intel/pmc/Kconfig | 11 ++
> drivers/platform/x86/intel/pmc/Makefile | 8 +-
> drivers/platform/x86/intel/pmc/arl.c | 14 ++-
> drivers/platform/x86/intel/pmc/core.c | 59 ++++++---
> drivers/platform/x86/intel/pmc/core.h | 6 +-
> drivers/platform/x86/intel/pmc/mtl.c | 14 ++-
> .../platform/x86/intel/pmc/ssram_telemetry.c | 118 +++++++++++-------
> .../platform/x86/intel/pmc/ssram_telemetry.h | 45 +++++++
> 8 files changed, 200 insertions(+), 75 deletions(-)
> 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..c2ccd48fe266 100644
> --- a/drivers/platform/x86/intel/pmc/Kconfig
> +++ b/drivers/platform/x86/intel/pmc/Kconfig
> @@ -8,6 +8,7 @@ config INTEL_PMC_CORE
> depends on PCI
> depends on ACPI
> depends on INTEL_PMT_TELEMETRY
> + depends on INTEL_PMC_SSRAM_TELEMETRY || !INTEL_PMC_SSRAM_TELEMETRY
> help
> The Intel Platform Controller Hub for Intel Core SoCs provides access
> to Power Management Controller registers via various interfaces. This
> @@ -24,3 +25,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.
> \ No newline at end of file
> diff --git a/drivers/platform/x86/intel/pmc/Makefile b/drivers/platform/x86/intel/pmc/Makefile
> index 4dd9fa93f873..e935602af2a3 100644
> --- a/drivers/platform/x86/intel/pmc/Makefile
> +++ b/drivers/platform/x86/intel/pmc/Makefile
> @@ -3,8 +3,12 @@
> # Intel x86 Platform-Specific Drivers
> #
>
> -intel_pmc_core-y := core.o ssram_telemetry.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
> +
> +# Intel PMC SSRAM driver
> +intel_pmc_ssram_telemetry-y += ssram_telemetry.o
> +obj-$(CONFIG_INTEL_PMC_SSRAM_TELEMETRY) += intel_pmc_ssram_telemetry.o
> \ No newline at end of file
Two files above are missing the last newline.
> diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c
> index 0460715c58f4..25268b1fdf97 100644
> --- a/drivers/platform/x86/intel/pmc/arl.c
> +++ b/drivers/platform/x86/intel/pmc/arl.c
> @@ -700,11 +700,13 @@ int arl_core_init(struct pmc_dev *pmcdev)
> 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);
> + 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) {
> ssram_init = false;
> pmc->map = &arl_socs_reg_map;
> @@ -718,7 +720,7 @@ int arl_core_init(struct pmc_dev *pmcdev)
> pmc_core_punit_pmt_init(pmcdev, ARL_PMT_DMU_GUID);
>
> if (ssram_init) {
> - ret = pmc_core_ssram_get_lpm_reqs(pmcdev);
> + ret = pmc_core_ssram_get_lpm_reqs(pmcdev, func);
> if (ret)
> return ret;
> }
> diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
> index 8984041f35f4..19256c5570ab 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 */
> @@ -1613,11 +1614,12 @@ static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *m
> return 0;
> }
>
> -static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
> +static int pmc_core_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;
> @@ -1630,11 +1632,16 @@ static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
> if (!guid)
> return -ENXIO;
>
> - ep = pmt_telem_find_and_register_endpoint(pmcdev->ssram_pcidev, guid, 0);
> + 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));
> - return -EPROBE_DEFER;
> + ret = -EPROBE_DEFER;
> + goto release_dev;
> }
>
> pmc->lpm_req_regs = devm_kzalloc(&pmcdev->pdev->dev,
> @@ -1710,23 +1717,22 @@ static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
>
> unregister_ep:
> pmt_telem_unregister_endpoint(ep);
> +release_dev:
> + pci_dev_put(pcidev);
>
> return ret;
> }
>
> -int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev)
> +int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev, int func)
> {
> unsigned int i;
> int ret;
>
> - 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]);
> + ret = pmc_core_get_lpm_req(pmcdev, pmcdev->pmcs[i], func);
> if (ret)
> return ret;
> }
> @@ -1743,14 +1749,22 @@ const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
> return NULL;
> }
>
> -int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
> - const struct pmc_reg_map *reg_map, unsigned int pmc_index)
> +static int pmc_core_pmc_add(struct pmc_dev *pmcdev, unsigned int pmc_index)
> {
> - struct pmc *pmc = pmcdev->pmcs[pmc_index];
> + struct pmc_ssram_telemetry pmc_ssram_telemetry;
> + const struct pmc_reg_map *map;
> + struct pmc *pmc;
> + int ret;
> +
> + ret = pmc_ssram_telemetry_get_pmc_info(pmc_index, &pmc_ssram_telemetry);
> + if (ret)
> + return ret;
>
> - if (!pwrm_base)
> + map = pmc_core_find_regmap(pmcdev->regmap_list, pmc_ssram_telemetry.devid);
> + if (!map)
> return -ENODEV;
>
> + pmc = pmcdev->pmcs[pmc_index];
> /* Memory for primary PMC has been allocated in core.c */
> if (!pmc) {
> pmc = devm_kzalloc(&pmcdev->pdev->dev, sizeof(*pmc), GFP_KERNEL);
> @@ -1758,8 +1772,8 @@ int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
> return -ENOMEM;
> }
>
> - pmc->map = reg_map;
> - pmc->base_addr = pwrm_base;
> + pmc->map = map;
> + pmc->base_addr = pmc_ssram_telemetry.base_addr;
> pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length);
>
> if (!pmc->regbase) {
> @@ -1772,6 +1786,23 @@ int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
> return 0;
> }
>
> +int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev)
> +{
> + int ret;
> +
> + if (!pmcdev->regmap_list)
> + return -ENOENT;
> +
> + ret = pmc_core_pmc_add(pmcdev, PMC_IDX_MAIN);
> + if (ret)
> + return ret;
> +
> + pmc_core_pmc_add(pmcdev, PMC_IDX_IOE);
> + pmc_core_pmc_add(pmcdev, PMC_IDX_PCH);
> +
> + return 0;
> +}
> +
> static const struct acpi_device_id pmc_core_acpi_ids[] = {
> {"INT33A1", 0}, /* _HID for Intel Power Engine, _CID PNP0D80*/
> { }
> diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
> index 5af1d41a83f7..2d62a71ec100 100644
> --- a/drivers/platform/x86/intel/pmc/core.h
> +++ b/drivers/platform/x86/intel/pmc/core.h
> @@ -594,7 +594,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_ssram_get_lpm_reqs(struct pmc_dev *pmcdev);
> +extern int pmc_core_ssram_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);
> @@ -603,10 +603,8 @@ 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);
> extern const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid);
> -extern int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
> - const struct pmc_reg_map *reg_map, unsigned int pmc_index);
> +extern int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev);
>
> int spt_core_init(struct pmc_dev *pmcdev);
> int cnp_core_init(struct pmc_dev *pmcdev);
> diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
> index e7f5b650902d..6ac52625a029 100644
> --- a/drivers/platform/x86/intel/pmc/mtl.c
> +++ b/drivers/platform/x86/intel/pmc/mtl.c
> @@ -1000,11 +1000,13 @@ int mtl_core_init(struct pmc_dev *pmcdev)
> 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);
> + 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) {
> ssram_init = false;
> dev_warn(&pmcdev->pdev->dev,
> @@ -1019,7 +1021,7 @@ int mtl_core_init(struct pmc_dev *pmcdev)
> pmc_core_punit_pmt_init(pmcdev, MTL_PMT_DMU_GUID);
>
> if (ssram_init)
> - return pmc_core_ssram_get_lpm_reqs(pmcdev);
> + return pmc_core_ssram_get_lpm_reqs(pmcdev, func);
>
> return 0;
> }
> diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> index f625d39d1aa3..1c6cc95bfefa 100644
> --- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> +++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> @@ -1,20 +1,19 @@
> // SPDX-License-Identifier: GPL-2.0
> /*
> - * This file contains functions to handle discovery of PMC metrics located
> - * in the PMC SSRAM PCI device.
> + * Intel PMC SSRAM TELEMETRY PCI Driver
> *
> * Copyright (c) 2023, Intel Corporation.
> * All Rights Reserved.
> *
> */
>
> -#include <linux/cleanup.h>
> #include <linux/pci.h>
> +#include <linux/types.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
>
> #include "core.h"
> +#include "ssram_telemetry.h"
> #include "../vsec.h"
> -#include "../pmt/telemetry.h"
>
> #define SSRAM_HDR_SIZE 0x100
> #define SSRAM_PWRM_OFFSET 0x14
> @@ -24,12 +23,14 @@
> #define SSRAM_IOE_OFFSET 0x68
> #define SSRAM_DEVID_OFFSET 0x70
>
> -DEFINE_FREE(pmc_core_iounmap, void __iomem *, iounmap(_T));
> +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_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram)
> +pmc_ssram_telemetry_add_pmt(struct pci_dev *pcidev, 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;
> @@ -58,7 +59,7 @@ pmc_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram)
> info.caps = VSEC_CAP_TELEMETRY;
> info.headers = headers;
> info.base_addr = ssram_base;
> - info.parent = &pmcdev->pdev->dev;
> + info.parent = &pcidev->dev;
>
> intel_vsec_register(pcidev, &info);
> }
> @@ -69,19 +70,14 @@ static inline u64 get_base(void __iomem *addr, u32 offset)
> }
>
> static int
> -pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset)
> +pmc_ssram_telemetry_get_pmc(struct pci_dev *pcidev, unsigned 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;
> + 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;
>
> - if (!pmcdev->regmap_list)
> - return -ENOENT;
> -
> - ssram_base = ssram_pcidev->resource[0].start;
> + ssram_base = pcidev->resource[0].start;
> tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
>
> if (!tmp_ssram)
> @@ -105,46 +101,82 @@ pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset)
> devid = readw(ssram + SSRAM_DEVID_OFFSET);
>
> /* Find and register and PMC telemetry entries */
> - pmc_add_pmt(pmcdev, ssram_base, ssram);
> + pmc_ssram_telemetry_add_pmt(pcidev, ssram_base, ssram);
> +
> + pmc_ssram_telems[pmc_idx].devid = devid;
> + pmc_ssram_telems[pmc_idx].base_addr = pwrm_base;
> +
> + return 0;
> +}
>
> - map = pmc_core_find_regmap(pmcdev->regmap_list, devid);
> - if (!map)
> +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;
I'm very very skeptical this is safe. Without barriers, nothing guarantees
you'll get the desired ordering. As is, device_probed could appear set
before something else you depend on below this.
> +
> + if (pmc_idx >= MAX_NUM_PMC)
> + return -EINVAL;
> +
> + if (!pmc_ssram_telems || !pmc_ssram_telems[pmc_idx].devid)
> return -ENODEV;
>
> - return pmc_core_pmc_add(pmcdev, pwrm_base, map, pmc_idx);
> + 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);
>
> -int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func)
> +static int intel_pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
> {
> - struct pci_dev *pcidev;
> int ret;
>
> - pcidev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(20, func));
> - if (!pcidev)
> - return -ENODEV;
> + pmc_ssram_telems = devm_kzalloc(&pcidev->dev, sizeof(*pmc_ssram_telems) * MAX_NUM_PMC,
> + GFP_KERNEL);
> + if (!pmc_ssram_telems) {
> + ret = -ENOMEM;
> + goto probe_finish;
> + }
>
> ret = pcim_enable_device(pcidev);
> - if (ret)
> - goto release_dev;
> -
> - pmcdev->ssram_pcidev = pcidev;
> + if (ret) {
> + dev_dbg(&pcidev->dev, "failed to enable PMC SSRAM device\n");
> + goto probe_finish;
> + }
>
> - ret = pmc_core_ssram_get_pmc(pmcdev, PMC_IDX_MAIN, 0);
> + ret = pmc_ssram_telemetry_get_pmc(pcidev, PMC_IDX_MAIN, 0);
> if (ret)
> - goto disable_dev;
> + goto probe_finish;
>
> - 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);
> + pmc_ssram_telemetry_get_pmc(pcidev, PMC_IDX_IOE, SSRAM_IOE_OFFSET);
> + pmc_ssram_telemetry_get_pmc(pcidev, 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_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_IMPORT_NS(INTEL_PMT_TELEMETRY);
> +MODULE_AUTHOR("Xi Pardee <xi.pardee@intel.com>");
> +MODULE_DESCRIPTION("Intel PMC SSRAM TELEMETRY driver");
Telemetry ?
> +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
Telemetry ?
> + *
> + * Copyright (c) 2024, Intel Corporation.
> + * All Rights Reserved.
> + *
Extra new line.
--
i.
> + */
> +
> +#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 */
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 09/11] platform/x86:intel/pmc: Add Lunar Lake SSRAM devid
2024-08-28 22:29 ` [PATCH v2 09/11] platform/x86:intel/pmc: Add Lunar Lake SSRAM devid Xi Pardee
@ 2024-08-29 12:03 ` Ilpo Järvinen
0 siblings, 0 replies; 26+ messages in thread
From: Ilpo Järvinen @ 2024-08-29 12:03 UTC (permalink / raw)
To: Xi Pardee
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
[-- Attachment #1: Type: text/plain, Size: 1662 bytes --]
On Wed, 28 Aug 2024, Xi Pardee wrote:
> Enable SSRAM device Lunar Lake support by adding Lunar Lake SSRAM
> devid to Intel SSRAM Telemetry driver.
>
> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
> ---
> drivers/platform/x86/intel/pmc/core.h | 3 +++
> drivers/platform/x86/intel/pmc/ssram_telemetry.c | 1 +
> 2 files changed, 4 insertions(+)
>
> diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
> index 2d62a71ec100..25974f9d329e 100644
> --- a/drivers/platform/x86/intel/pmc/core.h
> +++ b/drivers/platform/x86/intel/pmc/core.h
> @@ -300,6 +300,9 @@ enum ppfear_regs {
> #define PMC_DEVID_MTL_IOEP 0x7ecf
> #define PMC_DEVID_MTL_IOEM 0x7ebf
>
> +/* 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
> index 1c6cc95bfefa..025013b051c7 100644
> --- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> +++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> @@ -165,6 +165,7 @@ static int intel_pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct
> 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_ARL_SOCS) },
> + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_LNL_SOCM) },
> { }
> };
> MODULE_DEVICE_TABLE(pci, intel_pmc_ssram_telemetry_pci_ids);
>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
--
i.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 11/11] platform/x86:intel/pmc: Get LPM information for Lunar Lake
2024-08-28 22:29 ` [PATCH v2 11/11] platform/x86:intel/pmc: Get LPM information " Xi Pardee
@ 2024-08-29 12:13 ` Ilpo Järvinen
2024-09-10 0:49 ` Xi Pardee
0 siblings, 1 reply; 26+ messages in thread
From: Ilpo Järvinen @ 2024-08-29 12:13 UTC (permalink / raw)
To: Xi Pardee
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
On Wed, 28 Aug 2024, Xi Pardee wrote:
> Add support to find and read the requirements from the telemetry
> entries for Lunar Lake platforms.
>
> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
> ---
> drivers/platform/x86/intel/pmc/lnl.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/drivers/platform/x86/intel/pmc/lnl.c b/drivers/platform/x86/intel/pmc/lnl.c
> index 109b08d43fc8..f5fee9e105e2 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,6 +567,8 @@ static int lnl_resume(struct pmc_dev *pmcdev)
>
> int lnl_core_init(struct pmc_dev *pmcdev)
> {
> + bool ssram_init = true;
> + int func = 2;
> int ret;
> struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC];
>
> @@ -578,6 +586,7 @@ int lnl_core_init(struct pmc_dev *pmcdev)
>
> /* If regbase not assigned, set map and discover using legacy method */
> if (ret) {
> + ssram_init = false;
> pmc->map = &lnl_socm_reg_map;
> ret = get_primary_reg_base(pmc);
> if (ret)
> @@ -586,5 +595,11 @@ int lnl_core_init(struct pmc_dev *pmcdev)
>
> pmc_core_get_low_power_modes(pmcdev);
>
> + if (ssram_init) {
> + ret = pmc_core_ssram_get_lpm_reqs(pmcdev, func);
> + if (ret)
> + return ret;
There's quite much duplication related to this legacy/ssram init in
the per arch core init functions. And some inconsistencies too which
seem incidental such as mtl.c using return directly here.
--
i.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 11/11] platform/x86:intel/pmc: Get LPM information for Lunar Lake
2024-08-29 12:13 ` Ilpo Järvinen
@ 2024-09-10 0:49 ` Xi Pardee
0 siblings, 0 replies; 26+ messages in thread
From: Xi Pardee @ 2024-09-10 0:49 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
On 8/29/2024 5:13 AM, Ilpo Järvinen wrote:
> On Wed, 28 Aug 2024, Xi Pardee wrote:
>
>> Add support to find and read the requirements from the telemetry
>> entries for Lunar Lake platforms.
>>
>> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
>> ---
>> drivers/platform/x86/intel/pmc/lnl.c | 15 +++++++++++++++
>> 1 file changed, 15 insertions(+)
>>
>> diff --git a/drivers/platform/x86/intel/pmc/lnl.c b/drivers/platform/x86/intel/pmc/lnl.c
>> index 109b08d43fc8..f5fee9e105e2 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,6 +567,8 @@ static int lnl_resume(struct pmc_dev *pmcdev)
>>
>> int lnl_core_init(struct pmc_dev *pmcdev)
>> {
>> + bool ssram_init = true;
>> + int func = 2;
>> int ret;
>> struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC];
>>
>> @@ -578,6 +586,7 @@ int lnl_core_init(struct pmc_dev *pmcdev)
>>
>> /* If regbase not assigned, set map and discover using legacy method */
>> if (ret) {
>> + ssram_init = false;
>> pmc->map = &lnl_socm_reg_map;
>> ret = get_primary_reg_base(pmc);
>> if (ret)
>> @@ -586,5 +595,11 @@ int lnl_core_init(struct pmc_dev *pmcdev)
>>
>> pmc_core_get_low_power_modes(pmcdev);
>>
>> + if (ssram_init) {
>> + ret = pmc_core_ssram_get_lpm_reqs(pmcdev, func);
>> + if (ret)
>> + return ret;
> There's quite much duplication related to this legacy/ssram init in
> the per arch core init functions. And some inconsistencies too which
> seem incidental such as mtl.c using return directly here.
I will try to extract the duplicate code to a common function and remove
the
inconsistencies between different architecture in next version.
Xi
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 07/11] platform/x86:intel/pmc: Check return value of ioremap
2024-08-29 11:06 ` Ilpo Järvinen
@ 2024-09-10 6:53 ` Xi Pardee
0 siblings, 0 replies; 26+ messages in thread
From: Xi Pardee @ 2024-09-10 6:53 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
On 8/29/2024 4:06 AM, Ilpo Järvinen wrote:
> On Wed, 28 Aug 2024, Xi Pardee wrote:
>
>> Check the return value of ioremap operation and return ENOMEM when
>> the operation fails for better error handling.
>>
>> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
>> ---
>> drivers/platform/x86/intel/pmc/ssram_telemetry.c | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
>> index 73c727042ca6..f625d39d1aa3 100644
>> --- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
>> +++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
>> @@ -84,6 +84,9 @@ pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset)
>> ssram_base = ssram_pcidev->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)
> Is this a fix to the current code? And should have Fixes tag and go
> first because of that?
This is an improvement of the current code. We should check the value of
ioremap before using it to avoid
failure in the later process. I can add a fixes tag to it. Should this
patch be its own patch series and not
include in this one? Or should it be moved to be the first patch of this
series?
Thanks!
Xi
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 03/11] platform/x86:intel/pmc: Move PMC devid to core.h
2024-08-29 10:52 ` Ilpo Järvinen
@ 2024-09-10 6:55 ` Xi Pardee
0 siblings, 0 replies; 26+ messages in thread
From: Xi Pardee @ 2024-09-10 6:55 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
On 8/29/2024 3:52 AM, Ilpo Järvinen wrote:
> On Wed, 28 Aug 2024, Xi Pardee wrote:
>
>> Move PMC devid definition for each PMC of Arrow Lake and Meteor
>> Lake platforms to core.h. This patch is a preparation step to
>> introduce a new SSRAM Telemetry driver which will be using the
>> PMC devid.
>>
>> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
>> ---
>> drivers/platform/x86/intel/pmc/arl.c | 9 +++------
>> drivers/platform/x86/intel/pmc/core.h | 10 ++++++++++
>> drivers/platform/x86/intel/pmc/mtl.c | 9 +++------
>> 3 files changed, 16 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c
>> index e10527c4e3e0..870da98ceb41 100644
>> --- a/drivers/platform/x86/intel/pmc/arl.c
>> +++ b/drivers/platform/x86/intel/pmc/arl.c
>> @@ -650,23 +650,20 @@ const struct pmc_reg_map arl_pchs_reg_map = {
>> .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,
>> + .devid = PMC_DEVID_MTL_IOEP,
>> .map = &mtl_ioep_reg_map,
>> },
>> {
>> .guid = SOCS_LPM_REQ_GUID,
>> - .devid = PMC_DEVID_SOCS,
>> + .devid = PMC_DEVID_ARL_SOCS,
>> .map = &arl_socs_reg_map,
>> },
>> {
>> .guid = PCHS_LPM_REQ_GUID,
>> - .devid = PMC_DEVID_PCHS,
>> + .devid = PMC_DEVID_ARL_PCHS,
>> .map = &arl_pchs_reg_map,
>> },
>> {}
>> diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
>> index 9a1cc01f31d9..6763e59180a4 100644
>> --- a/drivers/platform/x86/intel/pmc/core.h
>> +++ b/drivers/platform/x86/intel/pmc/core.h
>> @@ -290,6 +290,16 @@ enum ppfear_regs {
>> #define LNL_PPFEAR_NUM_ENTRIES 12
>> #define LNL_S0IX_BLOCKER_OFFSET 0x2004
>>
>> +/* SSRAM PMC Device ID*/
> Missing space.
>
> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Will add a space in next version.
Thanks!
Xi
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 05/11] platform/x86:intel/pmc: Remove unneeded h file inclusion
2024-08-29 11:02 ` Ilpo Järvinen
@ 2024-09-10 7:08 ` Xi Pardee
0 siblings, 0 replies; 26+ messages in thread
From: Xi Pardee @ 2024-09-10 7:08 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
On 8/29/2024 4:02 AM, Ilpo Järvinen wrote:
> On Wed, 28 Aug 2024, Xi Pardee wrote:
>
> In the subject:
>
> h file -> header
>
>> telemetry.h header file is not needed in arl.c or mtl.c. Remove
>> them to avoid confusion.
> I'd also note this is cross directory/driver include, so perhaps something
> along these lines:
>
> telemetry.h from PMT is not needed in arl.c or mtl.c so remove
> the cross-driver include.
>
> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Thanks! I will modify the commit message in the next version.
Xi
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 08/11] platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver
2024-08-29 12:02 ` Ilpo Järvinen
@ 2024-09-10 19:57 ` Xi Pardee
0 siblings, 0 replies; 26+ messages in thread
From: Xi Pardee @ 2024-09-10 19:57 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: irenic.rajneesh, david.e.box, Hans de Goede, platform-driver-x86,
LKML, linux-pm
Hi, this email is resent because the last email was not delivered due to
some HTML error.
Sorry for the inconvenience. My response is in line.
On 8/29/2024 5:02 AM, Ilpo Järvinen wrote:
> On Wed, 28 Aug 2024, Xi Pardee wrote:
>
>> 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>
>> ---
>> drivers/platform/x86/intel/pmc/Kconfig | 11 ++
>> drivers/platform/x86/intel/pmc/Makefile | 8 +-
>> drivers/platform/x86/intel/pmc/arl.c | 14 ++-
>> drivers/platform/x86/intel/pmc/core.c | 59 ++++++---
>> drivers/platform/x86/intel/pmc/core.h | 6 +-
>> drivers/platform/x86/intel/pmc/mtl.c | 14 ++-
>> .../platform/x86/intel/pmc/ssram_telemetry.c | 118 +++++++++++-------
>> .../platform/x86/intel/pmc/ssram_telemetry.h | 45 +++++++
>> 8 files changed, 200 insertions(+), 75 deletions(-)
>> 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..c2ccd48fe266 100644
>> --- a/drivers/platform/x86/intel/pmc/Kconfig
>> +++ b/drivers/platform/x86/intel/pmc/Kconfig
>> @@ -8,6 +8,7 @@ config INTEL_PMC_CORE
>> depends on PCI
>> depends on ACPI
>> depends on INTEL_PMT_TELEMETRY
>> + depends on INTEL_PMC_SSRAM_TELEMETRY || !INTEL_PMC_SSRAM_TELEMETRY
>> help
>> The Intel Platform Controller Hub for Intel Core SoCs provides access
>> to Power Management Controller registers via various interfaces. This
>> @@ -24,3 +25,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.
>> \ No newline at end of file
>> diff --git a/drivers/platform/x86/intel/pmc/Makefile b/drivers/platform/x86/intel/pmc/Makefile
>> index 4dd9fa93f873..e935602af2a3 100644
>> --- a/drivers/platform/x86/intel/pmc/Makefile
>> +++ b/drivers/platform/x86/intel/pmc/Makefile
>> @@ -3,8 +3,12 @@
>> # Intel x86 Platform-Specific Drivers
>> #
>>
>> -intel_pmc_core-y := core.o ssram_telemetry.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
>> +
>> +# Intel PMC SSRAM driver
>> +intel_pmc_ssram_telemetry-y += ssram_telemetry.o
>> +obj-$(CONFIG_INTEL_PMC_SSRAM_TELEMETRY) += intel_pmc_ssram_telemetry.o
>> \ No newline at end of file
> Two files above are missing the last newline.
New line will be added in the next version.
>
>> diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c
>> index 0460715c58f4..25268b1fdf97 100644
>> --- a/drivers/platform/x86/intel/pmc/arl.c
>> +++ b/drivers/platform/x86/intel/pmc/arl.c
>> @@ -700,11 +700,13 @@ int arl_core_init(struct pmc_dev *pmcdev)
>> 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);
>> + 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) {
>> ssram_init = false;
>> pmc->map = &arl_socs_reg_map;
>> @@ -718,7 +720,7 @@ int arl_core_init(struct pmc_dev *pmcdev)
>> pmc_core_punit_pmt_init(pmcdev, ARL_PMT_DMU_GUID);
>>
>> if (ssram_init) {
>> - ret = pmc_core_ssram_get_lpm_reqs(pmcdev);
>> + ret = pmc_core_ssram_get_lpm_reqs(pmcdev, func);
>> if (ret)
>> return ret;
>> }
>> diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
>> index 8984041f35f4..19256c5570ab 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 */
>> @@ -1613,11 +1614,12 @@ static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *m
>> return 0;
>> }
>>
>> -static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
>> +static int pmc_core_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;
>> @@ -1630,11 +1632,16 @@ static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
>> if (!guid)
>> return -ENXIO;
>>
>> - ep = pmt_telem_find_and_register_endpoint(pmcdev->ssram_pcidev, guid, 0);
>> + 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));
>> - return -EPROBE_DEFER;
>> + ret = -EPROBE_DEFER;
>> + goto release_dev;
>> }
>>
>> pmc->lpm_req_regs = devm_kzalloc(&pmcdev->pdev->dev,
>> @@ -1710,23 +1717,22 @@ static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
>>
>> unregister_ep:
>> pmt_telem_unregister_endpoint(ep);
>> +release_dev:
>> + pci_dev_put(pcidev);
>>
>> return ret;
>> }
>>
>> -int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev)
>> +int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev, int func)
>> {
>> unsigned int i;
>> int ret;
>>
>> - 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]);
>> + ret = pmc_core_get_lpm_req(pmcdev, pmcdev->pmcs[i], func);
>> if (ret)
>> return ret;
>> }
>> @@ -1743,14 +1749,22 @@ const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
>> return NULL;
>> }
>>
>> -int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
>> - const struct pmc_reg_map *reg_map, unsigned int pmc_index)
>> +static int pmc_core_pmc_add(struct pmc_dev *pmcdev, unsigned int pmc_index)
>> {
>> - struct pmc *pmc = pmcdev->pmcs[pmc_index];
>> + struct pmc_ssram_telemetry pmc_ssram_telemetry;
>> + const struct pmc_reg_map *map;
>> + struct pmc *pmc;
>> + int ret;
>> +
>> + ret = pmc_ssram_telemetry_get_pmc_info(pmc_index, &pmc_ssram_telemetry);
>> + if (ret)
>> + return ret;
>>
>> - if (!pwrm_base)
>> + map = pmc_core_find_regmap(pmcdev->regmap_list, pmc_ssram_telemetry.devid);
>> + if (!map)
>> return -ENODEV;
>>
>> + pmc = pmcdev->pmcs[pmc_index];
>> /* Memory for primary PMC has been allocated in core.c */
>> if (!pmc) {
>> pmc = devm_kzalloc(&pmcdev->pdev->dev, sizeof(*pmc), GFP_KERNEL);
>> @@ -1758,8 +1772,8 @@ int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
>> return -ENOMEM;
>> }
>>
>> - pmc->map = reg_map;
>> - pmc->base_addr = pwrm_base;
>> + pmc->map = map;
>> + pmc->base_addr = pmc_ssram_telemetry.base_addr;
>> pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length);
>>
>> if (!pmc->regbase) {
>> @@ -1772,6 +1786,23 @@ int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
>> return 0;
>> }
>>
>> +int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev)
>> +{
>> + int ret;
>> +
>> + if (!pmcdev->regmap_list)
>> + return -ENOENT;
>> +
>> + ret = pmc_core_pmc_add(pmcdev, PMC_IDX_MAIN);
>> + if (ret)
>> + return ret;
>> +
>> + pmc_core_pmc_add(pmcdev, PMC_IDX_IOE);
>> + pmc_core_pmc_add(pmcdev, PMC_IDX_PCH);
>> +
>> + return 0;
>> +}
>> +
>> static const struct acpi_device_id pmc_core_acpi_ids[] = {
>> {"INT33A1", 0}, /* _HID for Intel Power Engine, _CID PNP0D80*/
>> { }
>> diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
>> index 5af1d41a83f7..2d62a71ec100 100644
>> --- a/drivers/platform/x86/intel/pmc/core.h
>> +++ b/drivers/platform/x86/intel/pmc/core.h
>> @@ -594,7 +594,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_ssram_get_lpm_reqs(struct pmc_dev *pmcdev);
>> +extern int pmc_core_ssram_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);
>> @@ -603,10 +603,8 @@ 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);
>> extern const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid);
>> -extern int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
>> - const struct pmc_reg_map *reg_map, unsigned int pmc_index);
>> +extern int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev);
>>
>> int spt_core_init(struct pmc_dev *pmcdev);
>> int cnp_core_init(struct pmc_dev *pmcdev);
>> diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
>> index e7f5b650902d..6ac52625a029 100644
>> --- a/drivers/platform/x86/intel/pmc/mtl.c
>> +++ b/drivers/platform/x86/intel/pmc/mtl.c
>> @@ -1000,11 +1000,13 @@ int mtl_core_init(struct pmc_dev *pmcdev)
>> 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);
>> + 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) {
>> ssram_init = false;
>> dev_warn(&pmcdev->pdev->dev,
>> @@ -1019,7 +1021,7 @@ int mtl_core_init(struct pmc_dev *pmcdev)
>> pmc_core_punit_pmt_init(pmcdev, MTL_PMT_DMU_GUID);
>>
>> if (ssram_init)
>> - return pmc_core_ssram_get_lpm_reqs(pmcdev);
>> + return pmc_core_ssram_get_lpm_reqs(pmcdev, func);
>>
>> return 0;
>> }
>> diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
>> index f625d39d1aa3..1c6cc95bfefa 100644
>> --- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
>> +++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
>> @@ -1,20 +1,19 @@
>> // SPDX-License-Identifier: GPL-2.0
>> /*
>> - * This file contains functions to handle discovery of PMC metrics located
>> - * in the PMC SSRAM PCI device.
>> + * Intel PMC SSRAM TELEMETRY PCI Driver
>> *
>> * Copyright (c) 2023, Intel Corporation.
>> * All Rights Reserved.
>> *
>> */
>>
>> -#include <linux/cleanup.h>
>> #include <linux/pci.h>
>> +#include <linux/types.h>
>> #include <linux/io-64-nonatomic-lo-hi.h>
>>
>> #include "core.h"
>> +#include "ssram_telemetry.h"
>> #include "../vsec.h"
>> -#include "../pmt/telemetry.h"
>>
>> #define SSRAM_HDR_SIZE 0x100
>> #define SSRAM_PWRM_OFFSET 0x14
>> @@ -24,12 +23,14 @@
>> #define SSRAM_IOE_OFFSET 0x68
>> #define SSRAM_DEVID_OFFSET 0x70
>>
>> -DEFINE_FREE(pmc_core_iounmap, void __iomem *, iounmap(_T));
>> +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_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram)
>> +pmc_ssram_telemetry_add_pmt(struct pci_dev *pcidev, 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;
>> @@ -58,7 +59,7 @@ pmc_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram)
>> info.caps = VSEC_CAP_TELEMETRY;
>> info.headers = headers;
>> info.base_addr = ssram_base;
>> - info.parent = &pmcdev->pdev->dev;
>> + info.parent = &pcidev->dev;
>>
>> intel_vsec_register(pcidev, &info);
>> }
>> @@ -69,19 +70,14 @@ static inline u64 get_base(void __iomem *addr, u32 offset)
>> }
>>
>> static int
>> -pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset)
>> +pmc_ssram_telemetry_get_pmc(struct pci_dev *pcidev, unsigned 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;
>> + 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;
>>
>> - if (!pmcdev->regmap_list)
>> - return -ENOENT;
>> -
>> - ssram_base = ssram_pcidev->resource[0].start;
>> + ssram_base = pcidev->resource[0].start;
>> tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
>>
>> if (!tmp_ssram)
>> @@ -105,46 +101,82 @@ pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset)
>> devid = readw(ssram + SSRAM_DEVID_OFFSET);
>>
>> /* Find and register and PMC telemetry entries */
>> - pmc_add_pmt(pmcdev, ssram_base, ssram);
>> + pmc_ssram_telemetry_add_pmt(pcidev, ssram_base, ssram);
>> +
>> + pmc_ssram_telems[pmc_idx].devid = devid;
>> + pmc_ssram_telems[pmc_idx].base_addr = pwrm_base;
>> +
>> + return 0;
>> +}
>>
>> - map = pmc_core_find_regmap(pmcdev->regmap_list, devid);
>> - if (!map)
>> +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;
> I'm very very skeptical this is safe. Without barriers, nothing guarantees
> you'll get the desired ordering. As is, device_probed could appear set
> before something else you depend on below this.
Thanks for the comments. Memory barrier should be added to ensure the
correct order of
load/store operation of device_probed variable.
Here is my proposed solution:
Add a write memory barrier smp_wmb right before setting device_probed to
true in the
intel_pmc_ssram_telemetry_probe function to ensure the store operation
order.
Add a read memory barrier smp_rmd after the check of device_probed in the
pmc_ssram_telemetry_get_pmc_info function to ensure the load operation
order.
These two barriers will ensure that the correct order of events being
perceived by the
consumers of this driver.
>
>> +
>> + if (pmc_idx >= MAX_NUM_PMC)
>> + return -EINVAL;
>> +
>> + if (!pmc_ssram_telems || !pmc_ssram_telems[pmc_idx].devid)
>> return -ENODEV;
>>
>> - return pmc_core_pmc_add(pmcdev, pwrm_base, map, pmc_idx);
>> + 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);
>>
>> -int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func)
>> +static int intel_pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
>> {
>> - struct pci_dev *pcidev;
>> int ret;
>>
>> - pcidev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(20, func));
>> - if (!pcidev)
>> - return -ENODEV;
>> + pmc_ssram_telems = devm_kzalloc(&pcidev->dev, sizeof(*pmc_ssram_telems) * MAX_NUM_PMC,
>> + GFP_KERNEL);
>> + if (!pmc_ssram_telems) {
>> + ret = -ENOMEM;
>> + goto probe_finish;
>> + }
>>
>> ret = pcim_enable_device(pcidev);
>> - if (ret)
>> - goto release_dev;
>> -
>> - pmcdev->ssram_pcidev = pcidev;
>> + if (ret) {
>> + dev_dbg(&pcidev->dev, "failed to enable PMC SSRAM device\n");
>> + goto probe_finish;
>> + }
>>
>> - ret = pmc_core_ssram_get_pmc(pmcdev, PMC_IDX_MAIN, 0);
>> + ret = pmc_ssram_telemetry_get_pmc(pcidev, PMC_IDX_MAIN, 0);
>> if (ret)
>> - goto disable_dev;
>> + goto probe_finish;
>>
>> - 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);
>> + pmc_ssram_telemetry_get_pmc(pcidev, PMC_IDX_IOE, SSRAM_IOE_OFFSET);
>> + pmc_ssram_telemetry_get_pmc(pcidev, 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_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_IMPORT_NS(INTEL_PMT_TELEMETRY);
>> +MODULE_AUTHOR("Xi Pardee <xi.pardee@intel.com>");
>> +MODULE_DESCRIPTION("Intel PMC SSRAM TELEMETRY driver");
> Telemetry ?
Will change in next version.
>
>> +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
> Telemetry ?
Will change in next version.
>
>> + *
>> + * Copyright (c) 2024, Intel Corporation.
>> + * All Rights Reserved.
>> + *
> Extra new line.
Will remove in next version.
Thanks!
Xi
>
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2024-09-10 19:57 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-28 22:29 [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver Xi Pardee
2024-08-28 22:29 ` [PATCH v2 01/11] platform/x86:intel/pmc: Move PMC Core related functions Xi Pardee
2024-08-29 10:49 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 02/11] platform/x86:intel/pmc: Rename core_ssram to ssram_telemetry Xi Pardee
2024-08-29 10:50 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 03/11] platform/x86:intel/pmc: Move PMC devid to core.h Xi Pardee
2024-08-29 10:52 ` Ilpo Järvinen
2024-09-10 6:55 ` Xi Pardee
2024-08-28 22:29 ` [PATCH v2 04/11] platform/x86:intel/pmc: Convert index variables to be unsigned Xi Pardee
2024-08-29 10:54 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 05/11] platform/x86:intel/pmc: Remove unneeded h file inclusion Xi Pardee
2024-08-29 11:02 ` Ilpo Järvinen
2024-09-10 7:08 ` Xi Pardee
2024-08-28 22:29 ` [PATCH v2 06/11] platform/x86:intel/pmc: Remove unneeded io operations Xi Pardee
2024-08-28 22:29 ` [PATCH v2 07/11] platform/x86:intel/pmc: Check return value of ioremap Xi Pardee
2024-08-29 11:06 ` Ilpo Järvinen
2024-09-10 6:53 ` Xi Pardee
2024-08-28 22:29 ` [PATCH v2 08/11] platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver Xi Pardee
2024-08-29 12:02 ` Ilpo Järvinen
2024-09-10 19:57 ` Xi Pardee
2024-08-28 22:29 ` [PATCH v2 09/11] platform/x86:intel/pmc: Add Lunar Lake SSRAM devid Xi Pardee
2024-08-29 12:03 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 10/11] platform/x86:intel/pmt: Get PMC from SSRAM for Lunar Lake Xi Pardee
2024-08-28 22:29 ` [PATCH v2 11/11] platform/x86:intel/pmc: Get LPM information " Xi Pardee
2024-08-29 12:13 ` Ilpo Järvinen
2024-09-10 0:49 ` Xi Pardee
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).