blob: cf1c9d0ef7e13b7295ffdc56bfedba0886982cf8 [file] [log] [blame]
Colin Crossd8611962010-01-28 16:40:29 -08001/*
2 * arch/arm/mach-tegra/tegra2_clocks.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/list.h>
23#include <linux/spinlock.h>
24#include <linux/delay.h>
25#include <linux/io.h>
26#include <linux/hrtimer.h>
27
28#include <asm/clkdev.h>
29
30#include <mach/iomap.h>
31
32#include "clock.h"
Colin Cross71fc84c2010-06-07 20:49:46 -070033#include "fuse.h"
34#include "tegra2_dvfs.h"
Colin Crossd8611962010-01-28 16:40:29 -080035
36#define RST_DEVICES 0x004
37#define RST_DEVICES_SET 0x300
38#define RST_DEVICES_CLR 0x304
Colin Cross71fc84c2010-06-07 20:49:46 -070039#define RST_DEVICES_NUM 3
Colin Crossd8611962010-01-28 16:40:29 -080040
41#define CLK_OUT_ENB 0x010
42#define CLK_OUT_ENB_SET 0x320
43#define CLK_OUT_ENB_CLR 0x324
Colin Cross71fc84c2010-06-07 20:49:46 -070044#define CLK_OUT_ENB_NUM 3
45
46#define CLK_MASK_ARM 0x44
47#define MISC_CLK_ENB 0x48
Colin Crossd8611962010-01-28 16:40:29 -080048
49#define OSC_CTRL 0x50
50#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
51#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
52#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30)
53#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30)
54#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
Colin Cross71fc84c2010-06-07 20:49:46 -070055#define OSC_CTRL_MASK 0x3f2
Colin Crossd8611962010-01-28 16:40:29 -080056
57#define OSC_FREQ_DET 0x58
58#define OSC_FREQ_DET_TRIG (1<<31)
59
60#define OSC_FREQ_DET_STATUS 0x5C
61#define OSC_FREQ_DET_BUSY (1<<31)
62#define OSC_FREQ_DET_CNT_MASK 0xFFFF
63
Colin Cross71fc84c2010-06-07 20:49:46 -070064#define PERIPH_CLK_SOURCE_I2S1 0x100
65#define PERIPH_CLK_SOURCE_EMC 0x19c
66#define PERIPH_CLK_SOURCE_OSC 0x1fc
67#define PERIPH_CLK_SOURCE_NUM \
68 ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4)
69
Colin Crossd8611962010-01-28 16:40:29 -080070#define PERIPH_CLK_SOURCE_MASK (3<<30)
71#define PERIPH_CLK_SOURCE_SHIFT 30
72#define PERIPH_CLK_SOURCE_ENABLE (1<<28)
Colin Cross71fc84c2010-06-07 20:49:46 -070073#define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF
74#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF
Colin Crossd8611962010-01-28 16:40:29 -080075#define PERIPH_CLK_SOURCE_DIV_SHIFT 0
76
77#define PLL_BASE 0x0
78#define PLL_BASE_BYPASS (1<<31)
79#define PLL_BASE_ENABLE (1<<30)
80#define PLL_BASE_REF_ENABLE (1<<29)
81#define PLL_BASE_OVERRIDE (1<<28)
82#define PLL_BASE_LOCK (1<<27)
83#define PLL_BASE_DIVP_MASK (0x7<<20)
84#define PLL_BASE_DIVP_SHIFT 20
85#define PLL_BASE_DIVN_MASK (0x3FF<<8)
86#define PLL_BASE_DIVN_SHIFT 8
87#define PLL_BASE_DIVM_MASK (0x1F)
88#define PLL_BASE_DIVM_SHIFT 0
89
90#define PLL_OUT_RATIO_MASK (0xFF<<8)
91#define PLL_OUT_RATIO_SHIFT 8
92#define PLL_OUT_OVERRIDE (1<<2)
93#define PLL_OUT_CLKEN (1<<1)
94#define PLL_OUT_RESET_DISABLE (1<<0)
95
96#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
Colin Cross71fc84c2010-06-07 20:49:46 -070097#define PLL_MISC_LOCK_ENABLE(c) (((c)->flags & PLLU) ? (1<<22) : (1<<18))
98
Colin Crossd8611962010-01-28 16:40:29 -080099#define PLL_MISC_DCCON_SHIFT 20
Colin Crossd8611962010-01-28 16:40:29 -0800100#define PLL_MISC_CPCON_SHIFT 8
101#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT)
102#define PLL_MISC_LFCON_SHIFT 4
103#define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT)
104#define PLL_MISC_VCOCON_SHIFT 0
105#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT)
106
Colin Cross71fc84c2010-06-07 20:49:46 -0700107#define PLLU_BASE_POST_DIV (1<<20)
108
Colin Crossd8611962010-01-28 16:40:29 -0800109#define PLLD_MISC_CLKENABLE (1<<30)
110#define PLLD_MISC_DIV_RST (1<<23)
111#define PLLD_MISC_DCCON_SHIFT 12
112
113#define PERIPH_CLK_TO_ENB_REG(c) ((c->clk_num / 32) * 4)
114#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->clk_num / 32) * 8)
115#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->clk_num % 32))
116
117#define SUPER_CLK_MUX 0x00
118#define SUPER_STATE_SHIFT 28
119#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT)
120#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT)
121#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT)
122#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT)
123#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT)
124#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT)
125#define SUPER_SOURCE_MASK 0xF
126#define SUPER_FIQ_SOURCE_SHIFT 12
127#define SUPER_IRQ_SOURCE_SHIFT 8
128#define SUPER_RUN_SOURCE_SHIFT 4
129#define SUPER_IDLE_SOURCE_SHIFT 0
130
131#define SUPER_CLK_DIVIDER 0x04
132
133#define BUS_CLK_DISABLE (1<<3)
134#define BUS_CLK_DIV_MASK 0x3
135
136static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
137
138#define clk_writel(value, reg) \
139 __raw_writel(value, (u32)reg_clk_base + (reg))
140#define clk_readl(reg) \
141 __raw_readl((u32)reg_clk_base + (reg))
142
143unsigned long clk_measure_input_freq(void)
144{
145 u32 clock_autodetect;
146 clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
147 do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
148 clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
149 if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
150 return 12000000;
151 } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
152 return 13000000;
153 } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
154 return 19200000;
155 } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
156 return 26000000;
157 } else {
158 pr_err("%s: Unexpected clock autodetect value %d", __func__, clock_autodetect);
159 BUG();
160 return 0;
161 }
162}
163
Colin Cross71fc84c2010-06-07 20:49:46 -0700164static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate)
Colin Crossd8611962010-01-28 16:40:29 -0800165{
Colin Cross71fc84c2010-06-07 20:49:46 -0700166 s64 divider_u71 = parent_rate * 2;
167 divider_u71 += rate - 1;
168 do_div(divider_u71, rate);
Colin Crossd8611962010-01-28 16:40:29 -0800169
Colin Cross71fc84c2010-06-07 20:49:46 -0700170 if (divider_u71 - 2 < 0)
171 return 0;
Colin Crossd8611962010-01-28 16:40:29 -0800172
Colin Cross71fc84c2010-06-07 20:49:46 -0700173 if (divider_u71 - 2 > 255)
Colin Crossd8611962010-01-28 16:40:29 -0800174 return -EINVAL;
175
176 return divider_u71 - 2;
177}
178
Colin Cross71fc84c2010-06-07 20:49:46 -0700179static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
Colin Crossd8611962010-01-28 16:40:29 -0800180{
Colin Cross71fc84c2010-06-07 20:49:46 -0700181 s64 divider_u16;
Colin Crossd8611962010-01-28 16:40:29 -0800182
Colin Cross71fc84c2010-06-07 20:49:46 -0700183 divider_u16 = parent_rate;
184 divider_u16 += rate - 1;
185 do_div(divider_u16, rate);
186
187 if (divider_u16 - 1 < 0)
188 return 0;
189
190 if (divider_u16 - 1 > 255)
191 return -EINVAL;
192
193 return divider_u16 - 1;
Colin Crossd8611962010-01-28 16:40:29 -0800194}
195
Colin Crossd8611962010-01-28 16:40:29 -0800196/* clk_m functions */
197static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c)
198{
199 u32 auto_clock_control = clk_readl(OSC_CTRL) & ~OSC_CTRL_OSC_FREQ_MASK;
200
201 c->rate = clk_measure_input_freq();
202 switch (c->rate) {
203 case 12000000:
204 auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
205 break;
206 case 13000000:
207 auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
208 break;
209 case 19200000:
210 auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
211 break;
212 case 26000000:
213 auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
214 break;
215 default:
216 pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
217 BUG();
218 }
219 clk_writel(auto_clock_control, OSC_CTRL);
220 return c->rate;
221}
222
223static void tegra2_clk_m_init(struct clk *c)
224{
225 pr_debug("%s on clock %s\n", __func__, c->name);
226 tegra2_clk_m_autodetect_rate(c);
227}
228
229static int tegra2_clk_m_enable(struct clk *c)
230{
231 pr_debug("%s on clock %s\n", __func__, c->name);
232 return 0;
233}
234
235static void tegra2_clk_m_disable(struct clk *c)
236{
237 pr_debug("%s on clock %s\n", __func__, c->name);
238 BUG();
239}
240
241static struct clk_ops tegra_clk_m_ops = {
242 .init = tegra2_clk_m_init,
243 .enable = tegra2_clk_m_enable,
244 .disable = tegra2_clk_m_disable,
245};
246
247/* super clock functions */
248/* "super clocks" on tegra have two-stage muxes and a clock skipping
249 * super divider. We will ignore the clock skipping divider, since we
250 * can't lower the voltage when using the clock skip, but we can if we
251 * lower the PLL frequency.
252 */
253static void tegra2_super_clk_init(struct clk *c)
254{
255 u32 val;
256 int source;
257 int shift;
258 const struct clk_mux_sel *sel;
259 val = clk_readl(c->reg + SUPER_CLK_MUX);
260 c->state = ON;
261 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
262 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
263 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
264 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
265 source = (val >> shift) & SUPER_SOURCE_MASK;
266 for (sel = c->inputs; sel->input != NULL; sel++) {
267 if (sel->value == source)
268 break;
269 }
270 BUG_ON(sel->input == NULL);
271 c->parent = sel->input;
Colin Crossd8611962010-01-28 16:40:29 -0800272}
273
274static int tegra2_super_clk_enable(struct clk *c)
275{
276 clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
277 return 0;
278}
279
280static void tegra2_super_clk_disable(struct clk *c)
281{
282 pr_debug("%s on clock %s\n", __func__, c->name);
283
284 /* oops - don't disable the CPU clock! */
285 BUG();
286}
287
288static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p)
289{
290 u32 val;
291 const struct clk_mux_sel *sel;
292 int shift;
Colin Cross71fc84c2010-06-07 20:49:46 -0700293
Colin Crossd8611962010-01-28 16:40:29 -0800294 val = clk_readl(c->reg + SUPER_CLK_MUX);;
295 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
296 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
297 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
298 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
299 for (sel = c->inputs; sel->input != NULL; sel++) {
300 if (sel->input == p) {
Colin Crossd8611962010-01-28 16:40:29 -0800301 val &= ~(SUPER_SOURCE_MASK << shift);
302 val |= sel->value << shift;
Colin Cross71fc84c2010-06-07 20:49:46 -0700303
304 if (c->refcnt)
305 clk_enable_locked(p);
306
Colin Crossd8611962010-01-28 16:40:29 -0800307 clk_writel(val, c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -0700308
309 if (c->refcnt && c->parent)
310 clk_disable_locked(c->parent);
311
312 clk_reparent(c, p);
Colin Crossd8611962010-01-28 16:40:29 -0800313 return 0;
314 }
315 }
316 return -EINVAL;
317}
318
319static struct clk_ops tegra_super_ops = {
320 .init = tegra2_super_clk_init,
321 .enable = tegra2_super_clk_enable,
322 .disable = tegra2_super_clk_disable,
323 .set_parent = tegra2_super_clk_set_parent,
Colin Cross71fc84c2010-06-07 20:49:46 -0700324};
325
326/* virtual cpu clock functions */
327/* some clocks can not be stopped (cpu, memory bus) while the SoC is running.
328 To change the frequency of these clocks, the parent pll may need to be
329 reprogrammed, so the clock must be moved off the pll, the pll reprogrammed,
330 and then the clock moved back to the pll. To hide this sequence, a virtual
331 clock handles it.
332 */
333static void tegra2_cpu_clk_init(struct clk *c)
334{
335}
336
337static int tegra2_cpu_clk_enable(struct clk *c)
338{
339 return 0;
340}
341
342static void tegra2_cpu_clk_disable(struct clk *c)
343{
344 pr_debug("%s on clock %s\n", __func__, c->name);
345
346 /* oops - don't disable the CPU clock! */
347 BUG();
348}
349
350static int tegra2_cpu_clk_set_rate(struct clk *c, unsigned long rate)
351{
352 int ret;
353 ret = clk_set_parent_locked(c->parent, c->backup);
354 if (ret) {
355 pr_err("Failed to switch cpu to clock %s\n", c->backup->name);
356 return ret;
357 }
358
359 ret = clk_set_rate_locked(c->main, rate);
360 if (ret) {
361 pr_err("Failed to change cpu pll to %lu\n", rate);
362 return ret;
363 }
364
365 ret = clk_set_parent_locked(c->parent, c->main);
366 if (ret) {
367 pr_err("Failed to switch cpu to clock %s\n", c->main->name);
368 return ret;
369 }
370
371 return 0;
372}
373
374static struct clk_ops tegra_cpu_ops = {
375 .init = tegra2_cpu_clk_init,
376 .enable = tegra2_cpu_clk_enable,
377 .disable = tegra2_cpu_clk_disable,
378 .set_rate = tegra2_cpu_clk_set_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800379};
380
381/* bus clock functions */
382static void tegra2_bus_clk_init(struct clk *c)
383{
384 u32 val = clk_readl(c->reg);
385 c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
386 c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
387 c->mul = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800388}
389
390static int tegra2_bus_clk_enable(struct clk *c)
391{
392 u32 val = clk_readl(c->reg);
393 val &= ~(BUS_CLK_DISABLE << c->reg_shift);
394 clk_writel(val, c->reg);
395 return 0;
396}
397
398static void tegra2_bus_clk_disable(struct clk *c)
399{
400 u32 val = clk_readl(c->reg);
401 val |= BUS_CLK_DISABLE << c->reg_shift;
402 clk_writel(val, c->reg);
403}
404
405static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate)
406{
407 u32 val = clk_readl(c->reg);
408 unsigned long parent_rate = c->parent->rate;
409 int i;
410 for (i = 1; i <= 4; i++) {
411 if (rate == parent_rate / i) {
412 val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
413 val |= (i - 1) << c->reg_shift;
414 clk_writel(val, c->reg);
415 c->div = i;
416 c->mul = 1;
417 return 0;
418 }
419 }
420 return -EINVAL;
421}
422
423static struct clk_ops tegra_bus_ops = {
424 .init = tegra2_bus_clk_init,
425 .enable = tegra2_bus_clk_enable,
426 .disable = tegra2_bus_clk_disable,
427 .set_rate = tegra2_bus_clk_set_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800428};
429
430/* PLL Functions */
Colin Crossd8611962010-01-28 16:40:29 -0800431static int tegra2_pll_clk_wait_for_lock(struct clk *c)
432{
433 ktime_t before;
434
435 before = ktime_get();
Colin Cross71fc84c2010-06-07 20:49:46 -0700436
Colin Crossd8611962010-01-28 16:40:29 -0800437 while (!(clk_readl(c->reg + PLL_BASE) & PLL_BASE_LOCK)) {
438 if (ktime_us_delta(ktime_get(), before) > 5000) {
439 pr_err("Timed out waiting for lock bit on pll %s",
440 c->name);
441 return -1;
442 }
443 }
444
445 return 0;
446}
447
448static void tegra2_pll_clk_init(struct clk *c)
449{
450 u32 val = clk_readl(c->reg + PLL_BASE);
451
452 c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
453
454 if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
455 pr_warning("Clock %s has unknown fixed frequency\n", c->name);
Colin Cross71fc84c2010-06-07 20:49:46 -0700456 c->mul = 1;
457 c->div = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800458 } else if (val & PLL_BASE_BYPASS) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700459 c->mul = 1;
460 c->div = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800461 } else {
Colin Cross71fc84c2010-06-07 20:49:46 -0700462 c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
463 c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
464 if (c->flags & PLLU)
465 c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
466 else
467 c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
Colin Crossd8611962010-01-28 16:40:29 -0800468 }
Colin Crossd8611962010-01-28 16:40:29 -0800469}
470
471static int tegra2_pll_clk_enable(struct clk *c)
472{
473 u32 val;
474 pr_debug("%s on clock %s\n", __func__, c->name);
475
476 val = clk_readl(c->reg + PLL_BASE);
477 val &= ~PLL_BASE_BYPASS;
478 val |= PLL_BASE_ENABLE;
479 clk_writel(val, c->reg + PLL_BASE);
480
481 val = clk_readl(c->reg + PLL_MISC(c));
Colin Cross71fc84c2010-06-07 20:49:46 -0700482 val |= PLL_MISC_LOCK_ENABLE(c);
Colin Crossd8611962010-01-28 16:40:29 -0800483 clk_writel(val, c->reg + PLL_MISC(c));
484
485 tegra2_pll_clk_wait_for_lock(c);
486
487 return 0;
488}
489
490static void tegra2_pll_clk_disable(struct clk *c)
491{
492 u32 val;
493 pr_debug("%s on clock %s\n", __func__, c->name);
494
495 val = clk_readl(c->reg);
496 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
497 clk_writel(val, c->reg);
498}
499
500static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate)
501{
502 u32 val;
503 unsigned long input_rate;
504 const struct clk_pll_table *sel;
505
506 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
507 BUG_ON(c->refcnt != 0);
508
509 input_rate = c->parent->rate;
510 for (sel = c->pll_table; sel->input_rate != 0; sel++) {
511 if (sel->input_rate == input_rate && sel->output_rate == rate) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700512 c->mul = sel->n;
513 c->div = sel->m * sel->p;
Colin Crossd8611962010-01-28 16:40:29 -0800514
515 val = clk_readl(c->reg + PLL_BASE);
516 if (c->flags & PLL_FIXED)
517 val |= PLL_BASE_OVERRIDE;
518 val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK |
519 PLL_BASE_DIVM_MASK);
Colin Cross71fc84c2010-06-07 20:49:46 -0700520 val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
521 (sel->n << PLL_BASE_DIVN_SHIFT);
522 BUG_ON(sel->p < 1 || sel->p > 2);
523 if (c->flags & PLLU) {
524 if (sel->p == 1)
525 val |= PLLU_BASE_POST_DIV;
526 } else {
527 if (sel->p == 2)
528 val |= 1 << PLL_BASE_DIVP_SHIFT;
529 }
Colin Crossd8611962010-01-28 16:40:29 -0800530 clk_writel(val, c->reg + PLL_BASE);
531
532 if (c->flags & PLL_HAS_CPCON) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700533 val = clk_readl(c->reg + PLL_MISC(c));
534 val &= ~PLL_MISC_CPCON_MASK;
535 val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
Colin Crossd8611962010-01-28 16:40:29 -0800536 clk_writel(val, c->reg + PLL_MISC(c));
537 }
538
539 if (c->state == ON)
540 tegra2_pll_clk_enable(c);
541
Colin Crossd8611962010-01-28 16:40:29 -0800542 return 0;
543 }
544 }
545 return -EINVAL;
546}
547
548static struct clk_ops tegra_pll_ops = {
549 .init = tegra2_pll_clk_init,
550 .enable = tegra2_pll_clk_enable,
551 .disable = tegra2_pll_clk_disable,
552 .set_rate = tegra2_pll_clk_set_rate,
Colin Cross71fc84c2010-06-07 20:49:46 -0700553};
554
555static void tegra2_pllx_clk_init(struct clk *c)
556{
557 tegra2_pll_clk_init(c);
558
559 if (tegra_sku_id() == 7)
560 c->max_rate = 750000000;
561}
562
563static struct clk_ops tegra_pllx_ops = {
564 .init = tegra2_pllx_clk_init,
565 .enable = tegra2_pll_clk_enable,
566 .disable = tegra2_pll_clk_disable,
567 .set_rate = tegra2_pll_clk_set_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800568};
569
570/* Clock divider ops */
571static void tegra2_pll_div_clk_init(struct clk *c)
572{
573 u32 val = clk_readl(c->reg);
574 u32 divu71;
575 val >>= c->reg_shift;
576 c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
577 if (!(val & PLL_OUT_RESET_DISABLE))
578 c->state = OFF;
579
580 if (c->flags & DIV_U71) {
581 divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
582 c->div = (divu71 + 2);
583 c->mul = 2;
584 } else if (c->flags & DIV_2) {
585 c->div = 2;
586 c->mul = 1;
587 } else {
588 c->div = 1;
589 c->mul = 1;
590 }
Colin Crossd8611962010-01-28 16:40:29 -0800591}
592
593static int tegra2_pll_div_clk_enable(struct clk *c)
594{
595 u32 val;
596 u32 new_val;
597
598 pr_debug("%s: %s\n", __func__, c->name);
599 if (c->flags & DIV_U71) {
600 val = clk_readl(c->reg);
601 new_val = val >> c->reg_shift;
602 new_val &= 0xFFFF;
603
604 new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
605
606 val &= ~(0xFFFF << c->reg_shift);
607 val |= new_val << c->reg_shift;
608 clk_writel(val, c->reg);
609 return 0;
610 } else if (c->flags & DIV_2) {
611 BUG_ON(!(c->flags & PLLD));
612 val = clk_readl(c->reg);
613 val &= ~PLLD_MISC_DIV_RST;
614 clk_writel(val, c->reg);
615 return 0;
616 }
617 return -EINVAL;
618}
619
620static void tegra2_pll_div_clk_disable(struct clk *c)
621{
622 u32 val;
623 u32 new_val;
624
625 pr_debug("%s: %s\n", __func__, c->name);
626 if (c->flags & DIV_U71) {
627 val = clk_readl(c->reg);
628 new_val = val >> c->reg_shift;
629 new_val &= 0xFFFF;
630
631 new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
632
633 val &= ~(0xFFFF << c->reg_shift);
634 val |= new_val << c->reg_shift;
635 clk_writel(val, c->reg);
636 } else if (c->flags & DIV_2) {
637 BUG_ON(!(c->flags & PLLD));
638 val = clk_readl(c->reg);
639 val |= PLLD_MISC_DIV_RST;
640 clk_writel(val, c->reg);
641 }
642}
643
644static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
645{
646 u32 val;
647 u32 new_val;
648 int divider_u71;
649 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
650 if (c->flags & DIV_U71) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700651 divider_u71 = clk_div71_get_divider(c->parent->rate, rate);
Colin Crossd8611962010-01-28 16:40:29 -0800652 if (divider_u71 >= 0) {
653 val = clk_readl(c->reg);
654 new_val = val >> c->reg_shift;
655 new_val &= 0xFFFF;
656 if (c->flags & DIV_U71_FIXED)
657 new_val |= PLL_OUT_OVERRIDE;
658 new_val &= ~PLL_OUT_RATIO_MASK;
659 new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
660
661 val &= ~(0xFFFF << c->reg_shift);
662 val |= new_val << c->reg_shift;
663 clk_writel(val, c->reg);
664 c->div = divider_u71 + 2;
665 c->mul = 2;
Colin Crossd8611962010-01-28 16:40:29 -0800666 return 0;
667 }
668 } else if (c->flags & DIV_2) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700669 if (c->parent->rate == rate * 2)
Colin Crossd8611962010-01-28 16:40:29 -0800670 return 0;
Colin Crossd8611962010-01-28 16:40:29 -0800671 }
672 return -EINVAL;
673}
674
Colin Cross71fc84c2010-06-07 20:49:46 -0700675static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
676{
677 int divider;
678 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
679
680 if (c->flags & DIV_U71) {
681 divider = clk_div71_get_divider(c->parent->rate, rate);
682 if (divider < 0)
683 return divider;
684 return c->parent->rate * 2 / (divider + 2);
685 } else if (c->flags & DIV_2) {
686 return c->parent->rate / 2;
687 }
688 return -EINVAL;
689}
Colin Crossd8611962010-01-28 16:40:29 -0800690
691static struct clk_ops tegra_pll_div_ops = {
692 .init = tegra2_pll_div_clk_init,
693 .enable = tegra2_pll_div_clk_enable,
694 .disable = tegra2_pll_div_clk_disable,
695 .set_rate = tegra2_pll_div_clk_set_rate,
Colin Cross71fc84c2010-06-07 20:49:46 -0700696 .round_rate = tegra2_pll_div_clk_round_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800697};
698
699/* Periph clk ops */
700
701static void tegra2_periph_clk_init(struct clk *c)
702{
703 u32 val = clk_readl(c->reg);
704 const struct clk_mux_sel *mux = 0;
705 const struct clk_mux_sel *sel;
706 if (c->flags & MUX) {
707 for (sel = c->inputs; sel->input != NULL; sel++) {
708 if (val >> PERIPH_CLK_SOURCE_SHIFT == sel->value)
709 mux = sel;
710 }
711 BUG_ON(!mux);
712
713 c->parent = mux->input;
714 } else {
715 c->parent = c->inputs[0].input;
716 }
717
718 if (c->flags & DIV_U71) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700719 u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
Colin Crossd8611962010-01-28 16:40:29 -0800720 c->div = divu71 + 2;
721 c->mul = 2;
Colin Cross71fc84c2010-06-07 20:49:46 -0700722 } else if (c->flags & DIV_U16) {
723 u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
724 c->div = divu16 + 1;
725 c->mul = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800726 } else {
727 c->div = 1;
728 c->mul = 1;
729 }
730
731 c->state = ON;
732 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
733 PERIPH_CLK_TO_ENB_BIT(c)))
734 c->state = OFF;
735 if (!(c->flags & PERIPH_NO_RESET))
736 if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
737 PERIPH_CLK_TO_ENB_BIT(c))
738 c->state = OFF;
Colin Crossd8611962010-01-28 16:40:29 -0800739}
740
741static int tegra2_periph_clk_enable(struct clk *c)
742{
743 u32 val;
744 pr_debug("%s on clock %s\n", __func__, c->name);
745
746 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
747 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
748 if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET))
749 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
750 RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
751 if (c->flags & PERIPH_EMC_ENB) {
752 /* The EMC peripheral clock has 2 extra enable bits */
753 /* FIXME: Do they need to be disabled? */
754 val = clk_readl(c->reg);
755 val |= 0x3 << 24;
756 clk_writel(val, c->reg);
757 }
758 return 0;
759}
760
761static void tegra2_periph_clk_disable(struct clk *c)
762{
763 pr_debug("%s on clock %s\n", __func__, c->name);
764
765 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
766 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
767}
768
769void tegra2_periph_reset_deassert(struct clk *c)
770{
771 pr_debug("%s on clock %s\n", __func__, c->name);
772 if (!(c->flags & PERIPH_NO_RESET))
773 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
774 RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
775}
776
777void tegra2_periph_reset_assert(struct clk *c)
778{
779 pr_debug("%s on clock %s\n", __func__, c->name);
780 if (!(c->flags & PERIPH_NO_RESET))
781 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
782 RST_DEVICES_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
783}
784
785
786static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
787{
788 u32 val;
789 const struct clk_mux_sel *sel;
790 pr_debug("%s: %s %s\n", __func__, c->name, p->name);
791 for (sel = c->inputs; sel->input != NULL; sel++) {
792 if (sel->input == p) {
Colin Crossd8611962010-01-28 16:40:29 -0800793 val = clk_readl(c->reg);
794 val &= ~PERIPH_CLK_SOURCE_MASK;
795 val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT;
Colin Cross71fc84c2010-06-07 20:49:46 -0700796
797 if (c->refcnt)
798 clk_enable_locked(p);
799
Colin Crossd8611962010-01-28 16:40:29 -0800800 clk_writel(val, c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -0700801
802 if (c->refcnt && c->parent)
803 clk_disable_locked(c->parent);
804
805 clk_reparent(c, p);
Colin Crossd8611962010-01-28 16:40:29 -0800806 return 0;
807 }
808 }
809
810 return -EINVAL;
811}
812
813static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
814{
815 u32 val;
Colin Cross71fc84c2010-06-07 20:49:46 -0700816 int divider;
Colin Crossd8611962010-01-28 16:40:29 -0800817 pr_debug("%s: %lu\n", __func__, rate);
818 if (c->flags & DIV_U71) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700819 divider = clk_div71_get_divider(c->parent->rate, rate);
820 if (divider >= 0) {
Colin Crossd8611962010-01-28 16:40:29 -0800821 val = clk_readl(c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -0700822 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
823 val |= divider;
Colin Crossd8611962010-01-28 16:40:29 -0800824 clk_writel(val, c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -0700825 c->div = divider + 2;
Colin Crossd8611962010-01-28 16:40:29 -0800826 c->mul = 2;
Colin Crossd8611962010-01-28 16:40:29 -0800827 return 0;
828 }
Colin Cross71fc84c2010-06-07 20:49:46 -0700829 } else if (c->flags & DIV_U16) {
830 divider = clk_div16_get_divider(c->parent->rate, rate);
831 if (divider >= 0) {
832 val = clk_readl(c->reg);
833 val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
834 val |= divider;
835 clk_writel(val, c->reg);
836 c->div = divider + 1;
837 c->mul = 1;
838 return 0;
839 }
840 } else if (c->parent->rate <= rate) {
841 c->div = 1;
842 c->mul = 1;
843 return 0;
844 }
845 return -EINVAL;
846}
847
848static long tegra2_periph_clk_round_rate(struct clk *c,
849 unsigned long rate)
850{
851 int divider;
852 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
853
854 if (c->flags & DIV_U71) {
855 divider = clk_div71_get_divider(c->parent->rate, rate);
856 if (divider < 0)
857 return divider;
858
859 return c->parent->rate * 2 / (divider + 2);
860 } else if (c->flags & DIV_U16) {
861 divider = clk_div16_get_divider(c->parent->rate, rate);
862 if (divider < 0)
863 return divider;
864 return c->parent->rate / (divider + 1);
Colin Crossd8611962010-01-28 16:40:29 -0800865 }
866 return -EINVAL;
867}
868
869static struct clk_ops tegra_periph_clk_ops = {
870 .init = &tegra2_periph_clk_init,
871 .enable = &tegra2_periph_clk_enable,
872 .disable = &tegra2_periph_clk_disable,
873 .set_parent = &tegra2_periph_clk_set_parent,
874 .set_rate = &tegra2_periph_clk_set_rate,
Colin Cross71fc84c2010-06-07 20:49:46 -0700875 .round_rate = &tegra2_periph_clk_round_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800876};
877
878/* Clock doubler ops */
879static void tegra2_clk_double_init(struct clk *c)
880{
881 c->mul = 2;
882 c->div = 1;
883 c->state = ON;
884 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
885 PERIPH_CLK_TO_ENB_BIT(c)))
886 c->state = OFF;
Colin Crossd8611962010-01-28 16:40:29 -0800887};
888
Colin Cross71fc84c2010-06-07 20:49:46 -0700889static int tegra2_clk_double_set_rate(struct clk *c, unsigned long rate)
890{
891 if (rate != 2 * c->parent->rate)
892 return -EINVAL;
893 c->mul = 2;
894 c->div = 1;
895 return 0;
896}
897
Colin Crossd8611962010-01-28 16:40:29 -0800898static struct clk_ops tegra_clk_double_ops = {
899 .init = &tegra2_clk_double_init,
900 .enable = &tegra2_periph_clk_enable,
901 .disable = &tegra2_periph_clk_disable,
Colin Cross71fc84c2010-06-07 20:49:46 -0700902 .set_rate = &tegra2_clk_double_set_rate,
903};
904
905static void tegra2_audio_sync_clk_init(struct clk *c)
906{
907 int source;
908 const struct clk_mux_sel *sel;
909 u32 val = clk_readl(c->reg);
910 c->state = (val & (1<<4)) ? OFF : ON;
911 source = val & 0xf;
912 for (sel = c->inputs; sel->input != NULL; sel++)
913 if (sel->value == source)
914 break;
915 BUG_ON(sel->input == NULL);
916 c->parent = sel->input;
917}
918
919static int tegra2_audio_sync_clk_enable(struct clk *c)
920{
921 clk_writel(0, c->reg);
922 return 0;
923}
924
925static void tegra2_audio_sync_clk_disable(struct clk *c)
926{
927 clk_writel(1, c->reg);
928}
929
930static int tegra2_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
931{
932 u32 val;
933 const struct clk_mux_sel *sel;
934 for (sel = c->inputs; sel->input != NULL; sel++) {
935 if (sel->input == p) {
936 val = clk_readl(c->reg);
937 val &= ~0xf;
938 val |= sel->value;
939
940 if (c->refcnt)
941 clk_enable_locked(p);
942
943 clk_writel(val, c->reg);
944
945 if (c->refcnt && c->parent)
946 clk_disable_locked(c->parent);
947
948 clk_reparent(c, p);
949 return 0;
950 }
951 }
952
953 return -EINVAL;
954}
955
956static int tegra2_audio_sync_clk_set_rate(struct clk *c, unsigned long rate)
957{
958 unsigned long parent_rate;
959 if (!c->parent) {
960 pr_err("%s: clock has no parent\n", __func__);
961 return -EINVAL;
962 }
963 parent_rate = c->parent->rate;
964 if (rate != parent_rate) {
965 pr_err("%s: %s/%ld differs from parent %s/%ld\n",
966 __func__,
967 c->name, rate,
968 c->parent->name, parent_rate);
969 return -EINVAL;
970 }
971 c->rate = parent_rate;
972 return 0;
973}
974
975static struct clk_ops tegra_audio_sync_clk_ops = {
976 .init = tegra2_audio_sync_clk_init,
977 .enable = tegra2_audio_sync_clk_enable,
978 .disable = tegra2_audio_sync_clk_disable,
979 .set_rate = tegra2_audio_sync_clk_set_rate,
980 .set_parent = tegra2_audio_sync_clk_set_parent,
Colin Crossd8611962010-01-28 16:40:29 -0800981};
982
983/* Clock definitions */
984static struct clk tegra_clk_32k = {
985 .name = "clk_32k",
Colin Cross71fc84c2010-06-07 20:49:46 -0700986 .rate = 32768,
Colin Crossd8611962010-01-28 16:40:29 -0800987 .ops = NULL,
Colin Cross71fc84c2010-06-07 20:49:46 -0700988 .max_rate = 32768,
Colin Crossd8611962010-01-28 16:40:29 -0800989};
990
991static struct clk_pll_table tegra_pll_s_table[] = {
992 {32768, 12000000, 366, 1, 1, 0},
993 {32768, 13000000, 397, 1, 1, 0},
994 {32768, 19200000, 586, 1, 1, 0},
995 {32768, 26000000, 793, 1, 1, 0},
996 {0, 0, 0, 0, 0, 0},
997};
998
999static struct clk tegra_pll_s = {
1000 .name = "pll_s",
1001 .flags = PLL_ALT_MISC_REG,
1002 .ops = &tegra_pll_ops,
1003 .reg = 0xf0,
1004 .input_min = 32768,
1005 .input_max = 32768,
1006 .parent = &tegra_clk_32k,
1007 .cf_min = 0, /* FIXME */
1008 .cf_max = 0, /* FIXME */
1009 .vco_min = 12000000,
1010 .vco_max = 26000000,
1011 .pll_table = tegra_pll_s_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001012 .max_rate = 26000000,
Colin Crossd8611962010-01-28 16:40:29 -08001013};
1014
1015static struct clk_mux_sel tegra_clk_m_sel[] = {
1016 { .input = &tegra_clk_32k, .value = 0},
1017 { .input = &tegra_pll_s, .value = 1},
1018 { 0, 0},
1019};
1020static struct clk tegra_clk_m = {
1021 .name = "clk_m",
1022 .flags = ENABLE_ON_INIT,
1023 .ops = &tegra_clk_m_ops,
1024 .inputs = tegra_clk_m_sel,
1025 .reg = 0x1fc,
1026 .reg_mask = (1<<28),
1027 .reg_shift = 28,
Colin Cross71fc84c2010-06-07 20:49:46 -07001028 .max_rate = 26000000,
Colin Crossd8611962010-01-28 16:40:29 -08001029};
1030
1031static struct clk_pll_table tegra_pll_c_table[] = {
1032 { 0, 0, 0, 0, 0, 0 },
1033};
1034
1035static struct clk tegra_pll_c = {
1036 .name = "pll_c",
1037 .flags = PLL_HAS_CPCON,
1038 .ops = &tegra_pll_ops,
1039 .reg = 0x80,
1040 .input_min = 2000000,
1041 .input_max = 31000000,
1042 .parent = &tegra_clk_m,
1043 .cf_min = 1000000,
1044 .cf_max = 6000000,
1045 .vco_min = 20000000,
1046 .vco_max = 1400000000,
1047 .pll_table = tegra_pll_c_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001048 .max_rate = 600000000,
Colin Crossd8611962010-01-28 16:40:29 -08001049};
1050
1051static struct clk tegra_pll_c_out1 = {
1052 .name = "pll_c_out1",
1053 .ops = &tegra_pll_div_ops,
1054 .flags = DIV_U71,
1055 .parent = &tegra_pll_c,
1056 .reg = 0x84,
1057 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001058 .max_rate = 600000000,
Colin Crossd8611962010-01-28 16:40:29 -08001059};
1060
1061static struct clk_pll_table tegra_pll_m_table[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001062 { 12000000, 666000000, 666, 12, 1, 8},
1063 { 13000000, 666000000, 666, 13, 1, 8},
1064 { 19200000, 666000000, 555, 16, 1, 8},
1065 { 26000000, 666000000, 666, 26, 1, 8},
1066 { 12000000, 600000000, 600, 12, 1, 8},
1067 { 13000000, 600000000, 600, 13, 1, 8},
1068 { 19200000, 600000000, 375, 12, 1, 6},
1069 { 26000000, 600000000, 600, 26, 1, 8},
Colin Crossd8611962010-01-28 16:40:29 -08001070 { 0, 0, 0, 0, 0, 0 },
1071};
1072
1073static struct clk tegra_pll_m = {
1074 .name = "pll_m",
1075 .flags = PLL_HAS_CPCON,
1076 .ops = &tegra_pll_ops,
1077 .reg = 0x90,
1078 .input_min = 2000000,
1079 .input_max = 31000000,
1080 .parent = &tegra_clk_m,
1081 .cf_min = 1000000,
1082 .cf_max = 6000000,
1083 .vco_min = 20000000,
1084 .vco_max = 1200000000,
1085 .pll_table = tegra_pll_m_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001086 .max_rate = 800000000,
Colin Crossd8611962010-01-28 16:40:29 -08001087};
1088
1089static struct clk tegra_pll_m_out1 = {
1090 .name = "pll_m_out1",
1091 .ops = &tegra_pll_div_ops,
1092 .flags = DIV_U71,
1093 .parent = &tegra_pll_m,
1094 .reg = 0x94,
1095 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001096 .max_rate = 600000000,
Colin Crossd8611962010-01-28 16:40:29 -08001097};
1098
1099static struct clk_pll_table tegra_pll_p_table[] = {
1100 { 12000000, 216000000, 432, 12, 2, 8},
1101 { 13000000, 216000000, 432, 13, 2, 8},
1102 { 19200000, 216000000, 90, 4, 2, 1},
1103 { 26000000, 216000000, 432, 26, 2, 8},
1104 { 12000000, 432000000, 432, 12, 1, 8},
1105 { 13000000, 432000000, 432, 13, 1, 8},
1106 { 19200000, 432000000, 90, 4, 1, 1},
1107 { 26000000, 432000000, 432, 26, 1, 8},
1108 { 0, 0, 0, 0, 0, 0 },
1109};
1110
1111static struct clk tegra_pll_p = {
1112 .name = "pll_p",
1113 .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
1114 .ops = &tegra_pll_ops,
1115 .reg = 0xa0,
1116 .input_min = 2000000,
1117 .input_max = 31000000,
1118 .parent = &tegra_clk_m,
1119 .cf_min = 1000000,
1120 .cf_max = 6000000,
1121 .vco_min = 20000000,
1122 .vco_max = 1400000000,
1123 .pll_table = tegra_pll_p_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001124 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001125};
1126
1127static struct clk tegra_pll_p_out1 = {
1128 .name = "pll_p_out1",
1129 .ops = &tegra_pll_div_ops,
1130 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1131 .parent = &tegra_pll_p,
1132 .reg = 0xa4,
1133 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001134 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001135};
1136
1137static struct clk tegra_pll_p_out2 = {
1138 .name = "pll_p_out2",
1139 .ops = &tegra_pll_div_ops,
1140 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1141 .parent = &tegra_pll_p,
1142 .reg = 0xa4,
1143 .reg_shift = 16,
Colin Cross71fc84c2010-06-07 20:49:46 -07001144 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001145};
1146
1147static struct clk tegra_pll_p_out3 = {
1148 .name = "pll_p_out3",
1149 .ops = &tegra_pll_div_ops,
1150 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1151 .parent = &tegra_pll_p,
1152 .reg = 0xa8,
1153 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001154 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001155};
1156
1157static struct clk tegra_pll_p_out4 = {
1158 .name = "pll_p_out4",
1159 .ops = &tegra_pll_div_ops,
1160 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1161 .parent = &tegra_pll_p,
1162 .reg = 0xa8,
1163 .reg_shift = 16,
Colin Cross71fc84c2010-06-07 20:49:46 -07001164 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001165};
1166
1167static struct clk_pll_table tegra_pll_a_table[] = {
1168 { 28800000, 56448000, 49, 25, 1, 1},
1169 { 28800000, 73728000, 64, 25, 1, 1},
1170 { 28800000, 11289600, 49, 25, 1, 1},
1171 { 28800000, 12288000, 64, 25, 1, 1},
Colin Cross71fc84c2010-06-07 20:49:46 -07001172 { 28800000, 24000000, 5, 6, 1, 1},
Colin Crossd8611962010-01-28 16:40:29 -08001173 { 0, 0, 0, 0, 0, 0 },
1174};
1175
1176static struct clk tegra_pll_a = {
1177 .name = "pll_a",
1178 .flags = PLL_HAS_CPCON,
1179 .ops = &tegra_pll_ops,
1180 .reg = 0xb0,
1181 .input_min = 2000000,
1182 .input_max = 31000000,
1183 .parent = &tegra_pll_p_out1,
1184 .cf_min = 1000000,
1185 .cf_max = 6000000,
1186 .vco_min = 20000000,
1187 .vco_max = 1400000000,
1188 .pll_table = tegra_pll_a_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001189 .max_rate = 56448000,
Colin Crossd8611962010-01-28 16:40:29 -08001190};
1191
1192static struct clk tegra_pll_a_out0 = {
1193 .name = "pll_a_out0",
1194 .ops = &tegra_pll_div_ops,
1195 .flags = DIV_U71,
1196 .parent = &tegra_pll_a,
1197 .reg = 0xb4,
1198 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001199 .max_rate = 56448000,
Colin Crossd8611962010-01-28 16:40:29 -08001200};
1201
1202static struct clk_pll_table tegra_pll_d_table[] = {
1203 { 12000000, 1000000000, 1000, 12, 1, 12},
1204 { 13000000, 1000000000, 1000, 13, 1, 12},
1205 { 19200000, 1000000000, 625, 12, 1, 8},
1206 { 26000000, 1000000000, 1000, 26, 1, 12},
1207 { 0, 0, 0, 0, 0, 0 },
1208};
1209
1210static struct clk tegra_pll_d = {
1211 .name = "pll_d",
1212 .flags = PLL_HAS_CPCON | PLLD,
1213 .ops = &tegra_pll_ops,
1214 .reg = 0xd0,
1215 .input_min = 2000000,
1216 .input_max = 40000000,
1217 .parent = &tegra_clk_m,
1218 .cf_min = 1000000,
1219 .cf_max = 6000000,
1220 .vco_min = 40000000,
1221 .vco_max = 1000000000,
1222 .pll_table = tegra_pll_d_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001223 .max_rate = 1000000000,
Colin Crossd8611962010-01-28 16:40:29 -08001224};
1225
1226static struct clk tegra_pll_d_out0 = {
1227 .name = "pll_d_out0",
1228 .ops = &tegra_pll_div_ops,
1229 .flags = DIV_2 | PLLD,
1230 .parent = &tegra_pll_d,
Colin Cross71fc84c2010-06-07 20:49:46 -07001231 .max_rate = 500000000,
Colin Crossd8611962010-01-28 16:40:29 -08001232};
1233
1234static struct clk_pll_table tegra_pll_u_table[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001235 { 12000000, 480000000, 960, 12, 2, 0},
1236 { 13000000, 480000000, 960, 13, 2, 0},
1237 { 19200000, 480000000, 200, 4, 2, 0},
1238 { 26000000, 480000000, 960, 26, 2, 0},
Colin Crossd8611962010-01-28 16:40:29 -08001239 { 0, 0, 0, 0, 0, 0 },
1240};
1241
1242static struct clk tegra_pll_u = {
1243 .name = "pll_u",
Colin Cross71fc84c2010-06-07 20:49:46 -07001244 .flags = PLLU,
Colin Crossd8611962010-01-28 16:40:29 -08001245 .ops = &tegra_pll_ops,
1246 .reg = 0xc0,
1247 .input_min = 2000000,
1248 .input_max = 40000000,
1249 .parent = &tegra_clk_m,
1250 .cf_min = 1000000,
1251 .cf_max = 6000000,
1252 .vco_min = 480000000,
1253 .vco_max = 960000000,
1254 .pll_table = tegra_pll_u_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001255 .max_rate = 480000000,
Colin Crossd8611962010-01-28 16:40:29 -08001256};
1257
1258static struct clk_pll_table tegra_pll_x_table[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001259 /* 1 GHz */
Colin Crossd8611962010-01-28 16:40:29 -08001260 { 12000000, 1000000000, 1000, 12, 1, 12},
1261 { 13000000, 1000000000, 1000, 13, 1, 12},
1262 { 19200000, 1000000000, 625, 12, 1, 8},
1263 { 26000000, 1000000000, 1000, 26, 1, 12},
Colin Cross71fc84c2010-06-07 20:49:46 -07001264
1265 /* 912 MHz */
1266 { 12000000, 912000000, 912, 12, 1, 12},
1267 { 13000000, 912000000, 912, 13, 1, 12},
1268 { 19200000, 912000000, 760, 16, 1, 8},
1269 { 26000000, 912000000, 912, 26, 1, 12},
1270
1271 /* 816 MHz */
1272 { 12000000, 816000000, 816, 12, 1, 12},
1273 { 13000000, 816000000, 816, 13, 1, 12},
1274 { 19200000, 816000000, 680, 16, 1, 8},
1275 { 26000000, 816000000, 816, 26, 1, 12},
1276
1277 /* 760 MHz */
1278 { 12000000, 760000000, 760, 12, 1, 12},
1279 { 13000000, 760000000, 760, 13, 1, 12},
1280 { 19200000, 760000000, 950, 24, 1, 8},
1281 { 26000000, 760000000, 760, 26, 1, 12},
1282
1283 /* 608 MHz */
1284 { 12000000, 608000000, 760, 12, 1, 12},
1285 { 13000000, 608000000, 760, 13, 1, 12},
1286 { 19200000, 608000000, 380, 12, 1, 8},
1287 { 26000000, 608000000, 760, 26, 1, 12},
1288
1289 /* 456 MHz */
1290 { 12000000, 456000000, 456, 12, 1, 12},
1291 { 13000000, 456000000, 456, 13, 1, 12},
1292 { 19200000, 456000000, 380, 16, 1, 8},
1293 { 26000000, 456000000, 456, 26, 1, 12},
1294
1295 /* 312 MHz */
1296 { 12000000, 312000000, 312, 12, 1, 12},
1297 { 13000000, 312000000, 312, 13, 1, 12},
1298 { 19200000, 312000000, 260, 16, 1, 8},
1299 { 26000000, 312000000, 312, 26, 1, 12},
1300
Colin Crossd8611962010-01-28 16:40:29 -08001301 { 0, 0, 0, 0, 0, 0 },
1302};
1303
1304static struct clk tegra_pll_x = {
1305 .name = "pll_x",
1306 .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG,
Colin Cross71fc84c2010-06-07 20:49:46 -07001307 .ops = &tegra_pllx_ops,
Colin Crossd8611962010-01-28 16:40:29 -08001308 .reg = 0xe0,
1309 .input_min = 2000000,
1310 .input_max = 31000000,
1311 .parent = &tegra_clk_m,
1312 .cf_min = 1000000,
1313 .cf_max = 6000000,
1314 .vco_min = 20000000,
1315 .vco_max = 1200000000,
1316 .pll_table = tegra_pll_x_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001317 .max_rate = 1000000000,
Colin Crossd8611962010-01-28 16:40:29 -08001318};
1319
1320static struct clk tegra_clk_d = {
1321 .name = "clk_d",
1322 .flags = PERIPH_NO_RESET,
1323 .ops = &tegra_clk_double_ops,
1324 .clk_num = 90,
1325 .reg = 0x34,
1326 .reg_shift = 12,
1327 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001328 .max_rate = 52000000,
Colin Crossd8611962010-01-28 16:40:29 -08001329};
1330
Colin Cross71fc84c2010-06-07 20:49:46 -07001331/* initialized before peripheral clocks */
1332static struct clk_mux_sel mux_audio_sync_clk[8+1];
1333static const struct audio_sources {
1334 const char *name;
1335 int value;
1336} mux_audio_sync_clk_sources[] = {
1337 { .name = "spdif_in", .value = 0 },
1338 { .name = "i2s1", .value = 1 },
1339 { .name = "i2s2", .value = 2 },
1340 { .name = "pll_a_out0", .value = 4 },
1341#if 0 /* FIXME: not implemented */
1342 { .name = "ac97", .value = 3 },
1343 { .name = "ext_audio_clk2", .value = 5 },
1344 { .name = "ext_audio_clk1", .value = 6 },
1345 { .name = "ext_vimclk", .value = 7 },
1346#endif
1347 { 0, 0 }
1348};
1349
1350static struct clk tegra_clk_audio = {
1351 .name = "audio",
1352 .inputs = mux_audio_sync_clk,
1353 .reg = 0x38,
1354 .max_rate = 24000000,
1355 .ops = &tegra_audio_sync_clk_ops
1356};
1357
Colin Crossd8611962010-01-28 16:40:29 -08001358static struct clk tegra_clk_audio_2x = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001359 .name = "audio_2x",
Colin Crossd8611962010-01-28 16:40:29 -08001360 .flags = PERIPH_NO_RESET,
Colin Cross71fc84c2010-06-07 20:49:46 -07001361 .max_rate = 48000000,
Colin Crossd8611962010-01-28 16:40:29 -08001362 .ops = &tegra_clk_double_ops,
1363 .clk_num = 89,
1364 .reg = 0x34,
1365 .reg_shift = 8,
Colin Cross71fc84c2010-06-07 20:49:46 -07001366 .parent = &tegra_clk_audio,
1367};
1368
1369struct clk_lookup tegra_audio_clk_lookups[] = {
1370 { .con_id = "audio", .clk = &tegra_clk_audio },
1371 { .con_id = "audio_2x", .clk = &tegra_clk_audio_2x }
1372};
1373
1374/* This is called after peripheral clocks are initialized, as the
1375 * audio_sync clock depends on some of the peripheral clocks.
1376 */
1377
1378static void init_audio_sync_clock_mux(void)
1379{
1380 int i;
1381 struct clk_mux_sel *sel = mux_audio_sync_clk;
1382 const struct audio_sources *src = mux_audio_sync_clk_sources;
1383 struct clk_lookup *lookup;
1384
1385 for (i = 0; src->name; i++, sel++, src++) {
1386 sel->input = tegra_get_clock_by_name(src->name);
1387 if (!sel->input)
1388 pr_err("%s: could not find clk %s\n", __func__,
1389 src->name);
1390 sel->value = src->value;
1391 }
1392
1393 lookup = tegra_audio_clk_lookups;
1394 for (i = 0; i < ARRAY_SIZE(tegra_audio_clk_lookups); i++, lookup++) {
1395 clk_init(lookup->clk);
1396 clkdev_add(lookup);
1397 }
Colin Crossd8611962010-01-28 16:40:29 -08001398}
Colin Crossd8611962010-01-28 16:40:29 -08001399
1400static struct clk_mux_sel mux_cclk[] = {
1401 { .input = &tegra_clk_m, .value = 0},
1402 { .input = &tegra_pll_c, .value = 1},
1403 { .input = &tegra_clk_32k, .value = 2},
1404 { .input = &tegra_pll_m, .value = 3},
1405 { .input = &tegra_pll_p, .value = 4},
1406 { .input = &tegra_pll_p_out4, .value = 5},
1407 { .input = &tegra_pll_p_out3, .value = 6},
1408 { .input = &tegra_clk_d, .value = 7},
1409 { .input = &tegra_pll_x, .value = 8},
1410 { 0, 0},
1411};
1412
1413static struct clk_mux_sel mux_sclk[] = {
1414 { .input = &tegra_clk_m, .value = 0},
1415 { .input = &tegra_pll_c_out1, .value = 1},
1416 { .input = &tegra_pll_p_out4, .value = 2},
1417 { .input = &tegra_pll_p_out3, .value = 3},
1418 { .input = &tegra_pll_p_out2, .value = 4},
1419 { .input = &tegra_clk_d, .value = 5},
1420 { .input = &tegra_clk_32k, .value = 6},
1421 { .input = &tegra_pll_m_out1, .value = 7},
1422 { 0, 0},
1423};
1424
Colin Cross71fc84c2010-06-07 20:49:46 -07001425static struct clk tegra_clk_cclk = {
1426 .name = "cclk",
Colin Crossd8611962010-01-28 16:40:29 -08001427 .inputs = mux_cclk,
1428 .reg = 0x20,
1429 .ops = &tegra_super_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001430 .max_rate = 1000000000,
Colin Crossd8611962010-01-28 16:40:29 -08001431};
1432
Colin Cross71fc84c2010-06-07 20:49:46 -07001433static struct clk tegra_clk_sclk = {
1434 .name = "sclk",
Colin Crossd8611962010-01-28 16:40:29 -08001435 .inputs = mux_sclk,
1436 .reg = 0x28,
1437 .ops = &tegra_super_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001438 .max_rate = 600000000,
1439};
1440
1441static struct clk tegra_clk_virtual_cpu = {
1442 .name = "cpu",
1443 .parent = &tegra_clk_cclk,
1444 .main = &tegra_pll_x,
1445 .backup = &tegra_clk_m,
1446 .ops = &tegra_cpu_ops,
1447 .max_rate = 1000000000,
1448 .dvfs = &tegra_dvfs_virtual_cpu_dvfs,
Colin Crossd8611962010-01-28 16:40:29 -08001449};
1450
1451static struct clk tegra_clk_hclk = {
1452 .name = "hclk",
1453 .flags = DIV_BUS,
Colin Cross71fc84c2010-06-07 20:49:46 -07001454 .parent = &tegra_clk_sclk,
Colin Crossd8611962010-01-28 16:40:29 -08001455 .reg = 0x30,
1456 .reg_shift = 4,
1457 .ops = &tegra_bus_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001458 .max_rate = 240000000,
Colin Crossd8611962010-01-28 16:40:29 -08001459};
1460
1461static struct clk tegra_clk_pclk = {
1462 .name = "pclk",
1463 .flags = DIV_BUS,
1464 .parent = &tegra_clk_hclk,
1465 .reg = 0x30,
1466 .reg_shift = 0,
1467 .ops = &tegra_bus_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001468 .max_rate = 108000000,
Colin Crossd8611962010-01-28 16:40:29 -08001469};
1470
1471static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
1472 { .input = &tegra_pll_m, .value = 0},
1473 { .input = &tegra_pll_c, .value = 1},
1474 { .input = &tegra_pll_p, .value = 2},
1475 { .input = &tegra_pll_a_out0, .value = 3},
1476 { 0, 0},
1477};
1478
1479static struct clk_mux_sel mux_pllm_pllc_pllp_clkm[] = {
1480 { .input = &tegra_pll_m, .value = 0},
1481 { .input = &tegra_pll_c, .value = 1},
1482 { .input = &tegra_pll_p, .value = 2},
1483 { .input = &tegra_clk_m, .value = 3},
1484 { 0, 0},
1485};
1486
1487static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
1488 { .input = &tegra_pll_p, .value = 0},
1489 { .input = &tegra_pll_c, .value = 1},
1490 { .input = &tegra_pll_m, .value = 2},
1491 { .input = &tegra_clk_m, .value = 3},
1492 { 0, 0},
1493};
1494
Colin Cross71fc84c2010-06-07 20:49:46 -07001495static struct clk_mux_sel mux_pllaout0_audio2x_pllp_clkm[] = {
1496 {.input = &tegra_pll_a_out0, .value = 0},
1497 {.input = &tegra_clk_audio_2x, .value = 1},
Colin Crossd8611962010-01-28 16:40:29 -08001498 {.input = &tegra_pll_p, .value = 2},
1499 {.input = &tegra_clk_m, .value = 3},
1500 { 0, 0},
1501};
1502
1503static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
1504 {.input = &tegra_pll_p, .value = 0},
1505 {.input = &tegra_pll_d_out0, .value = 1},
1506 {.input = &tegra_pll_c, .value = 2},
1507 {.input = &tegra_clk_m, .value = 3},
1508 { 0, 0},
1509};
1510
1511static struct clk_mux_sel mux_pllp_pllc_audio_clkm_clk32[] = {
1512 {.input = &tegra_pll_p, .value = 0},
1513 {.input = &tegra_pll_c, .value = 1},
Colin Cross71fc84c2010-06-07 20:49:46 -07001514 {.input = &tegra_clk_audio, .value = 2},
Colin Crossd8611962010-01-28 16:40:29 -08001515 {.input = &tegra_clk_m, .value = 3},
1516 {.input = &tegra_clk_32k, .value = 4},
1517 { 0, 0},
1518};
1519
1520static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
1521 {.input = &tegra_pll_p, .value = 0},
1522 {.input = &tegra_pll_c, .value = 1},
1523 {.input = &tegra_pll_m, .value = 2},
1524 { 0, 0},
1525};
1526
1527static struct clk_mux_sel mux_clk_m[] = {
1528 { .input = &tegra_clk_m, .value = 0},
1529 { 0, 0},
1530};
1531
1532static struct clk_mux_sel mux_pllp_out3[] = {
1533 { .input = &tegra_pll_p_out3, .value = 0},
1534 { 0, 0},
1535};
1536
1537static struct clk_mux_sel mux_plld[] = {
1538 { .input = &tegra_pll_d, .value = 0},
1539 { 0, 0},
1540};
1541
1542static struct clk_mux_sel mux_clk_32k[] = {
1543 { .input = &tegra_clk_32k, .value = 0},
1544 { 0, 0},
1545};
1546
Colin Cross71fc84c2010-06-07 20:49:46 -07001547#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
Colin Crossd8611962010-01-28 16:40:29 -08001548 { \
1549 .name = _name, \
1550 .lookup = { \
1551 .dev_id = _dev, \
1552 .con_id = _con, \
1553 }, \
1554 .ops = &tegra_periph_clk_ops, \
1555 .clk_num = _clk_num, \
1556 .reg = _reg, \
1557 .inputs = _inputs, \
1558 .flags = _flags, \
Colin Cross71fc84c2010-06-07 20:49:46 -07001559 .max_rate = _max, \
Colin Crossd8611962010-01-28 16:40:29 -08001560 }
1561
1562struct clk tegra_periph_clks[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001563 PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET),
1564 PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0),
1565 PERIPH_CLK("i2s1", "i2s.0", NULL, 11, 0x100, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
1566 PERIPH_CLK("i2s2", "i2s.1", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
Colin Crossd8611962010-01-28 16:40:29 -08001567 /* FIXME: spdif has 2 clocks but 1 enable */
Colin Cross71fc84c2010-06-07 20:49:46 -07001568 PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
1569 PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71),
1570 PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71),
1571 PERIPH_CLK("spi", "spi", NULL, 43, 0x114, 40000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1572 PERIPH_CLK("xio", "xio", NULL, 45, 0x120, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1573 PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1574 PERIPH_CLK("sbc1", "spi_tegra.0", NULL, 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1575 PERIPH_CLK("sbc2", "spi_tegra.1", NULL, 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1576 PERIPH_CLK("sbc3", "spi_tegra.2", NULL, 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1577 PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1578 PERIPH_CLK("ide", "ide", NULL, 25, 0x144, 100000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
1579 PERIPH_CLK("ndflash", "tegra_nand", NULL, 13, 0x160, 164000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
Colin Crossd8611962010-01-28 16:40:29 -08001580 /* FIXME: vfir shares an enable with uartb */
Colin Cross71fc84c2010-06-07 20:49:46 -07001581 PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1582 PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1583 PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1584 PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1585 PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x160, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1586 PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
1587 PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* max rate ??? */
Colin Crossd8611962010-01-28 16:40:29 -08001588 /* FIXME: what is la? */
Colin Cross71fc84c2010-06-07 20:49:46 -07001589 PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1590 PERIPH_CLK("owr", "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1591 PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, 92000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
1592 PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1593 PERIPH_CLK("i2c1", "tegra-i2c.0", NULL, 12, 0x124, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
1594 PERIPH_CLK("i2c2", "tegra-i2c.1", NULL, 54, 0x198, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
1595 PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
1596 PERIPH_CLK("dvc", "tegra-i2c.3", NULL, 47, 0x128, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
1597 PERIPH_CLK("i2c1_i2c", "tegra-i2c.0", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
1598 PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
1599 PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
1600 PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
1601 PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
1602 PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
1603 PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
1604 PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
1605 PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
1606 PERIPH_CLK("3d", "3d", NULL, 24, 0x158, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET), /* scales with voltage and process_id */
1607 PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
Colin Crossd8611962010-01-28 16:40:29 -08001608 /* FIXME: vi and vi_sensor share an enable */
Colin Cross71fc84c2010-06-07 20:49:46 -07001609 PERIPH_CLK("vi", "vi", NULL, 20, 0x148, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
1610 PERIPH_CLK("vi_sensor", "vi_sensor", NULL, 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET), /* scales with voltage and process_id */
1611 PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
1612 PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 250000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
1613 PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, 166000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
Colin Crossd8611962010-01-28 16:40:29 -08001614 /* FIXME: cve and tvo share an enable */
Colin Cross71fc84c2010-06-07 20:49:46 -07001615 PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
1616 PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
1617 PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, 148500000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
1618 PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
1619 PERIPH_CLK("disp1", "tegrafb.0", NULL, 27, 0x138, 190000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
1620 PERIPH_CLK("disp2", "tegrafb.1", NULL, 26, 0x13c, 190000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
1621 PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
1622 PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
1623 PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
1624 PERIPH_CLK("emc", "emc", NULL, 57, 0x19c, 800000000, mux_pllm_pllc_pllp_clkm, MUX | DIV_U71 | PERIPH_EMC_ENB),
1625 PERIPH_CLK("dsi", "dsi", NULL, 48, 0, 500000000, mux_plld, 0), /* scales with voltage */
1626 PERIPH_CLK("csi", "csi", NULL, 52, 0, 72000000, mux_pllp_out3, 0),
1627 PERIPH_CLK("isp", "isp", NULL, 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */
1628 PERIPH_CLK("csus", "csus", NULL, 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET),
Colin Crossd8611962010-01-28 16:40:29 -08001629};
1630
1631#define CLK_DUPLICATE(_name, _dev, _con) \
1632 { \
1633 .name = _name, \
1634 .lookup = { \
1635 .dev_id = _dev, \
1636 .con_id = _con, \
1637 }, \
1638 }
1639
1640/* Some clocks may be used by different drivers depending on the board
1641 * configuration. List those here to register them twice in the clock lookup
1642 * table under two names.
1643 */
1644struct clk_duplicate tegra_clk_duplicates[] = {
1645 CLK_DUPLICATE("uarta", "tegra_uart.0", NULL),
1646 CLK_DUPLICATE("uartb", "tegra_uart.1", NULL),
1647 CLK_DUPLICATE("uartc", "tegra_uart.2", NULL),
1648 CLK_DUPLICATE("uartd", "tegra_uart.3", NULL),
1649 CLK_DUPLICATE("uarte", "tegra_uart.4", NULL),
Colin Cross71fc84c2010-06-07 20:49:46 -07001650 CLK_DUPLICATE("host1x", "tegrafb.0", "host1x"),
1651 CLK_DUPLICATE("host1x", "tegrafb.1", "host1x"),
1652 CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
Colin Crossd8611962010-01-28 16:40:29 -08001653};
1654
1655#define CLK(dev, con, ck) \
1656 { \
1657 .dev_id = dev, \
1658 .con_id = con, \
1659 .clk = ck, \
1660 }
1661
1662struct clk_lookup tegra_clk_lookups[] = {
1663 /* external root sources */
1664 CLK(NULL, "32k_clk", &tegra_clk_32k),
1665 CLK(NULL, "pll_s", &tegra_pll_s),
1666 CLK(NULL, "clk_m", &tegra_clk_m),
1667 CLK(NULL, "pll_m", &tegra_pll_m),
1668 CLK(NULL, "pll_m_out1", &tegra_pll_m_out1),
1669 CLK(NULL, "pll_c", &tegra_pll_c),
1670 CLK(NULL, "pll_c_out1", &tegra_pll_c_out1),
1671 CLK(NULL, "pll_p", &tegra_pll_p),
1672 CLK(NULL, "pll_p_out1", &tegra_pll_p_out1),
1673 CLK(NULL, "pll_p_out2", &tegra_pll_p_out2),
1674 CLK(NULL, "pll_p_out3", &tegra_pll_p_out3),
1675 CLK(NULL, "pll_p_out4", &tegra_pll_p_out4),
1676 CLK(NULL, "pll_a", &tegra_pll_a),
1677 CLK(NULL, "pll_a_out0", &tegra_pll_a_out0),
1678 CLK(NULL, "pll_d", &tegra_pll_d),
1679 CLK(NULL, "pll_d_out0", &tegra_pll_d_out0),
1680 CLK(NULL, "pll_u", &tegra_pll_u),
1681 CLK(NULL, "pll_x", &tegra_pll_x),
Colin Cross71fc84c2010-06-07 20:49:46 -07001682 CLK(NULL, "cclk", &tegra_clk_cclk),
1683 CLK(NULL, "sclk", &tegra_clk_sclk),
Colin Crossd8611962010-01-28 16:40:29 -08001684 CLK(NULL, "hclk", &tegra_clk_hclk),
1685 CLK(NULL, "pclk", &tegra_clk_pclk),
1686 CLK(NULL, "clk_d", &tegra_clk_d),
Colin Cross71fc84c2010-06-07 20:49:46 -07001687 CLK(NULL, "cpu", &tegra_clk_virtual_cpu),
Colin Crossd8611962010-01-28 16:40:29 -08001688};
1689
1690void __init tegra2_init_clocks(void)
1691{
1692 int i;
1693 struct clk_lookup *cl;
1694 struct clk *c;
1695 struct clk_duplicate *cd;
1696
1697 for (i = 0; i < ARRAY_SIZE(tegra_clk_lookups); i++) {
1698 cl = &tegra_clk_lookups[i];
1699 clk_init(cl->clk);
1700 clkdev_add(cl);
1701 }
1702
1703 for (i = 0; i < ARRAY_SIZE(tegra_periph_clks); i++) {
1704 c = &tegra_periph_clks[i];
1705 cl = &c->lookup;
1706 cl->clk = c;
1707
1708 clk_init(cl->clk);
1709 clkdev_add(cl);
1710 }
1711
1712 for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
1713 cd = &tegra_clk_duplicates[i];
1714 c = tegra_get_clock_by_name(cd->name);
1715 if (c) {
1716 cl = &cd->lookup;
1717 cl->clk = c;
1718 clkdev_add(cl);
1719 } else {
1720 pr_err("%s: Unknown duplicate clock %s\n", __func__,
1721 cd->name);
1722 }
1723 }
Colin Cross71fc84c2010-06-07 20:49:46 -07001724
1725 init_audio_sync_clock_mux();
Colin Crossd8611962010-01-28 16:40:29 -08001726}
Colin Cross71fc84c2010-06-07 20:49:46 -07001727
1728#ifdef CONFIG_PM
1729static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM +
1730 PERIPH_CLK_SOURCE_NUM + 3];
1731
1732void tegra_clk_suspend(void)
1733{
1734 unsigned long off, i;
1735 u32 *ctx = clk_rst_suspend;
1736
1737 *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK;
1738
1739 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
1740 off += 4) {
1741 if (off == PERIPH_CLK_SOURCE_EMC)
1742 continue;
1743 *ctx++ = clk_readl(off);
1744 }
1745
1746 off = RST_DEVICES;
1747 for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
1748 *ctx++ = clk_readl(off);
1749
1750 off = CLK_OUT_ENB;
1751 for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
1752 *ctx++ = clk_readl(off);
1753
1754 *ctx++ = clk_readl(MISC_CLK_ENB);
1755 *ctx++ = clk_readl(CLK_MASK_ARM);
1756}
1757
1758void tegra_clk_resume(void)
1759{
1760 unsigned long off, i;
1761 const u32 *ctx = clk_rst_suspend;
1762 u32 val;
1763
1764 val = clk_readl(OSC_CTRL) & ~OSC_CTRL_MASK;
1765 val |= *ctx++;
1766 clk_writel(val, OSC_CTRL);
1767
1768 /* enable all clocks before configuring clock sources */
1769 clk_writel(0xbffffff9ul, CLK_OUT_ENB);
1770 clk_writel(0xfefffff7ul, CLK_OUT_ENB + 4);
1771 clk_writel(0x77f01bfful, CLK_OUT_ENB + 8);
1772 wmb();
1773
1774 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
1775 off += 4) {
1776 if (off == PERIPH_CLK_SOURCE_EMC)
1777 continue;
1778 clk_writel(*ctx++, off);
1779 }
1780 wmb();
1781
1782 off = RST_DEVICES;
1783 for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
1784 clk_writel(*ctx++, off);
1785 wmb();
1786
1787 off = CLK_OUT_ENB;
1788 for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
1789 clk_writel(*ctx++, off);
1790 wmb();
1791
1792 clk_writel(*ctx++, MISC_CLK_ENB);
1793 clk_writel(*ctx++, CLK_MASK_ARM);
1794}
1795#endif