]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
platform/x86: ISST: Support SST-PP revision 2
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Tue, 6 May 2025 16:35:30 +0000 (09:35 -0700)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Thu, 8 May 2025 13:04:06 +0000 (16:04 +0300)
SST PP revision 2 added fabric 1 P0, P1 and Pm frequencies. Export them
by using a new IOCTL ISST_IF_GET_PERF_LEVEL_FABRIC_INFO. This IOCTL
requires platforms with SST PP revision 2 or higher.

To accommodate potential future increases in fabric count and avoid ABI
changes, support is extended for up to 8 fabrics.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://lore.kernel.org/r/20250506163531.1061185-3-srinivas.pandruvada@linux.intel.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c
include/uapi/linux/isst_if.h

index a52fc2f5ea89e4c25bbe45efa98c963f06ae4802..f56bb63f7947b432ec71377b3e2d07f852dda403 100644 (file)
@@ -1016,6 +1016,7 @@ static int isst_if_set_perf_feature(void __user *argp)
 
 #define SST_PP_INFO_10_OFFSET  80
 #define SST_PP_INFO_11_OFFSET  88
+#define SST_PP_INFO_12_OFFSET  96
 
 #define SST_PP_P1_SSE_START    0
 #define SST_PP_P1_SSE_WIDTH    8
@@ -1068,6 +1069,15 @@ static int isst_if_set_perf_feature(void __user *argp)
 #define SST_PP_CORE_RATIO_PM_FABRIC_START      48
 #define SST_PP_CORE_RATIO_PM_FABRIC_WIDTH      8
 
+#define SST_PP_CORE_RATIO_P0_FABRIC_1_START    0
+#define SST_PP_CORE_RATIO_P0_FABRIC_1_WIDTH    8
+
+#define SST_PP_CORE_RATIO_P1_FABRIC_1_START    8
+#define SST_PP_CORE_RATIO_P1_FABRIC_1_WIDTH    8
+
+#define SST_PP_CORE_RATIO_PM_FABRIC_1_START    16
+#define SST_PP_CORE_RATIO_PM_FABRIC_1_WIDTH    8
+
 static int isst_if_get_perf_level_info(void __user *argp)
 {
        struct isst_perf_level_data_info perf_level;
@@ -1167,6 +1177,59 @@ static int isst_if_get_perf_level_info(void __user *argp)
        return 0;
 }
 
+static int isst_if_get_perf_level_fabric_info(void __user *argp)
+{
+       struct isst_perf_level_fabric_info perf_level_fabric;
+       struct tpmi_per_power_domain_info *power_domain_info;
+       int start = SST_PP_CORE_RATIO_P0_FABRIC_START;
+       int width = SST_PP_CORE_RATIO_P0_FABRIC_WIDTH;
+       int offset = SST_PP_INFO_11_OFFSET;
+       int i;
+
+       if (copy_from_user(&perf_level_fabric, argp, sizeof(perf_level_fabric)))
+               return -EFAULT;
+
+       power_domain_info = get_instance(perf_level_fabric.socket_id,
+                                        perf_level_fabric.power_domain_id);
+       if (!power_domain_info)
+               return -EINVAL;
+
+       if (perf_level_fabric.level > power_domain_info->max_level)
+               return -EINVAL;
+
+       if (power_domain_info->pp_header.feature_rev < 2)
+               return -EINVAL;
+
+       if (!(power_domain_info->pp_header.level_en_mask & BIT(perf_level_fabric.level)))
+               return -EINVAL;
+
+       /* For revision 2, maximum number of fabrics is 2 */
+       perf_level_fabric.max_fabrics = 2;
+
+       for (i = 0; i < perf_level_fabric.max_fabrics; i++) {
+               _read_pp_level_info("p0_fabric_freq_mhz", perf_level_fabric.p0_fabric_freq_mhz[i],
+                                   perf_level_fabric.level, offset, start, width,
+                                   SST_MUL_FACTOR_FREQ)
+               start += width;
+
+               _read_pp_level_info("p1_fabric_freq_mhz", perf_level_fabric.p1_fabric_freq_mhz[i],
+                                   perf_level_fabric.level, offset, start, width,
+                                   SST_MUL_FACTOR_FREQ)
+               start += width;
+
+               _read_pp_level_info("pm_fabric_freq_mhz", perf_level_fabric.pm_fabric_freq_mhz[i],
+                                   perf_level_fabric.level, offset, start, width,
+                                   SST_MUL_FACTOR_FREQ)
+               offset = SST_PP_INFO_12_OFFSET;
+               start = SST_PP_CORE_RATIO_P0_FABRIC_1_START;
+       }
+
+       if (copy_to_user(argp, &perf_level_fabric, sizeof(perf_level_fabric)))
+               return -EFAULT;
+
+       return 0;
+}
+
 #define SST_PP_FUSED_CORE_COUNT_START  0
 #define SST_PP_FUSED_CORE_COUNT_WIDTH  8
 
