public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "David E. Box" <david.e.box@linux.intel.com>
To: irenic.rajneesh@gmail.com, david.e.box@linux.intel.com,
	hdegoede@redhat.com, markgross@kernel.org,
	andy.shevchenko@gmail.com, rajvi.jingar@linux.intel.com,
	xi.pardee@intel.com
Cc: linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org
Subject: [PATCH 09/11] platform/x86/intel/pmc: Add Intel PMT support for MTL PMC
Date: Wed, 15 Mar 2023 11:34:03 -0700	[thread overview]
Message-ID: <20230315183405.2465630-10-david.e.box@linux.intel.com> (raw)
In-Reply-To: <20230315183405.2465630-1-david.e.box@linux.intel.com>

The PMC SSRAM device contains PMC metrics that are structured in Intel
Platform Monitoring Technology (PMT) telemetry regions. Register these
telemetry regions from the driver so that they may be read using the
Intel PMT API.

Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
 drivers/platform/x86/intel/pmc/Kconfig |   1 +
 drivers/platform/x86/intel/pmc/core.c  |   6 ++
 drivers/platform/x86/intel/pmc/core.h  |   2 +
 drivers/platform/x86/intel/pmc/mtl.c   | 106 +++++++++++++++++++++++++
 4 files changed, 115 insertions(+)

diff --git a/drivers/platform/x86/intel/pmc/Kconfig b/drivers/platform/x86/intel/pmc/Kconfig
index b526597e4deb..d2f651fbec2c 100644
--- a/drivers/platform/x86/intel/pmc/Kconfig
+++ b/drivers/platform/x86/intel/pmc/Kconfig
@@ -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
diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
index 4769ce0b0fbe..8f3a5a6fc874 100644
--- a/drivers/platform/x86/intel/pmc/core.c
+++ b/drivers/platform/x86/intel/pmc/core.c
@@ -1174,6 +1174,11 @@ static void pmc_core_remove(struct platform_device *pdev)
 	platform_set_drvdata(pdev, NULL);
 	mutex_destroy(&pmcdev->lock);
 	iounmap(pmcdev->regbase);
+
+	if (pmcdev->ssram_pcidev) {
+		pci_dev_put(pmcdev->ssram_pcidev);
+		pci_disable_device(pmcdev->ssram_pcidev);
+	}
 }
 
 static bool warn_on_s0ix_failures;
