diff --git a/Documentation/admin-guide/pm/intel_uncore_frequency_scaling.rst b/Documentation/admin-guide/pm/intel_uncore_frequency_scaling.rst index d367ba4d744a..b43ad4d5e333 100644 --- a/Documentation/admin-guide/pm/intel_uncore_frequency_scaling.rst +++ b/Documentation/admin-guide/pm/intel_uncore_frequency_scaling.rst @@ -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. diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c index 25ab511ed8d2..3b554418a7a3 100644 --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c @@ -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); diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h index 0d5fd91ee0aa..e319448dc1a4 100644 --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h @@ -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 diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c index 88015a2c6a0d..44e2a90004df 100644 --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c @@ -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;