Commit 0a17adc6 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'acpi-processor' and 'acpi-cppc'

Merge ACPI processor driver updates and ACPI CPPC library updates for
6.16-rc1:

 - Clean up the initialization of CPU data structures in the ACPI
   processor driver (Zhang Rui).

 - Remove an obsolete comment regarding the C-states handling in the
   ACPI processor driver (Giovanni Gherdovich).

 - Simplify PCC shared memory region handling (Sudeep Holla).

 - Rework and extend functions for reading CPPC register values and for
   updating CPPC registers (Lifeng Zheng).

 - Add three functions related to autonomous CPU performance state
   selection to the CPPC library (Lifeng Zheng).

* acpi-processor:
  ACPI: processor: idle: Remove redundant pr->power.count assignment
  ACPI: processor: idle: Set pr->flags.power unconditionally
  ACPI: processor: idle: Remove obsolete comment

* acpi-cppc:
  ACPI: CPPC: Add three functions related to autonomous selection
  ACPI: CPPC: Modify cppc_get_auto_sel_caps() to cppc_get_auto_sel()
  ACPI: CPPC: Refactor register value get and set ABIs
  ACPI: CPPC: Add cppc_set_reg_val()
  ACPI: CPPC: Extract cppc_get_reg_val_in_pcc()
  ACPI: CPPC: Rename cppc_get_perf() to cppc_get_reg_val()
  ACPI: CPPC: Optimize cppc_get_perf()
  ACPI: CPPC: Add IS_OPTIONAL_CPC_REG macro to judge if a cpc_reg is optional
  ACPI: CPPC: Simplify PCC shared memory region handling
  ACPI: PCC: Simplify PCC shared memory region handling
Loading
Loading
Loading
Loading
+2 −11
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@

struct pcc_data {
	struct pcc_mbox_chan *pcc_chan;
	void __iomem *pcc_comm_addr;
	struct completion done;
	struct mbox_client cl;
	struct acpi_pcc_info ctx;
@@ -81,14 +80,6 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
		ret = AE_SUPPORT;
		goto err_free_channel;
	}
	data->pcc_comm_addr = acpi_os_ioremap(pcc_chan->shmem_base_addr,
					      pcc_chan->shmem_size);
	if (!data->pcc_comm_addr) {
		pr_err("Failed to ioremap PCC comm region mem for %d\n",
		       ctx->subspace_id);
		ret = AE_NO_MEMORY;
		goto err_free_channel;
	}

	*region_context = data;
	return AE_OK;
@@ -113,7 +104,7 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
	reinit_completion(&data->done);

	/* Write to Shared Memory */
	memcpy_toio(data->pcc_comm_addr, (void *)value, data->ctx.length);
	memcpy_toio(data->pcc_chan->shmem, (void *)value, data->ctx.length);

	ret = mbox_send_message(data->pcc_chan->mchan, NULL);
	if (ret < 0)
@@ -134,7 +125,7 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,

	mbox_chan_txdone(data->pcc_chan->mchan, ret);

	memcpy_fromio(value, data->pcc_comm_addr, data->ctx.length);
	memcpy_fromio(value, data->pcc_chan->shmem, data->ctx.length);

	return AE_OK;
}
+193 −136
Original line number Diff line number Diff line
@@ -47,7 +47,6 @@

struct cppc_pcc_data {
	struct pcc_mbox_chan *pcc_channel;
	void __iomem *pcc_comm_addr;
	bool pcc_channel_acquired;
	unsigned int deadline_us;
	unsigned int pcc_mpar, pcc_mrtt, pcc_nominal;
@@ -95,7 +94,7 @@ static DEFINE_PER_CPU(int, cpu_pcc_subspace_idx);
static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);

/* pcc mapped address + header size + offset within PCC subspace */
#define GET_PCC_VADDR(offs, pcc_ss_id) (pcc_data[pcc_ss_id]->pcc_comm_addr + \
#define GET_PCC_VADDR(offs, pcc_ss_id) (pcc_data[pcc_ss_id]->pcc_channel->shmem + \
						0x8 + (offs))

