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 * 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 * feature_vsec_dev memory is also freed as part of device 243 * delete. 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 * 4 - 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 static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev) 312 { 313 struct intel_vsec_device *vsec_dev = auxdev_to_ivdev(auxdev); 314 struct pci_dev *pci_dev = vsec_dev->pcidev; 315 struct intel_tpmi_info *tpmi_info; 316 u64 pfs_start = 0; 317 int i; 318 319 tpmi_info = devm_kzalloc(&auxdev->dev, sizeof(*tpmi_info), GFP_KERNEL); 320 if (!tpmi_info) 321 return -ENOMEM; 322 323 tpmi_info->vsec_dev = vsec_dev; 324 tpmi_info->feature_count = vsec_dev->num_resources; 325 tpmi_info->plat_info.bus_number = pci_dev->bus->number; 326 327 tpmi_info->tpmi_features = devm_kcalloc(&auxdev->dev, vsec_dev->num_resources, 328 sizeof(*tpmi_info->tpmi_features), 329 GFP_KERNEL); 330 if (!tpmi_info->tpmi_features) 331 return -ENOMEM; 332 333 for (i = 0; i < vsec_dev->num_resources; i++) { 334 struct intel_tpmi_pm_feature *pfs; 335 struct resource *res; 336 u64 res_start; 337 int size, ret; 338 339 pfs = &tpmi_info->tpmi_features[i]; 340 341 res = &vsec_dev->resource[i]; 342 if (!res) 343 continue; 344 345 res_start = res->start; 346 size = resource_size(res); 347 if (size < 0) 348 continue; 349 350 ret = tpmi_fetch_pfs_header(pfs, res_start, size); 351 if (ret) 352 continue; 353 354 if (!pfs_start) 355 pfs_start = res_start; 356 357 pfs->pfs_header.cap_offset *= 1024; 358 359 pfs->vsec_offset = pfs_start + pfs->pfs_header.cap_offset; 360 361 /* 362 * Process TPMI_INFO to get PCI device to CPU package ID. 363 * Device nodes for TPMI features are not created in this 364 * for loop. So, the mapping information will be available 365 * when actual device nodes created outside this 366 * loop via tpmi_create_devices(). 367 */ 368 if (pfs->pfs_header.tpmi_id == TPMI_INFO_ID) 369 tpmi_process_info(tpmi_info, pfs); 370 } 371 372 tpmi_info->pfs_start = pfs_start; 373 374 auxiliary_set_drvdata(auxdev, tpmi_info); 375 376 return tpmi_create_devices(tpmi_info); 377 } 378 379 static int tpmi_probe(struct auxiliary_device *auxdev, 380 const struct auxiliary_device_id *id) 381 { 382 return intel_vsec_tpmi_init(auxdev); 383 } 384 385 /* 386 * Remove callback is not needed currently as there is no 387 * cleanup required. All memory allocs are device managed. All 388 * devices created by this modules are also device managed. 389 */ 390 391 static const struct auxiliary_device_id tpmi_id_table[] = { 392 { .name = "intel_vsec.tpmi" }, 393 {} 394 }; 395 MODULE_DEVICE_TABLE(auxiliary, tpmi_id_table); 396 397 static struct auxiliary_driver tpmi_aux_driver = { 398 .id_table = tpmi_id_table, 399 .probe = tpmi_probe, 400 }; 401 402 module_auxiliary_driver(tpmi_aux_driver); 403 404 MODULE_IMPORT_NS(INTEL_VSEC); 405 MODULE_DESCRIPTION("Intel TPMI enumeration module"); 406 MODULE_LICENSE("GPL"); 407