]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
platform/x86/intel-uncore-freq: Expose instance ID in the sysfs
authorMaciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Wed, 8 Apr 2026 16:27:51 +0000 (16:27 +0000)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Wed, 6 May 2026 10:36:50 +0000 (13:36 +0300)
Insufficient data is exported to allow direct access to TPMI registers
through MMIO. On non-partitioned systems domain_id can be used both for
mapping CPUs to their compute die IDs and for mapping die indices to
their MMIO memory blocks presented to userspace via TPMI debugfs.
However on partitioned systems the debugfs association doesn't work
anymore. This is due to how TPMI partitioning influences domain_id
calculation. The previous association is lost on partitioned systems in
order to keep using domain_id for mapping CPUs to compute dies.

Expose the instance ID in sysfs that's unique in the scope of one TPMI
partition (and hence one TPMI device). It's a physical index into mapped
MMIO blocks and can be used by userspace to figure out how to directly
access TPMI registers.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/b9ae8d5f1ab86bcdb1a8636fa48865a9e49e2e21.1775665057.git.m.wieczorretman@pm.me
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Documentation/admin-guide/pm/intel_uncore_frequency_scaling.rst
drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c
drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h
drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c

index d367ba4d744af4b890c110913f5aacdd3fd5061a..b43ad4d5e333b2c0332cdce2b882d43961720415 100644 (file)
@@ -88,8 +88,15 @@ and "fabric_cluster_id" in the directory.
 
 Attributes in each directory:
 
+``instance_id``
+       This attribute is used to get die indices in userspace mapped MMIO
+       blocks. Indices are local to a single TPMI partition. Needed for direct
+       TPMI register access.
+
 ``domain_id``
        This attribute is used to get the power domain id of this instance.
+       Indices are unique in all TPMI partitions on a given CPU package. Can be
+       used to map compute dies to corresponding CPUs.
 
 ``die_id``
        This attribute is used to get the Linux die id of this instance.
index 25ab511ed8d2a1a802119506cf854870b080d1ff..3b554418a7a3c1e1242c6dd38600c8967a62365b 100644 (file)
@@ -29,6 +29,13 @@ static ssize_t show_domain_id(struct kobject *kobj, struct kobj_attribute *attr,
        return sysfs_emit(buf, "%u\n", data->domain_id);
 }
 
+static ssize_t show_instance_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+       struct uncore_data *data = container_of(attr, struct uncore_data, instance_id_kobj_attr);
+
+       return sysfs_emit(buf, "%u\n", data->instance_id);
+}
+
 static ssize_t show_fabric_cluster_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
 {
        struct uncore_data *data = container_of(attr, struct uncore_data, fabric_cluster_id_kobj_attr);
@@ -200,6 +207,9 @@ static int create_attr_group(struct uncore_data *data, char *name)
        if (data->domain_id != UNCORE_DOMAIN_ID_INVALID) {
                init_attribute_root_ro(domain_id);
                data->uncore_attrs[index++] = &data->domain_id_kobj_attr.attr;
+               init_attribute_root_ro(instance_id);
+               data->uncore_attrs[index++] = &data->instance_id_kobj_attr.attr;
+
                init_attribute_root_ro(fabric_cluster_id);
                data->uncore_attrs[index++] = &data->fabric_cluster_id_kobj_attr.attr;
                init_attribute_root_ro(package_id);
index 0d5fd91ee0aac279704ead6e2a97d5002f6ae3aa..e319448dc1a4400a857cef4800ff7ce7669c6796 100644 (file)
@@ -36,6 +36,7 @@
  * @domain_id:         Power domain id for this instance
  * @cluster_id:                cluster id in a domain
  * @seqnum_id:         Unique sequential id to append to directory name
+ * @instance_id:       Die indices or feature instances for a single TPMI device
  * @name:              Sysfs entry name for this instance
  * @agent_type_mask:   Bit mask of all hardware agents for this domain
  * @uncore_attr_group: Attribute group storage
@@ -56,6 +57,7 @@
  * @elc_floor_freq_khz_kobj_attr: Storage for kobject attribute elc_floor_freq_khz
  * @agent_types_kobj_attr: Storage for kobject attribute agent_type
  * @die_id_kobj_attr:  Attribute storage for die_id information
+ * @instance_id_kobj_attr: Attribute storage for instance_id value
  * @uncore_attrs:      Attribute storage for group creation
  *
  * This structure is used to encapsulate all data related to uncore sysfs
@@ -72,6 +74,7 @@ struct uncore_data {
        int domain_id;
        int cluster_id;
        int seqnum_id;
+       int instance_id;
        char name[32];
        u16  agent_type_mask;
 
@@ -90,7 +93,8 @@ struct uncore_data {
        struct kobj_attribute elc_floor_freq_khz_kobj_attr;
        struct kobj_attribute agent_types_kobj_attr;
        struct kobj_attribute die_id_kobj_attr;
-       struct attribute *uncore_attrs[15];
+       struct kobj_attribute instance_id_kobj_attr;
+       struct attribute *uncore_attrs[16];
 };
 
 #define UNCORE_DOMAIN_ID_INVALID       -1
index 88015a2c6a0d12895484ff2547839f32f50e6e34..44e2a90004df39581cc1cec9940a96685c8c385e 100644 (file)
@@ -385,7 +385,19 @@ static u8 io_die_index_next;
 /* Lock to protect io_die_start, io_die_index_next */
 static DEFINE_MUTEX(domain_lock);
 
-static void set_domain_id(int id,  int num_resources,
+static inline void set_instance_id(int id, struct tpmi_uncore_cluster_info *cluster_info)
+{
+       /*
+        * On non-partitioned systems domain_id can be used for mapping both
+        * CPUs to compute die IDs and physical die indexes to MMIO mapped
+        * memory. However on partitioned systems domain_id loses the second
+        * association. Therefore instance_id should be used for that instead,
+        * while domain_id should still be used to match CPUs to compute dies.
+        */
+       cluster_info->uncore_data.instance_id = id;
+}
+
+static void set_domain_id(int id, int num_resources,
                          struct oobmsm_plat_info *plat_info,
                          struct tpmi_uncore_cluster_info *cluster_info)
 {
@@ -690,6 +702,7 @@ static int uncore_probe(struct auxiliary_device *auxdev, const struct auxiliary_
                        set_cdie_id(i, cluster_info, plat_info);
 
                        set_domain_id(i, num_resources, plat_info, cluster_info);
+                       set_instance_id(i, cluster_info);
 
                        cluster_info->uncore_root = tpmi_uncore;