cpufreq: amd-pstate: implement suspend and resume callbacks
authorPerry Yuan <Perry.Yuan@amd.com>
Tue, 31 Jan 2023 09:00:11 +0000 (17:00 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 3 Feb 2023 20:59:42 +0000 (21:59 +0100)
add suspend and resume support for the AMD processors by amd_pstate_epp
driver instance.

When the CPPC is suspended, EPP driver will set EPP profile to 'power'
profile and set max/min perf to lowest perf value.
When resume happens, it will restore the MSR registers with
previous cached value.

Acked-by: Huang Rui <ray.huang@amd.com>
Reviewed-by: Mario Limonciello <Mario.Limonciello@amd.com>
Reviewed-by: Wyes Karny <wyes.karny@amd.com>
Tested-by: Wyes Karny <wyes.karny@amd.com>
Signed-off-by: Perry Yuan <Perry.Yuan@amd.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpufreq/amd-pstate.c

index 26f6ac8..4e3770e 100644 (file)
@@ -1087,6 +1087,44 @@ static int amd_pstate_epp_verify_policy(struct cpufreq_policy_data *policy)
        return 0;
 }
 
+static int amd_pstate_epp_suspend(struct cpufreq_policy *policy)
+{
+       struct amd_cpudata *cpudata = policy->driver_data;
+       int ret;
+
+       /* avoid suspending when EPP is not enabled */
+       if (cppc_state != AMD_PSTATE_ACTIVE)
+               return 0;
+
+       /* set this flag to avoid setting core offline*/
+       cpudata->suspended = true;
+
+       /* disable CPPC in lowlevel firmware */
+       ret = amd_pstate_enable(false);
+       if (ret)
+               pr_err("failed to suspend, return %d\n", ret);
+
+       return 0;
+}
+
+static int amd_pstate_epp_resume(struct cpufreq_policy *policy)
+{
+       struct amd_cpudata *cpudata = policy->driver_data;
+
+       if (cpudata->suspended) {
+               mutex_lock(&amd_pstate_limits_lock);
+
+               /* enable amd pstate from suspend state*/
+               amd_pstate_epp_reenable(cpudata);
+
+               mutex_unlock(&amd_pstate_limits_lock);
+
+               cpudata->suspended = false;
+       }
+
+       return 0;
+}
+
 static struct cpufreq_driver amd_pstate_driver = {
        .flags          = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS,
        .verify         = amd_pstate_verify,
@@ -1108,6 +1146,8 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
        .exit           = amd_pstate_epp_cpu_exit,
        .offline        = amd_pstate_epp_cpu_offline,
        .online         = amd_pstate_epp_cpu_online,
+       .suspend        = amd_pstate_epp_suspend,
+       .resume         = amd_pstate_epp_resume,
        .name           = "amd_pstate_epp",
        .attr           = amd_pstate_epp_attr,
 };