mirror of https://gitee.com/openkylin/linux.git
121 lines
4.0 KiB
Plaintext
121 lines
4.0 KiB
Plaintext
CPU frequency and voltage scaling code in the Linux(TM) kernel
|
|
|
|
|
|
L i n u x C P U F r e q
|
|
|
|
C P U F r e q C o r e
|
|
|
|
|
|
Dominik Brodowski <linux@brodo.de>
|
|
David Kimdon <dwhedon@debian.org>
|
|
Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
|
Viresh Kumar <viresh.kumar@linaro.org>
|
|
|
|
|
|
|
|
Clock scaling allows you to change the clock speed of the CPUs on the
|
|
fly. This is a nice method to save battery power, because the lower
|
|
the clock speed, the less power the CPU consumes.
|
|
|
|
|
|
Contents:
|
|
---------
|
|
1. CPUFreq core and interfaces
|
|
2. CPUFreq notifiers
|
|
3. CPUFreq Table Generation with Operating Performance Point (OPP)
|
|
|
|
1. General Information
|
|
=======================
|
|
|
|
The CPUFreq core code is located in drivers/cpufreq/cpufreq.c. This
|
|
cpufreq code offers a standardized interface for the CPUFreq
|
|
architecture drivers (those pieces of code that do actual
|
|
frequency transitions), as well as to "notifiers". These are device
|
|
drivers or other part of the kernel that need to be informed of
|
|
policy changes (ex. thermal modules like ACPI) or of all
|
|
frequency changes (ex. timing code) or even need to force certain
|
|
speed limits (like LCD drivers on ARM architecture). Additionally, the
|
|
kernel "constant" loops_per_jiffy is updated on frequency changes
|
|
here.
|
|
|
|
Reference counting of the cpufreq policies is done by cpufreq_cpu_get
|
|
and cpufreq_cpu_put, which make sure that the cpufreq driver is
|
|
correctly registered with the core, and will not be unloaded until
|
|
cpufreq_put_cpu is called. That also ensures that the respective cpufreq
|
|
policy doesn't get freed while being used.
|
|
|
|
2. CPUFreq notifiers
|
|
====================
|
|
|
|
CPUFreq notifiers conform to the standard kernel notifier interface.
|
|
See linux/include/linux/notifier.h for details on notifiers.
|
|
|
|
There are two different CPUFreq notifiers - policy notifiers and
|
|
transition notifiers.
|
|
|
|
|
|
2.1 CPUFreq policy notifiers
|
|
----------------------------
|
|
|
|
These are notified when a new policy is intended to be set. Each
|
|
CPUFreq policy notifier is called twice for a policy transition:
|
|
|
|
1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if
|
|
they see a need for this - may it be thermal considerations or
|
|
hardware limitations.
|
|
|
|
2.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy
|
|
- if two hardware drivers failed to agree on a new policy before this
|
|
stage, the incompatible hardware shall be shut down, and the user
|
|
informed of this.
|
|
|
|
The phase is specified in the second argument to the notifier.
|
|
|
|
The third argument, a void *pointer, points to a struct cpufreq_policy
|
|
consisting of several values, including min, max (the lower and upper
|
|
frequencies (in kHz) of the new policy).
|
|
|
|
|
|
2.2 CPUFreq transition notifiers
|
|
--------------------------------
|
|
|
|
These are notified twice for each online CPU in the policy, when the
|
|
CPUfreq driver switches the CPU core frequency and this change has no
|
|
any external implications.
|
|
|
|
The second argument specifies the phase - CPUFREQ_PRECHANGE or
|
|
CPUFREQ_POSTCHANGE.
|
|
|
|
The third argument is a struct cpufreq_freqs with the following
|
|
values:
|
|
cpu - number of the affected CPU
|
|
old - old frequency
|
|
new - new frequency
|
|
flags - flags of the cpufreq driver
|
|
|
|
3. CPUFreq Table Generation with Operating Performance Point (OPP)
|
|
==================================================================
|
|
For details about OPP, see Documentation/power/opp.rst
|
|
|
|
dev_pm_opp_init_cpufreq_table -
|
|
This function provides a ready to use conversion routine to translate
|
|
the OPP layer's internal information about the available frequencies
|
|
into a format readily providable to cpufreq.
|
|
|
|
WARNING: Do not use this function in interrupt context.
|
|
|
|
Example:
|
|
soc_pm_init()
|
|
{
|
|
/* Do things */
|
|
r = dev_pm_opp_init_cpufreq_table(dev, &freq_table);
|
|
if (!r)
|
|
policy->freq_table = freq_table;
|
|
/* Do other things */
|
|
}
|
|
|
|
NOTE: This function is available only if CONFIG_CPU_FREQ is enabled in
|
|
addition to CONFIG_PM_OPP.
|
|
|
|
dev_pm_opp_free_cpufreq_table - Free up the table allocated by dev_pm_opp_init_cpufreq_table
|