-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
platform/x86:intel/pmc: Discover PMC devices
On platforms with multiple PMCs, additional PMC devices are discovered in the SSRAM device associated with the primary PMC. Add support for discovering PMC devices from SSRAM. Use PMC devid to assign the corresponding register map. Signed-off-by: Xi Pardee <xi.pardee@intel.com> Signed-off-by: David E. Box <david.e.box@linux.intel.com> Signed-off-by: Rajvi Jingar <rajvi.jingar@linux.intel.com> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Link: https://lore.kernel.org/r/20230613225347.2720665-6-rajvi.jingar@linux.intel.com Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- Loading branch information
David E. Box
authored and
Hans de Goede
committed
Jun 20, 2023
1 parent
2bcef45
commit 1b8c7b8
Showing
5 changed files
with
180 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* This file contains functions to handle discovery of PMC metrics located | ||
* in the PMC SSRAM PCI device. | ||
* | ||
* Copyright (c) 2023, Intel Corporation. | ||
* All Rights Reserved. | ||
* | ||
*/ | ||
|
||
#include <linux/pci.h> | ||
#include <linux/io-64-nonatomic-lo-hi.h> | ||
|
||
#include "core.h" | ||
|
||
#define SSRAM_HDR_SIZE 0x100 | ||
#define SSRAM_PWRM_OFFSET 0x14 | ||
#define SSRAM_DVSEC_OFFSET 0x1C | ||
#define SSRAM_DVSEC_SIZE 0x10 | ||
#define SSRAM_PCH_OFFSET 0x60 | ||
#define SSRAM_IOE_OFFSET 0x68 | ||
#define SSRAM_DEVID_OFFSET 0x70 | ||
|
||
static const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid) | ||
{ | ||
for (; list->map; ++list) | ||
if (devid == list->devid) | ||
return list->map; | ||
|
||
return NULL; | ||
} | ||
|
||
static inline u64 get_base(void __iomem *addr, u32 offset) | ||
{ | ||
return lo_hi_readq(addr + offset) & GENMASK_ULL(63, 3); | ||
} | ||
|
||
static void | ||
pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base, | ||
const struct pmc_reg_map *reg_map, int pmc_index) | ||
{ | ||
struct pmc *pmc = pmcdev->pmcs[pmc_index]; | ||
|
||
if (!pwrm_base) | ||
return; | ||
|
||
/* Memory for primary PMC has been allocated in core.c */ | ||
if (!pmc) { | ||
pmc = devm_kzalloc(&pmcdev->pdev->dev, sizeof(*pmc), GFP_KERNEL); | ||
if (!pmc) | ||
return; | ||
} | ||
|
||
pmc->map = reg_map; | ||
pmc->base_addr = pwrm_base; | ||
pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length); | ||
|
||
if (!pmc->regbase) { | ||
devm_kfree(&pmcdev->pdev->dev, pmc); | ||
return; | ||
} | ||
|
||
pmcdev->pmcs[pmc_index] = pmc; | ||
} | ||
|
||
static void | ||
pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, void __iomem *ssram, u32 offset, | ||
int pmc_idx) | ||
{ | ||
u64 pwrm_base; | ||
u16 devid; | ||
|
||
if (pmc_idx != PMC_IDX_SOC) { | ||
u64 ssram_base = get_base(ssram, offset); | ||
|
||
if (!ssram_base) | ||
return; | ||
|
||
ssram = ioremap(ssram_base, SSRAM_HDR_SIZE); | ||
if (!ssram) | ||
return; | ||
} | ||
|
||
pwrm_base = get_base(ssram, SSRAM_PWRM_OFFSET); | ||
devid = readw(ssram + SSRAM_DEVID_OFFSET); | ||
|
||
if (pmcdev->regmap_list) { | ||
const struct pmc_reg_map *map; | ||
|
||
map = pmc_core_find_regmap(pmcdev->regmap_list, devid); | ||
if (map) | ||
pmc_core_pmc_add(pmcdev, pwrm_base, map, pmc_idx); | ||
} | ||
|
||
if (pmc_idx != PMC_IDX_SOC) | ||
iounmap(ssram); | ||
} | ||
|
||
void pmc_core_ssram_init(struct pmc_dev *pmcdev) | ||
{ | ||
void __iomem *ssram; | ||
struct pci_dev *pcidev; | ||
u64 ssram_base; | ||
int ret; | ||
|
||
pcidev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(20, 2)); | ||
if (!pcidev) | ||
goto out; | ||
|
||
ret = pcim_enable_device(pcidev); | ||
if (ret) | ||
goto release_dev; | ||
|
||
ssram_base = pcidev->resource[0].start; | ||
ssram = ioremap(ssram_base, SSRAM_HDR_SIZE); | ||
if (!ssram) | ||
goto disable_dev; | ||
|
||
pmcdev->ssram_pcidev = pcidev; | ||
|
||
pmc_core_ssram_get_pmc(pmcdev, ssram, 0, PMC_IDX_SOC); | ||
pmc_core_ssram_get_pmc(pmcdev, ssram, SSRAM_IOE_OFFSET, PMC_IDX_IOE); | ||
pmc_core_ssram_get_pmc(pmcdev, ssram, SSRAM_PCH_OFFSET, PMC_IDX_PCH); | ||
|
||
iounmap(ssram); | ||
out: | ||
return; | ||
|
||
disable_dev: | ||
pci_disable_device(pcidev); | ||
release_dev: | ||
pci_dev_put(pcidev); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters