=================
ARM CPUs bindings
=================

The device tree allows to describe the layout of CPUs in a system through
the "cpus" node, which in turn contains a number of subnodes (ie "cpu")
defining properties for every cpu.

Bindings for CPU nodes follow the ePAPR v1.1 standard, available from:

https://www.power.org/documentation/epapr-version-1-1/

with updates for 32-bit and 64-bit ARM systems provided in this document.

================================
Convention used in this document
================================

This document follows the conventions described in the ePAPR v1.1, with
the addition:

- square brackets define bitfields, eg reg[7:0] value of the bitfield in
  the reg property contained in bits 7 down to 0

=====================================
cpus and cpu node bindings definition
=====================================

The ARM architecture, in accordance with the ePAPR, requires the cpus and cpu
nodes to be present and contain the properties described below.

- cpus node

	Description: Container of cpu nodes

	The node name must be "cpus".

	A cpus node must define the following properties:

	- #address-cells
		Usage: required
		Value type: <u32>

		Definition depends on ARM architecture version and
		configuration:

			# On uniprocessor ARM architectures previous to v7
			  value must be 1, to enable a simple enumeration
			  scheme for processors that do not have a HW CPU
			  identification register.
			# On 32-bit ARM 11 MPcore, ARM v7 or later systems
			  value must be 1, that corresponds to CPUID/MPIDR
			  registers sizes.
			# On ARM v8 64-bit systems value should be set to 2,
			  that corresponds to the MPIDR_EL1 register size.
			  If MPIDR_EL1[63:32] value is equal to 0 on all CPUs
			  in the system, #address-cells can be set to 1, since
			  MPIDR_EL1[63:32] bits are not used for CPUs
			  identification.
	- #size-cells
		Usage: required
		Value type: <u32>
		Definition: must be set to 0

- cpu node

	Description: Describes a CPU in an ARM based system

	PROPERTIES

	- device_type
		Usage: required
		Value type: <string>
		Definition: must be "cpu"
	- reg
		Usage and definition depend on ARM architecture version and
		configuration:

			# On uniprocessor ARM architectures previous to v7
			  this property is required and must be set to 0.

			# On ARM 11 MPcore based systems this property is
			  required and matches the CPUID[11:0] register bits.

			  Bits [11:0] in the reg cell must be set to
			  bits [11:0] in CPU ID register.

			  All other bits in the reg cell must be set to 0.

			# On 32-bit ARM v7 or later systems this property is
			  required and matches the CPU MPIDR[23:0] register
			  bits.

			  Bits [23:0] in the reg cell must be set to
			  bits [23:0] in MPIDR.

			  All other bits in the reg cell must be set to 0.

			# On ARM v8 64-bit systems this property is required
			  and matches the MPIDR_EL1 register affinity bits.

			  * If cpus node's #address-cells property is set to 2

			    The first reg cell bits [7:0] must be set to
			    bits [39:32] of MPIDR_EL1.

			    The second reg cell bits [23:0] must be set to
			    bits [23:0] of MPIDR_EL1.

			  * If cpus node's #address-cells property is set to 1

			    The reg cell bits [23:0] must be set to bits [23:0]
			    of MPIDR_EL1.

			  All other bits in the reg cells must be set to 0.

	- compatible:
		Usage: required
		Value type: <string>
		Definition: should be one of:
			    "arm,arm710t"
			    "arm,arm720t"
			    "arm,arm740t"
			    "arm,arm7ej-s"
			    "arm,arm7tdmi"
			    "arm,arm7tdmi-s"
			    "arm,arm9es"
			    "arm,arm9ej-s"
			    "arm,arm920t"
			    "arm,arm922t"
			    "arm,arm925"
			    "arm,arm926e-s"
			    "arm,arm926ej-s"
			    "arm,arm940t"
			    "arm,arm946e-s"
			    "arm,arm966e-s"
			    "arm,arm968e-s"
			    "arm,arm9tdmi"
			    "arm,arm1020e"
			    "arm,arm1020t"
			    "arm,arm1022e"
			    "arm,arm1026ej-s"
			    "arm,arm1136j-s"
			    "arm,arm1136jf-s"
			    "arm,arm1156t2-s"
			    "arm,arm1156t2f-s"
			    "arm,arm1176jzf"
			    "arm,arm1176jz-s"
			    "arm,arm1176jzf-s"
			    "arm,arm11mpcore"
			    "arm,cortex-a5"
			    "arm,cortex-a7"
			    "arm,cortex-a8"
			    "arm,cortex-a9"
			    "arm,cortex-a15"
			    "arm,cortex-a53"
			    "arm,cortex-a57"
			    "arm,cortex-m0"
			    "arm,cortex-m0+"
			    "arm,cortex-m1"
			    "arm,cortex-m3"
			    "arm,cortex-m4"
			    "arm,cortex-r4"
			    "arm,cortex-r5"
			    "arm,cortex-r7"
			    "faraday,fa526"
			    "intel,sa110"
			    "intel,sa1100"
			    "marvell,feroceon"
			    "marvell,mohawk"
			    "marvell,pj4a"
			    "marvell,pj4b"
			    "marvell,sheeva-v5"
			    "qcom,krait"
			    "qcom,scorpion"
	- enable-method
		Value type: <stringlist>
		Usage and definition depend on ARM architecture version.
			# On ARM v8 64-bit this property is required and must
			  be one of:
			     "spin-table"
			     "psci"
			# On ARM 32-bit systems this property is optional.

	- cpu-release-addr
		Usage: required for systems that have an "enable-method"
		       property value of "spin-table".
		Value type: <prop-encoded-array>
		Definition:
			# On ARM v8 64-bit systems must be a two cell
			  property identifying a 64-bit zero-initialised
			  memory location.

