diff options
Diffstat (limited to 'drivers/platform/x86/intel/tpmi.c')
-rw-r--r-- | drivers/platform/x86/intel/tpmi.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/drivers/platform/x86/intel/tpmi.c b/drivers/platform/x86/intel/tpmi.c index 910df7c654f4..6c0cbccd80bb 100644 --- a/drivers/platform/x86/intel/tpmi.c +++ b/drivers/platform/x86/intel/tpmi.c @@ -128,6 +128,9 @@ struct intel_tpmi_info { * @dev: PCI device number * @bus: PCI bus number * @pkg: CPU Package id + * @segment: PCI segment id + * @partition: Package Partition id + * @cdie_mask: Bitmap of compute dies in the current partition * @reserved: Reserved for future use * @lock: When set to 1 the register is locked and becomes read-only * until next reset. Not for use by the OS driver. @@ -139,7 +142,10 @@ struct tpmi_info_header { u64 dev:5; u64 bus:8; u64 pkg:8; - u64 reserved:39; + u64 segment:8; + u64 partition:2; + u64 cdie_mask:16; + u64 reserved:13; u64 lock:1; } __packed; @@ -666,28 +672,44 @@ static int tpmi_create_devices(struct intel_tpmi_info *tpmi_info) } #define TPMI_INFO_BUS_INFO_OFFSET 0x08 +#define TPMI_INFO_MAJOR_VERSION 0x00 +#define TPMI_INFO_MINOR_VERSION 0x02 static int tpmi_process_info(struct intel_tpmi_info *tpmi_info, struct intel_tpmi_pm_feature *pfs) { struct tpmi_info_header header; void __iomem *info_mem; + u64 feature_header; + int ret = 0; - info_mem = ioremap(pfs->vsec_offset + TPMI_INFO_BUS_INFO_OFFSET, - pfs->pfs_header.entry_size * sizeof(u32) - TPMI_INFO_BUS_INFO_OFFSET); + info_mem = ioremap(pfs->vsec_offset, pfs->pfs_header.entry_size * sizeof(u32)); if (!info_mem) return -ENOMEM; - memcpy_fromio(&header, info_mem, sizeof(header)); + feature_header = readq(info_mem); + if (TPMI_MAJOR_VERSION(feature_header) != TPMI_INFO_MAJOR_VERSION) { + ret = -ENODEV; + goto error_info_header; + } + + memcpy_fromio(&header, info_mem + TPMI_INFO_BUS_INFO_OFFSET, sizeof(header)); tpmi_info->plat_info.package_id = header.pkg; tpmi_info->plat_info.bus_number = header.bus; tpmi_info->plat_info.device_number = header.dev; tpmi_info->plat_info.function_number = header.fn; + if (TPMI_MINOR_VERSION(feature_header) >= TPMI_INFO_MINOR_VERSION) { + tpmi_info->plat_info.cdie_mask = header.cdie_mask; + tpmi_info->plat_info.partition = header.partition; + tpmi_info->plat_info.segment = header.segment; + } + +error_info_header: iounmap(info_mem); - return 0; + return ret; } static int tpmi_fetch_pfs_header(struct intel_tpmi_pm_feature *pfs, u64 start, int size) @@ -763,8 +785,11 @@ static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev) * when actual device nodes created outside this * loop via tpmi_create_devices(). */ - if (pfs->pfs_header.tpmi_id == TPMI_INFO_ID) - tpmi_process_info(tpmi_info, pfs); + if (pfs->pfs_header.tpmi_id == TPMI_INFO_ID) { + ret = tpmi_process_info(tpmi_info, pfs); + if (ret) + return ret; + } if (pfs->pfs_header.tpmi_id == TPMI_CONTROL_ID) tpmi_set_control_base(auxdev, tpmi_info, pfs); |