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 */
@@ -1354,7 +1355,7 @@ static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *m
13541355 return 0 ;
13551356}
13561357
1357- static int pmc_core_get_lpm_req (struct pmc_dev * pmcdev , struct pmc * pmc )
1358+ static int pmc_core_get_lpm_req (struct pmc_dev * pmcdev , struct pmc * pmc , struct pci_dev * pcidev )
13581359{
13591360 struct telem_endpoint * ep ;
13601361 const u8 * lpm_indices ;
@@ -1371,7 +1372,7 @@ static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
13711372 if (!guid )
13721373 return - ENXIO ;
13731374
1374- ep = pmt_telem_find_and_register_endpoint (pmcdev -> ssram_pcidev , guid , 0 );
1375+ ep = pmt_telem_find_and_register_endpoint (pcidev , guid , 0 );
13751376 if (IS_ERR (ep )) {
13761377 dev_dbg (& pmcdev -> pdev -> dev , "couldn't get telem endpoint %ld" ,
13771378 PTR_ERR (ep ));
@@ -1455,27 +1456,29 @@ static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
14551456 return ret ;
14561457}
14571458
1458- static int pmc_core_ssram_get_lpm_reqs (struct pmc_dev * pmcdev )
1459+ static int pmc_core_ssram_get_lpm_reqs (struct pmc_dev * pmcdev , int func )
14591460{
1461+ struct pci_dev * pcidev __free (pci_dev_put ) = NULL ;
14601462 unsigned int i ;
14611463 int ret ;
14621464
1463- if (!pmcdev -> ssram_pcidev )
1465+ pcidev = pci_get_domain_bus_and_slot (0 , 0 , PCI_DEVFN (20 , func ));
1466+ if (!pcidev )
14641467 return - ENODEV ;
14651468
14661469 for (i = 0 ; i < ARRAY_SIZE (pmcdev -> pmcs ); ++ i ) {
14671470 if (!pmcdev -> pmcs [i ])
14681471 continue ;
14691472
1470- ret = pmc_core_get_lpm_req (pmcdev , pmcdev -> pmcs [i ]);
1473+ ret = pmc_core_get_lpm_req (pmcdev , pmcdev -> pmcs [i ], pcidev );
14711474 if (ret )
14721475 return ret ;
14731476 }
14741477
14751478 return 0 ;
14761479}
14771480
1478- const struct pmc_reg_map * pmc_core_find_regmap (struct pmc_info * list , u16 devid )
1481+ static const struct pmc_reg_map * pmc_core_find_regmap (struct pmc_info * list , u16 devid )
14791482{
14801483 for (; list -> map ; ++ list )
14811484 if (devid == list -> devid )
@@ -1484,23 +1487,32 @@ const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
14841487 return NULL ;
14851488}
14861489
1487- int pmc_core_pmc_add (struct pmc_dev * pmcdev , u64 pwrm_base ,
1488- const struct pmc_reg_map * reg_map , unsigned int pmc_index )
1490+ static int pmc_core_pmc_add (struct pmc_dev * pmcdev , unsigned int pmc_index )
1491+
14891492{
1490- struct pmc * pmc = pmcdev -> pmcs [pmc_index ];
1493+ struct pmc_ssram_telemetry pmc_ssram_telemetry ;
1494+ const struct pmc_reg_map * map ;
1495+ struct pmc * pmc ;
1496+ int ret ;
1497+
1498+ ret = pmc_ssram_telemetry_get_pmc_info (pmc_index , & pmc_ssram_telemetry );
1499+ if (ret )
1500+ return ret ;
14911501
1492- if (!pwrm_base )
1502+ map = pmc_core_find_regmap (pmcdev -> regmap_list , pmc_ssram_telemetry .devid );
1503+ if (!map )
14931504 return - ENODEV ;
14941505
1495- /* Memory for primary PMC has been allocated in core.c */
1506+ pmc = pmcdev -> pmcs [pmc_index ];
1507+ /* Memory for primary PMC has been allocated */
14961508 if (!pmc ) {
14971509 pmc = devm_kzalloc (& pmcdev -> pdev -> dev , sizeof (* pmc ), GFP_KERNEL );
14981510 if (!pmc )
14991511 return - ENOMEM ;
15001512 }
15011513
1502- pmc -> map = reg_map ;
1503- pmc -> base_addr = pwrm_base ;
1514+ pmc -> map = map ;
1515+ pmc -> base_addr = pmc_ssram_telemetry . base_addr ;
15041516 pmc -> regbase = ioremap (pmc -> base_addr , pmc -> map -> regmap_length );
15051517
15061518 if (!pmc -> regbase ) {
@@ -1513,6 +1525,20 @@ int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
15131525 return 0 ;
15141526}
15151527
1528+ static int pmc_core_ssram_get_reg_base (struct pmc_dev * pmcdev )
1529+ {
1530+ int ret ;
1531+
1532+ ret = pmc_core_pmc_add (pmcdev , PMC_IDX_MAIN );
1533+ if (ret )
1534+ return ret ;
1535+
1536+ pmc_core_pmc_add (pmcdev , PMC_IDX_IOE );
1537+ pmc_core_pmc_add (pmcdev , PMC_IDX_PCH );
1538+
1539+ return 0 ;
1540+ }
1541+
15161542/*
15171543 * When supported, ssram init is used to achieve all available PMCs.
15181544 * If ssram init fails, this function uses legacy method to at least get the
@@ -1530,10 +1556,18 @@ int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
15301556 ssram = pmc_dev_info -> regmap_list != NULL ;
15311557 if (ssram ) {
15321558 pmcdev -> regmap_list = pmc_dev_info -> regmap_list ;
1533- ret = pmc_core_ssram_init (pmcdev , pmc_dev_info -> pci_func );
1559+ ret = pmc_core_ssram_get_reg_base (pmcdev );
1560+ /*
1561+ * EAGAIN error code indicates Intel PMC SSRAM Telemetry driver
1562+ * has not finished probe and PMC info is not available yet. Try
1563+ * again later.
1564+ */
1565+ if (ret == - EAGAIN )
1566+ return - EPROBE_DEFER ;
1567+
15341568 if (ret ) {
15351569 dev_warn (& pmcdev -> pdev -> dev ,
1536- "ssram init failed , %d, using legacy init\n" , ret );
1570+ "Failed to get PMC info from SSRAM , %d, using legacy init\n" , ret );
15371571 ssram = false;
15381572 }
15391573 }
@@ -1550,7 +1584,7 @@ int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
15501584 pmc_core_punit_pmt_init (pmcdev , pmc_dev_info -> dmu_guid );
15511585
15521586 if (ssram )
1553- return pmc_core_ssram_get_lpm_reqs (pmcdev );
1587+ return pmc_core_ssram_get_lpm_reqs (pmcdev , pmc_dev_info -> pci_func );
15541588
15551589 return 0 ;
15561590}
@@ -1639,15 +1673,10 @@ static void pmc_core_clean_structure(struct platform_device *pdev)
16391673 for (i = 0 ; i < ARRAY_SIZE (pmcdev -> pmcs ); ++ i ) {
16401674 struct pmc * pmc = pmcdev -> pmcs [i ];
16411675
1642- if (pmc )
1676+ if (pmc && pmc -> regbase )
16431677 iounmap (pmc -> regbase );
16441678 }
16451679
1646- if (pmcdev -> ssram_pcidev ) {
1647- pci_dev_put (pmcdev -> ssram_pcidev );
1648- pci_disable_device (pmcdev -> ssram_pcidev );
1649- }
1650-
16511680 if (pmcdev -> punit_ep )
16521681 pmt_telem_unregister_endpoint (pmcdev -> punit_ep );
16531682
0 commit comments