Skip to content

Commit 7bc1fcd

Browse files
Perry Yuanrafaeljw
authored andcommitted
ACPI: CPPC: Add AMD pstate energy performance preference cppc control
Add support for setting and querying EPP preferences to the generic CPPC driver. This enables downstream drivers such as amd-pstate to discover and use these values. Downstream drivers that want to use the new symbols cppc_get_epp_caps and cppc_set_epp_perf for querying and setting EPP preferences will need to call cppc_set_epp_perf to enable the EPP function firstly. 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>
1 parent 38a29e5 commit 7bc1fcd

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

drivers/acpi/cppc_acpi.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,19 @@ int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf)
11531153
return cppc_get_perf(cpunum, NOMINAL_PERF, nominal_perf);
11541154
}
11551155

1156+
/**
1157+
* cppc_get_epp_perf - Get the epp register value.
1158+
* @cpunum: CPU from which to get epp preference value.
1159+
* @epp_perf: Return address.
1160+
*
1161+
* Return: 0 for success, -EIO otherwise.
1162+
*/
1163+
int cppc_get_epp_perf(int cpunum, u64 *epp_perf)
1164+
{
1165+
return cppc_get_perf(cpunum, ENERGY_PERF, epp_perf);
1166+
}
1167+
EXPORT_SYMBOL_GPL(cppc_get_epp_perf);
1168+
11561169
/**
11571170
* cppc_get_perf_caps - Get a CPU's performance capabilities.
11581171
* @cpunum: CPU from which to get capabilities info.
@@ -1365,6 +1378,60 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
13651378
}
13661379
EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs);
13671380

1381+
/*
1382+
* Set Energy Performance Preference Register value through
1383+
* Performance Controls Interface
1384+
*/
1385+
int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable)
1386+
{
1387+
int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
1388+
struct cpc_register_resource *epp_set_reg;
1389+
struct cpc_register_resource *auto_sel_reg;
1390+
struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
1391+
struct cppc_pcc_data *pcc_ss_data = NULL;
1392+
int ret;
1393+
1394+
if (!cpc_desc) {
1395+
pr_debug("No CPC descriptor for CPU:%d\n", cpu);
1396+
return -ENODEV;
1397+
}
1398+
1399+
auto_sel_reg = &cpc_desc->cpc_regs[AUTO_SEL_ENABLE];
1400+
epp_set_reg = &cpc_desc->cpc_regs[ENERGY_PERF];
1401+
1402+
if (CPC_IN_PCC(epp_set_reg) || CPC_IN_PCC(auto_sel_reg)) {
1403+
if (pcc_ss_id < 0) {
1404+
pr_debug("Invalid pcc_ss_id for CPU:%d\n", cpu);
1405+
return -ENODEV;
1406+
}
1407+
1408+
if (CPC_SUPPORTED(auto_sel_reg)) {
1409+
ret = cpc_write(cpu, auto_sel_reg, enable);
1410+
if (ret)
1411+
return ret;
1412+
}
1413+
1414+
if (CPC_SUPPORTED(epp_set_reg)) {
1415+
ret = cpc_write(cpu, epp_set_reg, perf_ctrls->energy_perf);
1416+
if (ret)
1417+
return ret;
1418+
}
1419+
1420+
pcc_ss_data = pcc_data[pcc_ss_id];
1421+
1422+
down_write(&pcc_ss_data->pcc_lock);
1423+
/* after writing CPC, transfer the ownership of PCC to platform */
1424+
ret = send_pcc_cmd(pcc_ss_id, CMD_WRITE);
1425+
up_write(&pcc_ss_data->pcc_lock);
1426+
} else {
1427+
ret = -ENOTSUPP;
1428+
pr_debug("_CPC in PCC is not supported\n");
1429+
}
1430+
1431+
return ret;
1432+
}
1433+
EXPORT_SYMBOL_GPL(cppc_set_epp_perf);
1434+
13681435
/**
13691436
* cppc_set_enable - Set to enable CPPC on the processor by writing the
13701437
* Continuous Performance Control package EnableRegister field.

include/acpi/cppc_acpi.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,14 @@ struct cppc_perf_caps {
108108
u32 lowest_nonlinear_perf;
109109
u32 lowest_freq;
110110
u32 nominal_freq;
111+
u32 energy_perf;
111112
};
112113

113114
struct cppc_perf_ctrls {
114115
u32 max_perf;
115116
u32 min_perf;
116117
u32 desired_perf;
118+
u32 energy_perf;
117119
};
118120

119121
struct cppc_perf_fb_ctrs {
@@ -149,6 +151,8 @@ extern bool cpc_ffh_supported(void);
149151
extern bool cpc_supported_by_cpu(void);
150152
extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val);
151153
extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val);
154+
extern int cppc_get_epp_perf(int cpunum, u64 *epp_perf);
155+
extern int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable);
152156
#else /* !CONFIG_ACPI_CPPC_LIB */
153157
static inline int cppc_get_desired_perf(int cpunum, u64 *desired_perf)
154158
{
@@ -202,6 +206,14 @@ static inline int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val)
202206
{
203207
return -ENOTSUPP;
204208
}
209+
static inline int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable)
210+
{
211+
return -ENOTSUPP;
212+
}
213+
static inline int cppc_get_epp_perf(int cpunum, u64 *epp_perf)
214+
{
215+
return -ENOTSUPP;
216+
}
205217
#endif /* !CONFIG_ACPI_CPPC_LIB */
206218

207219
#endif /* _CPPC_ACPI_H*/

0 commit comments

Comments
 (0)