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 ret, i; 207 208 name = intel_tpmi_name(pfs->pfs_header.tpmi_id); 209 if (!name) 210 return -EOPNOTSUPP; 211 212 feature_vsec_dev = kzalloc(sizeof(*feature_vsec_dev), GFP_KERNEL); 213 if (!feature_vsec_dev) 214 return -ENOMEM; 215 216 res = kcalloc(pfs->pfs_header.num_entries, sizeof(*res), GFP_KERNEL); 217 if (!res) { 218 ret = -ENOMEM; 219 goto free_vsec; 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 * 4; 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 */ 243 ret = intel_vsec_add_aux(vsec_dev->pcidev, &vsec_dev->auxdev.dev, 244 feature_vsec_dev, feature_id_name); 245 if (ret) 246 goto free_res; 247 248 return 0; 249 250 free_res: 251 kfree(res); 252 free_vsec: 253 kfree(feature_vsec_dev); 254 255 return ret; 256 } 257 258 static int tpmi_create_devices(struct intel_tpmi_info *tpmi_info) 259 { 260 struct intel_vsec_device *vsec_dev = tpmi_info->vsec_dev; 261 int ret, i; 262 263 for (i = 0; i < vsec_dev->num_resources; i++) { 264 ret = tpmi_create_device(tpmi_info, &tpmi_info->tpmi_features[i], 265 tpmi_info->pfs_start); 266 /* 267 * Fail, if the supported features fails to create device, 268 * otherwise, continue. Even if one device failed to create, 269 * fail the loading of driver. Since intel_vsec_add_aux() 270 * is resource managed, no clean up is required for the 271 * successfully created devices. 272 */ 273 if (ret && ret != -EOPNOTSUPP) 274 return ret; 275 } 276 277 return 0; 278 } 279 280 #define TPMI_INFO_BUS_INFO_OFFSET 0x08 281 282 static int tpmi_process_info(struct intel_tpmi_info *tpmi_info, 283 struct intel_tpmi_pm_feature *pfs) 284 { 285 struct tpmi_info_header header; 286 void __iomem *info_mem; 287 288 info_mem = ioremap(pfs->vsec_offset + TPMI_INFO_BUS_INFO_OFFSET, 289 pfs->pfs_header.entry_size * 4 - TPMI_INFO_BUS_INFO_OFFSET); 290 if (!info_mem) 291 return -ENOMEM; 292 293 memcpy_fromio(&header, info_mem, sizeof(header)); 294 295 tpmi_info->plat_info.package_id = header.pkg; 296 tpmi_info->plat_info.bus_number = header.bus; 297 tpmi_info->plat_info.device_number = header.dev; 298 tpmi_info->plat_info.function_number = header.fn; 299 300 iounmap(info_mem); 301 302 return 0; 303 } 304 305 static int tpmi_fetch_pfs_header(struct intel_tpmi_pm_feature *pfs, u64 start, int size) 306 { 307 void __iomem *pfs_mem; 308 309 pfs_mem = ioremap(start, size); 310 if (!pfs_mem) 311 return -ENOMEM; 312 313 memcpy_fromio(&pfs->pfs_header, pfs_mem, sizeof(pfs->pfs_header)); 314 315 iounmap(pfs_mem); 316 317 return 0; 318 } 319 320 static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev) 321 { 322 struct intel_vsec_device *vsec_dev = auxdev_to_ivdev(auxdev); 323 struct pci_dev *pci_dev = vsec_dev->pcidev; 324 struct intel_tpmi_info *tpmi_info; 325 u64 pfs_start = 0; 326 int i; 327 328 tpmi_info = devm_kzalloc(&auxdev->dev, sizeof(*tpmi_info), GFP_KERNEL); 329 if (!tpmi_info) 330 return -ENOMEM; 331 332 tpmi_info->vsec_dev = vsec_dev; 333 tpmi_info->feature_count = vsec_dev->num_resources; 334 tpmi_info->plat_info.bus_number = pci_dev->bus->number; 335 336 tpmi_info->tpmi_features = devm_kcalloc(&auxdev->dev, vsec_dev->num_resources, 337 sizeof(*tpmi_info->tpmi_features), 338 GFP_KERNEL); 339 if (!tpmi_info->tpmi_features) 340 return -ENOMEM; 341 342 for (i = 0; i < vsec_dev->num_resources; i++) { 343 struct intel_tpmi_pm_feature *pfs; 344 struct resource *res; 345 u64 res_start; 346 int size, ret; 347 348 pfs = &tpmi_info->tpmi_features[i]; 349 350 res = &vsec_dev->resource[i]; 351 if (!res) 352 continue; 353 354 res_start = res->start; 355 size = resource_size(res); 356 if (size < 0) 357 continue; 358 359 ret = tpmi_fetch_pfs_header(pfs, res_start, size); 360 if (ret) 361 continue; 362 363 if (!pfs_start) 364 pfs_start = res_start; 365 366 pfs->pfs_header.cap_offset *= 1024; 367 368 pfs->vsec_offset = pfs_start + pfs->pfs_header.cap_offset; 369 370 /* 371 * Process TPMI_INFO to get PCI device to CPU package ID. 372 * Device nodes for TPMI features are not created in this 373 * for loop. So, the mapping information will be available 374 * when actual device nodes created outside this 375 * loop via tpmi_create_devices(). 376 */ 377 if (pfs->pfs_header.tpmi_id == TPMI_INFO_ID) 378 tpmi_process_info(tpmi_info, pfs); 379 } 380 381 tpmi_info->pfs_start = pfs_start; 382 383 auxiliary_set_drvdata(auxdev, tpmi_info); 384 385 return tpmi_create_devices(tpmi_info); 386 } 387 388 static int tpmi_probe(struct auxiliary_device *auxdev, 389 const struct auxiliary_device_id *id) 390 { 391 return intel_vsec_tpmi_init(auxdev); 392 } 393 394 /* 395 * Remove callback is not needed currently as there is no 396 * cleanup required. All memory allocs are device managed. All 397 * devices created by this modules are also device managed. 398 */ 399 400 static const struct auxiliary_device_id tpmi_id_table[] = { 401 { .name = "intel_vsec.tpmi" }, 402 {} 403 }; 404 MODULE_DEVICE_TABLE(auxiliary, tpmi_id_table); 405 406 static struct auxiliary_driver tpmi_aux_driver = { 407 .id_table = tpmi_id_table, 408 .probe = tpmi_probe, 409 }; 410 411 module_auxiliary_driver(tpmi_aux_driver); 412 413 MODULE_IMPORT_NS(INTEL_VSEC); 414 MODULE_DESCRIPTION("Intel TPMI enumeration module"); 415 MODULE_LICENSE("GPL"); 416