All of lore.kernel.org
 help / color / mirror / Atom feed
From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
To: hdegoede@redhat.com, markgross@kernel.org
Cc: platform-driver-x86@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>,
	Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>,
	"Rafael J . Wysocki" <rafael.j.wysocki@intel.com>
Subject: [PATCH 5/7] platform/x86/intel/tpmi: Process CPU package mapping
Date: Wed,  1 Feb 2023 17:07:36 -0800	[thread overview]
Message-ID: <20230202010738.2186174-6-srinivas.pandruvada@linux.intel.com> (raw)
In-Reply-To: <20230202010738.2186174-1-srinivas.pandruvada@linux.intel.com>

There is one Intel Out-of-Band (OOB) PCI device per CPU package. Since
TPMI feature is exposed via OOB PCI device, there will be multiple
TPMI device instances on a multi CPU package system.

There are several PM features, which needs to associate APIC based CPU
package ID information to a TPMI instance. For example if Intel Speed
Select feature requires control of a CPU package, it needs to identify
right TPMI device instance.

There is one special TPMI ID (ID = 0x81) in the PFS. The MMIO
region of this TPMI ID points to a mapping table:
- PCI Bus ID
- PCI Device ID
- APIC based Package ID

This mapping information can be used by any PM feature driver which
requires mapping from a CPU package to a TPMI device instance.

Unlike other TPMI features, device node is not created for this feature
ID (0x81). Instead store the mapping information as platform data, which
is part of the per PCI device TPMI instance (struct intel_tpmi_info).
Later the TPMI feature drivers can get the mapping information using an
interface "tpmi_get_platform_data()"

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/platform/x86/intel/tpmi.c | 72 +++++++++++++++++++++++++++++++
 include/linux/intel_tpmi.h        | 28 ++++++++++++
 2 files changed, 100 insertions(+)
 create mode 100644 include/linux/intel_tpmi.h

diff --git a/drivers/platform/x86/intel/tpmi.c b/drivers/platform/x86/intel/tpmi.c
index 1b87b46ba8a9..e612da579b29 100644
--- a/drivers/platform/x86/intel/tpmi.c
+++ b/drivers/platform/x86/intel/tpmi.c
@@ -47,6 +47,7 @@
  */
 
 #include <linux/auxiliary_bus.h>
+#include <linux/intel_tpmi.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -96,6 +97,7 @@ struct intel_tpmi_pm_feature {
  * @vsec_dev:		Pointer to intel_vsec_device structure for this TPMI device
  * @feature_count:	Number of TPMI of TPMI instances pointed by tpmi_features
  * @pfs_start:		Start of PFS offset for the TPMI instances in this device
+ * @plat_info:		Stores platform info which can be used by the client drivers
  *
  * Stores the information for all TPMI devices enumerated from a single PCI device.
  */
@@ -104,8 +106,30 @@ struct intel_tpmi_info {
 	struct intel_vsec_device *vsec_dev;
 	int feature_count;
 	u64 pfs_start;
+	struct intel_tpmi_plat_info plat_info;
 };
 
+/**
+ * struct tpmi_info_header - CPU package ID to PCI device mapping information
+ * @fn:		PCI function number
+ * @dev:	PCI device number
+ * @bus:	PCI bus number
+ * @pkg:	CPU Package id
+ * @reserved:	Reserved for future use
+ * @lock:	When set to 1 the register is locked and becomes read-only
+ *		until next reset. Not for use by the OS driver.
+ *
+ * The structure to read hardware provided mapping information.
+ */
+struct tpmi_info_header {
+	u64 fn:3;
+	u64 dev:5;
+	u64 bus:8;
+	u64 pkg:8;
+	u64 reserved:39;
+	u64 lock:1;
+} __packed;
+
 /*
  * List of supported TMPI IDs.
  * Some TMPI IDs are not used by Linux, so the numbers are not consecutive.
@@ -115,11 +139,20 @@ enum intel_tpmi_id {
 	TPMI_ID_PEM = 1, /* Power and Perf excursion Monitor */
 	TPMI_ID_UNCORE = 2, /* Uncore Frequency Scaling */
 	TPMI_ID_SST = 5, /* Speed Select Technology */
+	TPMI_INFO_ID = 0x81, /* Special ID for PCI BDF and Package ID information */
 };
 
 /* Used during auxbus device creation */
 static DEFINE_IDA(intel_vsec_tpmi_ida);
 
