// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * amd-pstate.c - AMD Processor P-state Frequency Driver
 *
 * Copyright (C) 2021 Advanced Micro Devices, Inc. All Rights Reserved.
 *
 * Author: Huang Rui <ray.huang@amd.com>
 *
 * AMD P-State introduces a new CPU performance scaling design for AMD
 * processors using the ACPI Collaborative Performance and Power Control (CPPC)
 * feature which works with the AMD SMU firmware providing a finer grained
 * frequency control range. It is to replace the legacy ACPI P-States control,
 * allows a flexible, low-latency interface for the Linux kernel to directly
 * communicate the performance hints to hardware.
 *
 * AMD P-State is supported on recent AMD Zen base CPU series include some of
 * Zen2 and Zen3 processors. _CPC needs to be present in the ACPI tables of AMD
 * P-State supported system. And there are two types of hardware implementations
 * for AMD P-State: 1) Full MSR Solution and 2) Shared Memory Solution.
 * X86_FEATURE_CPPC CPU feature flag is used to distinguish the different types.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/bitfield.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/sched.h>
#include <linux/cpufreq.h>
#include <linux/compiler.h>
#include <linux/dmi.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/power_supply.h>
#include <linux/static_call.h>
#include <linux/topology.h>

#include <acpi/processor.h>
#include <acpi/cppc_acpi.h>

#include <asm/msr.h>
#include <asm/processor.h>
#include <asm/cpufeature.h>
#include <asm/cpu_device_id.h>

#include "amd-pstate.h"
#include "amd-pstate-trace.h"

#define AMD_PSTATE_TRANSITION_LATENCY	20000
#define AMD_PSTATE_TRANSITION_DELAY	1000
#define AMD_PSTATE_FAST_CPPC_TRANSITION_DELAY 600

#define AMD_CPPC_EPP_PERFORMANCE		0x00
#define AMD_CPPC_EPP_BALANCE_PERFORMANCE	0x80
#define AMD_CPPC_EPP_BALANCE_POWERSAVE		0xBF
#define AMD_CPPC_EPP_POWERSAVE			0xFF

static const char * const amd_pstate_mode_string[] = {
	[AMD_PSTATE_UNDEFINED]   = "undefined",
	[AMD_PSTATE_DISABLE]     = "disable",
	[AMD_PSTATE_PASSIVE]     = "passive",
	[AMD_PSTATE_ACTIVE]      = "active",
	[AMD_PSTATE_GUIDED]      = "guided",
};
static_assert(ARRAY_SIZE(amd_pstate_mode_string) == AMD_PSTATE_MAX);

const char *amd_pstate_get_mode_string(enum amd_pstate_mode mode)
{
	if (mode < AMD_PSTATE_UNDEFINED || mode >= AMD_PSTATE_MAX)
		mode = AMD_PSTATE_UNDEFINED;
	return amd_pstate_mode_string[mode];
}
EXPORT_SYMBOL_GPL(amd_pstate_get_mode_string);

struct quirk_entry {
	u32 nominal_freq;
	u32 lowest_freq;
};

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_UNDEFINED;
static bool amd_pstate_prefcore = true;
static bool dynamic_epp;
static struct quirk_entry *quirks;

/*
 * AMD Energy Preference Performance (EPP)
 * The EPP is used in the CCLK DPM controller to drive
 * the frequency that a core is going to operate during
 * short periods of activity. EPP values will be utilized for
 * different OS profiles (balanced, performance, power savings)
 * display strings corresponding to EPP index in the
 * energy_perf_strings[]
 *	index		String
 *-------------------------------------
 *	0		default
 *	1		performance
 *	2		balance_performance
 *	3		balance_power
 *	4		power
 *	5		custom (for raw EPP values)
 */
enum energy_perf_value_index {
	EPP_INDEX_DEFAULT = 0,
	EPP_INDEX_PERFORMANCE,
	EPP_INDEX_BALANCE_PERFORMANCE,
	EPP_INDEX_BALANCE_POWERSAVE,
	EPP_INDEX_POWERSAVE,
	EPP_INDEX_CUSTOM,
	EPP_INDEX_MAX,
};

static const char * const energy_perf_strings[] = {
	[EPP_INDEX_DEFAULT] = "default",
	[EPP_INDEX_PERFORMANCE] = "performance",
	[EPP_INDEX_BALANCE_PERFORMANCE] = "balance_performance",
	[EPP_INDEX_BALANCE_POWERSAVE] = "balance_power",
	[EPP_INDEX_POWERSAVE] = "power",
	[EPP_INDEX_CUSTOM] = "custom",
};
static_assert(ARRAY_SIZE(energy_perf_strings) == EPP_INDEX_MAX);

static unsigned int epp_values[] = {
	[EPP_INDEX_DEFAULT] = 0,
	[EPP_INDEX_PERFORMANCE] = AMD_CPPC_EPP_PERFORMANCE,
	[EPP_INDEX_BALANCE_PERFORMANCE] = AMD_CPPC_EPP_BALANCE_PERFORMANCE,
	[EPP_INDEX_BALANCE_POWERSAVE] = AMD_CPPC_EPP_BALANCE_POWERSAVE,
	[EPP_INDEX_POWERSAVE] = AMD_CPPC_EPP_POWERSAVE,
};
static_assert(ARRAY_SIZE(epp_values) == EPP_INDEX_MAX - 1);

typedef int (*cppc_mode_transition_fn)(int);

static struct quirk_entry quirk_amd_7k62 = {
	.nominal_freq = 2600,
	.lowest_freq = 550,
};

static inline u8 freq_to_perf(union perf_cached perf, u32 nominal_freq, unsigned int freq_val)
{
	u32 perf_val = DIV_ROUND_UP_ULL((u64)freq_val * perf.nominal_perf, nominal_freq);

	return (u8)clamp(perf_val, perf.lowest_perf, perf.highest_perf);
}

static inline u32 perf_to_freq(union perf_cached perf, u32 nominal_freq, u8 perf_val)
{
	return DIV_ROUND_UP_ULL((u64)nominal_freq * perf_val,
				perf.nominal_perf);
}

static int __init dmi_matched_7k62_bios_bug(const struct dmi_system_id *dmi)
{
	/**
	 * match the broken bios for family 17h processor support CPPC V2
	 * broken BIOS lack of nominal_freq and lowest_freq capabilities
	 * definition in ACPI tables
	 */
	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;
	}

	return 0;
}

static const struct dmi_system_id amd_pstate_quirks_table[] __initconst = {
	{
		.callback = dmi_matched_7k62_bios_bug,
		.ident = "AMD EPYC 7K62",
		.matches = {
			DMI_MATCH(DMI_BIOS_VERSION, "5.14"),
			DMI_MATCH(DMI_BIOS_RELEASE, "12/12/2019"),
		},
		.driver_data = &quirk_amd_7k62,
	},
	{}
};
MODULE_DEVICE_TABLE(dmi, amd_pstate_quirks_table);

static inline int get_mode_idx_from_str(const char *str, size_t size)
{
	int i;

	for (i = 0; i < AMD_PSTATE_MAX; i++) {
		if (!strncmp(str, amd_pstate_mode_string[i], size))
			return i;
	}
	return -EINVAL;
}

static DEFINE_MUTEX(amd_pstate_driver_lock);

static u8 msr_get_epp(struct amd_cpudata *cpudata)
{
	u64 value;
	int ret;

	ret = rdmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, &value);
	if (ret < 0) {
		pr_debug("Could not retrieve energy perf value (%d)\n", ret);
		return ret;
	}

	return FIELD_GET(AMD_CPPC_EPP_PERF_MASK, value);
}

DEFINE_STATIC_CALL(amd_pstate_get_epp, msr_get_epp);

static inline s16 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)
{
	u64 epp;
	int ret;

	ret = cppc_get_epp_perf(cpudata->cpu, &epp);
	if (ret < 0) {
		pr_debug("Could not retrieve energy perf value (%d)\n", ret);
		return ret;
	}

	return FIELD_GET(AMD_CPPC_EPP_PERF_MASK, epp);
}

static int msr_update_perf(struct cpufreq_policy *policy, u8 min_perf,
			   u8 des_perf, u8 max_perf, u8 epp, bool fast_switch)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	u64 value, prev;

	value = prev = READ_ONCE(cpudata->cppc_req_cached);

	FIELD_MODIFY(AMD_CPPC_MAX_PERF_MASK, &value, max_perf);
	FIELD_MODIFY(AMD_CPPC_DES_PERF_MASK, &value, des_perf);
	FIELD_MODIFY(AMD_CPPC_MIN_PERF_MASK, &value, min_perf);
	FIELD_MODIFY(AMD_CPPC_EPP_PERF_MASK, &value, epp);

	if (trace_amd_pstate_epp_perf_enabled()) {
		union perf_cached perf = READ_ONCE(cpudata->perf);

		trace_call__amd_pstate_epp_perf(cpudata->cpu,
					  perf.highest_perf,
					  epp,
					  min_perf,
					  max_perf,
					  policy->boost_enabled,
					  value != prev);
	}

	if (value == prev)
		return 0;

	if (fast_switch) {
		wrmsrq(MSR_AMD_CPPC_REQ, value);
	} else {
		int ret = wrmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);

		if (ret)
			return ret;
	}

	WRITE_ONCE(cpudata->cppc_req_cached, value);

	return 0;
}

DEFINE_STATIC_CALL(amd_pstate_update_perf, msr_update_perf);

static inline int amd_pstate_update_perf(struct cpufreq_policy *policy,
					  u8 min_perf, u8 des_perf,
					  u8 max_perf, u8 epp,
					  bool fast_switch)
{
	return static_call(amd_pstate_update_perf)(policy, min_perf, des_perf,
						   max_perf, epp, fast_switch);
}

static int msr_set_epp(struct cpufreq_policy *policy, u8 epp)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	u64 value, prev;
	int ret;

	value = prev = READ_ONCE(cpudata->cppc_req_cached);
	FIELD_MODIFY(AMD_CPPC_EPP_PERF_MASK, &value, epp);

	if (trace_amd_pstate_epp_perf_enabled()) {
		union perf_cached perf = cpudata->perf;

		trace_call__amd_pstate_epp_perf(cpudata->cpu, perf.highest_perf,
					  epp,
					  FIELD_GET(AMD_CPPC_MIN_PERF_MASK,
						    cpudata->cppc_req_cached),
					  FIELD_GET(AMD_CPPC_MAX_PERF_MASK,
						    cpudata->cppc_req_cached),
					  policy->boost_enabled,
					  value != prev);
	}

	if (value == prev)
		return 0;

	ret = wrmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
	if (ret) {
		pr_err("failed to set energy perf value (%d)\n", ret);
		return ret;
	}

	/* update both so that msr_update_perf() can effectively check */
	WRITE_ONCE(cpudata->cppc_req_cached, value);

	return ret;
}

DEFINE_STATIC_CALL(amd_pstate_set_epp, msr_set_epp);

static inline int amd_pstate_set_epp(struct cpufreq_policy *policy, u8 epp)
{
	return static_call(amd_pstate_set_epp)(policy, epp);
}

static int amd_pstate_set_floor_perf(struct cpufreq_policy *policy, u8 perf)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	u64 value, prev;
	bool changed;
	int ret;

	if (!cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO))
		return 0;

	value = prev = READ_ONCE(cpudata->cppc_req2_cached);
	FIELD_MODIFY(AMD_CPPC_FLOOR_PERF_MASK, &value, perf);

	changed = value != prev;
	if (!changed) {
		ret = 0;
		goto out_trace;
	}

	ret = wrmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ2, value);
	if (ret) {
		changed = false;
		pr_err("failed to set CPPC REQ2 value. Error (%d)\n", ret);
		goto out_trace;
	}

	WRITE_ONCE(cpudata->cppc_req2_cached, value);

out_trace:
	if (trace_amd_pstate_cppc_req2_enabled())
		trace_call__amd_pstate_cppc_req2(cpudata->cpu, perf, changed,
						 ret);
	return ret;
}

static int amd_pstate_init_floor_perf(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	u8 floor_perf;
	u64 value;
	int ret;

	if (!cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO))
		return 0;

	ret = rdmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ2, &value);
	if (ret) {
		pr_err("failed to read CPPC REQ2 value. Error (%d)\n", ret);
		return ret;
	}

	WRITE_ONCE(cpudata->cppc_req2_cached, value);
	floor_perf = FIELD_GET(AMD_CPPC_FLOOR_PERF_MASK,
			       cpudata->cppc_req2_cached);

	/* Set a sane value for floor_perf if the default value is invalid */
	if (floor_perf < cpudata->perf.lowest_perf) {
		floor_perf = cpudata->perf.nominal_perf;
		ret = amd_pstate_set_floor_perf(policy, floor_perf);
		if (ret)
			return ret;
	}


	cpudata->bios_floor_perf = floor_perf;
	cpudata->floor_freq = perf_to_freq(cpudata->perf, cpudata->nominal_freq,
					   floor_perf);
	return 0;
}

static int shmem_set_epp(struct cpufreq_policy *policy, u8 epp)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	struct cppc_perf_ctrls perf_ctrls;
	u8 epp_cached;
	u64 value;
	int ret;


	epp_cached = FIELD_GET(AMD_CPPC_EPP_PERF_MASK, cpudata->cppc_req_cached);
	if (trace_amd_pstate_epp_perf_enabled()) {
		union perf_cached perf = cpudata->perf;

		trace_call__amd_pstate_epp_perf(cpudata->cpu, perf.highest_perf,
					  epp,
					  FIELD_GET(AMD_CPPC_MIN_PERF_MASK,
						    cpudata->cppc_req_cached),
					  FIELD_GET(AMD_CPPC_MAX_PERF_MASK,
						    cpudata->cppc_req_cached),
					  policy->boost_enabled,
					  epp != epp_cached);
	}

	if (epp == epp_cached)
		return 0;

	perf_ctrls.energy_perf = epp;
	ret = cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1);
	if (ret) {
		pr_debug("failed to set energy perf value (%d)\n", ret);
		return ret;
	}

	value = READ_ONCE(cpudata->cppc_req_cached);
	FIELD_MODIFY(AMD_CPPC_EPP_PERF_MASK, &value, epp);
	WRITE_ONCE(cpudata->cppc_req_cached, value);

	return ret;
}

static inline int msr_cppc_enable(struct cpufreq_policy *policy)
{
	return wrmsrq_safe_on_cpu(policy->cpu, MSR_AMD_CPPC_ENABLE, 1);
}

static int shmem_cppc_enable(struct cpufreq_policy *policy)
{
	return cppc_set_enable(policy->cpu, 1);
}

DEFINE_STATIC_CALL(amd_pstate_cppc_enable, msr_cppc_enable);

static inline int amd_pstate_cppc_enable(struct cpufreq_policy *policy)
{
	return static_call(amd_pstate_cppc_enable)(policy);
}

static int msr_init_perf(struct amd_cpudata *cpudata)
{
	union perf_cached perf = READ_ONCE(cpudata->perf);
	u64 cap1, numerator, cppc_req;
	u8 min_perf;

	int ret = rdmsrq_safe_on_cpu(cpudata->cpu, MSR_AMD_CPPC_CAP1,
				     &cap1);
	if (ret)
		return ret;

	ret = amd_get_boost_ratio_numerator(cpudata->cpu, &numerator);
	if (ret)
		return ret;

	ret = rdmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, &cppc_req);
	if (ret)
		return ret;

	WRITE_ONCE(cpudata->cppc_req_cached, cppc_req);
	min_perf = FIELD_GET(AMD_CPPC_MIN_PERF_MASK, cppc_req);

	/*
	 * Clear out the min_perf part to check if the rest of the MSR is 0, if yes, this is an
	 * indication that the min_perf value is the one specified through the BIOS option
	 */
	cppc_req &= ~(AMD_CPPC_MIN_PERF_MASK);

	if (!cppc_req)
		perf.bios_min_perf = min_perf;

	perf.highest_perf = numerator;
	perf.max_limit_perf = numerator;
	perf.min_limit_perf = FIELD_GET(AMD_CPPC_LOWEST_PERF_MASK, cap1);
	perf.nominal_perf = FIELD_GET(AMD_CPPC_NOMINAL_PERF_MASK, cap1);
	perf.lowest_nonlinear_perf = FIELD_GET(AMD_CPPC_LOWNONLIN_PERF_MASK, cap1);
	perf.lowest_perf = FIELD_GET(AMD_CPPC_LOWEST_PERF_MASK, cap1);
	WRITE_ONCE(cpudata->perf, perf);
	WRITE_ONCE(cpudata->prefcore_ranking, FIELD_GET(AMD_CPPC_HIGHEST_PERF_MASK, cap1));
	WRITE_ONCE(cpudata->floor_perf_cnt, FIELD_GET(AMD_CPPC_FLOOR_PERF_CNT_MASK, cap1));

	return 0;
}

static int shmem_init_perf(struct amd_cpudata *cpudata)
{
	struct cppc_perf_caps cppc_perf;
	union perf_cached perf = READ_ONCE(cpudata->perf);
	u64 numerator;
	bool auto_sel;

	int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
	if (ret)
		return ret;

	ret = amd_get_boost_ratio_numerator(cpudata->cpu, &numerator);
	if (ret)
		return ret;

	perf.highest_perf = numerator;
	perf.max_limit_perf = numerator;
	perf.min_limit_perf = cppc_perf.lowest_perf;
	perf.nominal_perf = cppc_perf.nominal_perf;
	perf.lowest_nonlinear_perf = cppc_perf.lowest_nonlinear_perf;
	perf.lowest_perf = cppc_perf.lowest_perf;
	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);
		return 0;
	}

	ret = cppc_set_auto_sel(cpudata->cpu,
			(cppc_state == AMD_PSTATE_PASSIVE) ? 0 : 1);

	if (ret)
		pr_warn("failed to set auto_sel, ret: %d\n", ret);

	return ret;
}

