1*cb7aa33aSEmmanuel Vadot========================================== 2*cb7aa33aSEmmanuel VadotCPU capacity bindings 3*cb7aa33aSEmmanuel Vadot========================================== 4*cb7aa33aSEmmanuel Vadot 5*cb7aa33aSEmmanuel Vadot========================================== 6*cb7aa33aSEmmanuel Vadot1 - Introduction 7*cb7aa33aSEmmanuel Vadot========================================== 8*cb7aa33aSEmmanuel Vadot 9*cb7aa33aSEmmanuel VadotSome systems may be configured to have cpus with different power/performance 10*cb7aa33aSEmmanuel Vadotcharacteristics within the same chip. In this case, additional information has 11*cb7aa33aSEmmanuel Vadotto be made available to the kernel for it to be aware of such differences and 12*cb7aa33aSEmmanuel Vadottake decisions accordingly. 13*cb7aa33aSEmmanuel Vadot 14*cb7aa33aSEmmanuel Vadot========================================== 15*cb7aa33aSEmmanuel Vadot2 - CPU capacity definition 16*cb7aa33aSEmmanuel Vadot========================================== 17*cb7aa33aSEmmanuel Vadot 18*cb7aa33aSEmmanuel VadotCPU capacity is a number that provides the scheduler information about CPUs 19*cb7aa33aSEmmanuel Vadotheterogeneity. Such heterogeneity can come from micro-architectural differences 20*cb7aa33aSEmmanuel Vadot(e.g., ARM big.LITTLE systems) or maximum frequency at which CPUs can run 21*cb7aa33aSEmmanuel Vadot(e.g., SMP systems with multiple frequency domains). Heterogeneity in this 22*cb7aa33aSEmmanuel Vadotcontext is about differing performance characteristics; this binding tries to 23*cb7aa33aSEmmanuel Vadotcapture a first-order approximation of the relative performance of CPUs. 24*cb7aa33aSEmmanuel Vadot 25*cb7aa33aSEmmanuel VadotCPU capacities are obtained by running a suitable benchmark. This binding makes 26*cb7aa33aSEmmanuel Vadotno guarantees on the validity or suitability of any particular benchmark, the 27*cb7aa33aSEmmanuel Vadotfinal capacity should, however, be: 28*cb7aa33aSEmmanuel Vadot 29*cb7aa33aSEmmanuel Vadot* A "single-threaded" or CPU affine benchmark 30*cb7aa33aSEmmanuel Vadot* Divided by the running frequency of the CPU executing the benchmark 31*cb7aa33aSEmmanuel Vadot* Not subject to dynamic frequency scaling of the CPU 32*cb7aa33aSEmmanuel Vadot 33*cb7aa33aSEmmanuel VadotFor the time being we however advise usage of the Dhrystone benchmark. What 34*cb7aa33aSEmmanuel Vadotabove thus becomes: 35*cb7aa33aSEmmanuel Vadot 36*cb7aa33aSEmmanuel VadotCPU capacities are obtained by running the Dhrystone benchmark on each CPU at 37*cb7aa33aSEmmanuel Vadotmax frequency (with caches enabled). The obtained DMIPS score is then divided 38*cb7aa33aSEmmanuel Vadotby the frequency (in MHz) at which the benchmark has been run, so that 39*cb7aa33aSEmmanuel VadotDMIPS/MHz are obtained. Such values are then normalized w.r.t. the highest 40*cb7aa33aSEmmanuel Vadotscore obtained in the system. 41*cb7aa33aSEmmanuel Vadot 42*cb7aa33aSEmmanuel Vadot========================================== 43*cb7aa33aSEmmanuel Vadot3 - capacity-dmips-mhz 44*cb7aa33aSEmmanuel Vadot========================================== 45*cb7aa33aSEmmanuel Vadot 46*cb7aa33aSEmmanuel Vadotcapacity-dmips-mhz is an optional cpu node [1] property: u32 value 47*cb7aa33aSEmmanuel Vadotrepresenting CPU capacity expressed in normalized DMIPS/MHz. At boot time, the 48*cb7aa33aSEmmanuel Vadotmaximum frequency available to the cpu is then used to calculate the capacity 49*cb7aa33aSEmmanuel Vadotvalue internally used by the kernel. 50*cb7aa33aSEmmanuel Vadot 51*cb7aa33aSEmmanuel Vadotcapacity-dmips-mhz property is all-or-nothing: if it is specified for a cpu 52*cb7aa33aSEmmanuel Vadotnode, it has to be specified for every other cpu nodes, or the system will 53*cb7aa33aSEmmanuel Vadotfall back to the default capacity value for every CPU. If cpufreq is not 54*cb7aa33aSEmmanuel Vadotavailable, final capacities are calculated by directly using capacity-dmips- 55*cb7aa33aSEmmanuel Vadotmhz values (normalized w.r.t. the highest value found while parsing the DT). 56*cb7aa33aSEmmanuel Vadot 57*cb7aa33aSEmmanuel Vadot=========================================== 58*cb7aa33aSEmmanuel Vadot4 - Examples 59*cb7aa33aSEmmanuel Vadot=========================================== 60*cb7aa33aSEmmanuel Vadot 61*cb7aa33aSEmmanuel VadotExample 1 (ARM 64-bit, 6-cpu system, two clusters): 62*cb7aa33aSEmmanuel VadotThe capacities-dmips-mhz or DMIPS/MHz values (scaled to 1024) 63*cb7aa33aSEmmanuel Vadotare 1024 and 578 for cluster0 and cluster1. Further normalization 64*cb7aa33aSEmmanuel Vadotis done by the operating system based on cluster0@max-freq=1100 and 65*cb7aa33aSEmmanuel Vadotcluster1@max-freq=850, final capacities are 1024 for cluster0 and 66*cb7aa33aSEmmanuel Vadot446 for cluster1 (578*850/1100). 67*cb7aa33aSEmmanuel Vadot 68*cb7aa33aSEmmanuel Vadotcpus { 69*cb7aa33aSEmmanuel Vadot #address-cells = <2>; 70*cb7aa33aSEmmanuel Vadot #size-cells = <0>; 71*cb7aa33aSEmmanuel Vadot 72*cb7aa33aSEmmanuel Vadot cpu-map { 73*cb7aa33aSEmmanuel Vadot cluster0 { 74*cb7aa33aSEmmanuel Vadot core0 { 75*cb7aa33aSEmmanuel Vadot cpu = <&A57_0>; 76*cb7aa33aSEmmanuel Vadot }; 77*cb7aa33aSEmmanuel Vadot core1 { 78*cb7aa33aSEmmanuel Vadot cpu = <&A57_1>; 79*cb7aa33aSEmmanuel Vadot }; 80*cb7aa33aSEmmanuel Vadot }; 81*cb7aa33aSEmmanuel Vadot 82*cb7aa33aSEmmanuel Vadot cluster1 { 83*cb7aa33aSEmmanuel Vadot core0 { 84*cb7aa33aSEmmanuel Vadot cpu = <&A53_0>; 85*cb7aa33aSEmmanuel Vadot }; 86*cb7aa33aSEmmanuel Vadot core1 { 87*cb7aa33aSEmmanuel Vadot cpu = <&A53_1>; 88*cb7aa33aSEmmanuel Vadot }; 89*cb7aa33aSEmmanuel Vadot core2 { 90*cb7aa33aSEmmanuel Vadot cpu = <&A53_2>; 91*cb7aa33aSEmmanuel Vadot }; 92*cb7aa33aSEmmanuel Vadot core3 { 93*cb7aa33aSEmmanuel Vadot cpu = <&A53_3>; 94*cb7aa33aSEmmanuel Vadot }; 95*cb7aa33aSEmmanuel Vadot }; 96*cb7aa33aSEmmanuel Vadot }; 97*cb7aa33aSEmmanuel Vadot 98*cb7aa33aSEmmanuel Vadot idle-states { 99*cb7aa33aSEmmanuel Vadot entry-method = "psci"; 100*cb7aa33aSEmmanuel Vadot 101*cb7aa33aSEmmanuel Vadot CPU_SLEEP_0: cpu-sleep-0 { 102*cb7aa33aSEmmanuel Vadot compatible = "arm,idle-state"; 103*cb7aa33aSEmmanuel Vadot arm,psci-suspend-param = <0x0010000>; 104*cb7aa33aSEmmanuel Vadot local-timer-stop; 105*cb7aa33aSEmmanuel Vadot entry-latency-us = <100>; 106*cb7aa33aSEmmanuel Vadot exit-latency-us = <250>; 107*cb7aa33aSEmmanuel Vadot min-residency-us = <150>; 108*cb7aa33aSEmmanuel Vadot }; 109*cb7aa33aSEmmanuel Vadot 110*cb7aa33aSEmmanuel Vadot CLUSTER_SLEEP_0: cluster-sleep-0 { 111*cb7aa33aSEmmanuel Vadot compatible = "arm,idle-state"; 112*cb7aa33aSEmmanuel Vadot arm,psci-suspend-param = <0x1010000>; 113*cb7aa33aSEmmanuel Vadot local-timer-stop; 114*cb7aa33aSEmmanuel Vadot entry-latency-us = <800>; 115*cb7aa33aSEmmanuel Vadot exit-latency-us = <700>; 116*cb7aa33aSEmmanuel Vadot min-residency-us = <2500>; 117*cb7aa33aSEmmanuel Vadot }; 118*cb7aa33aSEmmanuel Vadot }; 119*cb7aa33aSEmmanuel Vadot 120*cb7aa33aSEmmanuel Vadot A57_0: cpu@0 { 121*cb7aa33aSEmmanuel Vadot compatible = "arm,cortex-a57"; 122*cb7aa33aSEmmanuel Vadot reg = <0x0 0x0>; 123*cb7aa33aSEmmanuel Vadot device_type = "cpu"; 124*cb7aa33aSEmmanuel Vadot enable-method = "psci"; 125*cb7aa33aSEmmanuel Vadot next-level-cache = <&A57_L2>; 126*cb7aa33aSEmmanuel Vadot clocks = <&scpi_dvfs 0>; 127*cb7aa33aSEmmanuel Vadot cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; 128*cb7aa33aSEmmanuel Vadot capacity-dmips-mhz = <1024>; 129*cb7aa33aSEmmanuel Vadot }; 130*cb7aa33aSEmmanuel Vadot 131*cb7aa33aSEmmanuel Vadot A57_1: cpu@1 { 132*cb7aa33aSEmmanuel Vadot compatible = "arm,cortex-a57"; 133*cb7aa33aSEmmanuel Vadot reg = <0x0 0x1>; 134*cb7aa33aSEmmanuel Vadot device_type = "cpu"; 135*cb7aa33aSEmmanuel Vadot enable-method = "psci"; 136*cb7aa33aSEmmanuel Vadot next-level-cache = <&A57_L2>; 137*cb7aa33aSEmmanuel Vadot clocks = <&scpi_dvfs 0>; 138*cb7aa33aSEmmanuel Vadot cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; 139*cb7aa33aSEmmanuel Vadot capacity-dmips-mhz = <1024>; 140*cb7aa33aSEmmanuel Vadot }; 141*cb7aa33aSEmmanuel Vadot 142*cb7aa33aSEmmanuel Vadot A53_0: cpu@100 { 143*cb7aa33aSEmmanuel Vadot compatible = "arm,cortex-a53"; 144*cb7aa33aSEmmanuel Vadot reg = <0x0 0x100>; 145*cb7aa33aSEmmanuel Vadot device_type = "cpu"; 146*cb7aa33aSEmmanuel Vadot enable-method = "psci"; 147*cb7aa33aSEmmanuel Vadot next-level-cache = <&A53_L2>; 148*cb7aa33aSEmmanuel Vadot clocks = <&scpi_dvfs 1>; 149*cb7aa33aSEmmanuel Vadot cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; 150*cb7aa33aSEmmanuel Vadot capacity-dmips-mhz = <578>; 151*cb7aa33aSEmmanuel Vadot }; 152*cb7aa33aSEmmanuel Vadot 153*cb7aa33aSEmmanuel Vadot A53_1: cpu@101 { 154*cb7aa33aSEmmanuel Vadot compatible = "arm,cortex-a53"; 155*cb7aa33aSEmmanuel Vadot reg = <0x0 0x101>; 156*cb7aa33aSEmmanuel Vadot device_type = "cpu"; 157*cb7aa33aSEmmanuel Vadot enable-method = "psci"; 158*cb7aa33aSEmmanuel Vadot next-level-cache = <&A53_L2>; 159*cb7aa33aSEmmanuel Vadot clocks = <&scpi_dvfs 1>; 160*cb7aa33aSEmmanuel Vadot cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; 161*cb7aa33aSEmmanuel Vadot capacity-dmips-mhz = <578>; 162*cb7aa33aSEmmanuel Vadot }; 163*cb7aa33aSEmmanuel Vadot 164*cb7aa33aSEmmanuel Vadot A53_2: cpu@102 { 165*cb7aa33aSEmmanuel Vadot compatible = "arm,cortex-a53"; 166*cb7aa33aSEmmanuel Vadot reg = <0x0 0x102>; 167*cb7aa33aSEmmanuel Vadot device_type = "cpu"; 168*cb7aa33aSEmmanuel Vadot enable-method = "psci"; 169*cb7aa33aSEmmanuel Vadot next-level-cache = <&A53_L2>; 170*cb7aa33aSEmmanuel Vadot clocks = <&scpi_dvfs 1>; 171*cb7aa33aSEmmanuel Vadot cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; 172*cb7aa33aSEmmanuel Vadot capacity-dmips-mhz = <578>; 173*cb7aa33aSEmmanuel Vadot }; 174*cb7aa33aSEmmanuel Vadot 175*cb7aa33aSEmmanuel Vadot A53_3: cpu@103 { 176*cb7aa33aSEmmanuel Vadot compatible = "arm,cortex-a53"; 177*cb7aa33aSEmmanuel Vadot reg = <0x0 0x103>; 178*cb7aa33aSEmmanuel Vadot device_type = "cpu"; 179*cb7aa33aSEmmanuel Vadot enable-method = "psci"; 180*cb7aa33aSEmmanuel Vadot next-level-cache = <&A53_L2>; 181*cb7aa33aSEmmanuel Vadot clocks = <&scpi_dvfs 1>; 182*cb7aa33aSEmmanuel Vadot cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; 183*cb7aa33aSEmmanuel Vadot capacity-dmips-mhz = <578>; 184*cb7aa33aSEmmanuel Vadot }; 185*cb7aa33aSEmmanuel Vadot 186*cb7aa33aSEmmanuel Vadot A57_L2: l2-cache0 { 187*cb7aa33aSEmmanuel Vadot compatible = "cache"; 188*cb7aa33aSEmmanuel Vadot }; 189*cb7aa33aSEmmanuel Vadot 190*cb7aa33aSEmmanuel Vadot A53_L2: l2-cache1 { 191*cb7aa33aSEmmanuel Vadot compatible = "cache"; 192*cb7aa33aSEmmanuel Vadot }; 193*cb7aa33aSEmmanuel Vadot}; 194*cb7aa33aSEmmanuel Vadot 195*cb7aa33aSEmmanuel VadotExample 2 (ARM 32-bit, 4-cpu system, two clusters, 196*cb7aa33aSEmmanuel Vadot cpus 0,1@1GHz, cpus 2,3@500MHz): 197*cb7aa33aSEmmanuel Vadotcapacities-dmips-mhz are scaled w.r.t. 2 (cpu@0 and cpu@1), this means that first 198*cb7aa33aSEmmanuel Vadotcpu@0 and cpu@1 are twice fast than cpu@2 and cpu@3 (at the same frequency) 199*cb7aa33aSEmmanuel Vadot 200*cb7aa33aSEmmanuel Vadotcpus { 201*cb7aa33aSEmmanuel Vadot #address-cells = <1>; 202*cb7aa33aSEmmanuel Vadot #size-cells = <0>; 203*cb7aa33aSEmmanuel Vadot 204*cb7aa33aSEmmanuel Vadot cpu0: cpu@0 { 205*cb7aa33aSEmmanuel Vadot device_type = "cpu"; 206*cb7aa33aSEmmanuel Vadot compatible = "arm,cortex-a15"; 207*cb7aa33aSEmmanuel Vadot reg = <0>; 208*cb7aa33aSEmmanuel Vadot capacity-dmips-mhz = <2>; 209*cb7aa33aSEmmanuel Vadot }; 210*cb7aa33aSEmmanuel Vadot 211*cb7aa33aSEmmanuel Vadot cpu1: cpu@1 { 212*cb7aa33aSEmmanuel Vadot device_type = "cpu"; 213*cb7aa33aSEmmanuel Vadot compatible = "arm,cortex-a15"; 214*cb7aa33aSEmmanuel Vadot reg = <1>; 215*cb7aa33aSEmmanuel Vadot capacity-dmips-mhz = <2>; 216*cb7aa33aSEmmanuel Vadot }; 217*cb7aa33aSEmmanuel Vadot 218*cb7aa33aSEmmanuel Vadot cpu2: cpu@2 { 219*cb7aa33aSEmmanuel Vadot device_type = "cpu"; 220*cb7aa33aSEmmanuel Vadot compatible = "arm,cortex-a15"; 221*cb7aa33aSEmmanuel Vadot reg = <0x100>; 222*cb7aa33aSEmmanuel Vadot capacity-dmips-mhz = <1>; 223*cb7aa33aSEmmanuel Vadot }; 224*cb7aa33aSEmmanuel Vadot 225*cb7aa33aSEmmanuel Vadot cpu3: cpu@3 { 226*cb7aa33aSEmmanuel Vadot device_type = "cpu"; 227*cb7aa33aSEmmanuel Vadot compatible = "arm,cortex-a15"; 228*cb7aa33aSEmmanuel Vadot reg = <0x101>; 229*cb7aa33aSEmmanuel Vadot capacity-dmips-mhz = <1>; 230*cb7aa33aSEmmanuel Vadot }; 231*cb7aa33aSEmmanuel Vadot}; 232*cb7aa33aSEmmanuel Vadot 233*cb7aa33aSEmmanuel Vadot=========================================== 234*cb7aa33aSEmmanuel Vadot5 - References 235*cb7aa33aSEmmanuel Vadot=========================================== 236*cb7aa33aSEmmanuel Vadot 237*cb7aa33aSEmmanuel Vadot[1] ARM Linux Kernel documentation - CPUs bindings 238*cb7aa33aSEmmanuel Vadot Documentation/devicetree/bindings/arm/cpus.yaml 239