a3714977c60fa1c96df11534264b5761e8c1bac6
[linux-3.10.git] / arch / arm / mach-tegra / dvfs.h
1 /*
2  *
3  * Copyright (C) 2010 Google, Inc.
4  *
5  * Author:
6  *      Colin Cross <ccross@google.com>
7  *
8  * Copyright (C) 2010-2012 NVIDIA CORPORATION. All rights reserved.
9  *
10  * This software is licensed under the terms of the GNU General Public
11  * License version 2, as published by the Free Software Foundation, and
12  * may be copied, distributed, and modified under those terms.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  */
20
21 #ifndef _TEGRA_DVFS_H_
22 #define _TEGRA_DVFS_H_
23
24 #include <linux/of.h>
25 #include <mach/thermal.h>
26
27 #define MAX_DVFS_FREQS  40
28 #define MAX_DVFS_TABLES 80
29 #define DVFS_RAIL_STATS_TOP_BIN 60
30
31 struct clk;
32 struct dvfs_rail;
33
34 /*
35  * dvfs_relationship between to rails, "from" and "to"
36  * when the rail changes, it will call dvfs_rail_update on the rails
37  * in the relationship_to list.
38  * when determining the voltage to set a rail to, it will consider each
39  * rail in the relationship_from list.
40  */
41 struct dvfs_relationship {
42         struct dvfs_rail *to;
43         struct dvfs_rail *from;
44         int (*solve)(struct dvfs_rail *, struct dvfs_rail *);
45
46         struct list_head to_node; /* node in relationship_to list */
47         struct list_head from_node; /* node in relationship_from list */
48         bool solved_at_nominal;
49 };
50
51 struct rail_stats {
52         ktime_t time_at_mv[DVFS_RAIL_STATS_TOP_BIN + 1];
53         ktime_t last_update;
54         int last_index;
55         bool off;
56         int bin_uV;
57 };
58
59 struct dvfs_rail {
60         const char *reg_id;
61         int min_millivolts;
62         int max_millivolts;
63         int reg_max_millivolts;
64         int nominal_millivolts;
65         int min_millivolts_cold;
66
67         int step;
68         bool jmp_to_zero;
69         bool disabled;
70         bool updating;
71         bool resolving_to;
72
73         struct list_head node;  /* node in dvfs_rail_list */
74         struct list_head dvfs;  /* list head of attached dvfs clocks */
75         struct list_head relationships_to;
76         struct list_head relationships_from;
77         struct regulator *reg;
78         int millivolts;
79         int new_millivolts;
80         int offs_millivolts;
81         bool suspended;
82         bool dfll_mode;
83         bool dfll_mode_updating;
84         int thermal_idx;
85         struct tegra_cooling_device *pll_mode_cdev;
86         struct tegra_cooling_device *dfll_mode_cdev;
87         struct rail_stats stats;
88 };
89
90 enum dfll_range {
91         DFLL_RANGE_NONE = 0,
92         DFLL_RANGE_ALL_RATES,
93         DFLL_RANGE_HIGH_RATES,
94 };
95
96 struct dvfs_dfll_data {
97         u32             tune0;
98         u32             tune0_high_mv;
99         u32             tune1;
100         unsigned long   droop_rate_min;
101         unsigned long   use_dfll_rate_min;
102         unsigned long   out_rate_min;
103         unsigned long   max_rate_boost;
104         int tune_high_min_millivolts;
105         int min_millivolts;
106         enum dfll_range range;
107         void (*tune_trimmers)(bool trim_high);
108 };
109
110 struct dvfs {
111         /* Used only by tegra2_clock.c */
112         const char *clk_name;
113         int speedo_id;
114         int process_id;
115
116         /* Must be initialized before tegra_dvfs_init */
117         int freqs_mult;
118         unsigned long freqs[MAX_DVFS_FREQS];
119         unsigned long *alt_freqs;
120         const int *millivolts;
121         const int *dfll_millivolts;
122         struct dvfs_rail *dvfs_rail;
123         bool auto_dvfs;
124
125         /* Filled in by tegra_dvfs_init */
126         int max_millivolts;
127         int num_freqs;
128         struct dvfs_dfll_data dfll_data;
129
130         int cur_millivolts;
131         unsigned long cur_rate;
132         struct list_head node;
133         struct list_head debug_node;
134         struct list_head reg_node;
135 };
136
137 struct cpu_cvb_dvfs_parameters {
138         int     c0;
139         int     c1;
140         int     c2;
141 };
142
143 struct cpu_cvb_dvfs_table {
144         unsigned long freq;
145         struct cpu_cvb_dvfs_parameters cvb_dfll_param;
146         struct cpu_cvb_dvfs_parameters cvb_pll_param;
147 };
148
149 struct cpu_cvb_dvfs {
150         int speedo_id;
151         int process_id;
152
153         struct dvfs_dfll_data dfll_tune_data;
154         int max_mv;
155         int freqs_mult;
156         int speedo_scale;
157         int voltage_scale;
158         struct cpu_cvb_dvfs_table cvb_table[MAX_DVFS_FREQS];
159 };
160
161 extern struct dvfs_rail *tegra_cpu_rail;
162 extern struct dvfs_rail *tegra_core_rail;
163
164 struct dvfs_data {
165         struct dvfs_rail *rail;
166         struct dvfs *tables;
167         int *millivolts;
168         unsigned int num_tables;
169         unsigned int num_voltages;
170 };
171
172 struct core_dvfs_cap_table {
173         const char *cap_name;
174         struct clk *cap_clk;
175         unsigned long freqs[MAX_DVFS_FREQS];
176 };
177
178 struct core_bus_cap_table {
179         const char *cap_name;
180         struct clk *cap_clk;
181         struct kobj_attribute refcnt_attr;
182         struct kobj_attribute level_attr;
183         int refcnt;
184         int level;
185 };
186
187 #ifdef CONFIG_OF
188 typedef int (*of_tegra_dvfs_init_cb_t)(struct device_node *);
189 int of_tegra_dvfs_init(const struct of_device_id *matches);
190 #else
191 static inline int of_tegra_dvfs_init(const struct of_device_id *matches)
192 { return -ENODATA; }
193 #endif
194
195 void tegra11x_init_dvfs(void);
196 void tegra14x_init_dvfs(void);
197 int tegra_enable_dvfs_on_clk(struct clk *c, struct dvfs *d);
198 int dvfs_debugfs_init(struct dentry *clk_debugfs_root);
199 int tegra_dvfs_late_init(void);
200 int tegra_dvfs_init_rails(struct dvfs_rail *dvfs_rails[], int n);
201 void tegra_dvfs_add_relationships(struct dvfs_relationship *rels, int n);
202 void tegra_dvfs_rail_enable(struct dvfs_rail *rail);
203 void tegra_dvfs_rail_disable(struct dvfs_rail *rail);
204 bool tegra_dvfs_rail_updating(struct clk *clk);
205 void tegra_dvfs_rail_off(struct dvfs_rail *rail, ktime_t now);
206 void tegra_dvfs_rail_on(struct dvfs_rail *rail, ktime_t now);
207 void tegra_dvfs_rail_pause(struct dvfs_rail *rail, ktime_t delta, bool on);
208 struct dvfs_rail *tegra_dvfs_get_rail_by_name(const char *reg_id);
209 int tegra_dvfs_predict_millivolts(struct clk *c, unsigned long rate);
210 int tegra_dvfs_predict_millivolts_pll(struct clk *c, unsigned long rate);
211 int tegra_dvfs_predict_millivolts_dfll(struct clk *c, unsigned long rate);
212 void tegra_dvfs_core_cap_enable(bool enable);
213 void tegra_dvfs_core_cap_level_set(int level);
214 int tegra_dvfs_alt_freqs_set(struct dvfs *d, unsigned long *alt_freqs);
215 int tegra_cpu_dvfs_alter(int edp_thermal_index, const cpumask_t *cpus,
216                          bool before_clk_update, int cpu_event);
217 int tegra_dvfs_dfll_mode_set(struct dvfs *d, unsigned long rate);
218 int tegra_dvfs_dfll_mode_clear(struct dvfs *d, unsigned long rate);
219 struct tegra_cooling_device *tegra_dvfs_get_cpu_dfll_cdev(void);
220 struct tegra_cooling_device *tegra_dvfs_get_cpu_pll_cdev(void);
221 struct tegra_cooling_device *tegra_dvfs_get_core_cdev(void);
222 int tegra_dvfs_rail_dfll_mode_set_cold(struct dvfs_rail *rail);
223
224 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
225 int tegra_dvfs_rail_disable_prepare(struct dvfs_rail *rail);
226 int tegra_dvfs_rail_post_enable(struct dvfs_rail *rail);
227 #else
228 static inline int tegra_dvfs_rail_disable_prepare(struct dvfs_rail *rail)
229 { return 0; }
230 static inline int tegra_dvfs_rail_post_enable(struct dvfs_rail *rail)
231 { return 0; }
232 #endif
233
234 int tegra_init_core_cap(struct core_dvfs_cap_table *table, int table_size,
235         const int *millivolts, int millivolts_num, struct kobject *cap_kobj);
236 int tegra_init_shared_bus_cap(struct core_bus_cap_table *table, int table_size,
237         struct kobject *cap_kobj);
238
239 static inline bool tegra_dvfs_rail_is_dfll_mode(struct dvfs_rail *rail)
240 {
241         return rail ? rail->dfll_mode : false;
242 }
243 static inline bool tegra_dvfs_is_dfll_range_entry(struct dvfs *d,
244                                                   unsigned long rate)
245 {
246         return  d->dvfs_rail && (!d->dvfs_rail->dfll_mode) &&
247                 (d->dfll_data.range == DFLL_RANGE_HIGH_RATES) &&
248                 (rate >= d->dfll_data.use_dfll_rate_min) &&
249                 (d->cur_rate < d->dfll_data.use_dfll_rate_min);
250 }
251
252 static inline bool tegra_dvfs_is_dfll_scale(struct dvfs *d, unsigned long rate)
253 {
254         return tegra_dvfs_rail_is_dfll_mode(d->dvfs_rail) ||
255                 tegra_dvfs_is_dfll_range_entry(d, rate);
256 }
257
258 static inline bool tegra_dvfs_is_dfll_range(struct dvfs *d, unsigned long rate)
259 {
260         return (d->dfll_data.range == DFLL_RANGE_ALL_RATES) ||
261                 ((d->dfll_data.range == DFLL_RANGE_HIGH_RATES) &&
262                 (rate >= d->dfll_data.use_dfll_rate_min));
263 }
264 static inline int tegra_dvfs_set_dfll_range(struct dvfs *d, int range)
265 {
266         if (!d->dfll_millivolts)
267                 return -ENOSYS;
268
269         if ((range < DFLL_RANGE_NONE) || (range > DFLL_RANGE_HIGH_RATES))
270                 return -EINVAL;
271
272         d->dfll_data.range = range;
273         return 0;
274 }
275 static inline void tegra_dvfs_rail_mode_updating(struct dvfs_rail *rail,
276                                                  bool updating)
277 {
278         if (rail)
279                 rail->dfll_mode_updating = updating;
280 }
281
282 static inline void tegra_dvfs_set_dfll_tune_trimmers(
283         struct dvfs *d, void (*tune_trimmers)(bool trim_high))
284 {
285         d->dfll_data.tune_trimmers = tune_trimmers;
286 }
287
288 static inline int tegra_dvfs_rail_get_nominal_millivolts(struct dvfs_rail *rail)
289 {
290         if (rail)
291                 return rail->nominal_millivolts;
292         return -ENOENT;
293 }
294
295 #endif