@@ -94,6 +94,10 @@ static bool cppc_enabled;
static bool amd_pstate_prefcore = true;
static struct quirk_entry *quirks;
+/* export the amd_pstate_global_params for unit test */
+struct amd_pstate_global_params amd_pstate_global_params;
+EXPORT_SYMBOL_GPL(amd_pstate_global_params);
+
/*
* AMD Energy Preference Performance (EPP)
* The EPP is used in the CCLK DPM controller to drive
@@ -686,7 +690,7 @@ static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state)
if (!cpudata->boost_supported) {
pr_err("Boost mode is not supported by this processor or SBIOS\n");
- return -EINVAL;
+ return -ENOTSUPP;
}
if (state)
@@ -704,18 +708,42 @@ static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state)
return 0;
}
-static void amd_pstate_boost_init(struct amd_cpudata *cpudata)
+static int amd_pstate_init_boost_support(struct amd_cpudata *cpudata)
{
- u32 highest_perf, nominal_perf;
+ u64 boost_val;
+ int ret = -1;
- highest_perf = READ_ONCE(cpudata->highest_perf);
- nominal_perf = READ_ONCE(cpudata->nominal_perf);
+ /*
+ * If platform has no CPB support or disble it, initialize current driver
+ * boost_enabled state to be false, it is not an error for cpufreq core to handle.
+ */
+ if (!cpu_feature_enabled(X86_FEATURE_CPB)) {
+ pr_debug_once("Boost CPB capabilities not present in the processor\n");
+ ret = 0;
+ goto exit_err;
+ }
- if (highest_perf <= nominal_perf)
- return;
+ ret = rdmsrl_on_cpu(cpudata->cpu, MSR_K7_HWCR, &boost_val);
+ if (ret) {
+ pr_err_once("failed to read initial CPU boost state!\n");
+ ret = -EIO;
+ goto exit_err;
+ }
+
+ amd_pstate_global_params.cpb_supported = !(boost_val & MSR_K7_HWCR_CPB_DIS);
+ if (amd_pstate_global_params.cpb_supported) {
+ current_pstate_driver->boost_enabled = true;
+ cpudata->boost_supported = true;
+ }
+
+ amd_pstate_global_params.cpb_boost = amd_pstate_global_params.cpb_supported;
+ return 0;
- cpudata->boost_supported = true;
- current_pstate_driver->boost_enabled = true;
+exit_err:
+ cpudata->boost_supported = false;
+ current_pstate_driver->boost_enabled = false;
+ amd_pstate_global_params.cpb_boost = false;
+ return ret;
}
static void amd_perf_ctl_reset(unsigned int cpu)
@@ -1005,7 +1033,6 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
policy->driver_data = cpudata;
- amd_pstate_boost_init(cpudata);
if (!current_pstate_driver->adjust_perf)
current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;
@@ -1387,6 +1414,21 @@ static bool amd_pstate_acpi_pm_profile_undefined(void)
return false;
}
+static int amd_pstate_init_boost(struct cpufreq_policy *policy)
+{
+ struct amd_cpudata *cpudata = policy->driver_data;
+ int ret;
+
+ /* initialize cpu cores boot state */
+ ret = amd_pstate_init_boost_support(cpudata);
+ if (ret)
+ return ret;
+
+ policy->boost_enabled = READ_ONCE(cpudata->boost_supported);
+
+ return 0;
+}
+
static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
{
int min_freq, max_freq, ret;
@@ -1456,7 +1498,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
return ret;
WRITE_ONCE(cpudata->cppc_cap1_cached, value);
}
- amd_pstate_boost_init(cpudata);
return 0;
@@ -1701,6 +1742,7 @@ static struct cpufreq_driver amd_pstate_driver = {
.exit = amd_pstate_cpu_exit,
.suspend = amd_pstate_cpu_suspend,
.resume = amd_pstate_cpu_resume,
+ .init_boost = amd_pstate_init_boost,
.set_boost = amd_pstate_set_boost,
.update_limits = amd_pstate_update_limits,
.name = "amd-pstate",
@@ -1718,6 +1760,7 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
.suspend = amd_pstate_epp_suspend,
.resume = amd_pstate_epp_resume,
.update_limits = amd_pstate_update_limits,
+ .init_boost = amd_pstate_init_boost,
.name = "amd-pstate-epp",
.attr = amd_pstate_epp_attr,
};
@@ -102,4 +102,17 @@ struct amd_cpudata {
s16 epp_default;
};
+/**
+ * struct amd_pstate_global_params - Global parameters, mostly tunable via sysfs.
+ * @cpb_boost: Whether or not to use boost CPU P-states.
+ * @cpb_supported: Whether or not CPU boost P-states are available
+ * based on the MSR_K7_HWCR bit[25] state
+ */
+struct amd_pstate_global_params {
+ bool cpb_boost;
+ bool cpb_supported;
+};
+
+extern struct amd_pstate_global_params amd_pstate_global_params;
+
#endif /* _LINUX_AMD_PSTATE_H */