128 lines
4.7 KiB
Diff
128 lines
4.7 KiB
Diff
diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
|
|
--- a/drivers/cpufreq/amd-pstate-ut.c
|
|
+++ b/drivers/cpufreq/amd-pstate-ut.c
|
|
@@ -560,6 +560,11 @@ static int amd_pstate_ut_check_freq_attrs(u32 index)
|
|
static int __init amd_pstate_ut_init(void)
|
|
{
|
|
u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases);
|
|
+ enum amd_pstate_mode mode = amd_pstate_get_status();
|
|
+
|
|
+ /* don't test if no running amd-pstate driver */
|
|
+ if (mode == AMD_PSTATE_UNDEFINED || mode == AMD_PSTATE_DISABLE)
|
|
+ return -EOPNOTSUPP;
|
|
|
|
for (i = 0; i < arr_size; i++) {
|
|
int ret;
|
|
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
|
|
--- a/drivers/cpufreq/amd-pstate.c
|
|
+++ b/drivers/cpufreq/amd-pstate.c
|
|
@@ -199,7 +199,7 @@ static inline int get_mode_idx_from_str(const char *str, size_t size)
|
|
|
|
static DEFINE_MUTEX(amd_pstate_driver_lock);
|
|
|
|
-static u8 msr_get_epp(struct amd_cpudata *cpudata)
|
|
+static int msr_get_epp(struct amd_cpudata *cpudata)
|
|
{
|
|
u64 value;
|
|
int ret;
|
|
@@ -215,12 +215,12 @@ static u8 msr_get_epp(struct amd_cpudata *cpudata)
|
|
|
|
DEFINE_STATIC_CALL(amd_pstate_get_epp, msr_get_epp);
|
|
|
|
-static inline s16 amd_pstate_get_epp(struct amd_cpudata *cpudata)
|
|
+static inline int amd_pstate_get_epp(struct amd_cpudata *cpudata)
|
|
{
|
|
return static_call(amd_pstate_get_epp)(cpudata);
|
|
}
|
|
|
|
-static u8 shmem_get_epp(struct amd_cpudata *cpudata)
|
|
+static int shmem_get_epp(struct amd_cpudata *cpudata)
|
|
{
|
|
u64 epp;
|
|
int ret;
|
|
@@ -526,9 +526,6 @@ static int shmem_init_perf(struct amd_cpudata *cpudata)
|
|
WRITE_ONCE(cpudata->perf, perf);
|
|
WRITE_ONCE(cpudata->prefcore_ranking, cppc_perf.highest_perf);
|
|
|
|
- if (cppc_state == AMD_PSTATE_ACTIVE)
|
|
- return 0;
|
|
-
|
|
ret = cppc_get_auto_sel(cpudata->cpu, &auto_sel);
|
|
if (ret) {
|
|
pr_warn("failed to get auto_sel, ret: %d\n", ret);
|
|
@@ -1174,6 +1171,9 @@ static int amd_pstate_power_supply_notifier(struct notifier_block *nb,
|
|
if (cpudata->current_profile != PLATFORM_PROFILE_BALANCED)
|
|
return 0;
|
|
|
|
+ if (!policy)
|
|
+ return NOTIFY_OK;
|
|
+
|
|
epp = amd_pstate_get_balanced_epp(policy);
|
|
|
|
ret = amd_pstate_set_epp(policy, epp);
|
|
@@ -1209,6 +1209,9 @@ static int amd_pstate_profile_set(struct device *dev,
|
|
struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpudata->cpu);
|
|
int ret;
|
|
|
|
+ if (!policy)
|
|
+ return -ENODEV;
|
|
+
|
|
switch (profile) {
|
|
case PLATFORM_PROFILE_LOW_POWER:
|
|
ret = amd_pstate_set_epp(policy, AMD_CPPC_EPP_POWERSAVE);
|
|
@@ -1877,6 +1880,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
|
|
struct amd_cpudata *cpudata;
|
|
union perf_cached perf;
|
|
struct device *dev;
|
|
+ int default_epp;
|
|
int ret;
|
|
|
|
/*
|
|
@@ -1925,6 +1929,13 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
|
|
|
|
policy->boost_supported = READ_ONCE(cpudata->boost_supported);
|
|
|
|
+ /* Fetch the firmware programmed default EPP value */
|
|
+ default_epp = amd_pstate_get_epp(cpudata);
|
|
+ if (default_epp < 0) {
|
|
+ ret = default_epp;
|
|
+ goto free_cpudata1;
|
|
+ }
|
|
+
|
|
/*
|
|
* Set the policy to provide a valid fallback value in case
|
|
* the default cpufreq governor is neither powersave nor performance.
|
|
@@ -1932,7 +1943,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
|
|
if (amd_pstate_acpi_pm_profile_server() ||
|
|
amd_pstate_acpi_pm_profile_undefined()) {
|
|
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
|
|
- cpudata->epp_default_ac = cpudata->epp_default_dc = amd_pstate_get_epp(cpudata);
|
|
+ cpudata->epp_default_ac = cpudata->epp_default_dc = default_epp;
|
|
cpudata->current_profile = PLATFORM_PROFILE_PERFORMANCE;
|
|
} else {
|
|
policy->policy = CPUFREQ_POLICY_POWERSAVE;
|
|
diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
|
|
--- a/drivers/cpufreq/amd-pstate.h
|
|
+++ b/drivers/cpufreq/amd-pstate.h
|
|
@@ -32,6 +32,7 @@
|
|
* @min_limit_perf: Cached value of the performance corresponding to policy->min
|
|
* @max_limit_perf: Cached value of the performance corresponding to policy->max
|
|
* @bios_min_perf: Cached perf value corresponding to the "Requested CPU Min Frequency" BIOS option
|
|
+ * @val: Raw 64-bit value for atomic access via READ_ONCE()/WRITE_ONCE()
|
|
*/
|
|
union perf_cached {
|
|
struct {
|
|
@@ -89,7 +90,12 @@ struct amd_aperf_mperf {
|
|
* @epp_default_ac: Default EPP value for AC power source
|
|
* @epp_default_dc: Default EPP value for DC power source
|
|
* @dynamic_epp: Whether dynamic EPP is enabled
|
|
+ * @raw_epp: Whether the last EPP write was a raw numeric value rather than a
|
|
+ * named preference
|
|
* @power_nb: Notifier block for power events
|
|
+ * @current_profile: Currently selected platform profile option
|
|
+ * @ppdev: Device registered with the platform profile handler
|
|
+ * @profile_name: Name under which @ppdev is registered
|
|
*
|
|
* The amd_cpudata is key private data for each CPU thread in AMD P-State, and
|
|
* represents all the attributes and goals that AMD P-State requests at runtime.
|