at v6.6 18 kB view raw
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Generic OPP Interface 4 * 5 * Copyright (C) 2009-2010 Texas Instruments Incorporated. 6 * Nishanth Menon 7 * Romit Dasgupta 8 * Kevin Hilman 9 */ 10 11#ifndef __LINUX_OPP_H__ 12#define __LINUX_OPP_H__ 13 14#include <linux/energy_model.h> 15#include <linux/err.h> 16#include <linux/notifier.h> 17 18struct clk; 19struct regulator; 20struct dev_pm_opp; 21struct device; 22struct opp_table; 23 24enum dev_pm_opp_event { 25 OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE, 26 OPP_EVENT_ADJUST_VOLTAGE, 27}; 28 29/** 30 * struct dev_pm_opp_supply - Power supply voltage/current values 31 * @u_volt: Target voltage in microvolts corresponding to this OPP 32 * @u_volt_min: Minimum voltage in microvolts corresponding to this OPP 33 * @u_volt_max: Maximum voltage in microvolts corresponding to this OPP 34 * @u_amp: Maximum current drawn by the device in microamperes 35 * @u_watt: Power used by the device in microwatts 36 * 37 * This structure stores the voltage/current/power values for a single power 38 * supply. 39 */ 40struct dev_pm_opp_supply { 41 unsigned long u_volt; 42 unsigned long u_volt_min; 43 unsigned long u_volt_max; 44 unsigned long u_amp; 45 unsigned long u_watt; 46}; 47 48/** 49 * struct dev_pm_opp_icc_bw - Interconnect bandwidth values 50 * @avg: Average bandwidth corresponding to this OPP (in icc units) 51 * @peak: Peak bandwidth corresponding to this OPP (in icc units) 52 * 53 * This structure stores the bandwidth values for a single interconnect path. 54 */ 55struct dev_pm_opp_icc_bw { 56 u32 avg; 57 u32 peak; 58}; 59 60typedef int (*config_regulators_t)(struct device *dev, 61 struct dev_pm_opp *old_opp, struct dev_pm_opp *new_opp, 62 struct regulator **regulators, unsigned int count); 63 64typedef int (*config_clks_t)(struct device *dev, struct opp_table *opp_table, 65 struct dev_pm_opp *opp, void *data, bool scaling_down); 66 67/** 68 * struct dev_pm_opp_config - Device OPP configuration values 69 * @clk_names: Clk names, NULL terminated array. 70 * @config_clks: Custom set clk helper. 71 * @prop_name: Name to postfix to properties. 72 * @config_regulators: Custom set regulator helper. 73 * @supported_hw: Array of hierarchy of versions to match. 74 * @supported_hw_count: Number of elements in the array. 75 * @regulator_names: Array of pointers to the names of the regulator, NULL terminated. 76 * @genpd_names: Null terminated array of pointers containing names of genpd to 77 * attach. 78 * @virt_devs: Pointer to return the array of virtual devices. 79 * 80 * This structure contains platform specific OPP configurations for the device. 81 */ 82struct dev_pm_opp_config { 83 /* NULL terminated */ 84 const char * const *clk_names; 85 config_clks_t config_clks; 86 const char *prop_name; 87 config_regulators_t config_regulators; 88 const unsigned int *supported_hw; 89 unsigned int supported_hw_count; 90 const char * const *regulator_names; 91 const char * const *genpd_names; 92 struct device ***virt_devs; 93}; 94 95#if defined(CONFIG_PM_OPP) 96 97struct opp_table *dev_pm_opp_get_opp_table(struct device *dev); 98void dev_pm_opp_put_opp_table(struct opp_table *opp_table); 99 100unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp); 101 102int dev_pm_opp_get_supplies(struct dev_pm_opp *opp, struct dev_pm_opp_supply *supplies); 103 104unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp); 105 106unsigned long dev_pm_opp_get_freq_indexed(struct dev_pm_opp *opp, u32 index); 107 108unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp); 109 110unsigned int dev_pm_opp_get_required_pstate(struct dev_pm_opp *opp, 111 unsigned int index); 112 113bool dev_pm_opp_is_turbo(struct dev_pm_opp *opp); 114 115int dev_pm_opp_get_opp_count(struct device *dev); 116unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev); 117unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev); 118unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev); 119unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev); 120 121struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, 122 unsigned long freq, 123 bool available); 124 125struct dev_pm_opp * 126dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq, 127 u32 index, bool available); 128 129struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, 130 unsigned long *freq); 131 132struct dev_pm_opp *dev_pm_opp_find_freq_floor_indexed(struct device *dev, 133 unsigned long *freq, u32 index); 134 135struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, 136 unsigned long *freq); 137 138struct dev_pm_opp *dev_pm_opp_find_freq_ceil_indexed(struct device *dev, 139 unsigned long *freq, u32 index); 140 141struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev, 142 unsigned int level); 143 144struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev, 145 unsigned int *level); 146 147struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev, 148 unsigned int *bw, int index); 149 150struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev, 151 unsigned int *bw, int index); 152 153void dev_pm_opp_put(struct dev_pm_opp *opp); 154 155int dev_pm_opp_add(struct device *dev, unsigned long freq, 156 unsigned long u_volt); 157void dev_pm_opp_remove(struct device *dev, unsigned long freq); 158void dev_pm_opp_remove_all_dynamic(struct device *dev); 159 160int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq, 161 unsigned long u_volt, unsigned long u_volt_min, 162 unsigned long u_volt_max); 163 164int dev_pm_opp_enable(struct device *dev, unsigned long freq); 165 166int dev_pm_opp_disable(struct device *dev, unsigned long freq); 167 168int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb); 169int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb); 170 171int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); 172int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); 173void dev_pm_opp_clear_config(int token); 174int dev_pm_opp_config_clks_simple(struct device *dev, 175 struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, 176 bool scaling_down); 177 178struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, struct opp_table *dst_table, struct dev_pm_opp *src_opp); 179int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate); 180int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); 181int dev_pm_opp_set_opp(struct device *dev, struct dev_pm_opp *opp); 182int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask); 183int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); 184void dev_pm_opp_remove_table(struct device *dev); 185void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask); 186int dev_pm_opp_sync_regulators(struct device *dev); 187#else 188static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev) 189{ 190 return ERR_PTR(-EOPNOTSUPP); 191} 192 193static inline struct opp_table *dev_pm_opp_get_opp_table_indexed(struct device *dev, int index) 194{ 195 return ERR_PTR(-EOPNOTSUPP); 196} 197 198static inline void dev_pm_opp_put_opp_table(struct opp_table *opp_table) {} 199 200static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) 201{ 202 return 0; 203} 204 205static inline int dev_pm_opp_get_supplies(struct dev_pm_opp *opp, struct dev_pm_opp_supply *supplies) 206{ 207 return -EOPNOTSUPP; 208} 209 210static inline unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp) 211{ 212 return 0; 213} 214 215static inline unsigned long dev_pm_opp_get_freq_indexed(struct dev_pm_opp *opp, u32 index) 216{ 217 return 0; 218} 219 220static inline unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp) 221{ 222 return 0; 223} 224 225static inline 226unsigned int dev_pm_opp_get_required_pstate(struct dev_pm_opp *opp, 227 unsigned int index) 228{ 229 return 0; 230} 231 232static inline bool dev_pm_opp_is_turbo(struct dev_pm_opp *opp) 233{ 234 return false; 235} 236 237static inline int dev_pm_opp_get_opp_count(struct device *dev) 238{ 239 return 0; 240} 241 242static inline unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev) 243{ 244 return 0; 245} 246 247static inline unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) 248{ 249 return 0; 250} 251 252static inline unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev) 253{ 254 return 0; 255} 256 257static inline unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev) 258{ 259 return 0; 260} 261 262static inline struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, 263 unsigned long freq, bool available) 264{ 265 return ERR_PTR(-EOPNOTSUPP); 266} 267 268static inline struct dev_pm_opp * 269dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq, 270 u32 index, bool available) 271{ 272 return ERR_PTR(-EOPNOTSUPP); 273} 274 275static inline struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, 276 unsigned long *freq) 277{ 278 return ERR_PTR(-EOPNOTSUPP); 279} 280 281static inline struct dev_pm_opp * 282dev_pm_opp_find_freq_floor_indexed(struct device *dev, unsigned long *freq, u32 index) 283{ 284 return ERR_PTR(-EOPNOTSUPP); 285} 286 287static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, 288 unsigned long *freq) 289{ 290 return ERR_PTR(-EOPNOTSUPP); 291} 292 293static inline struct dev_pm_opp * 294dev_pm_opp_find_freq_ceil_indexed(struct device *dev, unsigned long *freq, u32 index) 295{ 296 return ERR_PTR(-EOPNOTSUPP); 297} 298 299static inline struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev, 300 unsigned int level) 301{ 302 return ERR_PTR(-EOPNOTSUPP); 303} 304 305static inline struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev, 306 unsigned int *level) 307{ 308 return ERR_PTR(-EOPNOTSUPP); 309} 310 311static inline struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev, 312 unsigned int *bw, int index) 313{ 314 return ERR_PTR(-EOPNOTSUPP); 315} 316 317static inline struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev, 318 unsigned int *bw, int index) 319{ 320 return ERR_PTR(-EOPNOTSUPP); 321} 322 323static inline void dev_pm_opp_put(struct dev_pm_opp *opp) {} 324 325static inline int dev_pm_opp_add(struct device *dev, unsigned long freq, 326 unsigned long u_volt) 327{ 328 return -EOPNOTSUPP; 329} 330 331static inline void dev_pm_opp_remove(struct device *dev, unsigned long freq) 332{ 333} 334 335static inline void dev_pm_opp_remove_all_dynamic(struct device *dev) 336{ 337} 338 339static inline int 340dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq, 341 unsigned long u_volt, unsigned long u_volt_min, 342 unsigned long u_volt_max) 343{ 344 return 0; 345} 346 347static inline int dev_pm_opp_enable(struct device *dev, unsigned long freq) 348{ 349 return 0; 350} 351 352static inline int dev_pm_opp_disable(struct device *dev, unsigned long freq) 353{ 354 return 0; 355} 356 357static inline int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb) 358{ 359 return -EOPNOTSUPP; 360} 361 362static inline int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb) 363{ 364 return -EOPNOTSUPP; 365} 366 367static inline int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) 368{ 369 return -EOPNOTSUPP; 370} 371 372static inline int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) 373{ 374 return -EOPNOTSUPP; 375} 376 377static inline void dev_pm_opp_clear_config(int token) {} 378 379static inline int dev_pm_opp_config_clks_simple(struct device *dev, 380 struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, 381 bool scaling_down) 382{ 383 return -EOPNOTSUPP; 384} 385 386static inline struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, 387 struct opp_table *dst_table, struct dev_pm_opp *src_opp) 388{ 389 return ERR_PTR(-EOPNOTSUPP); 390} 391 392static inline int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate) 393{ 394 return -EOPNOTSUPP; 395} 396 397static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) 398{ 399 return -EOPNOTSUPP; 400} 401 402static inline int dev_pm_opp_set_opp(struct device *dev, struct dev_pm_opp *opp) 403{ 404 return -EOPNOTSUPP; 405} 406 407static inline int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask) 408{ 409 return -EOPNOTSUPP; 410} 411 412static inline int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask) 413{ 414 return -EINVAL; 415} 416 417static inline void dev_pm_opp_remove_table(struct device *dev) 418{ 419} 420 421static inline void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask) 422{ 423} 424 425static inline int dev_pm_opp_sync_regulators(struct device *dev) 426{ 427 return -EOPNOTSUPP; 428} 429 430#endif /* CONFIG_PM_OPP */ 431 432#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) 433int dev_pm_opp_of_add_table(struct device *dev); 434int dev_pm_opp_of_add_table_indexed(struct device *dev, int index); 435int devm_pm_opp_of_add_table_indexed(struct device *dev, int index); 436void dev_pm_opp_of_remove_table(struct device *dev); 437int devm_pm_opp_of_add_table(struct device *dev); 438int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask); 439void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask); 440int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); 441struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev); 442struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp); 443int of_get_required_opp_performance_state(struct device_node *np, int index); 444int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_table *opp_table); 445int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus); 446static inline void dev_pm_opp_of_unregister_em(struct device *dev) 447{ 448 em_dev_unregister_perf_domain(dev); 449} 450#else 451static inline int dev_pm_opp_of_add_table(struct device *dev) 452{ 453 return -EOPNOTSUPP; 454} 455 456static inline int dev_pm_opp_of_add_table_indexed(struct device *dev, int index) 457{ 458 return -EOPNOTSUPP; 459} 460 461static inline int devm_pm_opp_of_add_table_indexed(struct device *dev, int index) 462{ 463 return -EOPNOTSUPP; 464} 465 466static inline void dev_pm_opp_of_remove_table(struct device *dev) 467{ 468} 469 470static inline int devm_pm_opp_of_add_table(struct device *dev) 471{ 472 return -EOPNOTSUPP; 473} 474 475static inline int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask) 476{ 477 return -EOPNOTSUPP; 478} 479 480static inline void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask) 481{ 482} 483 484static inline int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask) 485{ 486 return -EOPNOTSUPP; 487} 488 489static inline struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev) 490{ 491 return NULL; 492} 493 494static inline struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp) 495{ 496 return NULL; 497} 498 499static inline int dev_pm_opp_of_register_em(struct device *dev, 500 struct cpumask *cpus) 501{ 502 return -EOPNOTSUPP; 503} 504 505static inline void dev_pm_opp_of_unregister_em(struct device *dev) 506{ 507} 508 509static inline int of_get_required_opp_performance_state(struct device_node *np, int index) 510{ 511 return -EOPNOTSUPP; 512} 513 514static inline int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_table *opp_table) 515{ 516 return -EOPNOTSUPP; 517} 518#endif 519 520/* OPP Configuration helpers */ 521 522/* Regulators helpers */ 523static inline int dev_pm_opp_set_regulators(struct device *dev, 524 const char * const names[]) 525{ 526 struct dev_pm_opp_config config = { 527 .regulator_names = names, 528 }; 529 530 return dev_pm_opp_set_config(dev, &config); 531} 532 533static inline void dev_pm_opp_put_regulators(int token) 534{ 535 dev_pm_opp_clear_config(token); 536} 537 538static inline int devm_pm_opp_set_regulators(struct device *dev, 539 const char * const names[]) 540{ 541 struct dev_pm_opp_config config = { 542 .regulator_names = names, 543 }; 544 545 return devm_pm_opp_set_config(dev, &config); 546} 547 548/* Supported-hw helpers */ 549static inline int dev_pm_opp_set_supported_hw(struct device *dev, 550 const u32 *versions, 551 unsigned int count) 552{ 553 struct dev_pm_opp_config config = { 554 .supported_hw = versions, 555 .supported_hw_count = count, 556 }; 557 558 return dev_pm_opp_set_config(dev, &config); 559} 560 561static inline void dev_pm_opp_put_supported_hw(int token) 562{ 563 dev_pm_opp_clear_config(token); 564} 565 566static inline int devm_pm_opp_set_supported_hw(struct device *dev, 567 const u32 *versions, 568 unsigned int count) 569{ 570 struct dev_pm_opp_config config = { 571 .supported_hw = versions, 572 .supported_hw_count = count, 573 }; 574 575 return devm_pm_opp_set_config(dev, &config); 576} 577 578/* clkname helpers */ 579static inline int dev_pm_opp_set_clkname(struct device *dev, const char *name) 580{ 581 const char *names[] = { name, NULL }; 582 struct dev_pm_opp_config config = { 583 .clk_names = names, 584 }; 585 586 return dev_pm_opp_set_config(dev, &config); 587} 588 589static inline void dev_pm_opp_put_clkname(int token) 590{ 591 dev_pm_opp_clear_config(token); 592} 593 594static inline int devm_pm_opp_set_clkname(struct device *dev, const char *name) 595{ 596 const char *names[] = { name, NULL }; 597 struct dev_pm_opp_config config = { 598 .clk_names = names, 599 }; 600 601 return devm_pm_opp_set_config(dev, &config); 602} 603 604/* config-regulators helpers */ 605static inline int dev_pm_opp_set_config_regulators(struct device *dev, 606 config_regulators_t helper) 607{ 608 struct dev_pm_opp_config config = { 609 .config_regulators = helper, 610 }; 611 612 return dev_pm_opp_set_config(dev, &config); 613} 614 615static inline void dev_pm_opp_put_config_regulators(int token) 616{ 617 dev_pm_opp_clear_config(token); 618} 619 620/* genpd helpers */ 621static inline int dev_pm_opp_attach_genpd(struct device *dev, 622 const char * const *names, 623 struct device ***virt_devs) 624{ 625 struct dev_pm_opp_config config = { 626 .genpd_names = names, 627 .virt_devs = virt_devs, 628 }; 629 630 return dev_pm_opp_set_config(dev, &config); 631} 632 633static inline void dev_pm_opp_detach_genpd(int token) 634{ 635 dev_pm_opp_clear_config(token); 636} 637 638static inline int devm_pm_opp_attach_genpd(struct device *dev, 639 const char * const *names, 640 struct device ***virt_devs) 641{ 642 struct dev_pm_opp_config config = { 643 .genpd_names = names, 644 .virt_devs = virt_devs, 645 }; 646 647 return devm_pm_opp_set_config(dev, &config); 648} 649 650/* prop-name helpers */ 651static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name) 652{ 653 struct dev_pm_opp_config config = { 654 .prop_name = name, 655 }; 656 657 return dev_pm_opp_set_config(dev, &config); 658} 659 660static inline void dev_pm_opp_put_prop_name(int token) 661{ 662 dev_pm_opp_clear_config(token); 663} 664 665static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp) 666{ 667 return dev_pm_opp_get_freq_indexed(opp, 0); 668} 669 670#endif /* __LINUX_OPP_H__ */