DEFINE_STATIC_CALL(amd_pstate_init_perf, msr_init_perf);

static inline int amd_pstate_init_perf(struct amd_cpudata *cpudata)
{
	return static_call(amd_pstate_init_perf)(cpudata);
}

static int shmem_update_perf(struct cpufreq_policy *policy, u8 min_perf,
			     u8 des_perf, u8 max_perf, u8 epp, bool fast_switch)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	struct cppc_perf_ctrls perf_ctrls;
	u64 value, prev;
	int ret;

	if (cppc_state == AMD_PSTATE_ACTIVE) {
		int ret = shmem_set_epp(policy, epp);

		if (ret)
			return ret;
	}

	value = prev = READ_ONCE(cpudata->cppc_req_cached);

	FIELD_MODIFY(AMD_CPPC_MAX_PERF_MASK, &value, max_perf);
	FIELD_MODIFY(AMD_CPPC_DES_PERF_MASK, &value, des_perf);
	FIELD_MODIFY(AMD_CPPC_MIN_PERF_MASK, &value, min_perf);
	FIELD_MODIFY(AMD_CPPC_EPP_PERF_MASK, &value, epp);

	if (trace_amd_pstate_epp_perf_enabled()) {
		union perf_cached perf = READ_ONCE(cpudata->perf);

		trace_call__amd_pstate_epp_perf(cpudata->cpu,
					  perf.highest_perf,
					  epp,
					  min_perf,
					  max_perf,
					  policy->boost_enabled,
					  value != prev);
	}

	if (value == prev)
		return 0;

	perf_ctrls.max_perf = max_perf;
	perf_ctrls.min_perf = min_perf;
	perf_ctrls.desired_perf = des_perf;

	ret = cppc_set_perf(cpudata->cpu, &perf_ctrls);
	if (ret)
		return ret;

	WRITE_ONCE(cpudata->cppc_req_cached, value);

	return 0;
}

static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)
{
	u64 aperf, mperf, tsc;
	unsigned long flags;

	local_irq_save(flags);
	rdmsrq(MSR_IA32_APERF, aperf);
	rdmsrq(MSR_IA32_MPERF, mperf);
	tsc = rdtsc();

	if (cpudata->prev.mperf == mperf || cpudata->prev.tsc == tsc) {
		local_irq_restore(flags);
		return false;
	}

	local_irq_restore(flags);

	cpudata->cur.aperf = aperf;
	cpudata->cur.mperf = mperf;
	cpudata->cur.tsc =  tsc;
	cpudata->cur.aperf -= cpudata->prev.aperf;
	cpudata->cur.mperf -= cpudata->prev.mperf;
	cpudata->cur.tsc -= cpudata->prev.tsc;

	cpudata->prev.aperf = aperf;
	cpudata->prev.mperf = mperf;
	cpudata->prev.tsc = tsc;

	cpudata->freq = div64_u64((cpudata->cur.aperf * cpu_khz), cpudata->cur.mperf);

	return true;
}

static void amd_pstate_update(struct cpufreq_policy *policy, u8 min_perf,
			      u8 des_perf, u8 max_perf, bool fast_switch, int gov_flags)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	union perf_cached perf = READ_ONCE(cpudata->perf);

	/* limit the max perf when core performance boost feature is disabled */
	if (!cpudata->boost_supported)
		max_perf = min_t(u8, perf.nominal_perf, max_perf);

	des_perf = clamp_t(u8, des_perf, min_perf, max_perf);

	policy->cur = perf_to_freq(perf, cpudata->nominal_freq, des_perf);

	if ((cppc_state == AMD_PSTATE_GUIDED) && (gov_flags & CPUFREQ_GOV_DYNAMIC_SWITCHING)) {
		min_perf = des_perf;
		des_perf = 0;
	}

	if (trace_amd_pstate_perf_enabled() && amd_pstate_sample(cpudata)) {
		trace_call__amd_pstate_perf(min_perf, des_perf, max_perf, cpudata->freq,
			cpudata->cur.mperf, cpudata->cur.aperf, cpudata->cur.tsc,
				cpudata->cpu, fast_switch);
	}

	amd_pstate_update_perf(policy, min_perf, des_perf, max_perf, 0, fast_switch);
}

static int amd_pstate_verify(struct cpufreq_policy_data *policy_data)
{
	/*
	 * Initialize lower frequency limit (i.e.policy->min) with
	 * lowest_nonlinear_frequency or the min frequency (if) specified in BIOS,
	 * Override the initial value set by cpufreq core and amd-pstate qos_requests.
	 */
	if (policy_data->min == FREQ_QOS_MIN_DEFAULT_VALUE) {
		struct cpufreq_policy *policy __free(put_cpufreq_policy) =
					      cpufreq_cpu_get(policy_data->cpu);
		struct amd_cpudata *cpudata;
		union perf_cached perf;

		if (!policy)
			return -EINVAL;

		cpudata = policy->driver_data;
		perf = READ_ONCE(cpudata->perf);

		if (perf.bios_min_perf)
			policy_data->min = perf_to_freq(perf, cpudata->nominal_freq,
							perf.bios_min_perf);
		else
			policy_data->min = cpudata->lowest_nonlinear_freq;
	}

	cpufreq_verify_within_cpu_limits(policy_data);

	return 0;
}

static void amd_pstate_update_min_max_limit(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	union perf_cached perf = READ_ONCE(cpudata->perf);

	perf.max_limit_perf = freq_to_perf(perf, cpudata->nominal_freq, policy->max);
	WRITE_ONCE(cpudata->max_limit_freq, policy->max);

	if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) {
		/*
		 * For performance policy, set MinPerf to nominal_perf rather than
		 * highest_perf or lowest_nonlinear_perf.
		 *
		 * Per commit 0c411b39e4f4c, using highest_perf was observed
		 * to cause frequency throttling on power-limited platforms, leading to
		 * performance regressions. Using lowest_nonlinear_perf would limit
		 * performance too much for HPC workloads requiring high frequency
		 * operation and minimal wakeup latency from idle states.
		 *
		 * nominal_perf therefore provides a balance by avoiding throttling
		 * while still maintaining enough performance for HPC workloads.
		 */
		perf.min_limit_perf = min(perf.nominal_perf, perf.max_limit_perf);
		WRITE_ONCE(cpudata->min_limit_freq, min(cpudata->nominal_freq, cpudata->max_limit_freq));
	} else {
		perf.min_limit_perf = freq_to_perf(perf, cpudata->nominal_freq, policy->min);
		WRITE_ONCE(cpudata->min_limit_freq, policy->min);
	}

	WRITE_ONCE(cpudata->perf, perf);
}

static int amd_pstate_update_freq(struct cpufreq_policy *policy,
				  unsigned int target_freq, bool fast_switch)
{
	struct cpufreq_freqs freqs;
	struct amd_cpudata *cpudata;
	union perf_cached perf;
	u8 des_perf;

	cpudata = policy->driver_data;

	if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq)
		amd_pstate_update_min_max_limit(policy);

	perf = READ_ONCE(cpudata->perf);

	freqs.old = policy->cur;
	freqs.new = target_freq;

	des_perf = freq_to_perf(perf, cpudata->nominal_freq, target_freq);

	WARN_ON(fast_switch && !policy->fast_switch_enabled);
	/*
	 * If fast_switch is desired, then there aren't any registered
	 * transition notifiers. See comment for
	 * cpufreq_enable_fast_switch().
	 */
	if (!fast_switch)
		cpufreq_freq_transition_begin(policy, &freqs);

	amd_pstate_update(policy, perf.min_limit_perf, des_perf,
			  perf.max_limit_perf, fast_switch,
			  policy->governor->flags);

	if (!fast_switch)
		cpufreq_freq_transition_end(policy, &freqs, false);

	return 0;
}

static int amd_pstate_target(struct cpufreq_policy *policy,
			     unsigned int target_freq,
			     unsigned int relation)
{
	return amd_pstate_update_freq(policy, target_freq, false);
}

static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy,
				  unsigned int target_freq)
{
	if (!amd_pstate_update_freq(policy, target_freq, true))
		return target_freq;
	return policy->cur;
}

static void amd_pstate_adjust_perf(struct cpufreq_policy *policy,
				   unsigned long _min_perf,
				   unsigned long target_perf,
				   unsigned long capacity)
{
	u8 max_perf, min_perf, des_perf, cap_perf;
	struct amd_cpudata *cpudata;
	union perf_cached perf;

	if (!policy)
		return;

	cpudata = policy->driver_data;

	if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq)
		amd_pstate_update_min_max_limit(policy);

	perf = READ_ONCE(cpudata->perf);
	cap_perf = perf.highest_perf;

	des_perf = cap_perf;
	if (target_perf < capacity)
		des_perf = DIV_ROUND_UP(cap_perf * target_perf, capacity);

	if (_min_perf < capacity)
		min_perf = DIV_ROUND_UP(cap_perf * _min_perf, capacity);
	else
		min_perf = cap_perf;

	if (min_perf < perf.min_limit_perf)
		min_perf = perf.min_limit_perf;

	max_perf = perf.max_limit_perf;
	if (max_perf < min_perf)
		max_perf = min_perf;

	amd_pstate_update(policy, min_perf, des_perf, max_perf, true,
			policy->governor->flags);
}

