1===========================================
2ARM topology binding description
3===========================================
4
5===========================================
61 - Introduction
7===========================================
8
9In an ARM system, the hierarchy of CPUs is defined through three entities that
10are used to describe the layout of physical CPUs in the system:
11
12- cluster
13- core
14- thread
15
16The cpu nodes (bindings defined in [1]) represent the devices that
17correspond to physical CPUs and are to be mapped to the hierarchy levels.
18
19The bottom hierarchy level sits at core or thread level depending on whether
20symmetric multi-threading (SMT) is supported or not.
21
22For instance in a system where CPUs support SMT, "cpu" nodes represent all
23threads existing in the system and map to the hierarchy level "thread" above.
24In systems where SMT is not supported "cpu" nodes represent all cores present
25in the system and map to the hierarchy level "core" above.
26
27ARM topology bindings allow one to associate cpu nodes with hierarchical groups
28corresponding to the system hierarchy; syntactically they are defined as device
29tree nodes.
30
31The remainder of this document provides the topology bindings for ARM, based
32on the ePAPR standard, available from:
33
34http://www.power.org/documentation/epapr-version-1-1/
35
36If not stated otherwise, whenever a reference to a cpu node phandle is made its
37value must point to a cpu node compliant with the cpu node bindings as
38documented in [1].
39A topology description containing phandles to cpu nodes that are not compliant
40with bindings standardized in [1] is therefore considered invalid.
41
42===========================================
432 - cpu-map node
44===========================================
45
46The ARM CPU topology is defined within the cpu-map node, which is a direct
47child of the cpus node and provides a container where the actual topology
48nodes are listed.
49
50- cpu-map node
51
52	Usage: Optional - On ARM SMP systems provide CPUs topology to the OS.
53			  ARM uniprocessor systems do not require a topology
54			  description and therefore should not define a
55			  cpu-map node.
56
57	Description: The cpu-map node is just a container node where its
58		     subnodes describe the CPU topology.
59
60	Node name must be "cpu-map".
61
62	The cpu-map node's parent node must be the cpus node.
63
64	The cpu-map node's child nodes can be:
65
66	- one or more cluster nodes
67
68	Any other configuration is considered invalid.
69
70The cpu-map node can only contain three types of child nodes:
71
72- cluster node
73- core node
74- thread node
75
76whose bindings are described in paragraph 3.
77
78The nodes describing the CPU topology (cluster/core/thread) can only
79be defined within the cpu-map node and every core/thread in the system
80must be defined within the topology.  Any other configuration is
81invalid and therefore must be ignored.
82
83===========================================
842.1 - cpu-map child nodes naming convention
85===========================================
86
87cpu-map child nodes must follow a naming convention where the node name
88must be "clusterN", "coreN", "threadN" depending on the node type (ie
89cluster/core/thread) (where N = {0, 1, ...} is the node number; nodes which
90are siblings within a single common parent node must be given a unique and
91sequential N value, starting from 0).
92cpu-map child nodes which do not share a common parent node can have the same
93name (ie same number N as other cpu-map child nodes at different device tree
94levels) since name uniqueness will be guaranteed by the device tree hierarchy.
95
96===========================================
973 - cluster/core/thread node bindings
98===========================================
99
100Bindings for cluster/cpu/thread nodes are defined as follows:
101
102- cluster node
103
104	 Description: must be declared within a cpu-map node, one node
105		      per cluster. A system can contain several layers of
106		      clustering and cluster nodes can be contained in parent
107		      cluster nodes.
108
109	The cluster node name must be "clusterN" as described in 2.1 above.
110	A cluster node can not be a leaf node.
111
112	A cluster node's child nodes must be:
113
114	- one or more cluster nodes; or
115	- one or more core nodes
116
117	Any other configuration is considered invalid.
118
119- core node
120
121	Description: must be declared in a cluster node, one node per core in
122		     the cluster. If the system does not support SMT, core
123		     nodes are leaf nodes, otherwise they become containers of
124		     thread nodes.
125
126	The core node name must be "coreN" as described in 2.1 above.
127
128	A core node must be a leaf node if SMT is not supported.
129
130	Properties for core nodes that are leaf nodes:
131
132	- cpu
133		Usage: required
134		Value type: <phandle>
135		Definition: a phandle to the cpu node that corresponds to the
136			    core node.
137
138	If a core node is not a leaf node (CPUs supporting SMT) a core node's
139	child nodes can be:
140
141	- one or more thread nodes
142
143	Any other configuration is considered invalid.
144
145- thread node
146
147	Description: must be declared in a core node, one node per thread
148		     in the core if the system supports SMT. Thread nodes are
149		     always leaf nodes in the device tree.
150
151	The thread node name must be "threadN" as described in 2.1 above.
152
153	A thread node must be a leaf node.
154
155	A thread node must contain the following property:
156
157	- cpu
158		Usage: required
159		Value type: <phandle>
160		Definition: a phandle to the cpu node that corresponds to
161			    the thread node.
162
163===========================================
1644 - Example dts
165===========================================
166
167Example 1 (ARM 64-bit, 16-cpu system, two clusters of clusters):
168
169cpus {
170	#size-cells = <0>;
171	#address-cells = <2>;
172
173	cpu-map {
174		cluster0 {
175			cluster0 {
176				core0 {
177					thread0 {
178						cpu = <&CPU0>;
179					};
180					thread1 {
181						cpu = <&CPU1>;
182					};
183				};
184
185				core1 {
186					thread0 {
187						cpu = <&CPU2>;
188					};
189					thread1 {
190						cpu = <&CPU3>;
191					};
192				};
193			};
194
195			cluster1 {
196				core0 {
197					thread0 {
198						cpu = <&CPU4>;
199					};
200					thread1 {
201						cpu = <&CPU5>;
202					};
203				};
204
205				core1 {
206					thread0 {
207						cpu = <&CPU6>;
208					};
209					thread1 {
210						cpu = <&CPU7>;
211					};
212				};
213			};
214		};
215
216		cluster1 {
217			cluster0 {
218				core0 {
219					thread0 {
220						cpu = <&CPU8>;
221					};
222					thread1 {
223						cpu = <&CPU9>;
224					};
225				};
226				core1 {
227					thread0 {
228						cpu = <&CPU10>;
229					};
230					thread1 {
231						cpu = <&CPU11>;
232					};
233				};
234			};
235
236			cluster1 {
237				core0 {
238					thread0 {
239						cpu = <&CPU12>;
240					};
241					thread1 {
242						cpu = <&CPU13>;
243					};
244				};
245				core1 {
246					thread0 {
247						cpu = <&CPU14>;
248					};
249					thread1 {
250						cpu = <&CPU15>;
251					};
252				};
253			};
254		};
255	};
256
257	CPU0: cpu@0 {
258		device_type = "cpu";
259		compatible = "arm,cortex-a57";
260		reg = <0x0 0x0>;
261		enable-method = "spin-table";
262		cpu-release-addr = <0 0x20000000>;
263	};
264
265	CPU1: cpu@1 {
266		device_type = "cpu";
267		compatible = "arm,cortex-a57";
268		reg = <0x0 0x1>;
269		enable-method = "spin-table";
270		cpu-release-addr = <0 0x20000000>;
271	};
272
273	CPU2: cpu@100 {
274		device_type = "cpu";
275		compatible = "arm,cortex-a57";
276		reg = <0x0 0x100>;
277		enable-method = "spin-table";
278		cpu-release-addr = <0 0x20000000>;
279	};
280
281	CPU3: cpu@101 {
282		device_type = "cpu";
283		compatible = "arm,cortex-a57";
284		reg = <0x0 0x101>;
285		enable-method = "spin-table";
286		cpu-release-addr = <0 0x20000000>;
287	};
288
289	CPU4: cpu@10000 {
290		device_type = "cpu";
291		compatible = "arm,cortex-a57";
292		reg = <0x0 0x10000>;
293		enable-method = "spin-table";
294		cpu-release-addr = <0 0x20000000>;
295	};
296
297	CPU5: cpu@10001 {
298		device_type = "cpu";
299		compatible = "arm,cortex-a57";
300		reg = <0x0 0x10001>;
301		enable-method = "spin-table";
302		cpu-release-addr = <0 0x20000000>;
303	};
304
305	CPU6: cpu@10100 {
306		device_type = "cpu";
307		compatible = "arm,cortex-a57";
308		reg = <0x0 0x10100>;
309		enable-method = "spin-table";
310		cpu-release-addr = <0 0x20000000>;
311	};
312
313	CPU7: cpu@10101 {
314		device_type = "cpu";
315		compatible = "arm,cortex-a57";
316		reg = <0x0 0x10101>;
317		enable-method = "spin-table";
318		cpu-release-addr = <0 0x20000000>;
319	};
320
321	CPU8: cpu@100000000 {
322		device_type = "cpu";
323		compatible = "arm,cortex-a57";
324		reg = <0x1 0x0>;
325		enable-method = "spin-table";
326		cpu-release-addr = <0 0x20000000>;
327	};
328
329	CPU9: cpu@100000001 {
330		device_type = "cpu";
331		compatible = "arm,cortex-a57";
332		reg = <0x1 0x1>;
333		enable-method = "spin-table";
334		cpu-release-addr = <0 0x20000000>;
335	};
336
337	CPU10: cpu@100000100 {
338		device_type = "cpu";
339		compatible = "arm,cortex-a57";
340		reg = <0x1 0x100>;
341		enable-method = "spin-table";
342		cpu-release-addr = <0 0x20000000>;
343	};
344
345	CPU11: cpu@100000101 {
346		device_type = "cpu";
347		compatible = "arm,cortex-a57";
348		reg = <0x1 0x101>;
349		enable-method = "spin-table";
350		cpu-release-addr = <0 0x20000000>;
351	};
352
353	CPU12: cpu@100010000 {
354		device_type = "cpu";
355		compatible = "arm,cortex-a57";
356		reg = <0x1 0x10000>;
357		enable-method = "spin-table";
358		cpu-release-addr = <0 0x20000000>;
359	};
360
361	CPU13: cpu@100010001 {
362		device_type = "cpu";
363		compatible = "arm,cortex-a57";
364		reg = <0x1 0x10001>;
365		enable-method = "spin-table";
366		cpu-release-addr = <0 0x20000000>;
367	};
368
369	CPU14: cpu@100010100 {
370		device_type = "cpu";
371		compatible = "arm,cortex-a57";
372		reg = <0x1 0x10100>;
373		enable-method = "spin-table";
374		cpu-release-addr = <0 0x20000000>;
375	};
376
377	CPU15: cpu@100010101 {
378		device_type = "cpu";
379		compatible = "arm,cortex-a57";
380		reg = <0x1 0x10101>;
381		enable-method = "spin-table";
382		cpu-release-addr = <0 0x20000000>;
383	};
384};
385
386Example 2 (ARM 32-bit, dual-cluster, 8-cpu system, no SMT):
387
388cpus {
389	#size-cells = <0>;
390	#address-cells = <1>;
391
392	cpu-map {
393		cluster0 {
394			core0 {
395				cpu = <&CPU0>;
396			};
397			core1 {
398				cpu = <&CPU1>;
399			};
400			core2 {
401				cpu = <&CPU2>;
402			};
403			core3 {
404				cpu = <&CPU3>;
405			};
406		};
407
408		cluster1 {
409			core0 {
410				cpu = <&CPU4>;
411			};
412			core1 {
413				cpu = <&CPU5>;
414			};
415			core2 {
416				cpu = <&CPU6>;
417			};
418			core3 {
419				cpu = <&CPU7>;
420			};
421		};
422	};
423
424	CPU0: cpu@0 {
425		device_type = "cpu";
426		compatible = "arm,cortex-a15";
427		reg = <0x0>;
428	};
429
430	CPU1: cpu@1 {
431		device_type = "cpu";
432		compatible = "arm,cortex-a15";
433		reg = <0x1>;
434	};
435
436	CPU2: cpu@2 {
437		device_type = "cpu";
438		compatible = "arm,cortex-a15";
439		reg = <0x2>;
440	};
441
442	CPU3: cpu@3 {
443		device_type = "cpu";
444		compatible = "arm,cortex-a15";
445		reg = <0x3>;
446	};
447
448	CPU4: cpu@100 {
449		device_type = "cpu";
450		compatible = "arm,cortex-a7";
451		reg = <0x100>;
452	};
453
454	CPU5: cpu@101 {
455		device_type = "cpu";
456		compatible = "arm,cortex-a7";
457		reg = <0x101>;
458	};
459
460	CPU6: cpu@102 {
461		device_type = "cpu";
462		compatible = "arm,cortex-a7";
463		reg = <0x102>;
464	};
465
466	CPU7: cpu@103 {
467		device_type = "cpu";
468		compatible = "arm,cortex-a7";
469		reg = <0x103>;
470	};
471};
472
473===============================================================================
474[1] ARM Linux kernel documentation
475    Documentation/devicetree/bindings/arm/cpus.txt
476