]> www.infradead.org Git - users/hch/configfs.git/commitdiff
platform/x86/intel/pmc: Find and register PMC telemetry entries
authorDavid E. Box <david.e.box@linux.intel.com>
Wed, 29 Nov 2023 22:21:27 +0000 (14:21 -0800)
committerHans de Goede <hdegoede@redhat.com>
Mon, 4 Dec 2023 13:53:43 +0000 (14:53 +0100)
The PMC SSRAM device contains counters that are structured in Intel
Platform Monitoring Technology (PMT) telemetry regions. Look for and
register these telemetry regions from the driver so that they may be read
using the Intel PMT ABI.

Signed-off-by: David E. Box <david.e.box@linux.intel.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20231129222132.2331261-16-david.e.box@linux.intel.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
drivers/platform/x86/intel/pmc/Kconfig
drivers/platform/x86/intel/pmc/core_ssram.c

index b526597e4deb02290efa5ba6e2bcad124f5e5ee2..d2f651fbec2cf8315f09e2c36a060a23f3a15dcc 100644 (file)
@@ -7,6 +7,7 @@ config INTEL_PMC_CORE
        tristate "Intel PMC Core driver"
        depends on PCI
        depends on ACPI
+       depends on INTEL_PMT_TELEMETRY
        help
          The Intel Platform Controller Hub for Intel Core SoCs provides access
          to Power Management Controller registers via various interfaces. This
index c1b984255571545512e0a9491abd6f82663d0bfd..9ca720f9cbb233be4a3bfa0d72d0c234b28eb1a3 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/io-64-nonatomic-lo-hi.h>
 
 #include "core.h"
+#include "../vsec.h"
+#include "../pmt/telemetry.h"
 
 #define SSRAM_HDR_SIZE         0x100
 #define SSRAM_PWRM_OFFSET      0x14
 
 DEFINE_FREE(pmc_core_iounmap, void __iomem *, iounmap(_T));
 
+static void
+pmc_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram)
+{
+       struct pci_dev *pcidev = pmcdev->ssram_pcidev;
+       struct intel_vsec_platform_info info = {};
+       struct intel_vsec_header *headers[2] = {};
+       struct intel_vsec_header header;
+       void __iomem *dvsec;
+       u32 dvsec_offset;
+       u32 table, hdr;
+
+       ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
+       if (!ssram)
+               return;
+
+       dvsec_offset = readl(ssram + SSRAM_DVSEC_OFFSET);
+       iounmap(ssram);
+
+       dvsec = ioremap(ssram_base + dvsec_offset, SSRAM_DVSEC_SIZE);
+       if (!dvsec)
+               return;
+
+       hdr = readl(dvsec + PCI_DVSEC_HEADER1);
+       header.id = readw(dvsec + PCI_DVSEC_HEADER2);
+       header.rev = PCI_DVSEC_HEADER1_REV(hdr);
+       header.length = PCI_DVSEC_HEADER1_LEN(hdr);
+       header.num_entries = readb(dvsec + INTEL_DVSEC_ENTRIES);
+       header.entry_size = readb(dvsec + INTEL_DVSEC_SIZE);
+
+       table = readl(dvsec + INTEL_DVSEC_TABLE);
+       header.tbir = INTEL_DVSEC_TABLE_BAR(table);
+       header.offset = INTEL_DVSEC_TABLE_OFFSET(table);
+       iounmap(dvsec);
+
+       headers[0] = &header;
+       info.caps = VSEC_CAP_TELEMETRY;
+       info.headers = headers;
+       info.base_addr = ssram_base;
+       info.parent = &pmcdev->pdev->dev;
+
+       intel_vsec_register(pcidev, &info);
+}
+
 static const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
 {
        for (; list->map; ++list)
@@ -101,6 +146,9 @@ pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, int pmc_idx, u32 offset)
        pwrm_base = get_base(ssram, SSRAM_PWRM_OFFSET);
        devid = readw(ssram + SSRAM_DEVID_OFFSET);
 
+       /* Find and register and PMC telemetry entries */
+       pmc_add_pmt(pmcdev, ssram_base, ssram);
+
        map = pmc_core_find_regmap(pmcdev->regmap_list, devid);
        if (!map)
                return -ENODEV;
@@ -140,3 +188,4 @@ release_dev:
 
        return ret;
 }
+MODULE_IMPORT_NS(INTEL_VSEC);