static int amd_pstate_cpu_boost_update(struct cpufreq_policy *policy, bool on)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	u32 nominal_freq;
	int ret = 0;

	nominal_freq = READ_ONCE(cpudata->nominal_freq);

	if (on)
		policy->cpuinfo.max_freq = cpudata->max_freq;
	else if (policy->cpuinfo.max_freq > nominal_freq)
		policy->cpuinfo.max_freq = nominal_freq;

	if (cppc_state == AMD_PSTATE_PASSIVE) {
		ret = freq_qos_update_request(&cpudata->req[1], policy->cpuinfo.max_freq);
		if (ret < 0)
			pr_debug("Failed to update freq constraint: CPU%d\n", cpudata->cpu);
	}

	return ret < 0 ? ret : 0;
}

static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	int ret;

	if (!cpudata->boost_supported) {
		pr_err("Boost mode is not supported by this processor or SBIOS\n");
		return -EOPNOTSUPP;
	}

	ret = amd_pstate_cpu_boost_update(policy, state);
	refresh_frequency_limits(policy);

	return ret;
}

static int amd_pstate_init_boost_support(struct amd_cpudata *cpudata)
{
	u64 boost_val;
	int ret = -1;

	/*
	 * If platform has no CPB support or disable it, initialize current driver
	 * boost_enabled state to be false, it is not an error for cpufreq core to handle.
	 */
	if (!cpu_feature_enabled(X86_FEATURE_CPB)) {
		pr_debug_once("Boost CPB capabilities not present in the processor\n");
		ret = 0;
		goto exit_err;
	}

	ret = rdmsrq_on_cpu(cpudata->cpu, MSR_K7_HWCR, &boost_val);
	if (ret) {
		pr_err_once("failed to read initial CPU boost state!\n");
		ret = -EIO;
		goto exit_err;
	}

	if (!(boost_val & MSR_K7_HWCR_CPB_DIS))
		cpudata->boost_supported = true;

	return 0;

exit_err:
	cpudata->boost_supported = false;
	return ret;
}

static void amd_perf_ctl_reset(unsigned int cpu)
{
	wrmsrq_on_cpu(cpu, MSR_AMD_PERF_CTL, 0);
}

#define CPPC_MAX_PERF	U8_MAX

static void amd_pstate_init_prefcore(struct amd_cpudata *cpudata)
{
	/* user disabled or not detected */
	if (!amd_pstate_prefcore)
		return;

	/* should use amd-hfi instead */
	if (cpu_feature_enabled(X86_FEATURE_AMD_WORKLOAD_CLASS) &&
	    IS_ENABLED(CONFIG_AMD_HFI)) {
		amd_pstate_prefcore = false;
		return;
	}

	cpudata->hw_prefcore = true;

	/* Priorities must be initialized before ITMT support can be toggled on. */
	sched_set_itmt_core_prio((int)READ_ONCE(cpudata->prefcore_ranking), cpudata->cpu);
}

static void amd_pstate_update_limits(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata;
	u32 prev_high = 0, cur_high = 0;
	bool highest_perf_changed = false;
	unsigned int cpu = policy->cpu;

	if (!amd_pstate_prefcore)
		return;

	if (amd_get_highest_perf(cpu, &cur_high))
		return;

	cpudata = policy->driver_data;

	prev_high = READ_ONCE(cpudata->prefcore_ranking);
	highest_perf_changed = (prev_high != cur_high);
	if (highest_perf_changed) {
		WRITE_ONCE(cpudata->prefcore_ranking, cur_high);

		if (cur_high < CPPC_MAX_PERF) {
			sched_set_itmt_core_prio((int)cur_high, cpu);
			sched_update_asym_prefer_cpu(cpu, prev_high, cur_high);
		}
	}
}

/*
 * Get pstate transition delay time from ACPI tables that firmware set
 * instead of using hardcode value directly.
 */
static u32 amd_pstate_get_transition_delay_us(unsigned int cpu)
{
	int transition_delay_ns;

	transition_delay_ns = cppc_get_transition_latency(cpu);
	if (transition_delay_ns < 0) {
		if (cpu_feature_enabled(X86_FEATURE_AMD_FAST_CPPC))
			return AMD_PSTATE_FAST_CPPC_TRANSITION_DELAY;
		else
			return AMD_PSTATE_TRANSITION_DELAY;
	}

	return transition_delay_ns / NSEC_PER_USEC;
}

/*
 * Get pstate transition latency value from ACPI tables that firmware
 * set instead of using hardcode value directly.
 */
static u32 amd_pstate_get_transition_latency(unsigned int cpu)
{
	int transition_latency;

	transition_latency = cppc_get_transition_latency(cpu);
	if (transition_latency < 0)
		return AMD_PSTATE_TRANSITION_LATENCY;

	return transition_latency;
}

/*
 * amd_pstate_init_freq: Initialize the nominal_freq and lowest_nonlinear_freq
 *			 for the @cpudata object.
 *
 * Requires: all perf members of @cpudata to be initialized.
 *
 * Returns 0 on success, non-zero value on failure.
 */
static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
{
	u32 min_freq, max_freq, nominal_freq, lowest_nonlinear_freq;
	struct cppc_perf_caps cppc_perf;
	union perf_cached perf;
	int ret;

	ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
	if (ret)
		return ret;
	perf = READ_ONCE(cpudata->perf);

	if (quirks && quirks->nominal_freq)
		nominal_freq = quirks->nominal_freq;
	else
		nominal_freq = cppc_perf.nominal_freq;
	nominal_freq *= 1000;

	if (quirks && quirks->lowest_freq) {
		min_freq = quirks->lowest_freq;
		perf.lowest_perf = freq_to_perf(perf, nominal_freq, min_freq);
		WRITE_ONCE(cpudata->perf, perf);
	} else
		min_freq = cppc_perf.lowest_freq;

	min_freq *= 1000;

	WRITE_ONCE(cpudata->nominal_freq, nominal_freq);

	/* max_freq is calculated according to (nominal_freq * highest_perf)/nominal_perf */
	max_freq = perf_to_freq(perf, nominal_freq, perf.highest_perf);
	WRITE_ONCE(cpudata->max_freq, max_freq);

	lowest_nonlinear_freq = perf_to_freq(perf, nominal_freq, perf.lowest_nonlinear_perf);
	WRITE_ONCE(cpudata->lowest_nonlinear_freq, lowest_nonlinear_freq);

	/**
	 * Below values need to be initialized correctly, otherwise driver will fail to load
	 * 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);
		return -EINVAL;
	}

	if (lowest_nonlinear_freq <= min_freq || lowest_nonlinear_freq > nominal_freq) {
		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);
		return -EINVAL;
	}

	return 0;
}

static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata;
	union perf_cached perf;
	struct device *dev;
	int ret;

	/*
	 * Resetting PERF_CTL_MSR will put the CPU in P0 frequency,
	 * which is ideal for initialization process.
	 */
	amd_perf_ctl_reset(policy->cpu);
	dev = get_cpu_device(policy->cpu);
	if (!dev)
		return -ENODEV;

	cpudata = kzalloc_obj(*cpudata);
	if (!cpudata)
		return -ENOMEM;

	cpudata->cpu = policy->cpu;

	ret = amd_pstate_init_perf(cpudata);
	if (ret)
		goto free_cpudata1;

	amd_pstate_init_prefcore(cpudata);

	ret = amd_pstate_init_freq(cpudata);
	if (ret)
		goto free_cpudata1;

	ret = amd_pstate_init_boost_support(cpudata);
	if (ret)
		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);

	perf = READ_ONCE(cpudata->perf);

	policy->cpuinfo.min_freq = perf_to_freq(perf, cpudata->nominal_freq,
						perf.lowest_perf);
	policy->cpuinfo.max_freq = cpudata->max_freq;

	policy->driver_data = cpudata;
	ret = amd_pstate_cppc_enable(policy);
	if (ret)
		goto free_cpudata1;

	policy->boost_supported = READ_ONCE(cpudata->boost_supported);

	/* It will be updated by governor */
	policy->cur = policy->cpuinfo.min_freq;

	if (cpu_feature_enabled(X86_FEATURE_CPPC))
		policy->fast_switch_possible = true;

	ret = amd_pstate_init_floor_perf(policy);
	if (ret) {
		dev_err(dev, "Failed to initialize Floor Perf (%d)\n", ret);
		goto free_cpudata1;
	}

	ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
				   FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE);
	if (ret < 0) {
		dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret);
		goto free_cpudata1;
	}

	ret = freq_qos_add_request(&policy->constraints, &cpudata->req[1],
				   FREQ_QOS_MAX, policy->cpuinfo.max_freq);
	if (ret < 0) {
		dev_err(dev, "Failed to add max-freq constraint (%d)\n", ret);
		goto free_cpudata2;
	}


	if (!current_pstate_driver->adjust_perf)
		current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;

	return 0;

