Message ID | 20230615063300.4030172-1-perry.yuan@amd.com |
---|---|
State | New |
Headers | show |
Series | [v2,1/4] ACPI: CPPC: Add a symbol to check if the preferred profile is a server | expand |
On Thu, Jun 15, 2023 at 02:33:00PM +0800, Yuan, Perry wrote: > From: Mario Limonciello <mario.limonciello@amd.com> > > Users are having more success with amd-pstate since the introduction > of EPP and Guided modes. To expose the driver to more users by default > introduce a kernel configuration option for setting the default mode. > > Users can use an integer to map out which default mode they want to use > in lieu of a kernel command line option. > > This will default to EPP, but only if: > 1) The CPU supports an MSR. > 2) The system profile is identified > 3) The system profile is identified as a non-server by the FADT. > > Link: https://gitlab.freedesktop.org/hadess/power-profiles-daemon/-/merge_requests/121 > Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com> > Co-developed-by: Perry Yuan <perry.yuan@amd.com> > Signed-off-by: Perry Yuan <perry.yuan@amd.com> > Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Acked-by: Huang Rui <ray.huang@amd.com> > --- > drivers/cpufreq/Kconfig.x86 | 17 +++++++++ > drivers/cpufreq/amd-pstate.c | 73 ++++++++++++++++++++++++------------ > include/linux/amd-pstate.h | 4 +- > 3 files changed, 68 insertions(+), 26 deletions(-) > > diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 > index 00476e94db90..438c9e75a04d 100644 > --- a/drivers/cpufreq/Kconfig.x86 > +++ b/drivers/cpufreq/Kconfig.x86 > @@ -51,6 +51,23 @@ config X86_AMD_PSTATE > > If in doubt, say N. > > +config X86_AMD_PSTATE_DEFAULT_MODE > + int "AMD Processor P-State default mode" > + depends on X86_AMD_PSTATE > + default 3 if X86_AMD_PSTATE > + range 1 4 > + help > + Select the default mode the amd-pstate driver will use on > + supported hardware. > + The value set has the following meanings: > + 1 -> Disabled > + 2 -> Passive > + 3 -> Active (EPP) > + 4 -> Guided > + > + For details, take a look at: > + <file:Documentation/admin-guide/pm/amd-pstate.rst>. > + > config X86_AMD_PSTATE_UT > tristate "selftest for AMD Processor P-State driver" > depends on X86 && ACPI_PROCESSOR > diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c > index c9d296ebf81e..b400d1ee8e64 100644 > --- a/drivers/cpufreq/amd-pstate.c > +++ b/drivers/cpufreq/amd-pstate.c > @@ -62,7 +62,7 @@ > static struct cpufreq_driver *current_pstate_driver; > static struct cpufreq_driver amd_pstate_driver; > static struct cpufreq_driver amd_pstate_epp_driver; > -static int cppc_state = AMD_PSTATE_DISABLE; > +static int cppc_state = AMD_PSTATE_UNDEFINED; > > /* > * AMD Energy Preference Performance (EPP) > @@ -1363,6 +1363,25 @@ static struct cpufreq_driver amd_pstate_epp_driver = { > .attr = amd_pstate_epp_attr, > }; > > +static int __init amd_pstate_set_driver(int mode_idx) > +{ > + if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) { > + cppc_state = mode_idx; > + if (cppc_state == AMD_PSTATE_DISABLE) > + pr_info("driver is explicitly disabled\n"); > + > + if (cppc_state == AMD_PSTATE_ACTIVE) > + current_pstate_driver = &amd_pstate_epp_driver; > + > + if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED) > + current_pstate_driver = &amd_pstate_driver; > + > + return 0; > + } > + > + return -EINVAL; > +} > + > static int __init amd_pstate_init(void) > { > struct device *dev_root; > @@ -1370,15 +1389,6 @@ static int __init amd_pstate_init(void) > > if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) > return -ENODEV; > - /* > - * by default the pstate driver is disabled to load > - * enable the amd_pstate passive mode driver explicitly > - * with amd_pstate=passive or other modes in kernel command line > - */ > - if (cppc_state == AMD_PSTATE_DISABLE) { > - pr_info("driver load is disabled, boot with specific mode to enable this\n"); > - return -ENODEV; > - } > > if (!acpi_cpc_valid()) { > pr_warn_once("the _CPC object is not present in SBIOS or ACPI disabled\n"); > @@ -1389,6 +1399,33 @@ static int __init amd_pstate_init(void) > if (cpufreq_get_current_driver()) > return -EEXIST; > > + switch (cppc_state) { > + case AMD_PSTATE_UNDEFINED: > + /* Disable on the following configs by default: > + * 1. Undefined platforms > + * 2. Server platforms > + * 3. Shared memory designs > + */ > + if (acpi_pm_profile_undefined() || > + acpi_pm_profile_server() || > + !boot_cpu_has(X86_FEATURE_CPPC)) { > + 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; > + case AMD_PSTATE_DISABLE: > + return -ENODEV; > + case AMD_PSTATE_PASSIVE: > + case AMD_PSTATE_ACTIVE: > + case AMD_PSTATE_GUIDED: > + break; > + default: > + return -EINVAL; > + } > + > /* capability check */ > if (boot_cpu_has(X86_FEATURE_CPPC)) { > pr_debug("AMD CPPC MSR based functionality is supported\n"); > @@ -1441,21 +1478,7 @@ static int __init amd_pstate_param(char *str) > size = strlen(str); > mode_idx = get_mode_idx_from_str(str, size); > > - if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) { > - cppc_state = mode_idx; > - if (cppc_state == AMD_PSTATE_DISABLE) > - pr_info("driver is explicitly disabled\n"); > - > - if (cppc_state == AMD_PSTATE_ACTIVE) > - current_pstate_driver = &amd_pstate_epp_driver; > - > - if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED) > - current_pstate_driver = &amd_pstate_driver; > - > - return 0; > - } > - > - return -EINVAL; > + return amd_pstate_set_driver(mode_idx); > } > early_param("amd_pstate", amd_pstate_param); > > diff --git a/include/linux/amd-pstate.h b/include/linux/amd-pstate.h > index c10ebf8c42e6..446394f84606 100644 > --- a/include/linux/amd-pstate.h > +++ b/include/linux/amd-pstate.h > @@ -94,7 +94,8 @@ struct amd_cpudata { > * enum amd_pstate_mode - driver working mode of amd pstate > */ > enum amd_pstate_mode { > - AMD_PSTATE_DISABLE = 0, > + AMD_PSTATE_UNDEFINED = 0, > + AMD_PSTATE_DISABLE, > AMD_PSTATE_PASSIVE, > AMD_PSTATE_ACTIVE, > AMD_PSTATE_GUIDED, > @@ -102,6 +103,7 @@ enum amd_pstate_mode { > }; > > static const char * const amd_pstate_mode_string[] = { > + [AMD_PSTATE_UNDEFINED] = "undefined", > [AMD_PSTATE_DISABLE] = "disable", > [AMD_PSTATE_PASSIVE] = "passive", > [AMD_PSTATE_ACTIVE] = "active", > -- > 2.34.1 >
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 index 00476e94db90..438c9e75a04d 100644 --- a/drivers/cpufreq/Kconfig.x86 +++ b/drivers/cpufreq/Kconfig.x86 @@ -51,6 +51,23 @@ config X86_AMD_PSTATE If in doubt, say N. +config X86_AMD_PSTATE_DEFAULT_MODE + int "AMD Processor P-State default mode" + depends on X86_AMD_PSTATE + default 3 if X86_AMD_PSTATE + range 1 4 + help + Select the default mode the amd-pstate driver will use on + supported hardware. + The value set has the following meanings: + 1 -> Disabled + 2 -> Passive + 3 -> Active (EPP) + 4 -> Guided + + For details, take a look at: + <file:Documentation/admin-guide/pm/amd-pstate.rst>. + config X86_AMD_PSTATE_UT tristate "selftest for AMD Processor P-State driver" depends on X86 && ACPI_PROCESSOR diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index c9d296ebf81e..b400d1ee8e64 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -62,7 +62,7 @@ static struct cpufreq_driver *current_pstate_driver; static struct cpufreq_driver amd_pstate_driver; static struct cpufreq_driver amd_pstate_epp_driver; -static int cppc_state = AMD_PSTATE_DISABLE; +static int cppc_state = AMD_PSTATE_UNDEFINED; /* * AMD Energy Preference Performance (EPP) @@ -1363,6 +1363,25 @@ static struct cpufreq_driver amd_pstate_epp_driver = { .attr = amd_pstate_epp_attr, }; +static int __init amd_pstate_set_driver(int mode_idx) +{ + if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) { + cppc_state = mode_idx; + if (cppc_state == AMD_PSTATE_DISABLE) + pr_info("driver is explicitly disabled\n"); + + if (cppc_state == AMD_PSTATE_ACTIVE) + current_pstate_driver = &amd_pstate_epp_driver; + + if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED) + current_pstate_driver = &amd_pstate_driver; + + return 0; + } + + return -EINVAL; +} + static int __init amd_pstate_init(void) { struct device *dev_root; @@ -1370,15 +1389,6 @@ static int __init amd_pstate_init(void) if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) return -ENODEV; - /* - * by default the pstate driver is disabled to load - * enable the amd_pstate passive mode driver explicitly - * with amd_pstate=passive or other modes in kernel command line - */ - if (cppc_state == AMD_PSTATE_DISABLE) { - pr_info("driver load is disabled, boot with specific mode to enable this\n"); - return -ENODEV; - } if (!acpi_cpc_valid()) { pr_warn_once("the _CPC object is not present in SBIOS or ACPI disabled\n"); @@ -1389,6 +1399,33 @@ static int __init amd_pstate_init(void) if (cpufreq_get_current_driver()) return -EEXIST; + switch (cppc_state) { + case AMD_PSTATE_UNDEFINED: + /* Disable on the following configs by default: + * 1. Undefined platforms + * 2. Server platforms + * 3. Shared memory designs + */ + if (acpi_pm_profile_undefined() || + acpi_pm_profile_server() || + !boot_cpu_has(X86_FEATURE_CPPC)) { + 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; + case AMD_PSTATE_DISABLE: + return -ENODEV; + case AMD_PSTATE_PASSIVE: + case AMD_PSTATE_ACTIVE: + case AMD_PSTATE_GUIDED: + break; + default: + return -EINVAL; + } + /* capability check */ if (boot_cpu_has(X86_FEATURE_CPPC)) { pr_debug("AMD CPPC MSR based functionality is supported\n"); @@ -1441,21 +1478,7 @@ static int __init amd_pstate_param(char *str) size = strlen(str); mode_idx = get_mode_idx_from_str(str, size); - if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) { - cppc_state = mode_idx; - if (cppc_state == AMD_PSTATE_DISABLE) - pr_info("driver is explicitly disabled\n"); - - if (cppc_state == AMD_PSTATE_ACTIVE) - current_pstate_driver = &amd_pstate_epp_driver; - - if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED) - current_pstate_driver = &amd_pstate_driver; - - return 0; - } - - return -EINVAL; + return amd_pstate_set_driver(mode_idx); } early_param("amd_pstate", amd_pstate_param); diff --git a/include/linux/amd-pstate.h b/include/linux/amd-pstate.h index c10ebf8c42e6..446394f84606 100644 --- a/include/linux/amd-pstate.h +++ b/include/linux/amd-pstate.h @@ -94,7 +94,8 @@ struct amd_cpudata { * enum amd_pstate_mode - driver working mode of amd pstate */ enum amd_pstate_mode { - AMD_PSTATE_DISABLE = 0, + AMD_PSTATE_UNDEFINED = 0, + AMD_PSTATE_DISABLE, AMD_PSTATE_PASSIVE, AMD_PSTATE_ACTIVE, AMD_PSTATE_GUIDED, @@ -102,6 +103,7 @@ enum amd_pstate_mode { }; static const char * const amd_pstate_mode_string[] = { + [AMD_PSTATE_UNDEFINED] = "undefined", [AMD_PSTATE_DISABLE] = "disable", [AMD_PSTATE_PASSIVE] = "passive", [AMD_PSTATE_ACTIVE] = "active",