Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'pm-opp'

* pm-opp:
PM / OPP: Add binding for 'opp-suspend'
PM / OPP: Allow multiple OPP tables to be passed via DT
PM / OPP: Add new bindings to address shortcomings of existing bindings

+444 -4
+444 -4
Documentation/devicetree/bindings/power/opp.txt
··· 1 - * Generic OPP Interface 1 + Generic OPP (Operating Performance Points) Bindings 2 + ---------------------------------------------------- 2 3 3 - SoCs have a standard set of tuples consisting of frequency and 4 - voltage pairs that the device will support per voltage domain. These 5 - are called Operating Performance Points or OPPs. 4 + Devices work at voltage-current-frequency combinations and some implementations 5 + have the liberty of choosing these. These combinations are called Operating 6 + Performance Points aka OPPs. This document defines bindings for these OPPs 7 + applicable across wide range of devices. For illustration purpose, this document 8 + uses CPU as a device. 9 + 10 + This document contain multiple versions of OPP binding and only one of them 11 + should be used per device. 12 + 13 + Binding 1: operating-points 14 + ============================ 15 + 16 + This binding only supports voltage-frequency pairs. 6 17 7 18 Properties: 8 19 - operating-points: An array of 2-tuples items, and each item consists ··· 33 22 396000 950000 34 23 198000 850000 35 24 >; 25 + }; 26 + 27 + 28 + Binding 2: operating-points-v2 29 + ============================ 30 + 31 + * Property: operating-points-v2 32 + 33 + Devices supporting OPPs must set their "operating-points-v2" property with 34 + phandle to a OPP table in their DT node. The OPP core will use this phandle to 35 + find the operating points for the device. 36 + 37 + Devices may want to choose OPP tables at runtime and so can provide a list of 38 + phandles here. But only *one* of them should be chosen at runtime. This must be 39 + accompanied by a corresponding "operating-points-names" property, to uniquely 40 + identify the OPP tables. 41 + 42 + If required, this can be extended for SoC vendor specfic bindings. Such bindings 43 + should be documented as Documentation/devicetree/bindings/power/<vendor>-opp.txt 44 + and should have a compatible description like: "operating-points-v2-<vendor>". 45 + 46 + Optional properties: 47 + - operating-points-names: Names of OPP tables (required if multiple OPP 48 + tables are present), to uniquely identify them. The same list must be present 49 + for all the CPUs which are sharing clock/voltage rails and hence the OPP 50 + tables. 51 + 52 + * OPP Table Node 53 + 54 + This describes the OPPs belonging to a device. This node can have following 55 + properties: 56 + 57 + Required properties: 58 + - compatible: Allow OPPs to express their compatibility. It should be: 59 + "operating-points-v2". 60 + 61 + - OPP nodes: One or more OPP nodes describing voltage-current-frequency 62 + combinations. Their name isn't significant but their phandle can be used to 63 + reference an OPP. 64 + 65 + Optional properties: 66 + - opp-shared: Indicates that device nodes using this OPP Table Node's phandle 67 + switch their DVFS state together, i.e. they share clock/voltage/current lines. 68 + Missing property means devices have independent clock/voltage/current lines, 69 + but they share OPP tables. 70 + 71 + - status: Marks the OPP table enabled/disabled. 72 + 73 + 74 + * OPP Node 75 + 76 + This defines voltage-current-frequency combinations along with other related 77 + properties. 78 + 79 + Required properties: 80 + - opp-hz: Frequency in Hz 81 + 82 + Optional properties: 83 + - opp-microvolt: voltage in micro Volts. 84 + 85 + A single regulator's voltage is specified with an array of size one or three. 86 + Single entry is for target voltage and three entries are for <target min max> 87 + voltages. 88 + 89 + Entries for multiple regulators must be present in the same order as 90 + regulators are specified in device's DT node. 91 + 92 + - opp-microamp: The maximum current drawn by the device in microamperes 93 + considering system specific parameters (such as transients, process, aging, 94 + maximum operating temperature range etc.) as necessary. This may be used to 95 + set the most efficient regulator operating mode. 96 + 97 + Should only be set if opp-microvolt is set for the OPP. 98 + 99 + Entries for multiple regulators must be present in the same order as 100 + regulators are specified in device's DT node. If this property isn't required 101 + for few regulators, then this should be marked as zero for them. If it isn't 102 + required for any regulator, then this property need not be present. 103 + 104 + - clock-latency-ns: Specifies the maximum possible transition latency (in 105 + nanoseconds) for switching to this OPP from any other OPP. 106 + 107 + - turbo-mode: Marks the OPP to be used only for turbo modes. Turbo mode is 108 + available on some platforms, where the device can run over its operating 109 + frequency for a short duration of time limited by the device's power, current 110 + and thermal limits. 111 + 112 + - opp-suspend: Marks the OPP to be used during device suspend. Only one OPP in 113 + the table should have this. 114 + 115 + - status: Marks the node enabled/disabled. 116 + 117 + Example 1: Single cluster Dual-core ARM cortex A9, switch DVFS states together. 118 + 119 + / { 120 + cpus { 121 + #address-cells = <1>; 122 + #size-cells = <0>; 123 + 124 + cpu@0 { 125 + compatible = "arm,cortex-a9"; 126 + reg = <0>; 127 + next-level-cache = <&L2>; 128 + clocks = <&clk_controller 0>; 129 + clock-names = "cpu"; 130 + cpu-supply = <&cpu_supply0>; 131 + operating-points-v2 = <&cpu0_opp_table>; 132 + }; 133 + 134 + cpu@1 { 135 + compatible = "arm,cortex-a9"; 136 + reg = <1>; 137 + next-level-cache = <&L2>; 138 + clocks = <&clk_controller 0>; 139 + clock-names = "cpu"; 140 + cpu-supply = <&cpu_supply0>; 141 + operating-points-v2 = <&cpu0_opp_table>; 142 + }; 143 + }; 144 + 145 + cpu0_opp_table: opp_table0 { 146 + compatible = "operating-points-v2"; 147 + opp-shared; 148 + 149 + opp00 { 150 + opp-hz = <1000000000>; 151 + opp-microvolt = <970000 975000 985000>; 152 + opp-microamp = <70000>; 153 + clock-latency-ns = <300000>; 154 + opp-suspend; 155 + }; 156 + opp01 { 157 + opp-hz = <1100000000>; 158 + opp-microvolt = <980000 1000000 1010000>; 159 + opp-microamp = <80000>; 160 + clock-latency-ns = <310000>; 161 + }; 162 + opp02 { 163 + opp-hz = <1200000000>; 164 + opp-microvolt = <1025000>; 165 + clock-latency-ns = <290000>; 166 + turbo-mode; 167 + }; 168 + }; 169 + }; 170 + 171 + Example 2: Single cluster, Quad-core Qualcom-krait, switches DVFS states 172 + independently. 173 + 174 + / { 175 + cpus { 176 + #address-cells = <1>; 177 + #size-cells = <0>; 178 + 179 + cpu@0 { 180 + compatible = "qcom,krait"; 181 + reg = <0>; 182 + next-level-cache = <&L2>; 183 + clocks = <&clk_controller 0>; 184 + clock-names = "cpu"; 185 + cpu-supply = <&cpu_supply0>; 186 + operating-points-v2 = <&cpu_opp_table>; 187 + }; 188 + 189 + cpu@1 { 190 + compatible = "qcom,krait"; 191 + reg = <1>; 192 + next-level-cache = <&L2>; 193 + clocks = <&clk_controller 1>; 194 + clock-names = "cpu"; 195 + cpu-supply = <&cpu_supply1>; 196 + operating-points-v2 = <&cpu_opp_table>; 197 + }; 198 + 199 + cpu@2 { 200 + compatible = "qcom,krait"; 201 + reg = <2>; 202 + next-level-cache = <&L2>; 203 + clocks = <&clk_controller 2>; 204 + clock-names = "cpu"; 205 + cpu-supply = <&cpu_supply2>; 206 + operating-points-v2 = <&cpu_opp_table>; 207 + }; 208 + 209 + cpu@3 { 210 + compatible = "qcom,krait"; 211 + reg = <3>; 212 + next-level-cache = <&L2>; 213 + clocks = <&clk_controller 3>; 214 + clock-names = "cpu"; 215 + cpu-supply = <&cpu_supply3>; 216 + operating-points-v2 = <&cpu_opp_table>; 217 + }; 218 + }; 219 + 220 + cpu_opp_table: opp_table { 221 + compatible = "operating-points-v2"; 222 + 223 + /* 224 + * Missing opp-shared property means CPUs switch DVFS states 225 + * independently. 226 + */ 227 + 228 + opp00 { 229 + opp-hz = <1000000000>; 230 + opp-microvolt = <970000 975000 985000>; 231 + opp-microamp = <70000>; 232 + clock-latency-ns = <300000>; 233 + opp-suspend; 234 + }; 235 + opp01 { 236 + opp-hz = <1100000000>; 237 + opp-microvolt = <980000 1000000 1010000>; 238 + opp-microamp = <80000>; 239 + clock-latency-ns = <310000>; 240 + }; 241 + opp02 { 242 + opp-hz = <1200000000>; 243 + opp-microvolt = <1025000>; 244 + opp-microamp = <90000; 245 + lock-latency-ns = <290000>; 246 + turbo-mode; 247 + }; 248 + }; 249 + }; 250 + 251 + Example 3: Dual-cluster, Dual-core per cluster. CPUs within a cluster switch 252 + DVFS state together. 253 + 254 + / { 255 + cpus { 256 + #address-cells = <1>; 257 + #size-cells = <0>; 258 + 259 + cpu@0 { 260 + compatible = "arm,cortex-a7"; 261 + reg = <0>; 262 + next-level-cache = <&L2>; 263 + clocks = <&clk_controller 0>; 264 + clock-names = "cpu"; 265 + cpu-supply = <&cpu_supply0>; 266 + operating-points-v2 = <&cluster0_opp>; 267 + }; 268 + 269 + cpu@1 { 270 + compatible = "arm,cortex-a7"; 271 + reg = <1>; 272 + next-level-cache = <&L2>; 273 + clocks = <&clk_controller 0>; 274 + clock-names = "cpu"; 275 + cpu-supply = <&cpu_supply0>; 276 + operating-points-v2 = <&cluster0_opp>; 277 + }; 278 + 279 + cpu@100 { 280 + compatible = "arm,cortex-a15"; 281 + reg = <100>; 282 + next-level-cache = <&L2>; 283 + clocks = <&clk_controller 1>; 284 + clock-names = "cpu"; 285 + cpu-supply = <&cpu_supply1>; 286 + operating-points-v2 = <&cluster1_opp>; 287 + }; 288 + 289 + cpu@101 { 290 + compatible = "arm,cortex-a15"; 291 + reg = <101>; 292 + next-level-cache = <&L2>; 293 + clocks = <&clk_controller 1>; 294 + clock-names = "cpu"; 295 + cpu-supply = <&cpu_supply1>; 296 + operating-points-v2 = <&cluster1_opp>; 297 + }; 298 + }; 299 + 300 + cluster0_opp: opp_table0 { 301 + compatible = "operating-points-v2"; 302 + opp-shared; 303 + 304 + opp00 { 305 + opp-hz = <1000000000>; 306 + opp-microvolt = <970000 975000 985000>; 307 + opp-microamp = <70000>; 308 + clock-latency-ns = <300000>; 309 + opp-suspend; 310 + }; 311 + opp01 { 312 + opp-hz = <1100000000>; 313 + opp-microvolt = <980000 1000000 1010000>; 314 + opp-microamp = <80000>; 315 + clock-latency-ns = <310000>; 316 + }; 317 + opp02 { 318 + opp-hz = <1200000000>; 319 + opp-microvolt = <1025000>; 320 + opp-microamp = <90000>; 321 + clock-latency-ns = <290000>; 322 + turbo-mode; 323 + }; 324 + }; 325 + 326 + cluster1_opp: opp_table1 { 327 + compatible = "operating-points-v2"; 328 + opp-shared; 329 + 330 + opp10 { 331 + opp-hz = <1300000000>; 332 + opp-microvolt = <1045000 1050000 1055000>; 333 + opp-microamp = <95000>; 334 + clock-latency-ns = <400000>; 335 + opp-suspend; 336 + }; 337 + opp11 { 338 + opp-hz = <1400000000>; 339 + opp-microvolt = <1075000>; 340 + opp-microamp = <100000>; 341 + clock-latency-ns = <400000>; 342 + }; 343 + opp12 { 344 + opp-hz = <1500000000>; 345 + opp-microvolt = <1010000 1100000 1110000>; 346 + opp-microamp = <95000>; 347 + clock-latency-ns = <400000>; 348 + turbo-mode; 349 + }; 350 + }; 351 + }; 352 + 353 + Example 4: Handling multiple regulators 354 + 355 + / { 356 + cpus { 357 + cpu@0 { 358 + compatible = "arm,cortex-a7"; 359 + ... 360 + 361 + cpu-supply = <&cpu_supply0>, <&cpu_supply1>, <&cpu_supply2>; 362 + operating-points-v2 = <&cpu0_opp_table>; 363 + }; 364 + }; 365 + 366 + cpu0_opp_table: opp_table0 { 367 + compatible = "operating-points-v2"; 368 + opp-shared; 369 + 370 + opp00 { 371 + opp-hz = <1000000000>; 372 + opp-microvolt = <970000>, /* Supply 0 */ 373 + <960000>, /* Supply 1 */ 374 + <960000>; /* Supply 2 */ 375 + opp-microamp = <70000>, /* Supply 0 */ 376 + <70000>, /* Supply 1 */ 377 + <70000>; /* Supply 2 */ 378 + clock-latency-ns = <300000>; 379 + }; 380 + 381 + /* OR */ 382 + 383 + opp00 { 384 + opp-hz = <1000000000>; 385 + opp-microvolt = <970000 975000 985000>, /* Supply 0 */ 386 + <960000 965000 975000>, /* Supply 1 */ 387 + <960000 965000 975000>; /* Supply 2 */ 388 + opp-microamp = <70000>, /* Supply 0 */ 389 + <70000>, /* Supply 1 */ 390 + <70000>; /* Supply 2 */ 391 + clock-latency-ns = <300000>; 392 + }; 393 + 394 + /* OR */ 395 + 396 + opp00 { 397 + opp-hz = <1000000000>; 398 + opp-microvolt = <970000 975000 985000>, /* Supply 0 */ 399 + <960000 965000 975000>, /* Supply 1 */ 400 + <960000 965000 975000>; /* Supply 2 */ 401 + opp-microamp = <70000>, /* Supply 0 */ 402 + <0>, /* Supply 1 doesn't need this */ 403 + <70000>; /* Supply 2 */ 404 + clock-latency-ns = <300000>; 405 + }; 406 + }; 407 + }; 408 + 409 + Example 5: Multiple OPP tables 410 + 411 + / { 412 + cpus { 413 + cpu@0 { 414 + compatible = "arm,cortex-a7"; 415 + ... 416 + 417 + cpu-supply = <&cpu_supply> 418 + operating-points-v2 = <&cpu0_opp_table_slow>, <&cpu0_opp_table_fast>; 419 + operating-points-names = "slow", "fast"; 420 + }; 421 + }; 422 + 423 + cpu0_opp_table_slow: opp_table_slow { 424 + compatible = "operating-points-v2"; 425 + status = "okay"; 426 + opp-shared; 427 + 428 + opp00 { 429 + opp-hz = <600000000>; 430 + ... 431 + }; 432 + 433 + opp01 { 434 + opp-hz = <800000000>; 435 + ... 436 + }; 437 + }; 438 + 439 + cpu0_opp_table_fast: opp_table_fast { 440 + compatible = "operating-points-v2"; 441 + status = "okay"; 442 + opp-shared; 443 + 444 + opp10 { 445 + opp-hz = <1000000000>; 446 + ... 447 + }; 448 + 449 + opp11 { 450 + opp-hz = <1100000000>; 451 + ... 452 + }; 453 + }; 36 454 };