blob: b8197ab014f296c07fa5775325f3587af0784324 [file] [log] [blame]
David Brazdil0f672f62019-12-10 10:32:29 +00001/* SPDX-License-Identifier: GPL-2.0-only */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002/*
3 * Generic OPP Interface
4 *
5 * Copyright (C) 2009-2010 Texas Instruments Incorporated.
6 * Nishanth Menon
7 * Romit Dasgupta
8 * Kevin Hilman
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009 */
10
11#ifndef __LINUX_OPP_H__
12#define __LINUX_OPP_H__
13
14#include <linux/err.h>
15#include <linux/notifier.h>
16
17struct clk;
18struct regulator;
19struct dev_pm_opp;
20struct device;
21struct opp_table;
22
23enum dev_pm_opp_event {
24 OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE,
25};
26
27/**
28 * struct dev_pm_opp_supply - Power supply voltage/current values
29 * @u_volt: Target voltage in microvolts corresponding to this OPP
30 * @u_volt_min: Minimum voltage in microvolts corresponding to this OPP
31 * @u_volt_max: Maximum voltage in microvolts corresponding to this OPP
32 * @u_amp: Maximum current drawn by the device in microamperes
33 *
34 * This structure stores the voltage/current values for a single power supply.
35 */
36struct dev_pm_opp_supply {
37 unsigned long u_volt;
38 unsigned long u_volt_min;
39 unsigned long u_volt_max;
40 unsigned long u_amp;
41};
42
43/**
44 * struct dev_pm_opp_info - OPP freq/voltage/current values
45 * @rate: Target clk rate in hz
46 * @supplies: Array of voltage/current values for all power supplies
47 *
48 * This structure stores the freq/voltage/current values for a single OPP.
49 */
50struct dev_pm_opp_info {
51 unsigned long rate;
52 struct dev_pm_opp_supply *supplies;
53};
54
55/**
56 * struct dev_pm_set_opp_data - Set OPP data
57 * @old_opp: Old OPP info
58 * @new_opp: New OPP info
59 * @regulators: Array of regulator pointers
60 * @regulator_count: Number of regulators
61 * @clk: Pointer to clk
62 * @dev: Pointer to the struct device
63 *
64 * This structure contains all information required for setting an OPP.
65 */
66struct dev_pm_set_opp_data {
67 struct dev_pm_opp_info old_opp;
68 struct dev_pm_opp_info new_opp;
69
70 struct regulator **regulators;
71 unsigned int regulator_count;
72 struct clk *clk;
73 struct device *dev;
74};
75
76#if defined(CONFIG_PM_OPP)
77
78struct opp_table *dev_pm_opp_get_opp_table(struct device *dev);
David Brazdil0f672f62019-12-10 10:32:29 +000079struct opp_table *dev_pm_opp_get_opp_table_indexed(struct device *dev, int index);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000080void dev_pm_opp_put_opp_table(struct opp_table *opp_table);
81
82unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp);
83
84unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp);
85
David Brazdil0f672f62019-12-10 10:32:29 +000086unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp);
87
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000088bool dev_pm_opp_is_turbo(struct dev_pm_opp *opp);
89
90int dev_pm_opp_get_opp_count(struct device *dev);
91unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev);
92unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev);
93unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev);
94unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev);
95
96struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev,
97 unsigned long freq,
98 bool available);
David Brazdil0f672f62019-12-10 10:32:29 +000099struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev,
100 unsigned int level);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000101
102struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev,
103 unsigned long *freq);
David Brazdil0f672f62019-12-10 10:32:29 +0000104struct dev_pm_opp *dev_pm_opp_find_freq_ceil_by_volt(struct device *dev,
105 unsigned long u_volt);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000106
107struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev,
108 unsigned long *freq);
109void dev_pm_opp_put(struct dev_pm_opp *opp);
110
111int dev_pm_opp_add(struct device *dev, unsigned long freq,
112 unsigned long u_volt);
113void dev_pm_opp_remove(struct device *dev, unsigned long freq);
David Brazdil0f672f62019-12-10 10:32:29 +0000114void dev_pm_opp_remove_all_dynamic(struct device *dev);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000115
116int dev_pm_opp_enable(struct device *dev, unsigned long freq);
117
118int dev_pm_opp_disable(struct device *dev, unsigned long freq);
119
120int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb);
121int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb);
122
123struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, unsigned int count);
124void dev_pm_opp_put_supported_hw(struct opp_table *opp_table);
125struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name);
126void dev_pm_opp_put_prop_name(struct opp_table *opp_table);
127struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count);
128void dev_pm_opp_put_regulators(struct opp_table *opp_table);
129struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char * name);
130void dev_pm_opp_put_clkname(struct opp_table *opp_table);
131struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
132void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table);
David Brazdil0f672f62019-12-10 10:32:29 +0000133struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs);
134void dev_pm_opp_detach_genpd(struct opp_table *opp_table);
135int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000136int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
137int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
138int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
139void dev_pm_opp_remove_table(struct device *dev);
140void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask);
141#else
142static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev)
143{
144 return ERR_PTR(-ENOTSUPP);
145}
146
David Brazdil0f672f62019-12-10 10:32:29 +0000147static inline struct opp_table *dev_pm_opp_get_opp_table_indexed(struct device *dev, int index)
148{
149 return ERR_PTR(-ENOTSUPP);
150}
151
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000152static inline void dev_pm_opp_put_opp_table(struct opp_table *opp_table) {}
153
154static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
155{
156 return 0;
157}
158
159static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp)
160{
161 return 0;
162}
163
David Brazdil0f672f62019-12-10 10:32:29 +0000164static inline unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp)
165{
166 return 0;
167}
168
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000169static inline bool dev_pm_opp_is_turbo(struct dev_pm_opp *opp)
170{
171 return false;
172}
173
174static inline int dev_pm_opp_get_opp_count(struct device *dev)
175{
176 return 0;
177}
178
179static inline unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev)
180{
181 return 0;
182}
183
184static inline unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev)
185{
186 return 0;
187}
188
189static inline unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev)
190{
191 return 0;
192}
193
194static inline unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev)
195{
196 return 0;
197}
198
199static inline struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev,
200 unsigned long freq, bool available)
201{
202 return ERR_PTR(-ENOTSUPP);
203}
204
David Brazdil0f672f62019-12-10 10:32:29 +0000205static inline struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev,
206 unsigned int level)
207{
208 return ERR_PTR(-ENOTSUPP);
209}
210
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000211static inline struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev,
212 unsigned long *freq)
213{
214 return ERR_PTR(-ENOTSUPP);
215}
216
David Brazdil0f672f62019-12-10 10:32:29 +0000217static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil_by_volt(struct device *dev,
218 unsigned long u_volt)
219{
220 return ERR_PTR(-ENOTSUPP);
221}
222
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000223static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev,
224 unsigned long *freq)
225{
226 return ERR_PTR(-ENOTSUPP);
227}
228
229static inline void dev_pm_opp_put(struct dev_pm_opp *opp) {}
230
231static inline int dev_pm_opp_add(struct device *dev, unsigned long freq,
232 unsigned long u_volt)
233{
234 return -ENOTSUPP;
235}
236
237static inline void dev_pm_opp_remove(struct device *dev, unsigned long freq)
238{
239}
240
David Brazdil0f672f62019-12-10 10:32:29 +0000241static inline void dev_pm_opp_remove_all_dynamic(struct device *dev)
242{
243}
244
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000245static inline int dev_pm_opp_enable(struct device *dev, unsigned long freq)
246{
247 return 0;
248}
249
250static inline int dev_pm_opp_disable(struct device *dev, unsigned long freq)
251{
252 return 0;
253}
254
255static inline int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb)
256{
257 return -ENOTSUPP;
258}
259
260static inline int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb)
261{
262 return -ENOTSUPP;
263}
264
265static inline struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev,
266 const u32 *versions,
267 unsigned int count)
268{
269 return ERR_PTR(-ENOTSUPP);
270}
271
272static inline void dev_pm_opp_put_supported_hw(struct opp_table *opp_table) {}
273
274static inline struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev,
275 int (*set_opp)(struct dev_pm_set_opp_data *data))
276{
277 return ERR_PTR(-ENOTSUPP);
278}
279
280static inline void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) {}
281
282static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name)
283{
284 return ERR_PTR(-ENOTSUPP);
285}
286
287static inline void dev_pm_opp_put_prop_name(struct opp_table *opp_table) {}
288
289static inline struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count)
290{
291 return ERR_PTR(-ENOTSUPP);
292}
293
294static inline void dev_pm_opp_put_regulators(struct opp_table *opp_table) {}
295
296static inline struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char * name)
297{
298 return ERR_PTR(-ENOTSUPP);
299}
300
301static inline void dev_pm_opp_put_clkname(struct opp_table *opp_table) {}
302
David Brazdil0f672f62019-12-10 10:32:29 +0000303static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs)
304{
305 return ERR_PTR(-ENOTSUPP);
306}
307
308static inline void dev_pm_opp_detach_genpd(struct opp_table *opp_table) {}
309
310static inline int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate)
311{
312 return -ENOTSUPP;
313}
314
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000315static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
316{
317 return -ENOTSUPP;
318}
319
320static inline int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask)
321{
322 return -ENOTSUPP;
323}
324
325static inline int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
326{
327 return -EINVAL;
328}
329
330static inline void dev_pm_opp_remove_table(struct device *dev)
331{
332}
333
334static inline void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask)
335{
336}
337
338#endif /* CONFIG_PM_OPP */
339
340#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)
341int dev_pm_opp_of_add_table(struct device *dev);
342int dev_pm_opp_of_add_table_indexed(struct device *dev, int index);
343void dev_pm_opp_of_remove_table(struct device *dev);
344int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask);
345void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask);
346int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
347struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000348struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp);
David Brazdil0f672f62019-12-10 10:32:29 +0000349int of_get_required_opp_performance_state(struct device_node *np, int index);
350void dev_pm_opp_of_register_em(struct cpumask *cpus);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000351#else
352static inline int dev_pm_opp_of_add_table(struct device *dev)
353{
354 return -ENOTSUPP;
355}
356
357static inline int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
358{
359 return -ENOTSUPP;
360}
361
362static inline void dev_pm_opp_of_remove_table(struct device *dev)
363{
364}
365
366static inline int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask)
367{
368 return -ENOTSUPP;
369}
370
371static inline void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask)
372{
373}
374
375static inline int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
376{
377 return -ENOTSUPP;
378}
379
380static inline struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev)
381{
382 return NULL;
383}
384
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000385static inline struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp)
386{
387 return NULL;
388}
David Brazdil0f672f62019-12-10 10:32:29 +0000389
390static inline void dev_pm_opp_of_register_em(struct cpumask *cpus)
391{
392}
393
394static inline int of_get_required_opp_performance_state(struct device_node *np, int index)
395{
396 return -ENOTSUPP;
397}
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000398#endif
399
400#endif /* __LINUX_OPP_H__ */