Skip to content

Commit 54e74df

Browse files
fenghusthurafaeljw
authored andcommitted
cpufreq: CPPC: add SW BOOST support
To add SW BOOST support for CPPC, we need to get the max frequency of boost mode and non-boost mode. ACPI spec 6.2 section 8.4.7.1 describes the following two CPC registers. "Highest performance is the absolute maximum performance an individual processor may reach, assuming ideal conditions. This performance level may not be sustainable for long durations, and may only be achievable if other platform components are in a specific state; for example, it may require other processors be in an idle state. Nominal Performance is the maximum sustained performance level of the processor, assuming ideal operating conditions. In absence of an external constraint (power, thermal, etc.) this is the performance level the platform is expected to be able to maintain continuously. All processors are expected to be able to sustain their nominal performance state simultaneously." To add SW BOOST support for CPPC, we can use Highest Performance as the max performance in boost mode and Nominal Performance as the max performance in non-boost mode. If the Highest Performance is greater than the Nominal Performance, we assume SW BOOST is supported. The current CPPC driver does not support SW BOOST and use 'Highest Performance' as the max performance the CPU can achieve. 'Nominal Performance' is used to convert 'performance' to 'frequency'. That means, if firmware enable boost and provide a value for Highest Performance which is greater than Nominal Performance, boost feature is enabled by default. Because SW BOOST is disabled by default, so, after this patch, boost feature is disabled by default even if boost is enabled by firmware. Signed-off-by: Xiongfeng Wang <[email protected]> Suggested-by: Viresh Kumar <[email protected]> Acked-by: Viresh Kumar <[email protected]> [ rjw: Subject ] Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent cf6fada commit 54e74df

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

drivers/cpufreq/cppc_cpufreq.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
* requested etc.
3838
*/
3939
static struct cppc_cpudata **all_cpu_data;
40+
static bool boost_supported;
4041

4142
struct cppc_workaround_oem_info {
4243
char oem_id[ACPI_OEM_ID_SIZE + 1];
@@ -310,15 +311,15 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
310311
* Section 8.4.7.1.1.5 of ACPI 6.1 spec)
311312
*/
312313
policy->min = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_nonlinear_perf);
313-
policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf);
314+
policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf);
314315

315316
/*
316317
* Set cpuinfo.min_freq to Lowest to make the full range of performance
317318
* available if userspace wants to use any perf between lowest & lowest
318319
* nonlinear perf
319320
*/
320321
policy->cpuinfo.min_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_perf);
321-
policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf);
322+
policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf);
322323

323324
policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu_num);
324325
policy->shared_type = cpu->shared_type;
@@ -343,6 +344,13 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
343344

344345
cpu->cur_policy = policy;
345346

347+
/*
348+
* If 'highest_perf' is greater than 'nominal_perf', we assume CPU Boost
349+
* is supported.
350+
*/
351+
if (cpu->perf_caps.highest_perf > cpu->perf_caps.nominal_perf)
352+
boost_supported = true;
353+
346354
/* Set policy->cur to max now. The governors will adjust later. */
347355
policy->cur = cppc_cpufreq_perf_to_khz(cpu,
348356
cpu->perf_caps.highest_perf);
@@ -410,13 +418,40 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum)
410418
return cppc_get_rate_from_fbctrs(cpu, fb_ctrs_t0, fb_ctrs_t1);
411419
}
412420

421+
static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)
422+
{
423+
struct cppc_cpudata *cpudata;
424+
int ret;
425+
426+
if (!boost_supported) {
427+
pr_err("BOOST not supported by CPU or firmware\n");
428+
return -EINVAL;
429+
}
430+
431+
cpudata = all_cpu_data[policy->cpu];
432+
if (state)
433+
policy->max = cppc_cpufreq_perf_to_khz(cpudata,
434+
cpudata->perf_caps.highest_perf);
435+
else
436+
policy->max = cppc_cpufreq_perf_to_khz(cpudata,
437+
cpudata->perf_caps.nominal_perf);
438+
policy->cpuinfo.max_freq = policy->max;
439+
440+
ret = freq_qos_update_request(policy->max_freq_req, policy->max);
441+
if (ret < 0)
442+
return ret;
443+
444+
return 0;
445+
}
446+
413447
static struct cpufreq_driver cppc_cpufreq_driver = {
414448
.flags = CPUFREQ_CONST_LOOPS,
415449
.verify = cppc_verify_policy,
416450
.target = cppc_cpufreq_set_target,
417451
.get = cppc_cpufreq_get_rate,
418452
.init = cppc_cpufreq_cpu_init,
419453
.stop_cpu = cppc_cpufreq_stop_cpu,
454+
.set_boost = cppc_cpufreq_set_boost,
420455
.name = "cppc_cpufreq",
421456
};
422457

0 commit comments

Comments
 (0)