+struct intel_tpmi_plat_info *tpmi_get_platform_data(struct auxiliary_device *auxdev)
+{
+	struct intel_vsec_device *vsec_dev = auxdev_to_ivdev(auxdev);
+
+	return vsec_dev->priv_data;
+}
+EXPORT_SYMBOL_NS_GPL(tpmi_get_platform_data, INTEL_TPMI);
+
 static const char *intel_tpmi_name(enum intel_tpmi_id id)
 {
 	switch (id) {
@@ -177,6 +210,8 @@ static int tpmi_create_device(struct intel_tpmi_info *tpmi_info,
 	feature_vsec_dev->pcidev = vsec_dev->pcidev;
 	feature_vsec_dev->resource = res;
 	feature_vsec_dev->num_resources = pfs->pfs_header.num_entries;
+	feature_vsec_dev->priv_data = &tpmi_info->plat_info;
+	feature_vsec_dev->priv_data_size = sizeof(tpmi_info->plat_info);
 	feature_vsec_dev->ida = &intel_vsec_tpmi_ida;
 
 	/*
@@ -220,6 +255,31 @@ static int tpmi_create_devices(struct intel_tpmi_info *tpmi_info)
 	return 0;
 }
 
+#define TPMI_INFO_BUS_INFO_OFFSET	0x08
+
+static int tpmi_process_info(struct intel_tpmi_info *tpmi_info,
+			     struct intel_tpmi_pm_feature *pfs)
+{
+	struct tpmi_info_header header;
+	void __iomem *info_mem;
+
+	info_mem = ioremap(pfs->vsec_offset + TPMI_INFO_BUS_INFO_OFFSET,
+			   pfs->pfs_header.entry_size * 4 - TPMI_INFO_BUS_INFO_OFFSET);
+	if (!info_mem)
+		return -ENOMEM;
+
+	memcpy_fromio(&header, info_mem, sizeof(header));
+
+	tpmi_info->plat_info.package_id = header.pkg;
+	tpmi_info->plat_info.bus_number = header.bus;
+	tpmi_info->plat_info.device_number = header.dev;
+	tpmi_info->plat_info.function_number = header.fn;
+
+	iounmap(info_mem);
+
+	return 0;
+}
+
 static int tpmi_fetch_pfs_header(struct intel_tpmi_pm_feature *pfs, u64 start, int size)
 {
 	void __iomem *pfs_mem;
@@ -238,6 +298,7 @@ static int tpmi_fetch_pfs_header(struct intel_tpmi_pm_feature *pfs, u64 start, i
 static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev)
 {
 	struct intel_vsec_device *vsec_dev = auxdev_to_ivdev(auxdev);
+	struct pci_dev *pci_dev = vsec_dev->pcidev;
 	struct intel_tpmi_info *tpmi_info;
 	u64 pfs_start = 0;
 	int i;
@@ -248,6 +309,7 @@ static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev)
 
 	tpmi_info->vsec_dev = vsec_dev;
 	tpmi_info->feature_count = vsec_dev->num_resources;
+	tpmi_info->plat_info.bus_number = pci_dev->bus->number;
 
 	tpmi_info->tpmi_features = devm_kcalloc(&auxdev->dev, vsec_dev->num_resources,
 						sizeof(*tpmi_info->tpmi_features),
@@ -282,6 +344,16 @@ static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev)
 		pfs->pfs_header.cap_offset *= 1024;
 
 		pfs->vsec_offset = pfs_start + pfs->pfs_header.cap_offset;
+
+		/*
+		 * Process TPMI_INFO to get PCI device to CPU package ID.
+		 * Device nodes for TPMI features are not created in this
+		 * for loop. So, the mapping information will be available
+		 * when actual device nodes created outside this
+		 * loop via tpmi_create_devices().
+		 */
+		if (pfs->pfs_header.tpmi_id == TPMI_INFO_ID)
+			tpmi_process_info(tpmi_info, pfs);
 	}
 
 	tpmi_info->pfs_start = pfs_start;
diff --git a/include/linux/intel_tpmi.h b/include/linux/intel_tpmi.h
new file mode 100644
index 000000000000..5b665320ecb4
--- /dev/null
+++ b/include/linux/intel_tpmi.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * intel_tpmi.h: Intel TPMI core external interface
+ */
+
+#ifndef _INTEL_TPMI_H_
+#define _INTEL_TPMI_H_
+
+/**
+ * struct intel_tpmi_plat_info - Platform information for a TPMI device instance
+ * @package_id:	CPU Package id
+ * @bus_number:	PCI bus number
+ * @device_number: PCI device number
+ * @function_number: PCI function number
+ *
+ * Structure to store platform data for a TPMI device instance. This
+ * struct is used to return data via tpmi_get_platform_data().
+ */
+struct intel_tpmi_plat_info {
+	u8 package_id;
+	u8 bus_number;
+	u8 device_number;
+	u8 function_number;
+};
+
+struct intel_tpmi_plat_info *tpmi_get_platform_data(struct auxiliary_device *auxdev);
+
+#endif
-- 
2.31.1


  parent reply	other threads:[~2023-02-02  1:09 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-02  1:07 [PATCH 0/7] Add TPMI support Srinivas Pandruvada
2023-02-02  1:07 ` [PATCH 1/7] platform/x86/intel/vsec: Add TPMI ID Srinivas Pandruvada
2023-02-02  1:07 ` [PATCH 2/7] platform/x86/intel/vsec: Enhance and Export intel_vsec_add_aux() Srinivas Pandruvada
2023-02-02  1:07 ` [PATCH 3/7] platform/x86/intel/vsec: Support private data Srinivas Pandruvada
2023-02-02  1:07 ` [PATCH 4/7] platform/x86/intel: Intel TPMI enumeration driver Srinivas Pandruvada
2023-02-02  1:07 ` Srinivas Pandruvada [this message]
2023-02-02  1:07 ` [PATCH 6/7] platform/x86/intel/tpmi: ADD tpmi external interface for tpmi feature drivers Srinivas Pandruvada
2023-02-02  1:07 ` [PATCH 7/7] MAINTAINERS: Add entry for TPMI driver Srinivas Pandruvada
2023-02-06 12:50   ` Hans de Goede
2023-02-06 12:49 ` [PATCH 0/7] Add TPMI support Hans de Goede
2023-02-06 12:55   ` Hans de Goede
2023-02-06 13:29     ` srinivas pandruvada
2023-02-10  8:04   ` srinivas pandruvada
2023-02-10 14:24     ` Hans de Goede

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=20230202010738.2186174-6-srinivas.pandruvada@linux.intel.com \
    --to=srinivas.pandruvada@linux.intel.com \
    --cc=hdegoede@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=markgross@kernel.org \
    --cc=pierre-louis.bossart@linux.intel.com \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=rafael.j.wysocki@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.