162306a36Sopenharmony_ci==========================================
262306a36Sopenharmony_ciCPU capacity bindings
362306a36Sopenharmony_ci==========================================
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci==========================================
662306a36Sopenharmony_ci1 - Introduction
762306a36Sopenharmony_ci==========================================
862306a36Sopenharmony_ci
962306a36Sopenharmony_ciSome systems may be configured to have cpus with different power/performance
1062306a36Sopenharmony_cicharacteristics within the same chip. In this case, additional information has
1162306a36Sopenharmony_cito be made available to the kernel for it to be aware of such differences and
1262306a36Sopenharmony_citake decisions accordingly.
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci==========================================
1562306a36Sopenharmony_ci2 - CPU capacity definition
1662306a36Sopenharmony_ci==========================================
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ciCPU capacity is a number that provides the scheduler information about CPUs
1962306a36Sopenharmony_ciheterogeneity. Such heterogeneity can come from micro-architectural differences
2062306a36Sopenharmony_ci(e.g., ARM big.LITTLE systems) or maximum frequency at which CPUs can run
2162306a36Sopenharmony_ci(e.g., SMP systems with multiple frequency domains). Heterogeneity in this
2262306a36Sopenharmony_cicontext is about differing performance characteristics; this binding tries to
2362306a36Sopenharmony_cicapture a first-order approximation of the relative performance of CPUs.
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ciCPU capacities are obtained by running a suitable benchmark. This binding makes
2662306a36Sopenharmony_cino guarantees on the validity or suitability of any particular benchmark, the
2762306a36Sopenharmony_cifinal capacity should, however, be:
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci* A "single-threaded" or CPU affine benchmark
3062306a36Sopenharmony_ci* Divided by the running frequency of the CPU executing the benchmark
3162306a36Sopenharmony_ci* Not subject to dynamic frequency scaling of the CPU
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ciFor the time being we however advise usage of the Dhrystone benchmark. What
3462306a36Sopenharmony_ciabove thus becomes:
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ciCPU capacities are obtained by running the Dhrystone benchmark on each CPU at
3762306a36Sopenharmony_cimax frequency (with caches enabled). The obtained DMIPS score is then divided
3862306a36Sopenharmony_ciby the frequency (in MHz) at which the benchmark has been run, so that
3962306a36Sopenharmony_ciDMIPS/MHz are obtained.  Such values are then normalized w.r.t. the highest
4062306a36Sopenharmony_ciscore obtained in the system.
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci==========================================
4362306a36Sopenharmony_ci3 - capacity-dmips-mhz
4462306a36Sopenharmony_ci==========================================
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cicapacity-dmips-mhz is an optional cpu node [1] property: u32 value
4762306a36Sopenharmony_cirepresenting CPU capacity expressed in normalized DMIPS/MHz. At boot time, the
4862306a36Sopenharmony_cimaximum frequency available to the cpu is then used to calculate the capacity
4962306a36Sopenharmony_civalue internally used by the kernel.
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cicapacity-dmips-mhz property is all-or-nothing: if it is specified for a cpu
5262306a36Sopenharmony_cinode, it has to be specified for every other cpu nodes, or the system will
5362306a36Sopenharmony_cifall back to the default capacity value for every CPU. If cpufreq is not
5462306a36Sopenharmony_ciavailable, final capacities are calculated by directly using capacity-dmips-
5562306a36Sopenharmony_cimhz values (normalized w.r.t. the highest value found while parsing the DT).
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci===========================================
5862306a36Sopenharmony_ci4 - Examples
5962306a36Sopenharmony_ci===========================================
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ciExample 1 (ARM 64-bit, 6-cpu system, two clusters):
6262306a36Sopenharmony_ciThe capacities-dmips-mhz or DMIPS/MHz values (scaled to 1024)
6362306a36Sopenharmony_ciare 1024 and 578 for cluster0 and cluster1. Further normalization
6462306a36Sopenharmony_ciis done by the operating system based on cluster0@max-freq=1100 and
6562306a36Sopenharmony_cicluster1@max-freq=850, final capacities are 1024 for cluster0 and
6662306a36Sopenharmony_ci446 for cluster1 (578*850/1100).
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_cicpus {
6962306a36Sopenharmony_ci	#address-cells = <2>;
7062306a36Sopenharmony_ci	#size-cells = <0>;
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	cpu-map {
7362306a36Sopenharmony_ci		cluster0 {
7462306a36Sopenharmony_ci			core0 {
7562306a36Sopenharmony_ci				cpu = <&A57_0>;
7662306a36Sopenharmony_ci			};
7762306a36Sopenharmony_ci			core1 {
7862306a36Sopenharmony_ci				cpu = <&A57_1>;
7962306a36Sopenharmony_ci			};
8062306a36Sopenharmony_ci		};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci		cluster1 {
8362306a36Sopenharmony_ci			core0 {
8462306a36Sopenharmony_ci				cpu = <&A53_0>;
8562306a36Sopenharmony_ci			};
8662306a36Sopenharmony_ci			core1 {
8762306a36Sopenharmony_ci				cpu = <&A53_1>;
8862306a36Sopenharmony_ci			};
8962306a36Sopenharmony_ci			core2 {
9062306a36Sopenharmony_ci				cpu = <&A53_2>;
9162306a36Sopenharmony_ci			};
9262306a36Sopenharmony_ci			core3 {
9362306a36Sopenharmony_ci				cpu = <&A53_3>;
9462306a36Sopenharmony_ci			};
9562306a36Sopenharmony_ci		};
9662306a36Sopenharmony_ci	};
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	idle-states {
9962306a36Sopenharmony_ci		entry-method = "psci";
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci		CPU_SLEEP_0: cpu-sleep-0 {
10262306a36Sopenharmony_ci			compatible = "arm,idle-state";
10362306a36Sopenharmony_ci			arm,psci-suspend-param = <0x0010000>;
10462306a36Sopenharmony_ci			local-timer-stop;
10562306a36Sopenharmony_ci			entry-latency-us = <100>;
10662306a36Sopenharmony_ci			exit-latency-us = <250>;
10762306a36Sopenharmony_ci			min-residency-us = <150>;
10862306a36Sopenharmony_ci		};
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci		CLUSTER_SLEEP_0: cluster-sleep-0 {
11162306a36Sopenharmony_ci			compatible = "arm,idle-state";
11262306a36Sopenharmony_ci			arm,psci-suspend-param = <0x1010000>;
11362306a36Sopenharmony_ci			local-timer-stop;
11462306a36Sopenharmony_ci			entry-latency-us = <800>;
11562306a36Sopenharmony_ci			exit-latency-us = <700>;
11662306a36Sopenharmony_ci			min-residency-us = <2500>;
11762306a36Sopenharmony_ci		};
11862306a36Sopenharmony_ci	};
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci	A57_0: cpu@0 {
12162306a36Sopenharmony_ci		compatible = "arm,cortex-a57";
12262306a36Sopenharmony_ci		reg = <0x0 0x0>;
12362306a36Sopenharmony_ci		device_type = "cpu";
12462306a36Sopenharmony_ci		enable-method = "psci";
12562306a36Sopenharmony_ci		next-level-cache = <&A57_L2>;
12662306a36Sopenharmony_ci		clocks = <&scpi_dvfs 0>;
12762306a36Sopenharmony_ci		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
12862306a36Sopenharmony_ci		capacity-dmips-mhz = <1024>;
12962306a36Sopenharmony_ci	};
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	A57_1: cpu@1 {
13262306a36Sopenharmony_ci		compatible = "arm,cortex-a57";
13362306a36Sopenharmony_ci		reg = <0x0 0x1>;
13462306a36Sopenharmony_ci		device_type = "cpu";
13562306a36Sopenharmony_ci		enable-method = "psci";
13662306a36Sopenharmony_ci		next-level-cache = <&A57_L2>;
13762306a36Sopenharmony_ci		clocks = <&scpi_dvfs 0>;
13862306a36Sopenharmony_ci		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
13962306a36Sopenharmony_ci		capacity-dmips-mhz = <1024>;
14062306a36Sopenharmony_ci	};
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	A53_0: cpu@100 {
14362306a36Sopenharmony_ci		compatible = "arm,cortex-a53";
14462306a36Sopenharmony_ci		reg = <0x0 0x100>;
14562306a36Sopenharmony_ci		device_type = "cpu";
14662306a36Sopenharmony_ci		enable-method = "psci";
14762306a36Sopenharmony_ci		next-level-cache = <&A53_L2>;
14862306a36Sopenharmony_ci		clocks = <&scpi_dvfs 1>;
14962306a36Sopenharmony_ci		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
15062306a36Sopenharmony_ci		capacity-dmips-mhz = <578>;
15162306a36Sopenharmony_ci	};
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci	A53_1: cpu@101 {
15462306a36Sopenharmony_ci		compatible = "arm,cortex-a53";
15562306a36Sopenharmony_ci		reg = <0x0 0x101>;
15662306a36Sopenharmony_ci		device_type = "cpu";
15762306a36Sopenharmony_ci		enable-method = "psci";
15862306a36Sopenharmony_ci		next-level-cache = <&A53_L2>;
15962306a36Sopenharmony_ci		clocks = <&scpi_dvfs 1>;
16062306a36Sopenharmony_ci		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
16162306a36Sopenharmony_ci		capacity-dmips-mhz = <578>;
16262306a36Sopenharmony_ci	};
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci	A53_2: cpu@102 {
16562306a36Sopenharmony_ci		compatible = "arm,cortex-a53";
16662306a36Sopenharmony_ci		reg = <0x0 0x102>;
16762306a36Sopenharmony_ci		device_type = "cpu";
16862306a36Sopenharmony_ci		enable-method = "psci";
16962306a36Sopenharmony_ci		next-level-cache = <&A53_L2>;
17062306a36Sopenharmony_ci		clocks = <&scpi_dvfs 1>;
17162306a36Sopenharmony_ci		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
17262306a36Sopenharmony_ci		capacity-dmips-mhz = <578>;
17362306a36Sopenharmony_ci	};
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	A53_3: cpu@103 {
17662306a36Sopenharmony_ci		compatible = "arm,cortex-a53";
17762306a36Sopenharmony_ci		reg = <0x0 0x103>;
17862306a36Sopenharmony_ci		device_type = "cpu";
17962306a36Sopenharmony_ci		enable-method = "psci";
18062306a36Sopenharmony_ci		next-level-cache = <&A53_L2>;
18162306a36Sopenharmony_ci		clocks = <&scpi_dvfs 1>;
18262306a36Sopenharmony_ci		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
18362306a36Sopenharmony_ci		capacity-dmips-mhz = <578>;
18462306a36Sopenharmony_ci	};
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	A57_L2: l2-cache0 {
18762306a36Sopenharmony_ci		compatible = "cache";
18862306a36Sopenharmony_ci	};
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	A53_L2: l2-cache1 {
19162306a36Sopenharmony_ci		compatible = "cache";
19262306a36Sopenharmony_ci	};
19362306a36Sopenharmony_ci};
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ciExample 2 (ARM 32-bit, 4-cpu system, two clusters,
19662306a36Sopenharmony_ci	   cpus 0,1@1GHz, cpus 2,3@500MHz):
19762306a36Sopenharmony_cicapacities-dmips-mhz are scaled w.r.t. 2 (cpu@0 and cpu@1), this means that first
19862306a36Sopenharmony_cicpu@0 and cpu@1 are twice fast than cpu@2 and cpu@3 (at the same frequency)
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cicpus {
20162306a36Sopenharmony_ci	#address-cells = <1>;
20262306a36Sopenharmony_ci	#size-cells = <0>;
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	cpu0: cpu@0 {
20562306a36Sopenharmony_ci		device_type = "cpu";
20662306a36Sopenharmony_ci		compatible = "arm,cortex-a15";
20762306a36Sopenharmony_ci		reg = <0>;
20862306a36Sopenharmony_ci		capacity-dmips-mhz = <2>;
20962306a36Sopenharmony_ci	};
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	cpu1: cpu@1 {
21262306a36Sopenharmony_ci		device_type = "cpu";
21362306a36Sopenharmony_ci		compatible = "arm,cortex-a15";
21462306a36Sopenharmony_ci		reg = <1>;
21562306a36Sopenharmony_ci		capacity-dmips-mhz = <2>;
21662306a36Sopenharmony_ci	};
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	cpu2: cpu@2 {
21962306a36Sopenharmony_ci		device_type = "cpu";
22062306a36Sopenharmony_ci		compatible = "arm,cortex-a15";
22162306a36Sopenharmony_ci		reg = <0x100>;
22262306a36Sopenharmony_ci		capacity-dmips-mhz = <1>;
22362306a36Sopenharmony_ci	};
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	cpu3: cpu@3 {
22662306a36Sopenharmony_ci		device_type = "cpu";
22762306a36Sopenharmony_ci		compatible = "arm,cortex-a15";
22862306a36Sopenharmony_ci		reg = <0x101>;
22962306a36Sopenharmony_ci		capacity-dmips-mhz = <1>;
23062306a36Sopenharmony_ci	};
23162306a36Sopenharmony_ci};
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci===========================================
23462306a36Sopenharmony_ci5 - References
23562306a36Sopenharmony_ci===========================================
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci[1] ARM Linux Kernel documentation - CPUs bindings
23862306a36Sopenharmony_ci    Documentation/devicetree/bindings/arm/cpus.yaml
239