tools/power/x86/intel-speed-select: Add support for core-power discovery
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Tue, 14 Jan 2020 19:22:14 +0000 (11:22 -0800)
committerAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Mon, 20 Jan 2020 09:39:31 +0000 (11:39 +0200)
It is possible that BIOS may not enable core-power feature. In this case
this additional interface will allow to enable from this utility. Also
the information dump, includes the current status of core-power.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
tools/power/x86/intel-speed-select/isst-core.c
tools/power/x86/intel-speed-select/isst-display.c
tools/power/x86/intel-speed-select/isst.h

index d14c7bcd327af1c17ae947027c39684ac10bbb98..81a119f688a3a04b4c82bd29289043a9627764f0 100644 (file)
@@ -6,6 +6,44 @@
 
 #include "isst.h"
 
+int isst_write_pm_config(int cpu, int cp_state)
+{
+       unsigned int req, resp;
+       int ret;
+
+       if (cp_state)
+               req = BIT(16);
+       else
+               req = 0;
+
+       ret = isst_send_mbox_command(cpu, WRITE_PM_CONFIG, PM_FEATURE, 0, req,
+                                    &resp);
+       if (ret)
+               return ret;
+
+       debug_printf("cpu:%d WRITE_PM_CONFIG resp:%x\n", cpu, resp);
+
+       return 0;
+}
+
+int isst_read_pm_config(int cpu, int *cp_state, int *cp_cap)
+{
+       unsigned int resp;
+       int ret;
+
+       ret = isst_send_mbox_command(cpu, READ_PM_CONFIG, PM_FEATURE, 0, 0,
+                                    &resp);
+       if (ret)
+               return ret;
+
+       debug_printf("cpu:%d READ_PM_CONFIG resp:%x\n", cpu, resp);
+
+       *cp_state = resp & BIT(16);
+       *cp_cap = resp & BIT(0) ? 1 : 0;
+
+       return 0;
+}
+
 int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev)
 {
        unsigned int resp;
@@ -36,6 +74,7 @@ int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev)
 int isst_get_ctdp_control(int cpu, int config_index,
                          struct isst_pkg_ctdp_level_info *ctdp_level)
 {
+       int cp_state, cp_cap;
        unsigned int resp;
        int ret;
 
@@ -50,6 +89,15 @@ int isst_get_ctdp_control(int cpu, int config_index,
        ctdp_level->fact_enabled = !!(resp & BIT(16));
        ctdp_level->pbf_enabled = !!(resp & BIT(17));
 
+       ret = isst_read_pm_config(cpu, &cp_state, &cp_cap);
+       if (ret) {
+               debug_printf("cpu:%d pm_config is not supported \n", cpu);
+       } else {
+               debug_printf("cpu:%d pm_config SST-CP state:%d cap:%d \n", 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",
                cpu, resp, ctdp_level->fact_support, ctdp_level->pbf_support,
@@ -779,6 +827,13 @@ int isst_pm_qos_config(int cpu, int enable_clos, int priority_type)
                        debug_printf("Turbo-freq feature must be disabled first\n");
                        return -EINVAL;
                }
+               ret = isst_write_pm_config(cpu, 0);
+               if (ret)
+                       perror("isst_write_pm_config\n");
+       } else {
+               ret = isst_write_pm_config(cpu, 1);
+               if (ret)
+                       perror("isst_write_pm_config\n");
        }
 
        ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
index 040dd09d5eee41ac23cb4f62b47ede5cac09e597..1d1439036c1295237c1de518dde3e5ad1fa30f4c 100644 (file)
@@ -418,6 +418,17 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
                        snprintf(value, sizeof(value), "unsupported");
                format_and_print(outf, base_level + 4, header, value);
 
+               snprintf(header, sizeof(header),
+                        "speed-select-core-power");
+               if (ctdp_level->sst_cp_support) {
+                       if (ctdp_level->sst_cp_enabled)
+                               snprintf(value, sizeof(value), "enabled");
+                       else
+                               snprintf(value, sizeof(value), "disabled");
+               } else
+                       snprintf(value, sizeof(value), "unsupported");
+               format_and_print(outf, base_level + 4, header, value);
+
                if (is_clx_n_platform()) {
                        if (ctdp_level->pbf_support)
                                _isst_pbf_display_information(cpu, outf,
index cdf0f8a6dbbfabf3958a9549a991ba08ba3d531b..ad5aa6341d0fc10da35137fe44b6211c52e81589 100644 (file)
 #define PM_CLOS_OFFSET                         0x08
 #define PQR_ASSOC_OFFSET                       0x20
 
+#define READ_PM_CONFIG                         0x94
+#define WRITE_PM_CONFIG                                0x95
+#define PM_FEATURE                             0x03
+
 #define DISP_FREQ_MULTIPLIER 100
 
 struct isst_clos_config {
@@ -119,6 +123,8 @@ struct isst_pkg_ctdp_level_info {
        int pbf_support;
        int fact_enabled;
        int pbf_enabled;
+       int sst_cp_support;
+       int sst_cp_enabled;
        int tdp_ratio;
        int active;
        int tdp_control;