/* Check if a CPC register is in PCC */
@@ -129,6 +128,20 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
#define CPC_SUPPORTED(cpc) ((cpc)->type == ACPI_TYPE_INTEGER ?		\
				!!(cpc)->cpc_entry.int_value :		\
				!IS_NULL_REG(&(cpc)->cpc_entry.reg))

/*
 * Each bit indicates the optionality of the register in per-cpu
 * cpc_regs[] with the corresponding index. 0 means mandatory and 1
 * means optional.
 */
#define REG_OPTIONAL (0x1FC7D0)

/*
 * Use the index of the register in per-cpu cpc_regs[] to check if
 * it's an optional one.
 */
#define IS_OPTIONAL_CPC_REG(reg_idx) (REG_OPTIONAL & (1U << (reg_idx)))

/*
 * Arbitrary Retries in case the remote processor is slow to respond
 * to PCC commands. Keeping it high enough to cover emulators where
@@ -223,7 +236,7 @@ static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit)
	int ret, status;
	struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id];
	struct acpi_pcct_shared_memory __iomem *generic_comm_base =
		pcc_ss_data->pcc_comm_addr;
					pcc_ss_data->pcc_channel->shmem;

	if (!pcc_ss_data->platform_owns_pcc)
		return 0;
@@ -258,7 +271,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd)
	int ret = -EIO, i;
	struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id];
	struct acpi_pcct_shared_memory __iomem *generic_comm_base =
		pcc_ss_data->pcc_comm_addr;
					pcc_ss_data->pcc_channel->shmem;
	unsigned int time_delta;

	/*
@@ -571,15 +584,6 @@ static int register_pcc_channel(int pcc_ss_idx)
		pcc_data[pcc_ss_idx]->pcc_mpar = pcc_chan->max_access_rate;
		pcc_data[pcc_ss_idx]->pcc_nominal = pcc_chan->latency;

		pcc_data[pcc_ss_idx]->pcc_comm_addr =
			acpi_os_ioremap(pcc_chan->shmem_base_addr,
					pcc_chan->shmem_size);
		if (!pcc_data[pcc_ss_idx]->pcc_comm_addr) {
			pr_err("Failed to ioremap PCC comm region mem for %d\n",
			       pcc_ss_idx);
			return -ENOMEM;
		}

		/* Set flag so that we don't come here for each CPU. */
		pcc_data[pcc_ss_idx]->pcc_channel_acquired = true;
	}
@@ -1175,43 +1179,106 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
	return ret_val;
}

static int cppc_get_perf(int cpunum, enum cppc_regs reg_idx, u64 *perf)
static int cppc_get_reg_val_in_pcc(int cpu, struct cpc_register_resource *reg, u64 *val)
{
	struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);
	int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
	struct cppc_pcc_data *pcc_ss_data = NULL;
	int ret;

	if (pcc_ss_id < 0) {
		pr_debug("Invalid pcc_ss_id\n");
		return -ENODEV;
	}

	pcc_ss_data = pcc_data[pcc_ss_id];

	down_write(&pcc_ss_data->pcc_lock);

	if (send_pcc_cmd(pcc_ss_id, CMD_READ) >= 0)
		ret = cpc_read(cpu, reg, val);
	else
		ret = -EIO;

	up_write(&pcc_ss_data->pcc_lock);

	return ret;
}

static int cppc_get_reg_val(int cpu, enum cppc_regs reg_idx, u64 *val)
{
	struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
	struct cpc_register_resource *reg;

	if (val == NULL)
		return -EINVAL;

	if (!cpc_desc) {
		pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
		pr_debug("No CPC descriptor for CPU:%d\n", cpu);
		return -ENODEV;
	}

	reg = &cpc_desc->cpc_regs[reg_idx];

	if (CPC_IN_PCC(reg)) {
		int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
	if ((reg->type == ACPI_TYPE_INTEGER && IS_OPTIONAL_CPC_REG(reg_idx) &&
	     !reg->cpc_entry.int_value) || (reg->type != ACPI_TYPE_INTEGER &&
	     IS_NULL_REG(&reg->cpc_entry.reg))) {
		pr_debug("CPC register is not supported\n");
		return -EOPNOTSUPP;
	}

	if (CPC_IN_PCC(reg))
		return cppc_get_reg_val_in_pcc(cpu, reg, val);

	return cpc_read(cpu, reg, val);
}

static int cppc_set_reg_val_in_pcc(int cpu, struct cpc_register_resource *reg, u64 val)
{
	int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
	struct cppc_pcc_data *pcc_ss_data = NULL;
		int ret = 0;
	int ret;

		if (pcc_ss_id < 0)
			return -EIO;
	if (pcc_ss_id < 0) {
		pr_debug("Invalid pcc_ss_id\n");
		return -ENODEV;
	}

	ret = cpc_write(cpu, reg, val);
	if (ret)
		return ret;

	pcc_ss_data = pcc_data[pcc_ss_id];

	down_write(&pcc_ss_data->pcc_lock);

		if (send_pcc_cmd(pcc_ss_id, CMD_READ) >= 0)
			cpc_read(cpunum, reg, perf);
		else
			ret = -EIO;

	/* after writing CPC, transfer the ownership of PCC to platform */
	ret = send_pcc_cmd(pcc_ss_id, CMD_WRITE);
	up_write(&pcc_ss_data->pcc_lock);

	return ret;
}

	cpc_read(cpunum, reg, perf);
static int cppc_set_reg_val(int cpu, enum cppc_regs reg_idx, u64 val)
{
	struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
	struct cpc_register_resource *reg;

	return 0;
	if (!cpc_desc) {
		pr_debug("No CPC descriptor for CPU:%d\n", cpu);
		return -ENODEV;
	}

	reg = &cpc_desc->cpc_regs[reg_idx];

	/* if a register is writeable, it must be a buffer and not null */
	if ((reg->type != ACPI_TYPE_BUFFER) || IS_NULL_REG(&reg->cpc_entry.reg)) {
		pr_debug("CPC register is not supported\n");
		return -EOPNOTSUPP;
	}

	if (CPC_IN_PCC(reg))
		return cppc_set_reg_val_in_pcc(cpu, reg, val);

	return cpc_write(cpu, reg, val);
}

/**
@@ -1223,7 +1290,7 @@ static int cppc_get_perf(int cpunum, enum cppc_regs reg_idx, u64 *perf)
 */
int cppc_get_desired_perf(int cpunum, u64 *desired_perf)
{
	return cppc_get_perf(cpunum, DESIRED_PERF, desired_perf);
	return cppc_get_reg_val(cpunum, DESIRED_PERF, desired_perf);
}
EXPORT_SYMBOL_GPL(cppc_get_desired_perf);

@@ -1236,7 +1303,7 @@ EXPORT_SYMBOL_GPL(cppc_get_desired_perf);
 */
int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf)
{
	return cppc_get_perf(cpunum, NOMINAL_PERF, nominal_perf);
	return cppc_get_reg_val(cpunum, NOMINAL_PERF, nominal_perf);
}

/**
@@ -1248,7 +1315,7 @@ int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf)
 */
int cppc_get_highest_perf(int cpunum, u64 *highest_perf)
{
	return cppc_get_perf(cpunum, HIGHEST_PERF, highest_perf);
	return cppc_get_reg_val(cpunum, HIGHEST_PERF, highest_perf);
}
EXPORT_SYMBOL_GPL(cppc_get_highest_perf);

@@ -1261,7 +1328,7 @@ EXPORT_SYMBOL_GPL(cppc_get_highest_perf);
 */
int cppc_get_epp_perf(int cpunum, u64 *epp_perf)
{
	return cppc_get_perf(cpunum, ENERGY_PERF, epp_perf);
	return cppc_get_reg_val(cpunum, ENERGY_PERF, epp_perf);
}
EXPORT_SYMBOL_GPL(cppc_get_epp_perf);

@@ -1535,98 +1602,119 @@ int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable)
EXPORT_SYMBOL_GPL(cppc_set_epp_perf);

/**
 * cppc_get_auto_sel_caps - Read autonomous selection register.
 * @cpunum : CPU from which to read register.
 * @perf_caps : struct where autonomous selection register value is updated.
 * cppc_set_epp() - Write the EPP register.
 * @cpu: CPU on which to write register.
 * @epp_val: Value to write to the EPP register.
 */
int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps)
int cppc_set_epp(int cpu, u64 epp_val)
{
	struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);
	struct cpc_register_resource *auto_sel_reg;
	u64  auto_sel;
	if (epp_val > CPPC_ENERGY_PERF_MAX)
		return -EINVAL;

	if (!cpc_desc) {
		pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
		return -ENODEV;
	return cppc_set_reg_val(cpu, ENERGY_PERF, epp_val);
}
EXPORT_SYMBOL_GPL(cppc_set_epp);

	auto_sel_reg = &cpc_desc->cpc_regs[AUTO_SEL_ENABLE];
/**
 * cppc_get_auto_act_window() - Read autonomous activity window register.
 * @cpu: CPU from which to read register.
 * @auto_act_window: Return address.
 *
 * According to ACPI 6.5, s8.4.6.1.6, the value read from the autonomous
 * activity window register consists of two parts: a 7 bits value indicate
 * significand and a 3 bits value indicate exponent.
 */
