Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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__ */