From 7c7e7c0d396b99d5b41d052dbf2b2bddcd5f7f3c Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 20 Aug 2022 18:11:21 +0800 Subject: [PATCH 01/61] tools/power/x86/intel-speed-select: Unify TRL levels TRL supports different levels including SSE/AVX2/AVX512. Avoid using hardcoded level name and structure fields, so that a loop can be used to parse each TRL level instead. This reduces several lines of source code. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../power/x86/intel-speed-select/isst-core.c | 47 ++++++++++++------- .../x86/intel-speed-select/isst-display.c | 46 +++--------------- tools/power/x86/intel-speed-select/isst.h | 11 +++-- 3 files changed, 44 insertions(+), 60 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 2bfc118c4b871..aec81b5658a9d 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -6,6 +6,25 @@ #include "isst.h" +int isst_get_trl_max_levels(void) +{ + return 3; +} + +char *isst_get_trl_level_name(int level) +{ + switch (level) { + case 0: + return "sse"; + case 1: + return "avx2"; + case 2: + return "avx512"; + default: + return NULL; + } +} + int isst_write_pm_config(struct isst_id *id, int cp_state) { unsigned int req, resp; @@ -795,6 +814,8 @@ int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctd for (i = 0; i <= pkg_dev->levels; ++i) { struct isst_pkg_ctdp_level_info *ctdp_level; + int trl_max_levels = isst_get_trl_max_levels(); + int j; if (tdp_level != 0xff && i != tdp_level) continue; @@ -838,8 +859,8 @@ int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctd ctdp_level->tdp_ratio = ctdp_level->sse_p1; } - isst_get_get_trl_from_msr(id, ctdp_level->trl_sse_active_cores); - isst_get_trl_bucket_info(id, &ctdp_level->buckets_info); + isst_get_get_trl_from_msr(id, ctdp_level->trl_ratios[0]); + isst_get_trl_bucket_info(id, &ctdp_level->trl_cores); continue; } @@ -861,24 +882,16 @@ int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctd if (ret) return ret; - ret = isst_get_trl_bucket_info(id, &ctdp_level->buckets_info); + ret = isst_get_trl_bucket_info(id, &ctdp_level->trl_cores); if (ret) return ret; - ret = isst_get_get_trl(id, i, 0, - ctdp_level->trl_sse_active_cores); - if (ret) - return ret; - - ret = isst_get_get_trl(id, i, 1, - ctdp_level->trl_avx_active_cores); - if (ret) - return ret; - - ret = isst_get_get_trl(id, i, 2, - ctdp_level->trl_avx_512_active_cores); - if (ret) - return ret; + for (j = 0; j < trl_max_levels; j++) { + ret = isst_get_get_trl(id, i, j, + ctdp_level->trl_ratios[j]); + if (ret) + return ret; + } isst_get_uncore_p0_p1_info(id, i, ctdp_level); isst_get_p1_info(id, i, ctdp_level); diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 7feadac04a6f5..b9efbdf77dc1b 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -354,6 +354,7 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level char header[256]; char value[512]; static int level; + int trl_max_levels = isst_get_trl_max_levels(); int i; if (pkg_dev->processed) @@ -361,7 +362,7 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level for (i = 0; i <= pkg_dev->levels; ++i) { struct isst_pkg_ctdp_level_info *ctdp_level; - int j; + int j, k; ctdp_level = &pkg_dev->ctdp_level[i]; if (!ctdp_level->processed) @@ -505,54 +506,21 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level format_and_print(outf, level + 2, header, value); } - snprintf(header, sizeof(header), "turbo-ratio-limits-sse"); - format_and_print(outf, level + 2, header, NULL); - for (j = 0; j < 8; ++j) { - snprintf(header, sizeof(header), "bucket-%d", j); - format_and_print(outf, level + 3, header, NULL); - - snprintf(header, sizeof(header), "core-count"); - snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); - format_and_print(outf, level + 4, header, value); - - snprintf(header, sizeof(header), - "max-turbo-frequency(MHz)"); - snprintf(value, sizeof(value), "%d", - ctdp_level->trl_sse_active_cores[j] * - DISP_FREQ_MULTIPLIER); - format_and_print(outf, level + 4, header, value); - } - - if (ctdp_level->trl_avx_active_cores[0]) { - snprintf(header, sizeof(header), "turbo-ratio-limits-avx2"); + for (k = 0; k < trl_max_levels; k++) { + snprintf(header, sizeof(header), "turbo-ratio-limits-%s", isst_get_trl_level_name(k)); format_and_print(outf, level + 2, header, NULL); - for (j = 0; j < 8; ++j) { - snprintf(header, sizeof(header), "bucket-%d", j); - format_and_print(outf, level + 3, header, NULL); - snprintf(header, sizeof(header), "core-count"); - snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); - format_and_print(outf, level + 4, header, value); - - snprintf(header, sizeof(header), "max-turbo-frequency(MHz)"); - snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_active_cores[j] * DISP_FREQ_MULTIPLIER); - format_and_print(outf, level + 4, header, value); - } - } - - if (ctdp_level->trl_avx_512_active_cores[0]) { - snprintf(header, sizeof(header), "turbo-ratio-limits-avx512"); - format_and_print(outf, level + 2, header, NULL); for (j = 0; j < 8; ++j) { snprintf(header, sizeof(header), "bucket-%d", j); format_and_print(outf, level + 3, header, NULL); snprintf(header, sizeof(header), "core-count"); - snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); + + snprintf(value, sizeof(value), "%llu", (ctdp_level->trl_cores >> (j * 8)) & 0xff); format_and_print(outf, level + 4, header, value); snprintf(header, sizeof(header), "max-turbo-frequency(MHz)"); - snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_512_active_cores[j] * DISP_FREQ_MULTIPLIER); + snprintf(value, sizeof(value), "%d", ctdp_level->trl_ratios[k][j] * DISP_FREQ_MULTIPLIER); format_and_print(outf, level + 4, header, value); } } diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 824876e31e232..8f563ff300bb5 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -28,6 +28,8 @@ #include #include +#include + #define BIT(x) (1 << (x)) #define BIT_ULL(nr) (1ULL << (nr)) #define GENMASK(h, l) (((~0UL) << (l)) & (~0UL >> (sizeof(long) * 8 - 1 - (h)))) @@ -153,10 +155,8 @@ struct isst_pkg_ctdp_level_info { size_t core_cpumask_size; cpu_set_t *core_cpumask; int cpu_count; - unsigned long long buckets_info; - int trl_sse_active_cores[ISST_TRL_MAX_ACTIVE_CORES]; - int trl_avx_active_cores[ISST_TRL_MAX_ACTIVE_CORES]; - int trl_avx_512_active_cores[ISST_TRL_MAX_ACTIVE_CORES]; + unsigned long long trl_cores; /* Buckets info */ + int trl_ratios[TRL_MAX_LEVELS][ISST_TRL_MAX_ACTIVE_CORES]; int kobj_bucket_index; int active_bucket; int fact_max_index; @@ -205,6 +205,9 @@ extern int isst_send_mbox_command(unsigned int cpu, unsigned char command, extern int isst_send_msr_command(unsigned int cpu, unsigned int command, int write, unsigned long long *req_resp); +extern int isst_get_trl_max_levels(void); +extern char *isst_get_trl_level_name(int level); + extern int isst_get_ctdp_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev); extern int isst_get_ctdp_control(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); From 16c1892080d841e5d4b59295b96ae760b83c0b7f Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 20 Aug 2022 18:33:01 +0800 Subject: [PATCH 02/61] tools/power/x86/intel-speed-select: Follow TRL nameing for FACT info SST-TF high priority core count and ratios and low priority core ratios are also per TRL level. Cleanup the code to follow the same nameing convention as TRL. This removes hardcoded TRL level names and variables. No functional changes are expected. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada --- .../power/x86/intel-speed-select/isst-core.c | 28 ++------ .../x86/intel-speed-select/isst-display.c | 70 ++++++++----------- tools/power/x86/intel-speed-select/isst.h | 10 +-- 3 files changed, 38 insertions(+), 70 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index aec81b5658a9d..8aa2ee4bb2320 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -592,7 +592,7 @@ int isst_get_fact_bucket_info(struct isst_id *id, int level, id->cpu, i, level, resp); for (j = 0; j < 4; ++j) { - bucket_info[j + (i * 4)].high_priority_cores_count = + bucket_info[j + (i * 4)].hp_cores = (resp >> (j * 8)) & 0xff; } } @@ -613,22 +613,8 @@ int isst_get_fact_bucket_info(struct isst_id *id, int level, id->cpu, i, level, k, resp); for (j = 0; j < 4; ++j) { - switch (k) { - case 0: - bucket_info[j + (i * 4)].sse_trl = - (resp >> (j * 8)) & 0xff; - break; - case 1: - bucket_info[j + (i * 4)].avx_trl = - (resp >> (j * 8)) & 0xff; - break; - case 2: - bucket_info[j + (i * 4)].avx512_trl = - (resp >> (j * 8)) & 0xff; - break; - default: - break; - } + bucket_info[j + (i * 4)].hp_ratios[k] = + (resp >> (j * 8)) & 0xff; } } } @@ -672,9 +658,9 @@ int isst_get_fact_info(struct isst_id *id, int level, int fact_bucket, struct is debug_printf("cpu:%d CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO resp:%x\n", id->cpu, resp); - fact_info->lp_clipping_ratio_license_sse = resp & 0xff; - fact_info->lp_clipping_ratio_license_avx2 = (resp >> 8) & 0xff; - fact_info->lp_clipping_ratio_license_avx512 = (resp >> 16) & 0xff; + fact_info->lp_ratios[0] = resp & 0xff; + fact_info->lp_ratios[1] = (resp >> 8) & 0xff; + fact_info->lp_ratios[2] = (resp >> 16) & 0xff; ret = isst_get_fact_bucket_info(id, level, fact_info->bucket_info); if (ret) @@ -685,7 +671,7 @@ int isst_get_fact_info(struct isst_id *id, int level, int fact_bucket, struct is if (fact_bucket != 0xff && fact_bucket != j) continue; - if (!fact_info->bucket_info[j].high_priority_cores_count) + if (!fact_info->bucket_info[j].hp_cores) break; print = 1; diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index b9efbdf77dc1b..5e57623196fcd 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -235,6 +235,7 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l int base_level) { struct isst_fact_bucket_info *bucket_info = fact_info->bucket_info; + int trl_max_levels = isst_get_trl_max_levels(); char header[256]; char value[256]; int print = 0, j; @@ -243,7 +244,7 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l if (fact_bucket != 0xff && fact_bucket != j) continue; - if (!bucket_info[j].high_priority_cores_count) + if (!bucket_info[j].hp_cores) break; print = 1; @@ -256,10 +257,12 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l snprintf(header, sizeof(header), "speed-select-turbo-freq-properties"); format_and_print(outf, base_level, header, NULL); for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) { + int i; + if (fact_bucket != 0xff && fact_bucket != j) continue; - if (!bucket_info[j].high_priority_cores_count) + if (!bucket_info[j].hp_cores) break; snprintf(header, sizeof(header), "bucket-%d", j); @@ -267,54 +270,37 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l snprintf(header, sizeof(header), "high-priority-cores-count"); snprintf(value, sizeof(value), "%d", - bucket_info[j].high_priority_cores_count); + bucket_info[j].hp_cores); format_and_print(outf, base_level + 2, header, value); - - if (fact_avx & 0x01) { - snprintf(header, sizeof(header), - "high-priority-max-frequency(MHz)"); - snprintf(value, sizeof(value), "%d", - bucket_info[j].sse_trl * DISP_FREQ_MULTIPLIER); - format_and_print(outf, base_level + 2, header, value); - } - - if (fact_avx & 0x02) { - snprintf(header, sizeof(header), - "high-priority-max-avx2-frequency(MHz)"); - snprintf(value, sizeof(value), "%d", - bucket_info[j].avx_trl * DISP_FREQ_MULTIPLIER); - format_and_print(outf, base_level + 2, header, value); - } - - if (fact_avx & 0x04) { - snprintf(header, sizeof(header), - "high-priority-max-avx512-frequency(MHz)"); + for (i = 0; i < trl_max_levels; i++) { + if (fact_avx != 0xFF && !(fact_avx & (1 << i))) + continue; + if (i == 0) + snprintf(header, sizeof(header), + "high-priority-max-frequency(MHz)"); + else + snprintf(header, sizeof(header), + "high-priority-max-%s-frequency(MHz)", isst_get_trl_level_name(i)); snprintf(value, sizeof(value), "%d", - bucket_info[j].avx512_trl * - DISP_FREQ_MULTIPLIER); + bucket_info[j].hp_ratios[i] * DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 2, header, value); } } snprintf(header, sizeof(header), "speed-select-turbo-freq-clip-frequencies"); format_and_print(outf, base_level + 1, header, NULL); - snprintf(header, sizeof(header), "low-priority-max-frequency(MHz)"); - snprintf(value, sizeof(value), "%d", - fact_info->lp_clipping_ratio_license_sse * - DISP_FREQ_MULTIPLIER); - format_and_print(outf, base_level + 2, header, value); - snprintf(header, sizeof(header), - "low-priority-max-avx2-frequency(MHz)"); - snprintf(value, sizeof(value), "%d", - fact_info->lp_clipping_ratio_license_avx2 * - DISP_FREQ_MULTIPLIER); - format_and_print(outf, base_level + 2, header, value); - snprintf(header, sizeof(header), - "low-priority-max-avx512-frequency(MHz)"); - snprintf(value, sizeof(value), "%d", - fact_info->lp_clipping_ratio_license_avx512 * - DISP_FREQ_MULTIPLIER); - format_and_print(outf, base_level + 2, header, value); + + for (j = 0; j < trl_max_levels; j++) { + /* No AVX level name for SSE to be consistent with previous formatting */ + if (j == 0) + snprintf(header, sizeof(header), "low-priority-max-frequency(MHz)"); + else + snprintf(header, sizeof(header), "low-priority-max-%s-frequency(MHz)", + isst_get_trl_level_name(j)); + snprintf(value, sizeof(value), "%d", + fact_info->lp_ratios[j] * DISP_FREQ_MULTIPLIER); + format_and_print(outf, base_level + 2, header, value); + } } void isst_ctdp_display_core_info(struct isst_id *id, FILE *outf, char *prefix, diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 8f563ff300bb5..727afc5941091 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -98,10 +98,8 @@ struct isst_clos_config { }; struct isst_fact_bucket_info { - int high_priority_cores_count; - int sse_trl; - int avx_trl; - int avx512_trl; + int hp_cores; + int hp_ratios[TRL_MAX_LEVELS]; }; struct isst_pbf_info { @@ -119,9 +117,7 @@ struct isst_pbf_info { #define ISST_TRL_MAX_ACTIVE_CORES 8 #define ISST_FACT_MAX_BUCKETS 8 struct isst_fact_info { - int lp_clipping_ratio_license_sse; - int lp_clipping_ratio_license_avx2; - int lp_clipping_ratio_license_avx512; + int lp_ratios[TRL_MAX_LEVELS]; struct isst_fact_bucket_info bucket_info[ISST_FACT_MAX_BUCKETS]; }; From e157c8475e7c2d62d7b28983ea81167f3e6a5a57 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 17 Aug 2022 14:51:40 +0800 Subject: [PATCH 03/61] tools/power/x86/intel-speed-select: Introduce punit to isst_id Punit id can also be retrieved from ISST_IF_GET_PHY_ID. punit id is unique within a Package/Die, and together with Package id and Die id, they can be used to refer to a specific SST power domain. For current platforms, Punit id is always Zero. So no functional changes are expected for the current platforms. While here, prevent issuing IOCTL if the file /dev/isst_interface can't be opened. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-config.c | 74 +++++++++++++------ tools/power/x86/intel-speed-select/isst.h | 6 +- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 55d0a35df41cc..f17492fcf97c8 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -61,6 +61,7 @@ struct _cpu_map { unsigned short core_id; unsigned short pkg_id; unsigned short die_id; + unsigned short punit_id; unsigned short punit_cpu; unsigned short punit_cpu_core; unsigned short initialized; @@ -378,6 +379,17 @@ static int get_physical_die_id(int cpu) return ret; } +static int get_physical_punit_id(int cpu) +{ + if (cpu < 0) + return -1; + + if (cpu_map && cpu_map[cpu].initialized) + return cpu_map[cpu].punit_id; + + return -1; +} + void set_isst_id(struct isst_id *id, int cpu) { id->cpu = cpu; @@ -389,6 +401,10 @@ void set_isst_id(struct isst_id *id, int cpu) id->die = get_physical_die_id(cpu); if (id->die >= MAX_DIE_PER_PACKAGE) id->die = -1; + + id->punit = get_physical_punit_id(cpu); + if (id->punit >= MAX_PUNIT_PER_DIE) + id->punit = -1; } int is_cpu_in_power_domain(int cpu, struct isst_id *id) @@ -397,7 +413,7 @@ int is_cpu_in_power_domain(int cpu, struct isst_id *id) set_isst_id(&tid, cpu); - if (id->pkg == tid.pkg && id->die == tid.die) + if (id->pkg == tid.pkg && id->die == tid.die && id->punit == tid.punit) return 1; return 0; @@ -660,7 +676,7 @@ static void create_cpu_map(void) for (i = 0; i < topo_max_cpus; ++i) { char buffer[256]; - int pkg_id, die_id, core_id; + int pkg_id, die_id, core_id, punit_id; /* check if CPU is online */ snprintf(buffer, sizeof(buffer), @@ -682,31 +698,47 @@ static void create_cpu_map(void) cpu_map[i].pkg_id = pkg_id; cpu_map[i].die_id = die_id; cpu_map[i].core_id = core_id; - cpu_map[i].initialized = 1; - cpu_cnt[pkg_id][die_id]++; - if (fd < 0) - continue; - map.cmd_count = 1; - map.cpu_map[0].logical_cpu = i; - debug_printf(" map logical_cpu:%d\n", - map.cpu_map[0].logical_cpu); - if (ioctl(fd, ISST_IF_GET_PHY_ID, &map) == -1) { - perror("ISST_IF_GET_PHY_ID"); - fprintf(outf, "Error: map logical_cpu:%d\n", - map.cpu_map[0].logical_cpu); - continue; + punit_id = 0; + + if (fd >= 0) { + map.cmd_count = 1; + map.cpu_map[0].logical_cpu = i; + debug_printf(" map logical_cpu:%d\n", + map.cpu_map[0].logical_cpu); + if (ioctl(fd, ISST_IF_GET_PHY_ID, &map) == -1) { + perror("ISST_IF_GET_PHY_ID"); + fprintf(outf, "Error: map logical_cpu:%d\n", + map.cpu_map[0].logical_cpu); + } else { + /* + * Format + * Bit 0 – thread ID + * Bit 8:1 – core ID + * Bit 13:9 – punit ID + */ + cpu_map[i].punit_cpu = map.cpu_map[0].physical_cpu & 0x1ff; + cpu_map[i].punit_cpu_core = (cpu_map[i].punit_cpu >> + 1); // shift to get core id + punit_id = (map.cpu_map[0].physical_cpu >> 9) & 0x1f; + + if (punit_id >= MAX_PUNIT_PER_DIE) + punit_id = 0; + + cpu_map[i].punit_id = punit_id; + } } - cpu_map[i].punit_cpu = map.cpu_map[0].physical_cpu; - cpu_map[i].punit_cpu_core = (map.cpu_map[0].physical_cpu >> - 1); // shift to get core id + + cpu_map[i].initialized = 1; + + cpu_cnt[pkg_id][die_id]++; debug_printf( - "map logical_cpu:%d core: %d die:%d pkg:%d punit_cpu:%d punit_core:%d\n", + "map logical_cpu:%d core: %d die:%d pkg:%d punit:%d punit_cpu:%d punit_core:%d\n", i, cpu_map[i].core_id, cpu_map[i].die_id, - cpu_map[i].pkg_id, cpu_map[i].punit_cpu, - cpu_map[i].punit_cpu_core); + cpu_map[i].pkg_id, cpu_map[i].punit_id, + cpu_map[i].punit_cpu, cpu_map[i].punit_cpu_core); } if (fd >= 0) close(fd); diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 727afc5941091..148389c5ab84c 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -79,14 +79,16 @@ #define DISP_FREQ_MULTIPLIER 100 -#define MAX_PACKAGE_COUNT 8 -#define MAX_DIE_PER_PACKAGE 2 +#define MAX_PACKAGE_COUNT 8 +#define MAX_DIE_PER_PACKAGE 2 +#define MAX_PUNIT_PER_DIE 8 /* Unified structure to specific a CPU or a Power Domain */ struct isst_id { int cpu; int pkg; int die; + int punit; }; struct isst_clos_config { From 57ef2436a1759ae9d9b4d1536aed4701bfb4f737 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 17 Aug 2022 15:33:23 +0800 Subject: [PATCH 04/61] tools/power/x86/intel-speed-select: Introduce isst_is_punit_valid() Introduce isst_is_punit_valid() for checking a valid domain. For current platforms, it requires a punit 0 in a valid Package/Die. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-core.c | 11 +++++++++++ tools/power/x86/intel-speed-select/isst.h | 1 + 2 files changed, 12 insertions(+) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 8aa2ee4bb2320..f712da2b51467 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -25,6 +25,17 @@ char *isst_get_trl_level_name(int level) } } +int isst_is_punit_valid(struct isst_id *id) +{ + if (id->cpu < 0) + return 0; + + if (id->pkg < 0 || id->die < 0 || id->punit) + return 0; + + return 1; +} + int isst_write_pm_config(struct isst_id *id, int cp_state) { unsigned int req, resp; diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 148389c5ab84c..ef884d83d388c 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -205,6 +205,7 @@ extern int isst_send_msr_command(unsigned int cpu, unsigned int command, extern int isst_get_trl_max_levels(void); extern char *isst_get_trl_level_name(int level); +extern int isst_is_punit_valid(struct isst_id *id); extern int isst_get_ctdp_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev); extern int isst_get_ctdp_control(struct isst_id *id, int config_index, From b4edf3854a01fefe2eb2b4bb329ab97aaec5d5f5 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 01:06:45 +0800 Subject: [PATCH 05/61] tools/power/x86/intel-speed-select: Introduce support for multi-punit New platforms may have more than 1 punit in a Package/Die, thus it can have multiple power domains in a Package/Die. Package id and die id is not sufficient to refer to a specific Power domain. Introduce support for multi-punit per package/die. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-config.c | 72 ++++++++++--------- .../x86/intel-speed-select/isst-daemon.c | 21 +++--- 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index f17492fcf97c8..4c9623220e3bd 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -502,46 +502,54 @@ void for_each_online_package_in_set(void (*callback)(struct isst_id *, void *, v void *arg1, void *arg2, void *arg3, void *arg4) { - int max_packages[MAX_PACKAGE_COUNT * MAX_PACKAGE_COUNT]; - int pkg_index = 0, i; struct isst_id id; + int cpus[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE][MAX_PUNIT_PER_DIE]; + int valid_mask[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE] = {0}; + int i, j, k; + + memset(cpus, -1, sizeof(cpus)); - memset(max_packages, 0xff, sizeof(max_packages)); for (i = 0; i < topo_max_cpus; ++i) { - int j, online, pkg_id, die_id = 0, skip = 0; + int online; if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) continue; - if (i) - online = parse_int_file( - 1, "/sys/devices/system/cpu/cpu%d/online", i); - else - online = - 1; /* online entry for CPU 0 needs some special configs */ - die_id = get_physical_die_id(i); - if (die_id < 0) - die_id = 0; + online = parse_int_file( + i != 0, "/sys/devices/system/cpu/cpu%d/online", i); + if (online < 0) + online = 1; /* online entry for CPU 0 needs some special configs */ - pkg_id = parse_int_file(0, - "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", i); - if (pkg_id < 0) + if (!online) + continue; + + set_isst_id(&id, i); + + if (id.pkg < 0 || id.die < 0 || id.punit < 0) continue; - /* Create an unique id for package, die combination to store */ - pkg_id = (MAX_PACKAGE_COUNT * pkg_id + die_id); + valid_mask[id.pkg][id.die] = 1; - for (j = 0; j < pkg_index; ++j) { - if (max_packages[j] == pkg_id) { - skip = 1; - break; - } - } + if (cpus[id.pkg][id.die][id.punit] == -1) + cpus[id.pkg][id.die][id.punit] = i; + } - set_isst_id(&id, i); - if (!skip && online && callback) { - callback(&id, arg1, arg2, arg3, arg4); - max_packages[pkg_index++] = pkg_id; + for (i = 0; i < MAX_PACKAGE_COUNT; i++) { + for (j = 0; j < MAX_DIE_PER_PACKAGE; j++) { + /* + * Fix me: + * How to check a non-cpu die for a package/die with all cpu offlined? + */ + if (!valid_mask[i][j]) + continue; + for (k = 0; k < MAX_PUNIT_PER_DIE; k++) { + id.cpu = cpus[i][j][k]; + id.pkg = i; + id.die = j; + id.punit = k; + if (isst_is_punit_valid(&id)) + callback(&id, arg1, arg2, arg3, arg4); + } } } } @@ -626,7 +634,7 @@ void free_cpu_set(cpu_set_t *cpu_set) CPU_FREE(cpu_set); } -static int cpu_cnt[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE]; +static int cpu_cnt[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE][MAX_PUNIT_PER_DIE]; int get_max_punit_core_id(struct isst_id *id) { @@ -648,10 +656,10 @@ int get_max_punit_core_id(struct isst_id *id) int get_cpu_count(struct isst_id *id) { - if (id->pkg < 0 || id->die < 0) + if (id->pkg < 0 || id->die < 0 || id->punit < 0) return 0; - return cpu_cnt[id->pkg][id->die]; + return cpu_cnt[id->pkg][id->die][id->punit]; } static void create_cpu_map(void) @@ -732,7 +740,7 @@ static void create_cpu_map(void) cpu_map[i].initialized = 1; - cpu_cnt[pkg_id][die_id]++; + cpu_cnt[pkg_id][die_id][punit_id]++; debug_printf( "map logical_cpu:%d core: %d die:%d pkg:%d punit:%d punit_cpu:%d punit_core:%d\n", diff --git a/tools/power/x86/intel-speed-select/isst-daemon.c b/tools/power/x86/intel-speed-select/isst-daemon.c index c2290ef0e3af1..cc0eb98864114 100644 --- a/tools/power/x86/intel-speed-select/isst-daemon.c +++ b/tools/power/x86/intel-speed-select/isst-daemon.c @@ -20,16 +20,17 @@ #include "isst.h" -static int per_package_levels_info[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE]; -static time_t per_package_levels_tm[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE]; +static int per_package_levels_info[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE][MAX_PUNIT_PER_DIE]; +static time_t per_package_levels_tm[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE][MAX_PUNIT_PER_DIE]; static void init_levels(void) { - int i, j; + int i, j, k; for (i = 0; i < MAX_PACKAGE_COUNT; ++i) for (j = 0; j < MAX_DIE_PER_PACKAGE; ++j) - per_package_levels_info[i][j] = -1; + for (k = 0; k < MAX_PUNIT_PER_DIE; ++k) + per_package_levels_info[i][j][k] = -1; } void process_level_change(struct isst_id *id) @@ -39,16 +40,16 @@ void process_level_change(struct isst_id *id) time_t tm; int ret; - if (id->pkg < 0 || id->die < 0) { + if (id->pkg < 0 || id->die < 0 || id->punit < 0) { debug_printf("Invalid package/die info for cpu:%d\n", id->cpu); return; } tm = time(NULL); - if (tm - per_package_levels_tm[id->pkg][id->die] < 2) + if (tm - per_package_levels_tm[id->pkg][id->die][id->punit] < 2) return; - per_package_levels_tm[id->pkg][id->die] = tm; + per_package_levels_tm[id->pkg][id->die][id->punit] = tm; ret = isst_get_ctdp_levels(id, &pkg_dev); if (ret) { @@ -64,14 +65,14 @@ void process_level_change(struct isst_id *id) return; } - if (per_package_levels_info[id->pkg][id->die] == pkg_dev.current_level) + if (per_package_levels_info[id->pkg][id->die][id->punit] == pkg_dev.current_level) return; debug_printf("**Config level change for cpu:%d pkg:%d die:%d from %d to %d\n", - id->cpu, id->pkg, id->die, per_package_levels_info[id->pkg][id->die], + id->cpu, id->pkg, id->die, per_package_levels_info[id->pkg][id->die][id->punit], pkg_dev.current_level); - per_package_levels_info[id->pkg][id->die] = pkg_dev.current_level; + per_package_levels_info[id->pkg][id->die][id->punit] = pkg_dev.current_level; ctdp_level.core_cpumask_size = alloc_cpu_set(&ctdp_level.core_cpumask); From c77a8d4af68d98d0d83aa68f90041b395213c589 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 17 Aug 2022 15:50:43 +0800 Subject: [PATCH 06/61] tools/power/x86/intel-speed-select: Rename for_each_online_package_in_set for_each_online_package_in_set is actually used to invoke callback for each power domain. This is not a problem when there is a single power domain within a package/die, but it does not reflect the truth in multi-punit case. Rename for_each_online_package_in_set to for_each_online_power_domain_in_set. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-config.c | 26 +++++++++---------- .../x86/intel-speed-select/isst-daemon.c | 2 +- tools/power/x86/intel-speed-select/isst.h | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 4c9623220e3bd..42eaabc153d97 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -497,7 +497,7 @@ static void force_all_cpus_online(void) unlink("/var/run/isst_cpu_topology.dat"); } -void for_each_online_package_in_set(void (*callback)(struct isst_id *, void *, void *, +void for_each_online_power_domain_in_set(void (*callback)(struct isst_id *, void *, void *, void *, void *), void *arg1, void *arg2, void *arg3, void *arg4) @@ -1150,7 +1150,7 @@ static void exec_on_get_ctdp_cpu(struct isst_id *id, void *arg1, void *arg2, voi exec_on_get_ctdp_cpu, isst_get_ctdp_##suffix, \ &ctdp, desc, &ctdp.object); \ else \ - for_each_online_package_in_set(exec_on_get_ctdp_cpu, \ + for_each_online_power_domain_in_set(exec_on_get_ctdp_cpu, \ isst_get_ctdp_##suffix, \ &ctdp, desc, \ &ctdp.object); \ @@ -1354,7 +1354,7 @@ static void dump_isst_config(int arg) if (max_target_cpus) for_each_online_target_cpu_in_set(fn, NULL, NULL, NULL, NULL); else - for_each_online_package_in_set(fn, NULL, NULL, NULL, NULL); + for_each_online_power_domain_in_set(fn, NULL, NULL, NULL, NULL); isst_ctdp_display_information_end(outf); } @@ -1465,7 +1465,7 @@ static void set_tdp_level(int arg) for_each_online_target_cpu_in_set(set_tdp_level_for_cpu, NULL, NULL, NULL, NULL); else - for_each_online_package_in_set(set_tdp_level_for_cpu, NULL, + for_each_online_power_domain_in_set(set_tdp_level_for_cpu, NULL, NULL, NULL, NULL); isst_ctdp_display_information_end(outf); } @@ -1534,7 +1534,7 @@ static void dump_pbf_config(int arg) if (max_target_cpus) for_each_online_target_cpu_in_set(fn, NULL, NULL, NULL, NULL); else - for_each_online_package_in_set(fn, NULL, NULL, NULL, NULL); + for_each_online_power_domain_in_set(fn, NULL, NULL, NULL, NULL); isst_ctdp_display_information_end(outf); } @@ -1940,7 +1940,7 @@ static void set_pbf_enable(int arg) for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL, NULL, &enable); else - for_each_online_package_in_set(set_pbf_for_cpu, NULL, NULL, + for_each_online_power_domain_in_set(set_pbf_for_cpu, NULL, NULL, NULL, &enable); isst_ctdp_display_information_end(outf); } @@ -1986,7 +1986,7 @@ static void dump_fact_config(int arg) for_each_online_target_cpu_in_set(dump_fact_config_for_cpu, NULL, NULL, NULL, NULL); else - for_each_online_package_in_set(dump_fact_config_for_cpu, NULL, + for_each_online_power_domain_in_set(dump_fact_config_for_cpu, NULL, NULL, NULL, NULL); isst_ctdp_display_information_end(outf); } @@ -2095,7 +2095,7 @@ static void set_fact_enable(int arg) for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL, NULL, &enable); else - for_each_online_package_in_set(set_fact_for_cpu, NULL, NULL, + for_each_online_power_domain_in_set(set_fact_for_cpu, NULL, NULL, NULL, &enable); isst_ctdp_display_information_end(outf); @@ -2234,7 +2234,7 @@ static void set_clos_enable(int arg) for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL, NULL, NULL, &enable); else - for_each_online_package_in_set(enable_clos_qos_config, NULL, + for_each_online_power_domain_in_set(enable_clos_qos_config, NULL, NULL, NULL, &enable); isst_ctdp_display_information_end(outf); } @@ -2273,7 +2273,7 @@ static void dump_clos_config(int arg) for_each_online_target_cpu_in_set(dump_clos_config_for_cpu, NULL, NULL, NULL, NULL); else - for_each_online_package_in_set(dump_clos_config_for_cpu, NULL, + for_each_online_power_domain_in_set(dump_clos_config_for_cpu, NULL, NULL, NULL, NULL); isst_ctdp_display_information_end(outf); } @@ -2309,7 +2309,7 @@ static void dump_clos_info(int arg) for_each_online_target_cpu_in_set(get_clos_info_for_cpu, NULL, NULL, NULL, NULL); else - for_each_online_package_in_set(get_clos_info_for_cpu, NULL, + for_each_online_power_domain_in_set(get_clos_info_for_cpu, NULL, NULL, NULL, NULL); isst_ctdp_display_information_end(outf); @@ -2381,7 +2381,7 @@ static void set_clos_config(int arg) for_each_online_target_cpu_in_set(set_clos_config_for_cpu, NULL, NULL, NULL, NULL); else - for_each_online_package_in_set(set_clos_config_for_cpu, NULL, + for_each_online_power_domain_in_set(set_clos_config_for_cpu, NULL, NULL, NULL, NULL); isst_ctdp_display_information_end(outf); } @@ -2548,7 +2548,7 @@ static void process_trl(int arg) for_each_online_target_cpu_in_set(get_set_trl, NULL, NULL, NULL, &arg); else - for_each_online_package_in_set(get_set_trl, NULL, + for_each_online_power_domain_in_set(get_set_trl, NULL, NULL, NULL, &arg); isst_ctdp_display_information_end(outf); } diff --git a/tools/power/x86/intel-speed-select/isst-daemon.c b/tools/power/x86/intel-speed-select/isst-daemon.c index cc0eb98864114..6fa2942b5e12f 100644 --- a/tools/power/x86/intel-speed-select/isst-daemon.c +++ b/tools/power/x86/intel-speed-select/isst-daemon.c @@ -109,7 +109,7 @@ static void _poll_for_config_change(struct isst_id *id, void *arg1, void *arg2, static void poll_for_config_change(void) { - for_each_online_package_in_set(_poll_for_config_change, NULL, NULL, + for_each_online_power_domain_in_set(_poll_for_config_change, NULL, NULL, NULL, NULL); } diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index ef884d83d388c..c43a73751007b 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -271,7 +271,7 @@ extern int is_icx_platform(void); extern void isst_trl_display_information(struct isst_id *id, FILE *outf, unsigned long long trl); extern void set_cpu_online_offline(int cpu, int state); -extern void for_each_online_package_in_set(void (*callback)(struct isst_id *, void *, void *, +extern void for_each_online_power_domain_in_set(void (*callback)(struct isst_id *, void *, void *, void *, void *), void *arg1, void *arg2, void *arg3, void *arg4); From ad7e17fcb1261a4445f973369b610c972098e87f Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 17 Aug 2022 16:11:13 +0800 Subject: [PATCH 07/61] tools/power/x86/intel-speed-select: Improve isst_print_extended_platform_info The main thing done in isst_print_extended_platform_info is to get the isst feature status by checking one of the power domains of the platform. This can be done using the for_each_online_power_domain_in_set() function, which makes the code clean and easier to read. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-config.c | 91 +++++++++++-------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 42eaabc153d97..ef604c46cda7b 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1002,74 +1002,87 @@ static int isst_fill_platform_info(void) return 0; } -static void isst_print_extended_platform_info(void) +void get_isst_status(struct isst_id *id, void *arg1, void *arg2, void *arg3, void *arg4) { - int cp_state, cp_cap, fact_support = 0, pbf_support = 0; - struct isst_pkg_ctdp_level_info ctdp_level; struct isst_pkg_ctdp pkg_dev; - int ret, i, j; - FILE *filep; - struct isst_id id; - - for (i = 0; i < 256; ++i) { - char path[256]; + struct isst_id *tid = (struct isst_id *)arg2; + int *mask = (int *)arg3; + int *max_level = (int *)arg4; + int j, ret; - snprintf(path, sizeof(path), - "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", i); - filep = fopen(path, "r"); - if (filep) - break; - } - - if (!filep) + /* Only check the first cpu power domain */ + if (id->cpu < 0 || tid->cpu >= 0) return; - fclose(filep); - - set_isst_id(&id, i); - ret = isst_get_ctdp_levels(&id, &pkg_dev); + ret = isst_get_ctdp_levels(id, &pkg_dev); if (ret) return; - if (pkg_dev.enabled) { - fprintf(outf, "Intel(R) SST-PP (feature perf-profile) is supported\n"); - } else { - fprintf(outf, "Intel(R) SST-PP (feature perf-profile) is not supported\n"); - fprintf(outf, "Only performance level 0 (base level) is present\n"); - } + if (pkg_dev.enabled) + *mask |= BIT(0); if (pkg_dev.locked) - fprintf(outf, "TDP level change control is locked\n"); - else - fprintf(outf, "TDP level change control is unlocked, max level: %d \n", pkg_dev.levels); + *mask |= BIT(1); + + if (*max_level < pkg_dev.levels) + *max_level = pkg_dev.levels; for (j = 0; j <= pkg_dev.levels; ++j) { - ret = isst_get_ctdp_control(&id, j, &ctdp_level); + struct isst_pkg_ctdp_level_info ctdp_level; + + ret = isst_get_ctdp_control(id, j, &ctdp_level); if (ret) continue; - if (!fact_support && ctdp_level.fact_support) - fact_support = 1; + if (ctdp_level.fact_support) + *mask |= BIT(2); + + if (ctdp_level.pbf_support) + *mask |= BIT(3); + } + + tid->cpu = id->cpu; + tid->pkg = id->pkg; + tid->die = id->die; + tid->punit = id->punit; +} + +static void isst_print_extended_platform_info(void) +{ + int cp_state, cp_cap; + struct isst_id id; + int mask = 0, max_level = 0; + + id.cpu = -1; + for_each_online_power_domain_in_set(get_isst_status, NULL, &id, &mask, &max_level); - if (!pbf_support && ctdp_level.pbf_support) - pbf_support = 1; + if (mask & BIT(0)) { + fprintf(outf, "Intel(R) SST-PP (feature perf-profile) is supported\n"); + } else { + fprintf(outf, "Intel(R) SST-PP (feature perf-profile) is not supported\n"); + fprintf(outf, "Only performance level 0 (base level) is present\n"); } - if (fact_support) + if (mask & BIT(1)) + fprintf(outf, "TDP level change control is locked\n"); + else + fprintf(outf, "TDP level change control is unlocked, max level: %d\n", max_level); + + if (mask & BIT(2)) fprintf(outf, "Intel(R) SST-TF (feature turbo-freq) is supported\n"); else fprintf(outf, "Intel(R) SST-TF (feature turbo-freq) is not supported\n"); - if (pbf_support) + if (mask & BIT(3)) fprintf(outf, "Intel(R) SST-BF (feature base-freq) is supported\n"); else fprintf(outf, "Intel(R) SST-BF (feature base-freq) is not supported\n"); - ret = isst_read_pm_config(&id, &cp_state, &cp_cap); - if (ret) { + if (isst_read_pm_config(&id, &cp_state, &cp_cap)) { fprintf(outf, "Intel(R) SST-CP (feature core-power) status is unknown\n"); return; } + if (cp_cap) fprintf(outf, "Intel(R) SST-CP (feature core-power) is supported\n"); else From 2042c0abf050ce9de508c9efda891de496240708 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 20 Aug 2022 18:38:11 +0800 Subject: [PATCH 08/61] tools/power/x86/intel-speed-select: Move mbox functions to isst-core.c isst-config.c should only contain generic code. Move mbox functions which are platform specific code to isst-core.c. As there are some platform specific parameters set via generic application options, introduce isst_update_platform_param to pass these parameters to platform specific code. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-config.c | 185 +--------------- .../power/x86/intel-speed-select/isst-core.c | 198 ++++++++++++++++++ tools/power/x86/intel-speed-select/isst.h | 7 +- 3 files changed, 209 insertions(+), 181 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index ef604c46cda7b..f2da55ea7364d 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -45,9 +45,6 @@ static int force_online_offline; static int auto_mode; static int fact_enable_fail; -static int mbox_delay; -static int mbox_retries = 3; - /* clos related */ static int current_clos = -1; static int clos_epp = -1; @@ -799,184 +796,7 @@ int find_phy_core_num(int logical_cpu) return -EINVAL; } -static int isst_send_mmio_command(unsigned int cpu, unsigned int reg, int write, - unsigned int *value) -{ - struct isst_if_io_regs io_regs; - const char *pathname = "/dev/isst_interface"; - int cmd; - int fd; - - debug_printf("mmio_cmd cpu:%d reg:%d write:%d\n", cpu, reg, write); - - fd = open(pathname, O_RDWR); - if (fd < 0) - err(-1, "%s open failed", pathname); - - io_regs.req_count = 1; - io_regs.io_reg[0].logical_cpu = cpu; - io_regs.io_reg[0].reg = reg; - cmd = ISST_IF_IO_CMD; - if (write) { - io_regs.io_reg[0].read_write = 1; - io_regs.io_reg[0].value = *value; - } else { - io_regs.io_reg[0].read_write = 0; - } - - if (ioctl(fd, cmd, &io_regs) == -1) { - if (errno == ENOTTY) { - perror("ISST_IF_IO_COMMAND\n"); - fprintf(stderr, "Check presence of kernel modules: isst_if_mmio\n"); - exit(0); - } - fprintf(outf, "Error: mmio_cmd cpu:%d reg:%x read_write:%x\n", - cpu, reg, write); - } else { - if (!write) - *value = io_regs.io_reg[0].value; - - debug_printf( - "mmio_cmd response: cpu:%d reg:%x rd_write:%x resp:%x\n", - cpu, reg, write, *value); - } - - close(fd); - - return 0; -} - -int isst_send_mbox_command(unsigned int cpu, unsigned char command, - unsigned char sub_command, unsigned int parameter, - unsigned int req_data, unsigned int *resp) -{ - const char *pathname = "/dev/isst_interface"; - int fd, retry; - struct isst_if_mbox_cmds mbox_cmds = { 0 }; - - debug_printf( - "mbox_send: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n", - cpu, command, sub_command, parameter, req_data); - - if (!is_skx_based_platform() && command == CONFIG_CLOS && - sub_command != CLOS_PM_QOS_CONFIG) { - unsigned int value; - int write = 0; - int clos_id, core_id, ret = 0; - - debug_printf("CPU %d\n", cpu); - - if (parameter & BIT(MBOX_CMD_WRITE_BIT)) { - value = req_data; - write = 1; - } - - switch (sub_command) { - case CLOS_PQR_ASSOC: - core_id = parameter & 0xff; - ret = isst_send_mmio_command( - cpu, PQR_ASSOC_OFFSET + core_id * 4, write, - &value); - if (!ret && !write) - *resp = value; - break; - case CLOS_PM_CLOS: - clos_id = parameter & 0x03; - ret = isst_send_mmio_command( - cpu, PM_CLOS_OFFSET + clos_id * 4, write, - &value); - if (!ret && !write) - *resp = value; - break; - case CLOS_STATUS: - break; - default: - break; - } - return ret; - } - mbox_cmds.cmd_count = 1; - mbox_cmds.mbox_cmd[0].logical_cpu = cpu; - mbox_cmds.mbox_cmd[0].command = command; - mbox_cmds.mbox_cmd[0].sub_command = sub_command; - mbox_cmds.mbox_cmd[0].parameter = parameter; - mbox_cmds.mbox_cmd[0].req_data = req_data; - - if (mbox_delay) - usleep(mbox_delay * 1000); - - fd = open(pathname, O_RDWR); - if (fd < 0) - err(-1, "%s open failed", pathname); - - retry = mbox_retries; - - do { - if (ioctl(fd, ISST_IF_MBOX_COMMAND, &mbox_cmds) == -1) { - if (errno == ENOTTY) { - perror("ISST_IF_MBOX_COMMAND\n"); - fprintf(stderr, "Check presence of kernel modules: isst_if_mbox_pci or isst_if_mbox_msr\n"); - exit(0); - } - debug_printf( - "Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x errorno:%d\n", - cpu, command, sub_command, parameter, req_data, errno); - --retry; - } else { - *resp = mbox_cmds.mbox_cmd[0].resp_data; - debug_printf( - "mbox_cmd response: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x resp:%x\n", - cpu, command, sub_command, parameter, req_data, *resp); - break; - } - } while (retry); - - close(fd); - - if (!retry) { - debug_printf("Failed mbox command even after retries\n"); - return -1; - - } - return 0; -} - -int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write, - unsigned long long *req_resp) -{ - struct isst_if_msr_cmds msr_cmds; - const char *pathname = "/dev/isst_interface"; - int fd; - - fd = open(pathname, O_RDWR); - if (fd < 0) - err(-1, "%s open failed", pathname); - - msr_cmds.cmd_count = 1; - msr_cmds.msr_cmd[0].logical_cpu = cpu; - msr_cmds.msr_cmd[0].msr = msr; - msr_cmds.msr_cmd[0].read_write = write; - if (write) - msr_cmds.msr_cmd[0].data = *req_resp; - - if (ioctl(fd, ISST_IF_MSR_COMMAND, &msr_cmds) == -1) { - perror("ISST_IF_MSR_COMMAND"); - fprintf(outf, "Error: msr_cmd cpu:%d msr:%x read_write:%d\n", - cpu, msr, write); - } else { - if (!write) - *req_resp = msr_cmds.msr_cmd[0].data; - - debug_printf( - "msr_cmd response: cpu:%d msr:%x rd_write:%x resp:%llx %llx\n", - cpu, msr, write, *req_resp, msr_cmds.msr_cmd[0].data); - } - - close(fd); - - return 0; -} static int isst_fill_platform_info(void) { @@ -2971,6 +2791,7 @@ static void cmdline(int argc, char **argv) int oob_mode = 0; int poll_interval = -1; int no_daemon = 0; + int mbox_delay = 0, mbox_retries = 3; static struct option long_options[] = { { "all-cpus-online", no_argument, 0, 'a' }, @@ -3080,6 +2901,10 @@ static void cmdline(int argc, char **argv) usage(); exit(0); } + + isst_update_platform_param(ISST_PARAM_MBOX_DELAY, mbox_delay); + isst_update_platform_param(ISST_PARAM_MBOX_RETRIES, mbox_retries); + set_max_cpu_num(); if (force_cpus_online) force_all_cpus_online(); diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index f712da2b51467..385bc6c055453 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -6,6 +6,23 @@ #include "isst.h" +static int mbox_delay; +static int mbox_retries = 3; + +void isst_update_platform_param(enum isst_platform_param param, int value) +{ + switch (param) { + case ISST_PARAM_MBOX_DELAY: + mbox_delay = value; + break; + case ISST_PARAM_MBOX_RETRIES: + mbox_retries = value; + break; + default: + break; + } +} + int isst_get_trl_max_levels(void) { return 3; @@ -36,6 +53,187 @@ int isst_is_punit_valid(struct isst_id *id) return 1; } +static int isst_send_mmio_command(unsigned int cpu, unsigned int reg, int write, + unsigned int *value) +{ + struct isst_if_io_regs io_regs; + const char *pathname = "/dev/isst_interface"; + int cmd; + FILE *outf = get_output_file(); + int fd; + + debug_printf("mmio_cmd cpu:%d reg:%d write:%d\n", cpu, reg, write); + + fd = open(pathname, O_RDWR); + if (fd < 0) + err(-1, "%s open failed", pathname); + + io_regs.req_count = 1; + io_regs.io_reg[0].logical_cpu = cpu; + io_regs.io_reg[0].reg = reg; + cmd = ISST_IF_IO_CMD; + if (write) { + io_regs.io_reg[0].read_write = 1; + io_regs.io_reg[0].value = *value; + } else { + io_regs.io_reg[0].read_write = 0; + } + + if (ioctl(fd, cmd, &io_regs) == -1) { + if (errno == ENOTTY) { + perror("ISST_IF_IO_COMMAND\n"); + fprintf(stderr, "Check presence of kernel modules: isst_if_mmio\n"); + exit(0); + } + fprintf(outf, "Error: mmio_cmd cpu:%d reg:%x read_write:%x\n", + cpu, reg, write); + } else { + if (!write) + *value = io_regs.io_reg[0].value; + + debug_printf( + "mmio_cmd response: cpu:%d reg:%x rd_write:%x resp:%x\n", + cpu, reg, write, *value); + } + + close(fd); + + return 0; +} + +int isst_send_mbox_command(unsigned int cpu, unsigned char command, + unsigned char sub_command, unsigned int parameter, + unsigned int req_data, unsigned int *resp) +{ + const char *pathname = "/dev/isst_interface"; + int fd, retry; + struct isst_if_mbox_cmds mbox_cmds = { 0 }; + + debug_printf( + "mbox_send: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n", + cpu, command, sub_command, parameter, req_data); + + if (!is_skx_based_platform() && command == CONFIG_CLOS && + sub_command != CLOS_PM_QOS_CONFIG) { + unsigned int value; + int write = 0; + int clos_id, core_id, ret = 0; + + debug_printf("CPU %d\n", cpu); + + if (parameter & BIT(MBOX_CMD_WRITE_BIT)) { + value = req_data; + write = 1; + } + + switch (sub_command) { + case CLOS_PQR_ASSOC: + core_id = parameter & 0xff; + ret = isst_send_mmio_command( + cpu, PQR_ASSOC_OFFSET + core_id * 4, write, + &value); + if (!ret && !write) + *resp = value; + break; + case CLOS_PM_CLOS: + clos_id = parameter & 0x03; + ret = isst_send_mmio_command( + cpu, PM_CLOS_OFFSET + clos_id * 4, write, + &value); + if (!ret && !write) + *resp = value; + break; + case CLOS_STATUS: + break; + default: + break; + } + return ret; + } + + mbox_cmds.cmd_count = 1; + mbox_cmds.mbox_cmd[0].logical_cpu = cpu; + mbox_cmds.mbox_cmd[0].command = command; + mbox_cmds.mbox_cmd[0].sub_command = sub_command; + mbox_cmds.mbox_cmd[0].parameter = parameter; + mbox_cmds.mbox_cmd[0].req_data = req_data; + + if (mbox_delay) + usleep(mbox_delay * 1000); + + fd = open(pathname, O_RDWR); + if (fd < 0) + err(-1, "%s open failed", pathname); + + retry = mbox_retries; + + do { + if (ioctl(fd, ISST_IF_MBOX_COMMAND, &mbox_cmds) == -1) { + if (errno == ENOTTY) { + perror("ISST_IF_MBOX_COMMAND\n"); + fprintf(stderr, "Check presence of kernel modules: isst_if_mbox_pci or isst_if_mbox_msr\n"); + exit(0); + } + debug_printf( + "Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x errorno:%d\n", + cpu, command, sub_command, parameter, req_data, errno); + --retry; + } else { + *resp = mbox_cmds.mbox_cmd[0].resp_data; + debug_printf( + "mbox_cmd response: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x resp:%x\n", + cpu, command, sub_command, parameter, req_data, *resp); + break; + } + } while (retry); + + close(fd); + + if (!retry) { + debug_printf("Failed mbox command even after retries\n"); + return -1; + + } + return 0; +} + +int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write, + unsigned long long *req_resp) +{ + struct isst_if_msr_cmds msr_cmds; + const char *pathname = "/dev/isst_interface"; + FILE *outf = get_output_file(); + int fd; + + fd = open(pathname, O_RDWR); + if (fd < 0) + err(-1, "%s open failed", pathname); + + msr_cmds.cmd_count = 1; + msr_cmds.msr_cmd[0].logical_cpu = cpu; + msr_cmds.msr_cmd[0].msr = msr; + msr_cmds.msr_cmd[0].read_write = write; + if (write) + msr_cmds.msr_cmd[0].data = *req_resp; + + if (ioctl(fd, ISST_IF_MSR_COMMAND, &msr_cmds) == -1) { + perror("ISST_IF_MSR_COMMAND"); + fprintf(outf, "Error: msr_cmd cpu:%d msr:%x read_write:%d\n", + cpu, msr, write); + } else { + if (!write) + *req_resp = msr_cmds.msr_cmd[0].data; + + debug_printf( + "msr_cmd response: cpu:%d msr:%x rd_write:%x resp:%llx %llx\n", + cpu, msr, write, *req_resp, msr_cmds.msr_cmd[0].data); + } + + close(fd); + + return 0; +} + int isst_write_pm_config(struct isst_id *id, int cp_state) { unsigned int req, resp; diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index c43a73751007b..6f60fcf409eeb 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -176,6 +176,11 @@ struct isst_pkg_ctdp { struct isst_pkg_ctdp_level_info ctdp_level[ISST_MAX_TDP_LEVELS]; }; +enum isst_platform_param { + ISST_PARAM_MBOX_DELAY, + ISST_PARAM_MBOX_RETRIES, +}; + extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); extern int get_topo_max_cpus(void); extern int get_cpu_count(struct isst_id *id); @@ -194,7 +199,6 @@ extern void set_cpu_mask_from_punit_coremask(struct isst_id *id, size_t core_cpumask_size, cpu_set_t *core_cpumask, int *cpu_cnt); - extern int isst_send_mbox_command(unsigned int cpu, unsigned char command, unsigned char sub_command, unsigned int write, @@ -203,6 +207,7 @@ extern int isst_send_mbox_command(unsigned int cpu, unsigned char command, extern int isst_send_msr_command(unsigned int cpu, unsigned int command, int write, unsigned long long *req_resp); +extern void isst_update_platform_param(enum isst_platform_param, int vale); extern int isst_get_trl_max_levels(void); extern char *isst_get_trl_level_name(int level); extern int isst_is_punit_valid(struct isst_id *id); From 13b868f8928c947cbf51d167f1727c446beb9933 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 20 Aug 2022 18:44:59 +0800 Subject: [PATCH 09/61] tools/power/x86/intel-speed-select: Introduce isst_get_disp_freq_multiplier Remove hardcoded DISP_FREQ_MULTIPLIER in the code and use isst_get_disp_freq_multiplier() instead. No functional changes are expected. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-config.c | 6 ++-- .../power/x86/intel-speed-select/isst-core.c | 5 ++++ .../x86/intel-speed-select/isst-display.c | 28 +++++++++---------- tools/power/x86/intel-speed-select/isst.h | 1 + 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index f2da55ea7364d..806533fd4626b 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -2556,7 +2556,7 @@ static void parse_cmd_args(int argc, int start, char **argv) break; case 'd': clos_desired = atoi(optarg); - clos_desired /= DISP_FREQ_MULTIPLIER; + clos_desired /= isst_get_disp_freq_multiplier(); break; case 'e': clos_epp = atoi(optarg); @@ -2567,11 +2567,11 @@ static void parse_cmd_args(int argc, int start, char **argv) break; case 'n': clos_min = atoi(optarg); - clos_min /= DISP_FREQ_MULTIPLIER; + clos_min /= isst_get_disp_freq_multiplier(); break; case 'm': clos_max = atoi(optarg); - clos_max /= DISP_FREQ_MULTIPLIER; + clos_max /= isst_get_disp_freq_multiplier(); break; case 'p': clos_priority_type = atoi(optarg); diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 385bc6c055453..8d63db2bf07c7 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -23,6 +23,11 @@ void isst_update_platform_param(enum isst_platform_param param, int value) } } +int isst_get_disp_freq_multiplier(void) +{ + return DISP_FREQ_MULTIPLIER; +} + int isst_get_trl_max_levels(void) { return 3; diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 5e57623196fcd..af97ba5dbcc2e 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -198,7 +198,7 @@ static void _isst_pbf_display_information(struct isst_id *id, FILE *outf, int le snprintf(header, sizeof(header), "high-priority-base-frequency(MHz)"); snprintf(value, sizeof(value), "%d", - pbf_info->p1_high * DISP_FREQ_MULTIPLIER); + pbf_info->p1_high * isst_get_disp_freq_multiplier()); format_and_print(outf, disp_level + 1, header, value); snprintf(header, sizeof(header), "high-priority-cpu-mask"); @@ -214,7 +214,7 @@ static void _isst_pbf_display_information(struct isst_id *id, FILE *outf, int le snprintf(header, sizeof(header), "low-priority-base-frequency(MHz)"); snprintf(value, sizeof(value), "%d", - pbf_info->p1_low * DISP_FREQ_MULTIPLIER); + pbf_info->p1_low * isst_get_disp_freq_multiplier()); format_and_print(outf, disp_level + 1, header, value); if (is_clx_n_platform()) @@ -282,7 +282,7 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l snprintf(header, sizeof(header), "high-priority-max-%s-frequency(MHz)", isst_get_trl_level_name(i)); snprintf(value, sizeof(value), "%d", - bucket_info[j].hp_ratios[i] * DISP_FREQ_MULTIPLIER); + bucket_info[j].hp_ratios[i] * isst_get_disp_freq_multiplier()); format_and_print(outf, base_level + 2, header, value); } } @@ -298,7 +298,7 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l snprintf(header, sizeof(header), "low-priority-max-%s-frequency(MHz)", isst_get_trl_level_name(j)); snprintf(value, sizeof(value), "%d", - fact_info->lp_ratios[j] * DISP_FREQ_MULTIPLIER); + fact_info->lp_ratios[j] * isst_get_disp_freq_multiplier()); format_and_print(outf, base_level + 2, header, value); } } @@ -393,41 +393,41 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level if (!ctdp_level->sse_p1) ctdp_level->sse_p1 = ctdp_level->tdp_ratio; snprintf(value, sizeof(value), "%d", - ctdp_level->sse_p1 * DISP_FREQ_MULTIPLIER); + ctdp_level->sse_p1 * isst_get_disp_freq_multiplier()); format_and_print(outf, level + 2, header, value); if (ctdp_level->avx2_p1) { snprintf(header, sizeof(header), "base-frequency-avx2(MHz)"); snprintf(value, sizeof(value), "%d", - ctdp_level->avx2_p1 * DISP_FREQ_MULTIPLIER); + ctdp_level->avx2_p1 * isst_get_disp_freq_multiplier()); format_and_print(outf, level + 2, header, value); } if (ctdp_level->avx512_p1) { snprintf(header, sizeof(header), "base-frequency-avx512(MHz)"); snprintf(value, sizeof(value), "%d", - ctdp_level->avx512_p1 * DISP_FREQ_MULTIPLIER); + ctdp_level->avx512_p1 * isst_get_disp_freq_multiplier()); format_and_print(outf, level + 2, header, value); } if (ctdp_level->uncore_pm) { snprintf(header, sizeof(header), "uncore-frequency-min(MHz)"); snprintf(value, sizeof(value), "%d", - ctdp_level->uncore_pm * DISP_FREQ_MULTIPLIER); + ctdp_level->uncore_pm * isst_get_disp_freq_multiplier()); format_and_print(outf, level + 2, header, value); } if (ctdp_level->uncore_p0) { snprintf(header, sizeof(header), "uncore-frequency-max(MHz)"); snprintf(value, sizeof(value), "%d", - ctdp_level->uncore_p0 * DISP_FREQ_MULTIPLIER); + ctdp_level->uncore_p0 * isst_get_disp_freq_multiplier()); format_and_print(outf, level + 2, header, value); } if (ctdp_level->uncore_p1) { snprintf(header, sizeof(header), "uncore-frequency-base(MHz)"); snprintf(value, sizeof(value), "%d", - ctdp_level->uncore_p1 * DISP_FREQ_MULTIPLIER); + ctdp_level->uncore_p1 * isst_get_disp_freq_multiplier()); format_and_print(outf, level + 2, header, value); } @@ -506,7 +506,7 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level format_and_print(outf, level + 4, header, value); snprintf(header, sizeof(header), "max-turbo-frequency(MHz)"); - snprintf(value, sizeof(value), "%d", ctdp_level->trl_ratios[k][j] * DISP_FREQ_MULTIPLIER); + snprintf(value, sizeof(value), "%d", ctdp_level->trl_ratios[k][j] * isst_get_disp_freq_multiplier()); format_and_print(outf, level + 4, header, value); } } @@ -585,18 +585,18 @@ void isst_clos_display_information(struct isst_id *id, FILE *outf, int clos, format_and_print(outf, level + 2, header, value); snprintf(header, sizeof(header), "clos-min"); - snprintf(value, sizeof(value), "%d MHz", clos_config->clos_min * DISP_FREQ_MULTIPLIER); + snprintf(value, sizeof(value), "%d MHz", clos_config->clos_min * isst_get_disp_freq_multiplier()); format_and_print(outf, level + 2, header, value); snprintf(header, sizeof(header), "clos-max"); if (clos_config->clos_max == 0xff) snprintf(value, sizeof(value), "Max Turbo frequency"); else - snprintf(value, sizeof(value), "%d MHz", clos_config->clos_max * DISP_FREQ_MULTIPLIER); + snprintf(value, sizeof(value), "%d MHz", clos_config->clos_max * isst_get_disp_freq_multiplier()); format_and_print(outf, level + 2, header, value); snprintf(header, sizeof(header), "clos-desired"); - snprintf(value, sizeof(value), "%d MHz", clos_config->clos_desired * DISP_FREQ_MULTIPLIER); + snprintf(value, sizeof(value), "%d MHz", clos_config->clos_desired * isst_get_disp_freq_multiplier()); format_and_print(outf, level + 2, header, value); format_and_print(outf, level, NULL, NULL); diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 6f60fcf409eeb..8de9dd4798848 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -208,6 +208,7 @@ extern int isst_send_msr_command(unsigned int cpu, unsigned int command, int write, unsigned long long *req_resp); extern void isst_update_platform_param(enum isst_platform_param, int vale); +extern int isst_get_disp_freq_multiplier(void); extern int isst_get_trl_max_levels(void); extern char *isst_get_trl_level_name(int level); extern int isst_is_punit_valid(struct isst_id *id); From e9f79348aedbd1a262bdac0f9e8b104590a30cc0 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 20 Aug 2022 21:50:53 +0800 Subject: [PATCH 10/61] tools/power/x86/intel-speed-select: Always invoke isst_fill_platform_info isst_fill_platform_info fills platform specific information. And it is the proper place to set platform specific callbacks, as done in next patch. As the platform specific callbacks are needed in all cases, including isst_print_platform_information. The best way to achieve both is to invoke isst_fill_platform_info unconditionally, and make isst_print_platform_information leverage the data already filled. No functional changes are expected. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-config.c | 42 +++++++------------ 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 806533fd4626b..d4567b8d72db7 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -803,6 +803,9 @@ static int isst_fill_platform_info(void) const char *pathname = "/dev/isst_interface"; int fd; + if (is_clx_n_platform()) + return 0; + fd = open(pathname, O_RDWR); if (fd < 0) err(-1, "%s open failed", pathname); @@ -911,10 +914,6 @@ static void isst_print_extended_platform_info(void) static void isst_print_platform_information(void) { - struct isst_if_platform_info platform_info; - const char *pathname = "/dev/isst_interface"; - int fd; - if (is_clx_n_platform()) { fprintf(stderr, "\nThis option in not supported on this platform\n"); exit(0); @@ -924,25 +923,15 @@ static void isst_print_platform_information(void) set_max_cpu_num(); create_cpu_map(); - fd = open(pathname, O_RDWR); - if (fd < 0) - err(-1, "%s open failed", pathname); - - if (ioctl(fd, ISST_IF_GET_PLATFORM_INFO, &platform_info) == -1) { - perror("ISST_IF_GET_PLATFORM_INFO"); - } else { - fprintf(outf, "Platform: API version : %d\n", - platform_info.api_version); - fprintf(outf, "Platform: Driver version : %d\n", - platform_info.driver_version); - fprintf(outf, "Platform: mbox supported : %d\n", - platform_info.mbox_supported); - fprintf(outf, "Platform: mmio supported : %d\n", - platform_info.mmio_supported); - isst_print_extended_platform_info(); - } - - close(fd); + fprintf(outf, "Platform: API version : %d\n", + isst_platform_info.api_version); + fprintf(outf, "Platform: Driver version : %d\n", + isst_platform_info.driver_version); + fprintf(outf, "Platform: mbox supported : %d\n", + isst_platform_info.mbox_supported); + fprintf(outf, "Platform: mmio supported : %d\n", + isst_platform_info.mmio_supported); + isst_print_extended_platform_info(); exit(0); } @@ -2832,6 +2821,10 @@ static void cmdline(int argc, char **argv) fclose(fp); } + ret = isst_fill_platform_info(); + if (ret) + goto out; + progname = argv[0]; while ((opt = getopt_long_only(argc, argv, "+c:df:hio:vabw:n", long_options, &option_index)) != -1) { @@ -2922,9 +2915,6 @@ static void cmdline(int argc, char **argv) } if (!is_clx_n_platform()) { - ret = isst_fill_platform_info(); - if (ret) - goto out; process_command(argc, argv, isst_help_cmds, isst_cmds); } else { process_command(argc, argv, clx_n_help_cmds, clx_n_cmds); From d0d1a603c5fea39ada5d3c48f8b7273a2109af07 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 20 Aug 2022 18:59:54 +0800 Subject: [PATCH 11/61] tools/power/x86/intel-speed-select: Introduce isst-core-mbox.c isst-core.c should contain generic core APIs only. Platform specific implementations/configurations should be removed from this file. Introduce isst-core-mbox.c and move all mbox/mmio specific functions to this file. Introduce struct isst_platform_ops which contains a series of callbacks that used by the core APIs but need platform specific implementation. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/Build | 2 +- .../x86/intel-speed-select/isst-config.c | 8 +++- .../x86/intel-speed-select/isst-core-mbox.c | 43 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 37 ++++++++++------ tools/power/x86/intel-speed-select/isst.h | 11 +++++ 5 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 tools/power/x86/intel-speed-select/isst-core-mbox.c diff --git a/tools/power/x86/intel-speed-select/Build b/tools/power/x86/intel-speed-select/Build index 81e36bd578b1c..32a2493b52335 100644 --- a/tools/power/x86/intel-speed-select/Build +++ b/tools/power/x86/intel-speed-select/Build @@ -1 +1 @@ -intel-speed-select-y += isst-config.o isst-core.o isst-display.o isst-daemon.o hfi-events.o +intel-speed-select-y += isst-config.o isst-core.o isst-display.o isst-daemon.o hfi-events.o isst-core-mbox.o diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index d4567b8d72db7..1f357d499c899 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -804,7 +804,7 @@ static int isst_fill_platform_info(void) int fd; if (is_clx_n_platform()) - return 0; + goto set_platform_ops; fd = open(pathname, O_RDWR); if (fd < 0) @@ -822,6 +822,12 @@ static int isst_fill_platform_info(void) printf("Incompatible API versions; Upgrade of tool is required\n"); return -1; } + +set_platform_ops: + if (isst_set_platform_ops()) { + fprintf(stderr, "Failed to set platform callbacks\n"); + exit(0); + } return 0; } diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c new file mode 100644 index 0000000000000..221caa35c10c5 --- /dev/null +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Speed Select -- Enumerate and control features for Mailbox Interface + * Copyright (c) 2023 Intel Corporation. + */ +#include "isst.h" + +static int mbox_get_disp_freq_multiplier(void) +{ + return DISP_FREQ_MULTIPLIER; +} + +static int mbox_get_trl_max_levels(void) +{ + return 3; +} + +static char *mbox_get_trl_level_name(int level) +{ + switch (level) { + case 0: + return "sse"; + case 1: + return "avx2"; + case 2: + return "avx512"; + default: + return NULL; + } +} + + + +static struct isst_platform_ops mbox_ops = { + .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, + .get_trl_max_levels = mbox_get_trl_max_levels, + .get_trl_level_name = mbox_get_trl_level_name, +}; + +struct isst_platform_ops *mbox_get_platform_ops(void) +{ + return &mbox_ops; +} diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 8d63db2bf07c7..bf7b667d5ffa1 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -9,6 +9,25 @@ static int mbox_delay; static int mbox_retries = 3; +static struct isst_platform_ops *isst_ops; + +#define CHECK_CB(_name) \ + do { \ + if (!isst_ops || !isst_ops->_name) { \ + fprintf(stderr, "Invalid ops\n"); \ + exit(0); \ + } \ + } while (0) + +int isst_set_platform_ops(void) +{ + isst_ops = mbox_get_platform_ops(); + + if (!isst_ops) + return -1; + return 0; +} + void isst_update_platform_param(enum isst_platform_param param, int value) { switch (param) { @@ -25,26 +44,20 @@ void isst_update_platform_param(enum isst_platform_param param, int value) int isst_get_disp_freq_multiplier(void) { - return DISP_FREQ_MULTIPLIER; + CHECK_CB(get_disp_freq_multiplier); + return isst_ops->get_disp_freq_multiplier(); } int isst_get_trl_max_levels(void) { - return 3; + CHECK_CB(get_trl_max_levels); + return isst_ops->get_trl_max_levels(); } char *isst_get_trl_level_name(int level) { - switch (level) { - case 0: - return "sse"; - case 1: - return "avx2"; - case 2: - return "avx512"; - default: - return NULL; - } + CHECK_CB(get_trl_level_name); + return isst_ops->get_trl_level_name(level); } int isst_is_punit_valid(struct isst_id *id) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 8de9dd4798848..7bb74d0912c29 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -181,6 +181,12 @@ enum isst_platform_param { ISST_PARAM_MBOX_RETRIES, }; +struct isst_platform_ops { + int (*get_disp_freq_multiplier)(void); + int (*get_trl_max_levels)(void); + char *(*get_trl_level_name)(int level); +}; + extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); extern int get_topo_max_cpus(void); extern int get_cpu_count(struct isst_id *id); @@ -207,6 +213,7 @@ extern int isst_send_mbox_command(unsigned int cpu, unsigned char command, extern int isst_send_msr_command(unsigned int cpu, unsigned int command, int write, unsigned long long *req_resp); +extern int isst_set_platform_ops(void); extern void isst_update_platform_param(enum isst_platform_param, int vale); extern int isst_get_disp_freq_multiplier(void); extern int isst_get_trl_max_levels(void); @@ -285,4 +292,8 @@ extern int isst_daemon(int debug_mode, int poll_interval, int no_daemon); extern void process_level_change(struct isst_id *id); extern int hfi_main(void); extern void hfi_exit(void); + +/* Interface specific callbacks */ +extern struct isst_platform_ops *mbox_get_platform_ops(void); + #endif From 143584e8484fd5225efc4da490d744d26d2cf64e Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 20 Aug 2022 19:39:52 +0800 Subject: [PATCH 12/61] tools/power/x86/intel-speed-select: Abstract is_punit_valid Allow platform specific implementation to identify a valid punit. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-core-mbox.c | 10 ++++++++++ tools/power/x86/intel-speed-select/isst-core.c | 9 ++------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 221caa35c10c5..0d14286e0bae5 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -29,12 +29,22 @@ static char *mbox_get_trl_level_name(int level) } } +static int mbox_is_punit_valid(struct isst_id *id) +{ + if (id->cpu < 0) + return 0; + + if (id->pkg < 0 || id->die < 0 || id->punit) + return 0; + return 1; +} static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, .get_trl_level_name = mbox_get_trl_level_name, + .is_punit_valid = mbox_is_punit_valid, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index bf7b667d5ffa1..714ecd7109350 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -62,13 +62,8 @@ char *isst_get_trl_level_name(int level) int isst_is_punit_valid(struct isst_id *id) { - if (id->cpu < 0) - return 0; - - if (id->pkg < 0 || id->die < 0 || id->punit) - return 0; - - return 1; + CHECK_CB(is_punit_valid); + return isst_ops->is_punit_valid(id); } static int isst_send_mmio_command(unsigned int cpu, unsigned int reg, int write, diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 7bb74d0912c29..ce3638c0ab4da 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -185,6 +185,7 @@ struct isst_platform_ops { int (*get_disp_freq_multiplier)(void); int (*get_trl_max_levels)(void); char *(*get_trl_level_name)(int level); + int (*is_punit_valid)(struct isst_id *id); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From 724387448a45346768ca23ea92b99c67c89b82c8 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 20:23:26 +0800 Subject: [PATCH 13/61] tools/power/x86/intel-speed-select: Abstract get_config_levels Allow platform specific implementation to get SST-PP level. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 28 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 25 ++--------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 0d14286e0bae5..2d8043845ef36 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -40,11 +40,39 @@ static int mbox_is_punit_valid(struct isst_id *id) return 1; } +static int mbox_get_config_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev) +{ + unsigned int resp; + int ret; + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp); + if (ret) { + pkg_dev->levels = 0; + pkg_dev->locked = 1; + pkg_dev->current_level = 0; + pkg_dev->version = 0; + pkg_dev->enabled = 0; + return 0; + } + + debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", id->cpu, resp); + + pkg_dev->version = resp & 0xff; + pkg_dev->levels = (resp >> 8) & 0xff; + pkg_dev->current_level = (resp >> 16) & 0xff; + pkg_dev->locked = !!(resp & BIT(24)); + pkg_dev->enabled = !!(resp & BIT(31)); + + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, .get_trl_level_name = mbox_get_trl_level_name, .is_punit_valid = mbox_is_punit_valid, + .get_config_levels = mbox_get_config_levels, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 714ecd7109350..0cc5075a71788 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -287,29 +287,8 @@ int isst_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap) int isst_get_ctdp_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev) { - unsigned int resp; - int ret; - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, - CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp); - if (ret) { - pkg_dev->levels = 0; - pkg_dev->locked = 1; - pkg_dev->current_level = 0; - pkg_dev->version = 0; - pkg_dev->enabled = 0; - return 0; - } - - debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", id->cpu, resp); - - pkg_dev->version = resp & 0xff; - pkg_dev->levels = (resp >> 8) & 0xff; - pkg_dev->current_level = (resp >> 16) & 0xff; - pkg_dev->locked = !!(resp & BIT(24)); - pkg_dev->enabled = !!(resp & BIT(31)); - - return 0; + CHECK_CB(get_config_levels); + return isst_ops->get_config_levels(id, pkg_dev); } int isst_get_ctdp_control(struct isst_id *id, int config_index, diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index ce3638c0ab4da..03ad9e305b9d2 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -186,6 +186,7 @@ struct isst_platform_ops { int (*get_trl_max_levels)(void); char *(*get_trl_level_name)(int level); int (*is_punit_valid)(struct isst_id *id); + int (*get_config_levels)(struct isst_id *id, struct isst_pkg_ctdp *pkg_ctdp); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From bbe32d87524b7b3fe7f758b3f789af4d8997c271 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 20:28:06 +0800 Subject: [PATCH 14/61] tools/power/x86/intel-speed-select: Abstract get_ctdp_control Allow platform specific implementation to get SST-TF/BF/CP capabilities and status. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 36 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 32 ++--------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 2d8043845ef36..0394b5b1e4f05 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -67,12 +67,48 @@ static int mbox_get_config_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_ return 0; } +static int mbox_get_ctdp_control(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + int cp_state, cp_cap; + unsigned int resp; + int ret; + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + CONFIG_TDP_GET_TDP_CONTROL, 0, + config_index, &resp); + if (ret) + return ret; + + ctdp_level->fact_support = resp & BIT(0); + ctdp_level->pbf_support = !!(resp & BIT(1)); + ctdp_level->fact_enabled = !!(resp & BIT(16)); + ctdp_level->pbf_enabled = !!(resp & BIT(17)); + + ret = isst_read_pm_config(id, &cp_state, &cp_cap); + if (ret) { + debug_printf("cpu:%d pm_config is not supported\n", id->cpu); + } else { + debug_printf("cpu:%d pm_config SST-CP state:%d cap:%d\n", id->cpu, cp_state, cp_cap); + ctdp_level->sst_cp_support = cp_cap; + ctdp_level->sst_cp_enabled = cp_state; + } + + debug_printf( + "cpu:%d CONFIG_TDP_GET_TDP_CONTROL resp:%x fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n", + id->cpu, resp, ctdp_level->fact_support, ctdp_level->pbf_support, + ctdp_level->fact_enabled, ctdp_level->pbf_enabled); + + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, .get_trl_level_name = mbox_get_trl_level_name, .is_punit_valid = mbox_is_punit_valid, .get_config_levels = mbox_get_config_levels, + .get_ctdp_control = mbox_get_ctdp_control, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 0cc5075a71788..3d6fbf754d47c 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -294,36 +294,8 @@ int isst_get_ctdp_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev) int isst_get_ctdp_control(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { - int cp_state, cp_cap; - unsigned int resp; - int ret; - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, - CONFIG_TDP_GET_TDP_CONTROL, 0, - config_index, &resp); - if (ret) - return ret; - - ctdp_level->fact_support = resp & BIT(0); - ctdp_level->pbf_support = !!(resp & BIT(1)); - ctdp_level->fact_enabled = !!(resp & BIT(16)); - ctdp_level->pbf_enabled = !!(resp & BIT(17)); - - ret = isst_read_pm_config(id, &cp_state, &cp_cap); - if (ret) { - debug_printf("cpu:%d pm_config is not supported\n", id->cpu); - } else { - debug_printf("cpu:%d pm_config SST-CP state:%d cap:%d\n", id->cpu, cp_state, cp_cap); - ctdp_level->sst_cp_support = cp_cap; - ctdp_level->sst_cp_enabled = cp_state; - } - - debug_printf( - "cpu:%d CONFIG_TDP_GET_TDP_CONTROL resp:%x fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n", - id->cpu, resp, ctdp_level->fact_support, ctdp_level->pbf_support, - ctdp_level->fact_enabled, ctdp_level->pbf_enabled); - - return 0; + CHECK_CB(get_ctdp_control); + return isst_ops->get_ctdp_control(id, config_index, ctdp_level); } int isst_get_tdp_info(struct isst_id *id, int config_index, diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 03ad9e305b9d2..496e5c4e5b0d6 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -187,6 +187,7 @@ struct isst_platform_ops { char *(*get_trl_level_name)(int level); int (*is_punit_valid)(struct isst_id *id); int (*get_config_levels)(struct isst_id *id, struct isst_pkg_ctdp *pkg_ctdp); + int (*get_ctdp_control)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From 645b66054cb588c4aa47920643372dd6879ef3b4 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 20:31:38 +0800 Subject: [PATCH 15/61] tools/power/x86/intel-speed-select: Abstract get_tdp_info Allow platform specific implementation to get TDP information. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 24 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 20 ++-------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 0394b5b1e4f05..33537864a0684 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -102,6 +102,29 @@ static int mbox_get_ctdp_control(struct isst_id *id, int config_index, return 0; } +static int mbox_get_tdp_info(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO, + 0, config_index, &resp); + if (ret) { + isst_display_error_info_message(1, "Invalid level, Can't get TDP information at level", 1, config_index); + return ret; + } + + ctdp_level->pkg_tdp = resp & GENMASK(14, 0); + ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16; + + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO resp:%x tdp_ratio:%d pkg_tdp:%d\n", + id->cpu, config_index, resp, ctdp_level->tdp_ratio, + ctdp_level->pkg_tdp); + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -109,6 +132,7 @@ static struct isst_platform_ops mbox_ops = { .is_punit_valid = mbox_is_punit_valid, .get_config_levels = mbox_get_config_levels, .get_ctdp_control = mbox_get_ctdp_control, + .get_tdp_info = mbox_get_tdp_info, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 3d6fbf754d47c..b4f285d85be98 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -301,24 +301,8 @@ int isst_get_ctdp_control(struct isst_id *id, int config_index, int isst_get_tdp_info(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { - unsigned int resp; - int ret; - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO, - 0, config_index, &resp); - if (ret) { - isst_display_error_info_message(1, "Invalid level, Can't get TDP information at level", 1, config_index); - return ret; - } - - ctdp_level->pkg_tdp = resp & GENMASK(14, 0); - ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16; - - debug_printf( - "cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO resp:%x tdp_ratio:%d pkg_tdp:%d\n", - id->cpu, config_index, resp, ctdp_level->tdp_ratio, - ctdp_level->pkg_tdp); - return 0; + CHECK_CB(get_tdp_info); + return isst_ops->get_tdp_info(id, config_index, ctdp_level); } int isst_get_pwr_info(struct isst_id *id, int config_index, diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 496e5c4e5b0d6..ed8bcb2a28374 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -188,6 +188,7 @@ struct isst_platform_ops { int (*is_punit_valid)(struct isst_id *id); int (*get_config_levels)(struct isst_id *id, struct isst_pkg_ctdp *pkg_ctdp); int (*get_ctdp_control)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); + int (*get_tdp_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From e107dec9a8ddd97488e579f1d0cf10a849037cdf Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 20:34:45 +0800 Subject: [PATCH 16/61] tools/power/x86/intel-speed-select: Abstract get_pwr_info Allow platform specific implementation to get min and max power for a given SST-PP level. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 24 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 19 ++------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 33537864a0684..40c856f4c708f 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -125,6 +125,29 @@ static int mbox_get_tdp_info(struct isst_id *id, int config_index, return 0; } +static int mbox_get_pwr_info(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO, + 0, config_index, &resp); + if (ret) + return ret; + + ctdp_level->pkg_max_power = resp & GENMASK(14, 0); + ctdp_level->pkg_min_power = (resp & GENMASK(30, 16)) >> 16; + + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO resp:%x pkg_max_power:%d pkg_min_power:%d\n", + id->cpu, config_index, resp, ctdp_level->pkg_max_power, + ctdp_level->pkg_min_power); + + return 0; +} + + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -133,6 +156,7 @@ static struct isst_platform_ops mbox_ops = { .get_config_levels = mbox_get_config_levels, .get_ctdp_control = mbox_get_ctdp_control, .get_tdp_info = mbox_get_tdp_info, + .get_pwr_info = mbox_get_pwr_info, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index b4f285d85be98..def0a68889076 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -308,23 +308,8 @@ int isst_get_tdp_info(struct isst_id *id, int config_index, int isst_get_pwr_info(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { - unsigned int resp; - int ret; - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO, - 0, config_index, &resp); - if (ret) - return ret; - - ctdp_level->pkg_max_power = resp & GENMASK(14, 0); - ctdp_level->pkg_min_power = (resp & GENMASK(30, 16)) >> 16; - - debug_printf( - "cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO resp:%x pkg_max_power:%d pkg_min_power:%d\n", - id->cpu, config_index, resp, ctdp_level->pkg_max_power, - ctdp_level->pkg_min_power); - - return 0; + CHECK_CB(get_pwr_info); + return isst_ops->get_pwr_info(id, config_index, ctdp_level); } void isst_get_uncore_p0_p1_info(struct isst_id *id, int config_index, diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index ed8bcb2a28374..5dc2613a39ff3 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -189,6 +189,7 @@ struct isst_platform_ops { int (*get_config_levels)(struct isst_id *id, struct isst_pkg_ctdp *pkg_ctdp); int (*get_ctdp_control)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_tdp_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); + int (*get_pwr_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From e4cbd0f13f9ab3b3aefe79c45ab4d01984c37551 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 20:49:08 +0800 Subject: [PATCH 17/61] tools/power/x86/intel-speed-select: Move code right before its caller Some functions are defined far from its only caller. Rearrange the code. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../power/x86/intel-speed-select/isst-core.c | 203 +++++++++--------- 1 file changed, 102 insertions(+), 101 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index def0a68889076..9b993b00cd7d7 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -312,107 +312,6 @@ int isst_get_pwr_info(struct isst_id *id, int config_index, return isst_ops->get_pwr_info(id, config_index, ctdp_level); } -void isst_get_uncore_p0_p1_info(struct isst_id *id, int config_index, - struct isst_pkg_ctdp_level_info *ctdp_level) -{ - unsigned int resp; - int ret; - - ctdp_level->uncore_pm = 0; - ctdp_level->uncore_p0 = 0; - ctdp_level->uncore_p1 = 0; - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, - CONFIG_TDP_GET_RATIO_INFO, 0, - (BIT(16) | config_index), &resp); - if (ret) - goto try_uncore_mbox; - - ctdp_level->uncore_p0 = resp & GENMASK(7, 0); - ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8; - ctdp_level->uncore_pm = (resp & GENMASK(31, 24)) >> 24; - - debug_printf( - "cpu:%d ctdp:%d CONFIG_TDP_GET_RATIO_INFO resp:%x uncore p0:%d uncore p1:%d uncore pm:%d\n", - id->cpu, config_index, resp, ctdp_level->uncore_p0, ctdp_level->uncore_p1, - ctdp_level->uncore_pm); - - return; - -try_uncore_mbox: - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, - CONFIG_TDP_GET_UNCORE_P0_P1_INFO, 0, - config_index, &resp); - if (ret) { - ctdp_level->uncore_p0 = 0; - ctdp_level->uncore_p1 = 0; - return; - } - - ctdp_level->uncore_p0 = resp & GENMASK(7, 0); - ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8; - debug_printf( - "cpu:%d ctdp:%d CONFIG_TDP_GET_UNCORE_P0_P1_INFO resp:%x uncore p0:%d uncore p1:%d\n", - id->cpu, config_index, resp, ctdp_level->uncore_p0, - ctdp_level->uncore_p1); -} - -void isst_get_p1_info(struct isst_id *id, int config_index, - struct isst_pkg_ctdp_level_info *ctdp_level) -{ - unsigned int resp; - int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0, - config_index, &resp); - if (ret) { - ctdp_level->sse_p1 = 0; - ctdp_level->avx2_p1 = 0; - ctdp_level->avx512_p1 = 0; - return; - } - - ctdp_level->sse_p1 = resp & GENMASK(7, 0); - ctdp_level->avx2_p1 = (resp & GENMASK(15, 8)) >> 8; - ctdp_level->avx512_p1 = (resp & GENMASK(23, 16)) >> 16; - debug_printf( - "cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d\n", - id->cpu, config_index, resp, ctdp_level->sse_p1, - ctdp_level->avx2_p1, ctdp_level->avx512_p1); -} - -void isst_get_uncore_mem_freq(struct isst_id *id, int config_index, - struct isst_pkg_ctdp_level_info *ctdp_level) -{ - unsigned int resp; - int ret; - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ, - 0, config_index, &resp); - if (ret) { - ctdp_level->mem_freq = 0; - return; - } - - ctdp_level->mem_freq = resp & GENMASK(7, 0); - if (is_spr_platform()) { - ctdp_level->mem_freq *= 200; - } else if (is_icx_platform()) { - if (ctdp_level->mem_freq < 7) { - ctdp_level->mem_freq = (12 - ctdp_level->mem_freq) * 133.33 * 2 * 10; - ctdp_level->mem_freq /= 10; - if (ctdp_level->mem_freq % 10 > 5) - ctdp_level->mem_freq++; - } else { - ctdp_level->mem_freq = 0; - } - } else { - ctdp_level->mem_freq = 0; - } - debug_printf( - "cpu:%d ctdp:%d CONFIG_TDP_GET_MEM_FREQ resp:%x uncore mem_freq:%d\n", - id->cpu, config_index, resp, ctdp_level->mem_freq); -} - int isst_get_tjmax_info(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { @@ -917,6 +816,108 @@ void isst_get_process_ctdp_complete(struct isst_id *id, struct isst_pkg_ctdp *pk } } +void isst_get_uncore_p0_p1_info(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + + ctdp_level->uncore_pm = 0; + ctdp_level->uncore_p0 = 0; + ctdp_level->uncore_p1 = 0; + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + CONFIG_TDP_GET_RATIO_INFO, 0, + (BIT(16) | config_index) , &resp); + if (ret) { + goto try_uncore_mbox; + } + + ctdp_level->uncore_p0 = resp & GENMASK(7, 0); + ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8; + ctdp_level->uncore_pm = (resp & GENMASK(31, 24)) >> 24; + + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_RATIO_INFO resp:%x uncore p0:%d uncore p1:%d uncore pm:%d\n", + id->cpu, config_index, resp, ctdp_level->uncore_p0, ctdp_level->uncore_p1, + ctdp_level->uncore_pm); + + return; + +try_uncore_mbox: + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + CONFIG_TDP_GET_UNCORE_P0_P1_INFO, 0, + config_index, &resp); + if (ret) { + ctdp_level->uncore_p0 = 0; + ctdp_level->uncore_p1 = 0; + return; + } + + ctdp_level->uncore_p0 = resp & GENMASK(7, 0); + ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8; + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_UNCORE_P0_P1_INFO resp:%x uncore p0:%d uncore p1:%d\n", + id->cpu, config_index, resp, ctdp_level->uncore_p0, + ctdp_level->uncore_p1); +} + +void isst_get_p1_info(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0, + config_index, &resp); + if (ret) { + ctdp_level->sse_p1 = 0; + ctdp_level->avx2_p1 = 0; + ctdp_level->avx512_p1 = 0; + return; + } + + ctdp_level->sse_p1 = resp & GENMASK(7, 0); + ctdp_level->avx2_p1 = (resp & GENMASK(15, 8)) >> 8; + ctdp_level->avx512_p1 = (resp & GENMASK(23, 16)) >> 16; + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d\n", + id->cpu, config_index, resp, ctdp_level->sse_p1, + ctdp_level->avx2_p1, ctdp_level->avx512_p1); +} + +void isst_get_uncore_mem_freq(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ, + 0, config_index, &resp); + if (ret) { + ctdp_level->mem_freq = 0; + return; + } + + ctdp_level->mem_freq = resp & GENMASK(7, 0); + if (is_spr_platform()) { + ctdp_level->mem_freq *= 200; + } else if (is_icx_platform()) { + if (ctdp_level->mem_freq < 7) { + ctdp_level->mem_freq = (12 - ctdp_level->mem_freq) * 133.33 * 2 * 10; + ctdp_level->mem_freq /= 10; + if (ctdp_level->mem_freq % 10 > 5) + ctdp_level->mem_freq++; + } else { + ctdp_level->mem_freq = 0; + } + } else { + ctdp_level->mem_freq = 0; + } + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_MEM_FREQ resp:%x uncore mem_freq:%d\n", + id->cpu, config_index, resp, ctdp_level->mem_freq); +} + int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctdp *pkg_dev) { int i, ret, valid = 0; From a30cbd2270865136fbdcf0fbf7fadda707f32bba Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 20:52:23 +0800 Subject: [PATCH 18/61] tools/power/x86/intel-speed-select: Abstract get_tjmax_info Allow platform specific implementation to get the Tjmax info for a given SST-PP level. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 13 +++++++++- .../power/x86/intel-speed-select/isst-core.c | 24 ------------------- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 40c856f4c708f..2ae46aa7f9c4d 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -122,6 +122,18 @@ static int mbox_get_tdp_info(struct isst_id *id, int config_index, "cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO resp:%x tdp_ratio:%d pkg_tdp:%d\n", id->cpu, config_index, resp, ctdp_level->tdp_ratio, ctdp_level->pkg_tdp); + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO, + 0, config_index, &resp); + if (ret) + return ret; + + ctdp_level->t_proc_hot = resp & GENMASK(7, 0); + + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_TJMAX_INFO resp:%x t_proc_hot:%d\n", + id->cpu, config_index, resp, ctdp_level->t_proc_hot); + return 0; } @@ -147,7 +159,6 @@ static int mbox_get_pwr_info(struct isst_id *id, int config_index, return 0; } - static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 9b993b00cd7d7..d93735fbecea1 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -312,26 +312,6 @@ int isst_get_pwr_info(struct isst_id *id, int config_index, return isst_ops->get_pwr_info(id, config_index, ctdp_level); } -int isst_get_tjmax_info(struct isst_id *id, int config_index, - struct isst_pkg_ctdp_level_info *ctdp_level) -{ - unsigned int resp; - int ret; - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO, - 0, config_index, &resp); - if (ret) - return ret; - - ctdp_level->t_proc_hot = resp & GENMASK(7, 0); - - debug_printf( - "cpu:%d ctdp:%d CONFIG_TDP_GET_TJMAX_INFO resp:%x t_proc_hot:%d\n", - id->cpu, config_index, resp, ctdp_level->t_proc_hot); - - return 0; -} - int isst_get_coremask_info(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { @@ -1001,10 +981,6 @@ int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctd if (ret) return ret; - ret = isst_get_tjmax_info(id, i, ctdp_level); - if (ret) - return ret; - ctdp_level->core_cpumask_size = alloc_cpu_set(&ctdp_level->core_cpumask); ret = isst_get_coremask_info(id, i, ctdp_level); From 668cc16cc8a0b7e3d7f2f2acff2ca3214fbe38d7 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 9 Aug 2022 00:34:34 +0800 Subject: [PATCH 19/61] tools/power/x86/intel-speed-select: Abstract get_coremask_info Allow platform specific implementation to get the core mask for a given SST-PP level. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 35 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 31 ++-------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 2ae46aa7f9c4d..51f589fe6bf99 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -159,6 +159,40 @@ static int mbox_get_pwr_info(struct isst_id *id, int config_index, return 0; } +static int mbox_get_coremask_info(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int i, ret; + + ctdp_level->cpu_count = 0; + for (i = 0; i < 2; ++i) { + unsigned long long mask; + int cpu_count = 0; + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + CONFIG_TDP_GET_CORE_MASK, 0, + (i << 8) | config_index, &resp); + if (ret) + return ret; + + debug_printf( + "cpu:%d ctdp:%d mask:%d CONFIG_TDP_GET_CORE_MASK resp:%x\n", + id->cpu, config_index, i, resp); + + mask = (unsigned long long)resp << (32 * i); + set_cpu_mask_from_punit_coremask(id, mask, + ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask, + &cpu_count); + ctdp_level->cpu_count += cpu_count; + debug_printf("cpu:%d ctdp:%d mask:%d cpu count:%d\n", id->cpu, + config_index, i, ctdp_level->cpu_count); + } + + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -168,6 +202,7 @@ static struct isst_platform_ops mbox_ops = { .get_ctdp_control = mbox_get_ctdp_control, .get_tdp_info = mbox_get_tdp_info, .get_pwr_info = mbox_get_pwr_info, + .get_coremask_info = mbox_get_coremask_info, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index d93735fbecea1..43884632694d9 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -315,35 +315,8 @@ int isst_get_pwr_info(struct isst_id *id, int config_index, int isst_get_coremask_info(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { - unsigned int resp; - int i, ret; - - ctdp_level->cpu_count = 0; - for (i = 0; i < 2; ++i) { - unsigned long long mask; - int cpu_count = 0; - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, - CONFIG_TDP_GET_CORE_MASK, 0, - (i << 8) | config_index, &resp); - if (ret) - return ret; - - debug_printf( - "cpu:%d ctdp:%d mask:%d CONFIG_TDP_GET_CORE_MASK resp:%x\n", - id->cpu, config_index, i, resp); - - mask = (unsigned long long)resp << (32 * i); - set_cpu_mask_from_punit_coremask(id, mask, - ctdp_level->core_cpumask_size, - ctdp_level->core_cpumask, - &cpu_count); - ctdp_level->cpu_count += cpu_count; - debug_printf("cpu:%d ctdp:%d mask:%d cpu count:%d\n", id->cpu, - config_index, i, ctdp_level->cpu_count); - } - - return 0; + CHECK_CB(get_coremask_info); + return isst_ops->get_coremask_info(id, config_index, ctdp_level); } int isst_get_get_trl_from_msr(struct isst_id *id, int *trl) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 5dc2613a39ff3..0d5d35582d55a 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -190,6 +190,7 @@ struct isst_platform_ops { int (*get_ctdp_control)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_tdp_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_pwr_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); + int (*get_coremask_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From 39f768c341fa429bf9d37f477902aaf0f5aa904f Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 17 Aug 2022 23:19:15 +0800 Subject: [PATCH 20/61] tools/power/x86/intel-speed-select: Abstract get_get_trl Allow platform specific implementation to get turbo ratio limit of the selected SST-PP level, and AVX level. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 40 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 37 +---------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 51f589fe6bf99..4d31b49b4a26e 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -193,6 +193,45 @@ static int mbox_get_coremask_info(struct isst_id *id, int config_index, return 0; } +static int mbox_get_get_trl(struct isst_id *id, int level, int avx_level, int *trl) +{ + unsigned int req, resp; + int ret; + + req = level | (avx_level << 16); + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, + &resp); + if (ret) + return ret; + + debug_printf( + "cpu:%d CONFIG_TDP_GET_TURBO_LIMIT_RATIOS req:%x resp:%x\n", + id->cpu, req, resp); + + trl[0] = resp & GENMASK(7, 0); + trl[1] = (resp & GENMASK(15, 8)) >> 8; + trl[2] = (resp & GENMASK(23, 16)) >> 16; + trl[3] = (resp & GENMASK(31, 24)) >> 24; + + req = level | BIT(8) | (avx_level << 16); + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, + &resp); + if (ret) + return ret; + + debug_printf("cpu:%d CONFIG_TDP_GET_TURBO_LIMIT req:%x resp:%x\n", id->cpu, + req, resp); + + trl[4] = resp & GENMASK(7, 0); + trl[5] = (resp & GENMASK(15, 8)) >> 8; + trl[6] = (resp & GENMASK(23, 16)) >> 16; + trl[7] = (resp & GENMASK(31, 24)) >> 24; + + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -203,6 +242,7 @@ static struct isst_platform_ops mbox_ops = { .get_tdp_info = mbox_get_tdp_info, .get_pwr_info = mbox_get_pwr_info, .get_coremask_info = mbox_get_coremask_info, + .get_get_trl = mbox_get_get_trl, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 43884632694d9..6afae60d68fee 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -342,41 +342,8 @@ int isst_get_get_trl_from_msr(struct isst_id *id, int *trl) int isst_get_get_trl(struct isst_id *id, int level, int avx_level, int *trl) { - unsigned int req, resp; - int ret; - - req = level | (avx_level << 16); - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, - CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, - &resp); - if (ret) - return ret; - - debug_printf( - "cpu:%d CONFIG_TDP_GET_TURBO_LIMIT_RATIOS req:%x resp:%x\n", - id->cpu, req, resp); - - trl[0] = resp & GENMASK(7, 0); - trl[1] = (resp & GENMASK(15, 8)) >> 8; - trl[2] = (resp & GENMASK(23, 16)) >> 16; - trl[3] = (resp & GENMASK(31, 24)) >> 24; - - req = level | BIT(8) | (avx_level << 16); - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, - CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, - &resp); - if (ret) - return ret; - - debug_printf("cpu:%d CONFIG_TDP_GET_TURBO_LIMIT req:%x resp:%x\n", id->cpu, - req, resp); - - trl[4] = resp & GENMASK(7, 0); - trl[5] = (resp & GENMASK(15, 8)) >> 8; - trl[6] = (resp & GENMASK(23, 16)) >> 16; - trl[7] = (resp & GENMASK(31, 24)) >> 24; - - return 0; + CHECK_CB(get_get_trl); + return isst_ops->get_get_trl(id, level, avx_level, trl); } int isst_get_trl_bucket_info(struct isst_id *id, unsigned long long *buckets_info) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 0d5d35582d55a..b8b1bdafc18ba 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -191,6 +191,7 @@ struct isst_platform_ops { int (*get_tdp_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_pwr_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_coremask_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); + int (*get_get_trl)(struct isst_id *id, int level, int avx_level, int *trl); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From 1e37f1b21c7022f1d9dd641a6f2d4ffd2950202c Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 21:01:08 +0800 Subject: [PATCH 21/61] tools/power/x86/intel-speed-select: Abstract get_trl_bucket_info Allow platform specific implementation to get buckets info. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 19 ++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 22 +++++-------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 4d31b49b4a26e..0cc08dbb0cc4b 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -232,6 +232,24 @@ static int mbox_get_get_trl(struct isst_id *id, int level, int avx_level, int *t return 0; } +static int mbox_get_trl_bucket_info(struct isst_id *id, int level, unsigned long long *buckets_info) +{ + int ret; + + debug_printf("cpu:%d bucket info via MSR\n", id->cpu); + + *buckets_info = 0; + + ret = isst_send_msr_command(id->cpu, 0x1ae, 0, buckets_info); + if (ret) + return ret; + + debug_printf("cpu:%d bucket info via MSR successful 0x%llx\n", id->cpu, + *buckets_info); + + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -243,6 +261,7 @@ static struct isst_platform_ops mbox_ops = { .get_pwr_info = mbox_get_pwr_info, .get_coremask_info = mbox_get_coremask_info, .get_get_trl = mbox_get_get_trl, + .get_trl_bucket_info = mbox_get_trl_bucket_info, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 6afae60d68fee..bd4facdf746ec 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -346,22 +346,10 @@ int isst_get_get_trl(struct isst_id *id, int level, int avx_level, int *trl) return isst_ops->get_get_trl(id, level, avx_level, trl); } -int isst_get_trl_bucket_info(struct isst_id *id, unsigned long long *buckets_info) +int isst_get_trl_bucket_info(struct isst_id *id, int level, unsigned long long *buckets_info) { - int ret; - - debug_printf("cpu:%d bucket info via MSR\n", id->cpu); - - *buckets_info = 0; - - ret = isst_send_msr_command(id->cpu, 0x1ae, 0, buckets_info); - if (ret) - return ret; - - debug_printf("cpu:%d bucket info via MSR successful 0x%llx\n", id->cpu, - *buckets_info); - - return 0; + CHECK_CB(get_trl_bucket_info); + return isst_ops->get_trl_bucket_info(id, level, buckets_info); } int isst_set_tdp_level(struct isst_id *id, int tdp_level) @@ -909,7 +897,7 @@ int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctd } isst_get_get_trl_from_msr(id, ctdp_level->trl_ratios[0]); - isst_get_trl_bucket_info(id, &ctdp_level->trl_cores); + isst_get_trl_bucket_info(id, i, &ctdp_level->trl_cores); continue; } @@ -927,7 +915,7 @@ int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctd if (ret) return ret; - ret = isst_get_trl_bucket_info(id, &ctdp_level->trl_cores); + ret = isst_get_trl_bucket_info(id, i, &ctdp_level->trl_cores); if (ret) return ret; diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index b8b1bdafc18ba..465e07960ccb2 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -192,6 +192,7 @@ struct isst_platform_ops { int (*get_pwr_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_coremask_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_get_trl)(struct isst_id *id, int level, int avx_level, int *trl); + int (*get_trl_bucket_info)(struct isst_id *id, int level, unsigned long long *buckets_info); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From f88c3c4bd431a81e50e126342f8daa6ee9171b82 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 9 Aug 2022 01:49:48 +0800 Subject: [PATCH 22/61] tools/power/x86/intel-speed-select: Abstract set_tdp_level Allow platform specific implementation to set a SST-PP level. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 23 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 20 ++-------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 0cc08dbb0cc4b..f6f1632e35b94 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -250,6 +250,28 @@ static int mbox_get_trl_bucket_info(struct isst_id *id, int level, unsigned long return 0; } +static int mbox_set_tdp_level(struct isst_id *id, int tdp_level) +{ + unsigned int resp; + int ret; + + + if (isst_get_config_tdp_lock_status(id)) { + isst_display_error_info_message(1, "TDP is locked", 0, 0); + return -1; + + } + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0, + tdp_level, &resp); + if (ret) { + isst_display_error_info_message(1, "Set TDP level failed for level", 1, tdp_level); + return ret; + } + + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -262,6 +284,7 @@ static struct isst_platform_ops mbox_ops = { .get_coremask_info = mbox_get_coremask_info, .get_get_trl = mbox_get_get_trl, .get_trl_bucket_info = mbox_get_trl_bucket_info, + .set_tdp_level = mbox_set_tdp_level, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index bd4facdf746ec..53bfc5d47f528 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -354,24 +354,8 @@ int isst_get_trl_bucket_info(struct isst_id *id, int level, unsigned long long * int isst_set_tdp_level(struct isst_id *id, int tdp_level) { - unsigned int resp; - int ret; - - - if (isst_get_config_tdp_lock_status(id)) { - isst_display_error_info_message(1, "TDP is locked", 0, 0); - return -1; - - } - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0, - tdp_level, &resp); - if (ret) { - isst_display_error_info_message(1, "Set TDP level failed for level", 1, tdp_level); - return ret; - } - - return 0; + CHECK_CB(set_tdp_level); + return isst_ops->set_tdp_level(id, tdp_level); } int isst_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info *pbf_info) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 465e07960ccb2..cc1487c7b9b75 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -193,6 +193,7 @@ struct isst_platform_ops { int (*get_coremask_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_get_trl)(struct isst_id *id, int level, int avx_level, int *trl); int (*get_trl_bucket_info)(struct isst_id *id, int level, unsigned long long *buckets_info); + int (*set_tdp_level)(struct isst_id *id, int tdp_level); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From 7a1962904fe459d4763c6e02cd4b3ea503328a11 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 21:13:59 +0800 Subject: [PATCH 23/61] tools/power/x86/intel-speed-select: Abstract get_pbf_info Allow platform specific implementation to get SST-BF information. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 68 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 64 +---------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 72 insertions(+), 61 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index f6f1632e35b94..40e44fad95897 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -272,6 +272,73 @@ static int mbox_set_tdp_level(struct isst_id *id, int tdp_level) return 0; } +static int mbox_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info *pbf_info) +{ + int max_punit_core, max_mask_index; + unsigned int req, resp; + int i, ret; + + max_punit_core = get_max_punit_core_id(id); + max_mask_index = max_punit_core > 32 ? 2 : 1; + + for (i = 0; i < max_mask_index; ++i) { + unsigned long long mask; + int count; + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + CONFIG_TDP_PBF_GET_CORE_MASK_INFO, + 0, (i << 8) | level, &resp); + if (ret) + break; + + debug_printf( + "cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n", + id->cpu, resp); + + mask = (unsigned long long)resp << (32 * i); + set_cpu_mask_from_punit_coremask(id, mask, + pbf_info->core_cpumask_size, + pbf_info->core_cpumask, + &count); + } + + req = level; + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO, 0, req, + &resp); + if (ret) + return ret; + + debug_printf("cpu:%d CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO resp:%x\n", id->cpu, + resp); + + pbf_info->p1_low = resp & 0xff; + pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8; + + req = level; + ret = isst_send_mbox_command( + id->cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TDP_INFO, 0, req, &resp); + if (ret) + return ret; + + debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TDP_INFO resp:%x\n", id->cpu, resp); + + pbf_info->tdp = resp & 0xffff; + + req = level; + ret = isst_send_mbox_command( + id->cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TJ_MAX_INFO, 0, req, &resp); + if (ret) + return ret; + + debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TJ_MAX_INFO resp:%x\n", id->cpu, + resp); + pbf_info->t_control = (resp >> 8) & 0xff; + pbf_info->t_prochot = resp & 0xff; + + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -285,6 +352,7 @@ static struct isst_platform_ops mbox_ops = { .get_get_trl = mbox_get_get_trl, .get_trl_bucket_info = mbox_get_trl_bucket_info, .set_tdp_level = mbox_set_tdp_level, + .get_pbf_info = mbox_get_pbf_info, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 53bfc5d47f528..030c0bd4e5f04 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -362,8 +362,7 @@ int isst_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info *pbf_i { struct isst_pkg_ctdp_level_info ctdp_level; struct isst_pkg_ctdp pkg_dev; - int i, ret, max_punit_core, max_mask_index; - unsigned int req, resp; + int ret; ret = isst_get_ctdp_levels(id, &pkg_dev); if (ret) { @@ -387,65 +386,8 @@ int isst_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info *pbf_i pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask); - max_punit_core = get_max_punit_core_id(id); - max_mask_index = max_punit_core > 32 ? 2 : 1; - - for (i = 0; i < max_mask_index; ++i) { - unsigned long long mask; - int count; - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, - CONFIG_TDP_PBF_GET_CORE_MASK_INFO, - 0, (i << 8) | level, &resp); - if (ret) - break; - - debug_printf( - "cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n", - id->cpu, resp); - - mask = (unsigned long long)resp << (32 * i); - set_cpu_mask_from_punit_coremask(id, mask, - pbf_info->core_cpumask_size, - pbf_info->core_cpumask, - &count); - } - - req = level; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, - CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO, 0, req, - &resp); - if (ret) - return ret; - - debug_printf("cpu:%d CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO resp:%x\n", id->cpu, - resp); - - pbf_info->p1_low = resp & 0xff; - pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8; - - req = level; - ret = isst_send_mbox_command( - id->cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TDP_INFO, 0, req, &resp); - if (ret) - return ret; - - debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TDP_INFO resp:%x\n", id->cpu, resp); - - pbf_info->tdp = resp & 0xffff; - - req = level; - ret = isst_send_mbox_command( - id->cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TJ_MAX_INFO, 0, req, &resp); - if (ret) - return ret; - - debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TJ_MAX_INFO resp:%x\n", id->cpu, - resp); - pbf_info->t_control = (resp >> 8) & 0xff; - pbf_info->t_prochot = resp & 0xff; - - return 0; + CHECK_CB(get_pbf_info); + return isst_ops->get_pbf_info(id, level, pbf_info); } void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index cc1487c7b9b75..18659506bf68b 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -194,6 +194,7 @@ struct isst_platform_ops { int (*get_get_trl)(struct isst_id *id, int level, int avx_level, int *trl); int (*get_trl_bucket_info)(struct isst_id *id, int level, unsigned long long *buckets_info); int (*set_tdp_level)(struct isst_id *id, int tdp_level); + int (*get_pbf_info)(struct isst_id *id, int level, struct isst_pbf_info *pbf_info); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From 05ece6916e9a302f0d1eae1744ab72946f9ff32c Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 21:37:23 +0800 Subject: [PATCH 24/61] tools/power/x86/intel-speed-select: Remove isst_get_pbf_info_complete isst_get_pbf_info_complete does nothing but just free the core_mask. Remove the function and do free core_mask directly and free core mask in the caller. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-config.c | 2 +- tools/power/x86/intel-speed-select/isst-core.c | 5 ----- tools/power/x86/intel-speed-select/isst.h | 1 - 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 1f357d499c899..71e00d03062f8 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1331,7 +1331,7 @@ static void dump_pbf_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, exit(1); } else { isst_pbf_display_information(id, outf, tdp_level, &pbf_info); - isst_get_pbf_info_complete(&pbf_info); + free_cpu_set(pbf_info.core_cpumask); } } diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 030c0bd4e5f04..41aa1adc20253 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -390,11 +390,6 @@ int isst_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info *pbf_i return isst_ops->get_pbf_info(id, level, pbf_info); } -void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info) -{ - free_cpu_set(pbf_info->core_cpumask); -} - int isst_set_pbf_fact_status(struct isst_id *id, int pbf, int enable) { struct isst_pkg_ctdp pkg_dev; diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 18659506bf68b..06e089eaaa289 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -253,7 +253,6 @@ extern int isst_set_tdp_level(struct isst_id *id, int tdp_level); extern int isst_set_pbf_fact_status(struct isst_id *id, int pbf, int enable); extern int isst_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info *pbf_info); -extern void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info); extern int isst_get_fact_info(struct isst_id *id, int level, int fact_bucket, struct isst_fact_info *fact_info); extern int isst_get_fact_bucket_info(struct isst_id *id, int level, From 5843f2177058dab4d656fee692a0e8a2370e2d3d Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 21:44:04 +0800 Subject: [PATCH 25/61] tools/power/x86/intel-speed-select: Abstract set_pbf_fact_status Allow platform specific implementation to enable/disable SST-TF/BF. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 52 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 49 +---------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 55 insertions(+), 47 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 40e44fad95897..e6d32786a6add 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -339,6 +339,57 @@ static int mbox_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info return 0; } +static int mbox_set_pbf_fact_status(struct isst_id *id, int pbf, int enable) +{ + struct isst_pkg_ctdp pkg_dev; + struct isst_pkg_ctdp_level_info ctdp_level; + int current_level; + unsigned int req = 0, resp; + int ret; + + ret = isst_get_ctdp_levels(id, &pkg_dev); + if (ret) + debug_printf("cpu:%d No support for dynamic ISST\n", id->cpu); + + current_level = pkg_dev.current_level; + + ret = isst_get_ctdp_control(id, current_level, &ctdp_level); + if (ret) + return ret; + + if (pbf) { + if (ctdp_level.fact_enabled) + req = BIT(16); + + if (enable) + req |= BIT(17); + else + req &= ~BIT(17); + } else { + + if (enable && !ctdp_level.sst_cp_enabled) + isst_display_error_info_message(0, "Make sure to execute before: core-power enable", 0, 0); + + if (ctdp_level.pbf_enabled) + req = BIT(17); + + if (enable) + req |= BIT(16); + else + req &= ~BIT(16); + } + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp); + if (ret) + return ret; + + debug_printf("cpu:%d CONFIG_TDP_SET_TDP_CONTROL pbf/fact:%d req:%x\n", + id->cpu, pbf, req); + + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -353,6 +404,7 @@ static struct isst_platform_ops mbox_ops = { .get_trl_bucket_info = mbox_get_trl_bucket_info, .set_tdp_level = mbox_set_tdp_level, .get_pbf_info = mbox_get_pbf_info, + .set_pbf_fact_status = mbox_set_pbf_fact_status, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 41aa1adc20253..3765a1eefcc55 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -392,53 +392,8 @@ int isst_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info *pbf_i int isst_set_pbf_fact_status(struct isst_id *id, int pbf, int enable) { - struct isst_pkg_ctdp pkg_dev; - struct isst_pkg_ctdp_level_info ctdp_level; - int current_level; - unsigned int req = 0, resp; - int ret; - - ret = isst_get_ctdp_levels(id, &pkg_dev); - if (ret) - debug_printf("cpu:%d No support for dynamic ISST\n", id->cpu); - - current_level = pkg_dev.current_level; - - ret = isst_get_ctdp_control(id, current_level, &ctdp_level); - if (ret) - return ret; - - if (pbf) { - if (ctdp_level.fact_enabled) - req = BIT(16); - - if (enable) - req |= BIT(17); - else - req &= ~BIT(17); - } else { - - if (enable && !ctdp_level.sst_cp_enabled) - isst_display_error_info_message(0, "Make sure to execute before: core-power enable", 0, 0); - - if (ctdp_level.pbf_enabled) - req = BIT(17); - - if (enable) - req |= BIT(16); - else - req &= ~BIT(16); - } - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, - CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp); - if (ret) - return ret; - - debug_printf("cpu:%d CONFIG_TDP_SET_TDP_CONTROL pbf/fact:%d req:%x\n", - id->cpu, pbf, req); - - return 0; + CHECK_CB(set_pbf_fact_status); + return isst_ops->set_pbf_fact_status(id, pbf, enable); } int isst_get_fact_bucket_info(struct isst_id *id, int level, diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 06e089eaaa289..e8251a1c34cac 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -195,6 +195,7 @@ struct isst_platform_ops { int (*get_trl_bucket_info)(struct isst_id *id, int level, unsigned long long *buckets_info); int (*set_tdp_level)(struct isst_id *id, int tdp_level); int (*get_pbf_info)(struct isst_id *id, int level, struct isst_pbf_info *pbf_info); + int (*set_pbf_fact_status)(struct isst_id *id, int pbf, int enable); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From 7b5f586dcfdf94dad72a7f3569c100087b80a9ac Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 21:52:17 +0800 Subject: [PATCH 26/61] tools/power/x86/intel-speed-select: Abstract get_fact_info Allow platform specific implementation to get SST-TF info. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 92 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 88 +----------------- tools/power/x86/intel-speed-select/isst.h | 3 +- 3 files changed, 96 insertions(+), 87 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index e6d32786a6add..bf873dfe72e6a 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -390,6 +390,97 @@ static int mbox_set_pbf_fact_status(struct isst_id *id, int pbf, int enable) return 0; } +static int _get_fact_bucket_info(struct isst_id *id, int level, + struct isst_fact_bucket_info *bucket_info) +{ + unsigned int resp; + int i, k, ret; + + for (i = 0; i < 2; ++i) { + int j; + + ret = isst_send_mbox_command( + id->cpu, CONFIG_TDP, + CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES, 0, + (i << 8) | level, &resp); + if (ret) + return ret; + + debug_printf( + "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES index:%d level:%d resp:%x\n", + id->cpu, i, level, resp); + + for (j = 0; j < 4; ++j) { + bucket_info[j + (i * 4)].hp_cores = + (resp >> (j * 8)) & 0xff; + } + } + + for (k = 0; k < 3; ++k) { + for (i = 0; i < 2; ++i) { + int j; + + ret = isst_send_mbox_command( + id->cpu, CONFIG_TDP, + CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS, 0, + (k << 16) | (i << 8) | level, &resp); + if (ret) + return ret; + + debug_printf( + "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS index:%d level:%d avx:%d resp:%x\n", + id->cpu, i, level, k, resp); + + for (j = 0; j < 4; ++j) { + bucket_info[j + (i * 4)].hp_ratios[k] = + (resp >> (j * 8)) & 0xff; + } + } + } + + return 0; +} + +static int mbox_get_fact_info(struct isst_id *id, int level, int fact_bucket, struct isst_fact_info *fact_info) +{ + unsigned int resp; + int j, ret, print; + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0, + level, &resp); + if (ret) + return ret; + + debug_printf("cpu:%d CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO resp:%x\n", + id->cpu, resp); + + fact_info->lp_ratios[0] = resp & 0xff; + fact_info->lp_ratios[1] = (resp >> 8) & 0xff; + fact_info->lp_ratios[2] = (resp >> 16) & 0xff; + + ret = _get_fact_bucket_info(id, level, fact_info->bucket_info); + if (ret) + return ret; + + print = 0; + for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) { + if (fact_bucket != 0xff && fact_bucket != j) + continue; + + if (!fact_info->bucket_info[j].hp_cores) + break; + + print = 1; + } + if (!print) { + isst_display_error_info_message(1, "Invalid bucket", 0, 0); + return -1; + } + + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -405,6 +496,7 @@ static struct isst_platform_ops mbox_ops = { .set_tdp_level = mbox_set_tdp_level, .get_pbf_info = mbox_get_pbf_info, .set_pbf_fact_status = mbox_set_pbf_fact_status, + .get_fact_info = mbox_get_fact_info, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 3765a1eefcc55..e424693638035 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -396,63 +396,13 @@ int isst_set_pbf_fact_status(struct isst_id *id, int pbf, int enable) return isst_ops->set_pbf_fact_status(id, pbf, enable); } -int isst_get_fact_bucket_info(struct isst_id *id, int level, - struct isst_fact_bucket_info *bucket_info) -{ - unsigned int resp; - int i, k, ret; - - for (i = 0; i < 2; ++i) { - int j; - - ret = isst_send_mbox_command( - id->cpu, CONFIG_TDP, - CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES, 0, - (i << 8) | level, &resp); - if (ret) - return ret; - - debug_printf( - "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES index:%d level:%d resp:%x\n", - id->cpu, i, level, resp); - - for (j = 0; j < 4; ++j) { - bucket_info[j + (i * 4)].hp_cores = - (resp >> (j * 8)) & 0xff; - } - } - for (k = 0; k < 3; ++k) { - for (i = 0; i < 2; ++i) { - int j; - - ret = isst_send_mbox_command( - id->cpu, CONFIG_TDP, - CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS, 0, - (k << 16) | (i << 8) | level, &resp); - if (ret) - return ret; - - debug_printf( - "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS index:%d level:%d avx:%d resp:%x\n", - id->cpu, i, level, k, resp); - - for (j = 0; j < 4; ++j) { - bucket_info[j + (i * 4)].hp_ratios[k] = - (resp >> (j * 8)) & 0xff; - } - } - } - - return 0; -} int isst_get_fact_info(struct isst_id *id, int level, int fact_bucket, struct isst_fact_info *fact_info) { struct isst_pkg_ctdp_level_info ctdp_level; struct isst_pkg_ctdp pkg_dev; - unsigned int resp; - int j, ret, print; + int ret; ret = isst_get_ctdp_levels(id, &pkg_dev); if (ret) { @@ -473,40 +423,8 @@ int isst_get_fact_info(struct isst_id *id, int level, int fact_bucket, struct is isst_display_error_info_message(1, "turbo-freq feature is not present at this level", 1, level); return -1; } - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, - CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0, - level, &resp); - if (ret) - return ret; - - debug_printf("cpu:%d CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO resp:%x\n", - id->cpu, resp); - - fact_info->lp_ratios[0] = resp & 0xff; - fact_info->lp_ratios[1] = (resp >> 8) & 0xff; - fact_info->lp_ratios[2] = (resp >> 16) & 0xff; - - ret = isst_get_fact_bucket_info(id, level, fact_info->bucket_info); - if (ret) - return ret; - - print = 0; - for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) { - if (fact_bucket != 0xff && fact_bucket != j) - continue; - - if (!fact_info->bucket_info[j].hp_cores) - break; - - print = 1; - } - if (!print) { - isst_display_error_info_message(1, "Invalid bucket", 0, 0); - return -1; - } - - return 0; + CHECK_CB(get_fact_info); + return isst_ops->get_fact_info(id, level, fact_bucket, fact_info); } int isst_get_trl(struct isst_id *id, unsigned long long *trl) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index e8251a1c34cac..4fd901ef24376 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -196,6 +196,7 @@ struct isst_platform_ops { int (*set_tdp_level)(struct isst_id *id, int tdp_level); int (*get_pbf_info)(struct isst_id *id, int level, struct isst_pbf_info *pbf_info); int (*set_pbf_fact_status)(struct isst_id *id, int pbf, int enable); + int (*get_fact_info)(struct isst_id *id, int level, int fact_bucket, struct isst_fact_info *fact_info); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); @@ -256,8 +257,6 @@ extern int isst_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info *pbf_info); extern int isst_get_fact_info(struct isst_id *id, int level, int fact_bucket, struct isst_fact_info *fact_info); -extern int isst_get_fact_bucket_info(struct isst_id *id, int level, - struct isst_fact_bucket_info *bucket_info); extern void isst_fact_display_information(struct isst_id *id, FILE *outf, int level, int fact_bucket, int fact_avx, struct isst_fact_info *fact_info); From 00c26c1f7e3dfc0ec2e39deb1cffc2acad1d2ae4 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 00:28:41 +0800 Subject: [PATCH 27/61] tools/power/x86/intel-speed-select: Abstract get_uncore_p0_p1_info Allow platform specific implementation to get uncore frequency info. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 47 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 44 +---------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 50 insertions(+), 42 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index bf873dfe72e6a..466ed0934b425 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -102,6 +102,52 @@ static int mbox_get_ctdp_control(struct isst_id *id, int config_index, return 0; } +static void mbox_get_uncore_p0_p1_info(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + + ctdp_level->uncore_pm = 0; + ctdp_level->uncore_p0 = 0; + ctdp_level->uncore_p1 = 0; + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + CONFIG_TDP_GET_RATIO_INFO, 0, + (BIT(16) | config_index) , &resp); + if (ret) { + goto try_uncore_mbox; + } + + ctdp_level->uncore_p0 = resp & GENMASK(7, 0); + ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8; + ctdp_level->uncore_pm = (resp & GENMASK(31, 24)) >> 24; + + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_RATIO_INFO resp:%x uncore p0:%d uncore p1:%d uncore pm:%d\n", + id->cpu, config_index, resp, ctdp_level->uncore_p0, ctdp_level->uncore_p1, + ctdp_level->uncore_pm); + + return; + +try_uncore_mbox: + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + CONFIG_TDP_GET_UNCORE_P0_P1_INFO, 0, + config_index, &resp); + if (ret) { + ctdp_level->uncore_p0 = 0; + ctdp_level->uncore_p1 = 0; + return; + } + + ctdp_level->uncore_p0 = resp & GENMASK(7, 0); + ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8; + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_UNCORE_P0_P1_INFO resp:%x uncore p0:%d uncore p1:%d\n", + id->cpu, config_index, resp, ctdp_level->uncore_p0, + ctdp_level->uncore_p1); +} + static int mbox_get_tdp_info(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { @@ -497,6 +543,7 @@ static struct isst_platform_ops mbox_ops = { .get_pbf_info = mbox_get_pbf_info, .set_pbf_fact_status = mbox_set_pbf_fact_status, .get_fact_info = mbox_get_fact_info, + .get_uncore_p0_p1_info = mbox_get_uncore_p0_p1_info, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index e424693638035..5d0db84243614 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -521,47 +521,8 @@ void isst_get_process_ctdp_complete(struct isst_id *id, struct isst_pkg_ctdp *pk void isst_get_uncore_p0_p1_info(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { - unsigned int resp; - int ret; - - ctdp_level->uncore_pm = 0; - ctdp_level->uncore_p0 = 0; - ctdp_level->uncore_p1 = 0; - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, - CONFIG_TDP_GET_RATIO_INFO, 0, - (BIT(16) | config_index) , &resp); - if (ret) { - goto try_uncore_mbox; - } - - ctdp_level->uncore_p0 = resp & GENMASK(7, 0); - ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8; - ctdp_level->uncore_pm = (resp & GENMASK(31, 24)) >> 24; - - debug_printf( - "cpu:%d ctdp:%d CONFIG_TDP_GET_RATIO_INFO resp:%x uncore p0:%d uncore p1:%d uncore pm:%d\n", - id->cpu, config_index, resp, ctdp_level->uncore_p0, ctdp_level->uncore_p1, - ctdp_level->uncore_pm); - - return; - -try_uncore_mbox: - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, - CONFIG_TDP_GET_UNCORE_P0_P1_INFO, 0, - config_index, &resp); - if (ret) { - ctdp_level->uncore_p0 = 0; - ctdp_level->uncore_p1 = 0; - return; - } - - ctdp_level->uncore_p0 = resp & GENMASK(7, 0); - ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8; - debug_printf( - "cpu:%d ctdp:%d CONFIG_TDP_GET_UNCORE_P0_P1_INFO resp:%x uncore p0:%d uncore p1:%d\n", - id->cpu, config_index, resp, ctdp_level->uncore_p0, - ctdp_level->uncore_p1); + CHECK_CB(get_uncore_p0_p1_info); + return isst_ops->get_uncore_p0_p1_info(id, config_index, ctdp_level); } void isst_get_p1_info(struct isst_id *id, int config_index, @@ -719,7 +680,6 @@ int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctd if (ret) return ret; } - isst_get_uncore_p0_p1_info(id, i, ctdp_level); isst_get_p1_info(id, i, ctdp_level); isst_get_uncore_mem_freq(id, i, ctdp_level); diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 4fd901ef24376..e113a2bef4044 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -197,6 +197,7 @@ struct isst_platform_ops { int (*get_pbf_info)(struct isst_id *id, int level, struct isst_pbf_info *pbf_info); int (*set_pbf_fact_status)(struct isst_id *id, int pbf, int enable); int (*get_fact_info)(struct isst_id *id, int level, int fact_bucket, struct isst_fact_info *fact_info); + void (*get_uncore_p0_p1_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From 855932831511eef31b5e71c3b6155fd8c57e2a0b Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 2 Feb 2023 14:14:54 +0800 Subject: [PATCH 28/61] tools/power/x86/intel-speed-select: Enhance get_tdp_info mbox_get_uncore_p0_p1_info/get_p1_info/get_uncore_mem_freq can be done inside get_tdp_info(). Fold the code into get_tdp_info(). No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 60 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 59 ------------------ 2 files changed, 60 insertions(+), 59 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 466ed0934b425..8d62bafcaca5a 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -148,6 +148,62 @@ static void mbox_get_uncore_p0_p1_info(struct isst_id *id, int config_index, ctdp_level->uncore_p1); } +static void _get_p1_info(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0, + config_index, &resp); + if (ret) { + ctdp_level->sse_p1 = 0; + ctdp_level->avx2_p1 = 0; + ctdp_level->avx512_p1 = 0; + return; + } + + ctdp_level->sse_p1 = resp & GENMASK(7, 0); + ctdp_level->avx2_p1 = (resp & GENMASK(15, 8)) >> 8; + ctdp_level->avx512_p1 = (resp & GENMASK(23, 16)) >> 16; + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d\n", + id->cpu, config_index, resp, ctdp_level->sse_p1, + ctdp_level->avx2_p1, ctdp_level->avx512_p1); +} + +static void _get_uncore_mem_freq(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + + ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ, + 0, config_index, &resp); + if (ret) { + ctdp_level->mem_freq = 0; + return; + } + + ctdp_level->mem_freq = resp & GENMASK(7, 0); + if (is_spr_platform()) { + ctdp_level->mem_freq *= 200; + } else if (is_icx_platform()) { + if (ctdp_level->mem_freq < 7) { + ctdp_level->mem_freq = (12 - ctdp_level->mem_freq) * 133.33 * 2 * 10; + ctdp_level->mem_freq /= 10; + if (ctdp_level->mem_freq % 10 > 5) + ctdp_level->mem_freq++; + } else { + ctdp_level->mem_freq = 0; + } + } else { + ctdp_level->mem_freq = 0; + } + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_MEM_FREQ resp:%x uncore mem_freq:%d\n", + id->cpu, config_index, resp, ctdp_level->mem_freq); +} + static int mbox_get_tdp_info(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { @@ -176,6 +232,10 @@ static int mbox_get_tdp_info(struct isst_id *id, int config_index, ctdp_level->t_proc_hot = resp & GENMASK(7, 0); + mbox_get_uncore_p0_p1_info(id, config_index, ctdp_level); + _get_p1_info(id, config_index, ctdp_level); + _get_uncore_mem_freq(id, config_index, ctdp_level); + debug_printf( "cpu:%d ctdp:%d CONFIG_TDP_GET_TJMAX_INFO resp:%x t_proc_hot:%d\n", id->cpu, config_index, resp, ctdp_level->t_proc_hot); diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 5d0db84243614..27049e283eb32 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -525,62 +525,6 @@ void isst_get_uncore_p0_p1_info(struct isst_id *id, int config_index, return isst_ops->get_uncore_p0_p1_info(id, config_index, ctdp_level); } -void isst_get_p1_info(struct isst_id *id, int config_index, - struct isst_pkg_ctdp_level_info *ctdp_level) -{ - unsigned int resp; - int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0, - config_index, &resp); - if (ret) { - ctdp_level->sse_p1 = 0; - ctdp_level->avx2_p1 = 0; - ctdp_level->avx512_p1 = 0; - return; - } - - ctdp_level->sse_p1 = resp & GENMASK(7, 0); - ctdp_level->avx2_p1 = (resp & GENMASK(15, 8)) >> 8; - ctdp_level->avx512_p1 = (resp & GENMASK(23, 16)) >> 16; - debug_printf( - "cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d\n", - id->cpu, config_index, resp, ctdp_level->sse_p1, - ctdp_level->avx2_p1, ctdp_level->avx512_p1); -} - -void isst_get_uncore_mem_freq(struct isst_id *id, int config_index, - struct isst_pkg_ctdp_level_info *ctdp_level) -{ - unsigned int resp; - int ret; - - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ, - 0, config_index, &resp); - if (ret) { - ctdp_level->mem_freq = 0; - return; - } - - ctdp_level->mem_freq = resp & GENMASK(7, 0); - if (is_spr_platform()) { - ctdp_level->mem_freq *= 200; - } else if (is_icx_platform()) { - if (ctdp_level->mem_freq < 7) { - ctdp_level->mem_freq = (12 - ctdp_level->mem_freq) * 133.33 * 2 * 10; - ctdp_level->mem_freq /= 10; - if (ctdp_level->mem_freq % 10 > 5) - ctdp_level->mem_freq++; - } else { - ctdp_level->mem_freq = 0; - } - } else { - ctdp_level->mem_freq = 0; - } - debug_printf( - "cpu:%d ctdp:%d CONFIG_TDP_GET_MEM_FREQ resp:%x uncore mem_freq:%d\n", - id->cpu, config_index, resp, ctdp_level->mem_freq); -} - int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctdp *pkg_dev) { int i, ret, valid = 0; @@ -680,9 +624,6 @@ int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctd if (ret) return ret; } - isst_get_uncore_p0_p1_info(id, i, ctdp_level); - isst_get_p1_info(id, i, ctdp_level); - isst_get_uncore_mem_freq(id, i, ctdp_level); } if (!valid) From 4a17b29188734f6ec4d9835d74a7489e3409c692 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 9 Aug 2022 01:52:11 +0800 Subject: [PATCH 29/61] tools/power/x86/intel-speed-select: Abstract get_get_trls Allow platform specific implementation to get turbo ratio limits of each AVX level, for a selected SST-PP level. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 14 ++++++++++++++ tools/power/x86/intel-speed-select/isst-core.c | 17 +++++++++-------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 8d62bafcaca5a..2ea7ef4ef446f 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -338,6 +338,19 @@ static int mbox_get_get_trl(struct isst_id *id, int level, int avx_level, int *t return 0; } +static int mbox_get_get_trls(struct isst_id *id, int level, struct isst_pkg_ctdp_level_info *ctdp_level) +{ + int trl_max_levels = isst_get_trl_max_levels(); + int i, ret; + + for (i = 0; i < trl_max_levels; i++) { + ret = mbox_get_get_trl(id, level, i, ctdp_level->trl_ratios[i]); + if (ret) + return ret; + } + return 0; +} + static int mbox_get_trl_bucket_info(struct isst_id *id, int level, unsigned long long *buckets_info) { int ret; @@ -598,6 +611,7 @@ static struct isst_platform_ops mbox_ops = { .get_pwr_info = mbox_get_pwr_info, .get_coremask_info = mbox_get_coremask_info, .get_get_trl = mbox_get_get_trl, + .get_get_trls = mbox_get_get_trls, .get_trl_bucket_info = mbox_get_trl_bucket_info, .set_tdp_level = mbox_set_tdp_level, .get_pbf_info = mbox_get_pbf_info, diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 27049e283eb32..f4e3a91dc4c2e 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -346,6 +346,12 @@ int isst_get_get_trl(struct isst_id *id, int level, int avx_level, int *trl) return isst_ops->get_get_trl(id, level, avx_level, trl); } +int isst_get_get_trls(struct isst_id *id, int level, struct isst_pkg_ctdp_level_info *ctdp_level) +{ + CHECK_CB(get_get_trls); + return isst_ops->get_get_trls(id, level, ctdp_level); +} + int isst_get_trl_bucket_info(struct isst_id *id, int level, unsigned long long *buckets_info) { CHECK_CB(get_trl_bucket_info); @@ -550,8 +556,6 @@ int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctd for (i = 0; i <= pkg_dev->levels; ++i) { struct isst_pkg_ctdp_level_info *ctdp_level; - int trl_max_levels = isst_get_trl_max_levels(); - int j; if (tdp_level != 0xff && i != tdp_level) continue; @@ -618,12 +622,9 @@ int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctd if (ret) return ret; - for (j = 0; j < trl_max_levels; j++) { - ret = isst_get_get_trl(id, i, j, - ctdp_level->trl_ratios[j]); - if (ret) - return ret; - } + ret = isst_get_get_trls(id, i, ctdp_level); + if (ret) + return ret; } if (!valid) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index e113a2bef4044..b17fcf7375607 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -192,6 +192,7 @@ struct isst_platform_ops { int (*get_pwr_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_coremask_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_get_trl)(struct isst_id *id, int level, int avx_level, int *trl); + int (*get_get_trls)(struct isst_id *id, int level, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_trl_bucket_info)(struct isst_id *id, int level, unsigned long long *buckets_info); int (*set_tdp_level)(struct isst_id *id, int tdp_level); int (*get_pbf_info)(struct isst_id *id, int level, struct isst_pbf_info *pbf_info); From a07bdb81c1434f41eb444e51c2a4028ca2d21b30 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 22:42:47 +0800 Subject: [PATCH 30/61] tools/power/x86/intel-speed-select: Abstract get_clos_information Allow platform specific implementation to get CLOS config setting. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 25 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 23 ++--------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 2ea7ef4ef446f..a96d6bcf7d930 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -600,6 +600,30 @@ static int mbox_get_fact_info(struct isst_id *id, int level, int fact_bucket, st return 0; } +static int mbox_get_clos_information(struct isst_id *id, int *enable, int *type) +{ + unsigned int resp; + int ret; + + ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, + &resp); + if (ret) + return ret; + + debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", id->cpu, resp); + + if (resp & BIT(1)) + *enable = 1; + else + *enable = 0; + + if (resp & BIT(2)) + *type = 1; + else + *type = 0; + + return 0; +} static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -618,6 +642,7 @@ static struct isst_platform_ops mbox_ops = { .set_pbf_fact_status = mbox_set_pbf_fact_status, .get_fact_info = mbox_get_fact_info, .get_uncore_p0_p1_info = mbox_get_uncore_p0_p1_info, + .get_clos_information = mbox_get_clos_information, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index f4e3a91dc4c2e..33ee086458e98 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -635,27 +635,8 @@ int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctd int isst_clos_get_clos_information(struct isst_id *id, int *enable, int *type) { - unsigned int resp; - int ret; - - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, - &resp); - if (ret) - return ret; - - debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", id->cpu, resp); - - if (resp & BIT(1)) - *enable = 1; - else - *enable = 0; - - if (resp & BIT(2)) - *type = 1; - else - *type = 0; - - return 0; + CHECK_CB(get_clos_information); + return isst_ops->get_clos_information(id, enable, type); } int isst_pm_qos_config(struct isst_id *id, int enable_clos, int priority_type) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index b17fcf7375607..d6cbc0bcc1e31 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -199,6 +199,7 @@ struct isst_platform_ops { int (*set_pbf_fact_status)(struct isst_id *id, int pbf, int enable); int (*get_fact_info)(struct isst_id *id, int level, int fact_bucket, struct isst_fact_info *fact_info); void (*get_uncore_p0_p1_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); + int (*get_clos_information)(struct isst_id *id, int *enable, int *type); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From 904d2baa8b04691613a5e1e94061f99f0db2832c Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 22:46:57 +0800 Subject: [PATCH 31/61] tools/power/x86/intel-speed-select: Abstract pm_qos_config Allow platform specific implementation to set CLOS config settings. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 90 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 86 +----------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 93 insertions(+), 84 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index a96d6bcf7d930..27d802173d101 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -624,6 +624,95 @@ static int mbox_get_clos_information(struct isst_id *id, int *enable, int *type) return 0; } + +static int _write_pm_config(struct isst_id *id, int cp_state) +{ + unsigned int req, resp; + int ret; + + if (cp_state) + req = BIT(16); + else + req = 0; + + ret = isst_send_mbox_command(id->cpu, WRITE_PM_CONFIG, PM_FEATURE, 0, req, + &resp); + if (ret) + return ret; + + debug_printf("cpu:%d WRITE_PM_CONFIG resp:%x\n", id->cpu, resp); + + return 0; +} + +static int mbox_pm_qos_config(struct isst_id *id, int enable_clos, int priority_type) +{ + unsigned int req, resp; + int ret; + + if (!enable_clos) { + struct isst_pkg_ctdp pkg_dev; + struct isst_pkg_ctdp_level_info ctdp_level; + + ret = isst_get_ctdp_levels(id, &pkg_dev); + if (ret) { + debug_printf("isst_get_ctdp_levels\n"); + return ret; + } + + ret = isst_get_ctdp_control(id, pkg_dev.current_level, + &ctdp_level); + if (ret) + return ret; + + if (ctdp_level.fact_enabled) { + isst_display_error_info_message(1, "Ignoring request, turbo-freq feature is still enabled", 0, 0); + return -EINVAL; + } + ret = _write_pm_config(id, 0); + if (ret) + isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0); + } else { + ret = _write_pm_config(id, 1); + if (ret) + isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0); + } + + ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, + &resp); + if (ret) { + isst_display_error_info_message(1, "CLOS_PM_QOS_CONFIG command failed", 0, 0); + return ret; + } + + debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", id->cpu, resp); + + req = resp; + + if (enable_clos) + req = req | BIT(1); + else + req = req & ~BIT(1); + + if (priority_type > 1) + isst_display_error_info_message(1, "Invalid priority type: Changing type to ordered", 0, 0); + + if (priority_type) + req = req | BIT(2); + else + req = req & ~BIT(2); + + ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, + BIT(MBOX_CMD_WRITE_BIT), req, &resp); + if (ret) + return ret; + + debug_printf("cpu:%d CLOS_PM_QOS_CONFIG priority type:%d req:%x\n", id->cpu, + priority_type, req); + + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -643,6 +732,7 @@ static struct isst_platform_ops mbox_ops = { .get_fact_info = mbox_get_fact_info, .get_uncore_p0_p1_info = mbox_get_uncore_p0_p1_info, .get_clos_information = mbox_get_clos_information, + .pm_qos_config = mbox_pm_qos_config, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 33ee086458e98..39b9842ee6666 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -247,26 +247,6 @@ int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write, return 0; } -int isst_write_pm_config(struct isst_id *id, int cp_state) -{ - unsigned int req, resp; - int ret; - - if (cp_state) - req = BIT(16); - else - req = 0; - - ret = isst_send_mbox_command(id->cpu, WRITE_PM_CONFIG, PM_FEATURE, 0, req, - &resp); - if (ret) - return ret; - - debug_printf("cpu:%d WRITE_PM_CONFIG resp:%x\n", id->cpu, resp); - - return 0; -} - int isst_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap) { unsigned int resp; @@ -641,70 +621,8 @@ int isst_clos_get_clos_information(struct isst_id *id, int *enable, int *type) int isst_pm_qos_config(struct isst_id *id, int enable_clos, int priority_type) { - unsigned int req, resp; - int ret; - - if (!enable_clos) { - struct isst_pkg_ctdp pkg_dev; - struct isst_pkg_ctdp_level_info ctdp_level; - - ret = isst_get_ctdp_levels(id, &pkg_dev); - if (ret) { - debug_printf("isst_get_ctdp_levels\n"); - return ret; - } - - ret = isst_get_ctdp_control(id, pkg_dev.current_level, - &ctdp_level); - if (ret) - return ret; - - if (ctdp_level.fact_enabled) { - isst_display_error_info_message(1, "Ignoring request, turbo-freq feature is still enabled", 0, 0); - return -EINVAL; - } - ret = isst_write_pm_config(id, 0); - if (ret) - isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0); - } else { - ret = isst_write_pm_config(id, 1); - if (ret) - isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0); - } - - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, - &resp); - if (ret) { - isst_display_error_info_message(1, "CLOS_PM_QOS_CONFIG command failed", 0, 0); - return ret; - } - - debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", id->cpu, resp); - - req = resp; - - if (enable_clos) - req = req | BIT(1); - else - req = req & ~BIT(1); - - if (priority_type > 1) - isst_display_error_info_message(1, "Invalid priority type: Changing type to ordered", 0, 0); - - if (priority_type) - req = req | BIT(2); - else - req = req & ~BIT(2); - - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, - BIT(MBOX_CMD_WRITE_BIT), req, &resp); - if (ret) - return ret; - - debug_printf("cpu:%d CLOS_PM_QOS_CONFIG priority type:%d req:%x\n", id->cpu, - priority_type, req); - - return 0; + CHECK_CB(pm_qos_config); + return isst_ops->pm_qos_config(id, enable_clos, priority_type); } int isst_pm_get_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_config) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index d6cbc0bcc1e31..1f60acef0950b 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -200,6 +200,7 @@ struct isst_platform_ops { int (*get_fact_info)(struct isst_id *id, int level, int fact_bucket, struct isst_fact_info *fact_info); void (*get_uncore_p0_p1_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_clos_information)(struct isst_id *id, int *enable, int *type); + int (*pm_qos_config)(struct isst_id *id, int enable_clos, int priority_type); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From 43314e798c92b93b6f899c4dc9e027652990bdbc Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 22:50:28 +0800 Subject: [PATCH 32/61] tools/power/x86/intel-speed-select: Abstract pm_get_clos Allow platform specific implementation to get CLOS priority setting. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 20 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 17 ++-------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 27d802173d101..6a6298e3a8955 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -713,6 +713,25 @@ static int mbox_pm_qos_config(struct isst_id *id, int enable_clos, int priority_ return 0; } +static int mbox_pm_get_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_config) +{ + unsigned int resp; + int ret; + + ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0, + &resp); + if (ret) + return ret; + + clos_config->epp = resp & 0x0f; + clos_config->clos_prop_prio = (resp >> 4) & 0x0f; + clos_config->clos_min = (resp >> 8) & 0xff; + clos_config->clos_max = (resp >> 16) & 0xff; + clos_config->clos_desired = (resp >> 24) & 0xff; + + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -733,6 +752,7 @@ static struct isst_platform_ops mbox_ops = { .get_uncore_p0_p1_info = mbox_get_uncore_p0_p1_info, .get_clos_information = mbox_get_clos_information, .pm_qos_config = mbox_pm_qos_config, + .pm_get_clos = mbox_pm_get_clos, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 39b9842ee6666..11a07eb4aaf09 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -627,21 +627,8 @@ int isst_pm_qos_config(struct isst_id *id, int enable_clos, int priority_type) int isst_pm_get_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_config) { - unsigned int resp; - int ret; - - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0, - &resp); - if (ret) - return ret; - - clos_config->epp = resp & 0x0f; - clos_config->clos_prop_prio = (resp >> 4) & 0x0f; - clos_config->clos_min = (resp >> 8) & 0xff; - clos_config->clos_max = (resp >> 16) & 0xff; - clos_config->clos_desired = (resp >> 24) & 0xff; - - return 0; + CHECK_CB(pm_get_clos); + return isst_ops->pm_get_clos(id, clos, clos_config); } int isst_set_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_config) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 1f60acef0950b..99a0d92d36e16 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -201,6 +201,7 @@ struct isst_platform_ops { void (*get_uncore_p0_p1_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_clos_information)(struct isst_id *id, int *enable, int *type); int (*pm_qos_config)(struct isst_id *id, int enable_clos, int priority_type); + int (*pm_get_clos)(struct isst_id *id, int clos, struct isst_clos_config *clos_config); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From 33dbf360db5fbc09ea1d4962a964d57b5f6004f8 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 22:53:48 +0800 Subject: [PATCH 33/61] tools/power/x86/intel-speed-select: Abstract set_clos Allow platform specific implementation to set CLOS priority setting. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 25 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 22 ++-------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 6a6298e3a8955..3490315034d04 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -732,6 +732,30 @@ static int mbox_pm_get_clos(struct isst_id *id, int clos, struct isst_clos_confi return 0; } +static int mbox_set_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_config) +{ + unsigned int req, resp; + unsigned int param; + int ret; + + req = clos_config->epp & 0x0f; + req |= (clos_config->clos_prop_prio & 0x0f) << 4; + req |= (clos_config->clos_min & 0xff) << 8; + req |= (clos_config->clos_max & 0xff) << 16; + req |= (clos_config->clos_desired & 0xff) << 24; + + param = BIT(MBOX_CMD_WRITE_BIT) | clos; + + ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req, + &resp); + if (ret) + return ret; + + debug_printf("cpu:%d CLOS_PM_CLOS param:%x req:%x\n", id->cpu, param, req); + + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -753,6 +777,7 @@ static struct isst_platform_ops mbox_ops = { .get_clos_information = mbox_get_clos_information, .pm_qos_config = mbox_pm_qos_config, .pm_get_clos = mbox_pm_get_clos, + .set_clos = mbox_set_clos, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 11a07eb4aaf09..a901c63f73551 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -633,26 +633,8 @@ int isst_pm_get_clos(struct isst_id *id, int clos, struct isst_clos_config *clos int isst_set_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_config) { - unsigned int req, resp; - unsigned int param; - int ret; - - req = clos_config->epp & 0x0f; - req |= (clos_config->clos_prop_prio & 0x0f) << 4; - req |= (clos_config->clos_min & 0xff) << 8; - req |= (clos_config->clos_max & 0xff) << 16; - req |= (clos_config->clos_desired & 0xff) << 24; - - param = BIT(MBOX_CMD_WRITE_BIT) | clos; - - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req, - &resp); - if (ret) - return ret; - - debug_printf("cpu:%d CLOS_PM_CLOS param:%x req:%x\n", id->cpu, param, req); - - return 0; + CHECK_CB(set_clos); + return isst_ops->set_clos(id, clos, clos_config); } int isst_clos_get_assoc_status(struct isst_id *id, int *clos_id) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 99a0d92d36e16..5db3fc5487a69 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -202,6 +202,7 @@ struct isst_platform_ops { int (*get_clos_information)(struct isst_id *id, int *enable, int *type); int (*pm_qos_config)(struct isst_id *id, int enable_clos, int priority_type); int (*pm_get_clos)(struct isst_id *id, int clos, struct isst_clos_config *clos_config); + int (*set_clos)(struct isst_id *id, int clos, struct isst_clos_config *clos_config); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From b161bbad6db9a1e8d7cada5bf91b21340af7b163 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 22:55:51 +0800 Subject: [PATCH 34/61] tools/power/x86/intel-speed-select: Abstract clos_get_assoc_status Allow platform specific implementation to get per core CLOS setting. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 21 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 19 ++--------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 3490315034d04..4e86cce92585e 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -756,6 +756,26 @@ static int mbox_set_clos(struct isst_id *id, int clos, struct isst_clos_config * return 0; } +static int mbox_clos_get_assoc_status(struct isst_id *id, int *clos_id) +{ + unsigned int resp; + unsigned int param; + int core_id, ret; + + core_id = find_phy_core_num(id->cpu); + param = core_id; + + ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0, + &resp); + if (ret) + return ret; + + debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x resp:%x\n", id->cpu, param, + resp); + *clos_id = (resp >> 16) & 0x03; + + return 0; +} static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -778,6 +798,7 @@ static struct isst_platform_ops mbox_ops = { .pm_qos_config = mbox_pm_qos_config, .pm_get_clos = mbox_pm_get_clos, .set_clos = mbox_set_clos, + .clos_get_assoc_status = mbox_clos_get_assoc_status, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index a901c63f73551..c00622461c624 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -639,23 +639,8 @@ int isst_set_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_co int isst_clos_get_assoc_status(struct isst_id *id, int *clos_id) { - unsigned int resp; - unsigned int param; - int core_id, ret; - - core_id = find_phy_core_num(id->cpu); - param = core_id; - - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0, - &resp); - if (ret) - return ret; - - debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x resp:%x\n", id->cpu, param, - resp); - *clos_id = (resp >> 16) & 0x03; - - return 0; + CHECK_CB(clos_get_assoc_status); + return isst_ops->clos_get_assoc_status(id, clos_id); } int isst_clos_associate(struct isst_id *id, int clos_id) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 5db3fc5487a69..5794b31beafcc 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -203,6 +203,7 @@ struct isst_platform_ops { int (*pm_qos_config)(struct isst_id *id, int enable_clos, int priority_type); int (*pm_get_clos)(struct isst_id *id, int clos, struct isst_clos_config *clos_config); int (*set_clos)(struct isst_id *id, int clos, struct isst_clos_config *clos_config); + int (*clos_get_assoc_status)(struct isst_id *id, int *clos_id); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From a59a6c0cadd5f0d9a6837b7f62300f7985ea0de3 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 22:57:55 +0800 Subject: [PATCH 35/61] tools/power/x86/intel-speed-select: Abstract clos_associate Allow platform specific implementation to set per core CLOS setting. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 23 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 18 ++------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 4e86cce92585e..ca43cfc48b17f 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -776,6 +776,28 @@ static int mbox_clos_get_assoc_status(struct isst_id *id, int *clos_id) return 0; } + +static int mbox_clos_associate(struct isst_id *id, int clos_id) +{ + unsigned int req, resp; + unsigned int param; + int core_id, ret; + + req = (clos_id & 0x03) << 16; + core_id = find_phy_core_num(id->cpu); + param = BIT(MBOX_CMD_WRITE_BIT) | core_id; + + ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, + req, &resp); + if (ret) + return ret; + + debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x req:%x\n", id->cpu, param, + req); + + return 0; +} + static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, @@ -799,6 +821,7 @@ static struct isst_platform_ops mbox_ops = { .pm_get_clos = mbox_pm_get_clos, .set_clos = mbox_set_clos, .clos_get_assoc_status = mbox_clos_get_assoc_status, + .clos_associate = mbox_clos_associate, }; struct isst_platform_ops *mbox_get_platform_ops(void) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index c00622461c624..8ef71a8112be3 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -645,21 +645,7 @@ int isst_clos_get_assoc_status(struct isst_id *id, int *clos_id) int isst_clos_associate(struct isst_id *id, int clos_id) { - unsigned int req, resp; - unsigned int param; - int core_id, ret; + CHECK_CB(clos_associate); + return isst_ops->clos_associate(id, clos_id); - req = (clos_id & 0x03) << 16; - core_id = find_phy_core_num(id->cpu); - param = BIT(MBOX_CMD_WRITE_BIT) | core_id; - - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, - req, &resp); - if (ret) - return ret; - - debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x req:%x\n", id->cpu, param, - req); - - return 0; } diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 5794b31beafcc..752991ec70554 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -204,6 +204,7 @@ struct isst_platform_ops { int (*pm_get_clos)(struct isst_id *id, int clos, struct isst_clos_config *clos_config); int (*set_clos)(struct isst_id *id, int clos, struct isst_clos_config *clos_config); int (*clos_get_assoc_status)(struct isst_id *id, int *clos_id); + int (*clos_associate)(struct isst_id *id, int clos_id); }; extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); From 8f54104f7a9548466027e1ee8482b18c2a72656a Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 8 Aug 2022 23:19:55 +0800 Subject: [PATCH 36/61] tools/power/x86/intel-speed-select: Abstract read_pm_config Allow platform specific implementation to get SST-CP capability and current state. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 19 +++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 16 ++-------------- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index ca43cfc48b17f..2169ceddebeb5 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -40,6 +40,24 @@ static int mbox_is_punit_valid(struct isst_id *id) return 1; } +static int mbox_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap) +{ + unsigned int resp; + int ret; + + ret = isst_send_mbox_command(id->cpu, READ_PM_CONFIG, PM_FEATURE, 0, 0, + &resp); + if (ret) + return ret; + + debug_printf("cpu:%d READ_PM_CONFIG resp:%x\n", id->cpu, resp); + + *cp_state = resp & BIT(16); + *cp_cap = resp & BIT(0) ? 1 : 0; + + return 0; +} + static int mbox_get_config_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev) { unsigned int resp; @@ -803,6 +821,7 @@ static struct isst_platform_ops mbox_ops = { .get_trl_max_levels = mbox_get_trl_max_levels, .get_trl_level_name = mbox_get_trl_level_name, .is_punit_valid = mbox_is_punit_valid, + .read_pm_config = mbox_read_pm_config, .get_config_levels = mbox_get_config_levels, .get_ctdp_control = mbox_get_ctdp_control, .get_tdp_info = mbox_get_tdp_info, diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 8ef71a8112be3..c31ab8f5f6dc2 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -249,20 +249,8 @@ int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write, int isst_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap) { - unsigned int resp; - int ret; - - ret = isst_send_mbox_command(id->cpu, READ_PM_CONFIG, PM_FEATURE, 0, 0, - &resp); - if (ret) - return ret; - - debug_printf("cpu:%d READ_PM_CONFIG resp:%x\n", id->cpu, resp); - - *cp_state = resp & BIT(16); - *cp_cap = resp & BIT(0) ? 1 : 0; - - return 0; + CHECK_CB(read_pm_config); + return isst_ops->read_pm_config(id, cp_state, cp_cap); } int isst_get_ctdp_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 752991ec70554..c64af51a44aaf 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -186,6 +186,7 @@ struct isst_platform_ops { int (*get_trl_max_levels)(void); char *(*get_trl_level_name)(int level); int (*is_punit_valid)(struct isst_id *id); + int (*read_pm_config)(struct isst_id *id, int *cp_state, int *cp_cap); int (*get_config_levels)(struct isst_id *id, struct isst_pkg_ctdp *pkg_ctdp); int (*get_ctdp_control)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_tdp_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); From 73452ccc190a416929ccf7da4061365a5eaff627 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 2 Feb 2023 15:52:42 +0800 Subject: [PATCH 37/61] tools/power/x86/intel-speed-select: Abstract adjust_uncore_freq Allow platform specific implementation to adjust the uncore frequency. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-config.c | 35 +-------------- .../x86/intel-speed-select/isst-core-mbox.c | 45 +++++++++++++++++-- .../power/x86/intel-speed-select/isst-core.c | 6 +-- tools/power/x86/intel-speed-select/isst.h | 4 +- 4 files changed, 48 insertions(+), 42 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 71e00d03062f8..346f8271b00ff 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1187,34 +1187,6 @@ static void dump_isst_config(int arg) isst_ctdp_display_information_end(outf); } -static int set_uncore_min_max(struct isst_id *id, int max, int freq) -{ - char buffer[128], freq_str[16]; - int fd, ret, len; - - if (max) - snprintf(buffer, sizeof(buffer), - "/sys/devices/system/cpu/intel_uncore_frequency/package_%02d_die_%02d/max_freq_khz", id->pkg, id->die); - else - snprintf(buffer, sizeof(buffer), - "/sys/devices/system/cpu/intel_uncore_frequency/package_%02d_die_%02d/min_freq_khz", id->pkg, id->die); - - fd = open(buffer, O_WRONLY); - if (fd < 0) - return fd; - - snprintf(freq_str, sizeof(freq_str), "%d", freq); - len = strlen(freq_str); - ret = write(fd, freq_str, len); - if (ret == -1) { - close(fd); - return ret; - } - close(fd); - - return 0; -} - static void adjust_scaling_max_from_base_freq(int cpu); static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3, @@ -1237,12 +1209,7 @@ static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, vo usleep(2000); /* Adjusting uncore freq */ - isst_get_uncore_p0_p1_info(id, tdp_level, &ctdp_level); - if (ctdp_level.uncore_pm) - set_uncore_min_max(id, 0, ctdp_level.uncore_pm * 100000); - - if (ctdp_level.uncore_p0) - set_uncore_min_max(id, 1, ctdp_level.uncore_p0 * 100000); + isst_adjust_uncore_freq(id, tdp_level, &ctdp_level); fprintf(stderr, "Option is set to online/offline\n"); ctdp_level.core_cpumask_size = diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 2169ceddebeb5..8e224d154e040 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -120,7 +120,7 @@ static int mbox_get_ctdp_control(struct isst_id *id, int config_index, return 0; } -static void mbox_get_uncore_p0_p1_info(struct isst_id *id, int config_index, +static void _get_uncore_p0_p1_info(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { unsigned int resp; @@ -166,6 +166,45 @@ static void mbox_get_uncore_p0_p1_info(struct isst_id *id, int config_index, ctdp_level->uncore_p1); } +static int _set_uncore_min_max(struct isst_id *id, int max, int freq) +{ + char buffer[128], freq_str[16]; + int fd, ret, len; + + if (max) + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/intel_uncore_frequency/package_%02d_die_%02d/max_freq_khz", id->pkg, id->die); + else + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/intel_uncore_frequency/package_%02d_die_%02d/min_freq_khz", id->pkg, id->die); + + fd = open(buffer, O_WRONLY); + if (fd < 0) + return fd; + + snprintf(freq_str, sizeof(freq_str), "%d", freq); + len = strlen(freq_str); + ret = write(fd, freq_str, len); + if (ret == -1) { + close(fd); + return ret; + } + close(fd); + + return 0; +} + +static void mbox_adjust_uncore_freq(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + _get_uncore_p0_p1_info(id, config_index, ctdp_level); + if (ctdp_level->uncore_pm) + _set_uncore_min_max(id, 0, ctdp_level->uncore_pm * 100000); + + if (ctdp_level->uncore_p0) + _set_uncore_min_max(id, 1, ctdp_level->uncore_p0 * 100000); +} + static void _get_p1_info(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { @@ -250,7 +289,7 @@ static int mbox_get_tdp_info(struct isst_id *id, int config_index, ctdp_level->t_proc_hot = resp & GENMASK(7, 0); - mbox_get_uncore_p0_p1_info(id, config_index, ctdp_level); + _get_uncore_p0_p1_info(id, config_index, ctdp_level); _get_p1_info(id, config_index, ctdp_level); _get_uncore_mem_freq(id, config_index, ctdp_level); @@ -834,7 +873,7 @@ static struct isst_platform_ops mbox_ops = { .get_pbf_info = mbox_get_pbf_info, .set_pbf_fact_status = mbox_set_pbf_fact_status, .get_fact_info = mbox_get_fact_info, - .get_uncore_p0_p1_info = mbox_get_uncore_p0_p1_info, + .adjust_uncore_freq = mbox_adjust_uncore_freq, .get_clos_information = mbox_get_clos_information, .pm_qos_config = mbox_pm_qos_config, .pm_get_clos = mbox_pm_get_clos, diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index c31ab8f5f6dc2..24b2c041bfe0c 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -492,11 +492,11 @@ void isst_get_process_ctdp_complete(struct isst_id *id, struct isst_pkg_ctdp *pk } } -void isst_get_uncore_p0_p1_info(struct isst_id *id, int config_index, +void isst_adjust_uncore_freq(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { - CHECK_CB(get_uncore_p0_p1_info); - return isst_ops->get_uncore_p0_p1_info(id, config_index, ctdp_level); + CHECK_CB(adjust_uncore_freq); + return isst_ops->adjust_uncore_freq(id, config_index, ctdp_level); } int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctdp *pkg_dev) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index c64af51a44aaf..8192e683ac922 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -199,7 +199,7 @@ struct isst_platform_ops { int (*get_pbf_info)(struct isst_id *id, int level, struct isst_pbf_info *pbf_info); int (*set_pbf_fact_status)(struct isst_id *id, int pbf, int enable); int (*get_fact_info)(struct isst_id *id, int level, int fact_bucket, struct isst_fact_info *fact_info); - void (*get_uncore_p0_p1_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); + void (*adjust_uncore_freq)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); int (*get_clos_information)(struct isst_id *id, int *enable, int *type); int (*pm_qos_config)(struct isst_id *id, int enable_clos, int priority_type); int (*pm_get_clos)(struct isst_id *id, int clos, struct isst_clos_config *clos_config); @@ -246,7 +246,7 @@ extern int isst_get_ctdp_control(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); extern int isst_get_coremask_info(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); -extern void isst_get_uncore_p0_p1_info(struct isst_id *id, int config_index, +extern void isst_adjust_uncore_freq(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level); extern int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctdp *pkg_dev); From 2b86ed225e657867b405b3e9412e9efefcbe6ffb Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 20 Aug 2022 20:14:15 +0800 Subject: [PATCH 38/61] tools/power/x86/intel-speed-select: Move send_mbox_cmd to isst-core-mbox.c After the previous cleanup, there is no user of send_mbox_cmd outside of isst-core-mbox.c. Thus move send_mbox_cmd to isst-core-mbox.c as internal functions. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-core-mbox.c | 222 +++++++++++++++--- .../power/x86/intel-speed-select/isst-core.c | 160 +------------ 2 files changed, 195 insertions(+), 187 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 8e224d154e040..6eafef925d1ac 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -5,6 +5,9 @@ */ #include "isst.h" +static int mbox_delay; +static int mbox_retries = 3; + static int mbox_get_disp_freq_multiplier(void) { return DISP_FREQ_MULTIPLIER; @@ -29,6 +32,20 @@ static char *mbox_get_trl_level_name(int level) } } +static void mbox_update_platform_param(enum isst_platform_param param, int value) +{ + switch (param) { + case ISST_PARAM_MBOX_DELAY: + mbox_delay = value; + break; + case ISST_PARAM_MBOX_RETRIES: + mbox_retries = value; + break; + default: + break; + } +} + static int mbox_is_punit_valid(struct isst_id *id) { if (id->cpu < 0) @@ -40,12 +57,156 @@ static int mbox_is_punit_valid(struct isst_id *id) return 1; } +static int _send_mmio_command(unsigned int cpu, unsigned int reg, int write, + unsigned int *value) +{ + struct isst_if_io_regs io_regs; + const char *pathname = "/dev/isst_interface"; + int cmd; + FILE *outf = get_output_file(); + int fd; + + debug_printf("mmio_cmd cpu:%d reg:%d write:%d\n", cpu, reg, write); + + fd = open(pathname, O_RDWR); + if (fd < 0) + err(-1, "%s open failed", pathname); + + io_regs.req_count = 1; + io_regs.io_reg[0].logical_cpu = cpu; + io_regs.io_reg[0].reg = reg; + cmd = ISST_IF_IO_CMD; + if (write) { + io_regs.io_reg[0].read_write = 1; + io_regs.io_reg[0].value = *value; + } else { + io_regs.io_reg[0].read_write = 0; + } + + if (ioctl(fd, cmd, &io_regs) == -1) { + if (errno == ENOTTY) { + perror("ISST_IF_IO_COMMAND\n"); + fprintf(stderr, "Check presence of kernel modules: isst_if_mmio\n"); + exit(0); + } + fprintf(outf, "Error: mmio_cmd cpu:%d reg:%x read_write:%x\n", + cpu, reg, write); + } else { + if (!write) + *value = io_regs.io_reg[0].value; + + debug_printf( + "mmio_cmd response: cpu:%d reg:%x rd_write:%x resp:%x\n", + cpu, reg, write, *value); + } + + close(fd); + + return 0; +} + +int _send_mbox_command(unsigned int cpu, unsigned char command, + unsigned char sub_command, unsigned int parameter, + unsigned int req_data, unsigned int *resp) +{ + const char *pathname = "/dev/isst_interface"; + int fd, retry; + struct isst_if_mbox_cmds mbox_cmds = { 0 }; + + debug_printf( + "mbox_send: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n", + cpu, command, sub_command, parameter, req_data); + + if (!is_skx_based_platform() && command == CONFIG_CLOS && + sub_command != CLOS_PM_QOS_CONFIG) { + unsigned int value; + int write = 0; + int clos_id, core_id, ret = 0; + + debug_printf("CPU %d\n", cpu); + + if (parameter & BIT(MBOX_CMD_WRITE_BIT)) { + value = req_data; + write = 1; + } + + switch (sub_command) { + case CLOS_PQR_ASSOC: + core_id = parameter & 0xff; + ret = _send_mmio_command( + cpu, PQR_ASSOC_OFFSET + core_id * 4, write, + &value); + if (!ret && !write) + *resp = value; + break; + case CLOS_PM_CLOS: + clos_id = parameter & 0x03; + ret = _send_mmio_command( + cpu, PM_CLOS_OFFSET + clos_id * 4, write, + &value); + if (!ret && !write) + *resp = value; + break; + case CLOS_STATUS: + break; + default: + break; + } + return ret; + } + + mbox_cmds.cmd_count = 1; + mbox_cmds.mbox_cmd[0].logical_cpu = cpu; + mbox_cmds.mbox_cmd[0].command = command; + mbox_cmds.mbox_cmd[0].sub_command = sub_command; + mbox_cmds.mbox_cmd[0].parameter = parameter; + mbox_cmds.mbox_cmd[0].req_data = req_data; + + if (mbox_delay) + usleep(mbox_delay * 1000); + + fd = open(pathname, O_RDWR); + if (fd < 0) + err(-1, "%s open failed", pathname); + + retry = mbox_retries; + do { + if (ioctl(fd, ISST_IF_MBOX_COMMAND, &mbox_cmds) == -1) { + if (errno == ENOTTY) { + perror("ISST_IF_MBOX_COMMAND\n"); + fprintf(stderr, "Check presence of kernel modules: isst_if_mbox_pci or isst_if_mbox_msr\n"); + exit(0); + } + debug_printf( + "Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x errorno:%d\n", + cpu, command, sub_command, parameter, req_data, errno); + --retry; + } else { + *resp = mbox_cmds.mbox_cmd[0].resp_data; + debug_printf( + "mbox_cmd response: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x resp:%x\n", + cpu, command, sub_command, parameter, req_data, *resp); + break; + } + } while (retry); + + close(fd); + + if (!retry) { + debug_printf("Failed mbox command even after retries\n"); + return -1; + + } + + return 0; +} + static int mbox_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap) { unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, READ_PM_CONFIG, PM_FEATURE, 0, 0, + ret = _send_mbox_command(id->cpu, READ_PM_CONFIG, PM_FEATURE, 0, 0, &resp); if (ret) return ret; @@ -63,7 +224,7 @@ static int mbox_get_config_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_ unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp); if (ret) { pkg_dev->levels = 0; @@ -92,7 +253,7 @@ static int mbox_get_ctdp_control(struct isst_id *id, int config_index, unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_CONTROL, 0, config_index, &resp); if (ret) @@ -130,7 +291,7 @@ static void _get_uncore_p0_p1_info(struct isst_id *id, int config_index, ctdp_level->uncore_p0 = 0; ctdp_level->uncore_p1 = 0; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_RATIO_INFO, 0, (BIT(16) | config_index) , &resp); if (ret) { @@ -149,7 +310,7 @@ static void _get_uncore_p0_p1_info(struct isst_id *id, int config_index, return; try_uncore_mbox: - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_UNCORE_P0_P1_INFO, 0, config_index, &resp); if (ret) { @@ -210,7 +371,7 @@ static void _get_p1_info(struct isst_id *id, int config_index, { unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0, config_index, &resp); if (ret) { ctdp_level->sse_p1 = 0; @@ -234,7 +395,7 @@ static void _get_uncore_mem_freq(struct isst_id *id, int config_index, unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ, 0, config_index, &resp); if (ret) { ctdp_level->mem_freq = 0; @@ -267,7 +428,7 @@ static int mbox_get_tdp_info(struct isst_id *id, int config_index, unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO, 0, config_index, &resp); if (ret) { isst_display_error_info_message(1, "Invalid level, Can't get TDP information at level", 1, config_index); @@ -282,7 +443,7 @@ static int mbox_get_tdp_info(struct isst_id *id, int config_index, id->cpu, config_index, resp, ctdp_level->tdp_ratio, ctdp_level->pkg_tdp); - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO, 0, config_index, &resp); if (ret) return ret; @@ -306,7 +467,7 @@ static int mbox_get_pwr_info(struct isst_id *id, int config_index, unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO, 0, config_index, &resp); if (ret) return ret; @@ -333,7 +494,7 @@ static int mbox_get_coremask_info(struct isst_id *id, int config_index, unsigned long long mask; int cpu_count = 0; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_CORE_MASK, 0, (i << 8) | config_index, &resp); if (ret) @@ -362,7 +523,7 @@ static int mbox_get_get_trl(struct isst_id *id, int level, int avx_level, int *t int ret; req = level | (avx_level << 16); - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, &resp); if (ret) @@ -378,7 +539,7 @@ static int mbox_get_get_trl(struct isst_id *id, int level, int avx_level, int *t trl[3] = (resp & GENMASK(31, 24)) >> 24; req = level | BIT(8) | (avx_level << 16); - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, &resp); if (ret) @@ -438,7 +599,7 @@ static int mbox_set_tdp_level(struct isst_id *id, int tdp_level) } - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0, tdp_level, &resp); if (ret) { isst_display_error_info_message(1, "Set TDP level failed for level", 1, tdp_level); @@ -461,7 +622,7 @@ static int mbox_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info unsigned long long mask; int count; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_CORE_MASK_INFO, 0, (i << 8) | level, &resp); if (ret) @@ -479,7 +640,7 @@ static int mbox_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info } req = level; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO, 0, req, &resp); if (ret) @@ -492,7 +653,7 @@ static int mbox_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8; req = level; - ret = isst_send_mbox_command( + ret = _send_mbox_command( id->cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TDP_INFO, 0, req, &resp); if (ret) return ret; @@ -502,7 +663,7 @@ static int mbox_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info pbf_info->tdp = resp & 0xffff; req = level; - ret = isst_send_mbox_command( + ret = _send_mbox_command( id->cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TJ_MAX_INFO, 0, req, &resp); if (ret) return ret; @@ -555,7 +716,7 @@ static int mbox_set_pbf_fact_status(struct isst_id *id, int pbf, int enable) req &= ~BIT(16); } - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp); if (ret) return ret; @@ -575,7 +736,7 @@ static int _get_fact_bucket_info(struct isst_id *id, int level, for (i = 0; i < 2; ++i) { int j; - ret = isst_send_mbox_command( + ret = _send_mbox_command( id->cpu, CONFIG_TDP, CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES, 0, (i << 8) | level, &resp); @@ -596,7 +757,7 @@ static int _get_fact_bucket_info(struct isst_id *id, int level, for (i = 0; i < 2; ++i) { int j; - ret = isst_send_mbox_command( + ret = _send_mbox_command( id->cpu, CONFIG_TDP, CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS, 0, (k << 16) | (i << 8) | level, &resp); @@ -622,7 +783,7 @@ static int mbox_get_fact_info(struct isst_id *id, int level, int fact_bucket, st unsigned int resp; int j, ret, print; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0, level, &resp); if (ret) @@ -662,7 +823,7 @@ static int mbox_get_clos_information(struct isst_id *id, int *enable, int *type) unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, &resp); if (ret) return ret; @@ -692,7 +853,7 @@ static int _write_pm_config(struct isst_id *id, int cp_state) else req = 0; - ret = isst_send_mbox_command(id->cpu, WRITE_PM_CONFIG, PM_FEATURE, 0, req, + ret = _send_mbox_command(id->cpu, WRITE_PM_CONFIG, PM_FEATURE, 0, req, &resp); if (ret) return ret; @@ -735,7 +896,7 @@ static int mbox_pm_qos_config(struct isst_id *id, int enable_clos, int priority_ isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0); } - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, &resp); if (ret) { isst_display_error_info_message(1, "CLOS_PM_QOS_CONFIG command failed", 0, 0); @@ -759,7 +920,7 @@ static int mbox_pm_qos_config(struct isst_id *id, int enable_clos, int priority_ else req = req & ~BIT(2); - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, BIT(MBOX_CMD_WRITE_BIT), req, &resp); if (ret) return ret; @@ -775,7 +936,7 @@ static int mbox_pm_get_clos(struct isst_id *id, int clos, struct isst_clos_confi unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0, &resp); if (ret) return ret; @@ -803,7 +964,7 @@ static int mbox_set_clos(struct isst_id *id, int clos, struct isst_clos_config * param = BIT(MBOX_CMD_WRITE_BIT) | clos; - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req, &resp); if (ret) return ret; @@ -822,7 +983,7 @@ static int mbox_clos_get_assoc_status(struct isst_id *id, int *clos_id) core_id = find_phy_core_num(id->cpu); param = core_id; - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0, &resp); if (ret) return ret; @@ -844,7 +1005,7 @@ static int mbox_clos_associate(struct isst_id *id, int clos_id) core_id = find_phy_core_num(id->cpu); param = BIT(MBOX_CMD_WRITE_BIT) | core_id; - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, req, &resp); if (ret) return ret; @@ -859,6 +1020,7 @@ static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, .get_trl_level_name = mbox_get_trl_level_name, + .update_platform_param = mbox_update_platform_param, .is_punit_valid = mbox_is_punit_valid, .read_pm_config = mbox_read_pm_config, .get_config_levels = mbox_get_config_levels, diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 24b2c041bfe0c..fcab70ef5704c 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -6,9 +6,6 @@ #include "isst.h" -static int mbox_delay; -static int mbox_retries = 3; - static struct isst_platform_ops *isst_ops; #define CHECK_CB(_name) \ @@ -30,16 +27,9 @@ int isst_set_platform_ops(void) void isst_update_platform_param(enum isst_platform_param param, int value) { - switch (param) { - case ISST_PARAM_MBOX_DELAY: - mbox_delay = value; - break; - case ISST_PARAM_MBOX_RETRIES: - mbox_retries = value; - break; - default: - break; - } + CHECK_CB(update_platform_param); + + isst_ops->update_platform_param(param, value); } int isst_get_disp_freq_multiplier(void) @@ -66,150 +56,6 @@ int isst_is_punit_valid(struct isst_id *id) return isst_ops->is_punit_valid(id); } -static int isst_send_mmio_command(unsigned int cpu, unsigned int reg, int write, - unsigned int *value) -{ - struct isst_if_io_regs io_regs; - const char *pathname = "/dev/isst_interface"; - int cmd; - FILE *outf = get_output_file(); - int fd; - - debug_printf("mmio_cmd cpu:%d reg:%d write:%d\n", cpu, reg, write); - - fd = open(pathname, O_RDWR); - if (fd < 0) - err(-1, "%s open failed", pathname); - - io_regs.req_count = 1; - io_regs.io_reg[0].logical_cpu = cpu; - io_regs.io_reg[0].reg = reg; - cmd = ISST_IF_IO_CMD; - if (write) { - io_regs.io_reg[0].read_write = 1; - io_regs.io_reg[0].value = *value; - } else { - io_regs.io_reg[0].read_write = 0; - } - - if (ioctl(fd, cmd, &io_regs) == -1) { - if (errno == ENOTTY) { - perror("ISST_IF_IO_COMMAND\n"); - fprintf(stderr, "Check presence of kernel modules: isst_if_mmio\n"); - exit(0); - } - fprintf(outf, "Error: mmio_cmd cpu:%d reg:%x read_write:%x\n", - cpu, reg, write); - } else { - if (!write) - *value = io_regs.io_reg[0].value; - - debug_printf( - "mmio_cmd response: cpu:%d reg:%x rd_write:%x resp:%x\n", - cpu, reg, write, *value); - } - - close(fd); - - return 0; -} - -int isst_send_mbox_command(unsigned int cpu, unsigned char command, - unsigned char sub_command, unsigned int parameter, - unsigned int req_data, unsigned int *resp) -{ - const char *pathname = "/dev/isst_interface"; - int fd, retry; - struct isst_if_mbox_cmds mbox_cmds = { 0 }; - - debug_printf( - "mbox_send: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n", - cpu, command, sub_command, parameter, req_data); - - if (!is_skx_based_platform() && command == CONFIG_CLOS && - sub_command != CLOS_PM_QOS_CONFIG) { - unsigned int value; - int write = 0; - int clos_id, core_id, ret = 0; - - debug_printf("CPU %d\n", cpu); - - if (parameter & BIT(MBOX_CMD_WRITE_BIT)) { - value = req_data; - write = 1; - } - - switch (sub_command) { - case CLOS_PQR_ASSOC: - core_id = parameter & 0xff; - ret = isst_send_mmio_command( - cpu, PQR_ASSOC_OFFSET + core_id * 4, write, - &value); - if (!ret && !write) - *resp = value; - break; - case CLOS_PM_CLOS: - clos_id = parameter & 0x03; - ret = isst_send_mmio_command( - cpu, PM_CLOS_OFFSET + clos_id * 4, write, - &value); - if (!ret && !write) - *resp = value; - break; - case CLOS_STATUS: - break; - default: - break; - } - return ret; - } - - mbox_cmds.cmd_count = 1; - mbox_cmds.mbox_cmd[0].logical_cpu = cpu; - mbox_cmds.mbox_cmd[0].command = command; - mbox_cmds.mbox_cmd[0].sub_command = sub_command; - mbox_cmds.mbox_cmd[0].parameter = parameter; - mbox_cmds.mbox_cmd[0].req_data = req_data; - - if (mbox_delay) - usleep(mbox_delay * 1000); - - fd = open(pathname, O_RDWR); - if (fd < 0) - err(-1, "%s open failed", pathname); - - retry = mbox_retries; - - do { - if (ioctl(fd, ISST_IF_MBOX_COMMAND, &mbox_cmds) == -1) { - if (errno == ENOTTY) { - perror("ISST_IF_MBOX_COMMAND\n"); - fprintf(stderr, "Check presence of kernel modules: isst_if_mbox_pci or isst_if_mbox_msr\n"); - exit(0); - } - debug_printf( - "Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x errorno:%d\n", - cpu, command, sub_command, parameter, req_data, errno); - --retry; - } else { - *resp = mbox_cmds.mbox_cmd[0].resp_data; - debug_printf( - "mbox_cmd response: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x resp:%x\n", - cpu, command, sub_command, parameter, req_data, *resp); - break; - } - } while (retry); - - close(fd); - - if (!retry) { - debug_printf("Failed mbox command even after retries\n"); - return -1; - - } - return 0; -} - int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write, unsigned long long *req_resp) { From 05aab5b8c1b78c028cd95701e788623de744d1cd Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 20 Aug 2022 20:40:48 +0800 Subject: [PATCH 39/61] tools/power/x86/intel-speed-select: Allow api_version based platform callbacks Different api_version suggests different kernel driver used and different interface is used to communication with the hardware. Allow setting platform specific callbacks based on api_version. Currently, all platforms with api_version 1 uses Mbox/MMIO interfaces. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-config.c | 6 ++++-- tools/power/x86/intel-speed-select/isst-core.c | 13 ++++++++++--- tools/power/x86/intel-speed-select/isst.h | 8 ++------ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 346f8271b00ff..fb83f74f15a40 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -803,8 +803,10 @@ static int isst_fill_platform_info(void) const char *pathname = "/dev/isst_interface"; int fd; - if (is_clx_n_platform()) + if (is_clx_n_platform()) { + isst_platform_info.api_version = 1; goto set_platform_ops; + } fd = open(pathname, O_RDWR); if (fd < 0) @@ -824,7 +826,7 @@ static int isst_fill_platform_info(void) } set_platform_ops: - if (isst_set_platform_ops()) { + if (isst_set_platform_ops(isst_platform_info.api_version)) { fprintf(stderr, "Failed to set platform callbacks\n"); exit(0); } diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index fcab70ef5704c..674097289ebf3 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -16,9 +16,16 @@ static struct isst_platform_ops *isst_ops; } \ } while (0) -int isst_set_platform_ops(void) -{ - isst_ops = mbox_get_platform_ops(); +int isst_set_platform_ops(int api_version) +{ + switch (api_version) { + case 1: + isst_ops = mbox_get_platform_ops(); + break; + default: + isst_ops = NULL; + break; + } if (!isst_ops) return -1; diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 8192e683ac922..6839ad2d2b9d4 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -185,6 +185,7 @@ struct isst_platform_ops { int (*get_disp_freq_multiplier)(void); int (*get_trl_max_levels)(void); char *(*get_trl_level_name)(int level); + void (*update_platform_param)(enum isst_platform_param param, int value); int (*is_punit_valid)(struct isst_id *id); int (*read_pm_config)(struct isst_id *id, int *cp_state, int *cp_cap); int (*get_config_levels)(struct isst_id *id, struct isst_pkg_ctdp *pkg_ctdp); @@ -226,15 +227,10 @@ extern void set_cpu_mask_from_punit_coremask(struct isst_id *id, size_t core_cpumask_size, cpu_set_t *core_cpumask, int *cpu_cnt); -extern int isst_send_mbox_command(unsigned int cpu, unsigned char command, - unsigned char sub_command, - unsigned int write, - unsigned int req_data, unsigned int *resp); - extern int isst_send_msr_command(unsigned int cpu, unsigned int command, int write, unsigned long long *req_resp); -extern int isst_set_platform_ops(void); +extern int isst_set_platform_ops(int api_version); extern void isst_update_platform_param(enum isst_platform_param, int vale); extern int isst_get_disp_freq_multiplier(void); extern int isst_get_trl_max_levels(void); From 9798768ce9bc4da626091f4f87fc0a8edbee44d5 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 9 Aug 2022 01:56:04 +0800 Subject: [PATCH 40/61] tools/power/x86/intel-speed-select: Introduce is_debug_enabled() Platform specific code also needs to give debug output. Introduce is_debug_enabled() for this purpose. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-config.c | 5 +++++ tools/power/x86/intel-speed-select/isst.h | 1 + 2 files changed, 6 insertions(+) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index fb83f74f15a40..591fe30a55b01 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -77,6 +77,11 @@ FILE *get_output_file(void) return outf; } +int is_debug_enabled(void) +{ + return debug_flag; +} + void debug_printf(const char *format, ...) { va_list args; diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 6839ad2d2b9d4..b3bf989690d6d 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -216,6 +216,7 @@ extern int get_max_punit_core_id(struct isst_id *id); /* Common interfaces */ FILE *get_output_file(void); +extern int is_debug_enabled(void); extern void debug_printf(const char *format, ...); extern int out_format_is_json(void); extern void set_isst_id(struct isst_id *id, int cpu); From 20f06c9db22bf45de595a2a5855630b075596217 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 16 Aug 2022 21:20:00 +0800 Subject: [PATCH 41/61] tools/power/x86/intel-speed-select: Support large clos_min/max clos_min/max in TPMI interface is frequency in MHz, thus clos_min/max needs to support larger values. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index b3bf989690d6d..b854f4bf795f3 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -92,10 +92,10 @@ struct isst_id { }; struct isst_clos_config { + unsigned int clos_min; + unsigned int clos_max; unsigned char epp; unsigned char clos_prop_prio; - unsigned char clos_min; - unsigned char clos_max; unsigned char clos_desired; }; From 887e5be91dd253ff73c0b2644442c0cae5d6dca0 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 20 Aug 2022 20:51:33 +0800 Subject: [PATCH 42/61] tools/power/x86/intel-speed-select: Introduce api_version helper In some cases, the output format may be different with different api_version because of different capabilities or for backward capabilities reason. Introduce api_version() to get the api_version of the platform running. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-config.c | 5 +++++ tools/power/x86/intel-speed-select/isst.h | 1 + 2 files changed, 6 insertions(+) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 591fe30a55b01..891693ac12341 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -166,6 +166,11 @@ static int update_cpu_model(void) return 0; } +int api_version(void) +{ + return isst_platform_info.api_version; +} + /* Open a file, and exit on failure */ static FILE *fopen_or_exit(const char *path, const char *mode) { diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index b854f4bf795f3..3efa7251001f3 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -213,6 +213,7 @@ extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); extern int get_topo_max_cpus(void); extern int get_cpu_count(struct isst_id *id); extern int get_max_punit_core_id(struct isst_id *id); +extern int api_version(void); /* Common interfaces */ FILE *get_output_file(void); From a0ca5a097342f78d41e104d8d6bb0742ff0e7330 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 6 Mar 2023 09:26:28 -0800 Subject: [PATCH 43/61] tools/power/x86/intel-speed-select: Get punit core mapping information Get punit core mapping information using format of MSR 0x54. Based on the API version, decode is done using new format. The new format also include a power domain ID. TPMI SST information is for each power domain. Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-config.c | 57 +++++++++++++------ 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 891693ac12341..136da390b4b20 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -669,6 +669,46 @@ int get_cpu_count(struct isst_id *id) return cpu_cnt[id->pkg][id->die][id->punit]; } +static void update_punit_cpu_info(__u32 physical_cpu, struct _cpu_map *cpu_map) +{ + if (api_version() > 1) { + /* + * MSR 0x54 format + * [15:11] PM_DOMAIN_ID + * [10:3] MODULE_ID (aka IDI_AGENT_ID) + * [2:0] LP_ID (We don't care about these bits we only + * care die and core id + * For Atom: + * [2] Always 0 + * [1:0] core ID within module + * For Core + * [2:1] Always 0 + * [0] thread ID + */ + cpu_map->punit_id = (physical_cpu >> 11) & 0x1f; + cpu_map->punit_cpu_core = (physical_cpu >> 3) & 0xff; + cpu_map->punit_cpu = physical_cpu & 0x7ff; + } else { + int punit_id; + + /* + * MSR 0x53 format + * Format + * Bit 0 – thread ID + * Bit 8:1 – core ID + * Bit 13:9 – punit ID + */ + cpu_map->punit_cpu = physical_cpu & 0x1ff; + cpu_map->punit_cpu_core = (cpu_map->punit_cpu >> 1); // shift to get core id + punit_id = (physical_cpu >> 9) & 0x1f; + + if (punit_id >= MAX_PUNIT_PER_DIE) + punit_id = 0; + + cpu_map->punit_id = punit_id; + } +} + static void create_cpu_map(void) { const char *pathname = "/dev/isst_interface"; @@ -727,24 +767,9 @@ static void create_cpu_map(void) fprintf(outf, "Error: map logical_cpu:%d\n", map.cpu_map[0].logical_cpu); } else { - /* - * Format - * Bit 0 – thread ID - * Bit 8:1 – core ID - * Bit 13:9 – punit ID - */ - cpu_map[i].punit_cpu = map.cpu_map[0].physical_cpu & 0x1ff; - cpu_map[i].punit_cpu_core = (cpu_map[i].punit_cpu >> - 1); // shift to get core id - punit_id = (map.cpu_map[0].physical_cpu >> 9) & 0x1f; - - if (punit_id >= MAX_PUNIT_PER_DIE) - punit_id = 0; - - cpu_map[i].punit_id = punit_id; + update_punit_cpu_info(map.cpu_map[0].physical_cpu, &cpu_map[i]); } } - cpu_map[i].initialized = 1; cpu_cnt[pkg_id][die_id][punit_id]++; From 79554aaa224a3b99f95b9c2843dc904764c32541 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 9 Aug 2022 00:01:00 +0800 Subject: [PATCH 44/61] tools/power/x86/intel-speed-select: Introduce TPMI interface support TPMI (Topology Aware Register and PM Capsule Interface) creates a flexible, extendable and software-PCIe-driver-enumerable MMIO interface for PM features. SST feature is exposed via the TPMI interface on newer Xeon platforms. Kernel TPMI based SST driver provides a series of new IOCTLs for userspace to use. Introduce support for the platforms that do SST control via TPMI interface. Compared with previous platforms, Newer Xeons also supports multi-punit in a package/die, including cpu punit and non-cpu punit. These have already been handled in the generic code. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/Build | 2 +- .../x86/intel-speed-select/isst-core-tpmi.c | 787 ++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 3 + tools/power/x86/intel-speed-select/isst.h | 3 + 4 files changed, 794 insertions(+), 1 deletion(-) create mode 100644 tools/power/x86/intel-speed-select/isst-core-tpmi.c diff --git a/tools/power/x86/intel-speed-select/Build b/tools/power/x86/intel-speed-select/Build index 32a2493b52335..5a9637e1678c5 100644 --- a/tools/power/x86/intel-speed-select/Build +++ b/tools/power/x86/intel-speed-select/Build @@ -1 +1 @@ -intel-speed-select-y += isst-config.o isst-core.o isst-display.o isst-daemon.o hfi-events.o isst-core-mbox.o +intel-speed-select-y += isst-config.o isst-core.o isst-display.o isst-daemon.o hfi-events.o isst-core-mbox.o isst-core-tpmi.o diff --git a/tools/power/x86/intel-speed-select/isst-core-tpmi.c b/tools/power/x86/intel-speed-select/isst-core-tpmi.c new file mode 100644 index 0000000000000..19caa9c78d413 --- /dev/null +++ b/tools/power/x86/intel-speed-select/isst-core-tpmi.c @@ -0,0 +1,787 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Speed Select -- Enumerate and control features for TPMI Interface + * Copyright (c) 2022 Intel Corporation. + */ + +#include +#include "isst.h" + +int tpmi_process_ioctl(int ioctl_no, void *info) +{ + const char *pathname = "/dev/isst_interface"; + int fd; + + if (is_debug_enabled()) { + debug_printf("Issue IOCTL: "); + switch (ioctl_no) { + case ISST_IF_CORE_POWER_STATE: + debug_printf("ISST_IF_CORE_POWER_STATE\n"); + break; + case ISST_IF_CLOS_PARAM: + debug_printf("ISST_IF_CLOS_PARAM\n"); + break; + case ISST_IF_CLOS_ASSOC: + debug_printf("ISST_IF_CLOS_ASSOC\n"); + break; + case ISST_IF_PERF_LEVELS: + debug_printf("ISST_IF_PERF_LEVELS\n"); + break; + case ISST_IF_PERF_SET_LEVEL: + debug_printf("ISST_IF_PERF_SET_LEVEL\n"); + break; + case ISST_IF_PERF_SET_FEATURE: + debug_printf("ISST_IF_PERF_SET_FEATURE\n"); + break; + case ISST_IF_GET_PERF_LEVEL_INFO: + debug_printf("ISST_IF_GET_PERF_LEVEL_INFO\n"); + break; + case ISST_IF_GET_PERF_LEVEL_CPU_MASK: + debug_printf("ISST_IF_GET_PERF_LEVEL_CPU_MASK\n"); + break; + case ISST_IF_GET_BASE_FREQ_INFO: + debug_printf("ISST_IF_GET_BASE_FREQ_INFO\n"); + break; + case ISST_IF_GET_BASE_FREQ_CPU_MASK: + debug_printf("ISST_IF_GET_BASE_FREQ_CPU_MASK\n"); + break; + case ISST_IF_GET_TURBO_FREQ_INFO: + debug_printf("ISST_IF_GET_TURBO_FREQ_INFO\n"); + break; + case ISST_IF_COUNT_TPMI_INSTANCES: + debug_printf("ISST_IF_COUNT_TPMI_INSTANCES\n"); + break; + default: + debug_printf("%d\n", ioctl_no); + break; + } + } + + fd = open(pathname, O_RDWR); + if (fd < 0) + return -1; + + if (ioctl(fd, ioctl_no, info) == -1) { + debug_printf("IOCTL %d Failed\n", ioctl_no); + close(fd); + return -1; + } + + close(fd); + + return 0; +} + +static int tpmi_get_disp_freq_multiplier(void) +{ + return 1; +} + +static int tpmi_get_trl_max_levels(void) +{ + return TRL_MAX_LEVELS; +} + +static char *tpmi_get_trl_level_name(int level) +{ + switch (level) { + case 0: + return "level-0"; + case 1: + return "level-1"; + case 2: + return "level-2"; + case 3: + return "level-3"; + case 4: + return "level-4"; + case 5: + return "level-5"; + case 6: + return "level-6"; + case 7: + return "level-7"; + default: + return NULL; + } +} + + +static void tpmi_update_platform_param(enum isst_platform_param param, int value) +{ + /* No params need to be updated for now */ +} + +static int tpmi_is_punit_valid(struct isst_id *id) +{ + struct isst_tpmi_instance_count info; + int ret; + + if (id->punit < 0) + return 0; + + info.socket_id = id->pkg; + ret = tpmi_process_ioctl(ISST_IF_COUNT_TPMI_INSTANCES, &info); + if (ret == -1) + return 0; + + if (info.valid_mask & BIT(id->punit)) + return 1; + + return 0; +} + +static int tpmi_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap) +{ + struct isst_core_power info; + int ret; + + info.get_set = 0; + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info); + if (ret == -1) + return ret; + + *cp_state = info.enable; + *cp_cap = info.supported; + + return 0; +} + +int tpmi_get_config_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev) +{ + struct isst_perf_level_info info; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + + ret = tpmi_process_ioctl(ISST_IF_PERF_LEVELS, &info); + if (ret == -1) + return ret; + + pkg_dev->version = info.feature_rev; + pkg_dev->levels = info.max_level; + pkg_dev->locked = info.locked; + pkg_dev->current_level = info.current_level; + pkg_dev->locked = info.locked; + pkg_dev->enabled = info.enabled; + + return 0; +} + +static int tpmi_get_ctdp_control(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + struct isst_core_power core_power_info; + struct isst_perf_level_info info; + int level_mask; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + + ret = tpmi_process_ioctl(ISST_IF_PERF_LEVELS, &info); + if (ret == -1) + return -1; + + if (config_index != 0xff) + level_mask = 1 << config_index; + else + level_mask = config_index; + + if (!(info.level_mask & level_mask)) + return -1; + + ctdp_level->fact_support = info.sst_tf_support; + ctdp_level->pbf_support = info.sst_bf_support; + ctdp_level->fact_enabled = !!(info.feature_state & BIT(1)); + ctdp_level->pbf_enabled = !!(info.feature_state & BIT(0)); + + core_power_info.get_set = 0; + core_power_info.socket_id = id->pkg; + core_power_info.power_domain_id = id->punit; + + ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &core_power_info); + if (ret == -1) + return ret; + + ctdp_level->sst_cp_support = core_power_info.supported; + ctdp_level->sst_cp_enabled = core_power_info.enable; + + debug_printf + ("cpu:%d CONFIG_TDP_GET_TDP_CONTROL fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n", + id->cpu, ctdp_level->fact_support, ctdp_level->pbf_support, + ctdp_level->fact_enabled, ctdp_level->pbf_enabled); + + return 0; +} + +static int tpmi_get_tdp_info(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + struct isst_perf_level_data_info info; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = config_index; + + ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); + if (ret == -1) + return ret; + + ctdp_level->pkg_tdp = info.thermal_design_power_w; + ctdp_level->tdp_ratio = info.tdp_ratio; + ctdp_level->sse_p1 = info.base_freq_mhz; + ctdp_level->avx2_p1 = info.base_freq_avx2_mhz; + ctdp_level->avx512_p1 = info.base_freq_avx512_mhz; + ctdp_level->amx_p1 = info.base_freq_amx_mhz; + + ctdp_level->t_proc_hot = info.tjunction_max_c; + ctdp_level->mem_freq = info.max_memory_freq_mhz; + ctdp_level->cooling_type = info.cooling_type; + + ctdp_level->uncore_p0 = info.p0_fabric_freq_mhz; + ctdp_level->uncore_p1 = info.p1_fabric_freq_mhz; + ctdp_level->uncore_pm = info.pm_fabric_freq_mhz; + + debug_printf + ("cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO tdp_ratio:%d pkg_tdp:%d ctdp_level->t_proc_hot:%d\n", + id->cpu, config_index, ctdp_level->tdp_ratio, ctdp_level->pkg_tdp, + ctdp_level->t_proc_hot); + + return 0; +} + +static int tpmi_get_pwr_info(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + /* TBD */ + ctdp_level->pkg_max_power = 0; + ctdp_level->pkg_min_power = 0; + + debug_printf + ("cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO pkg_max_power:%d pkg_min_power:%d\n", + id->cpu, config_index, ctdp_level->pkg_max_power, + ctdp_level->pkg_min_power); + + return 0; +} + +int tpmi_get_coremask_info(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + struct isst_perf_level_cpu_mask info; + int ret, cpu_count; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = config_index; + info.punit_cpu_map = 1; + + ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_CPU_MASK, &info); + if (ret == -1) + return ret; + + set_cpu_mask_from_punit_coremask(id, info.mask, + ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask, &cpu_count); + ctdp_level->cpu_count = cpu_count; + + debug_printf("cpu:%d ctdp:%d core_mask ino cpu count:%d\n", + id->cpu, config_index, ctdp_level->cpu_count); + + return 0; +} + +static int tpmi_get_get_trls(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + struct isst_perf_level_data_info info; + int ret, i, j; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = config_index; + + ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); + if (ret == -1) + return ret; + + if (info.max_buckets > TRL_MAX_BUCKETS) + info.max_buckets = TRL_MAX_BUCKETS; + + if (info.max_trl_levels > TRL_MAX_LEVELS) + info.max_trl_levels = TRL_MAX_LEVELS; + + for (i = 0; i < info.max_trl_levels; ++i) + for (j = 0; j < info.max_buckets; ++j) + ctdp_level->trl_ratios[i][j] = info.trl_freq_mhz[i][j]; + + return 0; +} + +static int tpmi_get_get_trl(struct isst_id *id, int level, int config_index, + int *trl) +{ + struct isst_pkg_ctdp_level_info ctdp_level; + int ret, i; + + ret = tpmi_get_get_trls(id, config_index, &ctdp_level); + if (ret) + return ret; + + /* FIX ME: Just return for level 0 */ + for (i = 0; i < 8; ++i) + trl[i] = ctdp_level.trl_ratios[0][i]; + + return 0; +} + +static int tpmi_get_trl_bucket_info(struct isst_id *id, int config_index, + unsigned long long *buckets_info) +{ + struct isst_perf_level_data_info info; + unsigned char *mask = (unsigned char *)buckets_info; + int ret, i; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = config_index; + + ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); + if (ret == -1) + return ret; + + if (info.max_buckets > TRL_MAX_BUCKETS) + info.max_buckets = TRL_MAX_BUCKETS; + + for (i = 0; i < info.max_buckets; ++i) + mask[i] = info.bucket_core_counts[i]; + + debug_printf("cpu:%d TRL bucket info: 0x%llx\n", id->cpu, + *buckets_info); + + return 0; +} + +static int tpmi_set_tdp_level(struct isst_id *id, int tdp_level) +{ + struct isst_perf_level_control info; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = tdp_level; + + ret = tpmi_process_ioctl(ISST_IF_PERF_SET_LEVEL, &info); + if (ret == -1) + return ret; + + return 0; +} + +static int _pbf_get_coremask_info(struct isst_id *id, int config_index, + struct isst_pbf_info *pbf_info) +{ + struct isst_perf_level_cpu_mask info; + int ret, cpu_count; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = config_index; + info.punit_cpu_map = 1; + + ret = tpmi_process_ioctl(ISST_IF_GET_BASE_FREQ_CPU_MASK, &info); + if (ret == -1) + return ret; + + set_cpu_mask_from_punit_coremask(id, info.mask, + pbf_info->core_cpumask_size, + pbf_info->core_cpumask, &cpu_count); + + debug_printf("cpu:%d ctdp:%d pbf core_mask info cpu count:%d\n", + id->cpu, config_index, cpu_count); + + return 0; +} + +static int tpmi_get_pbf_info(struct isst_id *id, int level, + struct isst_pbf_info *pbf_info) +{ + struct isst_base_freq_info info; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = level; + + ret = tpmi_process_ioctl(ISST_IF_GET_BASE_FREQ_INFO, &info); + if (ret == -1) + return ret; + + pbf_info->p1_low = info.low_base_freq_mhz; + pbf_info->p1_high = info.high_base_freq_mhz; + pbf_info->tdp = info.thermal_design_power_w; + pbf_info->t_prochot = info.tjunction_max_c; + + debug_printf("cpu:%d ctdp:%d pbf info:%d:%d:%d:%d\n", + id->cpu, level, pbf_info->p1_low, pbf_info->p1_high, + pbf_info->tdp, pbf_info->t_prochot); + + return _pbf_get_coremask_info(id, level, pbf_info); +} + +static int tpmi_set_pbf_fact_status(struct isst_id *id, int pbf, int enable) +{ + struct isst_pkg_ctdp pkg_dev; + struct isst_pkg_ctdp_level_info ctdp_level; + int current_level; + struct isst_perf_feature_control info; + int ret; + + ret = isst_get_ctdp_levels(id, &pkg_dev); + if (ret) + debug_printf("cpu:%d No support for dynamic ISST\n", id->cpu); + + current_level = pkg_dev.current_level; + + ret = isst_get_ctdp_control(id, current_level, &ctdp_level); + if (ret) + return ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + + info.feature = 0; + + if (pbf) { + if (ctdp_level.fact_enabled) + info.feature |= BIT(1); + + if (enable) + info.feature |= BIT(0); + else + info.feature &= ~BIT(0); + } else { + + if (enable && !ctdp_level.sst_cp_enabled) + isst_display_error_info_message(0, + "Make sure to execute before: core-power enable", + 0, 0); + + if (ctdp_level.pbf_enabled) + info.feature |= BIT(0); + + if (enable) + info.feature |= BIT(1); + else + info.feature &= ~BIT(1); + } + + ret = tpmi_process_ioctl(ISST_IF_PERF_SET_FEATURE, &info); + if (ret == -1) + return ret; + + return 0; +} + +static int tpmi_get_fact_info(struct isst_id *id, int level, int fact_bucket, + struct isst_fact_info *fact_info) +{ + struct isst_turbo_freq_info info; + int i, j; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = level; + + ret = tpmi_process_ioctl(ISST_IF_GET_TURBO_FREQ_INFO, &info); + if (ret == -1) + return ret; + + for (i = 0; i < info.max_clip_freqs; ++i) + fact_info->lp_ratios[i] = info.lp_clip_freq_mhz[i]; + + if (info.max_buckets > TRL_MAX_BUCKETS) + info.max_buckets = TRL_MAX_BUCKETS; + + if (info.max_trl_levels > TRL_MAX_LEVELS) + info.max_trl_levels = TRL_MAX_LEVELS; + + for (i = 0; i < info.max_trl_levels; ++i) { + for (j = 0; j < info.max_buckets; ++j) + fact_info->bucket_info[j].hp_ratios[i] = + info.trl_freq_mhz[i][j]; + } + + for (i = 0; i < info.max_buckets; ++i) + fact_info->bucket_info[i].hp_cores = info.bucket_core_counts[i]; + + return 0; +} + +static void _set_uncore_min_max(struct isst_id *id, int max, int freq) +{ + DIR *dir; + FILE *filep; + struct dirent *entry; + char buffer[512]; + unsigned int tmp_id; + int ret; + + dir = opendir("/sys/devices/system/cpu/intel_uncore_frequency/"); + if (!dir) + return; + + while ((entry = readdir(dir)) != NULL ) { + /* Check domain_id */ + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/intel_uncore_frequency/%s/domain_id", entry->d_name); + + filep = fopen(buffer, "r"); + if (!filep) + goto end; + + ret = fscanf(filep, "%u", &tmp_id); + fclose(filep); + if (ret != 1) + goto end; + + if (tmp_id != id->punit) + continue; + + /* Check package_id */ + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/intel_uncore_frequency/%s/package_id", entry->d_name); + + filep = fopen(buffer, "r"); + if (!filep) + goto end; + + ret = fscanf(filep, "%u", &tmp_id); + fclose(filep); + + if (ret != 1) + goto end; + + if (tmp_id != id->pkg) + continue; + + /* Found the right sysfs path, adjust and quit */ + if (max) + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/intel_uncore_frequency/%s/max_freq_khz", entry->d_name); + else + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/intel_uncore_frequency/%s/min_freq_khz", entry->d_name); + + filep = fopen(buffer, "w"); + if (!filep) + goto end; + + fprintf(filep, "%d\n", freq); + fclose(filep); + break; + } + +end: + closedir(dir); +} + +static void tpmi_adjust_uncore_freq(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + struct isst_perf_level_data_info info; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = config_index; + + ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); + if (ret == -1) + return; + + ctdp_level->uncore_p0 = info.p0_fabric_freq_mhz; + ctdp_level->uncore_p1 = info.p1_fabric_freq_mhz; + ctdp_level->uncore_pm = info.pm_fabric_freq_mhz; + + if (ctdp_level->uncore_pm) + _set_uncore_min_max(id, 0, ctdp_level->uncore_pm * 100000); + + if (ctdp_level->uncore_p0) + _set_uncore_min_max(id, 1, ctdp_level->uncore_p0 * 100000); + + return; +} + +static int tpmi_get_clos_information(struct isst_id *id, int *enable, int *type) +{ + struct isst_core_power info; + int ret; + + info.get_set = 0; + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info); + if (ret == -1) + return ret; + + *enable = info.enable; + *type = info.priority_type; + + return 0; +} + +static int tpmi_pm_qos_config(struct isst_id *id, int enable_clos, + int priority_type) +{ + struct isst_core_power info; + int ret; + + info.get_set = 1; + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.enable = enable_clos; + info.priority_type = priority_type; + ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info); + if (ret == -1) + return ret; + + return 0; +} + +int tpmi_pm_get_clos(struct isst_id *id, int clos, + struct isst_clos_config *clos_config) +{ + struct isst_clos_param info; + int ret; + + info.get_set = 0; + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.clos = clos; + + ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info); + if (ret == -1) + return ret; + + clos_config->epp = 0; + clos_config->clos_prop_prio = info.prop_prio; + clos_config->clos_min = info.min_freq_mhz; + clos_config->clos_max = info.max_freq_mhz; + clos_config->clos_desired = 0; + + debug_printf("cpu:%d clos:%d min:%d max:%d\n", id->cpu, clos, + clos_config->clos_min, clos_config->clos_max); + + return 0; +} + +int tpmi_set_clos(struct isst_id *id, int clos, + struct isst_clos_config *clos_config) +{ + struct isst_clos_param info; + int ret; + + info.get_set = 1; + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.clos = clos; + info.prop_prio = clos_config->clos_prop_prio; + + info.min_freq_mhz = clos_config->clos_min; + info.max_freq_mhz = clos_config->clos_max; + + if (info.min_freq_mhz <= 0xff) + info.min_freq_mhz *= 100; + if (info.max_freq_mhz <= 0xff) + info.max_freq_mhz *= 100; + + ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info); + if (ret == -1) + return ret; + + debug_printf("set cpu:%d clos:%d min:%d max:%d\n", id->cpu, clos, + clos_config->clos_min, clos_config->clos_max); + + return 0; +} + +static int tpmi_clos_get_assoc_status(struct isst_id *id, int *clos_id) +{ + struct isst_if_clos_assoc_cmds assoc_cmds; + int ret; + + assoc_cmds.cmd_count = 1; + assoc_cmds.get_set = 0; + assoc_cmds.punit_cpu_map = 1; + assoc_cmds.assoc_info[0].logical_cpu = find_phy_core_num(id->cpu); + assoc_cmds.assoc_info[0].socket_id = id->pkg; + assoc_cmds.assoc_info[0].power_domain_id = id->punit; + + ret = tpmi_process_ioctl(ISST_IF_CLOS_ASSOC, &assoc_cmds); + if (ret == -1) + return ret; + + *clos_id = assoc_cmds.assoc_info[0].clos; + + return 0; +} + +static int tpmi_clos_associate(struct isst_id *id, int clos_id) +{ + struct isst_if_clos_assoc_cmds assoc_cmds; + int ret; + + assoc_cmds.cmd_count = 1; + assoc_cmds.get_set = 1; + assoc_cmds.punit_cpu_map = 1; + assoc_cmds.assoc_info[0].logical_cpu = find_phy_core_num(id->cpu); + assoc_cmds.assoc_info[0].clos = clos_id; + assoc_cmds.assoc_info[0].socket_id = id->pkg; + assoc_cmds.assoc_info[0].power_domain_id = id->punit; + + ret = tpmi_process_ioctl(ISST_IF_CLOS_ASSOC, &assoc_cmds); + if (ret == -1) + return ret; + + return 0; +} + +static struct isst_platform_ops tpmi_ops = { + .get_disp_freq_multiplier = tpmi_get_disp_freq_multiplier, + .get_trl_max_levels = tpmi_get_trl_max_levels, + .get_trl_level_name = tpmi_get_trl_level_name, + .update_platform_param = tpmi_update_platform_param, + .is_punit_valid = tpmi_is_punit_valid, + .read_pm_config = tpmi_read_pm_config, + .get_config_levels = tpmi_get_config_levels, + .get_ctdp_control = tpmi_get_ctdp_control, + .get_tdp_info = tpmi_get_tdp_info, + .get_pwr_info = tpmi_get_pwr_info, + .get_coremask_info = tpmi_get_coremask_info, + .get_get_trl = tpmi_get_get_trl, + .get_get_trls = tpmi_get_get_trls, + .get_trl_bucket_info = tpmi_get_trl_bucket_info, + .set_tdp_level = tpmi_set_tdp_level, + .get_pbf_info = tpmi_get_pbf_info, + .set_pbf_fact_status = tpmi_set_pbf_fact_status, + .get_fact_info = tpmi_get_fact_info, + .adjust_uncore_freq = tpmi_adjust_uncore_freq, + .get_clos_information = tpmi_get_clos_information, + .pm_qos_config = tpmi_pm_qos_config, + .pm_get_clos = tpmi_pm_get_clos, + .set_clos = tpmi_set_clos, + .clos_get_assoc_status = tpmi_clos_get_assoc_status, + .clos_associate = tpmi_clos_associate, +}; + +struct isst_platform_ops *tpmi_get_platform_ops(void) +{ + return &tpmi_ops; +} diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 674097289ebf3..f0b96d7078d3a 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -22,6 +22,9 @@ int isst_set_platform_ops(int api_version) case 1: isst_ops = mbox_get_platform_ops(); break; + case 2: + isst_ops = tpmi_get_platform_ops(); + break; default: isst_ops = NULL; break; diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 3efa7251001f3..1984cc564fa91 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -143,12 +143,14 @@ struct isst_pkg_ctdp_level_info { int pkg_max_power; int fact; int t_proc_hot; + int cooling_type; int uncore_p0; int uncore_p1; int uncore_pm; int sse_p1; int avx2_p1; int avx512_p1; + int amx_p1; int mem_freq; size_t core_cpumask_size; cpu_set_t *core_cpumask; @@ -311,5 +313,6 @@ extern void hfi_exit(void); /* Interface specific callbacks */ extern struct isst_platform_ops *mbox_get_platform_ops(void); +extern struct isst_platform_ops *tpmi_get_platform_ops(void); #endif From 46de87e39b871f926b429b14bde845412b541841 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 10 Aug 2022 17:14:11 +0800 Subject: [PATCH 45/61] tools/power/x86/intel-speed-select: Display punit info Display punit info for platforms with new api_version. For platforms with old api_version, don't display the punit info to be backward compatible. For example: Intel(R) Speed Select Technology Executing on CPU model:173[0xad] package-0 die-0 powerdomain-0 cpu-0 get-config-current_level:0 package-0 die-0 powerdomain-3 cpu--1 get-config-current_level:0 package-0 die-0 powerdomain-4 cpu--1 get-config-current_level:0 Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-display.c | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index af97ba5dbcc2e..959d2d81e13a3 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -169,21 +169,30 @@ static void format_and_print(FILE *outf, int level, char *header, char *value) static int print_package_info(struct isst_id *id, FILE *outf) { char header[256]; + int level = 1; if (out_format_is_json()) { - snprintf(header, sizeof(header), "package-%d:die-%d:cpu-%d", - id->pkg, id->die, id->cpu); - format_and_print(outf, 1, header, NULL); + if (api_version() > 1) + snprintf(header, sizeof(header), "package-%d:die-%d:powerdomain-%d:cpu-%d", + id->pkg, id->die, id->punit, id->cpu); + else + snprintf(header, sizeof(header), "package-%d:die-%d:cpu-%d", + id->pkg, id->die, id->cpu); + format_and_print(outf, level, header, NULL); return 1; } snprintf(header, sizeof(header), "package-%d", id->pkg); - format_and_print(outf, 1, header, NULL); + format_and_print(outf, level++, header, NULL); snprintf(header, sizeof(header), "die-%d", id->die); - format_and_print(outf, 2, header, NULL); + format_and_print(outf, level++, header, NULL); + if (api_version() > 1) { + snprintf(header, sizeof(header), "powerdomain-%d", id->punit); + format_and_print(outf, level++, header, NULL); + } snprintf(header, sizeof(header), "cpu-%d", id->cpu); - format_and_print(outf, 3, header, NULL); + format_and_print(outf, level, header, NULL); - return 3; + return level; } static void _isst_pbf_display_information(struct isst_id *id, FILE *outf, int level, @@ -306,22 +315,10 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l void isst_ctdp_display_core_info(struct isst_id *id, FILE *outf, char *prefix, unsigned int val, char *str0, char *str1) { - char header[256]; char value[256]; - int level = 1; + int level = print_package_info(id, outf); - if (out_format_is_json()) { - snprintf(header, sizeof(header), "package-%d:die-%d:cpu-%d", - id->pkg, id->die, id->cpu); - format_and_print(outf, level++, header, NULL); - } else { - snprintf(header, sizeof(header), "package-%d", id->pkg); - format_and_print(outf, level++, header, NULL); - snprintf(header, sizeof(header), "die-%d", id->die); - format_and_print(outf, level++, header, NULL); - snprintf(header, sizeof(header), "cpu-%d", id->cpu); - format_and_print(outf, level++, header, NULL); - } + level++; if (str0 && !val) snprintf(value, sizeof(value), "%s", str0); From 5f319081657cb653b55d2c9ef393fc5cd7aae6d4 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 9 Aug 2022 03:29:23 +0800 Subject: [PATCH 46/61] tools/power/x86/intel-speed-select: Display amx_p1 and cooling_type amx_p1 and cooling_type are newly introduced for TPMI interface. Display amx_p1 and cooling_type info for platforms that support them. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-display.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 959d2d81e13a3..8abb0335e0915 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -421,6 +421,13 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level format_and_print(outf, level + 2, header, value); } + if (api_version() > 1 && ctdp_level->amx_p1) { + snprintf(header, sizeof(header), "base-frequency-amx(MHz)"); + snprintf(value, sizeof(value), "%d", + ctdp_level->amx_p1 * isst_get_disp_freq_multiplier()); + format_and_print(outf, level + 2, header, value); + } + if (ctdp_level->uncore_p1) { snprintf(header, sizeof(header), "uncore-frequency-base(MHz)"); snprintf(value, sizeof(value), "%d", @@ -435,6 +442,13 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level format_and_print(outf, level + 2, header, value); } + if (api_version() > 1) { + snprintf(header, sizeof(header), "cooling_type"); + snprintf(value, sizeof(value), "%d", + ctdp_level->cooling_type); + format_and_print(outf, level + 2, header, value); + } + snprintf(header, sizeof(header), "speed-select-turbo-freq"); if (ctdp_level->fact_support) { From 2e54ba89ec5286d041999e6566ae96267d33b002 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 01:34:55 +0800 Subject: [PATCH 47/61] tools/power/x86/intel-speed-select: Allow display non-cpu power domain info Some power domain may not have CPUs associated, allow displaying information for these non-cpu power domains. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 8abb0335e0915..1bfa8e4b39b23 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -682,8 +682,7 @@ void isst_display_result(struct isst_id *id, FILE *outf, char *feature, char *cm char value[256]; int level = 3; - if (id->cpu >= 0) - level = print_package_info(id, outf); + level = print_package_info(id, outf); snprintf(header, sizeof(header), "%s", feature); format_and_print(outf, level + 1, header, NULL); From 443bf104ef10cfc0d22698613f8ba178427d4538 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 01:45:33 +0800 Subject: [PATCH 48/61] tools/power/x86/intel-speed-select: Prevent cpu clos config for non-cpu power domain Non-cpu power domain does not support cpu clos config. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-config.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 136da390b4b20..47431c577668b 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -2077,6 +2077,9 @@ static void dump_clos_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, struct isst_clos_config clos_config; int ret; + if (id->cpu < 0) + return; + ret = isst_pm_get_clos(id, current_clos, &clos_config); if (ret) isst_display_error_info_message(1, "isst_pm_get_clos failed", 0, 0); @@ -2153,6 +2156,9 @@ static void set_clos_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, struct isst_clos_config clos_config; int ret; + if (id->cpu < 0) + return; + clos_config.epp = clos_epp; clos_config.clos_prop_prio = clos_prop_prio; clos_config.clos_min = clos_min; From ca7c5d5b75fdac884d2ad6acd7cb28e3f1dfee9c Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 01:51:15 +0800 Subject: [PATCH 49/61] tools/power/x86/intel-speed-select: Show level 0 name for new api_version level 0 name is not shown in some case for backward compatibility reason. No need to keep this quirk for new api_version. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 1bfa8e4b39b23..4ad5df30ee835 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -284,7 +284,7 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l for (i = 0; i < trl_max_levels; i++) { if (fact_avx != 0xFF && !(fact_avx & (1 << i))) continue; - if (i == 0) + if (i == 0 && api_version() == 1) snprintf(header, sizeof(header), "high-priority-max-frequency(MHz)"); else @@ -301,7 +301,7 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l for (j = 0; j < trl_max_levels; j++) { /* No AVX level name for SSE to be consistent with previous formatting */ - if (j == 0) + if (j == 0 && api_version() == 1) snprintf(header, sizeof(header), "low-priority-max-frequency(MHz)"); else snprintf(header, sizeof(header), "low-priority-max-%s-frequency(MHz)", From b1e9b87b3b5999786685eb882afb99c468af94c1 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 21:18:03 +0800 Subject: [PATCH 50/61] tools/power/x86/intel-speed-select: Display fact info for non-cpu power domain Allow displaying SST-TF info for non-cpu power domain. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 4ad5df30ee835..1723e88411f5c 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -253,7 +253,8 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l if (fact_bucket != 0xff && fact_bucket != j) continue; - if (!bucket_info[j].hp_cores) + /* core count must be valid for CPU power domain */ + if (!bucket_info[j].hp_cores && id->cpu >= 0) break; print = 1; From c5a295caefa33ce7599d7afbe7a2e9b1bc8d92a2 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 21:21:46 +0800 Subject: [PATCH 51/61] tools/power/x86/intel-speed-select: Hide invalid TRL level TRL levels with Zero ratio values is meaningless. Prevent these TRL levels from being displayed. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 1723e88411f5c..d8b789b9656ae 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -505,6 +505,9 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level } for (k = 0; k < trl_max_levels; k++) { + if (!ctdp_level->trl_ratios[k][0]) + continue; + snprintf(header, sizeof(header), "turbo-ratio-limits-%s", isst_get_trl_level_name(k)); format_and_print(outf, level + 2, header, NULL); From c7ff8ff3b29ee031a2194f67b5ceced9b77fdc21 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 21:26:23 +0800 Subject: [PATCH 52/61] tools/power/x86/intel-speed-select: Remove cpu mask display for non-cpu power domain Non CPU power domains will not have any CPUs. So don't display any CPU count or enable mask. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: subject and changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-display.c | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index d8b789b9656ae..e3573895c8b0f 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -356,31 +356,33 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level ctdp_level->level); format_and_print(outf, level + 1, header, NULL); - snprintf(header, sizeof(header), "cpu-count"); - j = get_cpu_count(id); - snprintf(value, sizeof(value), "%d", j); - format_and_print(outf, level + 2, header, value); - - j = CPU_COUNT_S(ctdp_level->core_cpumask_size, - ctdp_level->core_cpumask); - if (j) { - snprintf(header, sizeof(header), "enable-cpu-count"); + if (id->cpu >= 0) { + snprintf(header, sizeof(header), "cpu-count"); + j = get_cpu_count(id); snprintf(value, sizeof(value), "%d", j); format_and_print(outf, level + 2, header, value); - } - if (ctdp_level->core_cpumask_size) { - snprintf(header, sizeof(header), "enable-cpu-mask"); - printcpumask(sizeof(value), value, - ctdp_level->core_cpumask_size, - ctdp_level->core_cpumask); - format_and_print(outf, level + 2, header, value); + j = CPU_COUNT_S(ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask); + if (j) { + snprintf(header, sizeof(header), "enable-cpu-count"); + snprintf(value, sizeof(value), "%d", j); + format_and_print(outf, level + 2, header, value); + } - snprintf(header, sizeof(header), "enable-cpu-list"); - printcpulist(sizeof(value), value, - ctdp_level->core_cpumask_size, - ctdp_level->core_cpumask); - format_and_print(outf, level + 2, header, value); + if (ctdp_level->core_cpumask_size) { + snprintf(header, sizeof(header), "enable-cpu-mask"); + printcpumask(sizeof(value), value, + ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask); + format_and_print(outf, level + 2, header, value); + + snprintf(header, sizeof(header), "enable-cpu-list"); + printcpulist(sizeof(value), value, + ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask); + format_and_print(outf, level + 2, header, value); + } } snprintf(header, sizeof(header), "thermal-design-power-ratio"); From 14f0cf6cfa53a3a4f2f713b1d54eb71e96ff34cb Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 2 Feb 2023 15:55:25 +0800 Subject: [PATCH 53/61] tools/power/x86/intel-speed-select: Avoid setting duplicate tdp level If the new TDP level requetsted is same as the current TDP level, don't call into driver to change level. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-config.c | 79 +++++++++++-------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 47431c577668b..b10c6ecd9777f 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1229,46 +1229,59 @@ static void adjust_scaling_max_from_base_freq(int cpu); static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3, void *arg4) { + struct isst_pkg_ctdp pkg_dev; int ret; + ret = isst_get_ctdp_levels(id, &pkg_dev); + if (ret) { + isst_display_error_info_message(1, "Get TDP level failed", 0, 0); + isst_ctdp_display_information_end(outf); + exit(1); + } + + if (pkg_dev.current_level == tdp_level) { + debug_printf("TDP level already set. Skipped\n"); + goto display_result; + } + ret = isst_set_tdp_level(id, tdp_level); if (ret) { isst_display_error_info_message(1, "Set TDP level failed", 0, 0); isst_ctdp_display_information_end(outf); exit(1); - } else { - isst_display_result(id, outf, "perf-profile", "set_tdp_level", - ret); - if (force_online_offline) { - struct isst_pkg_ctdp_level_info ctdp_level; - - /* Wait for updated base frequencies */ - usleep(2000); - - /* Adjusting uncore freq */ - isst_adjust_uncore_freq(id, tdp_level, &ctdp_level); - - fprintf(stderr, "Option is set to online/offline\n"); - ctdp_level.core_cpumask_size = - alloc_cpu_set(&ctdp_level.core_cpumask); - ret = isst_get_coremask_info(id, tdp_level, &ctdp_level); - if (ret) { - isst_display_error_info_message(1, "Can't get coremask, online/offline option is ignored", 0, 0); - return; - } - if (ctdp_level.cpu_count) { - int i, max_cpus = get_topo_max_cpus(); - for (i = 0; i < max_cpus; ++i) { - if (!is_cpu_in_power_domain(i, id)) - continue; - if (CPU_ISSET_S(i, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask)) { - fprintf(stderr, "online cpu %d\n", i); - set_cpu_online_offline(i, 1); - adjust_scaling_max_from_base_freq(i); - } else { - fprintf(stderr, "offline cpu %d\n", i); - set_cpu_online_offline(i, 0); - } + } + +display_result: + isst_display_result(id, outf, "perf-profile", "set_tdp_level", ret); + if (force_online_offline) { + struct isst_pkg_ctdp_level_info ctdp_level; + + /* Wait for updated base frequencies */ + usleep(2000); + + /* Adjusting uncore freq */ + isst_adjust_uncore_freq(id, tdp_level, &ctdp_level); + + fprintf(stderr, "Option is set to online/offline\n"); + ctdp_level.core_cpumask_size = + alloc_cpu_set(&ctdp_level.core_cpumask); + ret = isst_get_coremask_info(id, tdp_level, &ctdp_level); + if (ret) { + isst_display_error_info_message(1, "Can't get coremask, online/offline option is ignored", 0, 0); + return; + } + if (ctdp_level.cpu_count) { + int i, max_cpus = get_topo_max_cpus(); + for (i = 0; i < max_cpus; ++i) { + if (!is_cpu_in_power_domain(i, id)) + continue; + if (CPU_ISSET_S(i, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask)) { + fprintf(stderr, "online cpu %d\n", i); + set_cpu_online_offline(i, 1); + adjust_scaling_max_from_base_freq(i); + } else { + fprintf(stderr, "offline cpu %d\n", i); + set_cpu_online_offline(i, 0); } } } From d0e12c46f518620551d719b19b93777dafd0b5e6 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 13 Sep 2022 20:23:19 +0800 Subject: [PATCH 54/61] tools/power/x86/intel-speed-select: Add cpu id check Some operations applies to cpu-power-domain only. Add check for cpu id for these functions. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-config.c | 16 ++++++++++++++-- tools/power/x86/intel-speed-select/isst-core.c | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index b10c6ecd9777f..a04005622b323 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -800,6 +800,9 @@ void set_cpu_mask_from_punit_coremask(struct isst_id *id, unsigned long long cor { int i, cnt = 0; + if (id->cpu < 0) + return; + *cpu_cnt = 0; for (i = 0; i < 64; ++i) { @@ -1253,7 +1256,7 @@ static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, vo display_result: isst_display_result(id, outf, "perf-profile", "set_tdp_level", ret); - if (force_online_offline) { + if (force_online_offline && id->cpu >= 0) { struct isst_pkg_ctdp_level_info ctdp_level; /* Wait for updated base frequencies */ @@ -1547,6 +1550,9 @@ static void set_scaling_min_to_cpuinfo_max(struct isst_id *id) { int i; + if (id->cpu < 0) + return; + for (i = 0; i < get_topo_max_cpus(); ++i) { if (!is_cpu_in_power_domain(i, id)) continue; @@ -1564,6 +1570,9 @@ static void set_scaling_min_to_cpuinfo_min(struct isst_id *id) { int i; + if (id->cpu < 0) + return; + for (i = 0; i < get_topo_max_cpus(); ++i) { if (!is_cpu_in_power_domain(i, id)) continue; @@ -1643,6 +1652,9 @@ static int set_pbf_core_power(struct isst_id *id) struct isst_pkg_ctdp pkg_dev; int ret; + if (id->cpu < 0) + return 0; + ret = isst_get_ctdp_levels(id, &pkg_dev); if (ret) { debug_printf("isst_get_ctdp_levels failed"); @@ -1888,7 +1900,7 @@ static void set_fact_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *a struct isst_pkg_ctdp pkg_dev; ret = isst_get_ctdp_levels(id, &pkg_dev); - if (!ret) + if (!ret && id->cpu >= 0) ret = isst_set_trl(id, fact_trl); if (ret && auto_mode) isst_pm_qos_config(id, 0, 0); diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index f0b96d7078d3a..f55fef4c13a7a 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -287,6 +287,9 @@ int isst_set_trl_from_current_tdp(struct isst_id *id, unsigned long long trl) unsigned long long msr_trl; int ret; + if (id->cpu < 0) + return 0; + if (trl) { msr_trl = trl; } else { From 137ba3b13aacf80b64d363dd7cff69c2aed161f0 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 7 Jan 2023 21:45:42 +0800 Subject: [PATCH 55/61] tools/power/x86/intel-speed-select: Fix clos-max display with TPMI I/F Comparing clos_config->clos_max with 255 is broken with TPMI I/F because of different isst_get_disp_freq_multiplier() used. Checking for clos_config->clos_max * isst_get_disp_freq_multiplier() instead. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index e3573895c8b0f..218fb317f7ada 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -606,7 +606,7 @@ void isst_clos_display_information(struct isst_id *id, FILE *outf, int clos, format_and_print(outf, level + 2, header, value); snprintf(header, sizeof(header), "clos-max"); - if (clos_config->clos_max == 0xff) + if ((clos_config->clos_max * isst_get_disp_freq_multiplier()) == 25500) snprintf(value, sizeof(value), "Max Turbo frequency"); else snprintf(value, sizeof(value), "%d MHz", clos_config->clos_max * isst_get_disp_freq_multiplier()); From 57797f19d5a78b5a84b7452790f7da22865f6420 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 22 Feb 2023 03:26:29 -0800 Subject: [PATCH 56/61] tools/power/x86/intel-speed-select: Add missing free cpuset During perf level change cpuset is allocated but not freed. Add free_cpu_set() in success and failure path. Although this is not an issue, as the program will exit after processing of online/offline, but for completeness add the free_cpu_set(). Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-config.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index a04005622b323..a9bd87b4d4ee1 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1271,7 +1271,7 @@ static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, vo ret = isst_get_coremask_info(id, tdp_level, &ctdp_level); if (ret) { isst_display_error_info_message(1, "Can't get coremask, online/offline option is ignored", 0, 0); - return; + goto free_mask; } if (ctdp_level.cpu_count) { int i, max_cpus = get_topo_max_cpus(); @@ -1288,6 +1288,8 @@ static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, vo } } } +free_mask: + free_cpu_set(ctdp_level.core_cpumask); } } From 997074df658e444e79a5294b685b77b08a3c414c Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 22 Feb 2023 03:42:19 -0800 Subject: [PATCH 57/61] tools/power/x86/intel-speed-select: Use cgroup v2 isolation On supported systems, it is possiible to isolate CPUs instead of CPU online/offline. This is optional and can be specified using -g option when running as daemon or in combination with -o option for SST-PP level change. CPU isolation doesn't isolate IRQs. So IRQs needs to be moved away from isoolated CPUs. This can be done via IRQ sysfs or irqbalance daemon. The IRQ balance daemon is also capable to parse thermal HFI messages to move IRQs away from CPUS, which are supposed be isolated. But this requires version released after July 2022. Signed-off-by: Srinivas Pandruvada --- .../x86/intel-speed-select/isst-config.c | 155 +++++++++++++++++- .../x86/intel-speed-select/isst-daemon.c | 15 +- tools/power/x86/intel-speed-select/isst.h | 5 + 3 files changed, 173 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index a9bd87b4d4ee1..c4d00426cb6a5 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -44,6 +44,7 @@ static int cmd_help; static int force_online_offline; static int auto_mode; static int fact_enable_fail; +static int cgroupv2; /* clos related */ static int current_clos = -1; @@ -834,7 +835,137 @@ int find_phy_core_num(int logical_cpu) return -EINVAL; } +int use_cgroupv2(void) +{ + return cgroupv2; +} + +int enable_cpuset_controller(void) +{ + int fd, ret; + + fd = open("/sys/fs/cgroup/cgroup.subtree_control", O_RDWR, 0); + if (fd < 0) { + debug_printf("Can't activate cpuset controller\n"); + debug_printf("Either you are not root user or CGroup v2 is not supported\n"); + return fd; + } + + ret = write(fd, " +cpuset", strlen(" +cpuset")); + close(fd); + + if (ret == -1) { + debug_printf("Can't activate cpuset controller: Write failed\n"); + return ret; + } + + return 0; +} + +int isolate_cpus(struct isst_id *id, int mask_size, cpu_set_t *cpu_mask, int level) +{ + int i, first, curr_index, index, ret, fd; + static char str[512], dir_name[64]; + static char cpuset_cpus[128]; + int str_len = sizeof(str); + DIR *dir; + + snprintf(dir_name, sizeof(dir_name), "/sys/fs/cgroup/%d-%d-%d", id->pkg, id->die, id->punit); + dir = opendir(dir_name); + if (!dir) { + ret = mkdir(dir_name, 0744); + if (ret) { + debug_printf("Can't create dir:%s errno:%d\n", dir_name, errno); + return ret; + } + } + closedir(dir); + + if (!level) { + sprintf(cpuset_cpus, "%s/cpuset.cpus.partition", dir_name); + + fd = open(cpuset_cpus, O_RDWR, 0); + if (fd < 0) { + return fd; + } + + ret = write(fd, "member", strlen("member")); + if (ret == -1) { + printf("Can't update to member\n"); + return ret; + } + + return 0; + } + + if (!CPU_COUNT_S(mask_size, cpu_mask)) { + return -1; + } + curr_index = 0; + first = 1; + str[0] = '\0'; + for (i = 0; i < get_topo_max_cpus(); ++i) { + if (!is_cpu_in_power_domain(i, id)) + continue; + + if (CPU_ISSET_S(i, mask_size, cpu_mask)) + continue; + + if (!first) { + index = snprintf(&str[curr_index], + str_len - curr_index, ","); + curr_index += index; + if (curr_index >= str_len) + break; + } + index = snprintf(&str[curr_index], str_len - curr_index, "%d", + i); + curr_index += index; + if (curr_index >= str_len) + break; + first = 0; + } + + debug_printf("isolated CPUs list: package:%d curr_index:%d [%s]\n", id->pkg, curr_index ,str); + + snprintf(cpuset_cpus, sizeof(cpuset_cpus), "%s/cpuset.cpus", dir_name); + + fd = open(cpuset_cpus, O_RDWR, 0); + if (fd < 0) { + return fd; + } + + ret = write(fd, str, strlen(str)); + close(fd); + + if (ret == -1) { + debug_printf("Can't activate cpuset controller: Write failed\n"); + return ret; + } + + snprintf(cpuset_cpus, sizeof(cpuset_cpus), "%s/cpuset.cpus.partition", dir_name); + + fd = open(cpuset_cpus, O_RDWR, 0); + if (fd < 0) { + return fd; + } + + ret = write(fd, "isolated", strlen("isolated")); + if (ret == -1) { + debug_printf("Can't update to isolated\n"); + ret = write(fd, "root", strlen("root")); + if (ret == -1) + debug_printf("Can't update to root\n"); + } + + close(fd); + + if (ret < 0) + return ret; + + return 0; +} static int isst_fill_platform_info(void) { @@ -1273,6 +1404,23 @@ static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, vo isst_display_error_info_message(1, "Can't get coremask, online/offline option is ignored", 0, 0); goto free_mask; } + + if (use_cgroupv2()) { + int ret; + + fprintf(stderr, "Using cgroup v2 in lieu of online/offline\n"); + ret = enable_cpuset_controller(); + if (ret) + goto use_offline; + + ret = isolate_cpus(id, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask, tdp_level); + if (ret) + goto use_offline; + + goto free_mask; + } + +use_offline: if (ctdp_level.cpu_count) { int i, max_cpus = get_topo_max_cpus(); for (i = 0; i < max_cpus; ++i) { @@ -2787,6 +2935,7 @@ static void usage(void) printf("\t[-b|--oob : Start a daemon to process HFI events for perf profile change from Out of Band agent.\n"); printf("\t[-n|--no-daemon : Don't run as daemon. By default --oob will turn on daemon mode\n"); printf("\t[-w|--delay : Delay for reading config level state change in OOB poll mode.\n"); + printf("\t[-g|--cgroupv2 : Try to use cgroup v2 CPU isolation instead of CPU online/offline.\n"); printf("\nResult format\n"); printf("\tResult display uses a common format for each command:\n"); printf("\tResults are formatted in text/JSON with\n"); @@ -2839,6 +2988,7 @@ static void cmdline(int argc, char **argv) { "oob", no_argument, 0, 'b' }, { "no-daemon", no_argument, 0, 'n' }, { "poll-interval", required_argument, 0, 'w' }, + { "cgroupv2", required_argument, 0, 'g' }, { 0, 0, 0, 0 } }; @@ -2869,7 +3019,7 @@ static void cmdline(int argc, char **argv) goto out; progname = argv[0]; - while ((opt = getopt_long_only(argc, argv, "+c:df:hio:vabw:n", long_options, + while ((opt = getopt_long_only(argc, argv, "+c:df:hio:vabw:ng", long_options, &option_index)) != -1) { switch (opt) { case 'a': @@ -2928,6 +3078,9 @@ static void cmdline(int argc, char **argv) } poll_interval = ret; break; + case 'g': + cgroupv2 = 1; + break; default: usage(); } diff --git a/tools/power/x86/intel-speed-select/isst-daemon.c b/tools/power/x86/intel-speed-select/isst-daemon.c index 6fa2942b5e12f..12053fa435429 100644 --- a/tools/power/x86/intel-speed-select/isst-daemon.c +++ b/tools/power/x86/intel-speed-select/isst-daemon.c @@ -83,6 +83,19 @@ void process_level_change(struct isst_id *id) return; } + if (use_cgroupv2()) { + int ret; + + ret = enable_cpuset_controller(); + if (ret) + goto use_offline; + + isolate_cpus(id, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask, pkg_dev.current_level); + + goto free_mask; + } + +use_offline: if (ctdp_level.cpu_count) { int i, max_cpus = get_topo_max_cpus(); for (i = 0; i < max_cpus; ++i) { @@ -97,7 +110,7 @@ void process_level_change(struct isst_id *id) } } } - +free_mask: free_cpu_set(ctdp_level.core_cpumask); } diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 1984cc564fa91..6a37c26b1ef71 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -315,4 +315,9 @@ extern void hfi_exit(void); extern struct isst_platform_ops *mbox_get_platform_ops(void); extern struct isst_platform_ops *tpmi_get_platform_ops(void); +/* Cgroup related interface */ +extern int enable_cpuset_controller(void); +extern int isolate_cpus(struct isst_id *id, int mask_size, cpu_set_t *cpu_mask, int level); +extern int use_cgroupv2(void); + #endif From a835ff56dd9ce2dfc53526085ba8efc2807b9bcb Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 23 Feb 2023 05:59:24 -0800 Subject: [PATCH 58/61] tools/power/x86/intel-speed-select: Display AMX base frequency AMX frequency is present in non TPMI platforms also. When platform supports, the value is non zero. So, display AMX base frequency when non zero, irrespective of platform API version. Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-core-mbox.c | 5 +++-- tools/power/x86/intel-speed-select/isst-display.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 6eafef925d1ac..6951a9c31dc55 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -383,10 +383,11 @@ static void _get_p1_info(struct isst_id *id, int config_index, ctdp_level->sse_p1 = resp & GENMASK(7, 0); ctdp_level->avx2_p1 = (resp & GENMASK(15, 8)) >> 8; ctdp_level->avx512_p1 = (resp & GENMASK(23, 16)) >> 16; + ctdp_level->amx_p1 = (resp & GENMASK(31, 24)) >> 24; debug_printf( - "cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d\n", + "cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d amx_p1:%d\n", id->cpu, config_index, resp, ctdp_level->sse_p1, - ctdp_level->avx2_p1, ctdp_level->avx512_p1); + ctdp_level->avx2_p1, ctdp_level->avx512_p1, ctdp_level->amx_p1); } static void _get_uncore_mem_freq(struct isst_id *id, int config_index, diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 218fb317f7ada..0e364b35f0933 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -424,7 +424,7 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level format_and_print(outf, level + 2, header, value); } - if (api_version() > 1 && ctdp_level->amx_p1) { + if (ctdp_level->amx_p1) { snprintf(header, sizeof(header), "base-frequency-amx(MHz)"); snprintf(value, sizeof(value), "%d", ctdp_level->amx_p1 * isst_get_disp_freq_multiplier()); From 1d54b139f43482a5d394f26ce47aa9949dec6e76 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 22 Feb 2023 22:53:02 -0800 Subject: [PATCH 59/61] tools/power/x86/intel-speed-select: Identify Emerald Rapids There are some differences compared to Sapphire Rapids. So, add a separate API. Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-config.c | 11 ++++++++++- tools/power/x86/intel-speed-select/isst-core-mbox.c | 2 +- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index c4d00426cb6a5..2ad8726edc06b 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -114,12 +114,21 @@ int is_skx_based_platform(void) int is_spr_platform(void) { - if (cpu_model == 0x8F || cpu_model == 0xCF) + if (cpu_model == 0x8F) return 1; return 0; } +int is_emr_platform(void) +{ + if (cpu_model == 0xCF) + return 1; + + return 0; +} + + int is_icx_platform(void) { if (cpu_model == 0x6A || cpu_model == 0x6C) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 6951a9c31dc55..c860be30fe5ea 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -404,7 +404,7 @@ static void _get_uncore_mem_freq(struct isst_id *id, int config_index, } ctdp_level->mem_freq = resp & GENMASK(7, 0); - if (is_spr_platform()) { + if (is_spr_platform() || is_emr_platform()) { ctdp_level->mem_freq *= 200; } else if (is_icx_platform()) { if (ctdp_level->mem_freq < 7) { diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 6a37c26b1ef71..54fc21575d56d 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -298,6 +298,7 @@ extern int isst_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap); extern void isst_display_error_info_message(int error, char *msg, int arg_valid, int arg); extern int is_skx_based_platform(void); extern int is_spr_platform(void); +extern int is_emr_platform(void); extern int is_icx_platform(void); extern void isst_trl_display_information(struct isst_id *id, FILE *outf, unsigned long long trl); From 2c00056f54299983009c13a8790fa004e5337d16 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 23 Feb 2023 06:36:46 -0800 Subject: [PATCH 60/61] tools/power/x86/intel-speed-select: Change TRL display for Emerald Rapids Emerald Rapids doesn't specify TRL (Turbo Ratio Limits) based instruction types. Instead it specifies 5 TRL levels, which can be anyone of the instruction types. Increase TRL levels to 5 for Emerald Rapids. Also change display to show by level number. Show only non zero level values. Signed-off-by: Srinivas Pandruvada --- .../power/x86/intel-speed-select/isst-core-mbox.c | 15 +++++++++++++++ tools/power/x86/intel-speed-select/isst-display.c | 9 ++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index c860be30fe5ea..24bea57f4ff53 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -8,6 +8,8 @@ static int mbox_delay; static int mbox_retries = 3; +#define MAX_TRL_LEVELS_EMR 5 + static int mbox_get_disp_freq_multiplier(void) { return DISP_FREQ_MULTIPLIER; @@ -15,11 +17,24 @@ static int mbox_get_disp_freq_multiplier(void) static int mbox_get_trl_max_levels(void) { + if (is_emr_platform()) + return MAX_TRL_LEVELS_EMR; + return 3; } static char *mbox_get_trl_level_name(int level) { + if (is_emr_platform()) { + static char level_str[18]; + + if (level >= MAX_TRL_LEVELS_EMR) + return NULL; + + snprintf(level_str, sizeof(level_str), "level-%d", level); + return level_str; + } + switch (level) { case 0: return "sse"; diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 0e364b35f0933..0403d42ab1bae 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -283,9 +283,9 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l bucket_info[j].hp_cores); format_and_print(outf, base_level + 2, header, value); for (i = 0; i < trl_max_levels; i++) { - if (fact_avx != 0xFF && !(fact_avx & (1 << i))) + if (!bucket_info[j].hp_ratios[i] || (fact_avx != 0xFF && !(fact_avx & (1 << i)))) continue; - if (i == 0 && api_version() == 1) + if (i == 0 && api_version() == 1 && !is_emr_platform()) snprintf(header, sizeof(header), "high-priority-max-frequency(MHz)"); else @@ -301,8 +301,11 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l format_and_print(outf, base_level + 1, header, NULL); for (j = 0; j < trl_max_levels; j++) { + if (!fact_info->lp_ratios[j]) + continue; + /* No AVX level name for SSE to be consistent with previous formatting */ - if (j == 0 && api_version() == 1) + if (j == 0 && api_version() == 1 && !is_emr_platform()) snprintf(header, sizeof(header), "low-priority-max-frequency(MHz)"); else snprintf(header, sizeof(header), "low-priority-max-%s-frequency(MHz)", From 19799d3ae2edec99435b792cfe76b1cba74665fe Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 17 Oct 2022 19:34:14 +0800 Subject: [PATCH 61/61] tools/power/x86/intel-speed-select: Update version Update tool and supported API version. This is the first version which supports newer Xeon platforms with TPMI support. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: subject and changelog edits] Signed-off-by: Srinivas Pandruvada --- tools/power/x86/intel-speed-select/isst-config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 2ad8726edc06b..2ca0cedd418f0 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -15,9 +15,9 @@ struct process_cmd_struct { int arg; }; -static const char *version_str = "v1.14"; +static const char *version_str = "v1.15"; -static const int supported_api_ver = 1; +static const int supported_api_ver = 2; static struct isst_if_platform_info isst_platform_info; static char *progname; static int debug_flag;