@@ -7,6 +7,7 @@ config INTEL_PMC_CORE
tristate "Intel PMC Core driver"
depends on PCI
depends on ACPI
+ depends on INTEL_PMC_SSRAM_TELEMETRY || !INTEL_PMC_SSRAM_TELEMETRY
depends on INTEL_PMT_TELEMETRY
help
The Intel Platform Controller Hub for Intel Core SoCs provides access
@@ -28,6 +28,7 @@
#include <asm/tsc.h>
#include "core.h"
+#include "ssram_telemetry.h"
#include "../pmt/telemetry.h"
/* Maximum number of modes supported by platfoms that has low power mode capability */
@@ -1146,6 +1147,69 @@ int get_primary_reg_base(struct pmc *pmc)
return 0;
}
+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 int pmc_core_ssram_pmc_add(struct pmc_dev *pmcdev, int pmc_idx)
+{
+ const struct pmc_reg_map *map;
+ struct pmc_ssram_telemetry pmc_ssram_telemetry;
+ struct pmc *pmc;
+ int ret;
+
+ ret = pmc_ssram_telemetry_get_pmc_info(pmc_idx, &pmc_ssram_telemetry);
+ if (ret)
+ return ret;
+
+ map = pmc_core_find_regmap(pmcdev->regmap_list, pmc_ssram_telemetry.devid);
+ if (!map)
+ return -ENODEV;
+
+ pmc = pmcdev->pmcs[pmc_idx];
+ /* 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 -ENOMEM;
+ }
+
+ pmc->map = map;
+ pmc->base_addr = pmc_ssram_telemetry.base_addr;
+ pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length);
+
+ if (!pmc->regbase) {
+ devm_kfree(&pmcdev->pdev->dev, pmc);
+ return -ENOMEM;
+ }
+
+ pmcdev->pmcs[pmc_idx] = pmc;
+
+ return 0;
+}
+
+int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev)
+{
+ int ret;
+
+ if (!pmcdev->regmap_list)
+ return -ENOENT;
+
+ ret = pmc_core_ssram_pmc_add(pmcdev, PMC_IDX_MAIN);
+ if (ret)
+ return ret;
+
+ pmc_core_ssram_pmc_add(pmcdev, PMC_IDX_IOE);
+ pmc_core_ssram_pmc_add(pmcdev, PMC_IDX_PCH);
+
+ return 0;
+}
+
void pmc_core_punit_pmt_init(struct pmc_dev *pmcdev, u32 guid)
{
struct telem_endpoint *ep;
@@ -591,6 +591,7 @@ int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value, int ignore);
int pmc_core_resume_common(struct pmc_dev *pmcdev);
int get_primary_reg_base(struct pmc *pmc);
+extern int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev);
extern void pmc_core_get_low_power_modes(struct pmc_dev *pmcdev);
extern void pmc_core_punit_pmt_init(struct pmc_dev *pmcdev, u32 guid);
extern void pmc_core_set_device_d3(unsigned int device);
PWRMBASE address and devid for PMCs are available through API of Intel PMC SSRAM Telemetry driver. Add support to discover and achieve the information for each available PMC. Use PMC devid to find and assign the corresponding register map. Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com> --- drivers/platform/x86/intel/pmc/Kconfig | 1 + drivers/platform/x86/intel/pmc/core.c | 64 ++++++++++++++++++++++++++ drivers/platform/x86/intel/pmc/core.h | 1 + 3 files changed, 66 insertions(+)