123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- 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 D r i v e r s
- - information for developers -
- Dominik Brodowski <linux@brodo.de>
- 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. What To Do?
- 1.1 Initialization
- 1.2 Per-CPU Initialization
- 1.3 verify
- 1.4 target/target_index or setpolicy?
- 1.5 target/target_index
- 1.6 setpolicy
- 1.7 get_intermediate and target_intermediate
- 2. Frequency Table Helpers
- 1. What To Do?
- ==============
- So, you just got a brand-new CPU / chipset with datasheets and want to
- add cpufreq support for this CPU / chipset? Great. Here are some hints
- on what is necessary:
- 1.1 Initialization
- ------------------
- First of all, in an __initcall level 7 (module_init()) or later
- function check whether this kernel runs on the right CPU and the right
- chipset. If so, register a struct cpufreq_driver with the CPUfreq core
- using cpufreq_register_driver()
- What shall this struct cpufreq_driver contain?
- cpufreq_driver.name - The name of this driver.
- cpufreq_driver.init - A pointer to the per-CPU initialization
- function.
- cpufreq_driver.verify - A pointer to a "verification" function.
- cpufreq_driver.setpolicy _or_
- cpufreq_driver.target/
- target_index - See below on the differences.
- And optionally
- cpufreq_driver.exit - A pointer to a per-CPU cleanup
- function called during CPU_POST_DEAD
- phase of cpu hotplug process.
- cpufreq_driver.stop_cpu - A pointer to a per-CPU stop function
- called during CPU_DOWN_PREPARE phase of
- cpu hotplug process.
- cpufreq_driver.resume - A pointer to a per-CPU resume function
- which is called with interrupts disabled
- and _before_ the pre-suspend frequency
- and/or policy is restored by a call to
- ->target/target_index or ->setpolicy.
- cpufreq_driver.attr - A pointer to a NULL-terminated list of
- "struct freq_attr" which allow to
- export values to sysfs.
- cpufreq_driver.get_intermediate
- and target_intermediate Used to switch to stable frequency while
- changing CPU frequency.
- 1.2 Per-CPU Initialization
- --------------------------
- Whenever a new CPU is registered with the device model, or after the
- cpufreq driver registers itself, the per-CPU initialization function
- cpufreq_driver.init is called. It takes a struct cpufreq_policy
- *policy as argument. What to do now?
- If necessary, activate the CPUfreq support on your CPU.
- Then, the driver must fill in the following values:
- policy->cpuinfo.min_freq _and_
- policy->cpuinfo.max_freq - the minimum and maximum frequency
- (in kHz) which is supported by
- this CPU
- policy->cpuinfo.transition_latency the time it takes on this CPU to
- switch between two frequencies in
- nanoseconds (if appropriate, else
- specify CPUFREQ_ETERNAL)
- policy->cur The current operating frequency of
- this CPU (if appropriate)
- policy->min,
- policy->max,
- policy->policy and, if necessary,
- policy->governor must contain the "default policy" for
- this CPU. A few moments later,
- cpufreq_driver.verify and either
- cpufreq_driver.setpolicy or
- cpufreq_driver.target/target_index is called
- with these values.
- For setting some of these values (cpuinfo.min[max]_freq, policy->min[max]), the
- frequency table helpers might be helpful. See the section 2 for more information
- on them.
- SMP systems normally have same clock source for a group of cpus. For these the
- .init() would be called only once for the first online cpu. Here the .init()
- routine must initialize policy->cpus with mask of all possible cpus (Online +
- Offline) that share the clock. Then the core would copy this mask onto
- policy->related_cpus and will reset policy->cpus to carry only online cpus.
- 1.3 verify
- ------------
- When the user decides a new policy (consisting of
- "policy,governor,min,max") shall be set, this policy must be validated
- so that incompatible values can be corrected. For verifying these
- values, a frequency table helper and/or the
- cpufreq_verify_within_limits(struct cpufreq_policy *policy, unsigned
- int min_freq, unsigned int max_freq) function might be helpful. See
- section 2 for details on frequency table helpers.
- You need to make sure that at least one valid frequency (or operating
- range) is within policy->min and policy->max. If necessary, increase
- policy->max first, and only if this is no solution, decrease policy->min.
- 1.4 target/target_index or setpolicy?
- ----------------------------
- Most cpufreq drivers or even most cpu frequency scaling algorithms
- only allow the CPU to be set to one frequency. For these, you use the
- ->target/target_index call.
- Some cpufreq-capable processors switch the frequency between certain
- limits on their own. These shall use the ->setpolicy call
- 1.5. target/target_index
- -------------
- The target_index call has two arguments: struct cpufreq_policy *policy,
- and unsigned int index (into the exposed frequency table).
- The CPUfreq driver must set the new frequency when called here. The
- actual frequency must be determined by freq_table[index].frequency.
- It should always restore to earlier frequency (i.e. policy->restore_freq) in
- case of errors, even if we switched to intermediate frequency earlier.
- Deprecated:
- ----------
- The target call has three arguments: struct cpufreq_policy *policy,
- unsigned int target_frequency, unsigned int relation.
- The CPUfreq driver must set the new frequency when called here. The
- actual frequency must be determined using the following rules:
- - keep close to "target_freq"
- - policy->min <= new_freq <= policy->max (THIS MUST BE VALID!!!)
- - if relation==CPUFREQ_REL_L, try to select a new_freq higher than or equal
- target_freq. ("L for lowest, but no lower than")
- - if relation==CPUFREQ_REL_H, try to select a new_freq lower than or equal
- target_freq. ("H for highest, but no higher than")
- Here again the frequency table helper might assist you - see section 2
- for details.
- 1.6 setpolicy
- ---------------
- The setpolicy call only takes a struct cpufreq_policy *policy as
- argument. You need to set the lower limit of the in-processor or
- in-chipset dynamic frequency switching to policy->min, the upper limit
- to policy->max, and -if supported- select a performance-oriented
- setting when policy->policy is CPUFREQ_POLICY_PERFORMANCE, and a
- powersaving-oriented setting when CPUFREQ_POLICY_POWERSAVE. Also check
- the reference implementation in drivers/cpufreq/longrun.c
- 1.7 get_intermediate and target_intermediate
- --------------------------------------------
- Only for drivers with target_index() and CPUFREQ_ASYNC_NOTIFICATION unset.
- get_intermediate should return a stable intermediate frequency platform wants to
- switch to, and target_intermediate() should set CPU to to that frequency, before
- jumping to the frequency corresponding to 'index'. Core will take care of
- sending notifications and driver doesn't have to handle them in
- target_intermediate() or target_index().
- Drivers can return '0' from get_intermediate() in case they don't wish to switch
- to intermediate frequency for some target frequency. In that case core will
- directly call ->target_index().
- NOTE: ->target_index() should restore to policy->restore_freq in case of
- failures as core would send notifications for that.
- 2. Frequency Table Helpers
- ==========================
- As most cpufreq processors only allow for being set to a few specific
- frequencies, a "frequency table" with some functions might assist in
- some work of the processor driver. Such a "frequency table" consists
- of an array of struct cpufreq_frequency_table entries, with any value in
- "driver_data" you want to use, and the corresponding frequency in
- "frequency". At the end of the table, you need to add a
- cpufreq_frequency_table entry with frequency set to CPUFREQ_TABLE_END. And
- if you want to skip one entry in the table, set the frequency to
- CPUFREQ_ENTRY_INVALID. The entries don't need to be in ascending
- order.
- By calling cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
- struct cpufreq_frequency_table *table);
- the cpuinfo.min_freq and cpuinfo.max_freq values are detected, and
- policy->min and policy->max are set to the same values. This is
- helpful for the per-CPU initialization stage.
- int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
- struct cpufreq_frequency_table *table);
- assures that at least one valid frequency is within policy->min and
- policy->max, and all other criteria are met. This is helpful for the
- ->verify call.
- int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
- struct cpufreq_frequency_table *table,
- unsigned int target_freq,
- unsigned int relation,
- unsigned int *index);
- is the corresponding frequency table helper for the ->target
- stage. Just pass the values to this function, and the unsigned int
- index returns the number of the frequency table entry which contains
- the frequency the CPU shall be set to.
- The following macros can be used as iterators over cpufreq_frequency_table:
- cpufreq_for_each_entry(pos, table) - iterates over all entries of frequency
- table.
- cpufreq-for_each_valid_entry(pos, table) - iterates over all entries,
- excluding CPUFREQ_ENTRY_INVALID frequencies.
- Use arguments "pos" - a cpufreq_frequency_table * as a loop cursor and
- "table" - the cpufreq_frequency_table * you want to iterate over.
- For example:
- struct cpufreq_frequency_table *pos, *driver_freq_table;
- cpufreq_for_each_entry(pos, driver_freq_table) {
- /* Do something with pos */
- pos->frequency = ...
- }
|