blob: 260b77c41436e267d82d9acf00cd36286a6102fd [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>
Jean-Christop PLAGNIOL-VILLARD6d803ba2010-11-17 10:04:33 +010026#include <linux/clkdev.h>
Colin Cross4729fd72011-02-12 16:43:05 -080027#include <linux/clk.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"
Colin Cross6d296822010-11-22 18:37:54 -080034#include "tegra2_emc.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 Crosscea62c82010-10-04 11:49:26 -070055#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
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
Colin Cross9743b382011-02-12 18:24:32 -080077#define SDMMC_CLK_INT_FB_SEL (1 << 23)
78#define SDMMC_CLK_INT_FB_DLY_SHIFT 16
79#define SDMMC_CLK_INT_FB_DLY_MASK (0xF << SDMMC_CLK_INT_FB_DLY_SHIFT)
80
Colin Crossd8611962010-01-28 16:40:29 -080081#define PLL_BASE 0x0
82#define PLL_BASE_BYPASS (1<<31)
83#define PLL_BASE_ENABLE (1<<30)
84#define PLL_BASE_REF_ENABLE (1<<29)
85#define PLL_BASE_OVERRIDE (1<<28)
Colin Crossd8611962010-01-28 16:40:29 -080086#define PLL_BASE_DIVP_MASK (0x7<<20)
87#define PLL_BASE_DIVP_SHIFT 20
88#define PLL_BASE_DIVN_MASK (0x3FF<<8)
89#define PLL_BASE_DIVN_SHIFT 8
90#define PLL_BASE_DIVM_MASK (0x1F)
91#define PLL_BASE_DIVM_SHIFT 0
92
93#define PLL_OUT_RATIO_MASK (0xFF<<8)
94#define PLL_OUT_RATIO_SHIFT 8
95#define PLL_OUT_OVERRIDE (1<<2)
96#define PLL_OUT_CLKEN (1<<1)
97#define PLL_OUT_RESET_DISABLE (1<<0)
98
99#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
Colin Cross71fc84c2010-06-07 20:49:46 -0700100
Colin Crossd8611962010-01-28 16:40:29 -0800101#define PLL_MISC_DCCON_SHIFT 20
Colin Crossd8611962010-01-28 16:40:29 -0800102#define PLL_MISC_CPCON_SHIFT 8
103#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT)
104#define PLL_MISC_LFCON_SHIFT 4
105#define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT)
106#define PLL_MISC_VCOCON_SHIFT 0
107#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT)
108
Colin Cross71fc84c2010-06-07 20:49:46 -0700109#define PLLU_BASE_POST_DIV (1<<20)
110
Colin Crossd8611962010-01-28 16:40:29 -0800111#define PLLD_MISC_CLKENABLE (1<<30)
112#define PLLD_MISC_DIV_RST (1<<23)
113#define PLLD_MISC_DCCON_SHIFT 12
114
Mike Rapoport8d685bc2010-09-27 11:26:32 +0200115#define PLLE_MISC_READY (1 << 15)
116
Colin Crossf1519612011-02-12 16:05:31 -0800117#define PERIPH_CLK_TO_ENB_REG(c) ((c->u.periph.clk_num / 32) * 4)
118#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->u.periph.clk_num / 32) * 8)
119#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->u.periph.clk_num % 32))
Colin Crossd8611962010-01-28 16:40:29 -0800120
121#define SUPER_CLK_MUX 0x00
122#define SUPER_STATE_SHIFT 28
123#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT)
124#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT)
125#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT)
126#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT)
127#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT)
128#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT)
129#define SUPER_SOURCE_MASK 0xF
130#define SUPER_FIQ_SOURCE_SHIFT 12
131#define SUPER_IRQ_SOURCE_SHIFT 8
132#define SUPER_RUN_SOURCE_SHIFT 4
133#define SUPER_IDLE_SOURCE_SHIFT 0
134
135#define SUPER_CLK_DIVIDER 0x04
136
137#define BUS_CLK_DISABLE (1<<3)
138#define BUS_CLK_DIV_MASK 0x3
139
Colin Crosscea62c82010-10-04 11:49:26 -0700140#define PMC_CTRL 0x0
141 #define PMC_CTRL_BLINK_ENB (1 << 7)
142
143#define PMC_DPD_PADS_ORIDE 0x1c
144 #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20)
145
146#define PMC_BLINK_TIMER_DATA_ON_SHIFT 0
147#define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff
148#define PMC_BLINK_TIMER_ENB (1 << 15)
149#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
150#define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff
151
Colin Crossd8611962010-01-28 16:40:29 -0800152static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
Colin Crosscea62c82010-10-04 11:49:26 -0700153static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
Colin Crossd8611962010-01-28 16:40:29 -0800154
Colin Cross4729fd72011-02-12 16:43:05 -0800155/*
156 * Some clocks share a register with other clocks. Any clock op that
157 * non-atomically modifies a register used by another clock must lock
158 * clock_register_lock first.
159 */
160static DEFINE_SPINLOCK(clock_register_lock);
161
Colin Crossd8611962010-01-28 16:40:29 -0800162#define clk_writel(value, reg) \
163 __raw_writel(value, (u32)reg_clk_base + (reg))
164#define clk_readl(reg) \
165 __raw_readl((u32)reg_clk_base + (reg))
Colin Crosscea62c82010-10-04 11:49:26 -0700166#define pmc_writel(value, reg) \
167 __raw_writel(value, (u32)reg_pmc_base + (reg))
168#define pmc_readl(reg) \
169 __raw_readl((u32)reg_pmc_base + (reg))
Colin Crossd8611962010-01-28 16:40:29 -0800170
171unsigned long clk_measure_input_freq(void)
172{
173 u32 clock_autodetect;
174 clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
175 do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
176 clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
177 if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
178 return 12000000;
179 } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
180 return 13000000;
181 } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
182 return 19200000;
183 } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
184 return 26000000;
185 } else {
186 pr_err("%s: Unexpected clock autodetect value %d", __func__, clock_autodetect);
187 BUG();
188 return 0;
189 }
190}
191
Colin Cross71fc84c2010-06-07 20:49:46 -0700192static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate)
Colin Crossd8611962010-01-28 16:40:29 -0800193{
Colin Cross71fc84c2010-06-07 20:49:46 -0700194 s64 divider_u71 = parent_rate * 2;
195 divider_u71 += rate - 1;
196 do_div(divider_u71, rate);
Colin Crossd8611962010-01-28 16:40:29 -0800197
Colin Cross71fc84c2010-06-07 20:49:46 -0700198 if (divider_u71 - 2 < 0)
199 return 0;
Colin Crossd8611962010-01-28 16:40:29 -0800200
Colin Cross71fc84c2010-06-07 20:49:46 -0700201 if (divider_u71 - 2 > 255)
Colin Crossd8611962010-01-28 16:40:29 -0800202 return -EINVAL;
203
204 return divider_u71 - 2;
205}
206
Colin Cross71fc84c2010-06-07 20:49:46 -0700207static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
Colin Crossd8611962010-01-28 16:40:29 -0800208{
Colin Cross71fc84c2010-06-07 20:49:46 -0700209 s64 divider_u16;
Colin Crossd8611962010-01-28 16:40:29 -0800210
Colin Cross71fc84c2010-06-07 20:49:46 -0700211 divider_u16 = parent_rate;
212 divider_u16 += rate - 1;
213 do_div(divider_u16, rate);
214
215 if (divider_u16 - 1 < 0)
216 return 0;
217
218 if (divider_u16 - 1 > 255)
219 return -EINVAL;
220
221 return divider_u16 - 1;
Colin Crossd8611962010-01-28 16:40:29 -0800222}
223
Colin Crossd8611962010-01-28 16:40:29 -0800224/* clk_m functions */
225static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c)
226{
227 u32 auto_clock_control = clk_readl(OSC_CTRL) & ~OSC_CTRL_OSC_FREQ_MASK;
228
229 c->rate = clk_measure_input_freq();
230 switch (c->rate) {
231 case 12000000:
232 auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
233 break;
234 case 13000000:
235 auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
236 break;
237 case 19200000:
238 auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
239 break;
240 case 26000000:
241 auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
242 break;
243 default:
244 pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
245 BUG();
246 }
247 clk_writel(auto_clock_control, OSC_CTRL);
248 return c->rate;
249}
250
251static void tegra2_clk_m_init(struct clk *c)
252{
253 pr_debug("%s on clock %s\n", __func__, c->name);
254 tegra2_clk_m_autodetect_rate(c);
255}
256
257static int tegra2_clk_m_enable(struct clk *c)
258{
259 pr_debug("%s on clock %s\n", __func__, c->name);
260 return 0;
261}
262
263static void tegra2_clk_m_disable(struct clk *c)
264{
265 pr_debug("%s on clock %s\n", __func__, c->name);
266 BUG();
267}
268
269static struct clk_ops tegra_clk_m_ops = {
270 .init = tegra2_clk_m_init,
271 .enable = tegra2_clk_m_enable,
272 .disable = tegra2_clk_m_disable,
273};
274
Dima Zavin2b84cb4f2010-09-02 19:11:11 -0700275void tegra2_periph_reset_assert(struct clk *c)
276{
277 BUG_ON(!c->ops->reset);
278 c->ops->reset(c, true);
279}
280
281void tegra2_periph_reset_deassert(struct clk *c)
282{
283 BUG_ON(!c->ops->reset);
284 c->ops->reset(c, false);
285}
286
Colin Crossd8611962010-01-28 16:40:29 -0800287/* super clock functions */
288/* "super clocks" on tegra have two-stage muxes and a clock skipping
289 * super divider. We will ignore the clock skipping divider, since we
290 * can't lower the voltage when using the clock skip, but we can if we
291 * lower the PLL frequency.
292 */
293static void tegra2_super_clk_init(struct clk *c)
294{
295 u32 val;
296 int source;
297 int shift;
298 const struct clk_mux_sel *sel;
299 val = clk_readl(c->reg + SUPER_CLK_MUX);
300 c->state = ON;
301 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
302 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
303 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
304 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
305 source = (val >> shift) & SUPER_SOURCE_MASK;
306 for (sel = c->inputs; sel->input != NULL; sel++) {
307 if (sel->value == source)
308 break;
309 }
310 BUG_ON(sel->input == NULL);
311 c->parent = sel->input;
Colin Crossd8611962010-01-28 16:40:29 -0800312}
313
314static int tegra2_super_clk_enable(struct clk *c)
315{
316 clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
317 return 0;
318}
319
320static void tegra2_super_clk_disable(struct clk *c)
321{
322 pr_debug("%s on clock %s\n", __func__, c->name);
323
324 /* oops - don't disable the CPU clock! */
325 BUG();
326}
327
328static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p)
329{
330 u32 val;
331 const struct clk_mux_sel *sel;
332 int shift;
Colin Cross71fc84c2010-06-07 20:49:46 -0700333
Colin Crossd8611962010-01-28 16:40:29 -0800334 val = clk_readl(c->reg + SUPER_CLK_MUX);;
335 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
336 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
337 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
338 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
339 for (sel = c->inputs; sel->input != NULL; sel++) {
340 if (sel->input == p) {
Colin Crossd8611962010-01-28 16:40:29 -0800341 val &= ~(SUPER_SOURCE_MASK << shift);
342 val |= sel->value << shift;
Colin Cross71fc84c2010-06-07 20:49:46 -0700343
344 if (c->refcnt)
Colin Cross4729fd72011-02-12 16:43:05 -0800345 clk_enable(p);
Colin Cross71fc84c2010-06-07 20:49:46 -0700346
Colin Crossd8611962010-01-28 16:40:29 -0800347 clk_writel(val, c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -0700348
349 if (c->refcnt && c->parent)
Colin Cross4729fd72011-02-12 16:43:05 -0800350 clk_disable(c->parent);
Colin Cross71fc84c2010-06-07 20:49:46 -0700351
352 clk_reparent(c, p);
Colin Crossd8611962010-01-28 16:40:29 -0800353 return 0;
354 }
355 }
356 return -EINVAL;
357}
358
359static struct clk_ops tegra_super_ops = {
360 .init = tegra2_super_clk_init,
361 .enable = tegra2_super_clk_enable,
362 .disable = tegra2_super_clk_disable,
363 .set_parent = tegra2_super_clk_set_parent,
Colin Cross71fc84c2010-06-07 20:49:46 -0700364};
365
366/* virtual cpu clock functions */
367/* some clocks can not be stopped (cpu, memory bus) while the SoC is running.
368 To change the frequency of these clocks, the parent pll may need to be
369 reprogrammed, so the clock must be moved off the pll, the pll reprogrammed,
370 and then the clock moved back to the pll. To hide this sequence, a virtual
371 clock handles it.
372 */
373static void tegra2_cpu_clk_init(struct clk *c)
374{
375}
376
377static int tegra2_cpu_clk_enable(struct clk *c)
378{
379 return 0;
380}
381
382static void tegra2_cpu_clk_disable(struct clk *c)
383{
384 pr_debug("%s on clock %s\n", __func__, c->name);
385
386 /* oops - don't disable the CPU clock! */
387 BUG();
388}
389
390static int tegra2_cpu_clk_set_rate(struct clk *c, unsigned long rate)
391{
392 int ret;
Colin Cross89a5fb82010-10-20 17:47:59 -0700393 /*
394 * Take an extra reference to the main pll so it doesn't turn
395 * off when we move the cpu off of it
396 */
397 clk_enable(c->u.cpu.main);
398
Colin Cross4729fd72011-02-12 16:43:05 -0800399 ret = clk_set_parent(c->parent, c->u.cpu.backup);
Colin Cross71fc84c2010-06-07 20:49:46 -0700400 if (ret) {
Colin Crossf1519612011-02-12 16:05:31 -0800401 pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.backup->name);
Colin Cross89a5fb82010-10-20 17:47:59 -0700402 goto out;
Colin Cross71fc84c2010-06-07 20:49:46 -0700403 }
404
Colin Cross4729fd72011-02-12 16:43:05 -0800405 if (rate == clk_get_rate(c->u.cpu.backup))
Colin Crosscea62c82010-10-04 11:49:26 -0700406 goto out;
407
Colin Cross4729fd72011-02-12 16:43:05 -0800408 ret = clk_set_rate(c->u.cpu.main, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -0700409 if (ret) {
410 pr_err("Failed to change cpu pll to %lu\n", rate);
Colin Cross89a5fb82010-10-20 17:47:59 -0700411 goto out;
Colin Cross71fc84c2010-06-07 20:49:46 -0700412 }
413
Colin Cross4729fd72011-02-12 16:43:05 -0800414 ret = clk_set_parent(c->parent, c->u.cpu.main);
Colin Cross71fc84c2010-06-07 20:49:46 -0700415 if (ret) {
Colin Crossf1519612011-02-12 16:05:31 -0800416 pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.main->name);
Colin Cross89a5fb82010-10-20 17:47:59 -0700417 goto out;
Colin Cross71fc84c2010-06-07 20:49:46 -0700418 }
419
Colin Crosscea62c82010-10-04 11:49:26 -0700420out:
Colin Cross89a5fb82010-10-20 17:47:59 -0700421 clk_disable(c->u.cpu.main);
422 return ret;
Colin Cross71fc84c2010-06-07 20:49:46 -0700423}
424
425static struct clk_ops tegra_cpu_ops = {
426 .init = tegra2_cpu_clk_init,
427 .enable = tegra2_cpu_clk_enable,
428 .disable = tegra2_cpu_clk_disable,
429 .set_rate = tegra2_cpu_clk_set_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800430};
431
432/* bus clock functions */
433static void tegra2_bus_clk_init(struct clk *c)
434{
435 u32 val = clk_readl(c->reg);
436 c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
437 c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
438 c->mul = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800439}
440
441static int tegra2_bus_clk_enable(struct clk *c)
442{
Colin Cross4729fd72011-02-12 16:43:05 -0800443 u32 val;
444 unsigned long flags;
445
446 spin_lock_irqsave(&clock_register_lock, flags);
447
448 val = clk_readl(c->reg);
Colin Crossd8611962010-01-28 16:40:29 -0800449 val &= ~(BUS_CLK_DISABLE << c->reg_shift);
450 clk_writel(val, c->reg);
Colin Cross4729fd72011-02-12 16:43:05 -0800451
452 spin_unlock_irqrestore(&clock_register_lock, flags);
453
Colin Crossd8611962010-01-28 16:40:29 -0800454 return 0;
455}
456
457static void tegra2_bus_clk_disable(struct clk *c)
458{
Colin Cross4729fd72011-02-12 16:43:05 -0800459 u32 val;
460 unsigned long flags;
461
462 spin_lock_irqsave(&clock_register_lock, flags);
463
464 val = clk_readl(c->reg);
Colin Crossd8611962010-01-28 16:40:29 -0800465 val |= BUS_CLK_DISABLE << c->reg_shift;
466 clk_writel(val, c->reg);
Colin Cross4729fd72011-02-12 16:43:05 -0800467
468 spin_unlock_irqrestore(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800469}
470
471static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate)
472{
Colin Cross4729fd72011-02-12 16:43:05 -0800473 u32 val;
474 unsigned long parent_rate = clk_get_rate(c->parent);
475 unsigned long flags;
476 int ret = -EINVAL;
Colin Crossd8611962010-01-28 16:40:29 -0800477 int i;
Colin Cross4729fd72011-02-12 16:43:05 -0800478
479 spin_lock_irqsave(&clock_register_lock, flags);
480
481 val = clk_readl(c->reg);
Colin Crossd8611962010-01-28 16:40:29 -0800482 for (i = 1; i <= 4; i++) {
483 if (rate == parent_rate / i) {
484 val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
485 val |= (i - 1) << c->reg_shift;
486 clk_writel(val, c->reg);
487 c->div = i;
488 c->mul = 1;
Colin Cross4729fd72011-02-12 16:43:05 -0800489 ret = 0;
490 break;
Colin Crossd8611962010-01-28 16:40:29 -0800491 }
492 }
Colin Cross4729fd72011-02-12 16:43:05 -0800493
494 spin_unlock_irqrestore(&clock_register_lock, flags);
495
496 return ret;
Colin Crossd8611962010-01-28 16:40:29 -0800497}
498
499static struct clk_ops tegra_bus_ops = {
500 .init = tegra2_bus_clk_init,
501 .enable = tegra2_bus_clk_enable,
502 .disable = tegra2_bus_clk_disable,
503 .set_rate = tegra2_bus_clk_set_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800504};
505
Colin Crosscea62c82010-10-04 11:49:26 -0700506/* Blink output functions */
507
508static void tegra2_blink_clk_init(struct clk *c)
509{
510 u32 val;
511
512 val = pmc_readl(PMC_CTRL);
513 c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
514 c->mul = 1;
515 val = pmc_readl(c->reg);
516
517 if (val & PMC_BLINK_TIMER_ENB) {
518 unsigned int on_off;
519
520 on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
521 PMC_BLINK_TIMER_DATA_ON_MASK;
522 val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
523 val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
524 on_off += val;
525 /* each tick in the blink timer is 4 32KHz clocks */
526 c->div = on_off * 4;
527 } else {
528 c->div = 1;
529 }
530}
531
532static int tegra2_blink_clk_enable(struct clk *c)
533{
534 u32 val;
535
536 val = pmc_readl(PMC_DPD_PADS_ORIDE);
537 pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
538
539 val = pmc_readl(PMC_CTRL);
540 pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
541
542 return 0;
543}
544
545static void tegra2_blink_clk_disable(struct clk *c)
546{
547 u32 val;
548
549 val = pmc_readl(PMC_CTRL);
550 pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
551
552 val = pmc_readl(PMC_DPD_PADS_ORIDE);
553 pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
554}
555
556static int tegra2_blink_clk_set_rate(struct clk *c, unsigned long rate)
557{
Colin Cross4729fd72011-02-12 16:43:05 -0800558 unsigned long parent_rate = clk_get_rate(c->parent);
559 if (rate >= parent_rate) {
Colin Crosscea62c82010-10-04 11:49:26 -0700560 c->div = 1;
561 pmc_writel(0, c->reg);
562 } else {
563 unsigned int on_off;
564 u32 val;
565
Colin Cross4729fd72011-02-12 16:43:05 -0800566 on_off = DIV_ROUND_UP(parent_rate / 8, rate);
Colin Crosscea62c82010-10-04 11:49:26 -0700567 c->div = on_off * 8;
568
569 val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
570 PMC_BLINK_TIMER_DATA_ON_SHIFT;
571 on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
572 on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
573 val |= on_off;
574 val |= PMC_BLINK_TIMER_ENB;
575 pmc_writel(val, c->reg);
576 }
577
578 return 0;
579}
580
581static struct clk_ops tegra_blink_clk_ops = {
582 .init = &tegra2_blink_clk_init,
583 .enable = &tegra2_blink_clk_enable,
584 .disable = &tegra2_blink_clk_disable,
585 .set_rate = &tegra2_blink_clk_set_rate,
586};
587
Colin Crossd8611962010-01-28 16:40:29 -0800588/* PLL Functions */
Colin Crossd8611962010-01-28 16:40:29 -0800589static int tegra2_pll_clk_wait_for_lock(struct clk *c)
590{
Colin Crossf1519612011-02-12 16:05:31 -0800591 udelay(c->u.pll.lock_delay);
Colin Crossd8611962010-01-28 16:40:29 -0800592
593 return 0;
594}
595
596static void tegra2_pll_clk_init(struct clk *c)
597{
598 u32 val = clk_readl(c->reg + PLL_BASE);
599
600 c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
601
602 if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
603 pr_warning("Clock %s has unknown fixed frequency\n", c->name);
Colin Cross71fc84c2010-06-07 20:49:46 -0700604 c->mul = 1;
605 c->div = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800606 } else if (val & PLL_BASE_BYPASS) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700607 c->mul = 1;
608 c->div = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800609 } else {
Colin Cross71fc84c2010-06-07 20:49:46 -0700610 c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
611 c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
612 if (c->flags & PLLU)
613 c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
614 else
615 c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
Colin Crossd8611962010-01-28 16:40:29 -0800616 }
Colin Crossd8611962010-01-28 16:40:29 -0800617}
618
619static int tegra2_pll_clk_enable(struct clk *c)
620{
621 u32 val;
622 pr_debug("%s on clock %s\n", __func__, c->name);
623
624 val = clk_readl(c->reg + PLL_BASE);
625 val &= ~PLL_BASE_BYPASS;
626 val |= PLL_BASE_ENABLE;
627 clk_writel(val, c->reg + PLL_BASE);
628
Colin Crossd8611962010-01-28 16:40:29 -0800629 tegra2_pll_clk_wait_for_lock(c);
630
631 return 0;
632}
633
634static void tegra2_pll_clk_disable(struct clk *c)
635{
636 u32 val;
637 pr_debug("%s on clock %s\n", __func__, c->name);
638
639 val = clk_readl(c->reg);
640 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
641 clk_writel(val, c->reg);
642}
643
644static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate)
645{
646 u32 val;
647 unsigned long input_rate;
Colin Crossf1519612011-02-12 16:05:31 -0800648 const struct clk_pll_freq_table *sel;
Colin Crossd8611962010-01-28 16:40:29 -0800649
650 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
Colin Crossd8611962010-01-28 16:40:29 -0800651
Colin Cross4729fd72011-02-12 16:43:05 -0800652 input_rate = clk_get_rate(c->parent);
Colin Crossf1519612011-02-12 16:05:31 -0800653 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
Colin Crossd8611962010-01-28 16:40:29 -0800654 if (sel->input_rate == input_rate && sel->output_rate == rate) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700655 c->mul = sel->n;
656 c->div = sel->m * sel->p;
Colin Crossd8611962010-01-28 16:40:29 -0800657
658 val = clk_readl(c->reg + PLL_BASE);
659 if (c->flags & PLL_FIXED)
660 val |= PLL_BASE_OVERRIDE;
661 val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK |
662 PLL_BASE_DIVM_MASK);
Colin Cross71fc84c2010-06-07 20:49:46 -0700663 val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
664 (sel->n << PLL_BASE_DIVN_SHIFT);
665 BUG_ON(sel->p < 1 || sel->p > 2);
666 if (c->flags & PLLU) {
667 if (sel->p == 1)
668 val |= PLLU_BASE_POST_DIV;
669 } else {
670 if (sel->p == 2)
671 val |= 1 << PLL_BASE_DIVP_SHIFT;
672 }
Colin Crossd8611962010-01-28 16:40:29 -0800673 clk_writel(val, c->reg + PLL_BASE);
674
675 if (c->flags & PLL_HAS_CPCON) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700676 val = clk_readl(c->reg + PLL_MISC(c));
677 val &= ~PLL_MISC_CPCON_MASK;
678 val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
Colin Crossd8611962010-01-28 16:40:29 -0800679 clk_writel(val, c->reg + PLL_MISC(c));
680 }
681
682 if (c->state == ON)
683 tegra2_pll_clk_enable(c);
684
Colin Crossd8611962010-01-28 16:40:29 -0800685 return 0;
686 }
687 }
688 return -EINVAL;
689}
690
691static struct clk_ops tegra_pll_ops = {
692 .init = tegra2_pll_clk_init,
693 .enable = tegra2_pll_clk_enable,
694 .disable = tegra2_pll_clk_disable,
695 .set_rate = tegra2_pll_clk_set_rate,
Colin Cross71fc84c2010-06-07 20:49:46 -0700696};
697
698static void tegra2_pllx_clk_init(struct clk *c)
699{
700 tegra2_pll_clk_init(c);
701
702 if (tegra_sku_id() == 7)
703 c->max_rate = 750000000;
704}
705
706static struct clk_ops tegra_pllx_ops = {
707 .init = tegra2_pllx_clk_init,
708 .enable = tegra2_pll_clk_enable,
709 .disable = tegra2_pll_clk_disable,
710 .set_rate = tegra2_pll_clk_set_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800711};
712
Mike Rapoport8d685bc2010-09-27 11:26:32 +0200713static int tegra2_plle_clk_enable(struct clk *c)
714{
715 u32 val;
716
717 pr_debug("%s on clock %s\n", __func__, c->name);
718
719 mdelay(1);
720
721 val = clk_readl(c->reg + PLL_BASE);
722 if (!(val & PLLE_MISC_READY))
723 return -EBUSY;
724
725 val = clk_readl(c->reg + PLL_BASE);
726 val |= PLL_BASE_ENABLE | PLL_BASE_BYPASS;
727 clk_writel(val, c->reg + PLL_BASE);
728
729 return 0;
730}
731
732static struct clk_ops tegra_plle_ops = {
733 .init = tegra2_pll_clk_init,
734 .enable = tegra2_plle_clk_enable,
735 .set_rate = tegra2_pll_clk_set_rate,
736};
737
Colin Crossd8611962010-01-28 16:40:29 -0800738/* Clock divider ops */
739static void tegra2_pll_div_clk_init(struct clk *c)
740{
741 u32 val = clk_readl(c->reg);
742 u32 divu71;
743 val >>= c->reg_shift;
744 c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
745 if (!(val & PLL_OUT_RESET_DISABLE))
746 c->state = OFF;
747
748 if (c->flags & DIV_U71) {
749 divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
750 c->div = (divu71 + 2);
751 c->mul = 2;
752 } else if (c->flags & DIV_2) {
753 c->div = 2;
754 c->mul = 1;
755 } else {
756 c->div = 1;
757 c->mul = 1;
758 }
Colin Crossd8611962010-01-28 16:40:29 -0800759}
760
761static int tegra2_pll_div_clk_enable(struct clk *c)
762{
763 u32 val;
764 u32 new_val;
Colin Cross4729fd72011-02-12 16:43:05 -0800765 unsigned long flags;
Colin Crossd8611962010-01-28 16:40:29 -0800766
767 pr_debug("%s: %s\n", __func__, c->name);
768 if (c->flags & DIV_U71) {
Colin Cross4729fd72011-02-12 16:43:05 -0800769 spin_lock_irqsave(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800770 val = clk_readl(c->reg);
771 new_val = val >> c->reg_shift;
772 new_val &= 0xFFFF;
773
774 new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
775
776 val &= ~(0xFFFF << c->reg_shift);
777 val |= new_val << c->reg_shift;
778 clk_writel(val, c->reg);
Colin Cross4729fd72011-02-12 16:43:05 -0800779 spin_unlock_irqrestore(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800780 return 0;
781 } else if (c->flags & DIV_2) {
782 BUG_ON(!(c->flags & PLLD));
Colin Cross4729fd72011-02-12 16:43:05 -0800783 spin_lock_irqsave(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800784 val = clk_readl(c->reg);
785 val &= ~PLLD_MISC_DIV_RST;
786 clk_writel(val, c->reg);
Colin Cross4729fd72011-02-12 16:43:05 -0800787 spin_unlock_irqrestore(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800788 return 0;
789 }
790 return -EINVAL;
791}
792
793static void tegra2_pll_div_clk_disable(struct clk *c)
794{
795 u32 val;
796 u32 new_val;
Colin Cross4729fd72011-02-12 16:43:05 -0800797 unsigned long flags;
Colin Crossd8611962010-01-28 16:40:29 -0800798
799 pr_debug("%s: %s\n", __func__, c->name);
800 if (c->flags & DIV_U71) {
Colin Cross4729fd72011-02-12 16:43:05 -0800801 spin_lock_irqsave(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800802 val = clk_readl(c->reg);
803 new_val = val >> c->reg_shift;
804 new_val &= 0xFFFF;
805
806 new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
807
808 val &= ~(0xFFFF << c->reg_shift);
809 val |= new_val << c->reg_shift;
810 clk_writel(val, c->reg);
Colin Cross4729fd72011-02-12 16:43:05 -0800811 spin_unlock_irqrestore(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800812 } else if (c->flags & DIV_2) {
813 BUG_ON(!(c->flags & PLLD));
Colin Cross4729fd72011-02-12 16:43:05 -0800814 spin_lock_irqsave(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800815 val = clk_readl(c->reg);
816 val |= PLLD_MISC_DIV_RST;
817 clk_writel(val, c->reg);
Colin Cross4729fd72011-02-12 16:43:05 -0800818 spin_unlock_irqrestore(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800819 }
820}
821
822static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
823{
824 u32 val;
825 u32 new_val;
826 int divider_u71;
Colin Cross4729fd72011-02-12 16:43:05 -0800827 unsigned long parent_rate = clk_get_rate(c->parent);
828 unsigned long flags;
829
Colin Crossd8611962010-01-28 16:40:29 -0800830 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
831 if (c->flags & DIV_U71) {
Colin Cross4729fd72011-02-12 16:43:05 -0800832 divider_u71 = clk_div71_get_divider(parent_rate, rate);
Colin Crossd8611962010-01-28 16:40:29 -0800833 if (divider_u71 >= 0) {
Colin Cross4729fd72011-02-12 16:43:05 -0800834 spin_lock_irqsave(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800835 val = clk_readl(c->reg);
836 new_val = val >> c->reg_shift;
837 new_val &= 0xFFFF;
838 if (c->flags & DIV_U71_FIXED)
839 new_val |= PLL_OUT_OVERRIDE;
840 new_val &= ~PLL_OUT_RATIO_MASK;
841 new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
842
843 val &= ~(0xFFFF << c->reg_shift);
844 val |= new_val << c->reg_shift;
845 clk_writel(val, c->reg);
846 c->div = divider_u71 + 2;
847 c->mul = 2;
Colin Cross4729fd72011-02-12 16:43:05 -0800848 spin_unlock_irqrestore(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800849 return 0;
850 }
851 } else if (c->flags & DIV_2) {
Colin Cross4729fd72011-02-12 16:43:05 -0800852 if (parent_rate == rate * 2)
Colin Crossd8611962010-01-28 16:40:29 -0800853 return 0;
Colin Crossd8611962010-01-28 16:40:29 -0800854 }
855 return -EINVAL;
856}
857
Colin Cross71fc84c2010-06-07 20:49:46 -0700858static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
859{
860 int divider;
Colin Cross4729fd72011-02-12 16:43:05 -0800861 unsigned long parent_rate = clk_get_rate(c->parent);
Colin Cross71fc84c2010-06-07 20:49:46 -0700862 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
863
864 if (c->flags & DIV_U71) {
Colin Cross4729fd72011-02-12 16:43:05 -0800865 divider = clk_div71_get_divider(parent_rate, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -0700866 if (divider < 0)
867 return divider;
Colin Cross4729fd72011-02-12 16:43:05 -0800868 return parent_rate * 2 / (divider + 2);
Colin Cross71fc84c2010-06-07 20:49:46 -0700869 } else if (c->flags & DIV_2) {
Colin Cross4729fd72011-02-12 16:43:05 -0800870 return parent_rate / 2;
Colin Cross71fc84c2010-06-07 20:49:46 -0700871 }
872 return -EINVAL;
873}
Colin Crossd8611962010-01-28 16:40:29 -0800874
875static struct clk_ops tegra_pll_div_ops = {
876 .init = tegra2_pll_div_clk_init,
877 .enable = tegra2_pll_div_clk_enable,
878 .disable = tegra2_pll_div_clk_disable,
879 .set_rate = tegra2_pll_div_clk_set_rate,
Colin Cross71fc84c2010-06-07 20:49:46 -0700880 .round_rate = tegra2_pll_div_clk_round_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800881};
882
883/* Periph clk ops */
884
885static void tegra2_periph_clk_init(struct clk *c)
886{
887 u32 val = clk_readl(c->reg);
888 const struct clk_mux_sel *mux = 0;
889 const struct clk_mux_sel *sel;
890 if (c->flags & MUX) {
891 for (sel = c->inputs; sel->input != NULL; sel++) {
892 if (val >> PERIPH_CLK_SOURCE_SHIFT == sel->value)
893 mux = sel;
894 }
895 BUG_ON(!mux);
896
897 c->parent = mux->input;
898 } else {
899 c->parent = c->inputs[0].input;
900 }
901
902 if (c->flags & DIV_U71) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700903 u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
Colin Crossd8611962010-01-28 16:40:29 -0800904 c->div = divu71 + 2;
905 c->mul = 2;
Colin Cross71fc84c2010-06-07 20:49:46 -0700906 } else if (c->flags & DIV_U16) {
907 u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
908 c->div = divu16 + 1;
909 c->mul = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800910 } else {
911 c->div = 1;
912 c->mul = 1;
913 }
914
915 c->state = ON;
916 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
917 PERIPH_CLK_TO_ENB_BIT(c)))
918 c->state = OFF;
919 if (!(c->flags & PERIPH_NO_RESET))
920 if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
921 PERIPH_CLK_TO_ENB_BIT(c))
922 c->state = OFF;
Colin Crossd8611962010-01-28 16:40:29 -0800923}
924
925static int tegra2_periph_clk_enable(struct clk *c)
926{
927 u32 val;
928 pr_debug("%s on clock %s\n", __func__, c->name);
929
930 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
931 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
932 if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET))
933 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
934 RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
935 if (c->flags & PERIPH_EMC_ENB) {
936 /* The EMC peripheral clock has 2 extra enable bits */
937 /* FIXME: Do they need to be disabled? */
938 val = clk_readl(c->reg);
939 val |= 0x3 << 24;
940 clk_writel(val, c->reg);
941 }
942 return 0;
943}
944
945static void tegra2_periph_clk_disable(struct clk *c)
946{
947 pr_debug("%s on clock %s\n", __func__, c->name);
948
949 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
950 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
951}
952
Dima Zavin2b84cb4f2010-09-02 19:11:11 -0700953static void tegra2_periph_clk_reset(struct clk *c, bool assert)
Colin Crossd8611962010-01-28 16:40:29 -0800954{
Dima Zavin2b84cb4f2010-09-02 19:11:11 -0700955 unsigned long base = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
956
957 pr_debug("%s %s on clock %s\n", __func__,
958 assert ? "assert" : "deassert", c->name);
Colin Crossd8611962010-01-28 16:40:29 -0800959 if (!(c->flags & PERIPH_NO_RESET))
960 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
Dima Zavin2b84cb4f2010-09-02 19:11:11 -0700961 base + PERIPH_CLK_TO_ENB_SET_REG(c));
Colin Crossd8611962010-01-28 16:40:29 -0800962}
963
Colin Crossd8611962010-01-28 16:40:29 -0800964static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
965{
966 u32 val;
967 const struct clk_mux_sel *sel;
968 pr_debug("%s: %s %s\n", __func__, c->name, p->name);
969 for (sel = c->inputs; sel->input != NULL; sel++) {
970 if (sel->input == p) {
Colin Crossd8611962010-01-28 16:40:29 -0800971 val = clk_readl(c->reg);
972 val &= ~PERIPH_CLK_SOURCE_MASK;
973 val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT;
Colin Cross71fc84c2010-06-07 20:49:46 -0700974
975 if (c->refcnt)
Colin Cross4729fd72011-02-12 16:43:05 -0800976 clk_enable(p);
Colin Cross71fc84c2010-06-07 20:49:46 -0700977
Colin Crossd8611962010-01-28 16:40:29 -0800978 clk_writel(val, c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -0700979
980 if (c->refcnt && c->parent)
Colin Cross4729fd72011-02-12 16:43:05 -0800981 clk_disable(c->parent);
Colin Cross71fc84c2010-06-07 20:49:46 -0700982
983 clk_reparent(c, p);
Colin Crossd8611962010-01-28 16:40:29 -0800984 return 0;
985 }
986 }
987
988 return -EINVAL;
989}
990
991static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
992{
993 u32 val;
Colin Cross71fc84c2010-06-07 20:49:46 -0700994 int divider;
Colin Cross4729fd72011-02-12 16:43:05 -0800995 unsigned long parent_rate = clk_get_rate(c->parent);
996
Colin Crossd8611962010-01-28 16:40:29 -0800997 if (c->flags & DIV_U71) {
Colin Cross4729fd72011-02-12 16:43:05 -0800998 divider = clk_div71_get_divider(parent_rate, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -0700999 if (divider >= 0) {
Colin Crossd8611962010-01-28 16:40:29 -08001000 val = clk_readl(c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -07001001 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
1002 val |= divider;
Colin Crossd8611962010-01-28 16:40:29 -08001003 clk_writel(val, c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -07001004 c->div = divider + 2;
Colin Crossd8611962010-01-28 16:40:29 -08001005 c->mul = 2;
Colin Crossd8611962010-01-28 16:40:29 -08001006 return 0;
1007 }
Colin Cross71fc84c2010-06-07 20:49:46 -07001008 } else if (c->flags & DIV_U16) {
Colin Cross4729fd72011-02-12 16:43:05 -08001009 divider = clk_div16_get_divider(parent_rate, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -07001010 if (divider >= 0) {
1011 val = clk_readl(c->reg);
1012 val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
1013 val |= divider;
1014 clk_writel(val, c->reg);
1015 c->div = divider + 1;
1016 c->mul = 1;
1017 return 0;
1018 }
Colin Cross4729fd72011-02-12 16:43:05 -08001019 } else if (parent_rate <= rate) {
Colin Cross71fc84c2010-06-07 20:49:46 -07001020 c->div = 1;
1021 c->mul = 1;
1022 return 0;
1023 }
1024 return -EINVAL;
1025}
1026
1027static long tegra2_periph_clk_round_rate(struct clk *c,
1028 unsigned long rate)
1029{
1030 int divider;
Colin Cross4729fd72011-02-12 16:43:05 -08001031 unsigned long parent_rate = clk_get_rate(c->parent);
Colin Cross71fc84c2010-06-07 20:49:46 -07001032 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
1033
1034 if (c->flags & DIV_U71) {
Colin Cross4729fd72011-02-12 16:43:05 -08001035 divider = clk_div71_get_divider(parent_rate, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -07001036 if (divider < 0)
1037 return divider;
1038
Colin Cross4729fd72011-02-12 16:43:05 -08001039 return parent_rate * 2 / (divider + 2);
Colin Cross71fc84c2010-06-07 20:49:46 -07001040 } else if (c->flags & DIV_U16) {
Colin Cross4729fd72011-02-12 16:43:05 -08001041 divider = clk_div16_get_divider(parent_rate, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -07001042 if (divider < 0)
1043 return divider;
Colin Cross4729fd72011-02-12 16:43:05 -08001044 return parent_rate / (divider + 1);
Colin Crossd8611962010-01-28 16:40:29 -08001045 }
1046 return -EINVAL;
1047}
1048
1049static struct clk_ops tegra_periph_clk_ops = {
1050 .init = &tegra2_periph_clk_init,
1051 .enable = &tegra2_periph_clk_enable,
1052 .disable = &tegra2_periph_clk_disable,
1053 .set_parent = &tegra2_periph_clk_set_parent,
1054 .set_rate = &tegra2_periph_clk_set_rate,
Colin Cross71fc84c2010-06-07 20:49:46 -07001055 .round_rate = &tegra2_periph_clk_round_rate,
Dima Zavin2b84cb4f2010-09-02 19:11:11 -07001056 .reset = &tegra2_periph_clk_reset,
Colin Crossd8611962010-01-28 16:40:29 -08001057};
1058
Colin Cross9743b382011-02-12 18:24:32 -08001059/* The SDMMC controllers have extra bits in the clock source register that
1060 * adjust the delay between the clock and data to compenstate for delays
1061 * on the PCB. */
1062void tegra2_sdmmc_tap_delay(struct clk *c, int delay)
1063{
1064 u32 reg;
1065
1066 delay = clamp(delay, 0, 15);
1067 reg = clk_readl(c->reg);
1068 reg &= ~SDMMC_CLK_INT_FB_DLY_MASK;
1069 reg |= SDMMC_CLK_INT_FB_SEL;
1070 reg |= delay << SDMMC_CLK_INT_FB_DLY_SHIFT;
1071 clk_writel(reg, c->reg);
1072}
1073
Colin Cross6d296822010-11-22 18:37:54 -08001074/* External memory controller clock ops */
1075static void tegra2_emc_clk_init(struct clk *c)
1076{
1077 tegra2_periph_clk_init(c);
1078 c->max_rate = clk_get_rate_locked(c);
1079}
1080
1081static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate)
1082{
1083 long new_rate = rate;
1084
1085 new_rate = tegra_emc_round_rate(new_rate);
1086 if (new_rate < 0)
1087 return c->max_rate;
1088
1089 BUG_ON(new_rate != tegra2_periph_clk_round_rate(c, new_rate));
1090
1091 return new_rate;
1092}
1093
1094static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate)
1095{
1096 int ret;
1097 /*
1098 * The Tegra2 memory controller has an interlock with the clock
1099 * block that allows memory shadowed registers to be updated,
1100 * and then transfer them to the main registers at the same
1101 * time as the clock update without glitches.
1102 */
1103 ret = tegra_emc_set_rate(rate);
1104 if (ret < 0)
1105 return ret;
1106
1107 ret = tegra2_periph_clk_set_rate(c, rate);
1108 udelay(1);
1109
1110 return ret;
1111}
1112
1113static struct clk_ops tegra_emc_clk_ops = {
1114 .init = &tegra2_emc_clk_init,
1115 .enable = &tegra2_periph_clk_enable,
1116 .disable = &tegra2_periph_clk_disable,
1117 .set_parent = &tegra2_periph_clk_set_parent,
1118 .set_rate = &tegra2_emc_clk_set_rate,
1119 .round_rate = &tegra2_emc_clk_round_rate,
1120 .reset = &tegra2_periph_clk_reset,
1121};
1122
Colin Crossd8611962010-01-28 16:40:29 -08001123/* Clock doubler ops */
1124static void tegra2_clk_double_init(struct clk *c)
1125{
1126 c->mul = 2;
1127 c->div = 1;
1128 c->state = ON;
1129 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1130 PERIPH_CLK_TO_ENB_BIT(c)))
1131 c->state = OFF;
Colin Crossd8611962010-01-28 16:40:29 -08001132};
1133
Colin Cross71fc84c2010-06-07 20:49:46 -07001134static int tegra2_clk_double_set_rate(struct clk *c, unsigned long rate)
1135{
Colin Cross4729fd72011-02-12 16:43:05 -08001136 if (rate != 2 * clk_get_rate(c->parent))
Colin Cross71fc84c2010-06-07 20:49:46 -07001137 return -EINVAL;
1138 c->mul = 2;
1139 c->div = 1;
1140 return 0;
1141}
1142
Colin Crossd8611962010-01-28 16:40:29 -08001143static struct clk_ops tegra_clk_double_ops = {
1144 .init = &tegra2_clk_double_init,
1145 .enable = &tegra2_periph_clk_enable,
1146 .disable = &tegra2_periph_clk_disable,
Colin Cross71fc84c2010-06-07 20:49:46 -07001147 .set_rate = &tegra2_clk_double_set_rate,
1148};
1149
Colin Crosscea62c82010-10-04 11:49:26 -07001150/* Audio sync clock ops */
Colin Cross71fc84c2010-06-07 20:49:46 -07001151static void tegra2_audio_sync_clk_init(struct clk *c)
1152{
1153 int source;
1154 const struct clk_mux_sel *sel;
1155 u32 val = clk_readl(c->reg);
1156 c->state = (val & (1<<4)) ? OFF : ON;
1157 source = val & 0xf;
1158 for (sel = c->inputs; sel->input != NULL; sel++)
1159 if (sel->value == source)
1160 break;
1161 BUG_ON(sel->input == NULL);
1162 c->parent = sel->input;
1163}
1164
1165static int tegra2_audio_sync_clk_enable(struct clk *c)
1166{
1167 clk_writel(0, c->reg);
1168 return 0;
1169}
1170
1171static void tegra2_audio_sync_clk_disable(struct clk *c)
1172{
1173 clk_writel(1, c->reg);
1174}
1175
1176static int tegra2_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
1177{
1178 u32 val;
1179 const struct clk_mux_sel *sel;
1180 for (sel = c->inputs; sel->input != NULL; sel++) {
1181 if (sel->input == p) {
1182 val = clk_readl(c->reg);
1183 val &= ~0xf;
1184 val |= sel->value;
1185
1186 if (c->refcnt)
Colin Cross4729fd72011-02-12 16:43:05 -08001187 clk_enable(p);
Colin Cross71fc84c2010-06-07 20:49:46 -07001188
1189 clk_writel(val, c->reg);
1190
1191 if (c->refcnt && c->parent)
Colin Cross4729fd72011-02-12 16:43:05 -08001192 clk_disable(c->parent);
Colin Cross71fc84c2010-06-07 20:49:46 -07001193
1194 clk_reparent(c, p);
1195 return 0;
1196 }
1197 }
1198
1199 return -EINVAL;
1200}
1201
1202static int tegra2_audio_sync_clk_set_rate(struct clk *c, unsigned long rate)
1203{
1204 unsigned long parent_rate;
1205 if (!c->parent) {
1206 pr_err("%s: clock has no parent\n", __func__);
1207 return -EINVAL;
1208 }
1209 parent_rate = c->parent->rate;
1210 if (rate != parent_rate) {
1211 pr_err("%s: %s/%ld differs from parent %s/%ld\n",
1212 __func__,
1213 c->name, rate,
1214 c->parent->name, parent_rate);
1215 return -EINVAL;
1216 }
1217 c->rate = parent_rate;
1218 return 0;
1219}
1220
1221static struct clk_ops tegra_audio_sync_clk_ops = {
1222 .init = tegra2_audio_sync_clk_init,
1223 .enable = tegra2_audio_sync_clk_enable,
1224 .disable = tegra2_audio_sync_clk_disable,
1225 .set_rate = tegra2_audio_sync_clk_set_rate,
1226 .set_parent = tegra2_audio_sync_clk_set_parent,
Colin Crossd8611962010-01-28 16:40:29 -08001227};
1228
Colin Crosscea62c82010-10-04 11:49:26 -07001229/* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */
1230
1231static void tegra2_cdev_clk_init(struct clk *c)
1232{
1233 /* We could un-tristate the cdev1 or cdev2 pingroup here; this is
1234 * currently done in the pinmux code. */
1235 c->state = ON;
1236 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1237 PERIPH_CLK_TO_ENB_BIT(c)))
1238 c->state = OFF;
1239}
1240
1241static int tegra2_cdev_clk_enable(struct clk *c)
1242{
1243 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1244 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
1245 return 0;
1246}
1247
1248static void tegra2_cdev_clk_disable(struct clk *c)
1249{
1250 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1251 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1252}
1253
1254static struct clk_ops tegra_cdev_clk_ops = {
1255 .init = &tegra2_cdev_clk_init,
1256 .enable = &tegra2_cdev_clk_enable,
1257 .disable = &tegra2_cdev_clk_disable,
1258};
1259
Colin Cross310992c2011-02-12 16:14:03 -08001260/* shared bus ops */
1261/*
1262 * Some clocks may have multiple downstream users that need to request a
1263 * higher clock rate. Shared bus clocks provide a unique shared_bus_user
1264 * clock to each user. The frequency of the bus is set to the highest
1265 * enabled shared_bus_user clock, with a minimum value set by the
1266 * shared bus.
1267 */
1268static int tegra_clk_shared_bus_update(struct clk *bus)
1269{
1270 struct clk *c;
1271 unsigned long rate = bus->min_rate;
1272
1273 list_for_each_entry(c, &bus->shared_bus_list, u.shared_bus_user.node)
1274 if (c->u.shared_bus_user.enabled)
1275 rate = max(c->u.shared_bus_user.rate, rate);
1276
1277 if (rate == clk_get_rate_locked(bus))
1278 return 0;
1279
1280 return clk_set_rate_locked(bus, rate);
1281};
1282
1283static void tegra_clk_shared_bus_init(struct clk *c)
1284{
1285 unsigned long flags;
1286
1287 c->max_rate = c->parent->max_rate;
1288 c->u.shared_bus_user.rate = c->parent->max_rate;
1289 c->state = OFF;
Colin Cross310992c2011-02-12 16:14:03 -08001290 c->set = true;
Colin Cross310992c2011-02-12 16:14:03 -08001291
1292 spin_lock_irqsave(&c->parent->spinlock, flags);
1293
1294 list_add_tail(&c->u.shared_bus_user.node,
1295 &c->parent->shared_bus_list);
1296
1297 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1298}
1299
1300static int tegra_clk_shared_bus_set_rate(struct clk *c, unsigned long rate)
1301{
1302 unsigned long flags;
1303 int ret;
1304
1305 rate = clk_round_rate(c->parent, rate);
1306 if (rate < 0)
1307 return rate;
1308
1309 spin_lock_irqsave(&c->parent->spinlock, flags);
1310
1311 c->u.shared_bus_user.rate = rate;
1312 ret = tegra_clk_shared_bus_update(c->parent);
1313
1314 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1315
1316 return ret;
1317}
1318
1319static long tegra_clk_shared_bus_round_rate(struct clk *c, unsigned long rate)
1320{
1321 return clk_round_rate(c->parent, rate);
1322}
1323
1324static int tegra_clk_shared_bus_enable(struct clk *c)
1325{
1326 unsigned long flags;
1327 int ret;
1328
1329 spin_lock_irqsave(&c->parent->spinlock, flags);
1330
1331 c->u.shared_bus_user.enabled = true;
1332 ret = tegra_clk_shared_bus_update(c->parent);
1333
1334 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1335
1336 return ret;
1337}
1338
1339static void tegra_clk_shared_bus_disable(struct clk *c)
1340{
1341 unsigned long flags;
1342 int ret;
1343
1344 spin_lock_irqsave(&c->parent->spinlock, flags);
1345
1346 c->u.shared_bus_user.enabled = false;
1347 ret = tegra_clk_shared_bus_update(c->parent);
1348 WARN_ON_ONCE(ret);
1349
1350 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1351}
1352
1353static struct clk_ops tegra_clk_shared_bus_ops = {
1354 .init = tegra_clk_shared_bus_init,
1355 .enable = tegra_clk_shared_bus_enable,
1356 .disable = tegra_clk_shared_bus_disable,
1357 .set_rate = tegra_clk_shared_bus_set_rate,
1358 .round_rate = tegra_clk_shared_bus_round_rate,
1359};
1360
1361
Colin Crossd8611962010-01-28 16:40:29 -08001362/* Clock definitions */
1363static struct clk tegra_clk_32k = {
1364 .name = "clk_32k",
Colin Cross71fc84c2010-06-07 20:49:46 -07001365 .rate = 32768,
Colin Crossd8611962010-01-28 16:40:29 -08001366 .ops = NULL,
Colin Cross71fc84c2010-06-07 20:49:46 -07001367 .max_rate = 32768,
Colin Crossd8611962010-01-28 16:40:29 -08001368};
1369
Colin Crossf1519612011-02-12 16:05:31 -08001370static struct clk_pll_freq_table tegra_pll_s_freq_table[] = {
Colin Crossd8611962010-01-28 16:40:29 -08001371 {32768, 12000000, 366, 1, 1, 0},
1372 {32768, 13000000, 397, 1, 1, 0},
1373 {32768, 19200000, 586, 1, 1, 0},
1374 {32768, 26000000, 793, 1, 1, 0},
1375 {0, 0, 0, 0, 0, 0},
1376};
1377
1378static struct clk tegra_pll_s = {
1379 .name = "pll_s",
1380 .flags = PLL_ALT_MISC_REG,
1381 .ops = &tegra_pll_ops,
Colin Crossd8611962010-01-28 16:40:29 -08001382 .parent = &tegra_clk_32k,
Colin Cross71fc84c2010-06-07 20:49:46 -07001383 .max_rate = 26000000,
Colin Crossf1519612011-02-12 16:05:31 -08001384 .reg = 0xf0,
1385 .u.pll = {
1386 .input_min = 32768,
1387 .input_max = 32768,
1388 .cf_min = 0, /* FIXME */
1389 .cf_max = 0, /* FIXME */
1390 .vco_min = 12000000,
1391 .vco_max = 26000000,
1392 .freq_table = tegra_pll_s_freq_table,
1393 .lock_delay = 300,
1394 },
Colin Crossd8611962010-01-28 16:40:29 -08001395};
1396
1397static struct clk_mux_sel tegra_clk_m_sel[] = {
1398 { .input = &tegra_clk_32k, .value = 0},
1399 { .input = &tegra_pll_s, .value = 1},
1400 { 0, 0},
1401};
Colin Crossf1519612011-02-12 16:05:31 -08001402
Colin Crossd8611962010-01-28 16:40:29 -08001403static struct clk tegra_clk_m = {
1404 .name = "clk_m",
1405 .flags = ENABLE_ON_INIT,
1406 .ops = &tegra_clk_m_ops,
1407 .inputs = tegra_clk_m_sel,
1408 .reg = 0x1fc,
Colin Crossd8611962010-01-28 16:40:29 -08001409 .reg_shift = 28,
Colin Cross71fc84c2010-06-07 20:49:46 -07001410 .max_rate = 26000000,
Colin Crossd8611962010-01-28 16:40:29 -08001411};
1412
Colin Crossf1519612011-02-12 16:05:31 -08001413static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
Colin Crossd8611962010-01-28 16:40:29 -08001414 { 0, 0, 0, 0, 0, 0 },
1415};
1416
1417static struct clk tegra_pll_c = {
1418 .name = "pll_c",
1419 .flags = PLL_HAS_CPCON,
1420 .ops = &tegra_pll_ops,
1421 .reg = 0x80,
Colin Crossd8611962010-01-28 16:40:29 -08001422 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001423 .max_rate = 600000000,
Colin Crossf1519612011-02-12 16:05:31 -08001424 .u.pll = {
1425 .input_min = 2000000,
1426 .input_max = 31000000,
1427 .cf_min = 1000000,
1428 .cf_max = 6000000,
1429 .vco_min = 20000000,
1430 .vco_max = 1400000000,
1431 .freq_table = tegra_pll_c_freq_table,
1432 .lock_delay = 300,
1433 },
Colin Crossd8611962010-01-28 16:40:29 -08001434};
1435
1436static struct clk tegra_pll_c_out1 = {
1437 .name = "pll_c_out1",
1438 .ops = &tegra_pll_div_ops,
1439 .flags = DIV_U71,
1440 .parent = &tegra_pll_c,
1441 .reg = 0x84,
1442 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001443 .max_rate = 600000000,
Colin Crossd8611962010-01-28 16:40:29 -08001444};
1445
Colin Crossf1519612011-02-12 16:05:31 -08001446static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001447 { 12000000, 666000000, 666, 12, 1, 8},
1448 { 13000000, 666000000, 666, 13, 1, 8},
1449 { 19200000, 666000000, 555, 16, 1, 8},
1450 { 26000000, 666000000, 666, 26, 1, 8},
1451 { 12000000, 600000000, 600, 12, 1, 8},
1452 { 13000000, 600000000, 600, 13, 1, 8},
1453 { 19200000, 600000000, 375, 12, 1, 6},
1454 { 26000000, 600000000, 600, 26, 1, 8},
Colin Crossd8611962010-01-28 16:40:29 -08001455 { 0, 0, 0, 0, 0, 0 },
1456};
1457
1458static struct clk tegra_pll_m = {
1459 .name = "pll_m",
1460 .flags = PLL_HAS_CPCON,
1461 .ops = &tegra_pll_ops,
1462 .reg = 0x90,
Colin Crossd8611962010-01-28 16:40:29 -08001463 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001464 .max_rate = 800000000,
Colin Crossf1519612011-02-12 16:05:31 -08001465 .u.pll = {
1466 .input_min = 2000000,
1467 .input_max = 31000000,
1468 .cf_min = 1000000,
1469 .cf_max = 6000000,
1470 .vco_min = 20000000,
1471 .vco_max = 1200000000,
1472 .freq_table = tegra_pll_m_freq_table,
1473 .lock_delay = 300,
1474 },
Colin Crossd8611962010-01-28 16:40:29 -08001475};
1476
1477static struct clk tegra_pll_m_out1 = {
1478 .name = "pll_m_out1",
1479 .ops = &tegra_pll_div_ops,
1480 .flags = DIV_U71,
1481 .parent = &tegra_pll_m,
1482 .reg = 0x94,
1483 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001484 .max_rate = 600000000,
Colin Crossd8611962010-01-28 16:40:29 -08001485};
1486
Colin Crossf1519612011-02-12 16:05:31 -08001487static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
Colin Crossd8611962010-01-28 16:40:29 -08001488 { 12000000, 216000000, 432, 12, 2, 8},
1489 { 13000000, 216000000, 432, 13, 2, 8},
1490 { 19200000, 216000000, 90, 4, 2, 1},
1491 { 26000000, 216000000, 432, 26, 2, 8},
1492 { 12000000, 432000000, 432, 12, 1, 8},
1493 { 13000000, 432000000, 432, 13, 1, 8},
1494 { 19200000, 432000000, 90, 4, 1, 1},
1495 { 26000000, 432000000, 432, 26, 1, 8},
1496 { 0, 0, 0, 0, 0, 0 },
1497};
1498
1499static struct clk tegra_pll_p = {
1500 .name = "pll_p",
1501 .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
1502 .ops = &tegra_pll_ops,
1503 .reg = 0xa0,
Colin Crossd8611962010-01-28 16:40:29 -08001504 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001505 .max_rate = 432000000,
Colin Crossf1519612011-02-12 16:05:31 -08001506 .u.pll = {
1507 .input_min = 2000000,
1508 .input_max = 31000000,
1509 .cf_min = 1000000,
1510 .cf_max = 6000000,
1511 .vco_min = 20000000,
1512 .vco_max = 1400000000,
1513 .freq_table = tegra_pll_p_freq_table,
1514 .lock_delay = 300,
1515 },
Colin Crossd8611962010-01-28 16:40:29 -08001516};
1517
1518static struct clk tegra_pll_p_out1 = {
1519 .name = "pll_p_out1",
1520 .ops = &tegra_pll_div_ops,
1521 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1522 .parent = &tegra_pll_p,
1523 .reg = 0xa4,
1524 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001525 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001526};
1527
1528static struct clk tegra_pll_p_out2 = {
1529 .name = "pll_p_out2",
1530 .ops = &tegra_pll_div_ops,
1531 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1532 .parent = &tegra_pll_p,
1533 .reg = 0xa4,
1534 .reg_shift = 16,
Colin Cross71fc84c2010-06-07 20:49:46 -07001535 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001536};
1537
1538static struct clk tegra_pll_p_out3 = {
1539 .name = "pll_p_out3",
1540 .ops = &tegra_pll_div_ops,
1541 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1542 .parent = &tegra_pll_p,
1543 .reg = 0xa8,
1544 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001545 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001546};
1547
1548static struct clk tegra_pll_p_out4 = {
1549 .name = "pll_p_out4",
1550 .ops = &tegra_pll_div_ops,
1551 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1552 .parent = &tegra_pll_p,
1553 .reg = 0xa8,
1554 .reg_shift = 16,
Colin Cross71fc84c2010-06-07 20:49:46 -07001555 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001556};
1557
Colin Crossf1519612011-02-12 16:05:31 -08001558static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
Colin Crossd8611962010-01-28 16:40:29 -08001559 { 28800000, 56448000, 49, 25, 1, 1},
1560 { 28800000, 73728000, 64, 25, 1, 1},
1561 { 28800000, 11289600, 49, 25, 1, 1},
1562 { 28800000, 12288000, 64, 25, 1, 1},
Colin Cross71fc84c2010-06-07 20:49:46 -07001563 { 28800000, 24000000, 5, 6, 1, 1},
Colin Crossd8611962010-01-28 16:40:29 -08001564 { 0, 0, 0, 0, 0, 0 },
1565};
1566
1567static struct clk tegra_pll_a = {
1568 .name = "pll_a",
1569 .flags = PLL_HAS_CPCON,
1570 .ops = &tegra_pll_ops,
1571 .reg = 0xb0,
Colin Crossd8611962010-01-28 16:40:29 -08001572 .parent = &tegra_pll_p_out1,
Colin Cross71fc84c2010-06-07 20:49:46 -07001573 .max_rate = 56448000,
Colin Crossf1519612011-02-12 16:05:31 -08001574 .u.pll = {
1575 .input_min = 2000000,
1576 .input_max = 31000000,
1577 .cf_min = 1000000,
1578 .cf_max = 6000000,
1579 .vco_min = 20000000,
1580 .vco_max = 1400000000,
1581 .freq_table = tegra_pll_a_freq_table,
1582 .lock_delay = 300,
1583 },
Colin Crossd8611962010-01-28 16:40:29 -08001584};
1585
1586static struct clk tegra_pll_a_out0 = {
1587 .name = "pll_a_out0",
1588 .ops = &tegra_pll_div_ops,
1589 .flags = DIV_U71,
1590 .parent = &tegra_pll_a,
1591 .reg = 0xb4,
1592 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001593 .max_rate = 56448000,
Colin Crossd8611962010-01-28 16:40:29 -08001594};
1595
Colin Crossf1519612011-02-12 16:05:31 -08001596static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
Colin Crosscea62c82010-10-04 11:49:26 -07001597 { 12000000, 216000000, 216, 12, 1, 4},
1598 { 13000000, 216000000, 216, 13, 1, 4},
1599 { 19200000, 216000000, 135, 12, 1, 3},
1600 { 26000000, 216000000, 216, 26, 1, 4},
1601
1602 { 12000000, 594000000, 594, 12, 1, 8},
1603 { 13000000, 594000000, 594, 13, 1, 8},
1604 { 19200000, 594000000, 495, 16, 1, 8},
1605 { 26000000, 594000000, 594, 26, 1, 8},
1606
Colin Crossd8611962010-01-28 16:40:29 -08001607 { 12000000, 1000000000, 1000, 12, 1, 12},
1608 { 13000000, 1000000000, 1000, 13, 1, 12},
1609 { 19200000, 1000000000, 625, 12, 1, 8},
1610 { 26000000, 1000000000, 1000, 26, 1, 12},
Colin Crosscea62c82010-10-04 11:49:26 -07001611
Colin Crossd8611962010-01-28 16:40:29 -08001612 { 0, 0, 0, 0, 0, 0 },
1613};
1614
1615static struct clk tegra_pll_d = {
1616 .name = "pll_d",
1617 .flags = PLL_HAS_CPCON | PLLD,
1618 .ops = &tegra_pll_ops,
1619 .reg = 0xd0,
Colin Crossd8611962010-01-28 16:40:29 -08001620 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001621 .max_rate = 1000000000,
Colin Crossf1519612011-02-12 16:05:31 -08001622 .u.pll = {
1623 .input_min = 2000000,
1624 .input_max = 40000000,
1625 .cf_min = 1000000,
1626 .cf_max = 6000000,
1627 .vco_min = 40000000,
1628 .vco_max = 1000000000,
1629 .freq_table = tegra_pll_d_freq_table,
1630 .lock_delay = 1000,
1631 },
Colin Crossd8611962010-01-28 16:40:29 -08001632};
1633
1634static struct clk tegra_pll_d_out0 = {
1635 .name = "pll_d_out0",
1636 .ops = &tegra_pll_div_ops,
1637 .flags = DIV_2 | PLLD,
1638 .parent = &tegra_pll_d,
Colin Cross71fc84c2010-06-07 20:49:46 -07001639 .max_rate = 500000000,
Colin Crossd8611962010-01-28 16:40:29 -08001640};
1641
Colin Crossf1519612011-02-12 16:05:31 -08001642static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001643 { 12000000, 480000000, 960, 12, 2, 0},
1644 { 13000000, 480000000, 960, 13, 2, 0},
1645 { 19200000, 480000000, 200, 4, 2, 0},
1646 { 26000000, 480000000, 960, 26, 2, 0},
Colin Crossd8611962010-01-28 16:40:29 -08001647 { 0, 0, 0, 0, 0, 0 },
1648};
1649
1650static struct clk tegra_pll_u = {
1651 .name = "pll_u",
Colin Cross71fc84c2010-06-07 20:49:46 -07001652 .flags = PLLU,
Colin Crossd8611962010-01-28 16:40:29 -08001653 .ops = &tegra_pll_ops,
1654 .reg = 0xc0,
Colin Crossd8611962010-01-28 16:40:29 -08001655 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001656 .max_rate = 480000000,
Colin Crossf1519612011-02-12 16:05:31 -08001657 .u.pll = {
1658 .input_min = 2000000,
1659 .input_max = 40000000,
1660 .cf_min = 1000000,
1661 .cf_max = 6000000,
1662 .vco_min = 480000000,
1663 .vco_max = 960000000,
1664 .freq_table = tegra_pll_u_freq_table,
1665 .lock_delay = 1000,
1666 },
Colin Crossd8611962010-01-28 16:40:29 -08001667};
1668
Colin Crossf1519612011-02-12 16:05:31 -08001669static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001670 /* 1 GHz */
Colin Crossd8611962010-01-28 16:40:29 -08001671 { 12000000, 1000000000, 1000, 12, 1, 12},
1672 { 13000000, 1000000000, 1000, 13, 1, 12},
1673 { 19200000, 1000000000, 625, 12, 1, 8},
1674 { 26000000, 1000000000, 1000, 26, 1, 12},
Colin Cross71fc84c2010-06-07 20:49:46 -07001675
1676 /* 912 MHz */
1677 { 12000000, 912000000, 912, 12, 1, 12},
1678 { 13000000, 912000000, 912, 13, 1, 12},
1679 { 19200000, 912000000, 760, 16, 1, 8},
1680 { 26000000, 912000000, 912, 26, 1, 12},
1681
1682 /* 816 MHz */
1683 { 12000000, 816000000, 816, 12, 1, 12},
1684 { 13000000, 816000000, 816, 13, 1, 12},
1685 { 19200000, 816000000, 680, 16, 1, 8},
1686 { 26000000, 816000000, 816, 26, 1, 12},
1687
1688 /* 760 MHz */
1689 { 12000000, 760000000, 760, 12, 1, 12},
1690 { 13000000, 760000000, 760, 13, 1, 12},
1691 { 19200000, 760000000, 950, 24, 1, 8},
1692 { 26000000, 760000000, 760, 26, 1, 12},
1693
1694 /* 608 MHz */
1695 { 12000000, 608000000, 760, 12, 1, 12},
1696 { 13000000, 608000000, 760, 13, 1, 12},
1697 { 19200000, 608000000, 380, 12, 1, 8},
1698 { 26000000, 608000000, 760, 26, 1, 12},
1699
1700 /* 456 MHz */
1701 { 12000000, 456000000, 456, 12, 1, 12},
1702 { 13000000, 456000000, 456, 13, 1, 12},
1703 { 19200000, 456000000, 380, 16, 1, 8},
1704 { 26000000, 456000000, 456, 26, 1, 12},
1705
1706 /* 312 MHz */
1707 { 12000000, 312000000, 312, 12, 1, 12},
1708 { 13000000, 312000000, 312, 13, 1, 12},
1709 { 19200000, 312000000, 260, 16, 1, 8},
1710 { 26000000, 312000000, 312, 26, 1, 12},
1711
Colin Crossd8611962010-01-28 16:40:29 -08001712 { 0, 0, 0, 0, 0, 0 },
1713};
1714
1715static struct clk tegra_pll_x = {
1716 .name = "pll_x",
1717 .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG,
Colin Cross71fc84c2010-06-07 20:49:46 -07001718 .ops = &tegra_pllx_ops,
Colin Crossd8611962010-01-28 16:40:29 -08001719 .reg = 0xe0,
Colin Crossd8611962010-01-28 16:40:29 -08001720 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001721 .max_rate = 1000000000,
Colin Crossf1519612011-02-12 16:05:31 -08001722 .u.pll = {
1723 .input_min = 2000000,
1724 .input_max = 31000000,
1725 .cf_min = 1000000,
1726 .cf_max = 6000000,
1727 .vco_min = 20000000,
1728 .vco_max = 1200000000,
1729 .freq_table = tegra_pll_x_freq_table,
1730 .lock_delay = 300,
1731 },
Colin Crossd8611962010-01-28 16:40:29 -08001732};
1733
Colin Crossf1519612011-02-12 16:05:31 -08001734static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
Mike Rapoport8d685bc2010-09-27 11:26:32 +02001735 { 12000000, 100000000, 200, 24, 1, 0 },
1736 { 0, 0, 0, 0, 0, 0 },
1737};
1738
1739static struct clk tegra_pll_e = {
1740 .name = "pll_e",
1741 .flags = PLL_ALT_MISC_REG,
1742 .ops = &tegra_plle_ops,
Mike Rapoport8d685bc2010-09-27 11:26:32 +02001743 .parent = &tegra_clk_m,
1744 .reg = 0xe8,
Colin Crossf1519612011-02-12 16:05:31 -08001745 .max_rate = 100000000,
1746 .u.pll = {
1747 .input_min = 12000000,
1748 .input_max = 12000000,
1749 .freq_table = tegra_pll_e_freq_table,
1750 },
Mike Rapoport8d685bc2010-09-27 11:26:32 +02001751};
1752
Colin Crossd8611962010-01-28 16:40:29 -08001753static struct clk tegra_clk_d = {
1754 .name = "clk_d",
1755 .flags = PERIPH_NO_RESET,
1756 .ops = &tegra_clk_double_ops,
Colin Crossd8611962010-01-28 16:40:29 -08001757 .reg = 0x34,
1758 .reg_shift = 12,
1759 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001760 .max_rate = 52000000,
Colin Crossf1519612011-02-12 16:05:31 -08001761 .u.periph = {
1762 .clk_num = 90,
1763 },
Colin Crossd8611962010-01-28 16:40:29 -08001764};
1765
Colin Crosscea62c82010-10-04 11:49:26 -07001766/* dap_mclk1, belongs to the cdev1 pingroup. */
1767static struct clk tegra_dev1_clk = {
1768 .name = "clk_dev1",
1769 .ops = &tegra_cdev_clk_ops,
Colin Crosscea62c82010-10-04 11:49:26 -07001770 .rate = 26000000,
1771 .max_rate = 26000000,
Colin Crossf1519612011-02-12 16:05:31 -08001772 .u.periph = {
1773 .clk_num = 94,
1774 },
Colin Crosscea62c82010-10-04 11:49:26 -07001775};
1776
1777/* dap_mclk2, belongs to the cdev2 pingroup. */
1778static struct clk tegra_dev2_clk = {
1779 .name = "clk_dev2",
1780 .ops = &tegra_cdev_clk_ops,
Colin Crosscea62c82010-10-04 11:49:26 -07001781 .rate = 26000000,
1782 .max_rate = 26000000,
Colin Crossf1519612011-02-12 16:05:31 -08001783 .u.periph = {
1784 .clk_num = 93,
1785 },
Colin Crosscea62c82010-10-04 11:49:26 -07001786};
1787
Colin Cross71fc84c2010-06-07 20:49:46 -07001788/* initialized before peripheral clocks */
1789static struct clk_mux_sel mux_audio_sync_clk[8+1];
1790static const struct audio_sources {
1791 const char *name;
1792 int value;
1793} mux_audio_sync_clk_sources[] = {
1794 { .name = "spdif_in", .value = 0 },
1795 { .name = "i2s1", .value = 1 },
1796 { .name = "i2s2", .value = 2 },
1797 { .name = "pll_a_out0", .value = 4 },
1798#if 0 /* FIXME: not implemented */
1799 { .name = "ac97", .value = 3 },
1800 { .name = "ext_audio_clk2", .value = 5 },
1801 { .name = "ext_audio_clk1", .value = 6 },
1802 { .name = "ext_vimclk", .value = 7 },
1803#endif
1804 { 0, 0 }
1805};
1806
1807static struct clk tegra_clk_audio = {
1808 .name = "audio",
1809 .inputs = mux_audio_sync_clk,
1810 .reg = 0x38,
1811 .max_rate = 24000000,
1812 .ops = &tegra_audio_sync_clk_ops
1813};
1814
Colin Crossd8611962010-01-28 16:40:29 -08001815static struct clk tegra_clk_audio_2x = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001816 .name = "audio_2x",
Colin Crossd8611962010-01-28 16:40:29 -08001817 .flags = PERIPH_NO_RESET,
Colin Cross71fc84c2010-06-07 20:49:46 -07001818 .max_rate = 48000000,
Colin Crossd8611962010-01-28 16:40:29 -08001819 .ops = &tegra_clk_double_ops,
Colin Crossd8611962010-01-28 16:40:29 -08001820 .reg = 0x34,
1821 .reg_shift = 8,
Colin Cross71fc84c2010-06-07 20:49:46 -07001822 .parent = &tegra_clk_audio,
Colin Crossf1519612011-02-12 16:05:31 -08001823 .u.periph = {
1824 .clk_num = 89,
1825 },
Colin Cross71fc84c2010-06-07 20:49:46 -07001826};
1827
1828struct clk_lookup tegra_audio_clk_lookups[] = {
1829 { .con_id = "audio", .clk = &tegra_clk_audio },
1830 { .con_id = "audio_2x", .clk = &tegra_clk_audio_2x }
1831};
1832
1833/* This is called after peripheral clocks are initialized, as the
1834 * audio_sync clock depends on some of the peripheral clocks.
1835 */
1836
1837static void init_audio_sync_clock_mux(void)
1838{
1839 int i;
1840 struct clk_mux_sel *sel = mux_audio_sync_clk;
1841 const struct audio_sources *src = mux_audio_sync_clk_sources;
1842 struct clk_lookup *lookup;
1843
1844 for (i = 0; src->name; i++, sel++, src++) {
1845 sel->input = tegra_get_clock_by_name(src->name);
1846 if (!sel->input)
1847 pr_err("%s: could not find clk %s\n", __func__,
1848 src->name);
1849 sel->value = src->value;
1850 }
1851
1852 lookup = tegra_audio_clk_lookups;
1853 for (i = 0; i < ARRAY_SIZE(tegra_audio_clk_lookups); i++, lookup++) {
1854 clk_init(lookup->clk);
1855 clkdev_add(lookup);
1856 }
Colin Crossd8611962010-01-28 16:40:29 -08001857}
Colin Crossd8611962010-01-28 16:40:29 -08001858
1859static struct clk_mux_sel mux_cclk[] = {
1860 { .input = &tegra_clk_m, .value = 0},
1861 { .input = &tegra_pll_c, .value = 1},
1862 { .input = &tegra_clk_32k, .value = 2},
1863 { .input = &tegra_pll_m, .value = 3},
1864 { .input = &tegra_pll_p, .value = 4},
1865 { .input = &tegra_pll_p_out4, .value = 5},
1866 { .input = &tegra_pll_p_out3, .value = 6},
1867 { .input = &tegra_clk_d, .value = 7},
1868 { .input = &tegra_pll_x, .value = 8},
1869 { 0, 0},
1870};
1871
1872static struct clk_mux_sel mux_sclk[] = {
1873 { .input = &tegra_clk_m, .value = 0},
1874 { .input = &tegra_pll_c_out1, .value = 1},
1875 { .input = &tegra_pll_p_out4, .value = 2},
1876 { .input = &tegra_pll_p_out3, .value = 3},
1877 { .input = &tegra_pll_p_out2, .value = 4},
1878 { .input = &tegra_clk_d, .value = 5},
1879 { .input = &tegra_clk_32k, .value = 6},
1880 { .input = &tegra_pll_m_out1, .value = 7},
1881 { 0, 0},
1882};
1883
Colin Cross71fc84c2010-06-07 20:49:46 -07001884static struct clk tegra_clk_cclk = {
1885 .name = "cclk",
Colin Crossd8611962010-01-28 16:40:29 -08001886 .inputs = mux_cclk,
1887 .reg = 0x20,
1888 .ops = &tegra_super_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001889 .max_rate = 1000000000,
Colin Crossd8611962010-01-28 16:40:29 -08001890};
1891
Colin Cross71fc84c2010-06-07 20:49:46 -07001892static struct clk tegra_clk_sclk = {
1893 .name = "sclk",
Colin Crossd8611962010-01-28 16:40:29 -08001894 .inputs = mux_sclk,
1895 .reg = 0x28,
1896 .ops = &tegra_super_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001897 .max_rate = 600000000,
1898};
1899
1900static struct clk tegra_clk_virtual_cpu = {
1901 .name = "cpu",
1902 .parent = &tegra_clk_cclk,
Colin Cross71fc84c2010-06-07 20:49:46 -07001903 .ops = &tegra_cpu_ops,
1904 .max_rate = 1000000000,
Colin Crossf1519612011-02-12 16:05:31 -08001905 .u.cpu = {
1906 .main = &tegra_pll_x,
1907 .backup = &tegra_pll_p,
1908 },
Colin Crossd8611962010-01-28 16:40:29 -08001909};
1910
1911static struct clk tegra_clk_hclk = {
1912 .name = "hclk",
1913 .flags = DIV_BUS,
Colin Cross71fc84c2010-06-07 20:49:46 -07001914 .parent = &tegra_clk_sclk,
Colin Crossd8611962010-01-28 16:40:29 -08001915 .reg = 0x30,
1916 .reg_shift = 4,
1917 .ops = &tegra_bus_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001918 .max_rate = 240000000,
Colin Crossd8611962010-01-28 16:40:29 -08001919};
1920
1921static struct clk tegra_clk_pclk = {
1922 .name = "pclk",
1923 .flags = DIV_BUS,
1924 .parent = &tegra_clk_hclk,
1925 .reg = 0x30,
1926 .reg_shift = 0,
1927 .ops = &tegra_bus_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001928 .max_rate = 108000000,
Colin Crossd8611962010-01-28 16:40:29 -08001929};
1930
Colin Crosscea62c82010-10-04 11:49:26 -07001931static struct clk tegra_clk_blink = {
1932 .name = "blink",
1933 .parent = &tegra_clk_32k,
1934 .reg = 0x40,
1935 .ops = &tegra_blink_clk_ops,
1936 .max_rate = 32768,
1937};
1938
Colin Crossd8611962010-01-28 16:40:29 -08001939static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
1940 { .input = &tegra_pll_m, .value = 0},
1941 { .input = &tegra_pll_c, .value = 1},
1942 { .input = &tegra_pll_p, .value = 2},
1943 { .input = &tegra_pll_a_out0, .value = 3},
1944 { 0, 0},
1945};
1946
1947static struct clk_mux_sel mux_pllm_pllc_pllp_clkm[] = {
1948 { .input = &tegra_pll_m, .value = 0},
1949 { .input = &tegra_pll_c, .value = 1},
1950 { .input = &tegra_pll_p, .value = 2},
1951 { .input = &tegra_clk_m, .value = 3},
1952 { 0, 0},
1953};
1954
1955static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
1956 { .input = &tegra_pll_p, .value = 0},
1957 { .input = &tegra_pll_c, .value = 1},
1958 { .input = &tegra_pll_m, .value = 2},
1959 { .input = &tegra_clk_m, .value = 3},
1960 { 0, 0},
1961};
1962
Colin Cross71fc84c2010-06-07 20:49:46 -07001963static struct clk_mux_sel mux_pllaout0_audio2x_pllp_clkm[] = {
1964 {.input = &tegra_pll_a_out0, .value = 0},
1965 {.input = &tegra_clk_audio_2x, .value = 1},
Colin Crossd8611962010-01-28 16:40:29 -08001966 {.input = &tegra_pll_p, .value = 2},
1967 {.input = &tegra_clk_m, .value = 3},
1968 { 0, 0},
1969};
1970
1971static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
1972 {.input = &tegra_pll_p, .value = 0},
1973 {.input = &tegra_pll_d_out0, .value = 1},
1974 {.input = &tegra_pll_c, .value = 2},
1975 {.input = &tegra_clk_m, .value = 3},
1976 { 0, 0},
1977};
1978
1979static struct clk_mux_sel mux_pllp_pllc_audio_clkm_clk32[] = {
1980 {.input = &tegra_pll_p, .value = 0},
1981 {.input = &tegra_pll_c, .value = 1},
Colin Cross71fc84c2010-06-07 20:49:46 -07001982 {.input = &tegra_clk_audio, .value = 2},
Colin Crossd8611962010-01-28 16:40:29 -08001983 {.input = &tegra_clk_m, .value = 3},
1984 {.input = &tegra_clk_32k, .value = 4},
1985 { 0, 0},
1986};
1987
1988static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
1989 {.input = &tegra_pll_p, .value = 0},
1990 {.input = &tegra_pll_c, .value = 1},
1991 {.input = &tegra_pll_m, .value = 2},
1992 { 0, 0},
1993};
1994
1995static struct clk_mux_sel mux_clk_m[] = {
1996 { .input = &tegra_clk_m, .value = 0},
1997 { 0, 0},
1998};
1999
2000static struct clk_mux_sel mux_pllp_out3[] = {
2001 { .input = &tegra_pll_p_out3, .value = 0},
2002 { 0, 0},
2003};
2004
2005static struct clk_mux_sel mux_plld[] = {
2006 { .input = &tegra_pll_d, .value = 0},
2007 { 0, 0},
2008};
2009
2010static struct clk_mux_sel mux_clk_32k[] = {
2011 { .input = &tegra_clk_32k, .value = 0},
2012 { 0, 0},
2013};
2014
Stephen Warren1ca00342011-01-05 14:32:20 -07002015static struct clk_mux_sel mux_pclk[] = {
2016 { .input = &tegra_clk_pclk, .value = 0},
2017 { 0, 0},
2018};
2019
Colin Cross6d296822010-11-22 18:37:54 -08002020static struct clk tegra_clk_emc = {
2021 .name = "emc",
2022 .ops = &tegra_emc_clk_ops,
2023 .reg = 0x19c,
2024 .max_rate = 800000000,
2025 .inputs = mux_pllm_pllc_pllp_clkm,
2026 .flags = MUX | DIV_U71 | PERIPH_EMC_ENB,
2027 .u.periph = {
2028 .clk_num = 57,
2029 },
2030};
2031
Colin Cross71fc84c2010-06-07 20:49:46 -07002032#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
Colin Crossd8611962010-01-28 16:40:29 -08002033 { \
2034 .name = _name, \
2035 .lookup = { \
2036 .dev_id = _dev, \
2037 .con_id = _con, \
2038 }, \
2039 .ops = &tegra_periph_clk_ops, \
Colin Crossd8611962010-01-28 16:40:29 -08002040 .reg = _reg, \
2041 .inputs = _inputs, \
2042 .flags = _flags, \
Colin Cross71fc84c2010-06-07 20:49:46 -07002043 .max_rate = _max, \
Colin Crossf1519612011-02-12 16:05:31 -08002044 .u.periph = { \
2045 .clk_num = _clk_num, \
2046 }, \
Colin Crossd8611962010-01-28 16:40:29 -08002047 }
2048
Colin Cross310992c2011-02-12 16:14:03 -08002049#define SHARED_CLK(_name, _dev, _con, _parent) \
2050 { \
2051 .name = _name, \
2052 .lookup = { \
2053 .dev_id = _dev, \
2054 .con_id = _con, \
2055 }, \
2056 .ops = &tegra_clk_shared_bus_ops, \
2057 .parent = _parent, \
2058 }
2059
Colin Cross3ec349f2011-02-12 15:52:56 -08002060struct clk tegra_list_clks[] = {
Stephen Warren1ca00342011-01-05 14:32:20 -07002061 PERIPH_CLK("apbdma", "tegra-dma", NULL, 34, 0, 108000000, mux_pclk, 0),
Colin Cross71fc84c2010-06-07 20:49:46 -07002062 PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET),
2063 PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0),
2064 PERIPH_CLK("i2s1", "i2s.0", NULL, 11, 0x100, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
2065 PERIPH_CLK("i2s2", "i2s.1", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
Colin Crossd8611962010-01-28 16:40:29 -08002066 /* FIXME: spdif has 2 clocks but 1 enable */
Colin Cross71fc84c2010-06-07 20:49:46 -07002067 PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
2068 PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71),
2069 PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71),
2070 PERIPH_CLK("spi", "spi", NULL, 43, 0x114, 40000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2071 PERIPH_CLK("xio", "xio", NULL, 45, 0x120, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2072 PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2073 PERIPH_CLK("sbc1", "spi_tegra.0", NULL, 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2074 PERIPH_CLK("sbc2", "spi_tegra.1", NULL, 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2075 PERIPH_CLK("sbc3", "spi_tegra.2", NULL, 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2076 PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2077 PERIPH_CLK("ide", "ide", NULL, 25, 0x144, 100000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
2078 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 -08002079 /* FIXME: vfir shares an enable with uartb */
Colin Cross71fc84c2010-06-07 20:49:46 -07002080 PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2081 PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2082 PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2083 PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
Colin Crosscea62c82010-10-04 11:49:26 -07002084 PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x164, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
Colin Cross71fc84c2010-06-07 20:49:46 -07002085 PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
2086 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 -08002087 /* FIXME: what is la? */
Colin Cross71fc84c2010-06-07 20:49:46 -07002088 PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2089 PERIPH_CLK("owr", "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2090 PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, 92000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
2091 PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2092 PERIPH_CLK("i2c1", "tegra-i2c.0", NULL, 12, 0x124, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
2093 PERIPH_CLK("i2c2", "tegra-i2c.1", NULL, 54, 0x198, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
2094 PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
2095 PERIPH_CLK("dvc", "tegra-i2c.3", NULL, 47, 0x128, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
2096 PERIPH_CLK("i2c1_i2c", "tegra-i2c.0", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
2097 PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
2098 PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
2099 PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
Colin Crosscea62c82010-10-04 11:49:26 -07002100 PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
2101 PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
2102 PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
2103 PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
2104 PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
Colin Cross71fc84c2010-06-07 20:49:46 -07002105 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 */
2106 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 -08002107 /* FIXME: vi and vi_sensor share an enable */
Colin Crosscea62c82010-10-04 11:49:26 -07002108 PERIPH_CLK("vi", "tegra_camera", "vi", 20, 0x148, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
2109 PERIPH_CLK("vi_sensor", "tegra_camera", "vi_sensor", 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET), /* scales with voltage and process_id */
Colin Cross71fc84c2010-06-07 20:49:46 -07002110 PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
2111 PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 250000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
2112 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 -08002113 /* FIXME: cve and tvo share an enable */
Colin Cross71fc84c2010-06-07 20:49:46 -07002114 PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
2115 PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
Colin Crosscea62c82010-10-04 11:49:26 -07002116 PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
Colin Cross71fc84c2010-06-07 20:49:46 -07002117 PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
Colin Crosscea62c82010-10-04 11:49:26 -07002118 PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
2119 PERIPH_CLK("disp2", "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
Colin Cross71fc84c2010-06-07 20:49:46 -07002120 PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
2121 PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
2122 PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
Colin Cross71fc84c2010-06-07 20:49:46 -07002123 PERIPH_CLK("dsi", "dsi", NULL, 48, 0, 500000000, mux_plld, 0), /* scales with voltage */
Colin Crosscea62c82010-10-04 11:49:26 -07002124 PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 72000000, mux_pllp_out3, 0),
2125 PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */
2126 PERIPH_CLK("csus", "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET),
Mike Rapoport8d685bc2010-09-27 11:26:32 +02002127 PERIPH_CLK("pex", NULL, "pex", 70, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
2128 PERIPH_CLK("afi", NULL, "afi", 72, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
2129 PERIPH_CLK("pcie_xclk", NULL, "pcie_xclk", 74, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
Colin Crossd8611962010-01-28 16:40:29 -08002130};
2131
2132#define CLK_DUPLICATE(_name, _dev, _con) \
2133 { \
2134 .name = _name, \
2135 .lookup = { \
2136 .dev_id = _dev, \
2137 .con_id = _con, \
2138 }, \
2139 }
2140
2141/* Some clocks may be used by different drivers depending on the board
2142 * configuration. List those here to register them twice in the clock lookup
2143 * table under two names.
2144 */
2145struct clk_duplicate tegra_clk_duplicates[] = {
2146 CLK_DUPLICATE("uarta", "tegra_uart.0", NULL),
2147 CLK_DUPLICATE("uartb", "tegra_uart.1", NULL),
2148 CLK_DUPLICATE("uartc", "tegra_uart.2", NULL),
2149 CLK_DUPLICATE("uartd", "tegra_uart.3", NULL),
2150 CLK_DUPLICATE("uarte", "tegra_uart.4", NULL),
Colin Crosscea62c82010-10-04 11:49:26 -07002151 CLK_DUPLICATE("usbd", "utmip-pad", NULL),
Colin Cross71fc84c2010-06-07 20:49:46 -07002152 CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
Colin Crosscea62c82010-10-04 11:49:26 -07002153 CLK_DUPLICATE("usbd", "tegra-otg", NULL),
2154 CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
2155 CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
2156 CLK_DUPLICATE("pwm", "tegra_pwm.0", NULL),
2157 CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL),
2158 CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL),
2159 CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL),
Colin Crossd8611962010-01-28 16:40:29 -08002160};
2161
2162#define CLK(dev, con, ck) \
2163 { \
2164 .dev_id = dev, \
2165 .con_id = con, \
2166 .clk = ck, \
2167 }
2168
Colin Cross3ec349f2011-02-12 15:52:56 -08002169struct clk *tegra_ptr_clks[] = {
2170 &tegra_clk_32k,
2171 &tegra_pll_s,
2172 &tegra_clk_m,
2173 &tegra_pll_m,
2174 &tegra_pll_m_out1,
2175 &tegra_pll_c,
2176 &tegra_pll_c_out1,
2177 &tegra_pll_p,
2178 &tegra_pll_p_out1,
2179 &tegra_pll_p_out2,
2180 &tegra_pll_p_out3,
2181 &tegra_pll_p_out4,
2182 &tegra_pll_a,
2183 &tegra_pll_a_out0,
2184 &tegra_pll_d,
2185 &tegra_pll_d_out0,
2186 &tegra_pll_u,
2187 &tegra_pll_x,
2188 &tegra_pll_e,
2189 &tegra_clk_cclk,
2190 &tegra_clk_sclk,
2191 &tegra_clk_hclk,
2192 &tegra_clk_pclk,
2193 &tegra_clk_d,
2194 &tegra_dev1_clk,
2195 &tegra_dev2_clk,
2196 &tegra_clk_virtual_cpu,
2197 &tegra_clk_blink,
Colin Cross6d296822010-11-22 18:37:54 -08002198 &tegra_clk_emc,
Colin Crossd8611962010-01-28 16:40:29 -08002199};
2200
Colin Cross3ec349f2011-02-12 15:52:56 -08002201static void tegra2_init_one_clock(struct clk *c)
2202{
2203 clk_init(c);
Colin Cross310992c2011-02-12 16:14:03 -08002204 INIT_LIST_HEAD(&c->shared_bus_list);
Colin Cross3ec349f2011-02-12 15:52:56 -08002205 if (!c->lookup.dev_id && !c->lookup.con_id)
2206 c->lookup.con_id = c->name;
2207 c->lookup.clk = c;
2208 clkdev_add(&c->lookup);
2209}
2210
Colin Crossd8611962010-01-28 16:40:29 -08002211void __init tegra2_init_clocks(void)
2212{
2213 int i;
Colin Crossd8611962010-01-28 16:40:29 -08002214 struct clk *c;
Colin Crossd8611962010-01-28 16:40:29 -08002215
Colin Cross3ec349f2011-02-12 15:52:56 -08002216 for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
2217 tegra2_init_one_clock(tegra_ptr_clks[i]);
Colin Crossd8611962010-01-28 16:40:29 -08002218
Colin Cross3ec349f2011-02-12 15:52:56 -08002219 for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
2220 tegra2_init_one_clock(&tegra_list_clks[i]);
Colin Crossd8611962010-01-28 16:40:29 -08002221
2222 for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
Colin Cross3ec349f2011-02-12 15:52:56 -08002223 c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
2224 if (!c) {
Colin Crossd8611962010-01-28 16:40:29 -08002225 pr_err("%s: Unknown duplicate clock %s\n", __func__,
Colin Cross3ec349f2011-02-12 15:52:56 -08002226 tegra_clk_duplicates[i].name);
2227 continue;
Colin Crossd8611962010-01-28 16:40:29 -08002228 }
Colin Cross3ec349f2011-02-12 15:52:56 -08002229
2230 tegra_clk_duplicates[i].lookup.clk = c;
2231 clkdev_add(&tegra_clk_duplicates[i].lookup);
Colin Crossd8611962010-01-28 16:40:29 -08002232 }
Colin Cross71fc84c2010-06-07 20:49:46 -07002233
2234 init_audio_sync_clock_mux();
Colin Crossd8611962010-01-28 16:40:29 -08002235}
Colin Cross71fc84c2010-06-07 20:49:46 -07002236
2237#ifdef CONFIG_PM
2238static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM +
Colin Crossc2f44a92010-10-26 17:33:31 -07002239 PERIPH_CLK_SOURCE_NUM + 22];
Colin Cross71fc84c2010-06-07 20:49:46 -07002240
2241void tegra_clk_suspend(void)
2242{
2243 unsigned long off, i;
2244 u32 *ctx = clk_rst_suspend;
2245
2246 *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK;
Colin Crosscea62c82010-10-04 11:49:26 -07002247 *ctx++ = clk_readl(tegra_pll_c.reg + PLL_BASE);
2248 *ctx++ = clk_readl(tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
2249 *ctx++ = clk_readl(tegra_pll_a.reg + PLL_BASE);
2250 *ctx++ = clk_readl(tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
Colin Crossc2f44a92010-10-26 17:33:31 -07002251 *ctx++ = clk_readl(tegra_pll_s.reg + PLL_BASE);
2252 *ctx++ = clk_readl(tegra_pll_s.reg + PLL_MISC(&tegra_pll_s));
2253 *ctx++ = clk_readl(tegra_pll_d.reg + PLL_BASE);
2254 *ctx++ = clk_readl(tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
2255 *ctx++ = clk_readl(tegra_pll_u.reg + PLL_BASE);
2256 *ctx++ = clk_readl(tegra_pll_u.reg + PLL_MISC(&tegra_pll_u));
Colin Crosscea62c82010-10-04 11:49:26 -07002257
2258 *ctx++ = clk_readl(tegra_pll_m_out1.reg);
Colin Crosscea62c82010-10-04 11:49:26 -07002259 *ctx++ = clk_readl(tegra_pll_a_out0.reg);
2260 *ctx++ = clk_readl(tegra_pll_c_out1.reg);
2261
2262 *ctx++ = clk_readl(tegra_clk_cclk.reg);
2263 *ctx++ = clk_readl(tegra_clk_cclk.reg + SUPER_CLK_DIVIDER);
2264
2265 *ctx++ = clk_readl(tegra_clk_sclk.reg);
2266 *ctx++ = clk_readl(tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
2267 *ctx++ = clk_readl(tegra_clk_pclk.reg);
Colin Cross71fc84c2010-06-07 20:49:46 -07002268
Colin Crossc2f44a92010-10-26 17:33:31 -07002269 *ctx++ = clk_readl(tegra_clk_audio.reg);
2270
Colin Cross71fc84c2010-06-07 20:49:46 -07002271 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
2272 off += 4) {
2273 if (off == PERIPH_CLK_SOURCE_EMC)
2274 continue;
2275 *ctx++ = clk_readl(off);
2276 }
2277
2278 off = RST_DEVICES;
2279 for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
2280 *ctx++ = clk_readl(off);
2281
2282 off = CLK_OUT_ENB;
2283 for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
2284 *ctx++ = clk_readl(off);
2285
2286 *ctx++ = clk_readl(MISC_CLK_ENB);
2287 *ctx++ = clk_readl(CLK_MASK_ARM);
Colin Crossc2f44a92010-10-26 17:33:31 -07002288
2289 BUG_ON(ctx - clk_rst_suspend != ARRAY_SIZE(clk_rst_suspend));
Colin Cross71fc84c2010-06-07 20:49:46 -07002290}
2291
2292void tegra_clk_resume(void)
2293{
2294 unsigned long off, i;
2295 const u32 *ctx = clk_rst_suspend;
2296 u32 val;
2297
2298 val = clk_readl(OSC_CTRL) & ~OSC_CTRL_MASK;
2299 val |= *ctx++;
2300 clk_writel(val, OSC_CTRL);
2301
Colin Crosscea62c82010-10-04 11:49:26 -07002302 clk_writel(*ctx++, tegra_pll_c.reg + PLL_BASE);
2303 clk_writel(*ctx++, tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
2304 clk_writel(*ctx++, tegra_pll_a.reg + PLL_BASE);
2305 clk_writel(*ctx++, tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
Colin Crossc2f44a92010-10-26 17:33:31 -07002306 clk_writel(*ctx++, tegra_pll_s.reg + PLL_BASE);
2307 clk_writel(*ctx++, tegra_pll_s.reg + PLL_MISC(&tegra_pll_s));
2308 clk_writel(*ctx++, tegra_pll_d.reg + PLL_BASE);
2309 clk_writel(*ctx++, tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
2310 clk_writel(*ctx++, tegra_pll_u.reg + PLL_BASE);
2311 clk_writel(*ctx++, tegra_pll_u.reg + PLL_MISC(&tegra_pll_u));
2312 udelay(1000);
Colin Crosscea62c82010-10-04 11:49:26 -07002313
2314 clk_writel(*ctx++, tegra_pll_m_out1.reg);
Colin Crosscea62c82010-10-04 11:49:26 -07002315 clk_writel(*ctx++, tegra_pll_a_out0.reg);
2316 clk_writel(*ctx++, tegra_pll_c_out1.reg);
2317
2318 clk_writel(*ctx++, tegra_clk_cclk.reg);
2319 clk_writel(*ctx++, tegra_clk_cclk.reg + SUPER_CLK_DIVIDER);
2320
2321 clk_writel(*ctx++, tegra_clk_sclk.reg);
2322 clk_writel(*ctx++, tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
2323 clk_writel(*ctx++, tegra_clk_pclk.reg);
2324
Colin Crossc2f44a92010-10-26 17:33:31 -07002325 clk_writel(*ctx++, tegra_clk_audio.reg);
2326
Colin Cross71fc84c2010-06-07 20:49:46 -07002327 /* enable all clocks before configuring clock sources */
2328 clk_writel(0xbffffff9ul, CLK_OUT_ENB);
2329 clk_writel(0xfefffff7ul, CLK_OUT_ENB + 4);
2330 clk_writel(0x77f01bfful, CLK_OUT_ENB + 8);
2331 wmb();
2332
2333 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
2334 off += 4) {
2335 if (off == PERIPH_CLK_SOURCE_EMC)
2336 continue;
2337 clk_writel(*ctx++, off);
2338 }
2339 wmb();
2340
2341 off = RST_DEVICES;
2342 for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
2343 clk_writel(*ctx++, off);
2344 wmb();
2345
2346 off = CLK_OUT_ENB;
2347 for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
2348 clk_writel(*ctx++, off);
2349 wmb();
2350
2351 clk_writel(*ctx++, MISC_CLK_ENB);
2352 clk_writel(*ctx++, CLK_MASK_ARM);
2353}
2354#endif