blob: 2dd2b031a85303df49cc5f720e845878c7830fbb [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>
Jean-Christop PLAGNIOL-VILLARD6d803ba2010-11-17 10:04:33 +010027#include <linux/clkdev.h>
Colin Crossd8611962010-01-28 16:40:29 -080028
29#include <mach/iomap.h>
Colin Cross2ea67fd2010-10-04 08:49:49 -070030#include <mach/suspend.h>
Colin Crossd8611962010-01-28 16:40:29 -080031
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
Mike Rapoport8d685bc2010-09-27 11:26:32 +0200113#define PLLE_MISC_READY (1 << 15)
114
Colin Crossd8611962010-01-28 16:40:29 -0800115#define PERIPH_CLK_TO_ENB_REG(c) ((c->clk_num / 32) * 4)
116#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->clk_num / 32) * 8)
117#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->clk_num % 32))
118
119#define SUPER_CLK_MUX 0x00
120#define SUPER_STATE_SHIFT 28
121#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT)
122#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT)
123#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT)
124#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT)
125#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT)
126#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT)
127#define SUPER_SOURCE_MASK 0xF
128#define SUPER_FIQ_SOURCE_SHIFT 12
129#define SUPER_IRQ_SOURCE_SHIFT 8
130#define SUPER_RUN_SOURCE_SHIFT 4
131#define SUPER_IDLE_SOURCE_SHIFT 0
132
133#define SUPER_CLK_DIVIDER 0x04
134
135#define BUS_CLK_DISABLE (1<<3)
136#define BUS_CLK_DIV_MASK 0x3
137
138static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
139
140#define clk_writel(value, reg) \
141 __raw_writel(value, (u32)reg_clk_base + (reg))
142#define clk_readl(reg) \
143 __raw_readl((u32)reg_clk_base + (reg))
144
145unsigned long clk_measure_input_freq(void)
146{
147 u32 clock_autodetect;
148 clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
149 do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
150 clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
151 if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
152 return 12000000;
153 } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
154 return 13000000;
155 } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
156 return 19200000;
157 } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
158 return 26000000;
159 } else {
160 pr_err("%s: Unexpected clock autodetect value %d", __func__, clock_autodetect);
161 BUG();
162 return 0;
163 }
164}
165
Colin Cross71fc84c2010-06-07 20:49:46 -0700166static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate)
Colin Crossd8611962010-01-28 16:40:29 -0800167{
Colin Cross71fc84c2010-06-07 20:49:46 -0700168 s64 divider_u71 = parent_rate * 2;
169 divider_u71 += rate - 1;
170 do_div(divider_u71, rate);
Colin Crossd8611962010-01-28 16:40:29 -0800171
Colin Cross71fc84c2010-06-07 20:49:46 -0700172 if (divider_u71 - 2 < 0)
173 return 0;
Colin Crossd8611962010-01-28 16:40:29 -0800174
Colin Cross71fc84c2010-06-07 20:49:46 -0700175 if (divider_u71 - 2 > 255)
Colin Crossd8611962010-01-28 16:40:29 -0800176 return -EINVAL;
177
178 return divider_u71 - 2;
179}
180
Colin Cross71fc84c2010-06-07 20:49:46 -0700181static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
Colin Crossd8611962010-01-28 16:40:29 -0800182{
Colin Cross71fc84c2010-06-07 20:49:46 -0700183 s64 divider_u16;
Colin Crossd8611962010-01-28 16:40:29 -0800184
Colin Cross71fc84c2010-06-07 20:49:46 -0700185 divider_u16 = parent_rate;
186 divider_u16 += rate - 1;
187 do_div(divider_u16, rate);
188
189 if (divider_u16 - 1 < 0)
190 return 0;
191
192 if (divider_u16 - 1 > 255)
193 return -EINVAL;
194
195 return divider_u16 - 1;
Colin Crossd8611962010-01-28 16:40:29 -0800196}
197
Colin Crossd8611962010-01-28 16:40:29 -0800198/* clk_m functions */
199static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c)
200{
201 u32 auto_clock_control = clk_readl(OSC_CTRL) & ~OSC_CTRL_OSC_FREQ_MASK;
202
203 c->rate = clk_measure_input_freq();
204 switch (c->rate) {
205 case 12000000:
206 auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
207 break;
208 case 13000000:
209 auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
210 break;
211 case 19200000:
212 auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
213 break;
214 case 26000000:
215 auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
216 break;
217 default:
218 pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
219 BUG();
220 }
221 clk_writel(auto_clock_control, OSC_CTRL);
222 return c->rate;
223}
224
225static void tegra2_clk_m_init(struct clk *c)
226{
227 pr_debug("%s on clock %s\n", __func__, c->name);
228 tegra2_clk_m_autodetect_rate(c);
229}
230
231static int tegra2_clk_m_enable(struct clk *c)
232{
233 pr_debug("%s on clock %s\n", __func__, c->name);
234 return 0;
235}
236
237static void tegra2_clk_m_disable(struct clk *c)
238{
239 pr_debug("%s on clock %s\n", __func__, c->name);
240 BUG();
241}
242
243static struct clk_ops tegra_clk_m_ops = {
244 .init = tegra2_clk_m_init,
245 .enable = tegra2_clk_m_enable,
246 .disable = tegra2_clk_m_disable,
247};
248
249/* super clock functions */
250/* "super clocks" on tegra have two-stage muxes and a clock skipping
251 * super divider. We will ignore the clock skipping divider, since we
252 * can't lower the voltage when using the clock skip, but we can if we
253 * lower the PLL frequency.
254 */
255static void tegra2_super_clk_init(struct clk *c)
256{
257 u32 val;
258 int source;
259 int shift;
260 const struct clk_mux_sel *sel;
261 val = clk_readl(c->reg + SUPER_CLK_MUX);
262 c->state = ON;
263 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
264 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
265 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
266 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
267 source = (val >> shift) & SUPER_SOURCE_MASK;
268 for (sel = c->inputs; sel->input != NULL; sel++) {
269 if (sel->value == source)
270 break;
271 }
272 BUG_ON(sel->input == NULL);
273 c->parent = sel->input;
Colin Crossd8611962010-01-28 16:40:29 -0800274}
275
276static int tegra2_super_clk_enable(struct clk *c)
277{
278 clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
279 return 0;
280}
281
282static void tegra2_super_clk_disable(struct clk *c)
283{
284 pr_debug("%s on clock %s\n", __func__, c->name);
285
286 /* oops - don't disable the CPU clock! */
287 BUG();
288}
289
290static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p)
291{
292 u32 val;
293 const struct clk_mux_sel *sel;
294 int shift;
Colin Cross71fc84c2010-06-07 20:49:46 -0700295
Colin Crossd8611962010-01-28 16:40:29 -0800296 val = clk_readl(c->reg + SUPER_CLK_MUX);;
297 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
298 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
299 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
300 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
301 for (sel = c->inputs; sel->input != NULL; sel++) {
302 if (sel->input == p) {
Colin Crossd8611962010-01-28 16:40:29 -0800303 val &= ~(SUPER_SOURCE_MASK << shift);
304 val |= sel->value << shift;
Colin Cross71fc84c2010-06-07 20:49:46 -0700305
306 if (c->refcnt)
307 clk_enable_locked(p);
308
Colin Crossd8611962010-01-28 16:40:29 -0800309 clk_writel(val, c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -0700310
311 if (c->refcnt && c->parent)
312 clk_disable_locked(c->parent);
313
314 clk_reparent(c, p);
Colin Crossd8611962010-01-28 16:40:29 -0800315 return 0;
316 }
317 }
318 return -EINVAL;
319}
320
321static struct clk_ops tegra_super_ops = {
322 .init = tegra2_super_clk_init,
323 .enable = tegra2_super_clk_enable,
324 .disable = tegra2_super_clk_disable,
325 .set_parent = tegra2_super_clk_set_parent,
Colin Cross71fc84c2010-06-07 20:49:46 -0700326};
327
328/* virtual cpu clock functions */
329/* some clocks can not be stopped (cpu, memory bus) while the SoC is running.
330 To change the frequency of these clocks, the parent pll may need to be
331 reprogrammed, so the clock must be moved off the pll, the pll reprogrammed,
332 and then the clock moved back to the pll. To hide this sequence, a virtual
333 clock handles it.
334 */
335static void tegra2_cpu_clk_init(struct clk *c)
336{
337}
338
339static int tegra2_cpu_clk_enable(struct clk *c)
340{
341 return 0;
342}
343
344static void tegra2_cpu_clk_disable(struct clk *c)
345{
346 pr_debug("%s on clock %s\n", __func__, c->name);
347
348 /* oops - don't disable the CPU clock! */
349 BUG();
350}
351
352static int tegra2_cpu_clk_set_rate(struct clk *c, unsigned long rate)
353{
354 int ret;
355 ret = clk_set_parent_locked(c->parent, c->backup);
356 if (ret) {
357 pr_err("Failed to switch cpu to clock %s\n", c->backup->name);
358 return ret;
359 }
360
361 ret = clk_set_rate_locked(c->main, rate);
362 if (ret) {
363 pr_err("Failed to change cpu pll to %lu\n", rate);
364 return ret;
365 }
366
367 ret = clk_set_parent_locked(c->parent, c->main);
368 if (ret) {
369 pr_err("Failed to switch cpu to clock %s\n", c->main->name);
370 return ret;
371 }
372
373 return 0;
374}
375
376static struct clk_ops tegra_cpu_ops = {
377 .init = tegra2_cpu_clk_init,
378 .enable = tegra2_cpu_clk_enable,
379 .disable = tegra2_cpu_clk_disable,
380 .set_rate = tegra2_cpu_clk_set_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800381};
382
383/* bus clock functions */
384static void tegra2_bus_clk_init(struct clk *c)
385{
386 u32 val = clk_readl(c->reg);
387 c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
388 c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
389 c->mul = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800390}
391
392static int tegra2_bus_clk_enable(struct clk *c)
393{
394 u32 val = clk_readl(c->reg);
395 val &= ~(BUS_CLK_DISABLE << c->reg_shift);
396 clk_writel(val, c->reg);
397 return 0;
398}
399
400static void tegra2_bus_clk_disable(struct clk *c)
401{
402 u32 val = clk_readl(c->reg);
403 val |= BUS_CLK_DISABLE << c->reg_shift;
404 clk_writel(val, c->reg);
405}
406
407static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate)
408{
409 u32 val = clk_readl(c->reg);
410 unsigned long parent_rate = c->parent->rate;
411 int i;
412 for (i = 1; i <= 4; i++) {
413 if (rate == parent_rate / i) {
414 val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
415 val |= (i - 1) << c->reg_shift;
416 clk_writel(val, c->reg);
417 c->div = i;
418 c->mul = 1;
419 return 0;
420 }
421 }
422 return -EINVAL;
423}
424
425static struct clk_ops tegra_bus_ops = {
426 .init = tegra2_bus_clk_init,
427 .enable = tegra2_bus_clk_enable,
428 .disable = tegra2_bus_clk_disable,
429 .set_rate = tegra2_bus_clk_set_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800430};
431
432/* PLL Functions */
Colin Crossd8611962010-01-28 16:40:29 -0800433static int tegra2_pll_clk_wait_for_lock(struct clk *c)
434{
435 ktime_t before;
436
437 before = ktime_get();
Colin Cross71fc84c2010-06-07 20:49:46 -0700438
Colin Crossd8611962010-01-28 16:40:29 -0800439 while (!(clk_readl(c->reg + PLL_BASE) & PLL_BASE_LOCK)) {
440 if (ktime_us_delta(ktime_get(), before) > 5000) {
441 pr_err("Timed out waiting for lock bit on pll %s",
442 c->name);
443 return -1;
444 }
445 }
446
447 return 0;
448}
449
450static void tegra2_pll_clk_init(struct clk *c)
451{
452 u32 val = clk_readl(c->reg + PLL_BASE);
453
454 c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
455
456 if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
457 pr_warning("Clock %s has unknown fixed frequency\n", c->name);
Colin Cross71fc84c2010-06-07 20:49:46 -0700458 c->mul = 1;
459 c->div = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800460 } else if (val & PLL_BASE_BYPASS) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700461 c->mul = 1;
462 c->div = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800463 } else {
Colin Cross71fc84c2010-06-07 20:49:46 -0700464 c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
465 c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
466 if (c->flags & PLLU)
467 c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
468 else
469 c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
Colin Crossd8611962010-01-28 16:40:29 -0800470 }
Colin Crossd8611962010-01-28 16:40:29 -0800471}
472
473static int tegra2_pll_clk_enable(struct clk *c)
474{
475 u32 val;
476 pr_debug("%s on clock %s\n", __func__, c->name);
477
478 val = clk_readl(c->reg + PLL_BASE);
479 val &= ~PLL_BASE_BYPASS;
480 val |= PLL_BASE_ENABLE;
481 clk_writel(val, c->reg + PLL_BASE);
482
483 val = clk_readl(c->reg + PLL_MISC(c));
Colin Cross71fc84c2010-06-07 20:49:46 -0700484 val |= PLL_MISC_LOCK_ENABLE(c);
Colin Crossd8611962010-01-28 16:40:29 -0800485 clk_writel(val, c->reg + PLL_MISC(c));
486
487 tegra2_pll_clk_wait_for_lock(c);
488
489 return 0;
490}
491
492static void tegra2_pll_clk_disable(struct clk *c)
493{
494 u32 val;
495 pr_debug("%s on clock %s\n", __func__, c->name);
496
497 val = clk_readl(c->reg);
498 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
499 clk_writel(val, c->reg);
500}
501
502static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate)
503{
504 u32 val;
505 unsigned long input_rate;
506 const struct clk_pll_table *sel;
507
508 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
509 BUG_ON(c->refcnt != 0);
510
511 input_rate = c->parent->rate;
512 for (sel = c->pll_table; sel->input_rate != 0; sel++) {
513 if (sel->input_rate == input_rate && sel->output_rate == rate) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700514 c->mul = sel->n;
515 c->div = sel->m * sel->p;
Colin Crossd8611962010-01-28 16:40:29 -0800516
517 val = clk_readl(c->reg + PLL_BASE);
518 if (c->flags & PLL_FIXED)
519 val |= PLL_BASE_OVERRIDE;
520 val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK |
521 PLL_BASE_DIVM_MASK);
Colin Cross71fc84c2010-06-07 20:49:46 -0700522 val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
523 (sel->n << PLL_BASE_DIVN_SHIFT);
524 BUG_ON(sel->p < 1 || sel->p > 2);
525 if (c->flags & PLLU) {
526 if (sel->p == 1)
527 val |= PLLU_BASE_POST_DIV;
528 } else {
529 if (sel->p == 2)
530 val |= 1 << PLL_BASE_DIVP_SHIFT;
531 }
Colin Crossd8611962010-01-28 16:40:29 -0800532 clk_writel(val, c->reg + PLL_BASE);
533
534 if (c->flags & PLL_HAS_CPCON) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700535 val = clk_readl(c->reg + PLL_MISC(c));
536 val &= ~PLL_MISC_CPCON_MASK;
537 val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
Colin Crossd8611962010-01-28 16:40:29 -0800538 clk_writel(val, c->reg + PLL_MISC(c));
539 }
540
541 if (c->state == ON)
542 tegra2_pll_clk_enable(c);
543
Colin Crossd8611962010-01-28 16:40:29 -0800544 return 0;
545 }
546 }
547 return -EINVAL;
548}
549
550static struct clk_ops tegra_pll_ops = {
551 .init = tegra2_pll_clk_init,
552 .enable = tegra2_pll_clk_enable,
553 .disable = tegra2_pll_clk_disable,
554 .set_rate = tegra2_pll_clk_set_rate,
Colin Cross71fc84c2010-06-07 20:49:46 -0700555};
556
557static void tegra2_pllx_clk_init(struct clk *c)
558{
559 tegra2_pll_clk_init(c);
560
561 if (tegra_sku_id() == 7)
562 c->max_rate = 750000000;
563}
564
565static struct clk_ops tegra_pllx_ops = {
566 .init = tegra2_pllx_clk_init,
567 .enable = tegra2_pll_clk_enable,
568 .disable = tegra2_pll_clk_disable,
569 .set_rate = tegra2_pll_clk_set_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800570};
571
Mike Rapoport8d685bc2010-09-27 11:26:32 +0200572static int tegra2_plle_clk_enable(struct clk *c)
573{
574 u32 val;
575
576 pr_debug("%s on clock %s\n", __func__, c->name);
577
578 mdelay(1);
579
580 val = clk_readl(c->reg + PLL_BASE);
581 if (!(val & PLLE_MISC_READY))
582 return -EBUSY;
583
584 val = clk_readl(c->reg + PLL_BASE);
585 val |= PLL_BASE_ENABLE | PLL_BASE_BYPASS;
586 clk_writel(val, c->reg + PLL_BASE);
587
588 return 0;
589}
590
591static struct clk_ops tegra_plle_ops = {
592 .init = tegra2_pll_clk_init,
593 .enable = tegra2_plle_clk_enable,
594 .set_rate = tegra2_pll_clk_set_rate,
595};
596
Colin Crossd8611962010-01-28 16:40:29 -0800597/* Clock divider ops */
598static void tegra2_pll_div_clk_init(struct clk *c)
599{
600 u32 val = clk_readl(c->reg);
601 u32 divu71;
602 val >>= c->reg_shift;
603 c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
604 if (!(val & PLL_OUT_RESET_DISABLE))
605 c->state = OFF;
606
607 if (c->flags & DIV_U71) {
608 divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
609 c->div = (divu71 + 2);
610 c->mul = 2;
611 } else if (c->flags & DIV_2) {
612 c->div = 2;
613 c->mul = 1;
614 } else {
615 c->div = 1;
616 c->mul = 1;
617 }
Colin Crossd8611962010-01-28 16:40:29 -0800618}
619
620static int tegra2_pll_div_clk_enable(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 return 0;
637 } else if (c->flags & DIV_2) {
638 BUG_ON(!(c->flags & PLLD));
639 val = clk_readl(c->reg);
640 val &= ~PLLD_MISC_DIV_RST;
641 clk_writel(val, c->reg);
642 return 0;
643 }
644 return -EINVAL;
645}
646
647static void tegra2_pll_div_clk_disable(struct clk *c)
648{
649 u32 val;
650 u32 new_val;
651
652 pr_debug("%s: %s\n", __func__, c->name);
653 if (c->flags & DIV_U71) {
654 val = clk_readl(c->reg);
655 new_val = val >> c->reg_shift;
656 new_val &= 0xFFFF;
657
658 new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
659
660 val &= ~(0xFFFF << c->reg_shift);
661 val |= new_val << c->reg_shift;
662 clk_writel(val, c->reg);
663 } else if (c->flags & DIV_2) {
664 BUG_ON(!(c->flags & PLLD));
665 val = clk_readl(c->reg);
666 val |= PLLD_MISC_DIV_RST;
667 clk_writel(val, c->reg);
668 }
669}
670
671static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
672{
673 u32 val;
674 u32 new_val;
675 int divider_u71;
676 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
677 if (c->flags & DIV_U71) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700678 divider_u71 = clk_div71_get_divider(c->parent->rate, rate);
Colin Crossd8611962010-01-28 16:40:29 -0800679 if (divider_u71 >= 0) {
680 val = clk_readl(c->reg);
681 new_val = val >> c->reg_shift;
682 new_val &= 0xFFFF;
683 if (c->flags & DIV_U71_FIXED)
684 new_val |= PLL_OUT_OVERRIDE;
685 new_val &= ~PLL_OUT_RATIO_MASK;
686 new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
687
688 val &= ~(0xFFFF << c->reg_shift);
689 val |= new_val << c->reg_shift;
690 clk_writel(val, c->reg);
691 c->div = divider_u71 + 2;
692 c->mul = 2;
Colin Crossd8611962010-01-28 16:40:29 -0800693 return 0;
694 }
695 } else if (c->flags & DIV_2) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700696 if (c->parent->rate == rate * 2)
Colin Crossd8611962010-01-28 16:40:29 -0800697 return 0;
Colin Crossd8611962010-01-28 16:40:29 -0800698 }
699 return -EINVAL;
700}
701
Colin Cross71fc84c2010-06-07 20:49:46 -0700702static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
703{
704 int divider;
705 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
706
707 if (c->flags & DIV_U71) {
708 divider = clk_div71_get_divider(c->parent->rate, rate);
709 if (divider < 0)
710 return divider;
711 return c->parent->rate * 2 / (divider + 2);
712 } else if (c->flags & DIV_2) {
713 return c->parent->rate / 2;
714 }
715 return -EINVAL;
716}
Colin Crossd8611962010-01-28 16:40:29 -0800717
718static struct clk_ops tegra_pll_div_ops = {
719 .init = tegra2_pll_div_clk_init,
720 .enable = tegra2_pll_div_clk_enable,
721 .disable = tegra2_pll_div_clk_disable,
722 .set_rate = tegra2_pll_div_clk_set_rate,
Colin Cross71fc84c2010-06-07 20:49:46 -0700723 .round_rate = tegra2_pll_div_clk_round_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800724};
725
726/* Periph clk ops */
727
728static void tegra2_periph_clk_init(struct clk *c)
729{
730 u32 val = clk_readl(c->reg);
731 const struct clk_mux_sel *mux = 0;
732 const struct clk_mux_sel *sel;
733 if (c->flags & MUX) {
734 for (sel = c->inputs; sel->input != NULL; sel++) {
735 if (val >> PERIPH_CLK_SOURCE_SHIFT == sel->value)
736 mux = sel;
737 }
738 BUG_ON(!mux);
739
740 c->parent = mux->input;
741 } else {
742 c->parent = c->inputs[0].input;
743 }
744
745 if (c->flags & DIV_U71) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700746 u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
Colin Crossd8611962010-01-28 16:40:29 -0800747 c->div = divu71 + 2;
748 c->mul = 2;
Colin Cross71fc84c2010-06-07 20:49:46 -0700749 } else if (c->flags & DIV_U16) {
750 u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
751 c->div = divu16 + 1;
752 c->mul = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800753 } else {
754 c->div = 1;
755 c->mul = 1;
756 }
757
758 c->state = ON;
759 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
760 PERIPH_CLK_TO_ENB_BIT(c)))
761 c->state = OFF;
762 if (!(c->flags & PERIPH_NO_RESET))
763 if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
764 PERIPH_CLK_TO_ENB_BIT(c))
765 c->state = OFF;
Colin Crossd8611962010-01-28 16:40:29 -0800766}
767
768static int tegra2_periph_clk_enable(struct clk *c)
769{
770 u32 val;
771 pr_debug("%s on clock %s\n", __func__, c->name);
772
773 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
774 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
775 if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET))
776 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
777 RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
778 if (c->flags & PERIPH_EMC_ENB) {
779 /* The EMC peripheral clock has 2 extra enable bits */
780 /* FIXME: Do they need to be disabled? */
781 val = clk_readl(c->reg);
782 val |= 0x3 << 24;
783 clk_writel(val, c->reg);
784 }
785 return 0;
786}
787
788static void tegra2_periph_clk_disable(struct clk *c)
789{
790 pr_debug("%s on clock %s\n", __func__, c->name);
791
792 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
793 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
794}
795
796void tegra2_periph_reset_deassert(struct clk *c)
797{
798 pr_debug("%s on clock %s\n", __func__, c->name);
799 if (!(c->flags & PERIPH_NO_RESET))
800 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
801 RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
802}
803
804void tegra2_periph_reset_assert(struct clk *c)
805{
806 pr_debug("%s on clock %s\n", __func__, c->name);
807 if (!(c->flags & PERIPH_NO_RESET))
808 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
809 RST_DEVICES_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
810}
811
812
813static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
814{
815 u32 val;
816 const struct clk_mux_sel *sel;
817 pr_debug("%s: %s %s\n", __func__, c->name, p->name);
818 for (sel = c->inputs; sel->input != NULL; sel++) {
819 if (sel->input == p) {
Colin Crossd8611962010-01-28 16:40:29 -0800820 val = clk_readl(c->reg);
821 val &= ~PERIPH_CLK_SOURCE_MASK;
822 val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT;
Colin Cross71fc84c2010-06-07 20:49:46 -0700823
824 if (c->refcnt)
825 clk_enable_locked(p);
826
Colin Crossd8611962010-01-28 16:40:29 -0800827 clk_writel(val, c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -0700828
829 if (c->refcnt && c->parent)
830 clk_disable_locked(c->parent);
831
832 clk_reparent(c, p);
Colin Crossd8611962010-01-28 16:40:29 -0800833 return 0;
834 }
835 }
836
837 return -EINVAL;
838}
839
840static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
841{
842 u32 val;
Colin Cross71fc84c2010-06-07 20:49:46 -0700843 int divider;
Colin Crossd8611962010-01-28 16:40:29 -0800844 pr_debug("%s: %lu\n", __func__, rate);
845 if (c->flags & DIV_U71) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700846 divider = clk_div71_get_divider(c->parent->rate, rate);
847 if (divider >= 0) {
Colin Crossd8611962010-01-28 16:40:29 -0800848 val = clk_readl(c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -0700849 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
850 val |= divider;
Colin Crossd8611962010-01-28 16:40:29 -0800851 clk_writel(val, c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -0700852 c->div = divider + 2;
Colin Crossd8611962010-01-28 16:40:29 -0800853 c->mul = 2;
Colin Crossd8611962010-01-28 16:40:29 -0800854 return 0;
855 }
Colin Cross71fc84c2010-06-07 20:49:46 -0700856 } else if (c->flags & DIV_U16) {
857 divider = clk_div16_get_divider(c->parent->rate, rate);
858 if (divider >= 0) {
859 val = clk_readl(c->reg);
860 val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
861 val |= divider;
862 clk_writel(val, c->reg);
863 c->div = divider + 1;
864 c->mul = 1;
865 return 0;
866 }
867 } else if (c->parent->rate <= rate) {
868 c->div = 1;
869 c->mul = 1;
870 return 0;
871 }
872 return -EINVAL;
873}
874
875static long tegra2_periph_clk_round_rate(struct clk *c,
876 unsigned long rate)
877{
878 int divider;
879 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
880
881 if (c->flags & DIV_U71) {
882 divider = clk_div71_get_divider(c->parent->rate, rate);
883 if (divider < 0)
884 return divider;
885
886 return c->parent->rate * 2 / (divider + 2);
887 } else if (c->flags & DIV_U16) {
888 divider = clk_div16_get_divider(c->parent->rate, rate);
889 if (divider < 0)
890 return divider;
891 return c->parent->rate / (divider + 1);
Colin Crossd8611962010-01-28 16:40:29 -0800892 }
893 return -EINVAL;
894}
895
896static struct clk_ops tegra_periph_clk_ops = {
897 .init = &tegra2_periph_clk_init,
898 .enable = &tegra2_periph_clk_enable,
899 .disable = &tegra2_periph_clk_disable,
900 .set_parent = &tegra2_periph_clk_set_parent,
901 .set_rate = &tegra2_periph_clk_set_rate,
Colin Cross71fc84c2010-06-07 20:49:46 -0700902 .round_rate = &tegra2_periph_clk_round_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800903};
904
905/* Clock doubler ops */
906static void tegra2_clk_double_init(struct clk *c)
907{
908 c->mul = 2;
909 c->div = 1;
910 c->state = ON;
911 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
912 PERIPH_CLK_TO_ENB_BIT(c)))
913 c->state = OFF;
Colin Crossd8611962010-01-28 16:40:29 -0800914};
915
Colin Cross71fc84c2010-06-07 20:49:46 -0700916static int tegra2_clk_double_set_rate(struct clk *c, unsigned long rate)
917{
918 if (rate != 2 * c->parent->rate)
919 return -EINVAL;
920 c->mul = 2;
921 c->div = 1;
922 return 0;
923}
924
Colin Crossd8611962010-01-28 16:40:29 -0800925static struct clk_ops tegra_clk_double_ops = {
926 .init = &tegra2_clk_double_init,
927 .enable = &tegra2_periph_clk_enable,
928 .disable = &tegra2_periph_clk_disable,
Colin Cross71fc84c2010-06-07 20:49:46 -0700929 .set_rate = &tegra2_clk_double_set_rate,
930};
931
932static void tegra2_audio_sync_clk_init(struct clk *c)
933{
934 int source;
935 const struct clk_mux_sel *sel;
936 u32 val = clk_readl(c->reg);
937 c->state = (val & (1<<4)) ? OFF : ON;
938 source = val & 0xf;
939 for (sel = c->inputs; sel->input != NULL; sel++)
940 if (sel->value == source)
941 break;
942 BUG_ON(sel->input == NULL);
943 c->parent = sel->input;
944}
945
946static int tegra2_audio_sync_clk_enable(struct clk *c)
947{
948 clk_writel(0, c->reg);
949 return 0;
950}
951
952static void tegra2_audio_sync_clk_disable(struct clk *c)
953{
954 clk_writel(1, c->reg);
955}
956
957static int tegra2_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
958{
959 u32 val;
960 const struct clk_mux_sel *sel;
961 for (sel = c->inputs; sel->input != NULL; sel++) {
962 if (sel->input == p) {
963 val = clk_readl(c->reg);
964 val &= ~0xf;
965 val |= sel->value;
966
967 if (c->refcnt)
968 clk_enable_locked(p);
969
970 clk_writel(val, c->reg);
971
972 if (c->refcnt && c->parent)
973 clk_disable_locked(c->parent);
974
975 clk_reparent(c, p);
976 return 0;
977 }
978 }
979
980 return -EINVAL;
981}
982
983static int tegra2_audio_sync_clk_set_rate(struct clk *c, unsigned long rate)
984{
985 unsigned long parent_rate;
986 if (!c->parent) {
987 pr_err("%s: clock has no parent\n", __func__);
988 return -EINVAL;
989 }
990 parent_rate = c->parent->rate;
991 if (rate != parent_rate) {
992 pr_err("%s: %s/%ld differs from parent %s/%ld\n",
993 __func__,
994 c->name, rate,
995 c->parent->name, parent_rate);
996 return -EINVAL;
997 }
998 c->rate = parent_rate;
999 return 0;
1000}
1001
1002static struct clk_ops tegra_audio_sync_clk_ops = {
1003 .init = tegra2_audio_sync_clk_init,
1004 .enable = tegra2_audio_sync_clk_enable,
1005 .disable = tegra2_audio_sync_clk_disable,
1006 .set_rate = tegra2_audio_sync_clk_set_rate,
1007 .set_parent = tegra2_audio_sync_clk_set_parent,
Colin Crossd8611962010-01-28 16:40:29 -08001008};
1009
1010/* Clock definitions */
1011static struct clk tegra_clk_32k = {
1012 .name = "clk_32k",
Colin Cross71fc84c2010-06-07 20:49:46 -07001013 .rate = 32768,
Colin Crossd8611962010-01-28 16:40:29 -08001014 .ops = NULL,
Colin Cross71fc84c2010-06-07 20:49:46 -07001015 .max_rate = 32768,
Colin Crossd8611962010-01-28 16:40:29 -08001016};
1017
1018static struct clk_pll_table tegra_pll_s_table[] = {
1019 {32768, 12000000, 366, 1, 1, 0},
1020 {32768, 13000000, 397, 1, 1, 0},
1021 {32768, 19200000, 586, 1, 1, 0},
1022 {32768, 26000000, 793, 1, 1, 0},
1023 {0, 0, 0, 0, 0, 0},
1024};
1025
1026static struct clk tegra_pll_s = {
1027 .name = "pll_s",
1028 .flags = PLL_ALT_MISC_REG,
1029 .ops = &tegra_pll_ops,
1030 .reg = 0xf0,
1031 .input_min = 32768,
1032 .input_max = 32768,
1033 .parent = &tegra_clk_32k,
1034 .cf_min = 0, /* FIXME */
1035 .cf_max = 0, /* FIXME */
1036 .vco_min = 12000000,
1037 .vco_max = 26000000,
1038 .pll_table = tegra_pll_s_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001039 .max_rate = 26000000,
Colin Crossd8611962010-01-28 16:40:29 -08001040};
1041
1042static struct clk_mux_sel tegra_clk_m_sel[] = {
1043 { .input = &tegra_clk_32k, .value = 0},
1044 { .input = &tegra_pll_s, .value = 1},
1045 { 0, 0},
1046};
1047static struct clk tegra_clk_m = {
1048 .name = "clk_m",
1049 .flags = ENABLE_ON_INIT,
1050 .ops = &tegra_clk_m_ops,
1051 .inputs = tegra_clk_m_sel,
1052 .reg = 0x1fc,
1053 .reg_mask = (1<<28),
1054 .reg_shift = 28,
Colin Cross71fc84c2010-06-07 20:49:46 -07001055 .max_rate = 26000000,
Colin Crossd8611962010-01-28 16:40:29 -08001056};
1057
1058static struct clk_pll_table tegra_pll_c_table[] = {
1059 { 0, 0, 0, 0, 0, 0 },
1060};
1061
1062static struct clk tegra_pll_c = {
1063 .name = "pll_c",
1064 .flags = PLL_HAS_CPCON,
1065 .ops = &tegra_pll_ops,
1066 .reg = 0x80,
1067 .input_min = 2000000,
1068 .input_max = 31000000,
1069 .parent = &tegra_clk_m,
1070 .cf_min = 1000000,
1071 .cf_max = 6000000,
1072 .vco_min = 20000000,
1073 .vco_max = 1400000000,
1074 .pll_table = tegra_pll_c_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001075 .max_rate = 600000000,
Colin Crossd8611962010-01-28 16:40:29 -08001076};
1077
1078static struct clk tegra_pll_c_out1 = {
1079 .name = "pll_c_out1",
1080 .ops = &tegra_pll_div_ops,
1081 .flags = DIV_U71,
1082 .parent = &tegra_pll_c,
1083 .reg = 0x84,
1084 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001085 .max_rate = 600000000,
Colin Crossd8611962010-01-28 16:40:29 -08001086};
1087
1088static struct clk_pll_table tegra_pll_m_table[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001089 { 12000000, 666000000, 666, 12, 1, 8},
1090 { 13000000, 666000000, 666, 13, 1, 8},
1091 { 19200000, 666000000, 555, 16, 1, 8},
1092 { 26000000, 666000000, 666, 26, 1, 8},
1093 { 12000000, 600000000, 600, 12, 1, 8},
1094 { 13000000, 600000000, 600, 13, 1, 8},
1095 { 19200000, 600000000, 375, 12, 1, 6},
1096 { 26000000, 600000000, 600, 26, 1, 8},
Colin Crossd8611962010-01-28 16:40:29 -08001097 { 0, 0, 0, 0, 0, 0 },
1098};
1099
1100static struct clk tegra_pll_m = {
1101 .name = "pll_m",
1102 .flags = PLL_HAS_CPCON,
1103 .ops = &tegra_pll_ops,
1104 .reg = 0x90,
1105 .input_min = 2000000,
1106 .input_max = 31000000,
1107 .parent = &tegra_clk_m,
1108 .cf_min = 1000000,
1109 .cf_max = 6000000,
1110 .vco_min = 20000000,
1111 .vco_max = 1200000000,
1112 .pll_table = tegra_pll_m_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001113 .max_rate = 800000000,
Colin Crossd8611962010-01-28 16:40:29 -08001114};
1115
1116static struct clk tegra_pll_m_out1 = {
1117 .name = "pll_m_out1",
1118 .ops = &tegra_pll_div_ops,
1119 .flags = DIV_U71,
1120 .parent = &tegra_pll_m,
1121 .reg = 0x94,
1122 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001123 .max_rate = 600000000,
Colin Crossd8611962010-01-28 16:40:29 -08001124};
1125
1126static struct clk_pll_table tegra_pll_p_table[] = {
1127 { 12000000, 216000000, 432, 12, 2, 8},
1128 { 13000000, 216000000, 432, 13, 2, 8},
1129 { 19200000, 216000000, 90, 4, 2, 1},
1130 { 26000000, 216000000, 432, 26, 2, 8},
1131 { 12000000, 432000000, 432, 12, 1, 8},
1132 { 13000000, 432000000, 432, 13, 1, 8},
1133 { 19200000, 432000000, 90, 4, 1, 1},
1134 { 26000000, 432000000, 432, 26, 1, 8},
1135 { 0, 0, 0, 0, 0, 0 },
1136};
1137
1138static struct clk tegra_pll_p = {
1139 .name = "pll_p",
1140 .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
1141 .ops = &tegra_pll_ops,
1142 .reg = 0xa0,
1143 .input_min = 2000000,
1144 .input_max = 31000000,
1145 .parent = &tegra_clk_m,
1146 .cf_min = 1000000,
1147 .cf_max = 6000000,
1148 .vco_min = 20000000,
1149 .vco_max = 1400000000,
1150 .pll_table = tegra_pll_p_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001151 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001152};
1153
1154static struct clk tegra_pll_p_out1 = {
1155 .name = "pll_p_out1",
1156 .ops = &tegra_pll_div_ops,
1157 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1158 .parent = &tegra_pll_p,
1159 .reg = 0xa4,
1160 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001161 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001162};
1163
1164static struct clk tegra_pll_p_out2 = {
1165 .name = "pll_p_out2",
1166 .ops = &tegra_pll_div_ops,
1167 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1168 .parent = &tegra_pll_p,
1169 .reg = 0xa4,
1170 .reg_shift = 16,
Colin Cross71fc84c2010-06-07 20:49:46 -07001171 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001172};
1173
1174static struct clk tegra_pll_p_out3 = {
1175 .name = "pll_p_out3",
1176 .ops = &tegra_pll_div_ops,
1177 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1178 .parent = &tegra_pll_p,
1179 .reg = 0xa8,
1180 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001181 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001182};
1183
1184static struct clk tegra_pll_p_out4 = {
1185 .name = "pll_p_out4",
1186 .ops = &tegra_pll_div_ops,
1187 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1188 .parent = &tegra_pll_p,
1189 .reg = 0xa8,
1190 .reg_shift = 16,
Colin Cross71fc84c2010-06-07 20:49:46 -07001191 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001192};
1193
1194static struct clk_pll_table tegra_pll_a_table[] = {
1195 { 28800000, 56448000, 49, 25, 1, 1},
1196 { 28800000, 73728000, 64, 25, 1, 1},
1197 { 28800000, 11289600, 49, 25, 1, 1},
1198 { 28800000, 12288000, 64, 25, 1, 1},
Colin Cross71fc84c2010-06-07 20:49:46 -07001199 { 28800000, 24000000, 5, 6, 1, 1},
Colin Crossd8611962010-01-28 16:40:29 -08001200 { 0, 0, 0, 0, 0, 0 },
1201};
1202
1203static struct clk tegra_pll_a = {
1204 .name = "pll_a",
1205 .flags = PLL_HAS_CPCON,
1206 .ops = &tegra_pll_ops,
1207 .reg = 0xb0,
1208 .input_min = 2000000,
1209 .input_max = 31000000,
1210 .parent = &tegra_pll_p_out1,
1211 .cf_min = 1000000,
1212 .cf_max = 6000000,
1213 .vco_min = 20000000,
1214 .vco_max = 1400000000,
1215 .pll_table = tegra_pll_a_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001216 .max_rate = 56448000,
Colin Crossd8611962010-01-28 16:40:29 -08001217};
1218
1219static struct clk tegra_pll_a_out0 = {
1220 .name = "pll_a_out0",
1221 .ops = &tegra_pll_div_ops,
1222 .flags = DIV_U71,
1223 .parent = &tegra_pll_a,
1224 .reg = 0xb4,
1225 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001226 .max_rate = 56448000,
Colin Crossd8611962010-01-28 16:40:29 -08001227};
1228
1229static struct clk_pll_table tegra_pll_d_table[] = {
1230 { 12000000, 1000000000, 1000, 12, 1, 12},
1231 { 13000000, 1000000000, 1000, 13, 1, 12},
1232 { 19200000, 1000000000, 625, 12, 1, 8},
1233 { 26000000, 1000000000, 1000, 26, 1, 12},
1234 { 0, 0, 0, 0, 0, 0 },
1235};
1236
1237static struct clk tegra_pll_d = {
1238 .name = "pll_d",
1239 .flags = PLL_HAS_CPCON | PLLD,
1240 .ops = &tegra_pll_ops,
1241 .reg = 0xd0,
1242 .input_min = 2000000,
1243 .input_max = 40000000,
1244 .parent = &tegra_clk_m,
1245 .cf_min = 1000000,
1246 .cf_max = 6000000,
1247 .vco_min = 40000000,
1248 .vco_max = 1000000000,
1249 .pll_table = tegra_pll_d_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001250 .max_rate = 1000000000,
Colin Crossd8611962010-01-28 16:40:29 -08001251};
1252
1253static struct clk tegra_pll_d_out0 = {
1254 .name = "pll_d_out0",
1255 .ops = &tegra_pll_div_ops,
1256 .flags = DIV_2 | PLLD,
1257 .parent = &tegra_pll_d,
Colin Cross71fc84c2010-06-07 20:49:46 -07001258 .max_rate = 500000000,
Colin Crossd8611962010-01-28 16:40:29 -08001259};
1260
1261static struct clk_pll_table tegra_pll_u_table[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001262 { 12000000, 480000000, 960, 12, 2, 0},
1263 { 13000000, 480000000, 960, 13, 2, 0},
1264 { 19200000, 480000000, 200, 4, 2, 0},
1265 { 26000000, 480000000, 960, 26, 2, 0},
Colin Crossd8611962010-01-28 16:40:29 -08001266 { 0, 0, 0, 0, 0, 0 },
1267};
1268
1269static struct clk tegra_pll_u = {
1270 .name = "pll_u",
Colin Cross71fc84c2010-06-07 20:49:46 -07001271 .flags = PLLU,
Colin Crossd8611962010-01-28 16:40:29 -08001272 .ops = &tegra_pll_ops,
1273 .reg = 0xc0,
1274 .input_min = 2000000,
1275 .input_max = 40000000,
1276 .parent = &tegra_clk_m,
1277 .cf_min = 1000000,
1278 .cf_max = 6000000,
1279 .vco_min = 480000000,
1280 .vco_max = 960000000,
1281 .pll_table = tegra_pll_u_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001282 .max_rate = 480000000,
Colin Crossd8611962010-01-28 16:40:29 -08001283};
1284
1285static struct clk_pll_table tegra_pll_x_table[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001286 /* 1 GHz */
Colin Crossd8611962010-01-28 16:40:29 -08001287 { 12000000, 1000000000, 1000, 12, 1, 12},
1288 { 13000000, 1000000000, 1000, 13, 1, 12},
1289 { 19200000, 1000000000, 625, 12, 1, 8},
1290 { 26000000, 1000000000, 1000, 26, 1, 12},
Colin Cross71fc84c2010-06-07 20:49:46 -07001291
1292 /* 912 MHz */
1293 { 12000000, 912000000, 912, 12, 1, 12},
1294 { 13000000, 912000000, 912, 13, 1, 12},
1295 { 19200000, 912000000, 760, 16, 1, 8},
1296 { 26000000, 912000000, 912, 26, 1, 12},
1297
1298 /* 816 MHz */
1299 { 12000000, 816000000, 816, 12, 1, 12},
1300 { 13000000, 816000000, 816, 13, 1, 12},
1301 { 19200000, 816000000, 680, 16, 1, 8},
1302 { 26000000, 816000000, 816, 26, 1, 12},
1303
1304 /* 760 MHz */
1305 { 12000000, 760000000, 760, 12, 1, 12},
1306 { 13000000, 760000000, 760, 13, 1, 12},
1307 { 19200000, 760000000, 950, 24, 1, 8},
1308 { 26000000, 760000000, 760, 26, 1, 12},
1309
1310 /* 608 MHz */
1311 { 12000000, 608000000, 760, 12, 1, 12},
1312 { 13000000, 608000000, 760, 13, 1, 12},
1313 { 19200000, 608000000, 380, 12, 1, 8},
1314 { 26000000, 608000000, 760, 26, 1, 12},
1315
1316 /* 456 MHz */
1317 { 12000000, 456000000, 456, 12, 1, 12},
1318 { 13000000, 456000000, 456, 13, 1, 12},
1319 { 19200000, 456000000, 380, 16, 1, 8},
1320 { 26000000, 456000000, 456, 26, 1, 12},
1321
1322 /* 312 MHz */
1323 { 12000000, 312000000, 312, 12, 1, 12},
1324 { 13000000, 312000000, 312, 13, 1, 12},
1325 { 19200000, 312000000, 260, 16, 1, 8},
1326 { 26000000, 312000000, 312, 26, 1, 12},
1327
Colin Crossd8611962010-01-28 16:40:29 -08001328 { 0, 0, 0, 0, 0, 0 },
1329};
1330
1331static struct clk tegra_pll_x = {
1332 .name = "pll_x",
1333 .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG,
Colin Cross71fc84c2010-06-07 20:49:46 -07001334 .ops = &tegra_pllx_ops,
Colin Crossd8611962010-01-28 16:40:29 -08001335 .reg = 0xe0,
1336 .input_min = 2000000,
1337 .input_max = 31000000,
1338 .parent = &tegra_clk_m,
1339 .cf_min = 1000000,
1340 .cf_max = 6000000,
1341 .vco_min = 20000000,
1342 .vco_max = 1200000000,
1343 .pll_table = tegra_pll_x_table,
Colin Cross71fc84c2010-06-07 20:49:46 -07001344 .max_rate = 1000000000,
Colin Crossd8611962010-01-28 16:40:29 -08001345};
1346
Mike Rapoport8d685bc2010-09-27 11:26:32 +02001347static struct clk_pll_table tegra_pll_e_table[] = {
1348 { 12000000, 100000000, 200, 24, 1, 0 },
1349 { 0, 0, 0, 0, 0, 0 },
1350};
1351
1352static struct clk tegra_pll_e = {
1353 .name = "pll_e",
1354 .flags = PLL_ALT_MISC_REG,
1355 .ops = &tegra_plle_ops,
1356 .input_min = 12000000,
1357 .input_max = 12000000,
1358 .max_rate = 100000000,
1359 .parent = &tegra_clk_m,
1360 .reg = 0xe8,
1361 .pll_table = tegra_pll_e_table,
1362};
1363
Colin Crossd8611962010-01-28 16:40:29 -08001364static struct clk tegra_clk_d = {
1365 .name = "clk_d",
1366 .flags = PERIPH_NO_RESET,
1367 .ops = &tegra_clk_double_ops,
1368 .clk_num = 90,
1369 .reg = 0x34,
1370 .reg_shift = 12,
1371 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001372 .max_rate = 52000000,
Colin Crossd8611962010-01-28 16:40:29 -08001373};
1374
Colin Cross71fc84c2010-06-07 20:49:46 -07001375/* initialized before peripheral clocks */
1376static struct clk_mux_sel mux_audio_sync_clk[8+1];
1377static const struct audio_sources {
1378 const char *name;
1379 int value;
1380} mux_audio_sync_clk_sources[] = {
1381 { .name = "spdif_in", .value = 0 },
1382 { .name = "i2s1", .value = 1 },
1383 { .name = "i2s2", .value = 2 },
1384 { .name = "pll_a_out0", .value = 4 },
1385#if 0 /* FIXME: not implemented */
1386 { .name = "ac97", .value = 3 },
1387 { .name = "ext_audio_clk2", .value = 5 },
1388 { .name = "ext_audio_clk1", .value = 6 },
1389 { .name = "ext_vimclk", .value = 7 },
1390#endif
1391 { 0, 0 }
1392};
1393
1394static struct clk tegra_clk_audio = {
1395 .name = "audio",
1396 .inputs = mux_audio_sync_clk,
1397 .reg = 0x38,
1398 .max_rate = 24000000,
1399 .ops = &tegra_audio_sync_clk_ops
1400};
1401
Colin Crossd8611962010-01-28 16:40:29 -08001402static struct clk tegra_clk_audio_2x = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001403 .name = "audio_2x",
Colin Crossd8611962010-01-28 16:40:29 -08001404 .flags = PERIPH_NO_RESET,
Colin Cross71fc84c2010-06-07 20:49:46 -07001405 .max_rate = 48000000,
Colin Crossd8611962010-01-28 16:40:29 -08001406 .ops = &tegra_clk_double_ops,
1407 .clk_num = 89,
1408 .reg = 0x34,
1409 .reg_shift = 8,
Colin Cross71fc84c2010-06-07 20:49:46 -07001410 .parent = &tegra_clk_audio,
1411};
1412
1413struct clk_lookup tegra_audio_clk_lookups[] = {
1414 { .con_id = "audio", .clk = &tegra_clk_audio },
1415 { .con_id = "audio_2x", .clk = &tegra_clk_audio_2x }
1416};
1417
1418/* This is called after peripheral clocks are initialized, as the
1419 * audio_sync clock depends on some of the peripheral clocks.
1420 */
1421
1422static void init_audio_sync_clock_mux(void)
1423{
1424 int i;
1425 struct clk_mux_sel *sel = mux_audio_sync_clk;
1426 const struct audio_sources *src = mux_audio_sync_clk_sources;
1427 struct clk_lookup *lookup;
1428
1429 for (i = 0; src->name; i++, sel++, src++) {
1430 sel->input = tegra_get_clock_by_name(src->name);
1431 if (!sel->input)
1432 pr_err("%s: could not find clk %s\n", __func__,
1433 src->name);
1434 sel->value = src->value;
1435 }
1436
1437 lookup = tegra_audio_clk_lookups;
1438 for (i = 0; i < ARRAY_SIZE(tegra_audio_clk_lookups); i++, lookup++) {
1439 clk_init(lookup->clk);
1440 clkdev_add(lookup);
1441 }
Colin Crossd8611962010-01-28 16:40:29 -08001442}
Colin Crossd8611962010-01-28 16:40:29 -08001443
1444static struct clk_mux_sel mux_cclk[] = {
1445 { .input = &tegra_clk_m, .value = 0},
1446 { .input = &tegra_pll_c, .value = 1},
1447 { .input = &tegra_clk_32k, .value = 2},
1448 { .input = &tegra_pll_m, .value = 3},
1449 { .input = &tegra_pll_p, .value = 4},
1450 { .input = &tegra_pll_p_out4, .value = 5},
1451 { .input = &tegra_pll_p_out3, .value = 6},
1452 { .input = &tegra_clk_d, .value = 7},
1453 { .input = &tegra_pll_x, .value = 8},
1454 { 0, 0},
1455};
1456
1457static struct clk_mux_sel mux_sclk[] = {
1458 { .input = &tegra_clk_m, .value = 0},
1459 { .input = &tegra_pll_c_out1, .value = 1},
1460 { .input = &tegra_pll_p_out4, .value = 2},
1461 { .input = &tegra_pll_p_out3, .value = 3},
1462 { .input = &tegra_pll_p_out2, .value = 4},
1463 { .input = &tegra_clk_d, .value = 5},
1464 { .input = &tegra_clk_32k, .value = 6},
1465 { .input = &tegra_pll_m_out1, .value = 7},
1466 { 0, 0},
1467};
1468
Colin Cross71fc84c2010-06-07 20:49:46 -07001469static struct clk tegra_clk_cclk = {
1470 .name = "cclk",
Colin Crossd8611962010-01-28 16:40:29 -08001471 .inputs = mux_cclk,
1472 .reg = 0x20,
1473 .ops = &tegra_super_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001474 .max_rate = 1000000000,
Colin Crossd8611962010-01-28 16:40:29 -08001475};
1476
Colin Cross71fc84c2010-06-07 20:49:46 -07001477static struct clk tegra_clk_sclk = {
1478 .name = "sclk",
Colin Crossd8611962010-01-28 16:40:29 -08001479 .inputs = mux_sclk,
1480 .reg = 0x28,
1481 .ops = &tegra_super_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001482 .max_rate = 600000000,
1483};
1484
1485static struct clk tegra_clk_virtual_cpu = {
1486 .name = "cpu",
1487 .parent = &tegra_clk_cclk,
1488 .main = &tegra_pll_x,
1489 .backup = &tegra_clk_m,
1490 .ops = &tegra_cpu_ops,
1491 .max_rate = 1000000000,
1492 .dvfs = &tegra_dvfs_virtual_cpu_dvfs,
Colin Crossd8611962010-01-28 16:40:29 -08001493};
1494
1495static struct clk tegra_clk_hclk = {
1496 .name = "hclk",
1497 .flags = DIV_BUS,
Colin Cross71fc84c2010-06-07 20:49:46 -07001498 .parent = &tegra_clk_sclk,
Colin Crossd8611962010-01-28 16:40:29 -08001499 .reg = 0x30,
1500 .reg_shift = 4,
1501 .ops = &tegra_bus_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001502 .max_rate = 240000000,
Colin Crossd8611962010-01-28 16:40:29 -08001503};
1504
1505static struct clk tegra_clk_pclk = {
1506 .name = "pclk",
1507 .flags = DIV_BUS,
1508 .parent = &tegra_clk_hclk,
1509 .reg = 0x30,
1510 .reg_shift = 0,
1511 .ops = &tegra_bus_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001512 .max_rate = 108000000,
Colin Crossd8611962010-01-28 16:40:29 -08001513};
1514
1515static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
1516 { .input = &tegra_pll_m, .value = 0},
1517 { .input = &tegra_pll_c, .value = 1},
1518 { .input = &tegra_pll_p, .value = 2},
1519 { .input = &tegra_pll_a_out0, .value = 3},
1520 { 0, 0},
1521};
1522
1523static struct clk_mux_sel mux_pllm_pllc_pllp_clkm[] = {
1524 { .input = &tegra_pll_m, .value = 0},
1525 { .input = &tegra_pll_c, .value = 1},
1526 { .input = &tegra_pll_p, .value = 2},
1527 { .input = &tegra_clk_m, .value = 3},
1528 { 0, 0},
1529};
1530
1531static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
1532 { .input = &tegra_pll_p, .value = 0},
1533 { .input = &tegra_pll_c, .value = 1},
1534 { .input = &tegra_pll_m, .value = 2},
1535 { .input = &tegra_clk_m, .value = 3},
1536 { 0, 0},
1537};
1538
Colin Cross71fc84c2010-06-07 20:49:46 -07001539static struct clk_mux_sel mux_pllaout0_audio2x_pllp_clkm[] = {
1540 {.input = &tegra_pll_a_out0, .value = 0},
1541 {.input = &tegra_clk_audio_2x, .value = 1},
Colin Crossd8611962010-01-28 16:40:29 -08001542 {.input = &tegra_pll_p, .value = 2},
1543 {.input = &tegra_clk_m, .value = 3},
1544 { 0, 0},
1545};
1546
1547static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
1548 {.input = &tegra_pll_p, .value = 0},
1549 {.input = &tegra_pll_d_out0, .value = 1},
1550 {.input = &tegra_pll_c, .value = 2},
1551 {.input = &tegra_clk_m, .value = 3},
1552 { 0, 0},
1553};
1554
1555static struct clk_mux_sel mux_pllp_pllc_audio_clkm_clk32[] = {
1556 {.input = &tegra_pll_p, .value = 0},
1557 {.input = &tegra_pll_c, .value = 1},
Colin Cross71fc84c2010-06-07 20:49:46 -07001558 {.input = &tegra_clk_audio, .value = 2},
Colin Crossd8611962010-01-28 16:40:29 -08001559 {.input = &tegra_clk_m, .value = 3},
1560 {.input = &tegra_clk_32k, .value = 4},
1561 { 0, 0},
1562};
1563
1564static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
1565 {.input = &tegra_pll_p, .value = 0},
1566 {.input = &tegra_pll_c, .value = 1},
1567 {.input = &tegra_pll_m, .value = 2},
1568 { 0, 0},
1569};
1570
1571static struct clk_mux_sel mux_clk_m[] = {
1572 { .input = &tegra_clk_m, .value = 0},
1573 { 0, 0},
1574};
1575
1576static struct clk_mux_sel mux_pllp_out3[] = {
1577 { .input = &tegra_pll_p_out3, .value = 0},
1578 { 0, 0},
1579};
1580
1581static struct clk_mux_sel mux_plld[] = {
1582 { .input = &tegra_pll_d, .value = 0},
1583 { 0, 0},
1584};
1585
1586static struct clk_mux_sel mux_clk_32k[] = {
1587 { .input = &tegra_clk_32k, .value = 0},
1588 { 0, 0},
1589};
1590
Colin Cross71fc84c2010-06-07 20:49:46 -07001591#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
Colin Crossd8611962010-01-28 16:40:29 -08001592 { \
1593 .name = _name, \
1594 .lookup = { \
1595 .dev_id = _dev, \
1596 .con_id = _con, \
1597 }, \
1598 .ops = &tegra_periph_clk_ops, \
1599 .clk_num = _clk_num, \
1600 .reg = _reg, \
1601 .inputs = _inputs, \
1602 .flags = _flags, \
Colin Cross71fc84c2010-06-07 20:49:46 -07001603 .max_rate = _max, \
Colin Crossd8611962010-01-28 16:40:29 -08001604 }
1605
1606struct clk tegra_periph_clks[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001607 PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET),
1608 PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0),
1609 PERIPH_CLK("i2s1", "i2s.0", NULL, 11, 0x100, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
1610 PERIPH_CLK("i2s2", "i2s.1", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
Colin Crossd8611962010-01-28 16:40:29 -08001611 /* FIXME: spdif has 2 clocks but 1 enable */
Colin Cross71fc84c2010-06-07 20:49:46 -07001612 PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
1613 PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71),
1614 PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71),
1615 PERIPH_CLK("spi", "spi", NULL, 43, 0x114, 40000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1616 PERIPH_CLK("xio", "xio", NULL, 45, 0x120, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1617 PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1618 PERIPH_CLK("sbc1", "spi_tegra.0", NULL, 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1619 PERIPH_CLK("sbc2", "spi_tegra.1", NULL, 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1620 PERIPH_CLK("sbc3", "spi_tegra.2", NULL, 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1621 PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1622 PERIPH_CLK("ide", "ide", NULL, 25, 0x144, 100000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
1623 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 -08001624 /* FIXME: vfir shares an enable with uartb */
Colin Cross71fc84c2010-06-07 20:49:46 -07001625 PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1626 PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1627 PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1628 PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1629 PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x160, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1630 PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
1631 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 -08001632 /* FIXME: what is la? */
Colin Cross71fc84c2010-06-07 20:49:46 -07001633 PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1634 PERIPH_CLK("owr", "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1635 PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, 92000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
1636 PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1637 PERIPH_CLK("i2c1", "tegra-i2c.0", NULL, 12, 0x124, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
1638 PERIPH_CLK("i2c2", "tegra-i2c.1", NULL, 54, 0x198, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
1639 PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
1640 PERIPH_CLK("dvc", "tegra-i2c.3", NULL, 47, 0x128, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
1641 PERIPH_CLK("i2c1_i2c", "tegra-i2c.0", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
1642 PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
1643 PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
1644 PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
1645 PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
1646 PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
1647 PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
1648 PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
1649 PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, 216000000, mux_pllp_pllc_pllm_clkm, MUX),
1650 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 */
1651 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 -08001652 /* FIXME: vi and vi_sensor share an enable */
Colin Cross71fc84c2010-06-07 20:49:46 -07001653 PERIPH_CLK("vi", "vi", NULL, 20, 0x148, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
1654 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 */
1655 PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
1656 PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 250000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
1657 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 -08001658 /* FIXME: cve and tvo share an enable */
Colin Cross71fc84c2010-06-07 20:49:46 -07001659 PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
1660 PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
1661 PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, 148500000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
1662 PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
1663 PERIPH_CLK("disp1", "tegrafb.0", NULL, 27, 0x138, 190000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
1664 PERIPH_CLK("disp2", "tegrafb.1", NULL, 26, 0x13c, 190000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
1665 PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
1666 PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
1667 PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
1668 PERIPH_CLK("emc", "emc", NULL, 57, 0x19c, 800000000, mux_pllm_pllc_pllp_clkm, MUX | DIV_U71 | PERIPH_EMC_ENB),
1669 PERIPH_CLK("dsi", "dsi", NULL, 48, 0, 500000000, mux_plld, 0), /* scales with voltage */
1670 PERIPH_CLK("csi", "csi", NULL, 52, 0, 72000000, mux_pllp_out3, 0),
1671 PERIPH_CLK("isp", "isp", NULL, 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */
1672 PERIPH_CLK("csus", "csus", NULL, 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET),
Mike Rapoport8d685bc2010-09-27 11:26:32 +02001673 PERIPH_CLK("pex", NULL, "pex", 70, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
1674 PERIPH_CLK("afi", NULL, "afi", 72, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
1675 PERIPH_CLK("pcie_xclk", NULL, "pcie_xclk", 74, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
Colin Crossd8611962010-01-28 16:40:29 -08001676};
1677
1678#define CLK_DUPLICATE(_name, _dev, _con) \
1679 { \
1680 .name = _name, \
1681 .lookup = { \
1682 .dev_id = _dev, \
1683 .con_id = _con, \
1684 }, \
1685 }
1686
1687/* Some clocks may be used by different drivers depending on the board
1688 * configuration. List those here to register them twice in the clock lookup
1689 * table under two names.
1690 */
1691struct clk_duplicate tegra_clk_duplicates[] = {
1692 CLK_DUPLICATE("uarta", "tegra_uart.0", NULL),
1693 CLK_DUPLICATE("uartb", "tegra_uart.1", NULL),
1694 CLK_DUPLICATE("uartc", "tegra_uart.2", NULL),
1695 CLK_DUPLICATE("uartd", "tegra_uart.3", NULL),
1696 CLK_DUPLICATE("uarte", "tegra_uart.4", NULL),
Colin Cross71fc84c2010-06-07 20:49:46 -07001697 CLK_DUPLICATE("host1x", "tegrafb.0", "host1x"),
1698 CLK_DUPLICATE("host1x", "tegrafb.1", "host1x"),
1699 CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
Colin Crossd8611962010-01-28 16:40:29 -08001700};
1701
1702#define CLK(dev, con, ck) \
1703 { \
1704 .dev_id = dev, \
1705 .con_id = con, \
1706 .clk = ck, \
1707 }
1708
1709struct clk_lookup tegra_clk_lookups[] = {
1710 /* external root sources */
1711 CLK(NULL, "32k_clk", &tegra_clk_32k),
1712 CLK(NULL, "pll_s", &tegra_pll_s),
1713 CLK(NULL, "clk_m", &tegra_clk_m),
1714 CLK(NULL, "pll_m", &tegra_pll_m),
1715 CLK(NULL, "pll_m_out1", &tegra_pll_m_out1),
1716 CLK(NULL, "pll_c", &tegra_pll_c),
1717 CLK(NULL, "pll_c_out1", &tegra_pll_c_out1),
1718 CLK(NULL, "pll_p", &tegra_pll_p),
1719 CLK(NULL, "pll_p_out1", &tegra_pll_p_out1),
1720 CLK(NULL, "pll_p_out2", &tegra_pll_p_out2),
1721 CLK(NULL, "pll_p_out3", &tegra_pll_p_out3),
1722 CLK(NULL, "pll_p_out4", &tegra_pll_p_out4),
1723 CLK(NULL, "pll_a", &tegra_pll_a),
1724 CLK(NULL, "pll_a_out0", &tegra_pll_a_out0),
1725 CLK(NULL, "pll_d", &tegra_pll_d),
1726 CLK(NULL, "pll_d_out0", &tegra_pll_d_out0),
1727 CLK(NULL, "pll_u", &tegra_pll_u),
1728 CLK(NULL, "pll_x", &tegra_pll_x),
Mike Rapoport8d685bc2010-09-27 11:26:32 +02001729 CLK(NULL, "pll_e", &tegra_pll_e),
Colin Cross71fc84c2010-06-07 20:49:46 -07001730 CLK(NULL, "cclk", &tegra_clk_cclk),
1731 CLK(NULL, "sclk", &tegra_clk_sclk),
Colin Crossd8611962010-01-28 16:40:29 -08001732 CLK(NULL, "hclk", &tegra_clk_hclk),
1733 CLK(NULL, "pclk", &tegra_clk_pclk),
1734 CLK(NULL, "clk_d", &tegra_clk_d),
Colin Cross71fc84c2010-06-07 20:49:46 -07001735 CLK(NULL, "cpu", &tegra_clk_virtual_cpu),
Colin Crossd8611962010-01-28 16:40:29 -08001736};
1737
1738void __init tegra2_init_clocks(void)
1739{
1740 int i;
1741 struct clk_lookup *cl;
1742 struct clk *c;
1743 struct clk_duplicate *cd;
1744
1745 for (i = 0; i < ARRAY_SIZE(tegra_clk_lookups); i++) {
1746 cl = &tegra_clk_lookups[i];
1747 clk_init(cl->clk);
1748 clkdev_add(cl);
1749 }
1750
1751 for (i = 0; i < ARRAY_SIZE(tegra_periph_clks); i++) {
1752 c = &tegra_periph_clks[i];
1753 cl = &c->lookup;
1754 cl->clk = c;
1755
1756 clk_init(cl->clk);
1757 clkdev_add(cl);
1758 }
1759
1760 for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
1761 cd = &tegra_clk_duplicates[i];
1762 c = tegra_get_clock_by_name(cd->name);
1763 if (c) {
1764 cl = &cd->lookup;
1765 cl->clk = c;
1766 clkdev_add(cl);
1767 } else {
1768 pr_err("%s: Unknown duplicate clock %s\n", __func__,
1769 cd->name);
1770 }
1771 }
Colin Cross71fc84c2010-06-07 20:49:46 -07001772
1773 init_audio_sync_clock_mux();
Colin Crossd8611962010-01-28 16:40:29 -08001774}
Colin Cross71fc84c2010-06-07 20:49:46 -07001775
1776#ifdef CONFIG_PM
1777static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM +
1778 PERIPH_CLK_SOURCE_NUM + 3];
1779
1780void tegra_clk_suspend(void)
1781{
1782 unsigned long off, i;
1783 u32 *ctx = clk_rst_suspend;
1784
1785 *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK;
1786
1787 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
1788 off += 4) {
1789 if (off == PERIPH_CLK_SOURCE_EMC)
1790 continue;
1791 *ctx++ = clk_readl(off);
1792 }
1793
1794 off = RST_DEVICES;
1795 for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
1796 *ctx++ = clk_readl(off);
1797
1798 off = CLK_OUT_ENB;
1799 for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
1800 *ctx++ = clk_readl(off);
1801
1802 *ctx++ = clk_readl(MISC_CLK_ENB);
1803 *ctx++ = clk_readl(CLK_MASK_ARM);
1804}
1805
1806void tegra_clk_resume(void)
1807{
1808 unsigned long off, i;
1809 const u32 *ctx = clk_rst_suspend;
1810 u32 val;
1811
1812 val = clk_readl(OSC_CTRL) & ~OSC_CTRL_MASK;
1813 val |= *ctx++;
1814 clk_writel(val, OSC_CTRL);
1815
1816 /* enable all clocks before configuring clock sources */
1817 clk_writel(0xbffffff9ul, CLK_OUT_ENB);
1818 clk_writel(0xfefffff7ul, CLK_OUT_ENB + 4);
1819 clk_writel(0x77f01bfful, CLK_OUT_ENB + 8);
1820 wmb();
1821
1822 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
1823 off += 4) {
1824 if (off == PERIPH_CLK_SOURCE_EMC)
1825 continue;
1826 clk_writel(*ctx++, off);
1827 }
1828 wmb();
1829
1830 off = RST_DEVICES;
1831 for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
1832 clk_writel(*ctx++, off);
1833 wmb();
1834
1835 off = CLK_OUT_ENB;
1836 for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
1837 clk_writel(*ctx++, off);
1838 wmb();
1839
1840 clk_writel(*ctx++, MISC_CLK_ENB);
1841 clk_writel(*ctx++, CLK_MASK_ARM);
1842}
1843#endif