Example 1 (dual-cluster big.LITTLE system 32-bit):

	cpus {
		#size-cells = <0>;
		#address-cells = <1>;

		cpu@0 {
			device_type = "cpu";
			compatible = "arm,cortex-a15";
			reg = <0x0>;
		};

		cpu@1 {
			device_type = "cpu";
			compatible = "arm,cortex-a15";
			reg = <0x1>;
		};

		cpu@100 {
			device_type = "cpu";
			compatible = "arm,cortex-a7";
			reg = <0x100>;
		};

		cpu@101 {
			device_type = "cpu";
			compatible = "arm,cortex-a7";
			reg = <0x101>;
		};
	};

Example 2 (Cortex-A8 uniprocessor 32-bit system):

	cpus {
		#size-cells = <0>;
		#address-cells = <1>;

		cpu@0 {
			device_type = "cpu";
			compatible = "arm,cortex-a8";
			reg = <0x0>;
		};
	};

Example 3 (ARM 926EJ-S uniprocessor 32-bit system):

	cpus {
		#size-cells = <0>;
		#address-cells = <1>;

		cpu@0 {
			device_type = "cpu";
			compatible = "arm,arm926ej-s";
			reg = <0x0>;
		};
	};

Example 4 (ARM Cortex-A57 64-bit system):

cpus {
	#size-cells = <0>;
	#address-cells = <2>;

	cpu@0 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x0 0x0>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@1 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x0 0x1>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@100 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x0 0x100>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@101 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x0 0x101>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@10000 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x0 0x10000>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@10001 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x0 0x10001>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@10100 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x0 0x10100>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@10101 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x0 0x10101>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@100000000 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x1 0x0>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@100000001 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x1 0x1>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@100000100 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x1 0x100>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@100000101 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x1 0x101>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@100010000 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x1 0x10000>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@100010001 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x1 0x10001>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@100010100 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x1 0x10100>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};

	cpu@100010101 {
		device_type = "cpu";
		compatible = "arm,cortex-a57";
		reg = <0x1 0x10101>;
		enable-method = "spin-table";
		cpu-release-addr = <0 0x20000000>;
	};
};
