CPUFREQ(9) | Kernel Developer's Manual | CPUFREQ(9)

# NAME

`cpufreq`, `cpufreq_register`, `cpufreq_deregister`, `cpufreq_suspend`, `cpufreq_resume`, `cpufreq_get`, `cpufreq_get_backend`, `cpufreq_get_state`, `cpufreq_get_state_index`, `cpufreq_set`, `cpufreq_set_all` —
interface for CPU frequency scaling

# SYNOPSIS

`#include <sys/cpufreq.h>`

int
`cpufreq_register`(struct cpufreq *cf);

void
`cpufreq_deregister`(void);

void
`cpufreq_suspend`(struct cpu_info *ci);

void
`cpufreq_resume`(struct cpu_info *ci);

uint32_t
`cpufreq_get`(struct cpu_info *ci);

int
`cpufreq_get_backend`(struct cpufreq *cf);

int
`cpufreq_get_state`(uint32_t freq, struct cpufreq_state *cfs);

int
`cpufreq_get_state_index`(uint32_t index, struct cpufreq_state *cfs);

void
`cpufreq_set`(struct cpu_info *ci, uint32_t freq);

void
`cpufreq_set_all`(uint32_t freq);

# DESCRIPTION

The machine-independent `cpufreq` interface provides a framework for CPU frequency scaling done by a machine-dependent backend implementation.

The `cpufreq` interface is a per-CPU framework. It is implicitly assumed that the frequency can be set independently for all processors in the system. However, `cpufreq` does not imply any restrictions upon whether this information is utilized by the actual machine-dependent implementation. It is possible to use `cpufreq` with frequency scaling implemented via pci(4). In addition, it assumed that the available frequency levels are shared uniformly by all processors in the system, even when it is possible to control the frequency of individual processors.

It should be noted that the `cpufreq` interface is generally stateless. This implies for instance that possible caching should be done in the machine-dependent backend. The `cpufreq_suspend`() and `cpufreq_resume`() functions are exceptions. These can be integrated with pmf(9).

# FUNCTIONS

`cpufreq_register`(cf)
  The `cpufreq_register`() function initializes the interface by associating a machine-dependent backend with the framework. Only one backend can be registered. Upon successful completion, `cpufreq_register`() returns 0 and sets the frequency of all processors to the maximum available level. Note that the registration can be done only after interrupts have been enabled; cf. config_interrupts(9).

  The following elements in struct cpufreq should be filled prior to the call:

      char			 cf_name[CPUFREQ_NAME_MAX];
      struct cpufreq_state     cf_state[CPUFREQ_STATE_MAX];
      uint32_t                 cf_state_count;
      bool			 cf_mp;
      void                    *cf_cookie;
      xcfunc_t                 cf_get_freq;
      xcfunc_t                 cf_set_freq;

  - The name of the backend should be given in cf_name.
  - The cpufreq_state structure conveys descriptive information about the frequency states. The following fields can be used for the registration:

        uint32_t		 cfs_freq;
        uint32_t		 cfs_power;

    From these cfs_freq (the clock frequency in MHz) is mandatory, whereas the optional cfs_power can be filled to describe the power consumption (in mW) of each state. The cf_state array must be filled in descending order, that is, the highest frequency should be at the zero index.

    If the backend operates with a simple boolean switch without knowing the clock frequencies, the cfs_freq field should be set to `CPUFREQ_STATE_ENABLED` or `CPUFREQ_STATE_DISABLED`. The first constant should precede the latter one in cf_state.

  - The cf_state_count field defines the number of states that the backend has filled in the cf_state array.
  - The cf_mp boolean should be set to false if it is known that the backend can not handle per-CPU frequency states; changes should always be propagated to all processors in the system.
  - The cf_cookie field is an opaque pointer passed to the backend when `cpufreq_get`(), `cpufreq_set`(), or `cpufreq_set_all`() is called.
  - The cf_get_freq and cf_set_freq are function pointers that should be associated with the machine-dependent functions to get and set a frequency, respectively. The xcfunc_t type is part of xcall(9). When the function pointers are invoked by `cpufreq`, the first parameter is always the cf_cookie and the second parameter is the frequency, defined as uint32_t *.
`cpufreq_deregister`()
  Deregisters any possible backend in use.
`cpufreq_suspend`(ci)
  The `cpufreq_suspend`() can be called when the processor suspends. The function saves the current frequency of ci and sets the minimum available frequency.
`cpufreq_resume`(ci)
  Resumes the frequency of ci that was used before suspend.
`cpufreq_get`(ci)
  Returns the current frequency of the processor ci. A value zero is returned upon failure.
`cpufreq_get_backend`(cf)
  Upon successful completion, `cpufreq_get_backend`() returns 0 and fills cf with the data related to the currently used backend.
`cpufreq_get_state`(freq, cfs)
  The `cpufreq_get_state`() function looks for the given frequency from the array of known frequency states. If freq is not found, the closest match is returned. Upon successful completion, the function returns zero and stores the state information to cfs.
`cpufreq_get_state_index`(index, cfs)
  Stores the frequency state with the given index to cfs, returning zero upon successful completion.
`cpufreq_set`(ci, freq)
  The `cpufreq_set`() function sets the frequency of ci to freq.
`cpufreq_set_all`(freq)
  Sets freq for all processors in the system.

The three functions `cpufreq_get`(), `cpufreq_set`(), and `cpufreq_set_all`() guarantee that the call will be made in curcpu(9). The interface holds a mutex(9) while calling the functions. This, and the use of xcall(9), implies that no memory can be allocated in the backend during the calls. Nor should the functions be called from interrupt context.

# CODE REFERENCES

The `cpufreq` interface is implemented within sys/kern/subr_cpufreq.c.

# SEE ALSO

pmf(9), xcall(9)

Venkatesh Pallipadi and Alexey Starikovskiy, The Ondemand Governor. Past, Present, and Future, Intel Open Source Technology Center, http://www.kernel.org/doc/ols/2006/ols2006v2-pages-223-238.pdf, July, 2006, Proceedings of the Linux Symposium.

# HISTORY

The `cpufreq` interface first appeared in NetBSD 6.0.

# AUTHORS

Jukka Ruohonen ⟨jruohonen@iki.fi⟩

# BUGS

The interface does not support different “governors” and policies.

December 1, 2015 | NetBSD 9.2