Commit 50ddd2f7 authored by Perry Yuan's avatar Perry Yuan Committed by Rafael J. Wysocki
Browse files

cpufreq: amd-pstate: implement suspend and resume callbacks



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: default avatarHuang Rui <ray.huang@amd.com>
Reviewed-by: default avatarMario Limonciello <Mario.Limonciello@amd.com>
Reviewed-by: default avatarWyes Karny <wyes.karny@amd.com>
Tested-by: default avatarWyes Karny <wyes.karny@amd.com>
Signed-off-by: default avatarPerry Yuan <Perry.Yuan@amd.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent d4da12f8
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -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,
};