blob: 28dcd443a012760dc382074d3f31ad12a2d1b347 [file] [log] [blame]
Vincent Guittotc9018aa2011-08-08 13:21:59 +01001/*
2 * arch/arm/kernel/topology.c
3 *
4 * Copyright (C) 2011 Linaro Limited.
5 * Written by: Vincent Guittot
6 *
7 * based on arch/sh/kernel/topology.c
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13
14#include <linux/cpu.h>
15#include <linux/cpumask.h>
Arnd Bergmann92bdd3f2013-05-31 22:49:22 +010016#include <linux/export.h>
Vincent Guittotc9018aa2011-08-08 13:21:59 +010017#include <linux/init.h>
18#include <linux/percpu.h>
19#include <linux/node.h>
20#include <linux/nodemask.h>
Vincent Guittot339ca092012-07-10 14:13:12 +010021#include <linux/of.h>
Vincent Guittotc9018aa2011-08-08 13:21:59 +010022#include <linux/sched.h>
Vincent Guittot339ca092012-07-10 14:13:12 +010023#include <linux/slab.h>
Vincent Guittotc9018aa2011-08-08 13:21:59 +010024
25#include <asm/cputype.h>
26#include <asm/topology.h>
27
Vincent Guittot130d9aa2012-07-10 14:08:40 +010028/*
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -040029 * cpu capacity scale management
Vincent Guittot130d9aa2012-07-10 14:08:40 +010030 */
31
32/*
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -040033 * cpu capacity table
Vincent Guittot130d9aa2012-07-10 14:08:40 +010034 * This per cpu data structure describes the relative capacity of each core.
35 * On a heteregenous system, cores don't have the same computation capacity
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -040036 * and we reflect that difference in the cpu_capacity field so the scheduler
37 * can take this difference into account during load balance. A per cpu
38 * structure is preferred because each CPU updates its own cpu_capacity field
39 * during the load balance except for idle cores. One idle core is selected
40 * to run the rebalance_domains for all idle cores and the cpu_capacity can be
41 * updated during this sequence.
Vincent Guittot130d9aa2012-07-10 14:08:40 +010042 */
Juri Lellid78e13a2016-01-07 16:27:33 +010043static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE;
Vincent Guittot130d9aa2012-07-10 14:08:40 +010044
Maria Yu1dc40b02017-09-26 16:50:56 +080045unsigned long arch_scale_freq_power(struct sched_domain *sd, int cpu)
46{
47 return per_cpu(cpu_scale, cpu);
48}
49
50static void set_power_scale(unsigned int cpu, unsigned long power)
51{
52 per_cpu(cpu_scale, cpu) = power;
53}
54
Morten Rasmussen25cea242015-04-14 16:25:31 +010055unsigned long scale_cpu_capacity(struct sched_domain *sd, int cpu)
Vincent Guittot130d9aa2012-07-10 14:08:40 +010056{
Jon Medhurstaa9ea842016-06-02 12:18:08 +000057#ifdef CONFIG_CPU_FREQ
Dietmar Eggemann568913e2015-09-23 17:59:55 +010058 unsigned long max_freq_scale = cpufreq_scale_max_freq_capacity(cpu);
59
60 return per_cpu(cpu_scale, cpu) * max_freq_scale >> SCHED_CAPACITY_SHIFT;
61#else
Vincent Guittot130d9aa2012-07-10 14:08:40 +010062 return per_cpu(cpu_scale, cpu);
Dietmar Eggemann568913e2015-09-23 17:59:55 +010063#endif
Vincent Guittot130d9aa2012-07-10 14:08:40 +010064}
65
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -040066static void set_capacity_scale(unsigned int cpu, unsigned long capacity)
Vincent Guittot130d9aa2012-07-10 14:08:40 +010067{
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -040068 per_cpu(cpu_scale, cpu) = capacity;
Vincent Guittot130d9aa2012-07-10 14:08:40 +010069}
70
Jeevan Shriram490837a2017-03-01 17:52:49 -080071static int __init get_cpu_for_node(struct device_node *node)
72{
73 struct device_node *cpu_node;
74 int cpu;
75
76 cpu_node = of_parse_phandle(node, "cpu", 0);
77 if (!cpu_node)
78 return -EINVAL;
79
80 for_each_possible_cpu(cpu) {
81 if (of_get_cpu_node(cpu, NULL) == cpu_node) {
82 of_node_put(cpu_node);
83 return cpu;
84 }
85 }
86
87 pr_crit("Unable to find CPU node for %s\n", cpu_node->full_name);
88
89 of_node_put(cpu_node);
90 return -EINVAL;
91}
92
93static int __init parse_core(struct device_node *core, int cluster_id,
94 int core_id)
95{
96 char name[10];
97 bool leaf = true;
98 int i = 0;
99 int cpu;
100 struct device_node *t;
101
102 do {
103 snprintf(name, sizeof(name), "thread%d", i);
104 t = of_get_child_by_name(core, name);
105 if (t) {
106 leaf = false;
107 cpu = get_cpu_for_node(t);
108 if (cpu >= 0) {
109 cpu_topology[cpu].socket_id = cluster_id;
110 cpu_topology[cpu].core_id = core_id;
111 cpu_topology[cpu].thread_id = i;
112 } else {
113 pr_err("%s: Can't get CPU for thread\n",
114 t->full_name);
115 of_node_put(t);
116 return -EINVAL;
117 }
118 of_node_put(t);
119 }
120 i++;
121 } while (t);
122
123 cpu = get_cpu_for_node(core);
124 if (cpu >= 0) {
125 if (!leaf) {
126 pr_err("%s: Core has both threads and CPU\n",
127 core->full_name);
128 return -EINVAL;
129 }
130
131 cpu_topology[cpu].socket_id = cluster_id;
132 cpu_topology[cpu].core_id = core_id;
133 } else if (leaf) {
134 pr_err("%s: Can't get CPU for leaf core\n", core->full_name);
135 return -EINVAL;
136 }
137
138 return 0;
139}
140
141static int __init parse_cluster(struct device_node *cluster, int depth)
142{
143 static int cluster_id __initdata;
144 char name[10];
145 bool leaf = true;
146 bool has_cores = false;
147 struct device_node *c;
148 int core_id = 0;
149 int i, ret;
150
151 /*
152 * First check for child clusters; we currently ignore any
153 * information about the nesting of clusters and present the
154 * scheduler with a flat list of them.
155 */
156 i = 0;
157 do {
158 snprintf(name, sizeof(name), "cluster%d", i);
159 c = of_get_child_by_name(cluster, name);
160 if (c) {
161 leaf = false;
162 ret = parse_cluster(c, depth + 1);
163 of_node_put(c);
164 if (ret != 0)
165 return ret;
166 }
167 i++;
168 } while (c);
169
170 /* Now check for cores */
171 i = 0;
172 do {
173 snprintf(name, sizeof(name), "core%d", i);
174 c = of_get_child_by_name(cluster, name);
175 if (c) {
176 has_cores = true;
177
178 if (depth == 0) {
179 pr_err("%s: cpu-map children should be clusters\n",
180 c->full_name);
181 of_node_put(c);
182 return -EINVAL;
183 }
184
185 if (leaf) {
186 ret = parse_core(c, cluster_id, core_id++);
187 } else {
188 pr_err("%s: Non-leaf cluster with core %s\n",
189 cluster->full_name, name);
190 ret = -EINVAL;
191 }
192
193 of_node_put(c);
194 if (ret != 0)
195 return ret;
196 }
197 i++;
198 } while (c);
199
200 if (leaf && !has_cores)
201 pr_warn("%s: empty cluster\n", cluster->full_name);
202
203 if (leaf)
204 cluster_id++;
205
206 return 0;
207}
208
Srivatsa Vaddagirifd5704a2014-03-31 19:42:27 -0700209static DEFINE_PER_CPU(unsigned long, cpu_efficiency) = SCHED_CAPACITY_SCALE;
210
211unsigned long arch_get_cpu_efficiency(int cpu)
212{
213 return per_cpu(cpu_efficiency, cpu);
214}
Trilok Sonib10a8a82016-06-10 14:49:06 -0700215EXPORT_SYMBOL(arch_get_cpu_efficiency);
Srivatsa Vaddagirifd5704a2014-03-31 19:42:27 -0700216
Vincent Guittot339ca092012-07-10 14:13:12 +0100217#ifdef CONFIG_OF
218struct cpu_efficiency {
219 const char *compatible;
220 unsigned long efficiency;
221};
222
223/*
224 * Table of relative efficiency of each processors
225 * The efficiency value must fit in 20bit and the final
226 * cpu_scale value must be in the range
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -0400227 * 0 < cpu_scale < 3*SCHED_CAPACITY_SCALE/2
Vincent Guittot339ca092012-07-10 14:13:12 +0100228 * in order to return at most 1 when DIV_ROUND_CLOSEST
229 * is used to compute the capacity of a CPU.
230 * Processors that are not defined in the table,
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -0400231 * use the default SCHED_CAPACITY_SCALE value for cpu_scale.
Vincent Guittot339ca092012-07-10 14:13:12 +0100232 */
Mark Brown145bc292013-12-10 12:10:17 +0100233static const struct cpu_efficiency table_efficiency[] = {
Vincent Guittot339ca092012-07-10 14:13:12 +0100234 {"arm,cortex-a15", 3891},
235 {"arm,cortex-a7", 2048},
236 {NULL, },
237};
238
Mark Brown145bc292013-12-10 12:10:17 +0100239static unsigned long *__cpu_capacity;
Sudeep KarkadaNagesha816a8de2013-06-17 14:20:00 +0100240#define cpu_capacity(cpu) __cpu_capacity[cpu]
Vincent Guittot339ca092012-07-10 14:13:12 +0100241
Mark Brown145bc292013-12-10 12:10:17 +0100242static unsigned long middle_capacity = 1;
Vincent Guittot339ca092012-07-10 14:13:12 +0100243
244/*
245 * Iterate all CPUs' descriptor in DT and compute the efficiency
246 * (as per table_efficiency). Also calculate a middle efficiency
247 * as close as possible to (max{eff_i} - min{eff_i}) / 2
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -0400248 * This is later used to scale the cpu_capacity field such that an
249 * 'average' CPU is of middle capacity. Also see the comments near
250 * table_efficiency[] and update_cpu_capacity().
Vincent Guittot339ca092012-07-10 14:13:12 +0100251 */
Jeevan Shriram490837a2017-03-01 17:52:49 -0800252static int __init parse_dt_topology(void)
Vincent Guittot339ca092012-07-10 14:13:12 +0100253{
Mark Brown145bc292013-12-10 12:10:17 +0100254 const struct cpu_efficiency *cpu_eff;
Jeevan Shriram490837a2017-03-01 17:52:49 -0800255 struct device_node *cn = NULL, *map;
Mark Brown44ae9032014-03-20 15:16:54 +0100256 unsigned long min_capacity = ULONG_MAX;
Vincent Guittot339ca092012-07-10 14:13:12 +0100257 unsigned long max_capacity = 0;
258 unsigned long capacity = 0;
Jeevan Shriram490837a2017-03-01 17:52:49 -0800259 int cpu = 0, ret = 0;
260
Srinivas Ramana3ddfb502016-06-28 12:02:28 +0530261 __cpu_capacity = kcalloc(nr_cpu_ids, sizeof(*__cpu_capacity),
262 GFP_NOWAIT);
263
Jeevan Shriram490837a2017-03-01 17:52:49 -0800264 cn = of_find_node_by_path("/cpus");
265 if (!cn) {
266 pr_err("No CPU information found in DT\n");
267 return 0;
268 }
269
270 /*
271 * When topology is provided cpu-map is essentially a root
272 * cluster with restricted subnodes.
273 */
274 map = of_get_child_by_name(cn, "cpu-map");
275 if (!map)
276 goto out;
277
278 ret = parse_cluster(map, 0);
279 if (ret != 0)
280 goto out_map;
281
282 /*
283 * Check that all cores are in the topology; the SMP code will
284 * only mark cores described in the DT as possible.
285 */
286 for_each_possible_cpu(cpu)
287 if (cpu_topology[cpu].socket_id == -1)
288 ret = -EINVAL;
Vincent Guittot339ca092012-07-10 14:13:12 +0100289
Sudeep KarkadaNagesha816a8de2013-06-17 14:20:00 +0100290 for_each_possible_cpu(cpu) {
291 const u32 *rate;
Vincent Guittot339ca092012-07-10 14:13:12 +0100292 int len;
Pavankumar Kondeti31058f82015-05-07 17:14:48 +0530293 u32 efficiency;
Vincent Guittot339ca092012-07-10 14:13:12 +0100294
Sudeep KarkadaNagesha816a8de2013-06-17 14:20:00 +0100295 /* too early to use cpu->of_node */
296 cn = of_get_cpu_node(cpu, NULL);
297 if (!cn) {
298 pr_err("missing device node for CPU %d\n", cpu);
299 continue;
300 }
Vincent Guittot339ca092012-07-10 14:13:12 +0100301
Pavankumar Kondeti31058f82015-05-07 17:14:48 +0530302 /*
303 * The CPU efficiency value passed from the device tree
304 * overrides the value defined in the table_efficiency[]
305 */
306 if (of_property_read_u32(cn, "efficiency", &efficiency) < 0) {
Vincent Guittot339ca092012-07-10 14:13:12 +0100307
Pavankumar Kondeti31058f82015-05-07 17:14:48 +0530308 for (cpu_eff = table_efficiency;
309 cpu_eff->compatible; cpu_eff++)
Vincent Guittot339ca092012-07-10 14:13:12 +0100310
Pavankumar Kondeti31058f82015-05-07 17:14:48 +0530311 if (of_device_is_compatible(cn,
312 cpu_eff->compatible))
313 break;
314
315 if (cpu_eff->compatible == NULL)
316 continue;
317
318 efficiency = cpu_eff->efficiency;
319 }
320
321 per_cpu(cpu_efficiency, cpu) = efficiency;
Srivatsa Vaddagirifd5704a2014-03-31 19:42:27 -0700322
Vincent Guittot339ca092012-07-10 14:13:12 +0100323 rate = of_get_property(cn, "clock-frequency", &len);
324 if (!rate || len != 4) {
325 pr_err("%s missing clock-frequency property\n",
326 cn->full_name);
327 continue;
328 }
329
Pavankumar Kondeti31058f82015-05-07 17:14:48 +0530330 capacity = ((be32_to_cpup(rate)) >> 20) * efficiency;
Vincent Guittot339ca092012-07-10 14:13:12 +0100331
332 /* Save min capacity of the system */
333 if (capacity < min_capacity)
334 min_capacity = capacity;
335
336 /* Save max capacity of the system */
337 if (capacity > max_capacity)
338 max_capacity = capacity;
339
Sudeep KarkadaNagesha816a8de2013-06-17 14:20:00 +0100340 cpu_capacity(cpu) = capacity;
Vincent Guittot339ca092012-07-10 14:13:12 +0100341 }
342
Vincent Guittot339ca092012-07-10 14:13:12 +0100343 /* If min and max capacities are equals, we bypass the update of the
344 * cpu_scale because all CPUs have the same capacity. Otherwise, we
345 * compute a middle_capacity factor that will ensure that the capacity
346 * of an 'average' CPU of the system will be as close as possible to
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -0400347 * SCHED_CAPACITY_SCALE, which is the default value, but with the
Vincent Guittot339ca092012-07-10 14:13:12 +0100348 * constraint explained near table_efficiency[].
349 */
Sudeep KarkadaNagesha816a8de2013-06-17 14:20:00 +0100350 if (4*max_capacity < (3*(max_capacity + min_capacity)))
Vincent Guittot339ca092012-07-10 14:13:12 +0100351 middle_capacity = (min_capacity + max_capacity)
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -0400352 >> (SCHED_CAPACITY_SHIFT+1);
Vincent Guittot339ca092012-07-10 14:13:12 +0100353 else
354 middle_capacity = ((max_capacity / 3)
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -0400355 >> (SCHED_CAPACITY_SHIFT-1)) + 1;
Jeevan Shriram490837a2017-03-01 17:52:49 -0800356out_map:
357 of_node_put(map);
358out:
359 of_node_put(cn);
360 return ret;
Vincent Guittot339ca092012-07-10 14:13:12 +0100361}
362
Dietmar Eggemannb4ca4bc2015-07-10 13:57:19 +0100363static const struct sched_group_energy * const cpu_core_energy(int cpu);
364
Vincent Guittot339ca092012-07-10 14:13:12 +0100365/*
366 * Look for a customed capacity of a CPU in the cpu_capacity table during the
367 * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the
368 * function returns directly for SMP system.
369 */
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -0400370static void update_cpu_capacity(unsigned int cpu)
Vincent Guittot339ca092012-07-10 14:13:12 +0100371{
Dietmar Eggemannb4ca4bc2015-07-10 13:57:19 +0100372 unsigned long capacity = SCHED_CAPACITY_SCALE;
Vincent Guittot339ca092012-07-10 14:13:12 +0100373
Dietmar Eggemannb4ca4bc2015-07-10 13:57:19 +0100374 if (cpu_core_energy(cpu)) {
375 int max_cap_idx = cpu_core_energy(cpu)->nr_cap_states - 1;
376 capacity = cpu_core_energy(cpu)->cap_states[max_cap_idx].cap;
377 }
378
379 set_capacity_scale(cpu, capacity);
Vincent Guittot339ca092012-07-10 14:13:12 +0100380
Russell King4ed89f22014-10-28 11:26:42 +0000381 pr_info("CPU%u: update cpu_capacity %lu\n",
Vincent Guittotd3bfca12014-08-26 13:06:48 +0200382 cpu, arch_scale_cpu_capacity(NULL, cpu));
Vincent Guittot339ca092012-07-10 14:13:12 +0100383}
384
385#else
Jeevan Shriram490837a2017-03-01 17:52:49 -0800386static inline int parse_dt_topology(void) {}
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -0400387static inline void update_cpu_capacity(unsigned int cpuid) {}
Vincent Guittot339ca092012-07-10 14:13:12 +0100388#endif
389
Lorenzo Pieralisidca463d2012-11-15 17:30:32 +0000390 /*
Vincent Guittot130d9aa2012-07-10 14:08:40 +0100391 * cpu topology table
392 */
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100393struct cputopo_arm cpu_topology[NR_CPUS];
Arnd Bergmann92bdd3f2013-05-31 22:49:22 +0100394EXPORT_SYMBOL_GPL(cpu_topology);
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100395
Vincent Guittot4cbd6b12011-11-29 15:50:20 +0100396const struct cpumask *cpu_coregroup_mask(int cpu)
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100397{
398 return &cpu_topology[cpu].core_sibling;
399}
400
Vincent Guittotfb2aa852014-04-11 11:44:41 +0200401/*
402 * The current assumption is that we can power gate each core independently.
403 * This will be superseded by DT binding once available.
404 */
405const struct cpumask *cpu_corepower_mask(int cpu)
406{
407 return &cpu_topology[cpu].thread_sibling;
408}
409
Maria Yu1dc40b02017-09-26 16:50:56 +0800410static void update_cpu_power(unsigned int cpu)
411{
412 if (!cpu_capacity(cpu))
413 return;
414
415 set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity);
416
417 pr_info("CPU%u: update cpu_power %lu\n",
418 cpu, arch_scale_freq_power(NULL, cpu));
419}
420
421void update_cpu_power_capacity(int cpu)
422{
423 update_cpu_power(cpu);
424 update_cpu_capacity(cpu);
425}
426
Mark Brown145bc292013-12-10 12:10:17 +0100427static void update_siblings_masks(unsigned int cpuid)
Vincent Guittotcb75dac2012-07-10 14:11:11 +0100428{
429 struct cputopo_arm *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
430 int cpu;
431
432 /* update core and thread sibling masks */
433 for_each_possible_cpu(cpu) {
434 cpu_topo = &cpu_topology[cpu];
435
436 if (cpuid_topo->socket_id != cpu_topo->socket_id)
437 continue;
438
439 cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
440 if (cpu != cpuid)
441 cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
442
443 if (cpuid_topo->core_id != cpu_topo->core_id)
444 continue;
445
446 cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
447 if (cpu != cpuid)
448 cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
449 }
Srinivas Ramana3ddfb502016-06-28 12:02:28 +0530450
451 smp_wmb(); /* Ensure mask is updated*/
Vincent Guittotcb75dac2012-07-10 14:11:11 +0100452}
453
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100454/*
455 * store_cpu_topology is called at boot when only one cpu is running
456 * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
457 * which prevents simultaneous write access to cpu_topology array
458 */
459void store_cpu_topology(unsigned int cpuid)
460{
461 struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid];
462 unsigned int mpidr;
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100463
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100464 if (cpuid_topo->core_id != -1)
Jeevan Shriram490837a2017-03-01 17:52:49 -0800465 goto topology_populated;
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100466
467 mpidr = read_cpuid_mpidr();
468
469 /* create cpu topology mapping */
470 if ((mpidr & MPIDR_SMP_BITMASK) == MPIDR_SMP_VALUE) {
471 /*
472 * This is a multiprocessor system
473 * multiprocessor format & multiprocessor mode field are set
474 */
475
476 if (mpidr & MPIDR_MT_BITMASK) {
477 /* core performance interdependency */
Lorenzo Pieralisi71db5bf2012-11-16 15:24:06 +0000478 cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
479 cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
480 cpuid_topo->socket_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100481 } else {
482 /* largely independent cores */
483 cpuid_topo->thread_id = -1;
Lorenzo Pieralisi71db5bf2012-11-16 15:24:06 +0000484 cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
485 cpuid_topo->socket_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100486 }
487 } else {
488 /*
489 * This is an uniprocessor system
490 * we are in multiprocessor format but uniprocessor system
491 * or in the old uniprocessor format
492 */
493 cpuid_topo->thread_id = -1;
494 cpuid_topo->core_id = 0;
495 cpuid_topo->socket_id = -1;
496 }
497
Jeevan Shriram490837a2017-03-01 17:52:49 -0800498 pr_info("CPU%u: thread %d, cpu %d, cluster %d, mpidr %x\n",
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100499 cpuid, cpu_topology[cpuid].thread_id,
500 cpu_topology[cpuid].core_id,
501 cpu_topology[cpuid].socket_id, mpidr);
Jeevan Shriram490837a2017-03-01 17:52:49 -0800502
503topology_populated:
504 update_siblings_masks(cpuid);
505 update_cpu_capacity(cpuid);
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100506}
507
Dietmar Eggemann61100bd2014-11-14 17:16:41 +0000508/*
509 * ARM TC2 specific energy cost model data. There are no unit requirements for
510 * the data. Data can be normalized to any reference point, but the
511 * normalization must be consistent. That is, one bogo-joule/watt must be the
512 * same quantity for all data, but we don't care what it is.
513 */
514static struct idle_state idle_states_cluster_a7[] = {
515 { .power = 25 }, /* arch_cpu_idle() (active idle) = WFI */
516 { .power = 25 }, /* WFI */
517 { .power = 10 }, /* cluster-sleep-l */
518 };
519
520static struct idle_state idle_states_cluster_a15[] = {
521 { .power = 70 }, /* arch_cpu_idle() (active idle) = WFI */
522 { .power = 70 }, /* WFI */
523 { .power = 25 }, /* cluster-sleep-b */
524 };
525
526static struct capacity_state cap_states_cluster_a7[] = {
527 /* Cluster only power */
528 { .cap = 150, .power = 2967, }, /* 350 MHz */
529 { .cap = 172, .power = 2792, }, /* 400 MHz */
530 { .cap = 215, .power = 2810, }, /* 500 MHz */
531 { .cap = 258, .power = 2815, }, /* 600 MHz */
532 { .cap = 301, .power = 2919, }, /* 700 MHz */
533 { .cap = 344, .power = 2847, }, /* 800 MHz */
534 { .cap = 387, .power = 3917, }, /* 900 MHz */
535 { .cap = 430, .power = 4905, }, /* 1000 MHz */
536 };
537
538static struct capacity_state cap_states_cluster_a15[] = {
539 /* Cluster only power */
540 { .cap = 426, .power = 7920, }, /* 500 MHz */
541 { .cap = 512, .power = 8165, }, /* 600 MHz */
542 { .cap = 597, .power = 8172, }, /* 700 MHz */
543 { .cap = 682, .power = 8195, }, /* 800 MHz */
544 { .cap = 768, .power = 8265, }, /* 900 MHz */
545 { .cap = 853, .power = 8446, }, /* 1000 MHz */
546 { .cap = 938, .power = 11426, }, /* 1100 MHz */
547 { .cap = 1024, .power = 15200, }, /* 1200 MHz */
548 };
549
550static struct sched_group_energy energy_cluster_a7 = {
551 .nr_idle_states = ARRAY_SIZE(idle_states_cluster_a7),
552 .idle_states = idle_states_cluster_a7,
553 .nr_cap_states = ARRAY_SIZE(cap_states_cluster_a7),
554 .cap_states = cap_states_cluster_a7,
555};
556
557static struct sched_group_energy energy_cluster_a15 = {
558 .nr_idle_states = ARRAY_SIZE(idle_states_cluster_a15),
559 .idle_states = idle_states_cluster_a15,
560 .nr_cap_states = ARRAY_SIZE(cap_states_cluster_a15),
561 .cap_states = cap_states_cluster_a15,
562};
563
564static struct idle_state idle_states_core_a7[] = {
565 { .power = 0 }, /* arch_cpu_idle (active idle) = WFI */
566 { .power = 0 }, /* WFI */
567 { .power = 0 }, /* cluster-sleep-l */
568 };
569
570static struct idle_state idle_states_core_a15[] = {
571 { .power = 0 }, /* arch_cpu_idle (active idle) = WFI */
572 { .power = 0 }, /* WFI */
573 { .power = 0 }, /* cluster-sleep-b */
574 };
575
576static struct capacity_state cap_states_core_a7[] = {
577 /* Power per cpu */
578 { .cap = 150, .power = 187, }, /* 350 MHz */
579 { .cap = 172, .power = 275, }, /* 400 MHz */
580 { .cap = 215, .power = 334, }, /* 500 MHz */
581 { .cap = 258, .power = 407, }, /* 600 MHz */
582 { .cap = 301, .power = 447, }, /* 700 MHz */
583 { .cap = 344, .power = 549, }, /* 800 MHz */
584 { .cap = 387, .power = 761, }, /* 900 MHz */
585 { .cap = 430, .power = 1024, }, /* 1000 MHz */
586 };
587
588static struct capacity_state cap_states_core_a15[] = {
589 /* Power per cpu */
590 { .cap = 426, .power = 2021, }, /* 500 MHz */
591 { .cap = 512, .power = 2312, }, /* 600 MHz */
592 { .cap = 597, .power = 2756, }, /* 700 MHz */
593 { .cap = 682, .power = 3125, }, /* 800 MHz */
594 { .cap = 768, .power = 3524, }, /* 900 MHz */
595 { .cap = 853, .power = 3846, }, /* 1000 MHz */
596 { .cap = 938, .power = 5177, }, /* 1100 MHz */
597 { .cap = 1024, .power = 6997, }, /* 1200 MHz */
598 };
599
600static struct sched_group_energy energy_core_a7 = {
601 .nr_idle_states = ARRAY_SIZE(idle_states_core_a7),
602 .idle_states = idle_states_core_a7,
603 .nr_cap_states = ARRAY_SIZE(cap_states_core_a7),
604 .cap_states = cap_states_core_a7,
605};
606
607static struct sched_group_energy energy_core_a15 = {
608 .nr_idle_states = ARRAY_SIZE(idle_states_core_a15),
609 .idle_states = idle_states_core_a15,
610 .nr_cap_states = ARRAY_SIZE(cap_states_core_a15),
611 .cap_states = cap_states_core_a15,
612};
613
614/* sd energy functions */
615static inline
616const struct sched_group_energy * const cpu_cluster_energy(int cpu)
617{
618 return cpu_topology[cpu].socket_id ? &energy_cluster_a7 :
619 &energy_cluster_a15;
620}
621
622static inline
623const struct sched_group_energy * const cpu_core_energy(int cpu)
624{
625 return cpu_topology[cpu].socket_id ? &energy_core_a7 :
626 &energy_core_a15;
627}
628
Guenter Roeckb6220ad2014-06-24 18:05:29 -0700629static inline int cpu_corepower_flags(void)
Vincent Guittotfb2aa852014-04-11 11:44:41 +0200630{
Morten Rasmussen858d7182015-01-13 13:50:46 +0000631 return SD_SHARE_PKG_RESOURCES | SD_SHARE_POWERDOMAIN | \
632 SD_SHARE_CAP_STATES;
Vincent Guittotfb2aa852014-04-11 11:44:41 +0200633}
634
635static struct sched_domain_topology_level arm_topology[] = {
636#ifdef CONFIG_SCHED_MC
Dietmar Eggemann61100bd2014-11-14 17:16:41 +0000637 { cpu_coregroup_mask, cpu_corepower_flags, cpu_core_energy, SD_INIT_NAME(MC) },
Vincent Guittotfb2aa852014-04-11 11:44:41 +0200638#endif
Dietmar Eggemann61100bd2014-11-14 17:16:41 +0000639 { cpu_cpu_mask, NULL, cpu_cluster_energy, SD_INIT_NAME(DIE) },
Vincent Guittotfb2aa852014-04-11 11:44:41 +0200640 { NULL, },
641};
642
Srinivas Ramana3ddfb502016-06-28 12:02:28 +0530643static void __init reset_cpu_topology(void)
644{
645 unsigned int cpu;
646
647 for_each_possible_cpu(cpu) {
648 struct cputopo_arm *cpu_topo = &cpu_topology[cpu];
649
650 cpu_topo->thread_id = -1;
651 cpu_topo->core_id = -1;
652 cpu_topo->socket_id = -1;
653
654 cpumask_clear(&cpu_topo->core_sibling);
655 cpumask_clear(&cpu_topo->thread_sibling);
656 }
657 smp_wmb();
658}
659
660static void __init reset_cpu_capacity(void)
661{
662 unsigned int cpu;
663
664 for_each_possible_cpu(cpu)
665 set_capacity_scale(cpu, SCHED_CAPACITY_SCALE);
666}
667
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100668/*
669 * init_cpu_topology is called at boot when only one cpu is running
670 * which prevent simultaneous write access to cpu_topology array
671 */
Venkatraman Sathiyamoorthyf7e416e2012-08-03 07:58:33 +0100672void __init init_cpu_topology(void)
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100673{
674 unsigned int cpu;
675
Nicolas Pitreca8ce3d2014-05-26 18:19:39 -0400676 /* init core mask and capacity */
Srinivas Ramana3ddfb502016-06-28 12:02:28 +0530677 reset_cpu_topology();
678 reset_cpu_capacity();
679 smp_wmb(); /* Ensure CPU topology and capacity are up to date */
Vincent Guittot339ca092012-07-10 14:13:12 +0100680
Jeevan Shriram490837a2017-03-01 17:52:49 -0800681 if (parse_dt_topology()) {
Srinivas Ramana3ddfb502016-06-28 12:02:28 +0530682 reset_cpu_topology();
683 reset_cpu_capacity();
Jeevan Shriram490837a2017-03-01 17:52:49 -0800684 }
Vincent Guittotfb2aa852014-04-11 11:44:41 +0200685
Srivatsa Vaddagiri7cb075f2015-04-20 12:35:48 +0530686 for_each_possible_cpu(cpu)
687 update_siblings_masks(cpu);
688
Vincent Guittotfb2aa852014-04-11 11:44:41 +0200689 /* Set scheduler topology descriptor */
690 set_sched_topology(arm_topology);
Vincent Guittotc9018aa2011-08-08 13:21:59 +0100691}