Create Intel PMC SSRAM Telemetry driver
Subsystems (2)
Xi Pardee
maintainerv2 cover Create Intel PMC SSRAM Telemetry driver
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
Signature · 1 line
2.43.0
Xi Pardee
maintainerPATCH v2 1/11 platform/x86:intel/pmc: Move PMC Core related functions
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.
--- 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(-)
drivers/platform/x86/intel/pmc/core.c +168 -0
@@ -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" );
drivers/platform/x86/intel/pmc/core.h +8 -0
@@ -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);
drivers/platform/x86/intel/pmc/core_ssram.c +0 -173
192 lines not on this page · raw message
Signature · 1 line
2.43.0
Re: [PATCH v2 01/11] platform/x86:intel/pmc: Move PMC Core related functions
Quoted 5 lines · Xi Pardee
Move functions that implements PMC Core feature from
core_ssram.ctocore.c. This patch is a preparation step to introduce a new SSRAM Telemetry driver for the SSRAM device.Signed-off-by Xi Pardee <[email protected]>
Quoted 416 lines
--- 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(-)drivers/platform/x86/intel/pmc/core.c +168
-0@@ -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" );drivers/platform/x86/intel/pmc/core.h +8
-0@@ -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);drivers/platform/x86/intel/pmc/core_ssram.c +0
-173@@ -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) {
Signature · 1 line
i.
Xi Pardee
maintainerPATCH v2 2/11 platform/x86:intel/pmc: Rename core_ssram to ssram_telemetry
In reply to Xi PardeeRename core_ssram.c to ssram_telemetry.c. This patch is a preparation step to introduce a new SSRAM Telemetry driver for the SSRAM device.
---
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%)drivers/platform/x86/intel/pmc/Makefile +1 -1
@@ -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
drivers/platform/x86/intel/pmc/ssram_telemetry.c renamed from drivers/platform/x86/intel/pmc/core_ssram.c +0 -0
Signature · 1 line
2.43.0
Re: [PATCH v2 02/11] platform/x86:intel/pmc: Rename core_ssram to ssram_telemetry
Quoted 5 lines · Xi Pardee
Rename
core_ssram.ctossram_telemetry.c. This patch is a preparation step to introduce a new SSRAM Telemetry driver for the SSRAM device.Signed-off-by Xi Pardee <[email protected]>
Signature · 1 line
i.
Quoted 24 lines
--- 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%)drivers/platform/x86/intel/pmc/Makefile +1
-1@@ -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.odrivers/platform/x86/intel/pmc/ssram_telemetry.c renamed from drivers/platform/x86/intel/pmc/core_ssram.c +0
-0
Xi Pardee
maintainerPATCH v2 3/11 platform/x86:intel/pmc: Move PMC devid to core.h
In reply to Xi PardeeMove 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.
--- 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(-)
drivers/platform/x86/intel/pmc/arl.c +3 -6
@@ -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 0x7f27static 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, }, {}
drivers/platform/x86/intel/pmc/core.h +10 -0
@@ -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 {
drivers/platform/x86/intel/pmc/mtl.c +3 -6
@@ -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 0x7ebfstatic 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 }, {}
Signature · 1 line
2.43.0
Re: [PATCH v2 03/11] platform/x86:intel/pmc: Move PMC devid to core.h
Quoted 48 lines · Xi Pardee
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 <[email protected]>--- 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(-)drivers/platform/x86/intel/pmc/arl.c +3
-6@@ -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 0x7f27static 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, }, {}drivers/platform/x86/intel/pmc/core.h +0
-0
drivers/platform/x86/intel/pmc/core.h enum ppfear_regs { · line 293
Quoted 4 lines
drivers/platform/x86/intel/pmc/core.h +1
-0@@ -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.
Signature · 1 line
i.
Quoted 44 lines
drivers/platform/x86/intel/pmc/core.h +9
-0+/* 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 {drivers/platform/x86/intel/pmc/mtl.c +3
-6@@ -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 0x7ebfstatic 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 }, {}
Xi Pardee
maintainerRe: [PATCH v2 03/11] platform/x86:intel/pmc: Move PMC devid to core.h
Quoted 53 lines · Ilpo Järvinen
Quoted 51 lines · Xi Pardee
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 <[email protected]>--- 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(-)drivers/platform/x86/intel/pmc/arl.c +3
-6@@ -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 0x7f27static 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, }, {}drivers/platform/x86/intel/pmc/core.h +0
-0@@ -290,6 +290,16 @@ enum ppfear_regs {#define LNL_PPFEAR_NUM_ENTRIES 12#define LNL_S0IX_BLOCKER_OFFSET 0x2004
Quoted 4 lines
drivers/platform/x86/intel/pmc/core.h enum ppfear_regs { · line 293
Quoted 1 line
drivers/platform/x86/intel/pmc/core.h +1
-0+/* SSRAM PMC Device ID*/ Missing space.
Reviewed-by Ilpo Järvinen <[email protected]>
Will add a space in next version.
Thanks!
Xi
Quoted 1 line
Xi Pardee
maintainerPATCH v2 4/11 platform/x86:intel/pmc: Convert index variables to be unsigned
In reply to Xi PardeeConvert the index variables type to be unsigned to avoid confusion and error.
--- 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(-)
drivers/platform/x86/intel/pmc/core.c +3 -2
@@ -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];
drivers/platform/x86/intel/pmc/core.h +1 -1
@@ -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);
drivers/platform/x86/intel/pmc/ssram_telemetry.c +1 -1
@@ -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;
Signature · 1 line
2.43.0
Re: [PATCH v2 04/11] platform/x86:intel/pmc: Convert index variables to be unsigned
Quoted 4 lines · Xi Pardee
Convert the index variables type to be unsigned to avoid confusion and error.
Signed-off-by Xi Pardee <[email protected]>
Signature · 1 line
i.
Quoted 56 lines
--- 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(-)drivers/platform/x86/intel/pmc/core.c +3
-2@@ -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];drivers/platform/x86/intel/pmc/core.h +1
-1@@ -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);drivers/platform/x86/intel/pmc/ssram_telemetry.c +1
-1@@ -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;
Xi Pardee
maintainerPATCH v2 5/11 platform/x86:intel/pmc: Remove unneeded h file inclusion
In reply to Xi Pardeetelemetry.h header file is not needed in arl.c or mtl.c. Remove them to avoid confusion.
--- drivers/platform/x86/intel/pmc/arl.c | 1 - drivers/platform/x86/intel/pmc/mtl.c | 1 - 2 files changed, 2 deletions(-)
drivers/platform/x86/intel/pmc/arl.c +0 -1
@@ -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
drivers/platform/x86/intel/pmc/mtl.c +0 -1
@@ -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
Signature · 1 line
2.43.0
Re: [PATCH v2 05/11] platform/x86:intel/pmc: Remove unneeded h file inclusion
On Wed, 28 Aug 2024, Xi Pardee wrote:
In the subject:
h file -> header
Quoted 2 lines
telemetry.hheader file is not needed inarl.cormtl.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.
Signature · 1 line
i.
Quoted 31 lines
Signed-off-by Xi Pardee <[email protected]>--- drivers/platform/x86/intel/pmc/arl.c | 1 - drivers/platform/x86/intel/pmc/mtl.c | 1 - 2 files changed, 2 deletions(-)drivers/platform/x86/intel/pmc/arl.c +0
-1@@ -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 0x5077612drivers/platform/x86/intel/pmc/mtl.c +0
-1@@ -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
Xi Pardee
maintainerRe: [PATCH v2 05/11] platform/x86:intel/pmc: Remove unneeded h file inclusion
Quoted 8 lines · Ilpo Järvinen
On Wed, 28 Aug 2024, Xi Pardee wrote:
In the subject:
h file -> header
Quoted 2 lines
telemetry.hheader file is not needed inarl.cormtl.c. Remove them to avoid confusion.
Quoted 7 lines
I'd also note this is cross directory/driver include, so perhaps something along these lines:
telemetry.hfrom PMT is not needed inarl.cormtl.cso remove the cross-driver include.Reviewed-by Ilpo Järvinen <[email protected]>
Thanks! I will modify the commit message in the next version.
Xi
Xi Pardee
maintainerPATCH v2 6/11 platform/x86:intel/pmc: Remove unneeded io operations
In reply to Xi PardeeRemove ioremap and iounmap operations that are not needed. ioremap and iounmap operations are handled by the caller of the pmc_add_pmt function.
--- drivers/platform/x86/intel/pmc/ssram_telemetry.c | 6 ------ 1 file changed, 6 deletions(-)
drivers/platform/x86/intel/pmc/ssram_telemetry.c +0 -6
@@ -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 ;
Signature · 1 line
2.43.0
Xi Pardee
maintainerPATCH v2 7/11 platform/x86:intel/pmc: Check return value of ioremap
In reply to Xi PardeeCheck the return value of ioremap operation and return ENOMEM when the operation fails for better error handling.
--- drivers/platform/x86/intel/pmc/ssram_telemetry.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/platform/x86/intel/pmc/ssram_telemetry.c +3 -0
@@ -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)
Signature · 1 line
2.43.0
Ilpo Järvinen
maintainerRe: [PATCH v2 07/11] platform/x86:intel/pmc: Check return value of ioremap
Quoted 13 lines · Xi Pardee
Check the return value of ioremap operation and return ENOMEM when the operation fails for better error handling.
Signed-off-by Xi Pardee <[email protected]>--- drivers/platform/x86/intel/pmc/ssram_telemetry.c | 3 +++ 1 file changed, 3 insertions(+)drivers/platform/x86/intel/pmc/ssram_telemetry.c +0
-0
drivers/platform/x86/intel/pmc/ssram_telemetry.c pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset) · line 92
Quoted 9 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c +3
-0@@ -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?
Signature · 1 line
i.
Xi Pardee
maintainerRe: [PATCH v2 07/11] platform/x86:intel/pmc: Check return value of ioremap
Quoted 18 lines · Ilpo Järvinen
Quoted 16 lines · Xi Pardee
Check the return value of ioremap operation and return ENOMEM when the operation fails for better error handling.
Signed-off-by Xi Pardee <[email protected]>--- drivers/platform/x86/intel/pmc/ssram_telemetry.c | 3 +++ 1 file changed, 3 insertions(+)drivers/platform/x86/intel/pmc/ssram_telemetry.c +0
-0@@ -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 );
Quoted 8 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset) · line 92
Quoted 6 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c +3
-0+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
Quoted 1 line
Xi Pardee
maintainerPATCH v2 8/11 platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver
In reply to Xi PardeeConvert 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.
--- 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
drivers/platform/x86/intel/pmc/Kconfig +11 -0
@@ -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.
drivers/platform/x86/intel/pmc/Makefile +6 -2
@@ -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
drivers/platform/x86/intel/pmc/arl.c +8 -6
@@ -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; }
drivers/platform/x86/intel/pmc/core.c +45 -14
124 lines not on this page · raw message
drivers/platform/x86/intel/pmc/core.h +2 -4
@@ -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);
drivers/platform/x86/intel/pmc/mtl.c +8 -6
@@ -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 ; }
drivers/platform/x86/intel/pmc/ssram_telemetry.c +75 -43
179 lines not on this page · raw message
drivers/platform/x86/intel/pmc/ssram_telemetry.h new file +45 -0
45 lines not on this page · raw message
Signature · 1 line
2.43.0
Ilpo Järvinen
maintainerRe: [PATCH v2 08/11] platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver
Quoted 62 lines · Xi Pardee
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 <[email protected]>--- 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.hdrivers/platform/x86/intel/pmc/Kconfig +11
-0@@ -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.drivers/platform/x86/intel/pmc/Makefile +0
-2@@ -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
drivers/platform/x86/intel/pmc/Makefile line 14
Quoted 10 lines
drivers/platform/x86/intel/pmc/Makefile +6
-0+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
Two files above are missing the last newline.
Quoted 319 lines
drivers/platform/x86/intel/pmc/arl.c +8
-6@@ -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; }drivers/platform/x86/intel/pmc/core.c +45
-14@@ -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 *mreturn 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*/ { }drivers/platform/x86/intel/pmc/core.h +2
-4@@ -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);drivers/platform/x86/intel/pmc/mtl.c +8
-6@@ -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 ; }drivers/platform/x86/intel/pmc/ssram_telemetry.c +21
-20@@ -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,
drivers/platform/x86/intel/pmc/ssram_telemetry.c pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset) · line 122
Quoted 10 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c +10
-0+ 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.
Quoted 72 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c +35
-22+ +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 = {
drivers/platform/x86/intel/pmc/ssram_telemetry.c pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset) · line 181
Quoted 10 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c +8
-1+ .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 <[email protected]>" ); +MODULE_DESCRIPTION ("Intel PMC SSRAM TELEMETRY driver" );
Telemetry ?
drivers/platform/x86/intel/pmc/ssram_telemetry.h line 3
Quoted 10 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c +1
-0+MODULE_LICENSE ("GPL" );drivers/platform/x86/intel/pmc/ssram_telemetry.h new file +3
-0@@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Intel PMC SSRAM TELEMETRY PCI Driver Header File
Telemetry ?
drivers/platform/x86/intel/pmc/ssram_telemetry.h line 7
Quoted 4 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.h new file +4
-0+* +* Copyright (c) 2024, Intel Corporation. +* All Rights Reserved. +*
Extra new line.
Signature · 1 line
i.
Quoted 39 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.h new file +38
-0+*/ + +#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 */
Xi Pardee
maintainerRe: [PATCH v2 08/11] platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver
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.
Quoted 62 lines · Ilpo Järvinen
Quoted 60 lines · Xi Pardee
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 <[email protected]>--- 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.hdrivers/platform/x86/intel/pmc/Kconfig +11
-0@@ -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.drivers/platform/x86/intel/pmc/Makefile +0
-0@@ -3,8 +3,12 @@ # Intel x86 Platform-Specific Drivers #
Quoted 13 lines
drivers/platform/x86/intel/pmc/Makefile line 14
Quoted 12 lines
drivers/platform/x86/intel/pmc/Makefile +6
-2-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.oTwo files above are missing the last newline.
New line will be added in the next version.
Quoted 317 lines
Quoted 317 lines
drivers/platform/x86/intel/pmc/arl.c +8
-6@@ -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; }drivers/platform/x86/intel/pmc/core.c +45
-14@@ -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 *mreturn 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*/ { }drivers/platform/x86/intel/pmc/core.h +2
-4@@ -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);drivers/platform/x86/intel/pmc/mtl.c +8
-6@@ -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 ; }drivers/platform/x86/intel/pmc/ssram_telemetry.c +20
-18@@ -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 ; +}
Quoted 16 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset) · line 122
Quoted 13 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c +11
-2- 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_probedcould 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.
Quoted 76 lines
Quoted 76 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c +38
-22+ +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,
Quoted 8 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, unsigned int pmc_idx, u32 offset) · line 181
Quoted 7 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c +5
-1+}; +module_pci_driver (intel_pmc_ssram_telemetry_driver); +MODULE_IMPORT_NS (INTEL_VSEC ); -MODULE_IMPORT_NS (INTEL_PMT_TELEMETRY ); +MODULE_AUTHOR ("Xi Pardee <[email protected]>" ); +MODULE_DESCRIPTION ("Intel PMC SSRAM TELEMETRY driver" );Telemetry ?
Will change in next version.
Quoted 12 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.h line 3
Quoted 11 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c +1
-0+MODULE_LICENSE ("GPL" );drivers/platform/x86/intel/pmc/ssram_telemetry.h new file +3
-0@@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Intel PMC SSRAM TELEMETRY PCI Driver Header File Telemetry ?
Will change in next version.
Quoted 6 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.h line 7
Quoted 5 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.h new file +4
-0+* +* Copyright (c) 2024, Intel Corporation. +* All Rights Reserved. +* Extra new line.
Will remove in next version.
Thanks!
Xi
Quoted 1 line
Xi Pardee
maintainerPATCH v2 9/11 platform/x86:intel/pmc: Add Lunar Lake SSRAM devid
In reply to Xi PardeeEnable SSRAM device Lunar Lake support by adding Lunar Lake SSRAM devid to Intel SSRAM Telemetry driver.
--- drivers/platform/x86/intel/pmc/core.h | 3 +++ drivers/platform/x86/intel/pmc/ssram_telemetry.c | 1 + 2 files changed, 4 insertions(+)
drivers/platform/x86/intel/pmc/core.h +3 -0
@@ -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 {
drivers/platform/x86/intel/pmc/ssram_telemetry.c +1 -0
@@ -165,6 +165,7 @@ static int intel_pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const structstatic 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);
Signature · 1 line
2.43.0
Re: [PATCH v2 09/11] platform/x86:intel/pmc: Add Lunar Lake SSRAM devid
Quoted 29 lines · Xi Pardee
Enable SSRAM device Lunar Lake support by adding Lunar Lake SSRAM devid to Intel SSRAM Telemetry driver.
Signed-off-by Xi Pardee <[email protected]>--- drivers/platform/x86/intel/pmc/core.h | 3 +++ drivers/platform/x86/intel/pmc/ssram_telemetry.c | 1 + 2 files changed, 4 insertions(+)drivers/platform/x86/intel/pmc/core.h +3
-0@@ -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 {drivers/platform/x86/intel/pmc/ssram_telemetry.c +0
-0
drivers/platform/x86/intel/pmc/ssram_telemetry.c static int intel_pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct · line 171
Quoted 7 lines
drivers/platform/x86/intel/pmc/ssram_telemetry.c +1
-0@@ -165,6 +165,7 @@ static int intel_pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const structstatic 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);
Signature · 1 line
i.
Xi Pardee
maintainerPATCH v2 10/11 platform/x86:intel/pmt: Get PMC from SSRAM for Lunar Lake
In reply to Xi PardeeAdd support to discover and achieve PMC information from Intel SSRAM Telemetry driver for Lunar Lake platforms.
--- drivers/platform/x86/intel/pmc/lnl.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-)
drivers/platform/x86/intel/pmc/lnl.c +22 -4
@@ -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);
Signature · 1 line
2.43.0
Xi Pardee
maintainerPATCH v2 11/11 platform/x86:intel/pmc: Get LPM information for Lunar Lake
In reply to Xi PardeeAdd support to find and read the requirements from the telemetry entries for Lunar Lake platforms.
--- drivers/platform/x86/intel/pmc/lnl.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
drivers/platform/x86/intel/pmc/lnl.c +15 -0
@@ -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 ; }
Signature · 1 line
2.43.0
Ilpo Järvinen
maintainerRe: [PATCH v2 11/11] platform/x86:intel/pmc: Get LPM information for Lunar Lake
Quoted 52 lines · Xi Pardee
Add support to find and read the requirements from the telemetry entries for Lunar Lake platforms.
Signed-off-by Xi Pardee <[email protected]>--- drivers/platform/x86/intel/pmc/lnl.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)drivers/platform/x86/intel/pmc/lnl.c +9
-0@@ -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)
drivers/platform/x86/intel/pmc/lnl.c int lnl_core_init(struct pmc_dev *pmcdev) · line 601
Quoted 7 lines
drivers/platform/x86/intel/pmc/lnl.c +4
-0@@ -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.
Signature · 1 line
i.
Xi Pardee
maintainerRe: [PATCH v2 11/11] platform/x86:intel/pmc: Get LPM information for Lunar Lake
Quoted 57 lines · Ilpo Järvinen
Quoted 55 lines · Xi Pardee
Add support to find and read the requirements from the telemetry entries for Lunar Lake platforms.
Signed-off-by Xi Pardee <[email protected]>--- drivers/platform/x86/intel/pmc/lnl.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)drivers/platform/x86/intel/pmc/lnl.c +9
-0@@ -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);
Quoted 7 lines
drivers/platform/x86/intel/pmc/lnl.c int lnl_core_init(struct pmc_dev *pmcdev) · line 601
Quoted 4 lines
drivers/platform/x86/intel/pmc/lnl.c +4
-0+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.cusing 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