PM / EM: remove em_register_perf_domain
[linux-2.6-block.git] / include / linux / energy_model.h
CommitLineData
27871f7a
QP
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _LINUX_ENERGY_MODEL_H
3#define _LINUX_ENERGY_MODEL_H
4#include <linux/cpumask.h>
7d9895c7 5#include <linux/device.h>
27871f7a
QP
6#include <linux/jump_label.h>
7#include <linux/kobject.h>
8#include <linux/rcupdate.h>
9#include <linux/sched/cpufreq.h>
10#include <linux/sched/topology.h>
11#include <linux/types.h>
12
27871f7a 13/**
521b512b 14 * em_perf_state - Performance state of a performance domain
1bc138c6
LL
15 * @frequency: The frequency in KHz, for consistency with CPUFreq
16 * @power: The power consumed at this level, in milli-watts (by 1 CPU or
17 by a registered device). It can be a total power: static and
18 dynamic.
27871f7a
QP
19 * @cost: The cost coefficient associated with this level, used during
20 * energy calculation. Equal to: power * max_frequency / frequency
21 */
521b512b 22struct em_perf_state {
27871f7a
QP
23 unsigned long frequency;
24 unsigned long power;
25 unsigned long cost;
26};
27
28/**
29 * em_perf_domain - Performance domain
521b512b
LL
30 * @table: List of performance states, in ascending order
31 * @nr_perf_states: Number of performance states
1bc138c6
LL
32 * @cpus: Cpumask covering the CPUs of the domain. It's here
33 * for performance reasons to avoid potential cache
34 * misses during energy calculations in the scheduler
35 * and simplifies allocating/freeing that memory region.
27871f7a 36 *
1bc138c6
LL
37 * In case of CPU device, a "performance domain" represents a group of CPUs
38 * whose performance is scaled together. All CPUs of a performance domain
39 * must have the same micro-architecture. Performance domains often have
40 * a 1-to-1 mapping with CPUFreq policies. In case of other devices the @cpus
41 * field is unused.
27871f7a
QP
42 */
43struct em_perf_domain {
521b512b
LL
44 struct em_perf_state *table;
45 int nr_perf_states;
beb69f15 46 unsigned long cpus[];
27871f7a
QP
47};
48
521b512b
LL
49#define em_span_cpus(em) (to_cpumask((em)->cpus))
50
27a47e42 51#ifdef CONFIG_ENERGY_MODEL
7d9895c7 52#define EM_MAX_POWER 0xFFFF
27871f7a
QP
53
54struct em_data_callback {
55 /**
521b512b 56 * active_power() - Provide power at the next performance state of
d0351cc3 57 * a device
521b512b
LL
58 * @power : Active power at the performance state in mW
59 * (modified)
60 * @freq : Frequency at the performance state in kHz
61 * (modified)
d0351cc3 62 * @dev : Device for which we do this operation (can be a CPU)
27871f7a 63 *
d0351cc3 64 * active_power() must find the lowest performance state of 'dev' above
27871f7a
QP
65 * 'freq' and update 'power' and 'freq' to the matching active power
66 * and frequency.
67 *
d0351cc3
LL
68 * In case of CPUs, the power is the one of a single CPU in the domain,
69 * expressed in milli-watts. It is expected to fit in the
70 * [0, EM_MAX_POWER] range.
27871f7a
QP
71 *
72 * Return 0 on success.
73 */
d0351cc3
LL
74 int (*active_power)(unsigned long *power, unsigned long *freq,
75 struct device *dev);
27871f7a
QP
76};
77#define EM_DATA_CB(_active_power_cb) { .active_power = &_active_power_cb }
78
79struct em_perf_domain *em_cpu_get(int cpu);
1bc138c6 80struct em_perf_domain *em_pd_get(struct device *dev);
7d9895c7
LL
81int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
82 struct em_data_callback *cb, cpumask_t *span);
1bc138c6 83void em_dev_unregister_perf_domain(struct device *dev);
27871f7a
QP
84
85/**
86 * em_pd_energy() - Estimates the energy consumed by the CPUs of a perf. domain
87 * @pd : performance domain for which energy has to be estimated
88 * @max_util : highest utilization among CPUs of the domain
89 * @sum_util : sum of the utilization of all CPUs in the domain
90 *
91 * Return: the sum of the energy consumed by the CPUs of the domain assuming
92 * a capacity state satisfying the max utilization of the domain.
93 */
94static inline unsigned long em_pd_energy(struct em_perf_domain *pd,
95 unsigned long max_util, unsigned long sum_util)
96{
97 unsigned long freq, scale_cpu;
521b512b 98 struct em_perf_state *ps;
27871f7a
QP
99 int i, cpu;
100
101 /*
521b512b
LL
102 * In order to predict the performance state, map the utilization of
103 * the most utilized CPU of the performance domain to a requested
104 * frequency, like schedutil.
27871f7a
QP
105 */
106 cpu = cpumask_first(to_cpumask(pd->cpus));
8ec59c0f 107 scale_cpu = arch_scale_cpu_capacity(cpu);
521b512b
LL
108 ps = &pd->table[pd->nr_perf_states - 1];
109 freq = map_util_freq(max_util, ps->frequency, scale_cpu);
27871f7a
QP
110
111 /*
521b512b 112 * Find the lowest performance state of the Energy Model above the
27871f7a
QP
113 * requested frequency.
114 */
521b512b
LL
115 for (i = 0; i < pd->nr_perf_states; i++) {
116 ps = &pd->table[i];
117 if (ps->frequency >= freq)
27871f7a
QP
118 break;
119 }
120
121 /*
521b512b 122 * The capacity of a CPU in the domain at the performance state (ps)
27871f7a
QP
123 * can be computed as:
124 *
521b512b
LL
125 * ps->freq * scale_cpu
126 * ps->cap = -------------------- (1)
27871f7a
QP
127 * cpu_max_freq
128 *
129 * So, ignoring the costs of idle states (which are not available in
521b512b
LL
130 * the EM), the energy consumed by this CPU at that performance state
131 * is estimated as:
27871f7a 132 *
521b512b 133 * ps->power * cpu_util
27871f7a 134 * cpu_nrg = -------------------- (2)
521b512b 135 * ps->cap
27871f7a 136 *
521b512b 137 * since 'cpu_util / ps->cap' represents its percentage of busy time.
27871f7a
QP
138 *
139 * NOTE: Although the result of this computation actually is in
140 * units of power, it can be manipulated as an energy value
141 * over a scheduling period, since it is assumed to be
142 * constant during that interval.
143 *
144 * By injecting (1) in (2), 'cpu_nrg' can be re-expressed as a product
145 * of two terms:
146 *
521b512b 147 * ps->power * cpu_max_freq cpu_util
27871f7a 148 * cpu_nrg = ------------------------ * --------- (3)
521b512b 149 * ps->freq scale_cpu
27871f7a 150 *
521b512b
LL
151 * The first term is static, and is stored in the em_perf_state struct
152 * as 'ps->cost'.
27871f7a
QP
153 *
154 * Since all CPUs of the domain have the same micro-architecture, they
521b512b 155 * share the same 'ps->cost', and the same CPU capacity. Hence, the
27871f7a
QP
156 * total energy of the domain (which is the simple sum of the energy of
157 * all of its CPUs) can be factorized as:
158 *
521b512b 159 * ps->cost * \Sum cpu_util
27871f7a
QP
160 * pd_nrg = ------------------------ (4)
161 * scale_cpu
162 */
521b512b 163 return ps->cost * sum_util / scale_cpu;
27871f7a
QP
164}
165
166/**
521b512b
LL
167 * em_pd_nr_perf_states() - Get the number of performance states of a perf.
168 * domain
27871f7a
QP
169 * @pd : performance domain for which this must be done
170 *
521b512b 171 * Return: the number of performance states in the performance domain table
27871f7a 172 */
521b512b 173static inline int em_pd_nr_perf_states(struct em_perf_domain *pd)
27871f7a 174{
521b512b 175 return pd->nr_perf_states;
27871f7a
QP
176}
177
178#else
27871f7a
QP
179struct em_data_callback {};
180#define EM_DATA_CB(_active_power_cb) { }
181
7d9895c7
LL
182static inline
183int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
184 struct em_data_callback *cb, cpumask_t *span)
185{
186 return -EINVAL;
187}
1bc138c6
LL
188static inline void em_dev_unregister_perf_domain(struct device *dev)
189{
190}
27871f7a
QP
191static inline struct em_perf_domain *em_cpu_get(int cpu)
192{
193 return NULL;
194}
1bc138c6
LL
195static inline struct em_perf_domain *em_pd_get(struct device *dev)
196{
197 return NULL;
198}
27871f7a
QP
199static inline unsigned long em_pd_energy(struct em_perf_domain *pd,
200 unsigned long max_util, unsigned long sum_util)
201{
202 return 0;
203}
521b512b 204static inline int em_pd_nr_perf_states(struct em_perf_domain *pd)
27871f7a
QP
205{
206 return 0;
207}
208#endif
209
210#endif