1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * intel-tpmi : Driver to enumerate TPMI features and create devices 4 * 5 * Copyright (c) 2023, Intel Corporation. 6 * All Rights Reserved. 7 * 8 * The TPMI (Topology Aware Register and PM Capsule Interface) provides a 9 * flexible, extendable and PCIe enumerable MMIO interface for PM features. 10 * 11 * For example Intel RAPL (Running Average Power Limit) provides a MMIO 12 * interface using TPMI. This has advantage over traditional MSR 13 * (Model Specific Register) interface, where a thread needs to be scheduled 14 * on the target CPU to read or write. Also the RAPL features vary between 15 * CPU models, and hence lot of model specific code. Here TPMI provides an 16 * architectural interface by providing hierarchical tables and fields, 17 * which will not need any model specific implementation. 18 * 19 * The TPMI interface uses a PCI VSEC structure to expose the location of 20 * MMIO region. 21 * 22 * This VSEC structure is present in the PCI configuration space of the 23 * Intel Out-of-Band (OOB) device, which is handled by the Intel VSEC 24 * driver. The Intel VSEC driver parses VSEC structures present in the PCI 25 * configuration space of the given device and creates an auxiliary device 26 * object for each of them. In particular, it creates an auxiliary device 27 * object representing TPMI that can be bound by an auxiliary driver. 28 * 29 * This TPMI driver will bind to the TPMI auxiliary device object created 30 * by the Intel VSEC driver. 31 * 32 * The TPMI specification defines a PFS (PM Feature Structure) table. 33 * This table is present in the TPMI MMIO region. The starting address 34 * of PFS is derived from the tBIR (Bar Indicator Register) and "Address" 35 * field from the VSEC header. 36 * 37 * Each TPMI PM feature has one entry in the PFS with a unique TPMI 38 * ID and its access details. The TPMI driver creates device nodes 39 * for the supported PM features. 40 * 41 * The names of the devices created by the TPMI driver start with the 42 * "intel_vsec.tpmi-" prefix which is followed by a specific name of the 43 * given PM feature (for example, "intel_vsec.tpmi-rapl.0"). 44 * 45 * The device nodes are create by using interface "intel_vsec_add_aux()" 46 * provided by the Intel VSEC driver. 47 */ 48 49 #include <linux/auxiliary_bus.h> 50 #include <linux/intel_tpmi.h> 51 #include <linux/io.h> 52 #include <linux/module.h> 53 #include <linux/pci.h> 54 55 #include "vsec.h" 56 57 /** 58 * struct intel_tpmi_pfs_entry - TPMI PM Feature Structure (PFS) entry 59 * @tpmi_id: TPMI feature identifier (what the feature is and its data format). 60 * @num_entries: Number of feature interface instances present in the PFS. 61 * This represents the maximum number of Power domains in the SoC. 62 * @entry_size: Interface instance entry size in 32-bit words. 63 * @cap_offset: Offset from the PM_Features base address to the base of the PM VSEC 64 * register bank in KB. 65 * @attribute: Feature attribute: 0=BIOS. 1=OS. 2-3=Reserved. 66 * @reserved: Bits for use in the future. 67 * 68 * Represents one TPMI feature entry data in the PFS retrieved as is 69 * from the hardware. 70 */ 71 struct intel_tpmi_pfs_entry { 72 u64 tpmi_id:8; 73 u64 num_entries:8; 74 u64 entry_size:16; 75 u64 cap_offset:16; 76 u64 attribute:2; 77 u64 reserved:14; 78 } __packed; 79 80 /** 81 * struct intel_tpmi_pm_feature - TPMI PM Feature information for a TPMI ID 82 * @pfs_header: PFS header retireved from the hardware. 83 * @vsec_offset: Starting MMIO address for this feature in bytes. Essentially 84 * this offset = "Address" from VSEC header + PFS Capability 85 * offset for this feature entry. 86 * 87 * Represents TPMI instance information for one TPMI ID. 88 */ 89 struct intel_tpmi_pm_feature { 90 struct intel_tpmi_pfs_entry pfs_header; 91 unsigned int vsec_offset; 92 }; 93 94 /** 95 * struct intel_tpmi_info - TPMI information for all IDs in an instance 96 * @tpmi_features: Pointer to a list of TPMI feature instances 97 * @vsec_dev: Pointer to intel_vsec_device structure for this TPMI device 98 * @feature_count: Number of TPMI of TPMI instances pointed by tpmi_features 99 * @pfs_start: Start of PFS offset for the TPMI instances in this device 100 * @plat_info: Stores platform info which can be used by the client drivers 101 * 102 * Stores the information for all TPMI devices enumerated from a single PCI device. 103 */ 104 struct intel_tpmi_info { 105 struct intel_tpmi_pm_feature *tpmi_features; 106 struct intel_vsec_device *vsec_dev; 107 int feature_count; 108 u64 pfs_start; 109 struct intel_tpmi_plat_info plat_info; 110 }; 111 112 /** 113 * struct tpmi_info_header - CPU package ID to PCI device mapping information 114 * @fn: PCI function number 115 * @dev: PCI device number 116 * @bus: PCI bus number 117 * @pkg: CPU Package id 118 * @reserved: Reserved for future use 119 * @lock: When set to 1 the register is locked and becomes read-only 120 * until next reset. Not for use by the OS driver. 121 * 122 * The structure to read hardware provided mapping information. 123 */ 124 struct tpmi_info_header { 125 u64 fn:3; 126 u64 dev:5; 127 u64 bus:8; 128 u64 pkg:8; 129 u64 reserved:39; 130 u64 lock:1; 131 } __packed; 132 133 /* 134 * List of supported TMPI IDs. 135 * Some TMPI IDs are not used by Linux, so the numbers are not consecutive. 136 */ 137 enum intel_tpmi_id { 138 TPMI_ID_RAPL = 0, /* Running Average Power Limit */ 139 TPMI_ID_PEM = 1, /* Power and Perf excursion Monitor */ 140 TPMI_ID_UNCORE = 2, /* Uncore Frequency Scaling */ 141 TPMI_ID_SST = 5, /* Speed Select Technology */ 142 TPMI_INFO_ID = 0x81, /* Special ID for PCI BDF and Package ID information */ 143 }; 144 145 /* Used during auxbus device creation */ 146 static DEFINE_IDA(intel_vsec_tpmi_ida); 147 148 struct intel_tpmi_plat_info *tpmi_get_platform_data(struct auxiliary_device *auxdev) 149 { 150 struct intel_vsec_device *vsec_dev = auxdev_to_ivdev(auxdev); 151 152 return vsec_dev->priv_data; 153 } 154 EXPORT_SYMBOL_NS_GPL(tpmi_get_platform_data, INTEL_TPMI); 155 156 int tpmi_get_resource_count(struct auxiliary_device *auxdev) 157 { 158 struct intel_vsec_device *vsec_dev = auxdev_to_ivdev(auxdev); 159 160 if (vsec_dev) 161 return vsec_dev->num_resources; 162 163 return 0; 164 } 165 EXPORT_SYMBOL_NS_GPL(tpmi_get_resource_count, INTEL_TPMI); 166 167 struct resource *tpmi_get_resource_at_index(struct auxiliary_device *auxdev, int index) 168 { 169 struct intel_vsec_device *vsec_dev = auxdev_to_ivdev(auxdev); 170 171 if (vsec_dev && index < vsec_dev->num_resources) 172 return &vsec_dev->resource[index]; 173 174 return NULL; 175 } 176 EXPORT_SYMBOL_NS_GPL(tpmi_get_resource_at_index, INTEL_TPMI); 177 178 static const char *intel_tpmi_name(enum intel_tpmi_id id) 179 { 180 switch (id) { 181 case TPMI_ID_RAPL: 182 return "rapl"; 183 case TPMI_ID_PEM: 184 return "pem"; 185 case TPMI_ID_UNCORE: 186 return "uncore"; 187 case TPMI_ID_SST: 188 return "sst"; 189 default: 190 return NULL; 191 } 192 } 193 194 /* String Length for tpmi-"feature_name(upto 8 bytes)" */ 195 #define TPMI_FEATURE_NAME_LEN 14 196 197 static int tpmi_create_device(struct intel_tpmi_info *tpmi_info, 198 struct intel_tpmi_pm_feature *pfs, 199 u64 pfs_start) 200 { 201 struct intel_vsec_device *vsec_dev = tpmi_info->vsec_dev; 202 char feature_id_name[TPMI_FEATURE_NAME_LEN]; 203 struct intel_vsec_device *feature_vsec_dev; 204 struct resource *res, *tmp; 205 const char *name; 206 int i; 207 208 name = intel_tpmi_name(pfs->pfs_header.tpmi_id); 209 if (!name) 210 return -EOPNOTSUPP; 211 212 res = kcalloc(pfs->pfs_header.num_entries, sizeof(*res), GFP_KERNEL); 213 if (!res) 214 return -ENOMEM; 215 216 feature_vsec_dev = kzalloc(sizeof(*feature_vsec_dev), GFP_KERNEL); 217 if (!feature_vsec_dev) { 218 kfree(res); 219 return -ENOMEM; 220 } 221 222 snprintf(feature_id_name, sizeof(feature_id_name), "tpmi-%s", name); 223 224 for (i = 0, tmp = res; i < pfs->pfs_header.num_entries; i++, tmp++) { 225 u64 entry_size_bytes = pfs->pfs_header.entry_size * sizeof(u32); 226 227 tmp->start = pfs->vsec_offset + entry_size_bytes * i; 228 tmp->end = tmp->start + entry_size_bytes - 1; 229 tmp->flags = IORESOURCE_MEM; 230 } 231 232 feature_vsec_dev->pcidev = vsec_dev->pcidev; 233 feature_vsec_dev->resource = res; 234 feature_vsec_dev->num_resources = pfs->pfs_header.num_entries; 235 feature_vsec_dev->priv_data = &tpmi_info->plat_info; 236 feature_vsec_dev->priv_data_size = sizeof(tpmi_info->plat_info); 237 feature_vsec_dev->ida = &intel_vsec_tpmi_ida; 238 239 /* 240 * intel_vsec_add_aux() is resource managed, no explicit 241 * delete is required on error or on module unload. 242 * feature_vsec_dev and res memory are also freed as part of 243 * device deletion. 244 */ 245 return intel_vsec_add_aux(vsec_dev->pcidev, &vsec_dev->auxdev.dev, 246 feature_vsec_dev, feature_id_name); 247 } 248 249 static int tpmi_create_devices(struct intel_tpmi_info *tpmi_info) 250 { 251 struct intel_vsec_device *vsec_dev = tpmi_info->vsec_dev; 252 int ret, i; 253 254 for (i = 0; i < vsec_dev->num_resources; i++) { 255 ret = tpmi_create_device(tpmi_info, &tpmi_info->tpmi_features[i], 256 tpmi_info->pfs_start); 257 /* 258 * Fail, if the supported features fails to create device, 259 * otherwise, continue. Even if one device failed to create, 260 * fail the loading of driver. Since intel_vsec_add_aux() 261 * is resource managed, no clean up is required for the 262 * successfully created devices. 263 */ 264 if (ret && ret != -EOPNOTSUPP) 265 return ret; 266 } 267 268 return 0; 269 } 270 271 #define TPMI_INFO_BUS_INFO_OFFSET 0x08 272 273 static int tpmi_process_info(struct intel_tpmi_info *tpmi_info, 274 struct intel_tpmi_pm_feature *pfs) 275 { 276 struct tpmi_info_header header; 277 void __iomem *info_mem; 278 279 info_mem = ioremap(pfs->vsec_offset + TPMI_INFO_BUS_INFO_OFFSET, 280 pfs->pfs_header.entry_size * sizeof(u32) - TPMI_INFO_BUS_INFO_OFFSET); 281 if (!info_mem) 282 return -ENOMEM; 283 284 memcpy_fromio(&header, info_mem, sizeof(header)); 285 286 tpmi_info->plat_info.package_id = header.pkg; 287 tpmi_info->plat_info.bus_number = header.bus; 288 tpmi_info->plat_info.device_number = header.dev; 289 tpmi_info->plat_info.function_number = header.fn; 290 291 iounmap(info_mem); 292 293 return 0; 294 } 295 296 static int tpmi_fetch_pfs_header(struct intel_tpmi_pm_feature *pfs, u64 start, int size) 297 { 298 void __iomem *pfs_mem; 299 300 pfs_mem = ioremap(start, size); 301 if (!pfs_mem) 302 return -ENOMEM; 303 304 memcpy_fromio(&pfs->pfs_header, pfs_mem, sizeof(pfs->pfs_header)); 305 306 iounmap(pfs_mem); 307 308 return 0; 309 } 310 311 #define TPMI_CAP_OFFSET_UNIT 1024 312 313 static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev) 314 { 315 struct intel_vsec_device *vsec_dev = auxdev_to_ivdev(auxdev); 316 struct pci_dev *pci_dev = vsec_dev->pcidev; 317 struct intel_tpmi_info *tpmi_info; 318 u64 pfs_start = 0; 319 int i; 320 321 tpmi_info = devm_kzalloc(&auxdev->dev, sizeof(*tpmi_info), GFP_KERNEL); 322 if (!tpmi_info) 323 return -ENOMEM; 324 325 tpmi_info->vsec_dev = vsec_dev; 326 tpmi_info->feature_count = vsec_dev->num_resources; 327 tpmi_info->plat_info.bus_number = pci_dev->bus->number; 328 329 tpmi_info->tpmi_features = devm_kcalloc(&auxdev->dev, vsec_dev->num_resources, 330 sizeof(*tpmi_info->tpmi_features), 331 GFP_KERNEL); 332 if (!tpmi_info->tpmi_features) 333 return -ENOMEM; 334 335 for (i = 0; i < vsec_dev->num_resources; i++) { 336 struct intel_tpmi_pm_feature *pfs; 337 struct resource *res; 338 u64 res_start; 339 int size, ret; 340 341 pfs = &tpmi_info->tpmi_features[i]; 342 343 res = &vsec_dev->resource[i]; 344 if (!res) 345 continue; 346 347 res_start = res->start; 348 size = resource_size(res); 349 if (size < 0) 350 continue; 351 352 ret = tpmi_fetch_pfs_header(pfs, res_start, size); 353 if (ret) 354 continue; 355 356 if (!pfs_start) 357 pfs_start = res_start; 358 359 pfs->pfs_header.cap_offset *= TPMI_CAP_OFFSET_UNIT; 360 361 pfs->vsec_offset = pfs_start + pfs->pfs_header.cap_offset; 362 363 /* 364 * Process TPMI_INFO to get PCI device to CPU package ID. 365 * Device nodes for TPMI features are not created in this 366 * for loop. So, the mapping information will be available 367 * when actual device nodes created outside this 368 * loop via tpmi_create_devices(). 369 */ 370 if (pfs->pfs_header.tpmi_id == TPMI_INFO_ID) 371 tpmi_process_info(tpmi_info, pfs); 372 } 373 374 tpmi_info->pfs_start = pfs_start; 375 376 auxiliary_set_drvdata(auxdev, tpmi_info); 377 378 return tpmi_create_devices(tpmi_info); 379 } 380 381 static int tpmi_probe(struct auxiliary_device *auxdev, 382 const struct auxiliary_device_id *id) 383 { 384 return intel_vsec_tpmi_init(auxdev); 385 } 386 387 /* 388 * Remove callback is not needed currently as there is no 389 * cleanup required. All memory allocs are device managed. All 390 * devices created by this modules are also device managed. 391 */ 392 393 static const struct auxiliary_device_id tpmi_id_table[] = { 394 { .name = "intel_vsec.tpmi" }, 395 {} 396 }; 397 MODULE_DEVICE_TABLE(auxiliary, tpmi_id_table); 398 399 static struct auxiliary_driver tpmi_aux_driver = { 400 .id_table = tpmi_id_table, 401 .probe = tpmi_probe, 402 }; 403 404 module_auxiliary_driver(tpmi_aux_driver); 405 406 MODULE_IMPORT_NS(INTEL_VSEC); 407 MODULE_DESCRIPTION("Intel TPMI enumeration module"); 408 MODULE_LICENSE("GPL"); 409