mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 20:14:06 +02:00
The second round of changes for amd-pstate in 6.11:
* Enables amd-pstate by default in "shared memory" designs without a dedicated MSR. * Adds extra infrastructure for debugging problems. * Bug fixes found for init/unload failure -----BEGIN PGP SIGNATURE----- iQJOBAABCgA4FiEECwtuSU6dXvs5GA2aLRkspiR3AnYFAmZ55QYaHG1hcmlvLmxp bW9uY2llbGxvQGFtZC5jb20ACgkQLRkspiR3AnbdeBAAwuyBuny/RLem9FwllL3A azRXb5Tb8GCfoX+mi1CKGLe8UyLLugojEs5O/7AuEiX3GaovkumhFv0lO3r+JJAD IfDwZUeYCU5wD1dVFEW57t3ePxicjXEZH+gDljngu9wJ2po7XiI0NgDoSwdGKnO0 4mQjSyDnHIualbJ2/uFX33Ne0mK/Mh9wVe6obV2Scg/WzT1xjOx6XQUyKSXaE2Lj AhhDXfGsXSjmYCX/EYS/acjcDB2EaXy0oUbP8ilO806rkwTq2G0bnCFZx4wQmlY3 kmpGYRBkh/HNAuKZnry1VB+7RKoIuyQKNoZkHA1C+GJKp92KUFGAw5/8AbDw1dWx P9KBZtqnMX60gvzoj9sitW7m0zmW3W15yMl7gBJWxpPcnswYlliigWavPnsPYVLp sDlFlCOaX/dWUFlyjW1WrvJ6KeMyhoV/CvEBSqE5bxRx4ma0k5XzS3aI48M5p1PN L0u78y79mYV7BctoKj94lExpF9EqwUw4EviVx0eAaP6i+36GfGRXuLyAAB9Hixoi thz5C+DQefLYxDq/7fmbCI+De8f/huvLYzgFeN/bzBV+B/ZpkKPinih62FvGU/9n nKXdfwroJFInf3r9e87lOtJXvbFDP0+mFbjBZXxKdN4TB1W6lnv7gH8Uk7PKcRAz NxBK7Nrd6LcGUI8YVi4FdcM= =Eea8 -----END PGP SIGNATURE----- Merge tag 'amd-pstate-v6.11-2024-06-24' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/superm1/linux Merge the second round of changes for amd-pstate in 6.11 from Mario Limonciello: "* Enables amd-pstate by default in "shared memory" designs without a dedicated MSR. * Adds extra infrastructure for debugging problems. * Bug fixes found for init/unload failure." * tag 'amd-pstate-v6.11-2024-06-24' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/superm1/linux: cpufreq: simplify boolean parsing with kstrtobool in store function cpufreq: amd-pstate: Don't create attributes when registration fails cpufreq: amd-pstate: Make amd-pstate unit tests depend on amd-pstate cpufreq/amd-pstate: fix setting policy current frequency value cpufreq: amd-pstate: auto-load pstate driver by default cpufreq: amd-pstate: enable shared memory type CPPC by default cpufreq: amd-pstate: switch boot_cpu_has() to cpu_feature_enabled() Documentation: PM: amd-pstate: add guided mode to the Operation mode cpufreq: amd-pstate: add debug message while CPPC is supported and disabled by SBIOS cpufreq: amd-pstate: show CPPC debug message if CPPC is not supported cpufreq: amd-pstate: remove unused variable nominal_freq cpufreq: amd-pstate: optimize the initial frequency values verification cpufreq: amd-pstate: Allow users to write 'default' EPP string
This commit is contained in:
commit
787025a462
|
|
@ -406,7 +406,7 @@ control its functionality at the system level. They are located in the
|
|||
``/sys/devices/system/cpu/amd_pstate/`` directory and affect all CPUs.
|
||||
|
||||
``status``
|
||||
Operation mode of the driver: "active", "passive" or "disable".
|
||||
Operation mode of the driver: "active", "passive", "guided" or "disable".
|
||||
|
||||
"active"
|
||||
The driver is functional and in the ``active mode``
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ config X86_AMD_PSTATE_DEFAULT_MODE
|
|||
config X86_AMD_PSTATE_UT
|
||||
tristate "selftest for AMD Processor P-State driver"
|
||||
depends on X86 && ACPI_PROCESSOR
|
||||
depends on X86_AMD_PSTATE
|
||||
default n
|
||||
help
|
||||
This kernel module is used for testing. It's safe to say M here.
|
||||
|
|
|
|||
|
|
@ -86,15 +86,6 @@ struct quirk_entry {
|
|||
u32 lowest_freq;
|
||||
};
|
||||
|
||||
/*
|
||||
* TODO: We need more time to fine tune processors with shared memory solution
|
||||
* with community together.
|
||||
*
|
||||
* There are some performance drops on the CPU benchmarks which reports from
|
||||
* Suse. We are co-working with them to fine tune the shared memory solution. So
|
||||
* we disable it by default to go acpi-cpufreq on these processors and add a
|
||||
* module parameter to be able to enable it manually for debugging.
|
||||
*/
|
||||
static struct cpufreq_driver *current_pstate_driver;
|
||||
static struct cpufreq_driver amd_pstate_driver;
|
||||
static struct cpufreq_driver amd_pstate_epp_driver;
|
||||
|
|
@ -158,7 +149,7 @@ static int __init dmi_matched_7k62_bios_bug(const struct dmi_system_id *dmi)
|
|||
* broken BIOS lack of nominal_freq and lowest_freq capabilities
|
||||
* definition in ACPI tables
|
||||
*/
|
||||
if (boot_cpu_has(X86_FEATURE_ZEN2)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_ZEN2)) {
|
||||
quirks = dmi->driver_data;
|
||||
pr_info("Overriding nominal and lowest frequencies for %s\n", dmi->ident);
|
||||
return 1;
|
||||
|
|
@ -200,7 +191,7 @@ static s16 amd_pstate_get_epp(struct amd_cpudata *cpudata, u64 cppc_req_cached)
|
|||
u64 epp;
|
||||
int ret;
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_CPPC)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
||||
if (!cppc_req_cached) {
|
||||
epp = rdmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ,
|
||||
&cppc_req_cached);
|
||||
|
|
@ -253,7 +244,7 @@ static int amd_pstate_set_epp(struct amd_cpudata *cpudata, u32 epp)
|
|||
int ret;
|
||||
struct cppc_perf_ctrls perf_ctrls;
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_CPPC)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
||||
u64 value = READ_ONCE(cpudata->cppc_req_cached);
|
||||
|
||||
value &= ~GENMASK_ULL(31, 24);
|
||||
|
|
@ -282,10 +273,8 @@ static int amd_pstate_set_energy_pref_index(struct amd_cpudata *cpudata,
|
|||
int epp = -EINVAL;
|
||||
int ret;
|
||||
|
||||
if (!pref_index) {
|
||||
pr_debug("EPP pref_index is invalid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!pref_index)
|
||||
epp = cpudata->epp_default;
|
||||
|
||||
if (epp == -EINVAL)
|
||||
epp = epp_values[pref_index];
|
||||
|
|
@ -522,6 +511,8 @@ static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)
|
|||
static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
|
||||
u32 des_perf, u32 max_perf, bool fast_switch, int gov_flags)
|
||||
{
|
||||
unsigned long max_freq;
|
||||
struct cpufreq_policy *policy = cpufreq_cpu_get(cpudata->cpu);
|
||||
u64 prev = READ_ONCE(cpudata->cppc_req_cached);
|
||||
u64 value = prev;
|
||||
|
||||
|
|
@ -531,6 +522,9 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
|
|||
cpudata->max_limit_perf);
|
||||
des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf);
|
||||
|
||||
max_freq = READ_ONCE(cpudata->max_limit_freq);
|
||||
policy->cur = div_u64(des_perf * max_freq, max_perf);
|
||||
|
||||
if ((cppc_state == AMD_PSTATE_GUIDED) && (gov_flags & CPUFREQ_GOV_DYNAMIC_SWITCHING)) {
|
||||
min_perf = des_perf;
|
||||
des_perf = 0;
|
||||
|
|
@ -652,10 +646,9 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
|
|||
unsigned long capacity)
|
||||
{
|
||||
unsigned long max_perf, min_perf, des_perf,
|
||||
cap_perf, lowest_nonlinear_perf, max_freq;
|
||||
cap_perf, lowest_nonlinear_perf;
|
||||
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
|
||||
struct amd_cpudata *cpudata = policy->driver_data;
|
||||
unsigned int target_freq;
|
||||
|
||||
if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq)
|
||||
amd_pstate_update_min_max_limit(policy);
|
||||
|
|
@ -663,7 +656,6 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
|
|||
|
||||
cap_perf = READ_ONCE(cpudata->highest_perf);
|
||||
lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
|
||||
max_freq = READ_ONCE(cpudata->max_freq);
|
||||
|
||||
des_perf = cap_perf;
|
||||
if (target_perf < capacity)
|
||||
|
|
@ -681,8 +673,6 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
|
|||
max_perf = min_perf;
|
||||
|
||||
des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf);
|
||||
target_freq = div_u64(des_perf * max_freq, max_perf);
|
||||
policy->cur = target_freq;
|
||||
|
||||
amd_pstate_update(cpudata, min_perf, des_perf, max_perf, true,
|
||||
policy->governor->flags);
|
||||
|
|
@ -754,7 +744,7 @@ static int amd_pstate_get_highest_perf(int cpu, u32 *highest_perf)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_CPPC)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
||||
u64 cap1;
|
||||
|
||||
ret = rdmsrl_safe_on_cpu(cpu, MSR_AMD_CPPC_CAP1, &cap1);
|
||||
|
|
@ -926,12 +916,30 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
|
|||
WRITE_ONCE(cpudata->nominal_freq, nominal_freq);
|
||||
WRITE_ONCE(cpudata->max_freq, max_freq);
|
||||
|
||||
/**
|
||||
* Below values need to be initialized correctly, otherwise driver will fail to load
|
||||
* max_freq is calculated according to (nominal_freq * highest_perf)/nominal_perf
|
||||
* lowest_nonlinear_freq is a value between [min_freq, nominal_freq]
|
||||
* Check _CPC in ACPI table objects if any values are incorrect
|
||||
*/
|
||||
if (min_freq <= 0 || max_freq <= 0 || nominal_freq <= 0 || min_freq > max_freq) {
|
||||
pr_err("min_freq(%d) or max_freq(%d) or nominal_freq(%d) value is incorrect\n",
|
||||
min_freq, max_freq, nominal_freq * 1000);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (lowest_nonlinear_freq <= min_freq || lowest_nonlinear_freq > nominal_freq * 1000) {
|
||||
pr_err("lowest_nonlinear_freq(%d) value is out of range [min_freq(%d), nominal_freq(%d)]\n",
|
||||
lowest_nonlinear_freq, min_freq, nominal_freq * 1000);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
int min_freq, max_freq, nominal_freq, ret;
|
||||
int min_freq, max_freq, ret;
|
||||
struct device *dev;
|
||||
struct amd_cpudata *cpudata;
|
||||
|
||||
|
|
@ -962,16 +970,6 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
|
|||
|
||||
min_freq = READ_ONCE(cpudata->min_freq);
|
||||
max_freq = READ_ONCE(cpudata->max_freq);
|
||||
nominal_freq = READ_ONCE(cpudata->nominal_freq);
|
||||
|
||||
if (min_freq <= 0 || max_freq <= 0 ||
|
||||
nominal_freq <= 0 || min_freq > max_freq) {
|
||||
dev_err(dev,
|
||||
"min_freq(%d) or max_freq(%d) or nominal_freq (%d) value is incorrect, check _CPC in ACPI tables\n",
|
||||
min_freq, max_freq, nominal_freq);
|
||||
ret = -EINVAL;
|
||||
goto free_cpudata1;
|
||||
}
|
||||
|
||||
policy->cpuinfo.transition_latency = amd_pstate_get_transition_latency(policy->cpu);
|
||||
policy->transition_delay_us = amd_pstate_get_transition_delay_us(policy->cpu);
|
||||
|
|
@ -985,7 +983,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
|
|||
/* It will be updated by governor */
|
||||
policy->cur = policy->cpuinfo.min_freq;
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_CPPC))
|
||||
if (cpu_feature_enabled(X86_FEATURE_CPPC))
|
||||
policy->fast_switch_possible = true;
|
||||
|
||||
ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
|
||||
|
|
@ -1218,7 +1216,7 @@ static int amd_pstate_change_mode_without_dvr_change(int mode)
|
|||
|
||||
cppc_state = mode;
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_CPPC) || cppc_state == AMD_PSTATE_ACTIVE)
|
||||
if (cpu_feature_enabled(X86_FEATURE_CPPC) || cppc_state == AMD_PSTATE_ACTIVE)
|
||||
return 0;
|
||||
|
||||
for_each_present_cpu(cpu) {
|
||||
|
|
@ -1391,7 +1389,7 @@ static bool amd_pstate_acpi_pm_profile_undefined(void)
|
|||
|
||||
static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
int min_freq, max_freq, nominal_freq, ret;
|
||||
int min_freq, max_freq, ret;
|
||||
struct amd_cpudata *cpudata;
|
||||
struct device *dev;
|
||||
u64 value;
|
||||
|
|
@ -1424,15 +1422,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
|
|||
|
||||
min_freq = READ_ONCE(cpudata->min_freq);
|
||||
max_freq = READ_ONCE(cpudata->max_freq);
|
||||
nominal_freq = READ_ONCE(cpudata->nominal_freq);
|
||||
if (min_freq <= 0 || max_freq <= 0 ||
|
||||
nominal_freq <= 0 || min_freq > max_freq) {
|
||||
dev_err(dev,
|
||||
"min_freq(%d) or max_freq(%d) or nominal_freq(%d) value is incorrect, check _CPC in ACPI tables\n",
|
||||
min_freq, max_freq, nominal_freq);
|
||||
ret = -EINVAL;
|
||||
goto free_cpudata1;
|
||||
}
|
||||
|
||||
policy->cpuinfo.min_freq = min_freq;
|
||||
policy->cpuinfo.max_freq = max_freq;
|
||||
|
|
@ -1441,7 +1430,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
|
|||
|
||||
policy->driver_data = cpudata;
|
||||
|
||||
cpudata->epp_cached = amd_pstate_get_epp(cpudata, 0);
|
||||
cpudata->epp_cached = cpudata->epp_default = amd_pstate_get_epp(cpudata, 0);
|
||||
|
||||
policy->min = policy->cpuinfo.min_freq;
|
||||
policy->max = policy->cpuinfo.max_freq;
|
||||
|
|
@ -1456,7 +1445,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
|
|||
else
|
||||
policy->policy = CPUFREQ_POLICY_POWERSAVE;
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_CPPC)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
||||
ret = rdmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, &value);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
@ -1546,7 +1535,7 @@ static void amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
|
|||
epp = 0;
|
||||
|
||||
/* Set initial EPP value */
|
||||
if (boot_cpu_has(X86_FEATURE_CPPC)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
||||
value &= ~GENMASK_ULL(31, 24);
|
||||
value |= (u64)epp << 24;
|
||||
}
|
||||
|
|
@ -1569,6 +1558,12 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
|
|||
|
||||
amd_pstate_epp_update_limit(policy);
|
||||
|
||||
/*
|
||||
* policy->cur is never updated with the amd_pstate_epp driver, but it
|
||||
* is used as a stale frequency value. So, keep it within limits.
|
||||
*/
|
||||
policy->cur = policy->min;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1585,7 +1580,7 @@ static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata)
|
|||
value = READ_ONCE(cpudata->cppc_req_cached);
|
||||
max_perf = READ_ONCE(cpudata->highest_perf);
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_CPPC)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
||||
wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
|
||||
} else {
|
||||
perf_ctrls.max_perf = max_perf;
|
||||
|
|
@ -1619,7 +1614,7 @@ static void amd_pstate_epp_offline(struct cpufreq_policy *policy)
|
|||
value = READ_ONCE(cpudata->cppc_req_cached);
|
||||
|
||||
mutex_lock(&amd_pstate_limits_lock);
|
||||
if (boot_cpu_has(X86_FEATURE_CPPC)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
||||
cpudata->epp_policy = CPUFREQ_POLICY_UNKNOWN;
|
||||
|
||||
/* Set max perf same as min perf */
|
||||
|
|
@ -1746,6 +1741,46 @@ static int __init amd_pstate_set_driver(int mode_idx)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* CPPC function is not supported for family ID 17H with model_ID ranging from 0x10 to 0x2F.
|
||||
* show the debug message that helps to check if the CPU has CPPC support for loading issue.
|
||||
*/
|
||||
static bool amd_cppc_supported(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
bool warn = false;
|
||||
|
||||
if ((boot_cpu_data.x86 == 0x17) && (boot_cpu_data.x86_model < 0x30)) {
|
||||
pr_debug_once("CPPC feature is not supported by the processor\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the CPPC feature is disabled in the BIOS for processors that support MSR-based CPPC,
|
||||
* the AMD Pstate driver may not function correctly.
|
||||
* Check the CPPC flag and display a warning message if the platform supports CPPC.
|
||||
* Note: below checking code will not abort the driver registeration process because of
|
||||
* the code is added for debugging purposes.
|
||||
*/
|
||||
if (!cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_ZEN1) || cpu_feature_enabled(X86_FEATURE_ZEN2)) {
|
||||
if (c->x86_model > 0x60 && c->x86_model < 0xaf)
|
||||
warn = true;
|
||||
} else if (cpu_feature_enabled(X86_FEATURE_ZEN3) || cpu_feature_enabled(X86_FEATURE_ZEN4)) {
|
||||
if ((c->x86_model > 0x10 && c->x86_model < 0x1F) ||
|
||||
(c->x86_model > 0x40 && c->x86_model < 0xaf))
|
||||
warn = true;
|
||||
} else if (cpu_feature_enabled(X86_FEATURE_ZEN5)) {
|
||||
warn = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (warn)
|
||||
pr_warn_once("The CPPC feature is supported but currently disabled by the BIOS.\n"
|
||||
"Please enable it if your BIOS has the CPPC option.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __init amd_pstate_init(void)
|
||||
{
|
||||
struct device *dev_root;
|
||||
|
|
@ -1754,6 +1789,11 @@ static int __init amd_pstate_init(void)
|
|||
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
|
||||
return -ENODEV;
|
||||
|
||||
/* show debug message only if CPPC is not supported */
|
||||
if (!amd_cppc_supported())
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* show warning message when BIOS broken or ACPI disabled */
|
||||
if (!acpi_cpc_valid()) {
|
||||
pr_warn_once("the _CPC object is not present in SBIOS or ACPI disabled\n");
|
||||
return -ENODEV;
|
||||
|
|
@ -1768,35 +1808,43 @@ static int __init amd_pstate_init(void)
|
|||
/* check if this machine need CPPC quirks */
|
||||
dmi_check_system(amd_pstate_quirks_table);
|
||||
|
||||
switch (cppc_state) {
|
||||
case AMD_PSTATE_UNDEFINED:
|
||||
/*
|
||||
* determine the driver mode from the command line or kernel config.
|
||||
* If no command line input is provided, cppc_state will be AMD_PSTATE_UNDEFINED.
|
||||
* command line options will override the kernel config settings.
|
||||
*/
|
||||
|
||||
if (cppc_state == AMD_PSTATE_UNDEFINED) {
|
||||
/* Disable on the following configs by default:
|
||||
* 1. Undefined platforms
|
||||
* 2. Server platforms
|
||||
* 3. Shared memory designs
|
||||
*/
|
||||
if (amd_pstate_acpi_pm_profile_undefined() ||
|
||||
amd_pstate_acpi_pm_profile_server() ||
|
||||
!boot_cpu_has(X86_FEATURE_CPPC)) {
|
||||
amd_pstate_acpi_pm_profile_server()) {
|
||||
pr_info("driver load is disabled, boot with specific mode to enable this\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
ret = amd_pstate_set_driver(CONFIG_X86_AMD_PSTATE_DEFAULT_MODE);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
/* get driver mode from kernel config option [1:4] */
|
||||
cppc_state = CONFIG_X86_AMD_PSTATE_DEFAULT_MODE;
|
||||
}
|
||||
|
||||
switch (cppc_state) {
|
||||
case AMD_PSTATE_DISABLE:
|
||||
pr_info("driver load is disabled, boot with specific mode to enable this\n");
|
||||
return -ENODEV;
|
||||
case AMD_PSTATE_PASSIVE:
|
||||
case AMD_PSTATE_ACTIVE:
|
||||
case AMD_PSTATE_GUIDED:
|
||||
ret = amd_pstate_set_driver(cppc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* capability check */
|
||||
if (boot_cpu_has(X86_FEATURE_CPPC)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
||||
pr_debug("AMD CPPC MSR based functionality is supported\n");
|
||||
if (cppc_state != AMD_PSTATE_ACTIVE)
|
||||
current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;
|
||||
|
|
@ -1810,13 +1858,15 @@ static int __init amd_pstate_init(void)
|
|||
/* enable amd pstate feature */
|
||||
ret = amd_pstate_enable(true);
|
||||
if (ret) {
|
||||
pr_err("failed to enable with return %d\n", ret);
|
||||
pr_err("failed to enable driver mode(%d)\n", cppc_state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = cpufreq_register_driver(current_pstate_driver);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
pr_err("failed to register with return %d\n", ret);
|
||||
goto disable_driver;
|
||||
}
|
||||
|
||||
dev_root = bus_get_dev_root(&cpu_subsys);
|
||||
if (dev_root) {
|
||||
|
|
@ -1832,6 +1882,8 @@ static int __init amd_pstate_init(void)
|
|||
|
||||
global_attr_free:
|
||||
cpufreq_unregister_driver(current_pstate_driver);
|
||||
disable_driver:
|
||||
amd_pstate_enable(false);
|
||||
return ret;
|
||||
}
|
||||
device_initcall(amd_pstate_init);
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ struct amd_cpudata {
|
|||
u32 policy;
|
||||
u64 cppc_cap1_cached;
|
||||
bool suspended;
|
||||
s16 epp_default;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_AMD_PSTATE_H */
|
||||
|
|
|
|||
|
|
@ -614,10 +614,9 @@ static ssize_t show_boost(struct kobject *kobj,
|
|||
static ssize_t store_boost(struct kobject *kobj, struct kobj_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int ret, enable;
|
||||
bool enable;
|
||||
|
||||
ret = sscanf(buf, "%d", &enable);
|
||||
if (ret != 1 || enable < 0 || enable > 1)
|
||||
if (kstrtobool(buf, &enable))
|
||||
return -EINVAL;
|
||||
|
||||
if (cpufreq_boost_trigger_state(enable)) {
|
||||
|
|
@ -641,10 +640,10 @@ static ssize_t show_local_boost(struct cpufreq_policy *policy, char *buf)
|
|||
static ssize_t store_local_boost(struct cpufreq_policy *policy,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int ret, enable;
|
||||
int ret;
|
||||
bool enable;
|
||||
|
||||
ret = kstrtoint(buf, 10, &enable);
|
||||
if (ret || enable < 0 || enable > 1)
|
||||
if (kstrtobool(buf, &enable))
|
||||
return -EINVAL;
|
||||
|
||||
if (!cpufreq_driver->boost_enabled)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user