Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | CPU frequency and voltage scaling code in the Linux(TM) kernel |
| 2 | |
| 3 | |
| 4 | L i n u x C P U F r e q |
| 5 | |
| 6 | C P U F r e q C o r e |
| 7 | |
| 8 | |
| 9 | Dominik Brodowski <linux@brodo.de> |
| 10 | David Kimdon <dwhedon@debian.org> |
Viresh Kumar | 7de962c | 2017-01-06 11:08:05 +0530 | [diff] [blame^] | 11 | Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| 12 | Viresh Kumar <viresh.kumar@linaro.org> |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 13 | |
| 14 | |
| 15 | |
| 16 | Clock scaling allows you to change the clock speed of the CPUs on the |
| 17 | fly. This is a nice method to save battery power, because the lower |
| 18 | the clock speed, the less power the CPU consumes. |
| 19 | |
| 20 | |
| 21 | Contents: |
| 22 | --------- |
| 23 | 1. CPUFreq core and interfaces |
| 24 | 2. CPUFreq notifiers |
Nishanth Menon | a0dd7b7 | 2014-05-05 08:33:50 -0500 | [diff] [blame] | 25 | 3. CPUFreq Table Generation with Operating Performance Point (OPP) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 26 | |
| 27 | 1. General Information |
| 28 | ======================= |
| 29 | |
Dominik Brodowski | eff0df6 | 2006-10-02 19:26:47 -0400 | [diff] [blame] | 30 | The CPUFreq core code is located in drivers/cpufreq/cpufreq.c. This |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 31 | cpufreq code offers a standardized interface for the CPUFreq |
| 32 | architecture drivers (those pieces of code that do actual |
| 33 | frequency transitions), as well as to "notifiers". These are device |
| 34 | drivers or other part of the kernel that need to be informed of |
| 35 | policy changes (ex. thermal modules like ACPI) or of all |
| 36 | frequency changes (ex. timing code) or even need to force certain |
| 37 | speed limits (like LCD drivers on ARM architecture). Additionally, the |
| 38 | kernel "constant" loops_per_jiffy is updated on frequency changes |
| 39 | here. |
| 40 | |
Viresh Kumar | 7de962c | 2017-01-06 11:08:05 +0530 | [diff] [blame^] | 41 | Reference counting of the cpufreq policies is done by cpufreq_cpu_get |
| 42 | and cpufreq_cpu_put, which make sure that the cpufreq driver is |
| 43 | correctly registered with the core, and will not be unloaded until |
| 44 | cpufreq_put_cpu is called. That also ensures that the respective cpufreq |
| 45 | policy doesn't get freed while being used. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 46 | |
| 47 | 2. CPUFreq notifiers |
| 48 | ==================== |
| 49 | |
| 50 | CPUFreq notifiers conform to the standard kernel notifier interface. |
| 51 | See linux/include/linux/notifier.h for details on notifiers. |
| 52 | |
| 53 | There are two different CPUFreq notifiers - policy notifiers and |
| 54 | transition notifiers. |
| 55 | |
| 56 | |
| 57 | 2.1 CPUFreq policy notifiers |
| 58 | ---------------------------- |
| 59 | |
| 60 | These are notified when a new policy is intended to be set. Each |
Viresh Kumar | 6bfb7c7 | 2015-08-03 08:36:14 +0530 | [diff] [blame] | 61 | CPUFreq policy notifier is called twice for a policy transition: |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 62 | |
| 63 | 1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if |
| 64 | they see a need for this - may it be thermal considerations or |
| 65 | hardware limitations. |
| 66 | |
Viresh Kumar | 6bfb7c7 | 2015-08-03 08:36:14 +0530 | [diff] [blame] | 67 | 2.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 68 | - if two hardware drivers failed to agree on a new policy before this |
| 69 | stage, the incompatible hardware shall be shut down, and the user |
| 70 | informed of this. |
| 71 | |
| 72 | The phase is specified in the second argument to the notifier. |
| 73 | |
| 74 | The third argument, a void *pointer, points to a struct cpufreq_policy |
Viresh Kumar | 7de962c | 2017-01-06 11:08:05 +0530 | [diff] [blame^] | 75 | consisting of several values, including min, max (the lower and upper |
| 76 | frequencies (in kHz) of the new policy). |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 77 | |
| 78 | |
| 79 | 2.2 CPUFreq transition notifiers |
| 80 | -------------------------------- |
| 81 | |
Viresh Kumar | 7de962c | 2017-01-06 11:08:05 +0530 | [diff] [blame^] | 82 | These are notified twice for each online CPU in the policy, when the |
| 83 | CPUfreq driver switches the CPU core frequency and this change has no |
| 84 | any external implications. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 85 | |
| 86 | The second argument specifies the phase - CPUFREQ_PRECHANGE or |
| 87 | CPUFREQ_POSTCHANGE. |
| 88 | |
| 89 | The third argument is a struct cpufreq_freqs with the following |
| 90 | values: |
| 91 | cpu - number of the affected CPU |
| 92 | old - old frequency |
| 93 | new - new frequency |
Viresh Kumar | 7de962c | 2017-01-06 11:08:05 +0530 | [diff] [blame^] | 94 | flags - flags of the cpufreq driver |
Nishanth Menon | a0dd7b7 | 2014-05-05 08:33:50 -0500 | [diff] [blame] | 95 | |
| 96 | 3. CPUFreq Table Generation with Operating Performance Point (OPP) |
| 97 | ================================================================== |
| 98 | For details about OPP, see Documentation/power/opp.txt |
| 99 | |
| 100 | dev_pm_opp_init_cpufreq_table - cpufreq framework typically is initialized with |
Viresh Kumar | 64bf55a | 2016-05-31 16:50:23 +0530 | [diff] [blame] | 101 | cpufreq_table_validate_and_show() which is provided with the list of |
Nishanth Menon | a0dd7b7 | 2014-05-05 08:33:50 -0500 | [diff] [blame] | 102 | frequencies that are available for operation. This function provides |
| 103 | a ready to use conversion routine to translate the OPP layer's internal |
| 104 | information about the available frequencies into a format readily |
| 105 | providable to cpufreq. |
| 106 | |
| 107 | WARNING: Do not use this function in interrupt context. |
| 108 | |
| 109 | Example: |
| 110 | soc_pm_init() |
| 111 | { |
| 112 | /* Do things */ |
| 113 | r = dev_pm_opp_init_cpufreq_table(dev, &freq_table); |
| 114 | if (!r) |
Viresh Kumar | 64bf55a | 2016-05-31 16:50:23 +0530 | [diff] [blame] | 115 | cpufreq_table_validate_and_show(policy, freq_table); |
Nishanth Menon | a0dd7b7 | 2014-05-05 08:33:50 -0500 | [diff] [blame] | 116 | /* Do other things */ |
| 117 | } |
| 118 | |
| 119 | NOTE: This function is available only if CONFIG_CPU_FREQ is enabled in |
| 120 | addition to CONFIG_PM_OPP. |
| 121 | |
| 122 | dev_pm_opp_free_cpufreq_table - Free up the table allocated by dev_pm_opp_init_cpufreq_table |