Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

platform/x86:intel/pmc: Move PMC Core related functions

Move functions that implements PMC Core feature from core_ssram.c
to core.c. This patch is a preparation step to introduce a new
SSRAM Telemetry driver for the SSRAM device.

Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20250409191056.15434-2-xi.pardee@linux.intel.com
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

authored by

Xi Pardee and committed by
Ilpo Järvinen
78a7491d 88f67f2a

+176 -176
+168
drivers/platform/x86/intel/pmc/core.c
··· 1345 1345 } 1346 1346 } 1347 1347 1348 + static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *map) 1349 + { 1350 + for (; list->map; ++list) 1351 + if (list->map == map) 1352 + return list->guid; 1353 + 1354 + return 0; 1355 + } 1356 + 1357 + static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc) 1358 + { 1359 + struct telem_endpoint *ep; 1360 + const u8 *lpm_indices; 1361 + int num_maps, mode_offset = 0; 1362 + int ret, mode; 1363 + int lpm_size; 1364 + u32 guid; 1365 + 1366 + lpm_indices = pmc->map->lpm_reg_index; 1367 + num_maps = pmc->map->lpm_num_maps; 1368 + lpm_size = LPM_MAX_NUM_MODES * num_maps; 1369 + 1370 + guid = pmc_core_find_guid(pmcdev->regmap_list, pmc->map); 1371 + if (!guid) 1372 + return -ENXIO; 1373 + 1374 + ep = pmt_telem_find_and_register_endpoint(pmcdev->ssram_pcidev, guid, 0); 1375 + if (IS_ERR(ep)) { 1376 + dev_dbg(&pmcdev->pdev->dev, "couldn't get telem endpoint %ld", 1377 + PTR_ERR(ep)); 1378 + return -EPROBE_DEFER; 1379 + } 1380 + 1381 + pmc->lpm_req_regs = devm_kzalloc(&pmcdev->pdev->dev, 1382 + lpm_size * sizeof(u32), 1383 + GFP_KERNEL); 1384 + if (!pmc->lpm_req_regs) { 1385 + ret = -ENOMEM; 1386 + goto unregister_ep; 1387 + } 1388 + 1389 + /* 1390 + * PMC Low Power Mode (LPM) table 1391 + * 1392 + * In telemetry space, the LPM table contains a 4 byte header followed 1393 + * by 8 consecutive mode blocks (one for each LPM mode). Each block 1394 + * has a 4 byte header followed by a set of registers that describe the 1395 + * IP state requirements for the given mode. The IP mapping is platform 1396 + * specific but the same for each block, making for easy analysis. 1397 + * Platforms only use a subset of the space to track the requirements 1398 + * for their IPs. Callers provide the requirement registers they use as 1399 + * a list of indices. Each requirement register is associated with an 1400 + * IP map that's maintained by the caller. 1401 + * 1402 + * Header 1403 + * +----+----------------------------+----------------------------+ 1404 + * | 0 | REVISION | ENABLED MODES | 1405 + * +----+--------------+-------------+-------------+--------------+ 1406 + * 1407 + * Low Power Mode 0 Block 1408 + * +----+--------------+-------------+-------------+--------------+ 1409 + * | 1 | SUB ID | SIZE | MAJOR | MINOR | 1410 + * +----+--------------+-------------+-------------+--------------+ 1411 + * | 2 | LPM0 Requirements 0 | 1412 + * +----+---------------------------------------------------------+ 1413 + * | | ... | 1414 + * +----+---------------------------------------------------------+ 1415 + * | 29 | LPM0 Requirements 27 | 1416 + * +----+---------------------------------------------------------+ 1417 + * 1418 + * ... 1419 + * 1420 + * Low Power Mode 7 Block 1421 + * +----+--------------+-------------+-------------+--------------+ 1422 + * | | SUB ID | SIZE | MAJOR | MINOR | 1423 + * +----+--------------+-------------+-------------+--------------+ 1424 + * | 60 | LPM7 Requirements 0 | 1425 + * +----+---------------------------------------------------------+ 1426 + * | | ... | 1427 + * +----+---------------------------------------------------------+ 1428 + * | 87 | LPM7 Requirements 27 | 1429 + * +----+---------------------------------------------------------+ 1430 + * 1431 + */ 1432 + mode_offset = LPM_HEADER_OFFSET + LPM_MODE_OFFSET; 1433 + pmc_for_each_mode(mode, pmcdev) { 1434 + u32 *req_offset = pmc->lpm_req_regs + (mode * num_maps); 1435 + int m; 1436 + 1437 + for (m = 0; m < num_maps; m++) { 1438 + u8 sample_id = lpm_indices[m] + mode_offset; 1439 + 1440 + ret = pmt_telem_read32(ep, sample_id, req_offset, 1); 1441 + if (ret) { 1442 + dev_err(&pmcdev->pdev->dev, 1443 + "couldn't read Low Power Mode requirements: %d\n", ret); 1444 + devm_kfree(&pmcdev->pdev->dev, pmc->lpm_req_regs); 1445 + goto unregister_ep; 1446 + } 1447 + ++req_offset; 1448 + } 1449 + mode_offset += LPM_REG_COUNT + LPM_MODE_OFFSET; 1450 + } 1451 + 1452 + unregister_ep: 1453 + pmt_telem_unregister_endpoint(ep); 1454 + 1455 + return ret; 1456 + } 1457 + 1458 + static int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev) 1459 + { 1460 + int ret, i; 1461 + 1462 + if (!pmcdev->ssram_pcidev) 1463 + return -ENODEV; 1464 + 1465 + for (i = 0; i < ARRAY_SIZE(pmcdev->pmcs); ++i) { 1466 + if (!pmcdev->pmcs[i]) 1467 + continue; 1468 + 1469 + ret = pmc_core_get_lpm_req(pmcdev, pmcdev->pmcs[i]); 1470 + if (ret) 1471 + return ret; 1472 + } 1473 + 1474 + return 0; 1475 + } 1476 + 1477 + const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid) 1478 + { 1479 + for (; list->map; ++list) 1480 + if (devid == list->devid) 1481 + return list->map; 1482 + 1483 + return NULL; 1484 + } 1485 + 1486 + int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base, 1487 + const struct pmc_reg_map *reg_map, int pmc_index) 1488 + { 1489 + struct pmc *pmc = pmcdev->pmcs[pmc_index]; 1490 + 1491 + if (!pwrm_base) 1492 + return -ENODEV; 1493 + 1494 + /* Memory for primary PMC has been allocated in core.c */ 1495 + if (!pmc) { 1496 + pmc = devm_kzalloc(&pmcdev->pdev->dev, sizeof(*pmc), GFP_KERNEL); 1497 + if (!pmc) 1498 + return -ENOMEM; 1499 + } 1500 + 1501 + pmc->map = reg_map; 1502 + pmc->base_addr = pwrm_base; 1503 + pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length); 1504 + 1505 + if (!pmc->regbase) { 1506 + devm_kfree(&pmcdev->pdev->dev, pmc); 1507 + return -ENOMEM; 1508 + } 1509 + 1510 + pmcdev->pmcs[pmc_index] = pmc; 1511 + 1512 + return 0; 1513 + } 1514 + 1348 1515 /* 1349 1516 * When supported, ssram init is used to achieve all available PMCs. 1350 1517 * If ssram init fails, this function uses legacy method to at least get the ··· 1886 1719 1887 1720 module_platform_driver(pmc_core_driver); 1888 1721 1722 + MODULE_IMPORT_NS("INTEL_PMT_TELEMETRY"); 1889 1723 MODULE_LICENSE("GPL v2"); 1890 1724 MODULE_DESCRIPTION("Intel PMC Core Driver");
+8 -1
drivers/platform/x86/intel/pmc/core.h
··· 24 24 #define MAX_NUM_PMC 3 25 25 #define S0IX_BLK_SIZE 4 26 26 27 + /* PCH query */ 28 + #define LPM_HEADER_OFFSET 1 29 + #define LPM_REG_COUNT 28 30 + #define LPM_MODE_OFFSET 1 31 + 27 32 /* Sunrise Point Power Management Controller PCI Device ID */ 28 33 #define SPT_PMC_PCI_DEVICE_ID 0x9d21 29 34 #define SPT_PMC_BASE_ADDR_OFFSET 0x48 ··· 490 485 extern const struct pmc_reg_map mtl_ioep_reg_map; 491 486 492 487 void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev); 493 - int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev); 494 488 int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value, int ignore); 495 489 496 490 int pmc_core_resume_common(struct pmc_dev *pmcdev); ··· 501 497 int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func); 502 498 503 499 int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info); 500 + const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid); 501 + int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base, 502 + const struct pmc_reg_map *reg_map, int pmc_index); 504 503 505 504 extern struct pmc_dev_info spt_pmc_dev; 506 505 extern struct pmc_dev_info cnp_pmc_dev;
-175
drivers/platform/x86/intel/pmc/core_ssram.c
··· 14 14 #include <linux/io-64-nonatomic-lo-hi.h> 15 15 16 16 #include "core.h" 17 - #include "../pmt/telemetry.h" 18 17 19 18 #define SSRAM_HDR_SIZE 0x100 20 19 #define SSRAM_PWRM_OFFSET 0x14 ··· 23 24 #define SSRAM_IOE_OFFSET 0x68 24 25 #define SSRAM_DEVID_OFFSET 0x70 25 26 26 - /* PCH query */ 27 - #define LPM_HEADER_OFFSET 1 28 - #define LPM_REG_COUNT 28 29 - #define LPM_MODE_OFFSET 1 30 - 31 27 DEFINE_FREE(pmc_core_iounmap, void __iomem *, if (_T) iounmap(_T)) 32 - 33 - static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *map) 34 - { 35 - for (; list->map; ++list) 36 - if (list->map == map) 37 - return list->guid; 38 - 39 - return 0; 40 - } 41 - 42 - static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc) 43 - { 44 - struct telem_endpoint *ep; 45 - const u8 *lpm_indices; 46 - int num_maps, mode_offset = 0; 47 - int ret, mode; 48 - int lpm_size; 49 - u32 guid; 50 - 51 - lpm_indices = pmc->map->lpm_reg_index; 52 - num_maps = pmc->map->lpm_num_maps; 53 - lpm_size = LPM_MAX_NUM_MODES * num_maps; 54 - 55 - guid = pmc_core_find_guid(pmcdev->regmap_list, pmc->map); 56 - if (!guid) 57 - return -ENXIO; 58 - 59 - ep = pmt_telem_find_and_register_endpoint(pmcdev->ssram_pcidev, guid, 0); 60 - if (IS_ERR(ep)) { 61 - dev_dbg(&pmcdev->pdev->dev, "couldn't get telem endpoint %ld", 62 - PTR_ERR(ep)); 63 - return -EPROBE_DEFER; 64 - } 65 - 66 - pmc->lpm_req_regs = devm_kzalloc(&pmcdev->pdev->dev, 67 - lpm_size * sizeof(u32), 68 - GFP_KERNEL); 69 - if (!pmc->lpm_req_regs) { 70 - ret = -ENOMEM; 71 - goto unregister_ep; 72 - } 73 - 74 - /* 75 - * PMC Low Power Mode (LPM) table 76 - * 77 - * In telemetry space, the LPM table contains a 4 byte header followed 78 - * by 8 consecutive mode blocks (one for each LPM mode). Each block 79 - * has a 4 byte header followed by a set of registers that describe the 80 - * IP state requirements for the given mode. The IP mapping is platform 81 - * specific but the same for each block, making for easy analysis. 82 - * Platforms only use a subset of the space to track the requirements 83 - * for their IPs. Callers provide the requirement registers they use as 84 - * a list of indices. Each requirement register is associated with an 85 - * IP map that's maintained by the caller. 86 - * 87 - * Header 88 - * +----+----------------------------+----------------------------+ 89 - * | 0 | REVISION | ENABLED MODES | 90 - * +----+--------------+-------------+-------------+--------------+ 91 - * 92 - * Low Power Mode 0 Block 93 - * +----+--------------+-------------+-------------+--------------+ 94 - * | 1 | SUB ID | SIZE | MAJOR | MINOR | 95 - * +----+--------------+-------------+-------------+--------------+ 96 - * | 2 | LPM0 Requirements 0 | 97 - * +----+---------------------------------------------------------+ 98 - * | | ... | 99 - * +----+---------------------------------------------------------+ 100 - * | 29 | LPM0 Requirements 27 | 101 - * +----+---------------------------------------------------------+ 102 - * 103 - * ... 104 - * 105 - * Low Power Mode 7 Block 106 - * +----+--------------+-------------+-------------+--------------+ 107 - * | | SUB ID | SIZE | MAJOR | MINOR | 108 - * +----+--------------+-------------+-------------+--------------+ 109 - * | 60 | LPM7 Requirements 0 | 110 - * +----+---------------------------------------------------------+ 111 - * | | ... | 112 - * +----+---------------------------------------------------------+ 113 - * | 87 | LPM7 Requirements 27 | 114 - * +----+---------------------------------------------------------+ 115 - * 116 - */ 117 - mode_offset = LPM_HEADER_OFFSET + LPM_MODE_OFFSET; 118 - pmc_for_each_mode(mode, pmcdev) { 119 - u32 *req_offset = pmc->lpm_req_regs + (mode * num_maps); 120 - int m; 121 - 122 - for (m = 0; m < num_maps; m++) { 123 - u8 sample_id = lpm_indices[m] + mode_offset; 124 - 125 - ret = pmt_telem_read32(ep, sample_id, req_offset, 1); 126 - if (ret) { 127 - dev_err(&pmcdev->pdev->dev, 128 - "couldn't read Low Power Mode requirements: %d\n", ret); 129 - devm_kfree(&pmcdev->pdev->dev, pmc->lpm_req_regs); 130 - goto unregister_ep; 131 - } 132 - ++req_offset; 133 - } 134 - mode_offset += LPM_REG_COUNT + LPM_MODE_OFFSET; 135 - } 136 - 137 - unregister_ep: 138 - pmt_telem_unregister_endpoint(ep); 139 - 140 - return ret; 141 - } 142 - 143 - int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev) 144 - { 145 - int ret, i; 146 - 147 - if (!pmcdev->ssram_pcidev) 148 - return -ENODEV; 149 - 150 - for (i = 0; i < ARRAY_SIZE(pmcdev->pmcs); ++i) { 151 - if (!pmcdev->pmcs[i]) 152 - continue; 153 - 154 - ret = pmc_core_get_lpm_req(pmcdev, pmcdev->pmcs[i]); 155 - if (ret) 156 - return ret; 157 - } 158 - 159 - return 0; 160 - } 161 28 162 29 static void 163 30 pmc_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram) ··· 68 203 intel_vsec_register(pcidev, &info); 69 204 } 70 205 71 - static const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid) 72 - { 73 - for (; list->map; ++list) 74 - if (devid == list->devid) 75 - return list->map; 76 - 77 - return NULL; 78 - } 79 - 80 206 static inline u64 get_base(void __iomem *addr, u32 offset) 81 207 { 82 208 return lo_hi_readq(addr + offset) & GENMASK_ULL(63, 3); 83 - } 84 - 85 - static int 86 - pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base, 87 - const struct pmc_reg_map *reg_map, int pmc_index) 88 - { 89 - struct pmc *pmc = pmcdev->pmcs[pmc_index]; 90 - 91 - if (!pwrm_base) 92 - return -ENODEV; 93 - 94 - /* Memory for primary PMC has been allocated in core.c */ 95 - if (!pmc) { 96 - pmc = devm_kzalloc(&pmcdev->pdev->dev, sizeof(*pmc), GFP_KERNEL); 97 - if (!pmc) 98 - return -ENOMEM; 99 - } 100 - 101 - pmc->map = reg_map; 102 - pmc->base_addr = pwrm_base; 103 - pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length); 104 - 105 - if (!pmc->regbase) { 106 - devm_kfree(&pmcdev->pdev->dev, pmc); 107 - return -ENOMEM; 108 - } 109 - 110 - pmcdev->pmcs[pmc_index] = pmc; 111 - 112 - return 0; 113 209 } 114 210 115 211 static int ··· 155 329 return ret; 156 330 } 157 331 MODULE_IMPORT_NS("INTEL_VSEC"); 158 - MODULE_IMPORT_NS("INTEL_PMT_TELEMETRY");