diff options
Diffstat (limited to 'arch/arm/mach-tegra/clock.h')
-rw-r--r-- | arch/arm/mach-tegra/clock.h | 170 |
1 files changed, 163 insertions, 7 deletions
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h index 688316abc64..dde9e07292a 100644 --- a/arch/arm/mach-tegra/clock.h +++ b/arch/arm/mach-tegra/clock.h | |||
@@ -6,6 +6,8 @@ | |||
6 | * Author: | 6 | * Author: |
7 | * Colin Cross <ccross@google.com> | 7 | * Colin Cross <ccross@google.com> |
8 | * | 8 | * |
9 | * Copyright (C) 2010-2012, NVIDIA Corporation. | ||
10 | * | ||
9 | * This software is licensed under the terms of the GNU General Public | 11 | * This software is licensed under the terms of the GNU General Public |
10 | * License version 2, as published by the Free Software Foundation, and | 12 | * License version 2, as published by the Free Software Foundation, and |
11 | * may be copied, distributed, and modified under those terms. | 13 | * may be copied, distributed, and modified under those terms. |
@@ -20,9 +22,13 @@ | |||
20 | #ifndef __MACH_TEGRA_CLOCK_H | 22 | #ifndef __MACH_TEGRA_CLOCK_H |
21 | #define __MACH_TEGRA_CLOCK_H | 23 | #define __MACH_TEGRA_CLOCK_H |
22 | 24 | ||
23 | #include <linux/clkdev.h> | 25 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC |
24 | #include <linux/list.h> | 26 | #define USE_PLL_LOCK_BITS 0 /* Never use lock bits on Tegra2 */ |
25 | #include <linux/spinlock.h> | 27 | #else |
28 | #define USE_PLL_LOCK_BITS 1 /* Use lock bits for PLL stabiliation */ | ||
29 | #define USE_PLLE_SS 1 /* Use spread spectrum coefficients for PLLE */ | ||
30 | #define PLL_POST_LOCK_DELAY 50 /* Safety delay after lock is detected */ | ||
31 | #endif | ||
26 | 32 | ||
27 | #define DIV_BUS (1 << 0) | 33 | #define DIV_BUS (1 << 0) |
28 | #define DIV_U71 (1 << 1) | 34 | #define DIV_U71 (1 << 1) |
@@ -39,7 +45,29 @@ | |||
39 | #define PERIPH_MANUAL_RESET (1 << 12) | 45 | #define PERIPH_MANUAL_RESET (1 << 12) |
40 | #define PLL_ALT_MISC_REG (1 << 13) | 46 | #define PLL_ALT_MISC_REG (1 << 13) |
41 | #define PLLU (1 << 14) | 47 | #define PLLU (1 << 14) |
48 | #define PLLX (1 << 15) | ||
49 | #define MUX_PWM (1 << 16) | ||
50 | #define MUX8 (1 << 17) | ||
51 | #define DIV_U151_UART (1 << 18) | ||
52 | #define MUX_CLK_OUT (1 << 19) | ||
53 | #define PLLM (1 << 20) | ||
54 | #define DIV_U71_INT (1 << 21) | ||
55 | #define DIV_U71_IDLE (1 << 22) | ||
56 | #define DIV_U151 (1 << 23) | ||
42 | #define ENABLE_ON_INIT (1 << 28) | 57 | #define ENABLE_ON_INIT (1 << 28) |
58 | #define PERIPH_ON_APB (1 << 29) | ||
59 | #define PERIPH_ON_CBUS (1 << 30) | ||
60 | |||
61 | #ifndef __ASSEMBLY__ | ||
62 | |||
63 | #include <linux/clkdev.h> | ||
64 | #include <linux/list.h> | ||
65 | #include <linux/mutex.h> | ||
66 | #include <linux/spinlock.h> | ||
67 | #include <asm/cputime.h> | ||
68 | |||
69 | #include <mach/clk.h> | ||
70 | #define MAX_SAME_LIMIT_SKU_IDS 16 | ||
43 | 71 | ||
44 | struct clk; | 72 | struct clk; |
45 | 73 | ||
@@ -64,7 +92,26 @@ struct clk_ops { | |||
64 | int (*set_parent)(struct clk *, struct clk *); | 92 | int (*set_parent)(struct clk *, struct clk *); |
65 | int (*set_rate)(struct clk *, unsigned long); | 93 | int (*set_rate)(struct clk *, unsigned long); |
66 | long (*round_rate)(struct clk *, unsigned long); | 94 | long (*round_rate)(struct clk *, unsigned long); |
95 | int (*clk_cfg_ex)(struct clk *, enum tegra_clk_ex_param, u32); | ||
67 | void (*reset)(struct clk *, bool); | 96 | void (*reset)(struct clk *, bool); |
97 | int (*shared_bus_update)(struct clk *); | ||
98 | }; | ||
99 | |||
100 | struct clk_stats { | ||
101 | cputime64_t time_on; | ||
102 | u64 last_update; | ||
103 | }; | ||
104 | |||
105 | enum cpu_mode { | ||
106 | MODE_G = 0, | ||
107 | MODE_LP, | ||
108 | }; | ||
109 | |||
110 | enum shared_bus_users_mode { | ||
111 | SHARED_FLOOR = 0, | ||
112 | SHARED_BW, | ||
113 | SHARED_CEILING, | ||
114 | SHARED_AUTO, | ||
68 | }; | 115 | }; |
69 | 116 | ||
70 | enum clk_state { | 117 | enum clk_state { |
@@ -76,6 +123,7 @@ enum clk_state { | |||
76 | struct clk { | 123 | struct clk { |
77 | /* node for master clocks list */ | 124 | /* node for master clocks list */ |
78 | struct list_head node; /* node for list of all clocks */ | 125 | struct list_head node; /* node for list of all clocks */ |
126 | struct dvfs *dvfs; | ||
79 | struct clk_lookup lookup; | 127 | struct clk_lookup lookup; |
80 | 128 | ||
81 | #ifdef CONFIG_DEBUG_FS | 129 | #ifdef CONFIG_DEBUG_FS |
@@ -83,9 +131,12 @@ struct clk { | |||
83 | #endif | 131 | #endif |
84 | bool set; | 132 | bool set; |
85 | struct clk_ops *ops; | 133 | struct clk_ops *ops; |
134 | unsigned long dvfs_rate; | ||
86 | unsigned long rate; | 135 | unsigned long rate; |
87 | unsigned long max_rate; | 136 | unsigned long max_rate; |
88 | unsigned long min_rate; | 137 | unsigned long min_rate; |
138 | bool auto_dvfs; | ||
139 | bool cansleep; | ||
89 | u32 flags; | 140 | u32 flags; |
90 | const char *name; | 141 | const char *name; |
91 | 142 | ||
@@ -94,12 +145,14 @@ struct clk { | |||
94 | struct clk *parent; | 145 | struct clk *parent; |
95 | u32 div; | 146 | u32 div; |
96 | u32 mul; | 147 | u32 mul; |
148 | struct clk_stats stats; | ||
97 | 149 | ||
98 | const struct clk_mux_sel *inputs; | 150 | const struct clk_mux_sel *inputs; |
99 | u32 reg; | 151 | u32 reg; |
100 | u32 reg_shift; | 152 | u32 reg_shift; |
101 | 153 | ||
102 | struct list_head shared_bus_list; | 154 | struct list_head shared_bus_list; |
155 | struct clk_mux_sel shared_bus_backup; | ||
103 | 156 | ||
104 | union { | 157 | union { |
105 | struct { | 158 | struct { |
@@ -114,22 +167,45 @@ struct clk { | |||
114 | unsigned long vco_max; | 167 | unsigned long vco_max; |
115 | const struct clk_pll_freq_table *freq_table; | 168 | const struct clk_pll_freq_table *freq_table; |
116 | int lock_delay; | 169 | int lock_delay; |
170 | unsigned long fixed_rate; | ||
117 | } pll; | 171 | } pll; |
118 | struct { | 172 | struct { |
173 | unsigned long default_rate; | ||
174 | } pll_div; | ||
175 | struct { | ||
119 | u32 sel; | 176 | u32 sel; |
120 | u32 reg_mask; | 177 | u32 reg_mask; |
121 | } mux; | 178 | } mux; |
122 | struct { | 179 | struct { |
123 | struct clk *main; | 180 | struct clk *main; |
124 | struct clk *backup; | 181 | struct clk *backup; |
182 | unsigned long backup_rate; | ||
183 | enum cpu_mode mode; | ||
125 | } cpu; | 184 | } cpu; |
126 | struct { | 185 | struct { |
186 | u32 div71; | ||
187 | } cclk; | ||
188 | struct { | ||
189 | struct clk *pclk; | ||
190 | struct clk *hclk; | ||
191 | struct clk *sclk_low; | ||
192 | struct clk *sclk_high; | ||
193 | unsigned long threshold; | ||
194 | } system; | ||
195 | struct { | ||
127 | struct list_head node; | 196 | struct list_head node; |
128 | bool enabled; | 197 | bool enabled; |
129 | unsigned long rate; | 198 | unsigned long rate; |
199 | const char *client_id; | ||
200 | struct clk *client; | ||
201 | u32 client_div; | ||
202 | enum shared_bus_users_mode mode; | ||
130 | } shared_bus_user; | 203 | } shared_bus_user; |
131 | } u; | 204 | } u; |
132 | 205 | ||
206 | struct raw_notifier_head *rate_change_nh; | ||
207 | |||
208 | struct mutex mutex; | ||
133 | spinlock_t spinlock; | 209 | spinlock_t spinlock; |
134 | }; | 210 | }; |
135 | 211 | ||
@@ -145,16 +221,96 @@ struct tegra_clk_init_table { | |||
145 | bool enabled; | 221 | bool enabled; |
146 | }; | 222 | }; |
147 | 223 | ||
148 | void tegra2_init_clocks(void); | 224 | struct tegra_sku_rate_limit { |
149 | void tegra2_periph_reset_deassert(struct clk *c); | 225 | const char *clk_name; |
150 | void tegra2_periph_reset_assert(struct clk *c); | 226 | unsigned long max_rate; |
227 | int sku_ids[MAX_SAME_LIMIT_SKU_IDS]; | ||
228 | }; | ||
229 | |||
230 | void tegra_soc_init_clocks(void); | ||
231 | void tegra_init_max_rate(struct clk *c, unsigned long max_rate); | ||
151 | void clk_init(struct clk *clk); | 232 | void clk_init(struct clk *clk); |
152 | struct clk *tegra_get_clock_by_name(const char *name); | 233 | struct clk *tegra_get_clock_by_name(const char *name); |
153 | unsigned long clk_measure_input_freq(void); | 234 | unsigned long tegra_clk_measure_input_freq(void); |
154 | int clk_reparent(struct clk *c, struct clk *parent); | 235 | int clk_reparent(struct clk *c, struct clk *parent); |
155 | void tegra_clk_init_from_table(struct tegra_clk_init_table *table); | 236 | void tegra_clk_init_from_table(struct tegra_clk_init_table *table); |
237 | void clk_set_cansleep(struct clk *c); | ||
238 | unsigned long clk_get_max_rate(struct clk *c); | ||
239 | unsigned long clk_get_min_rate(struct clk *c); | ||
156 | unsigned long clk_get_rate_locked(struct clk *c); | 240 | unsigned long clk_get_rate_locked(struct clk *c); |
157 | int clk_set_rate_locked(struct clk *c, unsigned long rate); | 241 | int clk_set_rate_locked(struct clk *c, unsigned long rate); |
242 | int clk_set_parent_locked(struct clk *c, struct clk *parent); | ||
243 | int tegra_clk_shared_bus_update(struct clk *c); | ||
158 | void tegra2_sdmmc_tap_delay(struct clk *c, int delay); | 244 | void tegra2_sdmmc_tap_delay(struct clk *c, int delay); |
245 | void tegra3_set_cpu_skipper_delay(int delay); | ||
246 | int tegra_emc_set_rate(unsigned long rate); | ||
247 | long tegra_emc_round_rate(unsigned long rate); | ||
248 | struct clk *tegra_emc_predict_parent(unsigned long rate, u32 *div_value); | ||
249 | void tegra_emc_timing_invalidate(void); | ||
250 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
251 | static inline bool tegra_clk_is_parent_allowed(struct clk *c, struct clk *p) | ||
252 | { return true; } | ||
253 | #else | ||
254 | bool tegra_clk_is_parent_allowed(struct clk *c, struct clk *p); | ||
255 | #endif | ||
256 | |||
257 | static inline bool clk_is_auto_dvfs(struct clk *c) | ||
258 | { | ||
259 | return c->auto_dvfs; | ||
260 | } | ||
261 | |||
262 | static inline bool clk_is_dvfs(struct clk *c) | ||
263 | { | ||
264 | return (c->dvfs != NULL); | ||
265 | } | ||
266 | |||
267 | static inline bool clk_cansleep(struct clk *c) | ||
268 | { | ||
269 | return c->cansleep; | ||
270 | } | ||
159 | 271 | ||
272 | static inline void clk_lock_save(struct clk *c, unsigned long *flags) | ||
273 | { | ||
274 | if (clk_cansleep(c)) { | ||
275 | *flags = 0; | ||
276 | mutex_lock(&c->mutex); | ||
277 | } else { | ||
278 | spin_lock_irqsave(&c->spinlock, *flags); | ||
279 | } | ||
280 | } | ||
281 | |||
282 | static inline void clk_unlock_restore(struct clk *c, unsigned long *flags) | ||
283 | { | ||
284 | if (clk_cansleep(c)) | ||
285 | mutex_unlock(&c->mutex); | ||
286 | else | ||
287 | spin_unlock_irqrestore(&c->spinlock, *flags); | ||
288 | } | ||
289 | |||
290 | static inline void clk_lock_init(struct clk *c) | ||
291 | { | ||
292 | mutex_init(&c->mutex); | ||
293 | spin_lock_init(&c->spinlock); | ||
294 | } | ||
295 | |||
296 | #ifdef CONFIG_CPU_FREQ | ||
297 | struct cpufreq_frequency_table; | ||
298 | |||
299 | struct tegra_cpufreq_table_data { | ||
300 | struct cpufreq_frequency_table *freq_table; | ||
301 | int throttle_lowest_index; | ||
302 | int throttle_highest_index; | ||
303 | int suspend_index; | ||
304 | }; | ||
305 | struct tegra_cpufreq_table_data *tegra_cpufreq_table_get(void); | ||
306 | unsigned long tegra_emc_to_cpu_ratio(unsigned long cpu_rate); | ||
307 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
308 | static inline int tegra_update_mselect_rate(unsigned long cpu_rate) | ||
309 | { return 0; } | ||
310 | #else | ||
311 | int tegra_update_mselect_rate(unsigned long cpu_rate); | ||
312 | #endif | ||
313 | #endif | ||
314 | |||
315 | #endif | ||
160 | #endif | 316 | #endif |