0ae0a2883d1c6e41f7cdc2423f688b1a0e68c7a0
[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-2013 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 100
30 #define MAX_THERMAL_LIMITS      8
31
32 struct clk;
33 struct dvfs_rail;
34
35 /*
36  * dvfs_relationship between to rails, "from" and "to"
37  * when the rail changes, it will call dvfs_rail_update on the rails
38  * in the relationship_to list.
39  * when determining the voltage to set a rail to, it will consider each
40  * rail in the relationship_from list.
41  */
42 struct dvfs_relationship {
43         struct dvfs_rail *to;
44         struct dvfs_rail *from;
45         int (*solve)(struct dvfs_rail *, struct dvfs_rail *);
46
47         struct list_head to_node; /* node in relationship_to list */
48         struct list_head from_node; /* node in relationship_from list */
49         bool solved_at_nominal;
50 };
51
52 struct rail_stats {
53         ktime_t time_at_mv[DVFS_RAIL_STATS_TOP_BIN + 1];
54         ktime_t last_update;
55         int last_index;
56         bool off;
57         int bin_uV;
58 };
59
60 struct rail_alignment {
61         int offset_uv;
62         int step_uv;
63 };
64
65 struct dvfs_rail {
66         const char *reg_id;
67         int min_millivolts;
68         int max_millivolts;
69         int reg_max_millivolts;
70         int nominal_millivolts;
71         int fixed_millivolts;
72         int override_millivolts;
73         int min_override_millivolts;
74
75         const int *therm_mv_floors;
76         int therm_mv_floors_num;
77         const int *therm_mv_caps;
78         int therm_mv_caps_num;
79
80         int step;
81         int step_up;
82         bool jmp_to_zero;
83         bool in_band_pm;
84         bool disabled;
85         bool updating;
86         bool resolving_to;
87         bool rate_set;
88
89         struct list_head node;  /* node in dvfs_rail_list */
90         struct list_head dvfs;  /* list head of attached dvfs clocks */
91         struct list_head relationships_to;
92         struct list_head relationships_from;
93         struct regulator *reg;
94         int millivolts;
95         int new_millivolts;
96         int dbg_mv_offs;
97         int boot_millivolts;
98         int disable_millivolts;
99         int suspend_millivolts;
100
101         bool suspended;
102         bool dfll_mode;
103         bool dfll_mode_updating;
104         int therm_floor_idx;
105         struct tegra_cooling_device *vmin_cdev;
106         struct tegra_cooling_device *vmax_cdev;
107         struct rail_alignment alignment;
108         struct rail_stats stats;
109 };
110
111 enum dfll_range {
112         DFLL_RANGE_NONE = 0,
113         DFLL_RANGE_ALL_RATES,
114         DFLL_RANGE_HIGH_RATES,
115 };
116
117 struct dvfs_dfll_data {
118         u32             tune0;
119         u32             tune0_high_mv;
120         u32             tune1;
121         unsigned long   droop_rate_min;
122         unsigned long   use_dfll_rate_min;
123         unsigned long   out_rate_min;
124         unsigned long   max_rate_boost;
125         int tune_high_min_millivolts;
126         int tune_high_margin_mv;
127         int min_millivolts;
128         enum dfll_range range;
129         void (*tune_trimmers)(bool trim_high);
130 };
131
132 struct dvfs {
133         /* Used only by tegra2_clock.c */
134         const char *clk_name;
135         int speedo_id;
136         int process_id;
137
138         /* Must be initialized before tegra_dvfs_init */
139         int freqs_mult;
140         unsigned long freqs[MAX_DVFS_FREQS];
141         unsigned long *alt_freqs;
142         const int *millivolts;
143         const int *dfll_millivolts;
144         struct dvfs_rail *dvfs_rail;
145         bool auto_dvfs;
146         bool can_override;
147
148         /* Filled in by tegra_dvfs_init */
149         int max_millivolts;
150         int num_freqs;
151         struct dvfs_dfll_data dfll_data;
152
153         int cur_millivolts;
154         unsigned long cur_rate;
155         struct list_head node;
156         struct list_head debug_node;
157         struct list_head reg_node;
158 };
159
160 struct cvb_dvfs_parameters {
161         int     c0;
162         int     c1;
163         int     c2;
164 };
165
166 struct cvb_dvfs_table {
167         unsigned long freq;
168         struct cvb_dvfs_parameters cvb_dfll_param;
169         struct cvb_dvfs_parameters cvb_pll_param;
170 };
171
172 struct cvb_dvfs {
173         int speedo_id;
174         int process_id;
175
176         struct dvfs_dfll_data dfll_tune_data;
177         int max_mv;
178         int min_mv;
179         int freqs_mult;
180         int speedo_scale;
181         int voltage_scale;
182         struct cvb_dvfs_table cvb_table[MAX_DVFS_FREQS];
183         int vmin_trips_table[MAX_THERMAL_LIMITS];
184         int therm_floors_table[MAX_THERMAL_LIMITS];
185 };
186
187 #define cpu_cvb_dvfs    cvb_dvfs
188 #define gpu_cvb_dvfs    cvb_dvfs
189 #define core_cvb_dvfs   cvb_dvfs
190
191 extern struct dvfs_rail *tegra_cpu_rail;
192 extern struct dvfs_rail *tegra_gpu_rail;
193 extern struct dvfs_rail *tegra_core_rail;
194
195 struct dvfs_data {
196         struct dvfs_rail *rail;
197         struct dvfs *tables;
198         int *millivolts;
199         unsigned int num_tables;
200         unsigned int num_voltages;
201 };
202
203 #ifdef CONFIG_OF
204 typedef int (*of_tegra_dvfs_init_cb_t)(struct device_node *);
205 int of_tegra_dvfs_init(const struct of_device_id *matches);
206 #else
207 static inline int of_tegra_dvfs_init(const struct of_device_id *matches)
208 { return -ENODATA; }
209 #endif
210
211 void tegra11x_init_dvfs(void);
212 void tegra12x_init_dvfs(void);
213 void tegra14x_init_dvfs(void);
214 void tegra12x_vdd_cpu_align(int step_uv, int offset_uv);
215 int tegra_enable_dvfs_on_clk(struct clk *c, struct dvfs *d);
216 int dvfs_debugfs_init(struct dentry *clk_debugfs_root);
217 int tegra_dvfs_late_init(void);
218 int tegra_dvfs_init_rails(struct dvfs_rail *dvfs_rails[], int n);
219 void tegra_dvfs_add_relationships(struct dvfs_relationship *rels, int n);
220 void tegra_dvfs_rail_enable(struct dvfs_rail *rail);
221 void tegra_dvfs_rail_disable(struct dvfs_rail *rail);
222 int tegra_dvfs_rail_power_up(struct dvfs_rail *rail);
223 int tegra_dvfs_rail_power_down(struct dvfs_rail *rail);
224 bool tegra_dvfs_is_rail_up(struct dvfs_rail *rail);
225 bool tegra_dvfs_rail_updating(struct clk *clk);
226 void tegra_dvfs_rail_off(struct dvfs_rail *rail, ktime_t now);
227 void tegra_dvfs_rail_on(struct dvfs_rail *rail, ktime_t now);
228 void tegra_dvfs_rail_pause(struct dvfs_rail *rail, ktime_t delta, bool on);
229 struct dvfs_rail *tegra_dvfs_get_rail_by_name(const char *reg_id);
230
231 int tegra_dvfs_predict_millivolts(struct clk *c, unsigned long rate);
232 int tegra_dvfs_predict_millivolts_pll(struct clk *c, unsigned long rate);
233 int tegra_dvfs_predict_millivolts_dfll(struct clk *c, unsigned long rate);
234 int tegra_dvfs_core_cap_level_apply(int level);
235 int tegra_dvfs_alt_freqs_set(struct dvfs *d, unsigned long *alt_freqs);
236 int tegra_cpu_dvfs_alter(int edp_thermal_index, const cpumask_t *cpus,
237                          bool before_clk_update, int cpu_event);
238 int tegra_dvfs_dfll_mode_set(struct dvfs *d, unsigned long rate);
239 int tegra_dvfs_dfll_mode_clear(struct dvfs *d, unsigned long rate);
240
241 struct tegra_cooling_device *tegra_dvfs_get_cpu_vmax_cdev(void);
242 struct tegra_cooling_device *tegra_dvfs_get_cpu_vmin_cdev(void);
243 struct tegra_cooling_device *tegra_dvfs_get_core_vmin_cdev(void);
244 struct tegra_cooling_device *tegra_dvfs_get_gpu_vmin_cdev(void);
245 void tegra_dvfs_rail_init_vmin_thermal_profile(
246         int *therm_trips_table, int *therm_floors_table,
247         struct dvfs_rail *rail, struct dvfs_dfll_data *d);
248 void tegra_dvfs_rail_init_vmax_thermal_profile(
249         int *therm_trips_table, int *therm_caps_table,
250         struct dvfs_rail *rail, struct dvfs_dfll_data *d);
251 int tegra_dvfs_rail_dfll_mode_set_cold(struct dvfs_rail *rail);
252
253 #ifdef CONFIG_ARCH_TEGRA_12x_SOC
254 int read_gpu_dvfs_table(int **millivolts, unsigned long **freqs);
255 #else
256 static inline int read_gpu_dvfs_table(int **millivolts, unsigned long **freqs)
257 { return -EINVAL; }
258 #endif
259
260 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
261 int tegra_dvfs_rail_disable_prepare(struct dvfs_rail *rail);
262 int tegra_dvfs_rail_post_enable(struct dvfs_rail *rail);
263 #else
264 static inline int tegra_dvfs_rail_disable_prepare(struct dvfs_rail *rail)
265 { return 0; }
266 static inline int tegra_dvfs_rail_post_enable(struct dvfs_rail *rail)
267 { return 0; }
268 #endif
269
270 static inline bool tegra_dvfs_rail_is_dfll_mode(struct dvfs_rail *rail)
271 {
272         return rail ? rail->dfll_mode : false;
273 }
274 static inline bool tegra_dvfs_is_dfll_range_entry(struct dvfs *d,
275                                                   unsigned long rate)
276 {
277         /* make exception for cluster switch (cur_rate = 0) */
278         return  d->cur_rate && d->dvfs_rail && (!d->dvfs_rail->dfll_mode) &&
279                 (d->dfll_data.range == DFLL_RANGE_HIGH_RATES) &&
280                 (rate >= d->dfll_data.use_dfll_rate_min) &&
281                 (d->cur_rate < d->dfll_data.use_dfll_rate_min);
282 }
283
284 static inline bool tegra_dvfs_is_dfll_scale(struct dvfs *d, unsigned long rate)
285 {
286         return tegra_dvfs_rail_is_dfll_mode(d->dvfs_rail) ||
287                 tegra_dvfs_is_dfll_range_entry(d, rate);
288 }
289
290 static inline bool tegra_dvfs_is_dfll_range(struct dvfs *d, unsigned long rate)
291 {
292         return (d->dfll_data.range == DFLL_RANGE_ALL_RATES) ||
293                 ((d->dfll_data.range == DFLL_RANGE_HIGH_RATES) &&
294                 (rate >= d->dfll_data.use_dfll_rate_min));
295 }
296 static inline int tegra_dvfs_set_dfll_range(struct dvfs *d, int range)
297 {
298         if (!d->dfll_millivolts)
299                 return -ENOSYS;
300
301         if ((range < DFLL_RANGE_NONE) || (range > DFLL_RANGE_HIGH_RATES))
302                 return -EINVAL;
303
304         d->dfll_data.range = range;
305         return 0;
306 }
307 static inline void tegra_dvfs_rail_mode_updating(struct dvfs_rail *rail,
308                                                  bool updating)
309 {
310         if (rail)
311                 rail->dfll_mode_updating = updating;
312 }
313
314 static inline void tegra_dvfs_set_dfll_tune_trimmers(
315         struct dvfs *d, void (*tune_trimmers)(bool trim_high))
316 {
317         d->dfll_data.tune_trimmers = tune_trimmers;
318 }
319
320 static inline int tegra_dvfs_rail_get_nominal_millivolts(struct dvfs_rail *rail)
321 {
322         if (rail)
323                 return rail->nominal_millivolts;
324         return -ENOENT;
325 }
326
327 static inline int tegra_dvfs_rail_get_boot_level(struct dvfs_rail *rail)
328 {
329         if (rail)
330                 return rail->boot_millivolts ? : rail->nominal_millivolts;
331         return -ENOENT;
332 }
333
334 static inline int tegra_dvfs_rail_get_thermal_floor(struct dvfs_rail *rail)
335 {
336         if (rail && rail->therm_mv_floors &&
337             (rail->therm_floor_idx < rail->therm_mv_floors_num))
338                 return rail->therm_mv_floors[rail->therm_floor_idx];
339         return 0;
340 }
341
342 static inline int tegra_dvfs_rail_get_override_floor(struct dvfs_rail *rail)
343 {
344         if (rail)
345                 return rail->min_override_millivolts;
346         return -ENOENT;
347 }
348
349 static inline bool tegra_dvfs_is_dfll_bypass(void)
350 {
351 #ifdef CONFIG_REGULATOR_TEGRA_DFLL_BYPASS
352         return true;
353 #else
354         return false;
355 #endif
356 }
357
358 #endif