Update the PMC SSRAM discovery process to identify the device using its
PCI Device ID rather than relying on a fixed PCI bus location. The
enumeration of integrated devices on the PCI bus is no longer guaranteed
to be consistent across CPUs.
On earlier platforms, the IOE and PCH SSRAM devices were hidden from the
BIOS, and the SOC SSRAM device is associated to telemetry regions from all
available SSRAM devices. Starting with Nova Lake, the IOE and PCH SSRAM
devices register their telemetry regions independently, meaning each
telemetry region is now linked to its corresponding SSRAM device. A new
ssram_hidden attribute has been added to the pmc_dev_info structure to
reflect this distinction.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
Link: https://patch.msgid.link/20260505043342.2573556-5-xi.pardee@linux.intel.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
static u32 ARL_PMT_DMU_GUIDS[] = {ARL_PMT_DMU_GUID, 0x0};
struct pmc_dev_info arl_pmc_dev = {
- .pci_func = 0,
.dmu_guids = ARL_PMT_DMU_GUIDS,
.regmap_list = arl_pmc_info_list,
.map = &arl_socs_reg_map,
.resume = arl_resume,
.init = arl_core_init,
.sub_req = pmc_core_pmt_get_lpm_req,
+ .ssram_hidden = true,
};
static u32 ARL_H_PMT_DMU_GUIDS[] = {ARL_PMT_DMU_GUID, ARL_H_PMT_DMU_GUID, 0x0};
struct pmc_dev_info arl_h_pmc_dev = {
- .pci_func = 2,
.dmu_guids = ARL_H_PMT_DMU_GUIDS,
.regmap_list = arl_pmc_info_list,
.map = &mtl_socm_reg_map,
.resume = arl_h_resume,
.init = arl_h_core_init,
.sub_req = pmc_core_pmt_get_lpm_req,
+ .ssram_hidden = true,
};
static int pmc_core_get_telem_info(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
{
- struct pci_dev *pcidev __free(pci_dev_put) = NULL;
struct telem_endpoint *ep;
unsigned int pmc_idx;
int ret;
- pcidev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(20, pmc_dev_info->pci_func));
- if (!pcidev)
- return -ENODEV;
-
for (pmc_idx = 0; pmc_idx < ARRAY_SIZE(pmcdev->pmcs); ++pmc_idx) {
struct pmc *pmc;
+ u16 devid;
pmc = pmcdev->pmcs[pmc_idx];
if (!pmc)
if (!pmc->map->lpm_req_guid)
return -ENXIO;
+ if (pmc_dev_info->ssram_hidden)
+ devid = pmcdev->pmcs[PMC_IDX_MAIN]->devid;
+ else
+ devid = pmc->devid;
+
+ struct pci_dev *pcidev __free(pci_dev_put) =
+ pci_get_device(PCI_VENDOR_ID_INTEL, devid, NULL);
+ if (!pcidev)
+ return -ENODEV;
+
ep = pmt_telem_find_and_register_endpoint(&pcidev->dev, pmc->map->lpm_req_guid, 0);
if (IS_ERR(ep)) {
dev_dbg(&pmcdev->pdev->dev, "couldn't get telem endpoint %pe", ep);
pmc->map = map;
pmc->base_addr = pmc_ssram_telemetry.base_addr;
+ pmc->devid = pmc_ssram_telemetry.devid;
pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length);
if (!pmc->regbase) {
* @ltr_ign: Holds LTR ignore data while suspended
* @num_lpm_modes: Count of enabled modes
* @lpm_en_modes: Array of enabled modes from lowest to highest priority
+ * @devid: Device ID of the SSRAM device
*
* pmc contains info about one power management controller device.
*/
u32 ltr_ign;
u8 num_lpm_modes;
u8 lpm_en_modes[LPM_MAX_NUM_MODES];
+ u16 devid;
};
/**
/**
* struct pmc_dev_info - Structure to keep PMC device info
- * @pci_func: Function number of the primary PMC
* @dmu_guids: List of Die Management Unit GUID
* @pc_guid: GUID for telemetry region to read PKGC blocker info
* @pkgc_ltr_blocker_offset: Offset to PKGC LTR blockers in telemetry region
* @resume: Function to perform platform specific resume
* @init: Function to perform platform specific init action
* @sub_req: Function to achieve low power mode substate requirements
+ * @ssram_hidden: Some SSRAM devices are hidden on this platform
*/
struct pmc_dev_info {
- u8 pci_func;
u32 *dmu_guids;
u32 pc_guid;
u32 pkgc_ltr_blocker_offset;
int (*resume)(struct pmc_dev *pmcdev);
int (*init)(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info);
int (*sub_req)(struct pmc_dev *pmcdev, struct pmc *pmc, struct telem_endpoint *ep);
+ bool ssram_hidden;
};
extern const struct pmc_bit_map msr_map[];
}
struct pmc_dev_info lnl_pmc_dev = {
- .pci_func = 2,
.regmap_list = lnl_pmc_info_list,
.map = &lnl_socm_reg_map,
.sub_req_show = &pmc_core_substate_req_regs_fops,
.resume = lnl_resume,
.init = lnl_core_init,
.sub_req = pmc_core_pmt_get_lpm_req,
+ .ssram_hidden = true,
};
static u32 MTL_PMT_DMU_GUIDS[] = {MTL_PMT_DMU_GUID, 0x0};
struct pmc_dev_info mtl_pmc_dev = {
- .pci_func = 2,
.dmu_guids = MTL_PMT_DMU_GUIDS,
.regmap_list = mtl_pmc_info_list,
.map = &mtl_socm_reg_map,
.resume = mtl_resume,
.init = mtl_core_init,
.sub_req = pmc_core_pmt_get_lpm_req,
+ .ssram_hidden = true,
};
}
struct pmc_dev_info ptl_pmc_dev = {
- .pci_func = 2,
.regmap_list = ptl_pmc_info_list,
.map = &ptl_pcdp_reg_map,
.sub_req_show = &pmc_core_substate_blk_req_fops,
.resume = ptl_resume,
.init = ptl_core_init,
.sub_req = pmc_core_pmt_get_blk_sub_req,
+ .ssram_hidden = true,
};
}
struct pmc_dev_info wcl_pmc_dev = {
- .pci_func = 2,
.regmap_list = wcl_pmc_info_list,
.map = &wcl_pcdn_reg_map,
.sub_req_show = &pmc_core_substate_blk_req_fops,
.resume = wcl_resume,
.init = wcl_core_init,
.sub_req = pmc_core_pmt_get_blk_sub_req,
+ .ssram_hidden = true,
};