Skip to content

Commit 76531df

Browse files
wkarnyrafaeljw
authored andcommitted
ACPI: CPPC: Add min and max perf register writing support
Currently writing of min and max perf register is deferred in cppc_set_perf function. In CPPC guided mode, these registers needed to be written to guide the platform about min and max perf levels. Add this support to make guided mode work properly on AMD shared memory systems. Acked-by: Huang Rui <ray.huang@amd.com> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name> Signed-off-by: Wyes Karny <wyes.karny@amd.com> [ rjw: Fixed up a multiline comment, subject edits ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 1f5e62f commit 76531df

1 file changed

Lines changed: 15 additions & 7 deletions

File tree

drivers/acpi/cppc_acpi.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,7 +1488,7 @@ EXPORT_SYMBOL_GPL(cppc_set_enable);
14881488
int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
14891489
{
14901490
struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
1491-
struct cpc_register_resource *desired_reg;
1491+
struct cpc_register_resource *desired_reg, *min_perf_reg, *max_perf_reg;
14921492
int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
14931493
struct cppc_pcc_data *pcc_ss_data = NULL;
14941494
int ret = 0;
@@ -1499,6 +1499,8 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
14991499
}
15001500

15011501
desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF];
1502+
min_perf_reg = &cpc_desc->cpc_regs[MIN_PERF];
1503+
max_perf_reg = &cpc_desc->cpc_regs[MAX_PERF];
15021504

15031505
/*
15041506
* This is Phase-I where we want to write to CPC registers
@@ -1507,7 +1509,7 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
15071509
* Since read_lock can be acquired by multiple CPUs simultaneously we
15081510
* achieve that goal here
15091511
*/
1510-
if (CPC_IN_PCC(desired_reg)) {
1512+
if (CPC_IN_PCC(desired_reg) || CPC_IN_PCC(min_perf_reg) || CPC_IN_PCC(max_perf_reg)) {
15111513
if (pcc_ss_id < 0) {
15121514
pr_debug("Invalid pcc_ss_id\n");
15131515
return -ENODEV;
@@ -1530,13 +1532,19 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
15301532
cpc_desc->write_cmd_status = 0;
15311533
}
15321534

1535+
cpc_write(cpu, desired_reg, perf_ctrls->desired_perf);
1536+
15331537
/*
1534-
* Skip writing MIN/MAX until Linux knows how to come up with
1535-
* useful values.
1538+
* Only write if min_perf and max_perf not zero. Some drivers pass zero
1539+
* value to min and max perf, but they don't mean to set the zero value,
1540+
* they just don't want to write to those registers.
15361541
*/
1537-
cpc_write(cpu, desired_reg, perf_ctrls->desired_perf);
1542+
if (perf_ctrls->min_perf)
1543+
cpc_write(cpu, min_perf_reg, perf_ctrls->min_perf);
1544+
if (perf_ctrls->max_perf)
1545+
cpc_write(cpu, max_perf_reg, perf_ctrls->max_perf);
15381546

1539-
if (CPC_IN_PCC(desired_reg))
1547+
if (CPC_IN_PCC(desired_reg) || CPC_IN_PCC(min_perf_reg) || CPC_IN_PCC(max_perf_reg))
15401548
up_read(&pcc_ss_data->pcc_lock); /* END Phase-I */
15411549
/*
15421550
* This is Phase-II where we transfer the ownership of PCC to Platform
@@ -1584,7 +1592,7 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
15841592
* case during a CMD_READ and if there are pending writes it delivers
15851593
* the write command before servicing the read command
15861594
*/
1587-
if (CPC_IN_PCC(desired_reg)) {
1595+
if (CPC_IN_PCC(desired_reg) || CPC_IN_PCC(min_perf_reg) || CPC_IN_PCC(max_perf_reg)) {
15881596
if (down_write_trylock(&pcc_ss_data->pcc_lock)) {/* BEGIN Phase-II */
15891597
/* Update only if there are pending write commands */
15901598
if (pcc_ss_data->pending_pcc_write_cmd)

0 commit comments

Comments
 (0)