@@ -1453,6 +1516,9 @@ static long isst_if_def_ioctl(struct file *file, unsigned int cmd,
        case ISST_IF_GET_PERF_LEVEL_INFO:
                ret = isst_if_get_perf_level_info(argp);
                break;
+       case ISST_IF_GET_PERF_LEVEL_FABRIC_INFO:
+               ret = isst_if_get_perf_level_fabric_info(argp);
+               break;
        case ISST_IF_GET_PERF_LEVEL_CPU_MASK:
                ret = isst_if_get_perf_level_mask(argp);
                break;
index 0df1a1c3caf4f8d9c77792328f547f71a2f44f78..8197a4800604edc0160bea22eda547a8f6506347 100644 (file)
@@ -375,6 +375,30 @@ struct isst_perf_level_data_info {
        __u16 trl_freq_mhz[TRL_MAX_LEVELS][TRL_MAX_BUCKETS];
 };
 
+#define MAX_FABRIC_COUNT       8
+
+/**
+ * struct isst_perf_level_fabric_info - Structure to get SST-PP fabric details
+ * @socket_id:         Socket/package id
+ * @power_domain_id:   Power Domain id
+ * @level:             SST-PP level for which caller wants to get information
+ * @max_fabrics:       Count of fabrics in resonse
+ * @p0_fabric_freq_mhz: Fabric (Uncore) maximum frequency
+ * @p1_fabric_freq_mhz: Fabric (Uncore) TDP frequency
+ * @pm_fabric_freq_mhz: Fabric (Uncore) minimum frequency
+ *
+ * Structure used to get information on frequencies for fabrics.
+ */
+struct isst_perf_level_fabric_info {
+       __u8 socket_id;
+       __u8 power_domain_id;
+       __u16 level;
+       __u16 max_fabrics;
+       __u16 p0_fabric_freq_mhz[MAX_FABRIC_COUNT];
+       __u16 p1_fabric_freq_mhz[MAX_FABRIC_COUNT];
+       __u16 pm_fabric_freq_mhz[MAX_FABRIC_COUNT];
+};
+
 /**
  * struct isst_perf_level_cpu_mask - Structure to get SST-PP level CPU mask
  * @socket_id: Socket/package id
@@ -471,5 +495,7 @@ struct isst_turbo_freq_info {
 #define ISST_IF_GET_BASE_FREQ_INFO     _IOR(ISST_IF_MAGIC, 14, struct isst_base_freq_info *)
 #define ISST_IF_GET_BASE_FREQ_CPU_MASK _IOR(ISST_IF_MAGIC, 15, struct isst_perf_level_cpu_mask *)
 #define ISST_IF_GET_TURBO_FREQ_INFO    _IOR(ISST_IF_MAGIC, 16, struct isst_turbo_freq_info *)
+#define ISST_IF_GET_PERF_LEVEL_FABRIC_INFO _IOR(ISST_IF_MAGIC, 17,\
+                                               struct isst_perf_level_fabric_info *)
 
 #endif