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