Documentation: power: update Energy Model description
The Energy Model framework supports also other devices than CPUs. Update related information and add description for the new usage. Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org> Acked-by: Quentin Perret <qperret@google.com> Signed-off-by: Lukasz Luba <lukasz.luba@arm.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
f0b5694791
commit
7b7570ad0d
|
@ -1,15 +1,17 @@
|
||||||
====================
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
Energy Model of CPUs
|
|
||||||
====================
|
=======================
|
||||||
|
Energy Model of devices
|
||||||
|
=======================
|
||||||
|
|
||||||
1. Overview
|
1. Overview
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
The Energy Model (EM) framework serves as an interface between drivers knowing
|
The Energy Model (EM) framework serves as an interface between drivers knowing
|
||||||
the power consumed by CPUs at various performance levels, and the kernel
|
the power consumed by devices at various performance levels, and the kernel
|
||||||
subsystems willing to use that information to make energy-aware decisions.
|
subsystems willing to use that information to make energy-aware decisions.
|
||||||
|
|
||||||
The source of the information about the power consumed by CPUs can vary greatly
|
The source of the information about the power consumed by devices can vary greatly
|
||||||
from one platform to another. These power costs can be estimated using
|
from one platform to another. These power costs can be estimated using
|
||||||
devicetree data in some cases. In others, the firmware will know better.
|
devicetree data in some cases. In others, the firmware will know better.
|
||||||
Alternatively, userspace might be best positioned. And so on. In order to avoid
|
Alternatively, userspace might be best positioned. And so on. In order to avoid
|
||||||
|
@ -25,7 +27,7 @@ framework, and interested clients reading the data from it::
|
||||||
+---------------+ +-----------------+ +---------------+
|
+---------------+ +-----------------+ +---------------+
|
||||||
| Thermal (IPA) | | Scheduler (EAS) | | Other |
|
| Thermal (IPA) | | Scheduler (EAS) | | Other |
|
||||||
+---------------+ +-----------------+ +---------------+
|
+---------------+ +-----------------+ +---------------+
|
||||||
| | em_pd_energy() |
|
| | em_cpu_energy() |
|
||||||
| | em_cpu_get() |
|
| | em_cpu_get() |
|
||||||
+---------+ | +---------+
|
+---------+ | +---------+
|
||||||
| | |
|
| | |
|
||||||
|
@ -35,7 +37,7 @@ framework, and interested clients reading the data from it::
|
||||||
| Framework |
|
| Framework |
|
||||||
+---------------------+
|
+---------------------+
|
||||||
^ ^ ^
|
^ ^ ^
|
||||||
| | | em_register_perf_domain()
|
| | | em_dev_register_perf_domain()
|
||||||
+----------+ | +---------+
|
+----------+ | +---------+
|
||||||
| | |
|
| | |
|
||||||
+---------------+ +---------------+ +--------------+
|
+---------------+ +---------------+ +--------------+
|
||||||
|
@ -47,12 +49,12 @@ framework, and interested clients reading the data from it::
|
||||||
| Device Tree | | Firmware | | ? |
|
| Device Tree | | Firmware | | ? |
|
||||||
+--------------+ +---------------+ +--------------+
|
+--------------+ +---------------+ +--------------+
|
||||||
|
|
||||||
The EM framework manages power cost tables per 'performance domain' in the
|
In case of CPU devices the EM framework manages power cost tables per
|
||||||
system. A performance domain is a group of CPUs whose performance is scaled
|
'performance domain' in the system. A performance domain is a group of CPUs
|
||||||
together. Performance domains generally have a 1-to-1 mapping with CPUFreq
|
whose performance is scaled together. Performance domains generally have a
|
||||||
policies. All CPUs in a performance domain are required to have the same
|
1-to-1 mapping with CPUFreq policies. All CPUs in a performance domain are
|
||||||
micro-architecture. CPUs in different performance domains can have different
|
required to have the same micro-architecture. CPUs in different performance
|
||||||
micro-architectures.
|
domains can have different micro-architectures.
|
||||||
|
|
||||||
|
|
||||||
2. Core APIs
|
2. Core APIs
|
||||||
|
@ -70,14 +72,16 @@ CONFIG_ENERGY_MODEL must be enabled to use the EM framework.
|
||||||
Drivers are expected to register performance domains into the EM framework by
|
Drivers are expected to register performance domains into the EM framework by
|
||||||
calling the following API::
|
calling the following API::
|
||||||
|
|
||||||
int em_register_perf_domain(cpumask_t *span, unsigned int nr_states,
|
int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
|
||||||
struct em_data_callback *cb);
|
struct em_data_callback *cb, cpumask_t *cpus);
|
||||||
|
|
||||||
Drivers must specify the CPUs of the performance domains using the cpumask
|
Drivers must provide a callback function returning <frequency, power> tuples
|
||||||
argument, and provide a callback function returning <frequency, power> tuples
|
for each performance state. The callback function provided by the driver is free
|
||||||
for each capacity state. The callback function provided by the driver is free
|
|
||||||
to fetch data from any relevant location (DT, firmware, ...), and by any mean
|
to fetch data from any relevant location (DT, firmware, ...), and by any mean
|
||||||
deemed necessary. See Section 3. for an example of driver implementing this
|
deemed necessary. Only for CPU devices, drivers must specify the CPUs of the
|
||||||
|
performance domains using cpumask. For other devices than CPUs the last
|
||||||
|
argument must be set to NULL.
|
||||||
|
See Section 3. for an example of driver implementing this
|
||||||
callback, and kernel/power/energy_model.c for further documentation on this
|
callback, and kernel/power/energy_model.c for further documentation on this
|
||||||
API.
|
API.
|
||||||
|
|
||||||
|
@ -85,13 +89,20 @@ API.
|
||||||
2.3 Accessing performance domains
|
2.3 Accessing performance domains
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
There are two API functions which provide the access to the energy model:
|
||||||
|
em_cpu_get() which takes CPU id as an argument and em_pd_get() with device
|
||||||
|
pointer as an argument. It depends on the subsystem which interface it is
|
||||||
|
going to use, but in case of CPU devices both functions return the same
|
||||||
|
performance domain.
|
||||||
|
|
||||||
Subsystems interested in the energy model of a CPU can retrieve it using the
|
Subsystems interested in the energy model of a CPU can retrieve it using the
|
||||||
em_cpu_get() API. The energy model tables are allocated once upon creation of
|
em_cpu_get() API. The energy model tables are allocated once upon creation of
|
||||||
the performance domains, and kept in memory untouched.
|
the performance domains, and kept in memory untouched.
|
||||||
|
|
||||||
The energy consumed by a performance domain can be estimated using the
|
The energy consumed by a performance domain can be estimated using the
|
||||||
em_pd_energy() API. The estimation is performed assuming that the schedutil
|
em_cpu_energy() API. The estimation is performed assuming that the schedutil
|
||||||
CPUfreq governor is in use.
|
CPUfreq governor is in use in case of CPU device. Currently this calculation is
|
||||||
|
not provided for other type of devices.
|
||||||
|
|
||||||
More details about the above APIs can be found in include/linux/energy_model.h.
|
More details about the above APIs can be found in include/linux/energy_model.h.
|
||||||
|
|
||||||
|
@ -106,42 +117,46 @@ EM framework::
|
||||||
|
|
||||||
-> drivers/cpufreq/foo_cpufreq.c
|
-> drivers/cpufreq/foo_cpufreq.c
|
||||||
|
|
||||||
01 static int est_power(unsigned long *mW, unsigned long *KHz, int cpu)
|
01 static int est_power(unsigned long *mW, unsigned long *KHz,
|
||||||
02 {
|
02 struct device *dev)
|
||||||
03 long freq, power;
|
03 {
|
||||||
04
|
04 long freq, power;
|
||||||
05 /* Use the 'foo' protocol to ceil the frequency */
|
05
|
||||||
06 freq = foo_get_freq_ceil(cpu, *KHz);
|
06 /* Use the 'foo' protocol to ceil the frequency */
|
||||||
07 if (freq < 0);
|
07 freq = foo_get_freq_ceil(dev, *KHz);
|
||||||
08 return freq;
|
08 if (freq < 0);
|
||||||
09
|
09 return freq;
|
||||||
10 /* Estimate the power cost for the CPU at the relevant freq. */
|
10
|
||||||
11 power = foo_estimate_power(cpu, freq);
|
11 /* Estimate the power cost for the dev at the relevant freq. */
|
||||||
12 if (power < 0);
|
12 power = foo_estimate_power(dev, freq);
|
||||||
13 return power;
|
13 if (power < 0);
|
||||||
14
|
14 return power;
|
||||||
15 /* Return the values to the EM framework */
|
15
|
||||||
16 *mW = power;
|
16 /* Return the values to the EM framework */
|
||||||
17 *KHz = freq;
|
17 *mW = power;
|
||||||
18
|
18 *KHz = freq;
|
||||||
19 return 0;
|
19
|
||||||
20 }
|
20 return 0;
|
||||||
21
|
21 }
|
||||||
22 static int foo_cpufreq_init(struct cpufreq_policy *policy)
|
22
|
||||||
23 {
|
23 static int foo_cpufreq_init(struct cpufreq_policy *policy)
|
||||||
24 struct em_data_callback em_cb = EM_DATA_CB(est_power);
|
24 {
|
||||||
25 int nr_opp, ret;
|
25 struct em_data_callback em_cb = EM_DATA_CB(est_power);
|
||||||
26
|
26 struct device *cpu_dev;
|
||||||
27 /* Do the actual CPUFreq init work ... */
|
27 int nr_opp, ret;
|
||||||
28 ret = do_foo_cpufreq_init(policy);
|
28
|
||||||
29 if (ret)
|
29 cpu_dev = get_cpu_device(cpumask_first(policy->cpus));
|
||||||
30 return ret;
|
30
|
||||||
31
|
31 /* Do the actual CPUFreq init work ... */
|
||||||
32 /* Find the number of OPPs for this policy */
|
32 ret = do_foo_cpufreq_init(policy);
|
||||||
33 nr_opp = foo_get_nr_opp(policy);
|
33 if (ret)
|
||||||
34
|
34 return ret;
|
||||||
35 /* And register the new performance domain */
|
35
|
||||||
36 em_register_perf_domain(policy->cpus, nr_opp, &em_cb);
|
36 /* Find the number of OPPs for this policy */
|
||||||
37
|
37 nr_opp = foo_get_nr_opp(policy);
|
||||||
38 return 0;
|
38
|
||||||
39 }
|
39 /* And register the new performance domain */
|
||||||
|
40 em_dev_register_perf_domain(cpu_dev, nr_opp, &em_cb, policy->cpus);
|
||||||
|
41
|
||||||
|
42 return 0;
|
||||||
|
43 }
|
||||||
|
|
Loading…
Reference in New Issue