diff options
author | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> | 2023-03-08 10:06:41 +0300 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2023-03-16 17:18:02 +0300 |
commit | f8e0077a9d526cac7abbc682d83e98f834ffa909 (patch) | |
tree | f4627414969f7742428c92e70586de730c0dafa6 /drivers/platform/x86/intel/speed_select_if | |
parent | 06a61df83209ac7f376616f83f3485217c703d50 (diff) | |
download | linux-f8e0077a9d526cac7abbc682d83e98f834ffa909.tar.xz |
platform/x86: ISST: Add SST-TF support via TPMI
The support of Intel Speed Select Technology - Turbo Frequency (SST-TF)
feature enables the ability to set different “All core turbo ratio
limits” to cores based on the priority. By using this feature, some cores
can be configured to get higher turbo frequency by designating them as
high priority at the cost of lower or no turbo frequency on the low
priority cores.
One new IOCTLs are added:
ISST_IF_GET_TURBO_FREQ_INFO : Get information about turbo frequency
buckets
Once an instance is identified, read or write from correct MMIO
offset for a given field as defined in the specification.
For details on SST-TF operations using intel-speed-selet utility,
refer to:
Documentation/admin-guide/pm/intel-speed-select.rst
under the kernel documentation
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
Tested-by: Pragya Tanwar <pragya.tanwar@intel.com>
Link: https://lore.kernel.org/r/20230308070642.1727167-8-srinivas.pandruvada@linux.intel.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'drivers/platform/x86/intel/speed_select_if')
-rw-r--r-- | drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c b/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c index 0566c8d30181..5104717afe0e 100644 --- a/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c +++ b/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c @@ -1125,6 +1125,69 @@ static int isst_if_get_tpmi_instance_count(void __user *argp) return 0; } +#define SST_TF_INFO_0_OFFSET 0 +#define SST_TF_INFO_1_OFFSET 8 +#define SST_TF_INFO_2_OFFSET 16 + +#define SST_TF_MAX_LP_CLIP_RATIOS TRL_MAX_LEVELS + +#define SST_TF_LP_CLIP_RATIO_0_START 16 +#define SST_TF_LP_CLIP_RATIO_0_WIDTH 8 + +#define SST_TF_RATIO_0_START 0 +#define SST_TF_RATIO_0_WIDTH 8 + +#define SST_TF_NUM_CORE_0_START 0 +#define SST_TF_NUM_CORE_0_WIDTH 8 + +static int isst_if_get_turbo_freq_info(void __user *argp) +{ + static struct isst_turbo_freq_info turbo_freq; + struct tpmi_per_power_domain_info *power_domain_info; + int i, j; + + if (copy_from_user(&turbo_freq, argp, sizeof(turbo_freq))) + return -EFAULT; + + power_domain_info = get_instance(turbo_freq.socket_id, turbo_freq.power_domain_id); + if (!power_domain_info) + return -EINVAL; + + if (turbo_freq.level > power_domain_info->max_level) + return -EINVAL; + + turbo_freq.max_buckets = TRL_MAX_BUCKETS; + turbo_freq.max_trl_levels = TRL_MAX_LEVELS; + turbo_freq.max_clip_freqs = SST_TF_MAX_LP_CLIP_RATIOS; + + for (i = 0; i < turbo_freq.max_clip_freqs; ++i) + _read_tf_level_info("lp_clip*", turbo_freq.lp_clip_freq_mhz[i], + turbo_freq.level, SST_TF_INFO_0_OFFSET, + SST_TF_LP_CLIP_RATIO_0_START + + (i * SST_TF_LP_CLIP_RATIO_0_WIDTH), + SST_TF_LP_CLIP_RATIO_0_WIDTH, SST_MUL_FACTOR_FREQ) + + for (i = 0; i < TRL_MAX_LEVELS; ++i) { + for (j = 0; j < TRL_MAX_BUCKETS; ++j) + _read_tf_level_info("cydn*_bucket_*_trl", + turbo_freq.trl_freq_mhz[i][j], turbo_freq.level, + SST_TF_INFO_2_OFFSET + (i * SST_TF_RATIO_0_WIDTH), + j * SST_TF_RATIO_0_WIDTH, SST_TF_RATIO_0_WIDTH, + SST_MUL_FACTOR_FREQ) + } + + for (i = 0; i < TRL_MAX_BUCKETS; ++i) + _read_tf_level_info("bucket_*_core_count", turbo_freq.bucket_core_counts[i], + turbo_freq.level, SST_TF_INFO_1_OFFSET, + SST_TF_NUM_CORE_0_WIDTH * i, SST_TF_NUM_CORE_0_WIDTH, + SST_MUL_FACTOR_NONE) + + if (copy_to_user(argp, &turbo_freq, sizeof(turbo_freq))) + return -EFAULT; + + return 0; +} + static long isst_if_def_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -1166,6 +1229,9 @@ static long isst_if_def_ioctl(struct file *file, unsigned int cmd, case ISST_IF_GET_BASE_FREQ_CPU_MASK: ret = isst_if_get_base_freq_mask(argp); break; + case ISST_IF_GET_TURBO_FREQ_INFO: + ret = isst_if_get_turbo_freq_info(argp); + break; default: break; } |