2929#include <asm/tsc.h>
3030
3131#include "core.h"
32+ #include "ssram_telemetry.h"
3233#include "../pmt/telemetry.h"
3334
3435/* Maximum number of modes supported by platfoms that has low power mode capability */
@@ -1345,6 +1346,198 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
13451346 }
13461347}
13471348
1349+ static u32 pmc_core_find_guid (struct pmc_info * list , const struct pmc_reg_map * map )
1350+ {
1351+ for (; list -> map ; ++ list )
1352+ if (list -> map == map )
1353+ return list -> guid ;
1354+
1355+ return 0 ;
1356+ }
1357+
1358+ /*
1359+ * This function retrieves low power mode requirement data from PMC Low
1360+ * Power Mode (LPM) table.
1361+ *
1362+ * In telemetry space, the LPM table contains a 4 byte header followed
1363+ * by 8 consecutive mode blocks (one for each LPM mode). Each block
1364+ * has a 4 byte header followed by a set of registers that describe the
1365+ * IP state requirements for the given mode. The IP mapping is platform
1366+ * specific but the same for each block, making for easy analysis.
1367+ * Platforms only use a subset of the space to track the requirements
1368+ * for their IPs. Callers provide the requirement registers they use as
1369+ * a list of indices. Each requirement register is associated with an
1370+ * IP map that's maintained by the caller.
1371+ *
1372+ * Header
1373+ * +----+----------------------------+----------------------------+
1374+ * | 0 | REVISION | ENABLED MODES |
1375+ * +----+--------------+-------------+-------------+--------------+
1376+ *
1377+ * Low Power Mode 0 Block
1378+ * +----+--------------+-------------+-------------+--------------+
1379+ * | 1 | SUB ID | SIZE | MAJOR | MINOR |
1380+ * +----+--------------+-------------+-------------+--------------+
1381+ * | 2 | LPM0 Requirements 0 |
1382+ * +----+---------------------------------------------------------+
1383+ * | | ... |
1384+ * +----+---------------------------------------------------------+
1385+ * | 29 | LPM0 Requirements 27 |
1386+ * +----+---------------------------------------------------------+
1387+ *
1388+ * ...
1389+ *
1390+ * Low Power Mode 7 Block
1391+ * +----+--------------+-------------+-------------+--------------+
1392+ * | | SUB ID | SIZE | MAJOR | MINOR |
1393+ * +----+--------------+-------------+-------------+--------------+
1394+ * | 60 | LPM7 Requirements 0 |
1395+ * +----+---------------------------------------------------------+
1396+ * | | ... |
1397+ * +----+---------------------------------------------------------+
1398+ * | 87 | LPM7 Requirements 27 |
1399+ * +----+---------------------------------------------------------+
1400+ *
1401+ */
1402+ static int pmc_core_get_lpm_req (struct pmc_dev * pmcdev , struct pmc * pmc , struct pci_dev * pcidev )
1403+ {
1404+ struct telem_endpoint * ep ;
1405+ const u8 * lpm_indices ;
1406+ int num_maps , mode_offset = 0 ;
1407+ int ret , mode ;
1408+ int lpm_size ;
1409+ u32 guid ;
1410+
1411+ lpm_indices = pmc -> map -> lpm_reg_index ;
1412+ num_maps = pmc -> map -> lpm_num_maps ;
1413+ lpm_size = LPM_MAX_NUM_MODES * num_maps ;
1414+
1415+ guid = pmc_core_find_guid (pmcdev -> regmap_list , pmc -> map );
1416+ if (!guid )
1417+ return - ENXIO ;
1418+
1419+ ep = pmt_telem_find_and_register_endpoint (pcidev , guid , 0 );
1420+ if (IS_ERR (ep )) {
1421+ dev_dbg (& pmcdev -> pdev -> dev , "couldn't get telem endpoint %pe" , ep );
1422+ return - EPROBE_DEFER ;
1423+ }
1424+
1425+ pmc -> lpm_req_regs = devm_kzalloc (& pmcdev -> pdev -> dev ,
1426+ lpm_size * sizeof (u32 ),
1427+ GFP_KERNEL );
1428+ if (!pmc -> lpm_req_regs ) {
1429+ ret = - ENOMEM ;
1430+ goto unregister_ep ;
1431+ }
1432+
1433+ mode_offset = LPM_HEADER_OFFSET + LPM_MODE_OFFSET ;
1434+ pmc_for_each_mode (mode , pmcdev ) {
1435+ u32 * req_offset = pmc -> lpm_req_regs + (mode * num_maps );
1436+ int m ;
1437+
1438+ for (m = 0 ; m < num_maps ; m ++ ) {
1439+ u8 sample_id = lpm_indices [m ] + mode_offset ;
1440+
1441+ ret = pmt_telem_read32 (ep , sample_id , req_offset , 1 );
1442+ if (ret ) {
1443+ dev_err (& pmcdev -> pdev -> dev ,
1444+ "couldn't read Low Power Mode requirements: %d\n" , ret );
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 , int func )
1459+ {
1460+ struct pci_dev * pcidev __free (pci_dev_put ) = NULL ;
1461+ unsigned int i ;
1462+ int ret ;
1463+
1464+ pcidev = pci_get_domain_bus_and_slot (0 , 0 , PCI_DEVFN (20 , func ));
1465+ if (!pcidev )
1466+ return - ENODEV ;
1467+
1468+ for (i = 0 ; i < ARRAY_SIZE (pmcdev -> pmcs ); ++ i ) {
1469+ if (!pmcdev -> pmcs [i ])
1470+ continue ;
1471+
1472+ ret = pmc_core_get_lpm_req (pmcdev , pmcdev -> pmcs [i ], pcidev );
1473+ if (ret )
1474+ return ret ;
1475+ }
1476+
1477+ return 0 ;
1478+ }
1479+
1480+ static const struct pmc_reg_map * pmc_core_find_regmap (struct pmc_info * list , u16 devid )
1481+ {
1482+ for (; list -> map ; ++ list )
1483+ if (devid == list -> devid )
1484+ return list -> map ;
1485+
1486+ return NULL ;
1487+ }
1488+
1489+ static int pmc_core_pmc_add (struct pmc_dev * pmcdev , unsigned int pmc_index )
1490+
1491+ {
1492+ struct pmc_ssram_telemetry pmc_ssram_telemetry ;
1493+ const struct pmc_reg_map * map ;
1494+ struct pmc * pmc ;
1495+ int ret ;
1496+
1497+ ret = pmc_ssram_telemetry_get_pmc_info (pmc_index , & pmc_ssram_telemetry );
1498+ if (ret )
1499+ return ret ;
1500+
1501+ map = pmc_core_find_regmap (pmcdev -> regmap_list , pmc_ssram_telemetry .devid );
1502+ if (!map )
1503+ return - ENODEV ;
1504+
1505+ pmc = pmcdev -> pmcs [pmc_index ];
1506+ /* Memory for primary PMC has been allocated */
1507+ if (!pmc ) {
1508+ pmc = devm_kzalloc (& pmcdev -> pdev -> dev , sizeof (* pmc ), GFP_KERNEL );
1509+ if (!pmc )
1510+ return - ENOMEM ;
1511+ }
1512+
1513+ pmc -> map = map ;
1514+ pmc -> base_addr = pmc_ssram_telemetry .base_addr ;
1515+ pmc -> regbase = ioremap (pmc -> base_addr , pmc -> map -> regmap_length );
1516+
1517+ if (!pmc -> regbase ) {
1518+ devm_kfree (& pmcdev -> pdev -> dev , pmc );
1519+ return - ENOMEM ;
1520+ }
1521+
1522+ pmcdev -> pmcs [pmc_index ] = pmc ;
1523+
1524+ return 0 ;
1525+ }
1526+
1527+ static int pmc_core_ssram_get_reg_base (struct pmc_dev * pmcdev )
1528+ {
1529+ int ret ;
1530+
1531+ ret = pmc_core_pmc_add (pmcdev , PMC_IDX_MAIN );
1532+ if (ret )
1533+ return ret ;
1534+
1535+ pmc_core_pmc_add (pmcdev , PMC_IDX_IOE );
1536+ pmc_core_pmc_add (pmcdev , PMC_IDX_PCH );
1537+
1538+ return 0 ;
1539+ }
1540+
13481541/*
13491542 * When supported, ssram init is used to achieve all available PMCs.
13501543 * If ssram init fails, this function uses legacy method to at least get the
@@ -1362,10 +1555,18 @@ int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
13621555 ssram = pmc_dev_info -> regmap_list != NULL ;
13631556 if (ssram ) {
13641557 pmcdev -> regmap_list = pmc_dev_info -> regmap_list ;
1365- ret = pmc_core_ssram_init (pmcdev , pmc_dev_info -> pci_func );
1558+ ret = pmc_core_ssram_get_reg_base (pmcdev );
1559+ /*
1560+ * EAGAIN error code indicates Intel PMC SSRAM Telemetry driver
1561+ * has not finished probe and PMC info is not available yet. Try
1562+ * again later.
1563+ */
1564+ if (ret == - EAGAIN )
1565+ return - EPROBE_DEFER ;
1566+
13661567 if (ret ) {
13671568 dev_warn (& pmcdev -> pdev -> dev ,
1368- "ssram init failed , %d, using legacy init\n" , ret );
1569+ "Failed to get PMC info from SSRAM , %d, using legacy init\n" , ret );
13691570 ssram = false;
13701571 }
13711572 }
@@ -1381,10 +1582,26 @@ int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
13811582 if (pmc_dev_info -> dmu_guid )
13821583 pmc_core_punit_pmt_init (pmcdev , pmc_dev_info -> dmu_guid );
13831584
1384- if (ssram )
1385- return pmc_core_ssram_get_lpm_reqs (pmcdev );
1585+ if (ssram ) {
1586+ ret = pmc_core_ssram_get_lpm_reqs (pmcdev , pmc_dev_info -> pci_func );
1587+ if (ret )
1588+ goto unmap_regbase ;
1589+ }
13861590
13871591 return 0 ;
1592+
1593+ unmap_regbase :
1594+ for (unsigned int i = 0 ; i < ARRAY_SIZE (pmcdev -> pmcs ); ++ i ) {
1595+ struct pmc * pmc = pmcdev -> pmcs [i ];
1596+
1597+ if (pmc && pmc -> regbase )
1598+ iounmap (pmc -> regbase );
1599+ }
1600+
1601+ if (pmcdev -> punit_ep )
1602+ pmt_telem_unregister_endpoint (pmcdev -> punit_ep );
1603+
1604+ return ret ;
13881605}
13891606
13901607static const struct x86_cpu_id intel_pmc_core_ids [] = {
@@ -1408,6 +1625,7 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = {
14081625 X86_MATCH_VFM (INTEL_RAPTORLAKE_P , & tgl_l_pmc_dev ),
14091626 X86_MATCH_VFM (INTEL_RAPTORLAKE , & adl_pmc_dev ),
14101627 X86_MATCH_VFM (INTEL_RAPTORLAKE_S , & adl_pmc_dev ),
1628+ X86_MATCH_VFM (INTEL_BARTLETTLAKE , & adl_pmc_dev ),
14111629 X86_MATCH_VFM (INTEL_METEORLAKE_L , & mtl_pmc_dev ),
14121630 X86_MATCH_VFM (INTEL_ARROWLAKE , & arl_pmc_dev ),
14131631 X86_MATCH_VFM (INTEL_ARROWLAKE_H , & arl_h_pmc_dev ),
@@ -1471,20 +1689,14 @@ static void pmc_core_clean_structure(struct platform_device *pdev)
14711689 for (i = 0 ; i < ARRAY_SIZE (pmcdev -> pmcs ); ++ i ) {
14721690 struct pmc * pmc = pmcdev -> pmcs [i ];
14731691
1474- if (pmc )
1692+ if (pmc && pmc -> regbase )
14751693 iounmap (pmc -> regbase );
14761694 }
14771695
1478- if (pmcdev -> ssram_pcidev ) {
1479- pci_dev_put (pmcdev -> ssram_pcidev );
1480- pci_disable_device (pmcdev -> ssram_pcidev );
1481- }
1482-
14831696 if (pmcdev -> punit_ep )
14841697 pmt_telem_unregister_endpoint (pmcdev -> punit_ep );
14851698
14861699 platform_set_drvdata (pdev , NULL );
1487- mutex_destroy (& pmcdev -> lock );
14881700}
14891701
14901702static int pmc_core_probe (struct platform_device * pdev )
@@ -1529,15 +1741,17 @@ static int pmc_core_probe(struct platform_device *pdev)
15291741 if (!pmcdev -> pkgc_res_cnt )
15301742 return - ENOMEM ;
15311743
1532- mutex_init (& pmcdev -> lock );
1744+ ret = devm_mutex_init (& pdev -> dev , & pmcdev -> lock );
1745+ if (ret )
1746+ return ret ;
15331747
15341748 if (pmc_dev_info -> init )
15351749 ret = pmc_dev_info -> init (pmcdev , pmc_dev_info );
15361750 else
15371751 ret = generic_core_init (pmcdev , pmc_dev_info );
15381752
15391753 if (ret ) {
1540- pmc_core_clean_structure (pdev );
1754+ platform_set_drvdata (pdev , NULL );
15411755 return ret ;
15421756 }
15431757
@@ -1719,5 +1933,6 @@ static struct platform_driver pmc_core_driver = {
17191933
17201934module_platform_driver (pmc_core_driver );
17211935
1936+ MODULE_IMPORT_NS ("INTEL_PMT_TELEMETRY" );
17221937MODULE_LICENSE ("GPL v2" );
17231938MODULE_DESCRIPTION ("Intel PMC Core Driver" );
0 commit comments