at v6.7 19 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/** 96 * struct dev_pm_opp_data - The data to use to initialize an OPP. 97 * @level: The performance level for the OPP. 98 * @freq: The clock rate in Hz for the OPP. 99 * @u_volt: The voltage in uV for the OPP. 100 */ 101struct dev_pm_opp_data { 102 unsigned int level; 103 unsigned long freq; 104 unsigned long u_volt; 105}; 106 107#if defined(CONFIG_PM_OPP) 108 109struct opp_table *dev_pm_opp_get_opp_table(struct device *dev); 110void dev_pm_opp_put_opp_table(struct opp_table *opp_table); 111 112unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp); 113 114int dev_pm_opp_get_supplies(struct dev_pm_opp *opp, struct dev_pm_opp_supply *supplies); 115 116unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp); 117 118unsigned long dev_pm_opp_get_freq_indexed(struct dev_pm_opp *opp, u32 index); 119 120unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp); 121 122unsigned int dev_pm_opp_get_required_pstate(struct dev_pm_opp *opp, 123 unsigned int index); 124 125bool dev_pm_opp_is_turbo(struct dev_pm_opp *opp); 126 127int dev_pm_opp_get_opp_count(struct device *dev); 128unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev); 129unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev); 130unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev); 131unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev); 132 133struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, 134 unsigned long freq, 135 bool available); 136 137struct dev_pm_opp * 138dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq, 139 u32 index, bool available); 140 141struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, 142 unsigned long *freq); 143 144struct dev_pm_opp *dev_pm_opp_find_freq_floor_indexed(struct device *dev, 145 unsigned long *freq, u32 index); 146 147struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, 148 unsigned long *freq); 149 150struct dev_pm_opp *dev_pm_opp_find_freq_ceil_indexed(struct device *dev, 151 unsigned long *freq, u32 index); 152 153struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev, 154 unsigned int level); 155 156struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev, 157 unsigned int *level); 158 159struct dev_pm_opp *dev_pm_opp_find_level_floor(struct device *dev, 160 unsigned long *level); 161 162struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev, 163 unsigned int *bw, int index); 164 165struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev, 166 unsigned int *bw, int index); 167 168void dev_pm_opp_put(struct dev_pm_opp *opp); 169 170int dev_pm_opp_add_dynamic(struct device *dev, struct dev_pm_opp_data *opp); 171 172void dev_pm_opp_remove(struct device *dev, unsigned long freq); 173void dev_pm_opp_remove_all_dynamic(struct device *dev); 174 175int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq, 176 unsigned long u_volt, unsigned long u_volt_min, 177 unsigned long u_volt_max); 178 179int dev_pm_opp_enable(struct device *dev, unsigned long freq); 180 181int dev_pm_opp_disable(struct device *dev, unsigned long freq); 182 183int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb); 184int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb); 185 186int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); 187int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); 188void dev_pm_opp_clear_config(int token); 189int dev_pm_opp_config_clks_simple(struct device *dev, 190 struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, 191 bool scaling_down); 192 193struct 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); 194int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate); 195int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); 196int dev_pm_opp_set_opp(struct device *dev, struct dev_pm_opp *opp); 197int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask); 198int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); 199void dev_pm_opp_remove_table(struct device *dev); 200void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask); 201int dev_pm_opp_sync_regulators(struct device *dev); 202#else 203static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev) 204{ 205 return ERR_PTR(-EOPNOTSUPP); 206} 207 208static inline struct opp_table *dev_pm_opp_get_opp_table_indexed(struct device *dev, int index) 209{ 210 return ERR_PTR(-EOPNOTSUPP); 211} 212 213static inline void dev_pm_opp_put_opp_table(struct opp_table *opp_table) {} 214 215static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) 216{ 217 return 0; 218} 219 220static inline int dev_pm_opp_get_supplies(struct dev_pm_opp *opp, struct dev_pm_opp_supply *supplies) 221{ 222 return -EOPNOTSUPP; 223} 224 225static inline unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp) 226{ 227 return 0; 228} 229 230static inline unsigned long dev_pm_opp_get_freq_indexed(struct dev_pm_opp *opp, u32 index) 231{ 232 return 0; 233} 234 235static inline unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp) 236{ 237 return 0; 238} 239 240static inline 241unsigned int dev_pm_opp_get_required_pstate(struct dev_pm_opp *opp, 242 unsigned int index) 243{ 244 return 0; 245} 246 247static inline bool dev_pm_opp_is_turbo(struct dev_pm_opp *opp) 248{ 249 return false; 250} 251 252static inline int dev_pm_opp_get_opp_count(struct device *dev) 253{ 254 return 0; 255} 256 257static inline unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev) 258{ 259 return 0; 260} 261 262static inline unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) 263{ 264 return 0; 265} 266 267static inline unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev) 268{ 269 return 0; 270} 271 272static inline unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev) 273{ 274 return 0; 275} 276 277static inline struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, 278 unsigned long freq, bool available) 279{ 280 return ERR_PTR(-EOPNOTSUPP); 281} 282 283static inline struct dev_pm_opp * 284dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq, 285 u32 index, bool available) 286{ 287 return ERR_PTR(-EOPNOTSUPP); 288} 289 290static inline struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, 291 unsigned long *freq) 292{ 293 return ERR_PTR(-EOPNOTSUPP); 294} 295 296static inline struct dev_pm_opp * 297dev_pm_opp_find_freq_floor_indexed(struct device *dev, unsigned long *freq, u32 index) 298{ 299 return ERR_PTR(-EOPNOTSUPP); 300} 301 302static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, 303 unsigned long *freq) 304{ 305 return ERR_PTR(-EOPNOTSUPP); 306} 307 308static inline struct dev_pm_opp * 309dev_pm_opp_find_freq_ceil_indexed(struct device *dev, unsigned long *freq, u32 index) 310{ 311 return ERR_PTR(-EOPNOTSUPP); 312} 313 314static inline struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev, 315 unsigned int level) 316{ 317 return ERR_PTR(-EOPNOTSUPP); 318} 319 320static inline struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev, 321 unsigned int *level) 322{ 323 return ERR_PTR(-EOPNOTSUPP); 324} 325 326static inline struct dev_pm_opp *dev_pm_opp_find_level_floor(struct device *dev, 327 unsigned long *level) 328{ 329 return ERR_PTR(-EOPNOTSUPP); 330} 331 332static inline struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev, 333 unsigned int *bw, int index) 334{ 335 return ERR_PTR(-EOPNOTSUPP); 336} 337 338static inline struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev, 339 unsigned int *bw, int index) 340{ 341 return ERR_PTR(-EOPNOTSUPP); 342} 343 344static inline void dev_pm_opp_put(struct dev_pm_opp *opp) {} 345 346static inline int 347dev_pm_opp_add_dynamic(struct device *dev, struct dev_pm_opp_data *opp) 348{ 349 return -EOPNOTSUPP; 350} 351 352static inline void dev_pm_opp_remove(struct device *dev, unsigned long freq) 353{ 354} 355 356static inline void dev_pm_opp_remove_all_dynamic(struct device *dev) 357{ 358} 359 360static inline int 361dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq, 362 unsigned long u_volt, unsigned long u_volt_min, 363 unsigned long u_volt_max) 364{ 365 return 0; 366} 367 368static inline int dev_pm_opp_enable(struct device *dev, unsigned long freq) 369{ 370 return 0; 371} 372 373static inline int dev_pm_opp_disable(struct device *dev, unsigned long freq) 374{ 375 return 0; 376} 377 378static inline int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb) 379{ 380 return -EOPNOTSUPP; 381} 382 383static inline int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb) 384{ 385 return -EOPNOTSUPP; 386} 387 388static inline int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) 389{ 390 return -EOPNOTSUPP; 391} 392 393static inline int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) 394{ 395 return -EOPNOTSUPP; 396} 397 398static inline void dev_pm_opp_clear_config(int token) {} 399 400static inline int dev_pm_opp_config_clks_simple(struct device *dev, 401 struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, 402 bool scaling_down) 403{ 404 return -EOPNOTSUPP; 405} 406 407static inline struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, 408 struct opp_table *dst_table, struct dev_pm_opp *src_opp) 409{ 410 return ERR_PTR(-EOPNOTSUPP); 411} 412 413static inline int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate) 414{ 415 return -EOPNOTSUPP; 416} 417 418static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) 419{ 420 return -EOPNOTSUPP; 421} 422 423static inline int dev_pm_opp_set_opp(struct device *dev, struct dev_pm_opp *opp) 424{ 425 return -EOPNOTSUPP; 426} 427 428static inline int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask) 429{ 430 return -EOPNOTSUPP; 431} 432 433static inline int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask) 434{ 435 return -EINVAL; 436} 437 438static inline void dev_pm_opp_remove_table(struct device *dev) 439{ 440} 441 442static inline void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask) 443{ 444} 445 446static inline int dev_pm_opp_sync_regulators(struct device *dev) 447{ 448 return -EOPNOTSUPP; 449} 450 451#endif /* CONFIG_PM_OPP */ 452 453#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) 454int dev_pm_opp_of_add_table(struct device *dev); 455int dev_pm_opp_of_add_table_indexed(struct device *dev, int index); 456int devm_pm_opp_of_add_table_indexed(struct device *dev, int index); 457void dev_pm_opp_of_remove_table(struct device *dev); 458int devm_pm_opp_of_add_table(struct device *dev); 459int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask); 460void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask); 461int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); 462struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev); 463struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp); 464int of_get_required_opp_performance_state(struct device_node *np, int index); 465int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_table *opp_table); 466int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus); 467static inline void dev_pm_opp_of_unregister_em(struct device *dev) 468{ 469 em_dev_unregister_perf_domain(dev); 470} 471#else 472static inline int dev_pm_opp_of_add_table(struct device *dev) 473{ 474 return -EOPNOTSUPP; 475} 476 477static inline int dev_pm_opp_of_add_table_indexed(struct device *dev, int index) 478{ 479 return -EOPNOTSUPP; 480} 481 482static inline int devm_pm_opp_of_add_table_indexed(struct device *dev, int index) 483{ 484 return -EOPNOTSUPP; 485} 486 487static inline void dev_pm_opp_of_remove_table(struct device *dev) 488{ 489} 490 491static inline int devm_pm_opp_of_add_table(struct device *dev) 492{ 493 return -EOPNOTSUPP; 494} 495 496static inline int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask) 497{ 498 return -EOPNOTSUPP; 499} 500 501static inline void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask) 502{ 503} 504 505static inline int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask) 506{ 507 return -EOPNOTSUPP; 508} 509 510static inline struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev) 511{ 512 return NULL; 513} 514 515static inline struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp) 516{ 517 return NULL; 518} 519 520static inline int dev_pm_opp_of_register_em(struct device *dev, 521 struct cpumask *cpus) 522{ 523 return -EOPNOTSUPP; 524} 525 526static inline void dev_pm_opp_of_unregister_em(struct device *dev) 527{ 528} 529 530static inline int of_get_required_opp_performance_state(struct device_node *np, int index) 531{ 532 return -EOPNOTSUPP; 533} 534 535static inline int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_table *opp_table) 536{ 537 return -EOPNOTSUPP; 538} 539#endif 540 541/* OPP Configuration helpers */ 542 543static inline int dev_pm_opp_add(struct device *dev, unsigned long freq, 544 unsigned long u_volt) 545{ 546 struct dev_pm_opp_data data = { 547 .freq = freq, 548 .u_volt = u_volt, 549 }; 550 551 return dev_pm_opp_add_dynamic(dev, &data); 552} 553 554/* Regulators helpers */ 555static inline int dev_pm_opp_set_regulators(struct device *dev, 556 const char * const names[]) 557{ 558 struct dev_pm_opp_config config = { 559 .regulator_names = names, 560 }; 561 562 return dev_pm_opp_set_config(dev, &config); 563} 564 565static inline void dev_pm_opp_put_regulators(int token) 566{ 567 dev_pm_opp_clear_config(token); 568} 569 570static inline int devm_pm_opp_set_regulators(struct device *dev, 571 const char * const names[]) 572{ 573 struct dev_pm_opp_config config = { 574 .regulator_names = names, 575 }; 576 577 return devm_pm_opp_set_config(dev, &config); 578} 579 580/* Supported-hw helpers */ 581static inline int dev_pm_opp_set_supported_hw(struct device *dev, 582 const u32 *versions, 583 unsigned int count) 584{ 585 struct dev_pm_opp_config config = { 586 .supported_hw = versions, 587 .supported_hw_count = count, 588 }; 589 590 return dev_pm_opp_set_config(dev, &config); 591} 592 593static inline void dev_pm_opp_put_supported_hw(int token) 594{ 595 dev_pm_opp_clear_config(token); 596} 597 598static inline int devm_pm_opp_set_supported_hw(struct device *dev, 599 const u32 *versions, 600 unsigned int count) 601{ 602 struct dev_pm_opp_config config = { 603 .supported_hw = versions, 604 .supported_hw_count = count, 605 }; 606 607 return devm_pm_opp_set_config(dev, &config); 608} 609 610/* clkname helpers */ 611static inline int dev_pm_opp_set_clkname(struct device *dev, const char *name) 612{ 613 const char *names[] = { name, NULL }; 614 struct dev_pm_opp_config config = { 615 .clk_names = names, 616 }; 617 618 return dev_pm_opp_set_config(dev, &config); 619} 620 621static inline void dev_pm_opp_put_clkname(int token) 622{ 623 dev_pm_opp_clear_config(token); 624} 625 626static inline int devm_pm_opp_set_clkname(struct device *dev, const char *name) 627{ 628 const char *names[] = { name, NULL }; 629 struct dev_pm_opp_config config = { 630 .clk_names = names, 631 }; 632 633 return devm_pm_opp_set_config(dev, &config); 634} 635 636/* config-regulators helpers */ 637static inline int dev_pm_opp_set_config_regulators(struct device *dev, 638 config_regulators_t helper) 639{ 640 struct dev_pm_opp_config config = { 641 .config_regulators = helper, 642 }; 643 644 return dev_pm_opp_set_config(dev, &config); 645} 646 647static inline void dev_pm_opp_put_config_regulators(int token) 648{ 649 dev_pm_opp_clear_config(token); 650} 651 652/* genpd helpers */ 653static inline int dev_pm_opp_attach_genpd(struct device *dev, 654 const char * const *names, 655 struct device ***virt_devs) 656{ 657 struct dev_pm_opp_config config = { 658 .genpd_names = names, 659 .virt_devs = virt_devs, 660 }; 661 662 return dev_pm_opp_set_config(dev, &config); 663} 664 665static inline void dev_pm_opp_detach_genpd(int token) 666{ 667 dev_pm_opp_clear_config(token); 668} 669 670static inline int devm_pm_opp_attach_genpd(struct device *dev, 671 const char * const *names, 672 struct device ***virt_devs) 673{ 674 struct dev_pm_opp_config config = { 675 .genpd_names = names, 676 .virt_devs = virt_devs, 677 }; 678 679 return devm_pm_opp_set_config(dev, &config); 680} 681 682/* prop-name helpers */ 683static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name) 684{ 685 struct dev_pm_opp_config config = { 686 .prop_name = name, 687 }; 688 689 return dev_pm_opp_set_config(dev, &config); 690} 691 692static inline void dev_pm_opp_put_prop_name(int token) 693{ 694 dev_pm_opp_clear_config(token); 695} 696 697static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp) 698{ 699 return dev_pm_opp_get_freq_indexed(opp, 0); 700} 701 702#endif /* __LINUX_OPP_H__ */