free_cpudata2:
	freq_qos_remove_request(&cpudata->req[0]);
free_cpudata1:
	pr_warn("Failed to initialize CPU %d: %d\n", policy->cpu, ret);
	kfree(cpudata);
	policy->driver_data = NULL;
	return ret;
}

static void amd_pstate_cpu_exit(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	union perf_cached perf = READ_ONCE(cpudata->perf);

	/* Reset CPPC_REQ MSR to the BIOS value */
	amd_pstate_update_perf(policy, perf.bios_min_perf, 0U, 0U, 0U, false);
	amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);

	freq_qos_remove_request(&cpudata->req[1]);
	freq_qos_remove_request(&cpudata->req[0]);
	policy->fast_switch_possible = false;
	kfree(cpudata);
}

static int amd_pstate_get_balanced_epp(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata = policy->driver_data;

	if (power_supply_is_system_supplied())
		return cpudata->epp_default_ac;
	else
		return cpudata->epp_default_dc;
}

static int amd_pstate_power_supply_notifier(struct notifier_block *nb,
					    unsigned long event, void *data)
{
	struct amd_cpudata *cpudata = container_of(nb, struct amd_cpudata, power_nb);
	struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpudata->cpu);
	u8 epp;
	int ret;

	if (event != PSY_EVENT_PROP_CHANGED)
		return NOTIFY_OK;

	/* dynamic actions are only applied while platform profile is in balanced */
	if (cpudata->current_profile != PLATFORM_PROFILE_BALANCED)
		return 0;

	epp = amd_pstate_get_balanced_epp(policy);

	ret = amd_pstate_set_epp(policy, epp);
	if (ret)
		pr_warn("Failed to set CPU %d EPP %u: %d\n", cpudata->cpu, epp, ret);

	return NOTIFY_OK;
}

static int amd_pstate_profile_probe(void *drvdata, unsigned long *choices)
{
	set_bit(PLATFORM_PROFILE_LOW_POWER, choices);
	set_bit(PLATFORM_PROFILE_BALANCED, choices);
	set_bit(PLATFORM_PROFILE_PERFORMANCE, choices);

	return 0;
}

static int amd_pstate_profile_get(struct device *dev,
				  enum platform_profile_option *profile)
{
	struct amd_cpudata *cpudata = dev_get_drvdata(dev);

	*profile = cpudata->current_profile;

	return 0;
}

static int amd_pstate_profile_set(struct device *dev,
				  enum platform_profile_option profile)
{
	struct amd_cpudata *cpudata = dev_get_drvdata(dev);
	struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpudata->cpu);
	int ret;

	switch (profile) {
	case PLATFORM_PROFILE_LOW_POWER:
		ret = amd_pstate_set_epp(policy, AMD_CPPC_EPP_POWERSAVE);
		if (ret)
			return ret;
		break;
	case PLATFORM_PROFILE_BALANCED:
		ret = amd_pstate_set_epp(policy,
					 amd_pstate_get_balanced_epp(policy));
		if (ret)
			return ret;
		break;
	case PLATFORM_PROFILE_PERFORMANCE:
		ret = amd_pstate_set_epp(policy, AMD_CPPC_EPP_PERFORMANCE);
		if (ret)
			return ret;
		break;
	default:
		pr_err("Unknown Platform Profile %d\n", profile);
		return -EOPNOTSUPP;
	}

	cpudata->current_profile = profile;

	return 0;
}

static const struct platform_profile_ops amd_pstate_profile_ops = {
	.probe = amd_pstate_profile_probe,
	.profile_set = amd_pstate_profile_set,
	.profile_get = amd_pstate_profile_get,
};

void amd_pstate_clear_dynamic_epp(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata = policy->driver_data;

	if (cpudata->power_nb.notifier_call)
		power_supply_unreg_notifier(&cpudata->power_nb);
	if (cpudata->ppdev) {
		platform_profile_remove(cpudata->ppdev);
		cpudata->ppdev = NULL;
	}
	kfree(cpudata->profile_name);
	cpudata->dynamic_epp = false;
}
EXPORT_SYMBOL_GPL(amd_pstate_clear_dynamic_epp);

static int amd_pstate_set_dynamic_epp(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	int ret;
	u8 epp;

	switch (cpudata->current_profile) {
	case PLATFORM_PROFILE_PERFORMANCE:
		epp = AMD_CPPC_EPP_PERFORMANCE;
		break;
	case PLATFORM_PROFILE_LOW_POWER:
		epp = AMD_CPPC_EPP_POWERSAVE;
		break;
	case PLATFORM_PROFILE_BALANCED:
		epp = amd_pstate_get_balanced_epp(policy);
		break;
	default:
		pr_err("Unknown Platform Profile %d\n", cpudata->current_profile);
		return -EOPNOTSUPP;
	}
	ret = amd_pstate_set_epp(policy, epp);
	if (ret)
		return ret;

	cpudata->profile_name = kasprintf(GFP_KERNEL, "amd-pstate-epp-cpu%d", cpudata->cpu);
	if (!cpudata->profile_name)
		return -ENOMEM;

	cpudata->ppdev = platform_profile_register(get_cpu_device(policy->cpu),
						   cpudata->profile_name,
						   policy->driver_data,
						   &amd_pstate_profile_ops);
	if (IS_ERR(cpudata->ppdev)) {
		ret = PTR_ERR(cpudata->ppdev);
		goto cleanup;
	}

	/* only enable notifier if things will actually change */
	if (cpudata->epp_default_ac != cpudata->epp_default_dc) {
		cpudata->power_nb.notifier_call = amd_pstate_power_supply_notifier;
		ret = power_supply_reg_notifier(&cpudata->power_nb);
		if (ret)
			goto cleanup;
	}

	cpudata->dynamic_epp = true;

	return 0;

cleanup:
	amd_pstate_clear_dynamic_epp(policy);

	return ret;
}

/* Sysfs attributes */

/*
 * This frequency is to indicate the maximum hardware frequency.
 * If boost is not active but supported, the frequency will be larger than the
 * one in cpuinfo.
 */
static ssize_t show_amd_pstate_max_freq(struct cpufreq_policy *policy,
					char *buf)
{
	struct amd_cpudata *cpudata = policy->driver_data;

	return sysfs_emit(buf, "%u\n", cpudata->max_freq);
}

static ssize_t show_amd_pstate_lowest_nonlinear_freq(struct cpufreq_policy *policy,
						     char *buf)
{
	struct amd_cpudata *cpudata;
	union perf_cached perf;

	cpudata = policy->driver_data;
	perf = READ_ONCE(cpudata->perf);

	return sysfs_emit(buf, "%u\n",
			  perf_to_freq(perf, cpudata->nominal_freq, perf.lowest_nonlinear_perf));
}

/*
 * In some of ASICs, the highest_perf is not the one in the _CPC table, so we
 * need to expose it to sysfs.
 */
static ssize_t show_amd_pstate_highest_perf(struct cpufreq_policy *policy,
					    char *buf)
{
	struct amd_cpudata *cpudata;

	cpudata = policy->driver_data;

	return sysfs_emit(buf, "%u\n", cpudata->perf.highest_perf);
}

static ssize_t show_amd_pstate_prefcore_ranking(struct cpufreq_policy *policy,
						char *buf)
{
	u8 perf;
	struct amd_cpudata *cpudata = policy->driver_data;

	perf = READ_ONCE(cpudata->prefcore_ranking);

	return sysfs_emit(buf, "%u\n", perf);
}

static ssize_t show_amd_pstate_hw_prefcore(struct cpufreq_policy *policy,
					   char *buf)
{
	bool hw_prefcore;
	struct amd_cpudata *cpudata = policy->driver_data;

	hw_prefcore = READ_ONCE(cpudata->hw_prefcore);

	return sysfs_emit(buf, "%s\n", str_enabled_disabled(hw_prefcore));
}

static ssize_t show_energy_performance_available_preferences(
				struct cpufreq_policy *policy, char *buf)
{
	int offset = 0, i;
	struct amd_cpudata *cpudata = policy->driver_data;

	if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
		return sysfs_emit_at(buf, offset, "%s\n",
				energy_perf_strings[EPP_INDEX_PERFORMANCE]);

	for (i = 0; i < ARRAY_SIZE(energy_perf_strings); i++)
		offset += sysfs_emit_at(buf, offset, "%s ", energy_perf_strings[i]);

	offset += sysfs_emit_at(buf, offset, "\n");

	return offset;
}

ssize_t store_energy_performance_preference(struct cpufreq_policy *policy,
				    const char *buf, size_t count)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	ssize_t ret;
	bool raw_epp = false;
	u8 epp;

	if (cpudata->dynamic_epp) {
		pr_debug("EPP cannot be set when dynamic EPP is enabled\n");
		return -EBUSY;
	}

	/*
	 * if the value matches a number, use that, otherwise see if
	 * matches an index in the energy_perf_strings array
	 */
	ret = kstrtou8(buf, 0, &epp);
	raw_epp = !ret;
	if (ret) {
		ret = sysfs_match_string(energy_perf_strings, buf);
		if (ret < 0 || ret == EPP_INDEX_CUSTOM)
			return -EINVAL;
		if (ret)
			epp = epp_values[ret];
		else
			epp = cpudata->epp_default_dc;
	}

	if (epp > 0 && cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) {
		pr_debug("EPP cannot be set under performance policy\n");
		return -EBUSY;
	}

	ret = amd_pstate_set_epp(policy, epp);
	if (ret)
		return ret;

	cpudata->raw_epp = raw_epp;

	return count;
}
EXPORT_SYMBOL_GPL(store_energy_performance_preference);

ssize_t show_energy_performance_preference(struct cpufreq_policy *policy, char *buf)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	u8 preference, epp;

	epp = FIELD_GET(AMD_CPPC_EPP_PERF_MASK, cpudata->cppc_req_cached);

	if (cpudata->raw_epp)
		return sysfs_emit(buf, "%u\n", epp);

	switch (epp) {
	case AMD_CPPC_EPP_PERFORMANCE:
		preference = EPP_INDEX_PERFORMANCE;
		break;
	case AMD_CPPC_EPP_BALANCE_PERFORMANCE:
		preference = EPP_INDEX_BALANCE_PERFORMANCE;
		break;
	case AMD_CPPC_EPP_BALANCE_POWERSAVE:
		preference = EPP_INDEX_BALANCE_POWERSAVE;
		break;
	case AMD_CPPC_EPP_POWERSAVE:
		preference = EPP_INDEX_POWERSAVE;
		break;
	default:
		return -EINVAL;
	}

	return sysfs_emit(buf, "%s\n", energy_perf_strings[preference]);
}
EXPORT_SYMBOL_GPL(show_energy_performance_preference);

static ssize_t store_amd_pstate_floor_freq(struct cpufreq_policy *policy,
					   const char *buf, size_t count)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	union perf_cached perf = READ_ONCE(cpudata->perf);
	unsigned int freq;
	u8 floor_perf;
	int ret;

	ret = kstrtouint(buf, 0, &freq);
	if (ret)
		return ret;

	if (freq < policy->cpuinfo.min_freq || freq > policy->max)
		return -EINVAL;

	floor_perf = freq_to_perf(perf, cpudata->nominal_freq, freq);
	ret = amd_pstate_set_floor_perf(policy, floor_perf);

	if (!ret)
		cpudata->floor_freq = freq;

	return ret ?: count;
}

static ssize_t show_amd_pstate_floor_freq(struct cpufreq_policy *policy, char *buf)
{
	struct amd_cpudata *cpudata = policy->driver_data;

	return sysfs_emit(buf, "%u\n", cpudata->floor_freq);
}

static ssize_t show_amd_pstate_floor_count(struct cpufreq_policy *policy, char *buf)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	u8 count = cpudata->floor_perf_cnt;

	return sysfs_emit(buf, "%u\n", count);
}

cpufreq_freq_attr_ro(amd_pstate_max_freq);
cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq);

cpufreq_freq_attr_ro(amd_pstate_highest_perf);
cpufreq_freq_attr_ro(amd_pstate_prefcore_ranking);
cpufreq_freq_attr_ro(amd_pstate_hw_prefcore);
cpufreq_freq_attr_rw(energy_performance_preference);
cpufreq_freq_attr_ro(energy_performance_available_preferences);
cpufreq_freq_attr_rw(amd_pstate_floor_freq);
cpufreq_freq_attr_ro(amd_pstate_floor_count);

struct freq_attr_visibility {
	struct freq_attr *attr;
	bool (*visibility_fn)(void);
};

/* For attributes which are always visible */
static bool always_visible(void)
{
	return true;
}

/* Determines whether prefcore related attributes should be visible */
static bool prefcore_visibility(void)
{
	return amd_pstate_prefcore;
}

/* Determines whether energy performance preference should be visible */
static bool epp_visibility(void)
{
	return cppc_state == AMD_PSTATE_ACTIVE;
}

/* Determines whether amd_pstate_floor_freq related attributes should be visible */
static bool floor_freq_visibility(void)
{
	return cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO);
}

static struct freq_attr_visibility amd_pstate_attr_visibility[] = {
	{&amd_pstate_max_freq, always_visible},
	{&amd_pstate_lowest_nonlinear_freq, always_visible},
	{&amd_pstate_highest_perf, always_visible},
	{&amd_pstate_prefcore_ranking, prefcore_visibility},
	{&amd_pstate_hw_prefcore, prefcore_visibility},
	{&energy_performance_preference, epp_visibility},
	{&energy_performance_available_preferences, epp_visibility},
	{&amd_pstate_floor_freq, floor_freq_visibility},
	{&amd_pstate_floor_count, floor_freq_visibility},
};

struct freq_attr **amd_pstate_get_current_attrs(void)
{
	if (!current_pstate_driver)
		return NULL;
	return current_pstate_driver->attr;
}
EXPORT_SYMBOL_GPL(amd_pstate_get_current_attrs);

static struct freq_attr **get_freq_attrs(void)
{
	bool attr_visible[ARRAY_SIZE(amd_pstate_attr_visibility)];
	struct freq_attr **attrs;
	int i, j, count;

	for (i = 0, count = 0; i < ARRAY_SIZE(amd_pstate_attr_visibility); i++) {
		struct freq_attr_visibility *v = &amd_pstate_attr_visibility[i];

		attr_visible[i] = v->visibility_fn();
		if (attr_visible[i])
			count++;
	}

	/* amd_pstate_{max_freq, lowest_nonlinear_freq, highest_perf} should always be visible */
	BUG_ON(!count);

	attrs = kcalloc(count + 1, sizeof(struct freq_attr *), GFP_KERNEL);
	if (!attrs)
		return ERR_PTR(-ENOMEM);

	for (i = 0, j = 0; i < ARRAY_SIZE(amd_pstate_attr_visibility); i++) {
		if (!attr_visible[i])
			continue;

		attrs[j++] = amd_pstate_attr_visibility[i].attr;
	}

	return attrs;
}

static void amd_pstate_driver_cleanup(void)
{
	if (amd_pstate_prefcore)
		sched_clear_itmt_support();

	cppc_state = AMD_PSTATE_DISABLE;
	kfree(current_pstate_driver->attr);
	current_pstate_driver->attr = NULL;
	current_pstate_driver = NULL;
}

static int 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 amd_pstate_register_driver(int mode)
{
	struct freq_attr **attr = NULL;
	int ret;

	ret = amd_pstate_set_driver(mode);
	if (ret)
		return ret;

	cppc_state = mode;

	/*
	 * Note: It is important to compute the attrs _after_
	 * re-initializing the cppc_state.  Some attributes become
	 * visible only when cppc_state is AMD_PSTATE_ACTIVE.
	 */
	attr = get_freq_attrs();
	if (IS_ERR(attr)) {
		ret = (int) PTR_ERR(attr);
		pr_err("Couldn't compute freq_attrs for current mode %s [%d]\n",
			amd_pstate_get_mode_string(cppc_state), ret);
		amd_pstate_driver_cleanup();
		return ret;
	}

	current_pstate_driver->attr = attr;

	/* at least one CPU supports CPB */
	current_pstate_driver->boost_enabled = cpu_feature_enabled(X86_FEATURE_CPB);

	ret = cpufreq_register_driver(current_pstate_driver);
	if (ret) {
		amd_pstate_driver_cleanup();
		return ret;
	}

	/* Enable ITMT support once all CPUs have initialized their asym priorities. */
	if (amd_pstate_prefcore)
		sched_set_itmt_support();

	return 0;
}

static int amd_pstate_unregister_driver(int dummy)
{
	cpufreq_unregister_driver(current_pstate_driver);
	amd_pstate_driver_cleanup();
	return 0;
}

static int amd_pstate_change_mode_without_dvr_change(int mode)
{
	int cpu = 0;

	cppc_state = mode;

	if (cpu_feature_enabled(X86_FEATURE_CPPC) || cppc_state == AMD_PSTATE_ACTIVE)
		return 0;

	for_each_online_cpu(cpu) {
		cppc_set_auto_sel(cpu, (cppc_state == AMD_PSTATE_PASSIVE) ? 0 : 1);
	}

	return 0;
}

static int amd_pstate_change_driver_mode(int mode)
{
	int ret;

	lockdep_assert_held(&amd_pstate_driver_lock);

	ret = amd_pstate_unregister_driver(0);
	if (ret)
		return ret;

	ret = amd_pstate_register_driver(mode);
	if (ret)
		return ret;

	return 0;
}

static cppc_mode_transition_fn mode_state_machine[AMD_PSTATE_MAX][AMD_PSTATE_MAX] = {
	[AMD_PSTATE_DISABLE]         = {
		[AMD_PSTATE_DISABLE]     = NULL,
		[AMD_PSTATE_PASSIVE]     = amd_pstate_register_driver,
		[AMD_PSTATE_ACTIVE]      = amd_pstate_register_driver,
		[AMD_PSTATE_GUIDED]      = amd_pstate_register_driver,
	},
	[AMD_PSTATE_PASSIVE]         = {
		[AMD_PSTATE_DISABLE]     = amd_pstate_unregister_driver,
		[AMD_PSTATE_PASSIVE]     = NULL,
		[AMD_PSTATE_ACTIVE]      = amd_pstate_change_driver_mode,
		[AMD_PSTATE_GUIDED]      = amd_pstate_change_mode_without_dvr_change,
	},
	[AMD_PSTATE_ACTIVE]          = {
		[AMD_PSTATE_DISABLE]     = amd_pstate_unregister_driver,
		[AMD_PSTATE_PASSIVE]     = amd_pstate_change_driver_mode,
		[AMD_PSTATE_ACTIVE]      = NULL,
		[AMD_PSTATE_GUIDED]      = amd_pstate_change_driver_mode,
	},
	[AMD_PSTATE_GUIDED]          = {
		[AMD_PSTATE_DISABLE]     = amd_pstate_unregister_driver,
		[AMD_PSTATE_PASSIVE]     = amd_pstate_change_mode_without_dvr_change,
		[AMD_PSTATE_ACTIVE]      = amd_pstate_change_driver_mode,
		[AMD_PSTATE_GUIDED]      = NULL,
	},
};

static ssize_t amd_pstate_show_status(char *buf)
{
	if (!current_pstate_driver)
		return sysfs_emit(buf, "disable\n");

	return sysfs_emit(buf, "%s\n", amd_pstate_mode_string[cppc_state]);
}

int amd_pstate_get_status(void)
{
	return cppc_state;
}
EXPORT_SYMBOL_GPL(amd_pstate_get_status);

int amd_pstate_update_status(const char *buf, size_t size)
{
	int mode_idx;

	if (size > strlen("passive") || size < strlen("active"))
		return -EINVAL;

	mode_idx = get_mode_idx_from_str(buf, size);
	if (mode_idx < 0)
		return mode_idx;

	if (mode_state_machine[cppc_state][mode_idx]) {
		guard(mutex)(&amd_pstate_driver_lock);
		return mode_state_machine[cppc_state][mode_idx](mode_idx);
	}

	return 0;
}
EXPORT_SYMBOL_GPL(amd_pstate_update_status);

static ssize_t status_show(struct device *dev,
			   struct device_attribute *attr, char *buf)
{

	guard(mutex)(&amd_pstate_driver_lock);

	return amd_pstate_show_status(buf);
}

static ssize_t status_store(struct device *a, struct device_attribute *b,
			    const char *buf, size_t count)
{
	char *p = memchr(buf, '\n', count);
	int ret;

	ret = amd_pstate_update_status(buf, p ? p - buf : count);

	return ret < 0 ? ret : count;
}

static ssize_t prefcore_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	return sysfs_emit(buf, "%s\n", str_enabled_disabled(amd_pstate_prefcore));
}

static ssize_t dynamic_epp_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	return sysfs_emit(buf, "%s\n", str_enabled_disabled(dynamic_epp));
}

static ssize_t dynamic_epp_store(struct device *a, struct device_attribute *b,
				 const char *buf, size_t count)
{
	bool enabled;
	int ret;

	ret = kstrtobool(buf, &enabled);
	if (ret)
		return ret;

	guard(mutex)(&amd_pstate_driver_lock);

	if (cppc_state != AMD_PSTATE_ACTIVE) {
		pr_debug("dynamic_epp can only be toggled in active mode\n");
		return -EINVAL;
	}

	/* Nothing to do */
	if (dynamic_epp == enabled)
		return count;

	/* reinitialize with desired dynamic EPP value */
	dynamic_epp = enabled;
	ret = amd_pstate_change_driver_mode(cppc_state);
	if (ret)
		dynamic_epp = false;

	return ret ? ret : count;
}

static DEVICE_ATTR_RW(status);
static DEVICE_ATTR_RO(prefcore);
static DEVICE_ATTR_RW(dynamic_epp);

static struct attribute *pstate_global_attributes[] = {
	&dev_attr_status.attr,
	&dev_attr_prefcore.attr,
	&dev_attr_dynamic_epp.attr,
	NULL
};

static const struct attribute_group amd_pstate_global_attr_group = {
	.name = "amd_pstate",
	.attrs = pstate_global_attributes,
};

static bool amd_pstate_acpi_pm_profile_server(void)
{
	switch (acpi_gbl_FADT.preferred_profile) {
	case PM_ENTERPRISE_SERVER:
	case PM_SOHO_SERVER:
	case PM_PERFORMANCE_SERVER:
		return true;
	}
	return false;
}

static bool amd_pstate_acpi_pm_profile_undefined(void)
{
	if (acpi_gbl_FADT.preferred_profile == PM_UNSPECIFIED)
		return true;
	if (acpi_gbl_FADT.preferred_profile >= NR_PM_PROFILES)
		return true;
	return false;
}

static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata;
	union perf_cached perf;
	struct device *dev;
	int ret;

	/*
	 * Resetting PERF_CTL_MSR will put the CPU in P0 frequency,
	 * which is ideal for initialization process.
	 */
	amd_perf_ctl_reset(policy->cpu);
	dev = get_cpu_device(policy->cpu);
	if (!dev)
		return -ENODEV;

	cpudata = kzalloc_obj(*cpudata);
	if (!cpudata)
		return -ENOMEM;

	cpudata->cpu = policy->cpu;

	ret = amd_pstate_init_perf(cpudata);
	if (ret)
		goto free_cpudata1;

	amd_pstate_init_prefcore(cpudata);

	ret = amd_pstate_init_freq(cpudata);
	if (ret)
		goto free_cpudata1;

	ret = amd_pstate_init_boost_support(cpudata);
	if (ret)
		goto free_cpudata1;

	perf = READ_ONCE(cpudata->perf);

	policy->cpuinfo.min_freq = perf_to_freq(perf, cpudata->nominal_freq,
						perf.lowest_perf);
	policy->cpuinfo.max_freq = cpudata->max_freq;
	policy->driver_data = cpudata;

	ret = amd_pstate_cppc_enable(policy);
	if (ret)
		goto free_cpudata1;

	/* It will be updated by governor */
	policy->cur = policy->cpuinfo.min_freq;


	policy->boost_supported = READ_ONCE(cpudata->boost_supported);

	/*
	 * Set the policy to provide a valid fallback value in case
	 * the default cpufreq governor is neither powersave nor performance.
	 */
	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->current_profile = PLATFORM_PROFILE_PERFORMANCE;
	} else {
		policy->policy = CPUFREQ_POLICY_POWERSAVE;
		cpudata->epp_default_ac = AMD_CPPC_EPP_PERFORMANCE;
		cpudata->epp_default_dc = AMD_CPPC_EPP_BALANCE_PERFORMANCE;
		cpudata->current_profile = PLATFORM_PROFILE_BALANCED;
	}

	if (dynamic_epp)
		ret = amd_pstate_set_dynamic_epp(policy);
	else
		ret = amd_pstate_set_epp(policy, cpudata->epp_default_dc);
	if (ret)
		goto free_cpudata1;

	ret = amd_pstate_init_floor_perf(policy);
	if (ret) {
		dev_err(dev, "Failed to initialize Floor Perf (%d)\n", ret);
		goto free_cpudata1;
	}

	current_pstate_driver->adjust_perf = NULL;

	return 0;

free_cpudata1:
	pr_warn("Failed to initialize CPU %d: %d\n", policy->cpu, ret);
	kfree(cpudata);
	policy->driver_data = NULL;
	return ret;
}

static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata = policy->driver_data;

	if (cpudata) {
		union perf_cached perf = READ_ONCE(cpudata->perf);

		if (cpudata->dynamic_epp)
			amd_pstate_clear_dynamic_epp(policy);

		/* Reset CPPC_REQ MSR to the BIOS value */
		amd_pstate_update_perf(policy, perf.bios_min_perf, 0U, 0U, 0U, false);
		amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);

		kfree(cpudata);
		policy->driver_data = NULL;
	}

	pr_debug("CPU %d exiting\n", policy->cpu);
}

static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy, bool policy_change)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	union perf_cached perf;
	u8 epp;

	if (policy_change ||
	    policy->min != cpudata->min_limit_freq ||
	    policy->max != cpudata->max_limit_freq)
		amd_pstate_update_min_max_limit(policy);

	if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
		epp = 0;
	else
		epp = FIELD_GET(AMD_CPPC_EPP_PERF_MASK, cpudata->cppc_req_cached);

	perf = READ_ONCE(cpudata->perf);

	return amd_pstate_update_perf(policy, perf.min_limit_perf, 0U,
				      perf.max_limit_perf, epp, false);
}

static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	int ret;

	if (!policy->cpuinfo.max_freq)
		return -ENODEV;

	cpudata->policy = policy->policy;

	ret = amd_pstate_epp_update_limit(policy, true);
	if (ret)
		return ret;

	/*
	 * 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;
}

static int amd_pstate_cpu_online(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	union perf_cached perf = READ_ONCE(cpudata->perf);
	u8 cached_floor_perf;
	int ret;

	ret = amd_pstate_cppc_enable(policy);
	if (ret)
		return ret;

	cached_floor_perf = freq_to_perf(perf, cpudata->nominal_freq, cpudata->floor_freq);
	return amd_pstate_set_floor_perf(policy, cached_floor_perf);
}

static int amd_pstate_cpu_offline(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	union perf_cached perf = READ_ONCE(cpudata->perf);
	int ret;

	/*
	 * Reset CPPC_REQ MSR to the BIOS value, this will allow us to retain the BIOS specified
	 * min_perf value across kexec reboots. If this CPU is just onlined normally after this, the
	 * limits, epp and desired perf will get reset to the cached values in cpudata struct
	 */
	ret = amd_pstate_update_perf(policy, perf.bios_min_perf,
				     FIELD_GET(AMD_CPPC_DES_PERF_MASK, cpudata->cppc_req_cached),
				     FIELD_GET(AMD_CPPC_MAX_PERF_MASK, cpudata->cppc_req_cached),
				     FIELD_GET(AMD_CPPC_EPP_PERF_MASK, cpudata->cppc_req_cached),
				     false);
	if (ret)
		return ret;

	return amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
}

static int amd_pstate_suspend(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	union perf_cached perf = READ_ONCE(cpudata->perf);
	int ret;

	/*
	 * Reset CPPC_REQ MSR to the BIOS value, this will allow us to retain the BIOS specified
	 * min_perf value across kexec reboots. If this CPU is just resumed back without kexec,
	 * the limits, epp and desired perf will get reset to the cached values in cpudata struct
	 */
	ret = amd_pstate_update_perf(policy, perf.bios_min_perf,
				     FIELD_GET(AMD_CPPC_DES_PERF_MASK, cpudata->cppc_req_cached),
				     FIELD_GET(AMD_CPPC_MAX_PERF_MASK, cpudata->cppc_req_cached),
				     FIELD_GET(AMD_CPPC_EPP_PERF_MASK, cpudata->cppc_req_cached),
				     false);
	if (ret)
		return ret;

	ret = amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
	if (ret)
		return ret;

	/* set this flag to avoid setting core offline*/
	cpudata->suspended = true;

	return 0;
}

static int amd_pstate_resume(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	union perf_cached perf = READ_ONCE(cpudata->perf);
	int cur_perf = freq_to_perf(perf, cpudata->nominal_freq, policy->cur);
	u8 cached_floor_perf;
	int ret;

	/* Set CPPC_REQ to last sane value until the governor updates it */
	ret = amd_pstate_update_perf(policy, perf.min_limit_perf, cur_perf, perf.max_limit_perf,
				     0U, false);
	if (ret)
		return ret;

	cached_floor_perf = freq_to_perf(perf, cpudata->nominal_freq, cpudata->floor_freq);
	return amd_pstate_set_floor_perf(policy, cached_floor_perf);
}

static int amd_pstate_epp_resume(struct cpufreq_policy *policy)
{
	struct amd_cpudata *cpudata = policy->driver_data;
	union perf_cached perf = READ_ONCE(cpudata->perf);
	u8 cached_floor_perf;

	if (cpudata->suspended) {
		int ret;

		/* enable amd pstate from suspend state*/
		ret = amd_pstate_epp_update_limit(policy, false);
		if (ret)
			return ret;

		cpudata->suspended = false;
	}

	cached_floor_perf = freq_to_perf(perf, cpudata->nominal_freq, cpudata->floor_freq);
	return amd_pstate_set_floor_perf(policy, cached_floor_perf);
}

static struct cpufreq_driver amd_pstate_driver = {
	.flags		= CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS,
	.verify		= amd_pstate_verify,
	.target		= amd_pstate_target,
	.fast_switch    = amd_pstate_fast_switch,
	.init		= amd_pstate_cpu_init,
	.exit		= amd_pstate_cpu_exit,
	.online		= amd_pstate_cpu_online,
	.offline	= amd_pstate_cpu_offline,
	.suspend	= amd_pstate_suspend,
	.resume		= amd_pstate_resume,
	.set_boost	= amd_pstate_set_boost,
	.update_limits	= amd_pstate_update_limits,
	.name		= "amd-pstate",
};

static struct cpufreq_driver amd_pstate_epp_driver = {
	.flags		= CPUFREQ_CONST_LOOPS,
	.verify		= amd_pstate_verify,
	.setpolicy	= amd_pstate_epp_set_policy,
	.init		= amd_pstate_epp_cpu_init,
	.exit		= amd_pstate_epp_cpu_exit,
	.offline	= amd_pstate_cpu_offline,
	.online		= amd_pstate_cpu_online,
	.suspend	= amd_pstate_suspend,
	.resume		= amd_pstate_epp_resume,
	.update_limits	= amd_pstate_update_limits,
	.set_boost	= amd_pstate_set_boost,
	.name		= "amd-pstate-epp",
};

/*
 * 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.
	 *
	 * For such processors, check the CPPC flag and display a
	 * warning message if the platform supports CPPC.
	 *
	 * Note: The code check below will not abort the driver
	 * registration process because of the code is added for
	 * debugging purposes. Besides, it may still be possible for
	 * the driver to work using the shared-memory mechanism.
	 */
	if (!cpu_feature_enabled(X86_FEATURE_CPPC)) {
		if (cpu_feature_enabled(X86_FEATURE_ZEN2)) {
			switch (c->x86_model) {
			case 0x60 ... 0x6F:
			case 0x80 ... 0xAF:
				warn = true;
				break;
			}
		} else if (cpu_feature_enabled(X86_FEATURE_ZEN3) ||
			   cpu_feature_enabled(X86_FEATURE_ZEN4)) {
			switch (c->x86_model) {
			case 0x10 ... 0x1F:
			case 0x40 ... 0xAF:
				warn = true;
				break;
			}
		} 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;
	int ret;

	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;
	}

	/* don't keep reloading if cpufreq_driver exists */
	if (cpufreq_get_current_driver())
		return -EEXIST;

	quirks = NULL;

	/* check if this machine need CPPC quirks */
	dmi_check_system(amd_pstate_quirks_table);

	/*
	* 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 with CPUs older than Family 0x1A.
		 */
		if (amd_pstate_acpi_pm_profile_undefined() ||
		    (amd_pstate_acpi_pm_profile_server() && boot_cpu_data.x86 < 0x1A)) {
			pr_info("driver load is disabled, boot with specific mode to enable this\n");
			return -ENODEV;
		}
		/* get driver mode from kernel config option [1:4] */
		cppc_state = CONFIG_X86_AMD_PSTATE_DEFAULT_MODE;
	}

	if (cppc_state == AMD_PSTATE_DISABLE) {
		pr_info("driver load is disabled, boot with specific mode to enable this\n");
		return -ENODEV;
	}

	/* capability check */
	if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
		pr_debug("AMD CPPC MSR based functionality is supported\n");
	} else {
		pr_debug("AMD CPPC shared memory based functionality is supported\n");
		static_call_update(amd_pstate_cppc_enable, shmem_cppc_enable);
		static_call_update(amd_pstate_init_perf, shmem_init_perf);
		static_call_update(amd_pstate_update_perf, shmem_update_perf);
		static_call_update(amd_pstate_get_epp, shmem_get_epp);
		static_call_update(amd_pstate_set_epp, shmem_set_epp);
	}

	if (amd_pstate_prefcore) {
		ret = amd_detect_prefcore(&amd_pstate_prefcore);
		if (ret)
			return ret;
	}

	ret = amd_pstate_register_driver(cppc_state);
	if (ret) {
		pr_err("failed to register with return %d\n", ret);
		return ret;
	}

	dev_root = bus_get_dev_root(&cpu_subsys);
	if (dev_root) {
		ret = sysfs_create_group(&dev_root->kobj, &amd_pstate_global_attr_group);
		put_device(dev_root);
		if (ret) {
			pr_err("sysfs attribute export failed with error %d.\n", ret);
			goto global_attr_free;
		}
	}

	return ret;

global_attr_free:
	amd_pstate_unregister_driver(0);
	return ret;
}
device_initcall(amd_pstate_init);

static int __init amd_pstate_param(char *str)
{
	size_t size;
	int mode_idx;

	if (!str)
		return -EINVAL;

	size = strlen(str);
	mode_idx = get_mode_idx_from_str(str, size);

	return amd_pstate_set_driver(mode_idx);
}

static int __init amd_prefcore_param(char *str)
{
	if (!strcmp(str, "disable"))
		amd_pstate_prefcore = false;

	return 0;
}

static int __init amd_dynamic_epp_param(char *str)
{
	if (!strcmp(str, "disable"))
		dynamic_epp = false;
	if (!strcmp(str, "enable"))
		dynamic_epp = true;

	return 0;
}

early_param("amd_pstate", amd_pstate_param);
early_param("amd_prefcore", amd_prefcore_param);
early_param("amd_dynamic_epp", amd_dynamic_epp_param);

MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>");
MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver");