int cppc_get_auto_act_window(int cpu, u64 *auto_act_window)
{
	unsigned int exp;
	u64 val, sig;
	int ret;

	if (!CPC_SUPPORTED(auto_sel_reg))
		pr_warn_once("Autonomous mode is not unsupported!\n");
	if (auto_act_window == NULL)
		return -EINVAL;

	if (CPC_IN_PCC(auto_sel_reg)) {
		int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
		struct cppc_pcc_data *pcc_ss_data = NULL;
		int ret = 0;
	ret = cppc_get_reg_val(cpu, AUTO_ACT_WINDOW, &val);
	if (ret)
		return ret;

		if (pcc_ss_id < 0)
			return -ENODEV;
	sig = val & CPPC_AUTO_ACT_WINDOW_MAX_SIG;
	exp = (val >> CPPC_AUTO_ACT_WINDOW_SIG_BIT_SIZE) & CPPC_AUTO_ACT_WINDOW_MAX_EXP;
	*auto_act_window = sig * int_pow(10, exp);

		pcc_ss_data = pcc_data[pcc_ss_id];
	return 0;
}
EXPORT_SYMBOL_GPL(cppc_get_auto_act_window);

		down_write(&pcc_ss_data->pcc_lock);
/**
 * cppc_set_auto_act_window() - Write autonomous activity window register.
 * @cpu: CPU on which to write register.
 * @auto_act_window: usec value to write to the autonomous activity window register.
 *
 * According to ACPI 6.5, s8.4.6.1.6, the value to write to the autonomous
 * activity window register consists of two parts: a 7 bits value indicate
 * significand and a 3 bits value indicate exponent.
 */
int cppc_set_auto_act_window(int cpu, u64 auto_act_window)
{
	/* The max value to store is 1270000000 */
	u64 max_val = CPPC_AUTO_ACT_WINDOW_MAX_SIG * int_pow(10, CPPC_AUTO_ACT_WINDOW_MAX_EXP);
	int exp = 0;
	u64 val;

		if (send_pcc_cmd(pcc_ss_id, CMD_READ) >= 0) {
			cpc_read(cpunum, auto_sel_reg, &auto_sel);
			perf_caps->auto_sel = (bool)auto_sel;
		} else {
			ret = -EIO;
	if (auto_act_window > max_val)
		return -EINVAL;

	/*
	 * The max significand is 127, when auto_act_window is larger than
	 * 129, discard the precision of the last digit and increase the
	 * exponent by 1.
	 */
	while (auto_act_window > CPPC_AUTO_ACT_WINDOW_SIG_CARRY_THRESH) {
		auto_act_window /= 10;
		exp += 1;
	}

		up_write(&pcc_ss_data->pcc_lock);
	/* For 128 and 129, cut it to 127. */
	if (auto_act_window > CPPC_AUTO_ACT_WINDOW_MAX_SIG)
		auto_act_window = CPPC_AUTO_ACT_WINDOW_MAX_SIG;

		return ret;
	}
	val = (exp << CPPC_AUTO_ACT_WINDOW_SIG_BIT_SIZE) + auto_act_window;

	return 0;
	return cppc_set_reg_val(cpu, AUTO_ACT_WINDOW, val);
}
EXPORT_SYMBOL_GPL(cppc_get_auto_sel_caps);
EXPORT_SYMBOL_GPL(cppc_set_auto_act_window);

/**
 * cppc_set_auto_sel - Write autonomous selection register.
 * @cpu    : CPU to which to write register.
 * @enable : the desired value of autonomous selection resiter to be updated.
 * cppc_get_auto_sel() - Read autonomous selection register.
 * @cpu: CPU from which to read register.
 * @enable: Return address.
 */
int cppc_set_auto_sel(int cpu, bool enable)
int cppc_get_auto_sel(int cpu, bool *enable)
{
	int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
	struct cpc_register_resource *auto_sel_reg;
	struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
	struct cppc_pcc_data *pcc_ss_data = NULL;
	int ret = -EINVAL;

	if (!cpc_desc) {
		pr_debug("No CPC descriptor for CPU:%d\n", cpu);
		return -ENODEV;
	}

	auto_sel_reg = &cpc_desc->cpc_regs[AUTO_SEL_ENABLE];
	u64 auto_sel;
	int ret;

	if (CPC_IN_PCC(auto_sel_reg)) {
		if (pcc_ss_id < 0) {
			pr_debug("Invalid pcc_ss_id\n");
			return -ENODEV;
		}
	if (enable == NULL)
		return -EINVAL;

		if (CPC_SUPPORTED(auto_sel_reg)) {
			ret = cpc_write(cpu, auto_sel_reg, enable);
	ret = cppc_get_reg_val(cpu, AUTO_SEL_ENABLE, &auto_sel);
	if (ret)
		return ret;
		}

		pcc_ss_data = pcc_data[pcc_ss_id];
	*enable = (bool)auto_sel;

		down_write(&pcc_ss_data->pcc_lock);
		/* after writing CPC, transfer the ownership of PCC to platform */
		ret = send_pcc_cmd(pcc_ss_id, CMD_WRITE);
		up_write(&pcc_ss_data->pcc_lock);
	} else {
		ret = -ENOTSUPP;
		pr_debug("_CPC in PCC is not supported\n");
	return 0;
}
EXPORT_SYMBOL_GPL(cppc_get_auto_sel);

	return ret;
/**
 * cppc_set_auto_sel - Write autonomous selection register.
 * @cpu    : CPU to which to write register.
 * @enable : the desired value of autonomous selection resiter to be updated.
 */
int cppc_set_auto_sel(int cpu, bool enable)
{
	return cppc_set_reg_val(cpu, AUTO_SEL_ENABLE, enable);
}
EXPORT_SYMBOL_GPL(cppc_set_auto_sel);

@@ -1640,38 +1728,7 @@ EXPORT_SYMBOL_GPL(cppc_set_auto_sel);
 */
int cppc_set_enable(int cpu, bool enable)
{
	int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
	struct cpc_register_resource *enable_reg;
	struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
	struct cppc_pcc_data *pcc_ss_data = NULL;
	int ret = -EINVAL;

	if (!cpc_desc) {
		pr_debug("No CPC descriptor for CPU:%d\n", cpu);
		return -EINVAL;
	}

	enable_reg = &cpc_desc->cpc_regs[ENABLE];

	if (CPC_IN_PCC(enable_reg)) {

		if (pcc_ss_id < 0)
			return -EIO;

		ret = cpc_write(cpu, enable_reg, enable);
		if (ret)
			return ret;

		pcc_ss_data = pcc_data[pcc_ss_id];

		down_write(&pcc_ss_data->pcc_lock);
		/* after writing CPC, transfer the ownership of PCC to platfrom */
		ret = send_pcc_cmd(pcc_ss_id, CMD_WRITE);
		up_write(&pcc_ss_data->pcc_lock);
		return ret;
	}

	return cpc_write(cpu, enable_reg, enable);
	return cppc_set_reg_val(cpu, ENABLE, enable);
}
EXPORT_SYMBOL_GPL(cppc_set_enable);

+1 −13
Original line number Diff line number Diff line
@@ -461,10 +461,8 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)

static int acpi_processor_get_cstate_info(struct acpi_processor *pr)
{
	unsigned int i;
	int result;


	/* NOTE: the idle thread may not be running while calling
	 * this function */

@@ -481,17 +479,7 @@ static int acpi_processor_get_cstate_info(struct acpi_processor *pr)
	acpi_processor_get_power_info_default(pr);

	pr->power.count = acpi_processor_power_verify(pr);

	/*
	 * if one state of type C2 or C3 is available, mark this
	 * CPU as being "idle manageable"
	 */
	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
		if (pr->power.states[i].valid) {
			pr->power.count = i;
	pr->flags.power = 1;
		}
	}

	return 0;
}
+2 −1
Original line number Diff line number Diff line
@@ -417,6 +417,7 @@ 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)
@@ -438,7 +439,7 @@ static int shmem_init_perf(struct amd_cpudata *cpudata)
	if (cppc_state == AMD_PSTATE_ACTIVE)
		return 0;

	ret = cppc_get_auto_sel_caps(cpudata->cpu, &cppc_perf);
	ret = cppc_get_auto_sel(cpudata->cpu, &auto_sel);
	if (ret) {
		pr_warn("failed to get auto_sel, ret: %d\n", ret);
		return 0;
+27 −3
Original line number Diff line number Diff line
@@ -32,6 +32,15 @@
#define	CMD_READ 0
#define	CMD_WRITE 1

#define CPPC_AUTO_ACT_WINDOW_SIG_BIT_SIZE	(7)
#define CPPC_AUTO_ACT_WINDOW_EXP_BIT_SIZE	(3)
#define CPPC_AUTO_ACT_WINDOW_MAX_SIG	((1 << CPPC_AUTO_ACT_WINDOW_SIG_BIT_SIZE) - 1)
#define CPPC_AUTO_ACT_WINDOW_MAX_EXP	((1 << CPPC_AUTO_ACT_WINDOW_EXP_BIT_SIZE) - 1)
/* CPPC_AUTO_ACT_WINDOW_MAX_SIG is 127, so 128 and 129 will decay to 127 when writing */
#define CPPC_AUTO_ACT_WINDOW_SIG_CARRY_THRESH 129

#define CPPC_ENERGY_PERF_MAX	(0xFF)

/* Each register has the folowing format. */
struct cpc_reg {
	u8 descriptor;
@@ -159,7 +168,10 @@ extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val);
extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val);
extern int cppc_get_epp_perf(int cpunum, u64 *epp_perf);
extern int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable);
extern int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps);
extern int cppc_set_epp(int cpu, u64 epp_val);
extern int cppc_get_auto_act_window(int cpu, u64 *auto_act_window);
extern int cppc_set_auto_act_window(int cpu, u64 auto_act_window);
extern int cppc_get_auto_sel(int cpu, bool *enable);
extern int cppc_set_auto_sel(int cpu, bool enable);
extern int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf);
extern int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator);
@@ -229,11 +241,23 @@ static inline int cppc_get_epp_perf(int cpunum, u64 *epp_perf)
{
	return -EOPNOTSUPP;
}
static inline int cppc_set_auto_sel(int cpu, bool enable)
static inline int cppc_set_epp(int cpu, u64 epp_val)
{
	return -EOPNOTSUPP;
}
static inline int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps)
static inline int cppc_get_auto_act_window(int cpu, u64 *auto_act_window)
{
	return -EOPNOTSUPP;
}
static inline int cppc_set_auto_act_window(int cpu, u64 auto_act_window)
{
	return -EOPNOTSUPP;
}
static inline int cppc_get_auto_sel(int cpu, bool *enable)
{
	return -EOPNOTSUPP;
}
static inline int cppc_set_auto_sel(int cpu, bool enable)
{
	return -EOPNOTSUPP;
}