@@ -1287,3 +1292,4 @@ module_platform_driver(pmc_core_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Intel PMC Core Driver");
+MODULE_IMPORT_NS(INTEL_VSEC);
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index 3ce83c837fdc..ba30db31f439 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -315,6 +315,7 @@ struct pmc_reg_map {
  * @map:		pointer to pmc_reg_map struct that contains platform
  *			specific attributes
  * @pdev:		pointer to platform_device struct
+ * @ssram_pcidev:	pointer to pci device struct for the PMC SSRAM
  * @dbgfs_dir:		path to debugfs interface
  * @pmc_xram_read_bit:	flag to indicate whether PMC XRAM shadow registers
  *			used to read MPHY PG and PLL status are available
@@ -334,6 +335,7 @@ struct pmc_dev {
 	const struct pmc_reg_map *map;
 	struct dentry *dbgfs_dir;
 	struct platform_device *pdev;
+	struct pci_dev *ssram_pcidev;
 	int pmc_xram_read_bit;
 	struct mutex lock; /* generic mutex lock for PMC Core */
 
diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
index 96106ffbd367..48c7ec094af8 100644
--- a/drivers/platform/x86/intel/pmc/mtl.c
+++ b/drivers/platform/x86/intel/pmc/mtl.c
@@ -8,7 +8,18 @@
  *
  */
 
+#include <linux/pci.h>
+
 #include "core.h"
+#include "../vsec.h"
+#include "../pmt/telemetry.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
 
 const struct pmc_reg_map mtl_reg_map = {
 	.pfear_sts = ext_tgl_pfear_map,
@@ -36,6 +47,99 @@ const struct pmc_reg_map mtl_reg_map = {
 	.lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET,
 };
 
+static void
+mtl_pmc_add_pmt(struct pmc_dev *pmcdev, struct pci_dev *pdev, u64 ssram_base)
+{
+	struct intel_vsec_platform_info info = {};
+	struct intel_vsec_header *headers[2] = {};
+	struct intel_vsec_header header;
+	void __iomem *ssram, *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;
+
+	intel_vsec_register(pdev, &info);
+}
+
+static inline u64 get_ssram_base(void __iomem *addr, u32 offset)
+{
+	u64 low, high;
+
+	low = readl(addr + offset) & GENMASK(31, 3);
+	high = readl(addr + offset + 4);
+
+	return (high << 32) + low;
+}
+
+static void mtl_pmc_ssram_init(struct pmc_dev *pmcdev)
+{
+	void __iomem *ssram;
+	struct pci_dev *pcidev;
+	u64 socs_ssram_base;
+	u64 ioe_ssram_base;
+	u64 pch_ssram_base;
+	int ret;
+
+	pcidev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(20, 2));
+	if (!pcidev) {
+		dev_err(&pmcdev->pdev->dev, "pci_dev is not found.");
+		return;
+	}
+
+	ret = pcim_enable_device(pcidev);
+	if (ret) {
+		pci_dev_put(pcidev);
+		return;
+	}
+
+	socs_ssram_base = pcidev->resource[0].start;
+	ssram = ioremap(socs_ssram_base, SSRAM_HDR_SIZE);
+	if (!ssram) {
+		pci_dev_put(pcidev);
+		pci_disable_device(pcidev);
+		return;
+	}
+
+	pmcdev->ssram_pcidev = pcidev;
+
+	ioe_ssram_base = get_ssram_base(ssram, SSRAM_IOE_OFFSET);
+	pch_ssram_base = get_ssram_base(ssram, SSRAM_PCH_OFFSET);
+	iounmap(ssram);
+
+	mtl_pmc_add_pmt(pmcdev, pcidev, socs_ssram_base);
+	if (ioe_ssram_base)
+		mtl_pmc_add_pmt(pmcdev, pcidev, ioe_ssram_base);
+	if (pch_ssram_base)
+		mtl_pmc_add_pmt(pmcdev, pcidev, pch_ssram_base);
+}
+
 int mtl_core_init(struct pmc_dev *pmcdev)
 {
 	int ret;
@@ -45,6 +149,8 @@ int mtl_core_init(struct pmc_dev *pmcdev)
 	if (ret)
 		return ret;
 
+	mtl_pmc_ssram_init(pmcdev);
+
 	/* Due to a hardware limitation, the GBE LTR blocks PC10
 	 * when a cable is attached. Tell the PMC to ignore it.
 	 */
-- 
2.34.1


  parent reply	other threads:[~2023-03-15 18:35 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-15 18:33 [PATCH 00/11] Intel pmc_core: Enable telemetry David E. Box
2023-03-15 18:33 ` [PATCH 01/11] platform/x86/intel/vsec: Add intel_vsec_register David E. Box
2023-03-15 18:33 ` [PATCH 02/11] platform/x86/intel/vsec: Explicitly enable capabilities David E. Box
2023-03-15 18:33 ` [PATCH 03/11] platform/x86/intel/vsec: Add base address field David E. Box
2023-03-15 18:33 ` [PATCH 04/11] platform/x86/intel/pmt: Add INTEL_PMT module namespace David E. Box
2023-03-15 18:33 ` [PATCH 05/11] platform/x86/intel/pmt: telemetry: Add telemetry read functions David E. Box
2023-03-15 18:34 ` [PATCH 06/11] platform/x86/intel/pmt/telemetry: Add driver version David E. Box
2023-03-15 18:34 ` [PATCH 07/11] platform/x86/intel/pmc: Alder Lake slp_s0_residency fix David E. Box
2023-03-15 18:34 ` [PATCH 08/11] platform/x86:intel/pmc: Combine core_init and core_configure function David E. Box
2023-03-15 18:34 ` David E. Box [this message]
2023-03-15 18:34 ` [PATCH 10/11] platform/x86:intel/pmc: Move get_low_power_modes function David E. Box
2023-03-15 18:34 ` [PATCH 11/11] platform/x86/intel/pmc/mtl: get LPM information using Intel PMT David E. Box
2023-03-16 14:51 ` [PATCH 00/11] Intel pmc_core: Enable telemetry Hans de Goede
2023-03-16 15:36   ` David E. Box

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230315183405.2465630-10-david.e.box@linux.intel.com \
    --to=david.e.box@linux.intel.com \
    --cc=andy.shevchenko@gmail.com \
    --cc=hdegoede@redhat.com \
    --cc=irenic.rajneesh@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=markgross@kernel.org \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=rajvi.jingar@linux.intel.com \
    --cc=xi.pardee@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox