blob: 7f70687140492f6d4773ddc25e0f22d4699d3a70 [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
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)
Colin Crossd8611962010-01-28 16:40:29 -080082#define PLL_BASE_DIVP_MASK (0x7<<20)
83#define PLL_BASE_DIVP_SHIFT 20
84#define PLL_BASE_DIVN_MASK (0x3FF<<8)
85#define PLL_BASE_DIVN_SHIFT 8
86#define PLL_BASE_DIVM_MASK (0x1F)
87#define PLL_BASE_DIVM_SHIFT 0
88
89#define PLL_OUT_RATIO_MASK (0xFF<<8)
90#define PLL_OUT_RATIO_SHIFT 8
91#define PLL_OUT_OVERRIDE (1<<2)
92#define PLL_OUT_CLKEN (1<<1)
93#define PLL_OUT_RESET_DISABLE (1<<0)
94
95#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
Colin Cross71fc84c2010-06-07 20:49:46 -070096
Colin Crossd8611962010-01-28 16:40:29 -080097#define PLL_MISC_DCCON_SHIFT 20
Colin Crossd8611962010-01-28 16:40:29 -080098#define PLL_MISC_CPCON_SHIFT 8
99#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT)
100#define PLL_MISC_LFCON_SHIFT 4
101#define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT)
102#define PLL_MISC_VCOCON_SHIFT 0
103#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT)
104
Colin Cross71fc84c2010-06-07 20:49:46 -0700105#define PLLU_BASE_POST_DIV (1<<20)
106
Colin Crossd8611962010-01-28 16:40:29 -0800107#define PLLD_MISC_CLKENABLE (1<<30)
108#define PLLD_MISC_DIV_RST (1<<23)
109#define PLLD_MISC_DCCON_SHIFT 12
110
Mike Rapoport8d685bc2010-09-27 11:26:32 +0200111#define PLLE_MISC_READY (1 << 15)
112
Colin Crossf1519612011-02-12 16:05:31 -0800113#define PERIPH_CLK_TO_ENB_REG(c) ((c->u.periph.clk_num / 32) * 4)
114#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->u.periph.clk_num / 32) * 8)
115#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->u.periph.clk_num % 32))
Colin Crossd8611962010-01-28 16:40:29 -0800116
117#define SUPER_CLK_MUX 0x00
118#define SUPER_STATE_SHIFT 28
119#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT)
120#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT)
121#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT)
122#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT)
123#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT)
124#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT)
125#define SUPER_SOURCE_MASK 0xF
126#define SUPER_FIQ_SOURCE_SHIFT 12
127#define SUPER_IRQ_SOURCE_SHIFT 8
128#define SUPER_RUN_SOURCE_SHIFT 4
129#define SUPER_IDLE_SOURCE_SHIFT 0
130
131#define SUPER_CLK_DIVIDER 0x04
132
133#define BUS_CLK_DISABLE (1<<3)
134#define BUS_CLK_DIV_MASK 0x3
135
Colin Crosscea62c82010-10-04 11:49:26 -0700136#define PMC_CTRL 0x0
137 #define PMC_CTRL_BLINK_ENB (1 << 7)
138
139#define PMC_DPD_PADS_ORIDE 0x1c
140 #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20)
141
142#define PMC_BLINK_TIMER_DATA_ON_SHIFT 0
143#define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff
144#define PMC_BLINK_TIMER_ENB (1 << 15)
145#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
146#define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff
147
Colin Crossd8611962010-01-28 16:40:29 -0800148static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
Colin Crosscea62c82010-10-04 11:49:26 -0700149static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
Colin Crossd8611962010-01-28 16:40:29 -0800150
Colin Cross4729fd72011-02-12 16:43:05 -0800151/*
152 * Some clocks share a register with other clocks. Any clock op that
153 * non-atomically modifies a register used by another clock must lock
154 * clock_register_lock first.
155 */
156static DEFINE_SPINLOCK(clock_register_lock);
157
Colin Crossd8611962010-01-28 16:40:29 -0800158#define clk_writel(value, reg) \
159 __raw_writel(value, (u32)reg_clk_base + (reg))
160#define clk_readl(reg) \
161 __raw_readl((u32)reg_clk_base + (reg))
Colin Crosscea62c82010-10-04 11:49:26 -0700162#define pmc_writel(value, reg) \
163 __raw_writel(value, (u32)reg_pmc_base + (reg))
164#define pmc_readl(reg) \
165 __raw_readl((u32)reg_pmc_base + (reg))
Colin Crossd8611962010-01-28 16:40:29 -0800166
167unsigned long clk_measure_input_freq(void)
168{
169 u32 clock_autodetect;
170 clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
171 do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
172 clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
173 if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
174 return 12000000;
175 } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
176 return 13000000;
177 } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
178 return 19200000;
179 } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
180 return 26000000;
181 } else {
182 pr_err("%s: Unexpected clock autodetect value %d", __func__, clock_autodetect);
183 BUG();
184 return 0;
185 }
186}
187
Colin Cross71fc84c2010-06-07 20:49:46 -0700188static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate)
Colin Crossd8611962010-01-28 16:40:29 -0800189{
Colin Cross71fc84c2010-06-07 20:49:46 -0700190 s64 divider_u71 = parent_rate * 2;
191 divider_u71 += rate - 1;
192 do_div(divider_u71, rate);
Colin Crossd8611962010-01-28 16:40:29 -0800193
Colin Cross71fc84c2010-06-07 20:49:46 -0700194 if (divider_u71 - 2 < 0)
195 return 0;
Colin Crossd8611962010-01-28 16:40:29 -0800196
Colin Cross71fc84c2010-06-07 20:49:46 -0700197 if (divider_u71 - 2 > 255)
Colin Crossd8611962010-01-28 16:40:29 -0800198 return -EINVAL;
199
200 return divider_u71 - 2;
201}
202
Colin Cross71fc84c2010-06-07 20:49:46 -0700203static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
Colin Crossd8611962010-01-28 16:40:29 -0800204{
Colin Cross71fc84c2010-06-07 20:49:46 -0700205 s64 divider_u16;
Colin Crossd8611962010-01-28 16:40:29 -0800206
Colin Cross71fc84c2010-06-07 20:49:46 -0700207 divider_u16 = parent_rate;
208 divider_u16 += rate - 1;
209 do_div(divider_u16, rate);
210
211 if (divider_u16 - 1 < 0)
212 return 0;
213
214 if (divider_u16 - 1 > 255)
215 return -EINVAL;
216
217 return divider_u16 - 1;
Colin Crossd8611962010-01-28 16:40:29 -0800218}
219
Colin Crossd8611962010-01-28 16:40:29 -0800220/* clk_m functions */
221static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c)
222{
223 u32 auto_clock_control = clk_readl(OSC_CTRL) & ~OSC_CTRL_OSC_FREQ_MASK;
224
225 c->rate = clk_measure_input_freq();
226 switch (c->rate) {
227 case 12000000:
228 auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
229 break;
230 case 13000000:
231 auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
232 break;
233 case 19200000:
234 auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
235 break;
236 case 26000000:
237 auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
238 break;
239 default:
240 pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
241 BUG();
242 }
243 clk_writel(auto_clock_control, OSC_CTRL);
244 return c->rate;
245}
246
247static void tegra2_clk_m_init(struct clk *c)
248{
249 pr_debug("%s on clock %s\n", __func__, c->name);
250 tegra2_clk_m_autodetect_rate(c);
251}
252
253static int tegra2_clk_m_enable(struct clk *c)
254{
255 pr_debug("%s on clock %s\n", __func__, c->name);
256 return 0;
257}
258
259static void tegra2_clk_m_disable(struct clk *c)
260{
261 pr_debug("%s on clock %s\n", __func__, c->name);
262 BUG();
263}
264
265static struct clk_ops tegra_clk_m_ops = {
266 .init = tegra2_clk_m_init,
267 .enable = tegra2_clk_m_enable,
268 .disable = tegra2_clk_m_disable,
269};
270
Dima Zavin2b84cb4f2010-09-02 19:11:11 -0700271void tegra2_periph_reset_assert(struct clk *c)
272{
273 BUG_ON(!c->ops->reset);
274 c->ops->reset(c, true);
275}
276
277void tegra2_periph_reset_deassert(struct clk *c)
278{
279 BUG_ON(!c->ops->reset);
280 c->ops->reset(c, false);
281}
282
Colin Crossd8611962010-01-28 16:40:29 -0800283/* super clock functions */
284/* "super clocks" on tegra have two-stage muxes and a clock skipping
285 * super divider. We will ignore the clock skipping divider, since we
286 * can't lower the voltage when using the clock skip, but we can if we
287 * lower the PLL frequency.
288 */
289static void tegra2_super_clk_init(struct clk *c)
290{
291 u32 val;
292 int source;
293 int shift;
294 const struct clk_mux_sel *sel;
295 val = clk_readl(c->reg + SUPER_CLK_MUX);
296 c->state = ON;
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 source = (val >> shift) & SUPER_SOURCE_MASK;
302 for (sel = c->inputs; sel->input != NULL; sel++) {
303 if (sel->value == source)
304 break;
305 }
306 BUG_ON(sel->input == NULL);
307 c->parent = sel->input;
Colin Crossd8611962010-01-28 16:40:29 -0800308}
309
310static int tegra2_super_clk_enable(struct clk *c)
311{
312 clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
313 return 0;
314}
315
316static void tegra2_super_clk_disable(struct clk *c)
317{
318 pr_debug("%s on clock %s\n", __func__, c->name);
319
320 /* oops - don't disable the CPU clock! */
321 BUG();
322}
323
324static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p)
325{
326 u32 val;
327 const struct clk_mux_sel *sel;
328 int shift;
Colin Cross71fc84c2010-06-07 20:49:46 -0700329
Colin Crossd8611962010-01-28 16:40:29 -0800330 val = clk_readl(c->reg + SUPER_CLK_MUX);;
331 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
332 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
333 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
334 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
335 for (sel = c->inputs; sel->input != NULL; sel++) {
336 if (sel->input == p) {
Colin Crossd8611962010-01-28 16:40:29 -0800337 val &= ~(SUPER_SOURCE_MASK << shift);
338 val |= sel->value << shift;
Colin Cross71fc84c2010-06-07 20:49:46 -0700339
340 if (c->refcnt)
Colin Cross4729fd72011-02-12 16:43:05 -0800341 clk_enable(p);
Colin Cross71fc84c2010-06-07 20:49:46 -0700342
Colin Crossd8611962010-01-28 16:40:29 -0800343 clk_writel(val, c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -0700344
345 if (c->refcnt && c->parent)
Colin Cross4729fd72011-02-12 16:43:05 -0800346 clk_disable(c->parent);
Colin Cross71fc84c2010-06-07 20:49:46 -0700347
348 clk_reparent(c, p);
Colin Crossd8611962010-01-28 16:40:29 -0800349 return 0;
350 }
351 }
352 return -EINVAL;
353}
354
355static struct clk_ops tegra_super_ops = {
356 .init = tegra2_super_clk_init,
357 .enable = tegra2_super_clk_enable,
358 .disable = tegra2_super_clk_disable,
359 .set_parent = tegra2_super_clk_set_parent,
Colin Cross71fc84c2010-06-07 20:49:46 -0700360};
361
362/* virtual cpu clock functions */
363/* some clocks can not be stopped (cpu, memory bus) while the SoC is running.
364 To change the frequency of these clocks, the parent pll may need to be
365 reprogrammed, so the clock must be moved off the pll, the pll reprogrammed,
366 and then the clock moved back to the pll. To hide this sequence, a virtual
367 clock handles it.
368 */
369static void tegra2_cpu_clk_init(struct clk *c)
370{
371}
372
373static int tegra2_cpu_clk_enable(struct clk *c)
374{
375 return 0;
376}
377
378static void tegra2_cpu_clk_disable(struct clk *c)
379{
380 pr_debug("%s on clock %s\n", __func__, c->name);
381
382 /* oops - don't disable the CPU clock! */
383 BUG();
384}
385
386static int tegra2_cpu_clk_set_rate(struct clk *c, unsigned long rate)
387{
388 int ret;
Colin Cross89a5fb82010-10-20 17:47:59 -0700389 /*
390 * Take an extra reference to the main pll so it doesn't turn
391 * off when we move the cpu off of it
392 */
393 clk_enable(c->u.cpu.main);
394
Colin Cross4729fd72011-02-12 16:43:05 -0800395 ret = clk_set_parent(c->parent, c->u.cpu.backup);
Colin Cross71fc84c2010-06-07 20:49:46 -0700396 if (ret) {
Colin Crossf1519612011-02-12 16:05:31 -0800397 pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.backup->name);
Colin Cross89a5fb82010-10-20 17:47:59 -0700398 goto out;
Colin Cross71fc84c2010-06-07 20:49:46 -0700399 }
400
Colin Cross4729fd72011-02-12 16:43:05 -0800401 if (rate == clk_get_rate(c->u.cpu.backup))
Colin Crosscea62c82010-10-04 11:49:26 -0700402 goto out;
403
Colin Cross4729fd72011-02-12 16:43:05 -0800404 ret = clk_set_rate(c->u.cpu.main, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -0700405 if (ret) {
406 pr_err("Failed to change cpu pll to %lu\n", rate);
Colin Cross89a5fb82010-10-20 17:47:59 -0700407 goto out;
Colin Cross71fc84c2010-06-07 20:49:46 -0700408 }
409
Colin Cross4729fd72011-02-12 16:43:05 -0800410 ret = clk_set_parent(c->parent, c->u.cpu.main);
Colin Cross71fc84c2010-06-07 20:49:46 -0700411 if (ret) {
Colin Crossf1519612011-02-12 16:05:31 -0800412 pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.main->name);
Colin Cross89a5fb82010-10-20 17:47:59 -0700413 goto out;
Colin Cross71fc84c2010-06-07 20:49:46 -0700414 }
415
Colin Crosscea62c82010-10-04 11:49:26 -0700416out:
Colin Cross89a5fb82010-10-20 17:47:59 -0700417 clk_disable(c->u.cpu.main);
418 return ret;
Colin Cross71fc84c2010-06-07 20:49:46 -0700419}
420
421static struct clk_ops tegra_cpu_ops = {
422 .init = tegra2_cpu_clk_init,
423 .enable = tegra2_cpu_clk_enable,
424 .disable = tegra2_cpu_clk_disable,
425 .set_rate = tegra2_cpu_clk_set_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800426};
427
428/* bus clock functions */
429static void tegra2_bus_clk_init(struct clk *c)
430{
431 u32 val = clk_readl(c->reg);
432 c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
433 c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
434 c->mul = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800435}
436
437static int tegra2_bus_clk_enable(struct clk *c)
438{
Colin Cross4729fd72011-02-12 16:43:05 -0800439 u32 val;
440 unsigned long flags;
441
442 spin_lock_irqsave(&clock_register_lock, flags);
443
444 val = clk_readl(c->reg);
Colin Crossd8611962010-01-28 16:40:29 -0800445 val &= ~(BUS_CLK_DISABLE << c->reg_shift);
446 clk_writel(val, c->reg);
Colin Cross4729fd72011-02-12 16:43:05 -0800447
448 spin_unlock_irqrestore(&clock_register_lock, flags);
449
Colin Crossd8611962010-01-28 16:40:29 -0800450 return 0;
451}
452
453static void tegra2_bus_clk_disable(struct clk *c)
454{
Colin Cross4729fd72011-02-12 16:43:05 -0800455 u32 val;
456 unsigned long flags;
457
458 spin_lock_irqsave(&clock_register_lock, flags);
459
460 val = clk_readl(c->reg);
Colin Crossd8611962010-01-28 16:40:29 -0800461 val |= BUS_CLK_DISABLE << c->reg_shift;
462 clk_writel(val, c->reg);
Colin Cross4729fd72011-02-12 16:43:05 -0800463
464 spin_unlock_irqrestore(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800465}
466
467static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate)
468{
Colin Cross4729fd72011-02-12 16:43:05 -0800469 u32 val;
470 unsigned long parent_rate = clk_get_rate(c->parent);
471 unsigned long flags;
472 int ret = -EINVAL;
Colin Crossd8611962010-01-28 16:40:29 -0800473 int i;
Colin Cross4729fd72011-02-12 16:43:05 -0800474
475 spin_lock_irqsave(&clock_register_lock, flags);
476
477 val = clk_readl(c->reg);
Colin Crossd8611962010-01-28 16:40:29 -0800478 for (i = 1; i <= 4; i++) {
479 if (rate == parent_rate / i) {
480 val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
481 val |= (i - 1) << c->reg_shift;
482 clk_writel(val, c->reg);
483 c->div = i;
484 c->mul = 1;
Colin Cross4729fd72011-02-12 16:43:05 -0800485 ret = 0;
486 break;
Colin Crossd8611962010-01-28 16:40:29 -0800487 }
488 }
Colin Cross4729fd72011-02-12 16:43:05 -0800489
490 spin_unlock_irqrestore(&clock_register_lock, flags);
491
492 return ret;
Colin Crossd8611962010-01-28 16:40:29 -0800493}
494
495static struct clk_ops tegra_bus_ops = {
496 .init = tegra2_bus_clk_init,
497 .enable = tegra2_bus_clk_enable,
498 .disable = tegra2_bus_clk_disable,
499 .set_rate = tegra2_bus_clk_set_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800500};
501
Colin Crosscea62c82010-10-04 11:49:26 -0700502/* Blink output functions */
503
504static void tegra2_blink_clk_init(struct clk *c)
505{
506 u32 val;
507
508 val = pmc_readl(PMC_CTRL);
509 c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
510 c->mul = 1;
511 val = pmc_readl(c->reg);
512
513 if (val & PMC_BLINK_TIMER_ENB) {
514 unsigned int on_off;
515
516 on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
517 PMC_BLINK_TIMER_DATA_ON_MASK;
518 val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
519 val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
520 on_off += val;
521 /* each tick in the blink timer is 4 32KHz clocks */
522 c->div = on_off * 4;
523 } else {
524 c->div = 1;
525 }
526}
527
528static int tegra2_blink_clk_enable(struct clk *c)
529{
530 u32 val;
531
532 val = pmc_readl(PMC_DPD_PADS_ORIDE);
533 pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
534
535 val = pmc_readl(PMC_CTRL);
536 pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
537
538 return 0;
539}
540
541static void tegra2_blink_clk_disable(struct clk *c)
542{
543 u32 val;
544
545 val = pmc_readl(PMC_CTRL);
546 pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
547
548 val = pmc_readl(PMC_DPD_PADS_ORIDE);
549 pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
550}
551
552static int tegra2_blink_clk_set_rate(struct clk *c, unsigned long rate)
553{
Colin Cross4729fd72011-02-12 16:43:05 -0800554 unsigned long parent_rate = clk_get_rate(c->parent);
555 if (rate >= parent_rate) {
Colin Crosscea62c82010-10-04 11:49:26 -0700556 c->div = 1;
557 pmc_writel(0, c->reg);
558 } else {
559 unsigned int on_off;
560 u32 val;
561
Colin Cross4729fd72011-02-12 16:43:05 -0800562 on_off = DIV_ROUND_UP(parent_rate / 8, rate);
Colin Crosscea62c82010-10-04 11:49:26 -0700563 c->div = on_off * 8;
564
565 val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
566 PMC_BLINK_TIMER_DATA_ON_SHIFT;
567 on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
568 on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
569 val |= on_off;
570 val |= PMC_BLINK_TIMER_ENB;
571 pmc_writel(val, c->reg);
572 }
573
574 return 0;
575}
576
577static struct clk_ops tegra_blink_clk_ops = {
578 .init = &tegra2_blink_clk_init,
579 .enable = &tegra2_blink_clk_enable,
580 .disable = &tegra2_blink_clk_disable,
581 .set_rate = &tegra2_blink_clk_set_rate,
582};
583
Colin Crossd8611962010-01-28 16:40:29 -0800584/* PLL Functions */
Colin Crossd8611962010-01-28 16:40:29 -0800585static int tegra2_pll_clk_wait_for_lock(struct clk *c)
586{
Colin Crossf1519612011-02-12 16:05:31 -0800587 udelay(c->u.pll.lock_delay);
Colin Crossd8611962010-01-28 16:40:29 -0800588
589 return 0;
590}
591
592static void tegra2_pll_clk_init(struct clk *c)
593{
594 u32 val = clk_readl(c->reg + PLL_BASE);
595
596 c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
597
598 if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
599 pr_warning("Clock %s has unknown fixed frequency\n", c->name);
Colin Cross71fc84c2010-06-07 20:49:46 -0700600 c->mul = 1;
601 c->div = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800602 } else if (val & PLL_BASE_BYPASS) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700603 c->mul = 1;
604 c->div = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800605 } else {
Colin Cross71fc84c2010-06-07 20:49:46 -0700606 c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
607 c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
608 if (c->flags & PLLU)
609 c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
610 else
611 c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
Colin Crossd8611962010-01-28 16:40:29 -0800612 }
Colin Crossd8611962010-01-28 16:40:29 -0800613}
614
615static int tegra2_pll_clk_enable(struct clk *c)
616{
617 u32 val;
618 pr_debug("%s on clock %s\n", __func__, c->name);
619
620 val = clk_readl(c->reg + PLL_BASE);
621 val &= ~PLL_BASE_BYPASS;
622 val |= PLL_BASE_ENABLE;
623 clk_writel(val, c->reg + PLL_BASE);
624
Colin Crossd8611962010-01-28 16:40:29 -0800625 tegra2_pll_clk_wait_for_lock(c);
626
627 return 0;
628}
629
630static void tegra2_pll_clk_disable(struct clk *c)
631{
632 u32 val;
633 pr_debug("%s on clock %s\n", __func__, c->name);
634
635 val = clk_readl(c->reg);
636 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
637 clk_writel(val, c->reg);
638}
639
640static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate)
641{
642 u32 val;
643 unsigned long input_rate;
Colin Crossf1519612011-02-12 16:05:31 -0800644 const struct clk_pll_freq_table *sel;
Colin Crossd8611962010-01-28 16:40:29 -0800645
646 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
Colin Crossd8611962010-01-28 16:40:29 -0800647
Colin Cross4729fd72011-02-12 16:43:05 -0800648 input_rate = clk_get_rate(c->parent);
Colin Crossf1519612011-02-12 16:05:31 -0800649 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
Colin Crossd8611962010-01-28 16:40:29 -0800650 if (sel->input_rate == input_rate && sel->output_rate == rate) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700651 c->mul = sel->n;
652 c->div = sel->m * sel->p;
Colin Crossd8611962010-01-28 16:40:29 -0800653
654 val = clk_readl(c->reg + PLL_BASE);
655 if (c->flags & PLL_FIXED)
656 val |= PLL_BASE_OVERRIDE;
657 val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK |
658 PLL_BASE_DIVM_MASK);
Colin Cross71fc84c2010-06-07 20:49:46 -0700659 val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
660 (sel->n << PLL_BASE_DIVN_SHIFT);
661 BUG_ON(sel->p < 1 || sel->p > 2);
662 if (c->flags & PLLU) {
663 if (sel->p == 1)
664 val |= PLLU_BASE_POST_DIV;
665 } else {
666 if (sel->p == 2)
667 val |= 1 << PLL_BASE_DIVP_SHIFT;
668 }
Colin Crossd8611962010-01-28 16:40:29 -0800669 clk_writel(val, c->reg + PLL_BASE);
670
671 if (c->flags & PLL_HAS_CPCON) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700672 val = clk_readl(c->reg + PLL_MISC(c));
673 val &= ~PLL_MISC_CPCON_MASK;
674 val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
Colin Crossd8611962010-01-28 16:40:29 -0800675 clk_writel(val, c->reg + PLL_MISC(c));
676 }
677
678 if (c->state == ON)
679 tegra2_pll_clk_enable(c);
680
Colin Crossd8611962010-01-28 16:40:29 -0800681 return 0;
682 }
683 }
684 return -EINVAL;
685}
686
687static struct clk_ops tegra_pll_ops = {
688 .init = tegra2_pll_clk_init,
689 .enable = tegra2_pll_clk_enable,
690 .disable = tegra2_pll_clk_disable,
691 .set_rate = tegra2_pll_clk_set_rate,
Colin Cross71fc84c2010-06-07 20:49:46 -0700692};
693
694static void tegra2_pllx_clk_init(struct clk *c)
695{
696 tegra2_pll_clk_init(c);
697
698 if (tegra_sku_id() == 7)
699 c->max_rate = 750000000;
700}
701
702static struct clk_ops tegra_pllx_ops = {
703 .init = tegra2_pllx_clk_init,
704 .enable = tegra2_pll_clk_enable,
705 .disable = tegra2_pll_clk_disable,
706 .set_rate = tegra2_pll_clk_set_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800707};
708
Mike Rapoport8d685bc2010-09-27 11:26:32 +0200709static int tegra2_plle_clk_enable(struct clk *c)
710{
711 u32 val;
712
713 pr_debug("%s on clock %s\n", __func__, c->name);
714
715 mdelay(1);
716
717 val = clk_readl(c->reg + PLL_BASE);
718 if (!(val & PLLE_MISC_READY))
719 return -EBUSY;
720
721 val = clk_readl(c->reg + PLL_BASE);
722 val |= PLL_BASE_ENABLE | PLL_BASE_BYPASS;
723 clk_writel(val, c->reg + PLL_BASE);
724
725 return 0;
726}
727
728static struct clk_ops tegra_plle_ops = {
729 .init = tegra2_pll_clk_init,
730 .enable = tegra2_plle_clk_enable,
731 .set_rate = tegra2_pll_clk_set_rate,
732};
733
Colin Crossd8611962010-01-28 16:40:29 -0800734/* Clock divider ops */
735static void tegra2_pll_div_clk_init(struct clk *c)
736{
737 u32 val = clk_readl(c->reg);
738 u32 divu71;
739 val >>= c->reg_shift;
740 c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
741 if (!(val & PLL_OUT_RESET_DISABLE))
742 c->state = OFF;
743
744 if (c->flags & DIV_U71) {
745 divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
746 c->div = (divu71 + 2);
747 c->mul = 2;
748 } else if (c->flags & DIV_2) {
749 c->div = 2;
750 c->mul = 1;
751 } else {
752 c->div = 1;
753 c->mul = 1;
754 }
Colin Crossd8611962010-01-28 16:40:29 -0800755}
756
757static int tegra2_pll_div_clk_enable(struct clk *c)
758{
759 u32 val;
760 u32 new_val;
Colin Cross4729fd72011-02-12 16:43:05 -0800761 unsigned long flags;
Colin Crossd8611962010-01-28 16:40:29 -0800762
763 pr_debug("%s: %s\n", __func__, c->name);
764 if (c->flags & DIV_U71) {
Colin Cross4729fd72011-02-12 16:43:05 -0800765 spin_lock_irqsave(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800766 val = clk_readl(c->reg);
767 new_val = val >> c->reg_shift;
768 new_val &= 0xFFFF;
769
770 new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
771
772 val &= ~(0xFFFF << c->reg_shift);
773 val |= new_val << c->reg_shift;
774 clk_writel(val, c->reg);
Colin Cross4729fd72011-02-12 16:43:05 -0800775 spin_unlock_irqrestore(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800776 return 0;
777 } else if (c->flags & DIV_2) {
778 BUG_ON(!(c->flags & PLLD));
Colin Cross4729fd72011-02-12 16:43:05 -0800779 spin_lock_irqsave(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800780 val = clk_readl(c->reg);
781 val &= ~PLLD_MISC_DIV_RST;
782 clk_writel(val, c->reg);
Colin Cross4729fd72011-02-12 16:43:05 -0800783 spin_unlock_irqrestore(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800784 return 0;
785 }
786 return -EINVAL;
787}
788
789static void tegra2_pll_div_clk_disable(struct clk *c)
790{
791 u32 val;
792 u32 new_val;
Colin Cross4729fd72011-02-12 16:43:05 -0800793 unsigned long flags;
Colin Crossd8611962010-01-28 16:40:29 -0800794
795 pr_debug("%s: %s\n", __func__, c->name);
796 if (c->flags & DIV_U71) {
Colin Cross4729fd72011-02-12 16:43:05 -0800797 spin_lock_irqsave(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800798 val = clk_readl(c->reg);
799 new_val = val >> c->reg_shift;
800 new_val &= 0xFFFF;
801
802 new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
803
804 val &= ~(0xFFFF << c->reg_shift);
805 val |= new_val << c->reg_shift;
806 clk_writel(val, c->reg);
Colin Cross4729fd72011-02-12 16:43:05 -0800807 spin_unlock_irqrestore(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800808 } else if (c->flags & DIV_2) {
809 BUG_ON(!(c->flags & PLLD));
Colin Cross4729fd72011-02-12 16:43:05 -0800810 spin_lock_irqsave(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800811 val = clk_readl(c->reg);
812 val |= PLLD_MISC_DIV_RST;
813 clk_writel(val, c->reg);
Colin Cross4729fd72011-02-12 16:43:05 -0800814 spin_unlock_irqrestore(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800815 }
816}
817
818static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
819{
820 u32 val;
821 u32 new_val;
822 int divider_u71;
Colin Cross4729fd72011-02-12 16:43:05 -0800823 unsigned long parent_rate = clk_get_rate(c->parent);
824 unsigned long flags;
825
Colin Crossd8611962010-01-28 16:40:29 -0800826 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
827 if (c->flags & DIV_U71) {
Colin Cross4729fd72011-02-12 16:43:05 -0800828 divider_u71 = clk_div71_get_divider(parent_rate, rate);
Colin Crossd8611962010-01-28 16:40:29 -0800829 if (divider_u71 >= 0) {
Colin Cross4729fd72011-02-12 16:43:05 -0800830 spin_lock_irqsave(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800831 val = clk_readl(c->reg);
832 new_val = val >> c->reg_shift;
833 new_val &= 0xFFFF;
834 if (c->flags & DIV_U71_FIXED)
835 new_val |= PLL_OUT_OVERRIDE;
836 new_val &= ~PLL_OUT_RATIO_MASK;
837 new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
838
839 val &= ~(0xFFFF << c->reg_shift);
840 val |= new_val << c->reg_shift;
841 clk_writel(val, c->reg);
842 c->div = divider_u71 + 2;
843 c->mul = 2;
Colin Cross4729fd72011-02-12 16:43:05 -0800844 spin_unlock_irqrestore(&clock_register_lock, flags);
Colin Crossd8611962010-01-28 16:40:29 -0800845 return 0;
846 }
847 } else if (c->flags & DIV_2) {
Colin Cross4729fd72011-02-12 16:43:05 -0800848 if (parent_rate == rate * 2)
Colin Crossd8611962010-01-28 16:40:29 -0800849 return 0;
Colin Crossd8611962010-01-28 16:40:29 -0800850 }
851 return -EINVAL;
852}
853
Colin Cross71fc84c2010-06-07 20:49:46 -0700854static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
855{
856 int divider;
Colin Cross4729fd72011-02-12 16:43:05 -0800857 unsigned long parent_rate = clk_get_rate(c->parent);
Colin Cross71fc84c2010-06-07 20:49:46 -0700858 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
859
860 if (c->flags & DIV_U71) {
Colin Cross4729fd72011-02-12 16:43:05 -0800861 divider = clk_div71_get_divider(parent_rate, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -0700862 if (divider < 0)
863 return divider;
Colin Cross4729fd72011-02-12 16:43:05 -0800864 return parent_rate * 2 / (divider + 2);
Colin Cross71fc84c2010-06-07 20:49:46 -0700865 } else if (c->flags & DIV_2) {
Colin Cross4729fd72011-02-12 16:43:05 -0800866 return parent_rate / 2;
Colin Cross71fc84c2010-06-07 20:49:46 -0700867 }
868 return -EINVAL;
869}
Colin Crossd8611962010-01-28 16:40:29 -0800870
871static struct clk_ops tegra_pll_div_ops = {
872 .init = tegra2_pll_div_clk_init,
873 .enable = tegra2_pll_div_clk_enable,
874 .disable = tegra2_pll_div_clk_disable,
875 .set_rate = tegra2_pll_div_clk_set_rate,
Colin Cross71fc84c2010-06-07 20:49:46 -0700876 .round_rate = tegra2_pll_div_clk_round_rate,
Colin Crossd8611962010-01-28 16:40:29 -0800877};
878
879/* Periph clk ops */
880
881static void tegra2_periph_clk_init(struct clk *c)
882{
883 u32 val = clk_readl(c->reg);
884 const struct clk_mux_sel *mux = 0;
885 const struct clk_mux_sel *sel;
886 if (c->flags & MUX) {
887 for (sel = c->inputs; sel->input != NULL; sel++) {
888 if (val >> PERIPH_CLK_SOURCE_SHIFT == sel->value)
889 mux = sel;
890 }
891 BUG_ON(!mux);
892
893 c->parent = mux->input;
894 } else {
895 c->parent = c->inputs[0].input;
896 }
897
898 if (c->flags & DIV_U71) {
Colin Cross71fc84c2010-06-07 20:49:46 -0700899 u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
Colin Crossd8611962010-01-28 16:40:29 -0800900 c->div = divu71 + 2;
901 c->mul = 2;
Colin Cross71fc84c2010-06-07 20:49:46 -0700902 } else if (c->flags & DIV_U16) {
903 u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
904 c->div = divu16 + 1;
905 c->mul = 1;
Colin Crossd8611962010-01-28 16:40:29 -0800906 } else {
907 c->div = 1;
908 c->mul = 1;
909 }
910
911 c->state = ON;
912 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
913 PERIPH_CLK_TO_ENB_BIT(c)))
914 c->state = OFF;
915 if (!(c->flags & PERIPH_NO_RESET))
916 if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
917 PERIPH_CLK_TO_ENB_BIT(c))
918 c->state = OFF;
Colin Crossd8611962010-01-28 16:40:29 -0800919}
920
921static int tegra2_periph_clk_enable(struct clk *c)
922{
923 u32 val;
924 pr_debug("%s on clock %s\n", __func__, c->name);
925
926 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
927 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
928 if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET))
929 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
930 RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
931 if (c->flags & PERIPH_EMC_ENB) {
932 /* The EMC peripheral clock has 2 extra enable bits */
933 /* FIXME: Do they need to be disabled? */
934 val = clk_readl(c->reg);
935 val |= 0x3 << 24;
936 clk_writel(val, c->reg);
937 }
938 return 0;
939}
940
941static void tegra2_periph_clk_disable(struct clk *c)
942{
943 pr_debug("%s on clock %s\n", __func__, c->name);
944
945 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
946 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
947}
948
Dima Zavin2b84cb4f2010-09-02 19:11:11 -0700949static void tegra2_periph_clk_reset(struct clk *c, bool assert)
Colin Crossd8611962010-01-28 16:40:29 -0800950{
Dima Zavin2b84cb4f2010-09-02 19:11:11 -0700951 unsigned long base = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
952
953 pr_debug("%s %s on clock %s\n", __func__,
954 assert ? "assert" : "deassert", c->name);
Colin Crossd8611962010-01-28 16:40:29 -0800955 if (!(c->flags & PERIPH_NO_RESET))
956 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
Dima Zavin2b84cb4f2010-09-02 19:11:11 -0700957 base + PERIPH_CLK_TO_ENB_SET_REG(c));
Colin Crossd8611962010-01-28 16:40:29 -0800958}
959
Colin Crossd8611962010-01-28 16:40:29 -0800960static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
961{
962 u32 val;
963 const struct clk_mux_sel *sel;
964 pr_debug("%s: %s %s\n", __func__, c->name, p->name);
965 for (sel = c->inputs; sel->input != NULL; sel++) {
966 if (sel->input == p) {
Colin Crossd8611962010-01-28 16:40:29 -0800967 val = clk_readl(c->reg);
968 val &= ~PERIPH_CLK_SOURCE_MASK;
969 val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT;
Colin Cross71fc84c2010-06-07 20:49:46 -0700970
971 if (c->refcnt)
Colin Cross4729fd72011-02-12 16:43:05 -0800972 clk_enable(p);
Colin Cross71fc84c2010-06-07 20:49:46 -0700973
Colin Crossd8611962010-01-28 16:40:29 -0800974 clk_writel(val, c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -0700975
976 if (c->refcnt && c->parent)
Colin Cross4729fd72011-02-12 16:43:05 -0800977 clk_disable(c->parent);
Colin Cross71fc84c2010-06-07 20:49:46 -0700978
979 clk_reparent(c, p);
Colin Crossd8611962010-01-28 16:40:29 -0800980 return 0;
981 }
982 }
983
984 return -EINVAL;
985}
986
987static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
988{
989 u32 val;
Colin Cross71fc84c2010-06-07 20:49:46 -0700990 int divider;
Colin Cross4729fd72011-02-12 16:43:05 -0800991 unsigned long parent_rate = clk_get_rate(c->parent);
992
Colin Crossd8611962010-01-28 16:40:29 -0800993 if (c->flags & DIV_U71) {
Colin Cross4729fd72011-02-12 16:43:05 -0800994 divider = clk_div71_get_divider(parent_rate, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -0700995 if (divider >= 0) {
Colin Crossd8611962010-01-28 16:40:29 -0800996 val = clk_readl(c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -0700997 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
998 val |= divider;
Colin Crossd8611962010-01-28 16:40:29 -0800999 clk_writel(val, c->reg);
Colin Cross71fc84c2010-06-07 20:49:46 -07001000 c->div = divider + 2;
Colin Crossd8611962010-01-28 16:40:29 -08001001 c->mul = 2;
Colin Crossd8611962010-01-28 16:40:29 -08001002 return 0;
1003 }
Colin Cross71fc84c2010-06-07 20:49:46 -07001004 } else if (c->flags & DIV_U16) {
Colin Cross4729fd72011-02-12 16:43:05 -08001005 divider = clk_div16_get_divider(parent_rate, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -07001006 if (divider >= 0) {
1007 val = clk_readl(c->reg);
1008 val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
1009 val |= divider;
1010 clk_writel(val, c->reg);
1011 c->div = divider + 1;
1012 c->mul = 1;
1013 return 0;
1014 }
Colin Cross4729fd72011-02-12 16:43:05 -08001015 } else if (parent_rate <= rate) {
Colin Cross71fc84c2010-06-07 20:49:46 -07001016 c->div = 1;
1017 c->mul = 1;
1018 return 0;
1019 }
1020 return -EINVAL;
1021}
1022
1023static long tegra2_periph_clk_round_rate(struct clk *c,
1024 unsigned long rate)
1025{
1026 int divider;
Colin Cross4729fd72011-02-12 16:43:05 -08001027 unsigned long parent_rate = clk_get_rate(c->parent);
Colin Cross71fc84c2010-06-07 20:49:46 -07001028 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
1029
1030 if (c->flags & DIV_U71) {
Colin Cross4729fd72011-02-12 16:43:05 -08001031 divider = clk_div71_get_divider(parent_rate, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -07001032 if (divider < 0)
1033 return divider;
1034
Colin Cross4729fd72011-02-12 16:43:05 -08001035 return parent_rate * 2 / (divider + 2);
Colin Cross71fc84c2010-06-07 20:49:46 -07001036 } else if (c->flags & DIV_U16) {
Colin Cross4729fd72011-02-12 16:43:05 -08001037 divider = clk_div16_get_divider(parent_rate, rate);
Colin Cross71fc84c2010-06-07 20:49:46 -07001038 if (divider < 0)
1039 return divider;
Colin Cross4729fd72011-02-12 16:43:05 -08001040 return parent_rate / (divider + 1);
Colin Crossd8611962010-01-28 16:40:29 -08001041 }
1042 return -EINVAL;
1043}
1044
1045static struct clk_ops tegra_periph_clk_ops = {
1046 .init = &tegra2_periph_clk_init,
1047 .enable = &tegra2_periph_clk_enable,
1048 .disable = &tegra2_periph_clk_disable,
1049 .set_parent = &tegra2_periph_clk_set_parent,
1050 .set_rate = &tegra2_periph_clk_set_rate,
Colin Cross71fc84c2010-06-07 20:49:46 -07001051 .round_rate = &tegra2_periph_clk_round_rate,
Dima Zavin2b84cb4f2010-09-02 19:11:11 -07001052 .reset = &tegra2_periph_clk_reset,
Colin Crossd8611962010-01-28 16:40:29 -08001053};
1054
Colin Cross6d296822010-11-22 18:37:54 -08001055/* External memory controller clock ops */
1056static void tegra2_emc_clk_init(struct clk *c)
1057{
1058 tegra2_periph_clk_init(c);
1059 c->max_rate = clk_get_rate_locked(c);
1060}
1061
1062static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate)
1063{
1064 long new_rate = rate;
1065
1066 new_rate = tegra_emc_round_rate(new_rate);
1067 if (new_rate < 0)
1068 return c->max_rate;
1069
1070 BUG_ON(new_rate != tegra2_periph_clk_round_rate(c, new_rate));
1071
1072 return new_rate;
1073}
1074
1075static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate)
1076{
1077 int ret;
1078 /*
1079 * The Tegra2 memory controller has an interlock with the clock
1080 * block that allows memory shadowed registers to be updated,
1081 * and then transfer them to the main registers at the same
1082 * time as the clock update without glitches.
1083 */
1084 ret = tegra_emc_set_rate(rate);
1085 if (ret < 0)
1086 return ret;
1087
1088 ret = tegra2_periph_clk_set_rate(c, rate);
1089 udelay(1);
1090
1091 return ret;
1092}
1093
1094static struct clk_ops tegra_emc_clk_ops = {
1095 .init = &tegra2_emc_clk_init,
1096 .enable = &tegra2_periph_clk_enable,
1097 .disable = &tegra2_periph_clk_disable,
1098 .set_parent = &tegra2_periph_clk_set_parent,
1099 .set_rate = &tegra2_emc_clk_set_rate,
1100 .round_rate = &tegra2_emc_clk_round_rate,
1101 .reset = &tegra2_periph_clk_reset,
1102};
1103
Colin Crossd8611962010-01-28 16:40:29 -08001104/* Clock doubler ops */
1105static void tegra2_clk_double_init(struct clk *c)
1106{
1107 c->mul = 2;
1108 c->div = 1;
1109 c->state = ON;
1110 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1111 PERIPH_CLK_TO_ENB_BIT(c)))
1112 c->state = OFF;
Colin Crossd8611962010-01-28 16:40:29 -08001113};
1114
Colin Cross71fc84c2010-06-07 20:49:46 -07001115static int tegra2_clk_double_set_rate(struct clk *c, unsigned long rate)
1116{
Colin Cross4729fd72011-02-12 16:43:05 -08001117 if (rate != 2 * clk_get_rate(c->parent))
Colin Cross71fc84c2010-06-07 20:49:46 -07001118 return -EINVAL;
1119 c->mul = 2;
1120 c->div = 1;
1121 return 0;
1122}
1123
Colin Crossd8611962010-01-28 16:40:29 -08001124static struct clk_ops tegra_clk_double_ops = {
1125 .init = &tegra2_clk_double_init,
1126 .enable = &tegra2_periph_clk_enable,
1127 .disable = &tegra2_periph_clk_disable,
Colin Cross71fc84c2010-06-07 20:49:46 -07001128 .set_rate = &tegra2_clk_double_set_rate,
1129};
1130
Colin Crosscea62c82010-10-04 11:49:26 -07001131/* Audio sync clock ops */
Colin Cross71fc84c2010-06-07 20:49:46 -07001132static void tegra2_audio_sync_clk_init(struct clk *c)
1133{
1134 int source;
1135 const struct clk_mux_sel *sel;
1136 u32 val = clk_readl(c->reg);
1137 c->state = (val & (1<<4)) ? OFF : ON;
1138 source = val & 0xf;
1139 for (sel = c->inputs; sel->input != NULL; sel++)
1140 if (sel->value == source)
1141 break;
1142 BUG_ON(sel->input == NULL);
1143 c->parent = sel->input;
1144}
1145
1146static int tegra2_audio_sync_clk_enable(struct clk *c)
1147{
1148 clk_writel(0, c->reg);
1149 return 0;
1150}
1151
1152static void tegra2_audio_sync_clk_disable(struct clk *c)
1153{
1154 clk_writel(1, c->reg);
1155}
1156
1157static int tegra2_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
1158{
1159 u32 val;
1160 const struct clk_mux_sel *sel;
1161 for (sel = c->inputs; sel->input != NULL; sel++) {
1162 if (sel->input == p) {
1163 val = clk_readl(c->reg);
1164 val &= ~0xf;
1165 val |= sel->value;
1166
1167 if (c->refcnt)
Colin Cross4729fd72011-02-12 16:43:05 -08001168 clk_enable(p);
Colin Cross71fc84c2010-06-07 20:49:46 -07001169
1170 clk_writel(val, c->reg);
1171
1172 if (c->refcnt && c->parent)
Colin Cross4729fd72011-02-12 16:43:05 -08001173 clk_disable(c->parent);
Colin Cross71fc84c2010-06-07 20:49:46 -07001174
1175 clk_reparent(c, p);
1176 return 0;
1177 }
1178 }
1179
1180 return -EINVAL;
1181}
1182
1183static int tegra2_audio_sync_clk_set_rate(struct clk *c, unsigned long rate)
1184{
1185 unsigned long parent_rate;
1186 if (!c->parent) {
1187 pr_err("%s: clock has no parent\n", __func__);
1188 return -EINVAL;
1189 }
1190 parent_rate = c->parent->rate;
1191 if (rate != parent_rate) {
1192 pr_err("%s: %s/%ld differs from parent %s/%ld\n",
1193 __func__,
1194 c->name, rate,
1195 c->parent->name, parent_rate);
1196 return -EINVAL;
1197 }
1198 c->rate = parent_rate;
1199 return 0;
1200}
1201
1202static struct clk_ops tegra_audio_sync_clk_ops = {
1203 .init = tegra2_audio_sync_clk_init,
1204 .enable = tegra2_audio_sync_clk_enable,
1205 .disable = tegra2_audio_sync_clk_disable,
1206 .set_rate = tegra2_audio_sync_clk_set_rate,
1207 .set_parent = tegra2_audio_sync_clk_set_parent,
Colin Crossd8611962010-01-28 16:40:29 -08001208};
1209
Colin Crosscea62c82010-10-04 11:49:26 -07001210/* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */
1211
1212static void tegra2_cdev_clk_init(struct clk *c)
1213{
1214 /* We could un-tristate the cdev1 or cdev2 pingroup here; this is
1215 * currently done in the pinmux code. */
1216 c->state = ON;
1217 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1218 PERIPH_CLK_TO_ENB_BIT(c)))
1219 c->state = OFF;
1220}
1221
1222static int tegra2_cdev_clk_enable(struct clk *c)
1223{
1224 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1225 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
1226 return 0;
1227}
1228
1229static void tegra2_cdev_clk_disable(struct clk *c)
1230{
1231 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1232 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1233}
1234
1235static struct clk_ops tegra_cdev_clk_ops = {
1236 .init = &tegra2_cdev_clk_init,
1237 .enable = &tegra2_cdev_clk_enable,
1238 .disable = &tegra2_cdev_clk_disable,
1239};
1240
Colin Cross310992c2011-02-12 16:14:03 -08001241/* shared bus ops */
1242/*
1243 * Some clocks may have multiple downstream users that need to request a
1244 * higher clock rate. Shared bus clocks provide a unique shared_bus_user
1245 * clock to each user. The frequency of the bus is set to the highest
1246 * enabled shared_bus_user clock, with a minimum value set by the
1247 * shared bus.
1248 */
1249static int tegra_clk_shared_bus_update(struct clk *bus)
1250{
1251 struct clk *c;
1252 unsigned long rate = bus->min_rate;
1253
1254 list_for_each_entry(c, &bus->shared_bus_list, u.shared_bus_user.node)
1255 if (c->u.shared_bus_user.enabled)
1256 rate = max(c->u.shared_bus_user.rate, rate);
1257
1258 if (rate == clk_get_rate_locked(bus))
1259 return 0;
1260
1261 return clk_set_rate_locked(bus, rate);
1262};
1263
1264static void tegra_clk_shared_bus_init(struct clk *c)
1265{
1266 unsigned long flags;
1267
1268 c->max_rate = c->parent->max_rate;
1269 c->u.shared_bus_user.rate = c->parent->max_rate;
1270 c->state = OFF;
Colin Cross310992c2011-02-12 16:14:03 -08001271 c->set = true;
Colin Cross310992c2011-02-12 16:14:03 -08001272
1273 spin_lock_irqsave(&c->parent->spinlock, flags);
1274
1275 list_add_tail(&c->u.shared_bus_user.node,
1276 &c->parent->shared_bus_list);
1277
1278 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1279}
1280
1281static int tegra_clk_shared_bus_set_rate(struct clk *c, unsigned long rate)
1282{
1283 unsigned long flags;
1284 int ret;
1285
1286 rate = clk_round_rate(c->parent, rate);
1287 if (rate < 0)
1288 return rate;
1289
1290 spin_lock_irqsave(&c->parent->spinlock, flags);
1291
1292 c->u.shared_bus_user.rate = rate;
1293 ret = tegra_clk_shared_bus_update(c->parent);
1294
1295 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1296
1297 return ret;
1298}
1299
1300static long tegra_clk_shared_bus_round_rate(struct clk *c, unsigned long rate)
1301{
1302 return clk_round_rate(c->parent, rate);
1303}
1304
1305static int tegra_clk_shared_bus_enable(struct clk *c)
1306{
1307 unsigned long flags;
1308 int ret;
1309
1310 spin_lock_irqsave(&c->parent->spinlock, flags);
1311
1312 c->u.shared_bus_user.enabled = true;
1313 ret = tegra_clk_shared_bus_update(c->parent);
1314
1315 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1316
1317 return ret;
1318}
1319
1320static void tegra_clk_shared_bus_disable(struct clk *c)
1321{
1322 unsigned long flags;
1323 int ret;
1324
1325 spin_lock_irqsave(&c->parent->spinlock, flags);
1326
1327 c->u.shared_bus_user.enabled = false;
1328 ret = tegra_clk_shared_bus_update(c->parent);
1329 WARN_ON_ONCE(ret);
1330
1331 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1332}
1333
1334static struct clk_ops tegra_clk_shared_bus_ops = {
1335 .init = tegra_clk_shared_bus_init,
1336 .enable = tegra_clk_shared_bus_enable,
1337 .disable = tegra_clk_shared_bus_disable,
1338 .set_rate = tegra_clk_shared_bus_set_rate,
1339 .round_rate = tegra_clk_shared_bus_round_rate,
1340};
1341
1342
Colin Crossd8611962010-01-28 16:40:29 -08001343/* Clock definitions */
1344static struct clk tegra_clk_32k = {
1345 .name = "clk_32k",
Colin Cross71fc84c2010-06-07 20:49:46 -07001346 .rate = 32768,
Colin Crossd8611962010-01-28 16:40:29 -08001347 .ops = NULL,
Colin Cross71fc84c2010-06-07 20:49:46 -07001348 .max_rate = 32768,
Colin Crossd8611962010-01-28 16:40:29 -08001349};
1350
Colin Crossf1519612011-02-12 16:05:31 -08001351static struct clk_pll_freq_table tegra_pll_s_freq_table[] = {
Colin Crossd8611962010-01-28 16:40:29 -08001352 {32768, 12000000, 366, 1, 1, 0},
1353 {32768, 13000000, 397, 1, 1, 0},
1354 {32768, 19200000, 586, 1, 1, 0},
1355 {32768, 26000000, 793, 1, 1, 0},
1356 {0, 0, 0, 0, 0, 0},
1357};
1358
1359static struct clk tegra_pll_s = {
1360 .name = "pll_s",
1361 .flags = PLL_ALT_MISC_REG,
1362 .ops = &tegra_pll_ops,
Colin Crossd8611962010-01-28 16:40:29 -08001363 .parent = &tegra_clk_32k,
Colin Cross71fc84c2010-06-07 20:49:46 -07001364 .max_rate = 26000000,
Colin Crossf1519612011-02-12 16:05:31 -08001365 .reg = 0xf0,
1366 .u.pll = {
1367 .input_min = 32768,
1368 .input_max = 32768,
1369 .cf_min = 0, /* FIXME */
1370 .cf_max = 0, /* FIXME */
1371 .vco_min = 12000000,
1372 .vco_max = 26000000,
1373 .freq_table = tegra_pll_s_freq_table,
1374 .lock_delay = 300,
1375 },
Colin Crossd8611962010-01-28 16:40:29 -08001376};
1377
1378static struct clk_mux_sel tegra_clk_m_sel[] = {
1379 { .input = &tegra_clk_32k, .value = 0},
1380 { .input = &tegra_pll_s, .value = 1},
1381 { 0, 0},
1382};
Colin Crossf1519612011-02-12 16:05:31 -08001383
Colin Crossd8611962010-01-28 16:40:29 -08001384static struct clk tegra_clk_m = {
1385 .name = "clk_m",
1386 .flags = ENABLE_ON_INIT,
1387 .ops = &tegra_clk_m_ops,
1388 .inputs = tegra_clk_m_sel,
1389 .reg = 0x1fc,
Colin Crossd8611962010-01-28 16:40:29 -08001390 .reg_shift = 28,
Colin Cross71fc84c2010-06-07 20:49:46 -07001391 .max_rate = 26000000,
Colin Crossd8611962010-01-28 16:40:29 -08001392};
1393
Colin Crossf1519612011-02-12 16:05:31 -08001394static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
Colin Crossd8611962010-01-28 16:40:29 -08001395 { 0, 0, 0, 0, 0, 0 },
1396};
1397
1398static struct clk tegra_pll_c = {
1399 .name = "pll_c",
1400 .flags = PLL_HAS_CPCON,
1401 .ops = &tegra_pll_ops,
1402 .reg = 0x80,
Colin Crossd8611962010-01-28 16:40:29 -08001403 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001404 .max_rate = 600000000,
Colin Crossf1519612011-02-12 16:05:31 -08001405 .u.pll = {
1406 .input_min = 2000000,
1407 .input_max = 31000000,
1408 .cf_min = 1000000,
1409 .cf_max = 6000000,
1410 .vco_min = 20000000,
1411 .vco_max = 1400000000,
1412 .freq_table = tegra_pll_c_freq_table,
1413 .lock_delay = 300,
1414 },
Colin Crossd8611962010-01-28 16:40:29 -08001415};
1416
1417static struct clk tegra_pll_c_out1 = {
1418 .name = "pll_c_out1",
1419 .ops = &tegra_pll_div_ops,
1420 .flags = DIV_U71,
1421 .parent = &tegra_pll_c,
1422 .reg = 0x84,
1423 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001424 .max_rate = 600000000,
Colin Crossd8611962010-01-28 16:40:29 -08001425};
1426
Colin Crossf1519612011-02-12 16:05:31 -08001427static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001428 { 12000000, 666000000, 666, 12, 1, 8},
1429 { 13000000, 666000000, 666, 13, 1, 8},
1430 { 19200000, 666000000, 555, 16, 1, 8},
1431 { 26000000, 666000000, 666, 26, 1, 8},
1432 { 12000000, 600000000, 600, 12, 1, 8},
1433 { 13000000, 600000000, 600, 13, 1, 8},
1434 { 19200000, 600000000, 375, 12, 1, 6},
1435 { 26000000, 600000000, 600, 26, 1, 8},
Colin Crossd8611962010-01-28 16:40:29 -08001436 { 0, 0, 0, 0, 0, 0 },
1437};
1438
1439static struct clk tegra_pll_m = {
1440 .name = "pll_m",
1441 .flags = PLL_HAS_CPCON,
1442 .ops = &tegra_pll_ops,
1443 .reg = 0x90,
Colin Crossd8611962010-01-28 16:40:29 -08001444 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001445 .max_rate = 800000000,
Colin Crossf1519612011-02-12 16:05:31 -08001446 .u.pll = {
1447 .input_min = 2000000,
1448 .input_max = 31000000,
1449 .cf_min = 1000000,
1450 .cf_max = 6000000,
1451 .vco_min = 20000000,
1452 .vco_max = 1200000000,
1453 .freq_table = tegra_pll_m_freq_table,
1454 .lock_delay = 300,
1455 },
Colin Crossd8611962010-01-28 16:40:29 -08001456};
1457
1458static struct clk tegra_pll_m_out1 = {
1459 .name = "pll_m_out1",
1460 .ops = &tegra_pll_div_ops,
1461 .flags = DIV_U71,
1462 .parent = &tegra_pll_m,
1463 .reg = 0x94,
1464 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001465 .max_rate = 600000000,
Colin Crossd8611962010-01-28 16:40:29 -08001466};
1467
Colin Crossf1519612011-02-12 16:05:31 -08001468static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
Colin Crossd8611962010-01-28 16:40:29 -08001469 { 12000000, 216000000, 432, 12, 2, 8},
1470 { 13000000, 216000000, 432, 13, 2, 8},
1471 { 19200000, 216000000, 90, 4, 2, 1},
1472 { 26000000, 216000000, 432, 26, 2, 8},
1473 { 12000000, 432000000, 432, 12, 1, 8},
1474 { 13000000, 432000000, 432, 13, 1, 8},
1475 { 19200000, 432000000, 90, 4, 1, 1},
1476 { 26000000, 432000000, 432, 26, 1, 8},
1477 { 0, 0, 0, 0, 0, 0 },
1478};
1479
1480static struct clk tegra_pll_p = {
1481 .name = "pll_p",
1482 .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
1483 .ops = &tegra_pll_ops,
1484 .reg = 0xa0,
Colin Crossd8611962010-01-28 16:40:29 -08001485 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001486 .max_rate = 432000000,
Colin Crossf1519612011-02-12 16:05:31 -08001487 .u.pll = {
1488 .input_min = 2000000,
1489 .input_max = 31000000,
1490 .cf_min = 1000000,
1491 .cf_max = 6000000,
1492 .vco_min = 20000000,
1493 .vco_max = 1400000000,
1494 .freq_table = tegra_pll_p_freq_table,
1495 .lock_delay = 300,
1496 },
Colin Crossd8611962010-01-28 16:40:29 -08001497};
1498
1499static struct clk tegra_pll_p_out1 = {
1500 .name = "pll_p_out1",
1501 .ops = &tegra_pll_div_ops,
1502 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1503 .parent = &tegra_pll_p,
1504 .reg = 0xa4,
1505 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001506 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001507};
1508
1509static struct clk tegra_pll_p_out2 = {
1510 .name = "pll_p_out2",
1511 .ops = &tegra_pll_div_ops,
1512 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1513 .parent = &tegra_pll_p,
1514 .reg = 0xa4,
1515 .reg_shift = 16,
Colin Cross71fc84c2010-06-07 20:49:46 -07001516 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001517};
1518
1519static struct clk tegra_pll_p_out3 = {
1520 .name = "pll_p_out3",
1521 .ops = &tegra_pll_div_ops,
1522 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1523 .parent = &tegra_pll_p,
1524 .reg = 0xa8,
1525 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001526 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001527};
1528
1529static struct clk tegra_pll_p_out4 = {
1530 .name = "pll_p_out4",
1531 .ops = &tegra_pll_div_ops,
1532 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
1533 .parent = &tegra_pll_p,
1534 .reg = 0xa8,
1535 .reg_shift = 16,
Colin Cross71fc84c2010-06-07 20:49:46 -07001536 .max_rate = 432000000,
Colin Crossd8611962010-01-28 16:40:29 -08001537};
1538
Colin Crossf1519612011-02-12 16:05:31 -08001539static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
Colin Crossd8611962010-01-28 16:40:29 -08001540 { 28800000, 56448000, 49, 25, 1, 1},
1541 { 28800000, 73728000, 64, 25, 1, 1},
1542 { 28800000, 11289600, 49, 25, 1, 1},
1543 { 28800000, 12288000, 64, 25, 1, 1},
Colin Cross71fc84c2010-06-07 20:49:46 -07001544 { 28800000, 24000000, 5, 6, 1, 1},
Colin Crossd8611962010-01-28 16:40:29 -08001545 { 0, 0, 0, 0, 0, 0 },
1546};
1547
1548static struct clk tegra_pll_a = {
1549 .name = "pll_a",
1550 .flags = PLL_HAS_CPCON,
1551 .ops = &tegra_pll_ops,
1552 .reg = 0xb0,
Colin Crossd8611962010-01-28 16:40:29 -08001553 .parent = &tegra_pll_p_out1,
Colin Cross71fc84c2010-06-07 20:49:46 -07001554 .max_rate = 56448000,
Colin Crossf1519612011-02-12 16:05:31 -08001555 .u.pll = {
1556 .input_min = 2000000,
1557 .input_max = 31000000,
1558 .cf_min = 1000000,
1559 .cf_max = 6000000,
1560 .vco_min = 20000000,
1561 .vco_max = 1400000000,
1562 .freq_table = tegra_pll_a_freq_table,
1563 .lock_delay = 300,
1564 },
Colin Crossd8611962010-01-28 16:40:29 -08001565};
1566
1567static struct clk tegra_pll_a_out0 = {
1568 .name = "pll_a_out0",
1569 .ops = &tegra_pll_div_ops,
1570 .flags = DIV_U71,
1571 .parent = &tegra_pll_a,
1572 .reg = 0xb4,
1573 .reg_shift = 0,
Colin Cross71fc84c2010-06-07 20:49:46 -07001574 .max_rate = 56448000,
Colin Crossd8611962010-01-28 16:40:29 -08001575};
1576
Colin Crossf1519612011-02-12 16:05:31 -08001577static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
Colin Crosscea62c82010-10-04 11:49:26 -07001578 { 12000000, 216000000, 216, 12, 1, 4},
1579 { 13000000, 216000000, 216, 13, 1, 4},
1580 { 19200000, 216000000, 135, 12, 1, 3},
1581 { 26000000, 216000000, 216, 26, 1, 4},
1582
1583 { 12000000, 594000000, 594, 12, 1, 8},
1584 { 13000000, 594000000, 594, 13, 1, 8},
1585 { 19200000, 594000000, 495, 16, 1, 8},
1586 { 26000000, 594000000, 594, 26, 1, 8},
1587
Colin Crossd8611962010-01-28 16:40:29 -08001588 { 12000000, 1000000000, 1000, 12, 1, 12},
1589 { 13000000, 1000000000, 1000, 13, 1, 12},
1590 { 19200000, 1000000000, 625, 12, 1, 8},
1591 { 26000000, 1000000000, 1000, 26, 1, 12},
Colin Crosscea62c82010-10-04 11:49:26 -07001592
Colin Crossd8611962010-01-28 16:40:29 -08001593 { 0, 0, 0, 0, 0, 0 },
1594};
1595
1596static struct clk tegra_pll_d = {
1597 .name = "pll_d",
1598 .flags = PLL_HAS_CPCON | PLLD,
1599 .ops = &tegra_pll_ops,
1600 .reg = 0xd0,
Colin Crossd8611962010-01-28 16:40:29 -08001601 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001602 .max_rate = 1000000000,
Colin Crossf1519612011-02-12 16:05:31 -08001603 .u.pll = {
1604 .input_min = 2000000,
1605 .input_max = 40000000,
1606 .cf_min = 1000000,
1607 .cf_max = 6000000,
1608 .vco_min = 40000000,
1609 .vco_max = 1000000000,
1610 .freq_table = tegra_pll_d_freq_table,
1611 .lock_delay = 1000,
1612 },
Colin Crossd8611962010-01-28 16:40:29 -08001613};
1614
1615static struct clk tegra_pll_d_out0 = {
1616 .name = "pll_d_out0",
1617 .ops = &tegra_pll_div_ops,
1618 .flags = DIV_2 | PLLD,
1619 .parent = &tegra_pll_d,
Colin Cross71fc84c2010-06-07 20:49:46 -07001620 .max_rate = 500000000,
Colin Crossd8611962010-01-28 16:40:29 -08001621};
1622
Colin Crossf1519612011-02-12 16:05:31 -08001623static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001624 { 12000000, 480000000, 960, 12, 2, 0},
1625 { 13000000, 480000000, 960, 13, 2, 0},
1626 { 19200000, 480000000, 200, 4, 2, 0},
1627 { 26000000, 480000000, 960, 26, 2, 0},
Colin Crossd8611962010-01-28 16:40:29 -08001628 { 0, 0, 0, 0, 0, 0 },
1629};
1630
1631static struct clk tegra_pll_u = {
1632 .name = "pll_u",
Colin Cross71fc84c2010-06-07 20:49:46 -07001633 .flags = PLLU,
Colin Crossd8611962010-01-28 16:40:29 -08001634 .ops = &tegra_pll_ops,
1635 .reg = 0xc0,
Colin Crossd8611962010-01-28 16:40:29 -08001636 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001637 .max_rate = 480000000,
Colin Crossf1519612011-02-12 16:05:31 -08001638 .u.pll = {
1639 .input_min = 2000000,
1640 .input_max = 40000000,
1641 .cf_min = 1000000,
1642 .cf_max = 6000000,
1643 .vco_min = 480000000,
1644 .vco_max = 960000000,
1645 .freq_table = tegra_pll_u_freq_table,
1646 .lock_delay = 1000,
1647 },
Colin Crossd8611962010-01-28 16:40:29 -08001648};
1649
Colin Crossf1519612011-02-12 16:05:31 -08001650static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001651 /* 1 GHz */
Colin Crossd8611962010-01-28 16:40:29 -08001652 { 12000000, 1000000000, 1000, 12, 1, 12},
1653 { 13000000, 1000000000, 1000, 13, 1, 12},
1654 { 19200000, 1000000000, 625, 12, 1, 8},
1655 { 26000000, 1000000000, 1000, 26, 1, 12},
Colin Cross71fc84c2010-06-07 20:49:46 -07001656
1657 /* 912 MHz */
1658 { 12000000, 912000000, 912, 12, 1, 12},
1659 { 13000000, 912000000, 912, 13, 1, 12},
1660 { 19200000, 912000000, 760, 16, 1, 8},
1661 { 26000000, 912000000, 912, 26, 1, 12},
1662
1663 /* 816 MHz */
1664 { 12000000, 816000000, 816, 12, 1, 12},
1665 { 13000000, 816000000, 816, 13, 1, 12},
1666 { 19200000, 816000000, 680, 16, 1, 8},
1667 { 26000000, 816000000, 816, 26, 1, 12},
1668
1669 /* 760 MHz */
1670 { 12000000, 760000000, 760, 12, 1, 12},
1671 { 13000000, 760000000, 760, 13, 1, 12},
1672 { 19200000, 760000000, 950, 24, 1, 8},
1673 { 26000000, 760000000, 760, 26, 1, 12},
1674
1675 /* 608 MHz */
1676 { 12000000, 608000000, 760, 12, 1, 12},
1677 { 13000000, 608000000, 760, 13, 1, 12},
1678 { 19200000, 608000000, 380, 12, 1, 8},
1679 { 26000000, 608000000, 760, 26, 1, 12},
1680
1681 /* 456 MHz */
1682 { 12000000, 456000000, 456, 12, 1, 12},
1683 { 13000000, 456000000, 456, 13, 1, 12},
1684 { 19200000, 456000000, 380, 16, 1, 8},
1685 { 26000000, 456000000, 456, 26, 1, 12},
1686
1687 /* 312 MHz */
1688 { 12000000, 312000000, 312, 12, 1, 12},
1689 { 13000000, 312000000, 312, 13, 1, 12},
1690 { 19200000, 312000000, 260, 16, 1, 8},
1691 { 26000000, 312000000, 312, 26, 1, 12},
1692
Colin Crossd8611962010-01-28 16:40:29 -08001693 { 0, 0, 0, 0, 0, 0 },
1694};
1695
1696static struct clk tegra_pll_x = {
1697 .name = "pll_x",
1698 .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG,
Colin Cross71fc84c2010-06-07 20:49:46 -07001699 .ops = &tegra_pllx_ops,
Colin Crossd8611962010-01-28 16:40:29 -08001700 .reg = 0xe0,
Colin Crossd8611962010-01-28 16:40:29 -08001701 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001702 .max_rate = 1000000000,
Colin Crossf1519612011-02-12 16:05:31 -08001703 .u.pll = {
1704 .input_min = 2000000,
1705 .input_max = 31000000,
1706 .cf_min = 1000000,
1707 .cf_max = 6000000,
1708 .vco_min = 20000000,
1709 .vco_max = 1200000000,
1710 .freq_table = tegra_pll_x_freq_table,
1711 .lock_delay = 300,
1712 },
Colin Crossd8611962010-01-28 16:40:29 -08001713};
1714
Colin Crossf1519612011-02-12 16:05:31 -08001715static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
Mike Rapoport8d685bc2010-09-27 11:26:32 +02001716 { 12000000, 100000000, 200, 24, 1, 0 },
1717 { 0, 0, 0, 0, 0, 0 },
1718};
1719
1720static struct clk tegra_pll_e = {
1721 .name = "pll_e",
1722 .flags = PLL_ALT_MISC_REG,
1723 .ops = &tegra_plle_ops,
Mike Rapoport8d685bc2010-09-27 11:26:32 +02001724 .parent = &tegra_clk_m,
1725 .reg = 0xe8,
Colin Crossf1519612011-02-12 16:05:31 -08001726 .max_rate = 100000000,
1727 .u.pll = {
1728 .input_min = 12000000,
1729 .input_max = 12000000,
1730 .freq_table = tegra_pll_e_freq_table,
1731 },
Mike Rapoport8d685bc2010-09-27 11:26:32 +02001732};
1733
Colin Crossd8611962010-01-28 16:40:29 -08001734static struct clk tegra_clk_d = {
1735 .name = "clk_d",
1736 .flags = PERIPH_NO_RESET,
1737 .ops = &tegra_clk_double_ops,
Colin Crossd8611962010-01-28 16:40:29 -08001738 .reg = 0x34,
1739 .reg_shift = 12,
1740 .parent = &tegra_clk_m,
Colin Cross71fc84c2010-06-07 20:49:46 -07001741 .max_rate = 52000000,
Colin Crossf1519612011-02-12 16:05:31 -08001742 .u.periph = {
1743 .clk_num = 90,
1744 },
Colin Crossd8611962010-01-28 16:40:29 -08001745};
1746
Colin Crosscea62c82010-10-04 11:49:26 -07001747/* dap_mclk1, belongs to the cdev1 pingroup. */
1748static struct clk tegra_dev1_clk = {
1749 .name = "clk_dev1",
1750 .ops = &tegra_cdev_clk_ops,
Colin Crosscea62c82010-10-04 11:49:26 -07001751 .rate = 26000000,
1752 .max_rate = 26000000,
Colin Crossf1519612011-02-12 16:05:31 -08001753 .u.periph = {
1754 .clk_num = 94,
1755 },
Colin Crosscea62c82010-10-04 11:49:26 -07001756};
1757
1758/* dap_mclk2, belongs to the cdev2 pingroup. */
1759static struct clk tegra_dev2_clk = {
1760 .name = "clk_dev2",
1761 .ops = &tegra_cdev_clk_ops,
Colin Crosscea62c82010-10-04 11:49:26 -07001762 .rate = 26000000,
1763 .max_rate = 26000000,
Colin Crossf1519612011-02-12 16:05:31 -08001764 .u.periph = {
1765 .clk_num = 93,
1766 },
Colin Crosscea62c82010-10-04 11:49:26 -07001767};
1768
Colin Cross71fc84c2010-06-07 20:49:46 -07001769/* initialized before peripheral clocks */
1770static struct clk_mux_sel mux_audio_sync_clk[8+1];
1771static const struct audio_sources {
1772 const char *name;
1773 int value;
1774} mux_audio_sync_clk_sources[] = {
1775 { .name = "spdif_in", .value = 0 },
1776 { .name = "i2s1", .value = 1 },
1777 { .name = "i2s2", .value = 2 },
1778 { .name = "pll_a_out0", .value = 4 },
1779#if 0 /* FIXME: not implemented */
1780 { .name = "ac97", .value = 3 },
1781 { .name = "ext_audio_clk2", .value = 5 },
1782 { .name = "ext_audio_clk1", .value = 6 },
1783 { .name = "ext_vimclk", .value = 7 },
1784#endif
1785 { 0, 0 }
1786};
1787
1788static struct clk tegra_clk_audio = {
1789 .name = "audio",
1790 .inputs = mux_audio_sync_clk,
1791 .reg = 0x38,
1792 .max_rate = 24000000,
1793 .ops = &tegra_audio_sync_clk_ops
1794};
1795
Colin Crossd8611962010-01-28 16:40:29 -08001796static struct clk tegra_clk_audio_2x = {
Colin Cross71fc84c2010-06-07 20:49:46 -07001797 .name = "audio_2x",
Colin Crossd8611962010-01-28 16:40:29 -08001798 .flags = PERIPH_NO_RESET,
Colin Cross71fc84c2010-06-07 20:49:46 -07001799 .max_rate = 48000000,
Colin Crossd8611962010-01-28 16:40:29 -08001800 .ops = &tegra_clk_double_ops,
Colin Crossd8611962010-01-28 16:40:29 -08001801 .reg = 0x34,
1802 .reg_shift = 8,
Colin Cross71fc84c2010-06-07 20:49:46 -07001803 .parent = &tegra_clk_audio,
Colin Crossf1519612011-02-12 16:05:31 -08001804 .u.periph = {
1805 .clk_num = 89,
1806 },
Colin Cross71fc84c2010-06-07 20:49:46 -07001807};
1808
1809struct clk_lookup tegra_audio_clk_lookups[] = {
1810 { .con_id = "audio", .clk = &tegra_clk_audio },
1811 { .con_id = "audio_2x", .clk = &tegra_clk_audio_2x }
1812};
1813
1814/* This is called after peripheral clocks are initialized, as the
1815 * audio_sync clock depends on some of the peripheral clocks.
1816 */
1817
1818static void init_audio_sync_clock_mux(void)
1819{
1820 int i;
1821 struct clk_mux_sel *sel = mux_audio_sync_clk;
1822 const struct audio_sources *src = mux_audio_sync_clk_sources;
1823 struct clk_lookup *lookup;
1824
1825 for (i = 0; src->name; i++, sel++, src++) {
1826 sel->input = tegra_get_clock_by_name(src->name);
1827 if (!sel->input)
1828 pr_err("%s: could not find clk %s\n", __func__,
1829 src->name);
1830 sel->value = src->value;
1831 }
1832
1833 lookup = tegra_audio_clk_lookups;
1834 for (i = 0; i < ARRAY_SIZE(tegra_audio_clk_lookups); i++, lookup++) {
1835 clk_init(lookup->clk);
1836 clkdev_add(lookup);
1837 }
Colin Crossd8611962010-01-28 16:40:29 -08001838}
Colin Crossd8611962010-01-28 16:40:29 -08001839
1840static struct clk_mux_sel mux_cclk[] = {
1841 { .input = &tegra_clk_m, .value = 0},
1842 { .input = &tegra_pll_c, .value = 1},
1843 { .input = &tegra_clk_32k, .value = 2},
1844 { .input = &tegra_pll_m, .value = 3},
1845 { .input = &tegra_pll_p, .value = 4},
1846 { .input = &tegra_pll_p_out4, .value = 5},
1847 { .input = &tegra_pll_p_out3, .value = 6},
1848 { .input = &tegra_clk_d, .value = 7},
1849 { .input = &tegra_pll_x, .value = 8},
1850 { 0, 0},
1851};
1852
1853static struct clk_mux_sel mux_sclk[] = {
1854 { .input = &tegra_clk_m, .value = 0},
1855 { .input = &tegra_pll_c_out1, .value = 1},
1856 { .input = &tegra_pll_p_out4, .value = 2},
1857 { .input = &tegra_pll_p_out3, .value = 3},
1858 { .input = &tegra_pll_p_out2, .value = 4},
1859 { .input = &tegra_clk_d, .value = 5},
1860 { .input = &tegra_clk_32k, .value = 6},
1861 { .input = &tegra_pll_m_out1, .value = 7},
1862 { 0, 0},
1863};
1864
Colin Cross71fc84c2010-06-07 20:49:46 -07001865static struct clk tegra_clk_cclk = {
1866 .name = "cclk",
Colin Crossd8611962010-01-28 16:40:29 -08001867 .inputs = mux_cclk,
1868 .reg = 0x20,
1869 .ops = &tegra_super_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001870 .max_rate = 1000000000,
Colin Crossd8611962010-01-28 16:40:29 -08001871};
1872
Colin Cross71fc84c2010-06-07 20:49:46 -07001873static struct clk tegra_clk_sclk = {
1874 .name = "sclk",
Colin Crossd8611962010-01-28 16:40:29 -08001875 .inputs = mux_sclk,
1876 .reg = 0x28,
1877 .ops = &tegra_super_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001878 .max_rate = 600000000,
1879};
1880
1881static struct clk tegra_clk_virtual_cpu = {
1882 .name = "cpu",
1883 .parent = &tegra_clk_cclk,
Colin Cross71fc84c2010-06-07 20:49:46 -07001884 .ops = &tegra_cpu_ops,
1885 .max_rate = 1000000000,
Colin Crossf1519612011-02-12 16:05:31 -08001886 .u.cpu = {
1887 .main = &tegra_pll_x,
1888 .backup = &tegra_pll_p,
1889 },
Colin Crossd8611962010-01-28 16:40:29 -08001890};
1891
1892static struct clk tegra_clk_hclk = {
1893 .name = "hclk",
1894 .flags = DIV_BUS,
Colin Cross71fc84c2010-06-07 20:49:46 -07001895 .parent = &tegra_clk_sclk,
Colin Crossd8611962010-01-28 16:40:29 -08001896 .reg = 0x30,
1897 .reg_shift = 4,
1898 .ops = &tegra_bus_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001899 .max_rate = 240000000,
Colin Crossd8611962010-01-28 16:40:29 -08001900};
1901
1902static struct clk tegra_clk_pclk = {
1903 .name = "pclk",
1904 .flags = DIV_BUS,
1905 .parent = &tegra_clk_hclk,
1906 .reg = 0x30,
1907 .reg_shift = 0,
1908 .ops = &tegra_bus_ops,
Colin Cross71fc84c2010-06-07 20:49:46 -07001909 .max_rate = 108000000,
Colin Crossd8611962010-01-28 16:40:29 -08001910};
1911
Colin Crosscea62c82010-10-04 11:49:26 -07001912static struct clk tegra_clk_blink = {
1913 .name = "blink",
1914 .parent = &tegra_clk_32k,
1915 .reg = 0x40,
1916 .ops = &tegra_blink_clk_ops,
1917 .max_rate = 32768,
1918};
1919
Colin Crossd8611962010-01-28 16:40:29 -08001920static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
1921 { .input = &tegra_pll_m, .value = 0},
1922 { .input = &tegra_pll_c, .value = 1},
1923 { .input = &tegra_pll_p, .value = 2},
1924 { .input = &tegra_pll_a_out0, .value = 3},
1925 { 0, 0},
1926};
1927
1928static struct clk_mux_sel mux_pllm_pllc_pllp_clkm[] = {
1929 { .input = &tegra_pll_m, .value = 0},
1930 { .input = &tegra_pll_c, .value = 1},
1931 { .input = &tegra_pll_p, .value = 2},
1932 { .input = &tegra_clk_m, .value = 3},
1933 { 0, 0},
1934};
1935
1936static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
1937 { .input = &tegra_pll_p, .value = 0},
1938 { .input = &tegra_pll_c, .value = 1},
1939 { .input = &tegra_pll_m, .value = 2},
1940 { .input = &tegra_clk_m, .value = 3},
1941 { 0, 0},
1942};
1943
Colin Cross71fc84c2010-06-07 20:49:46 -07001944static struct clk_mux_sel mux_pllaout0_audio2x_pllp_clkm[] = {
1945 {.input = &tegra_pll_a_out0, .value = 0},
1946 {.input = &tegra_clk_audio_2x, .value = 1},
Colin Crossd8611962010-01-28 16:40:29 -08001947 {.input = &tegra_pll_p, .value = 2},
1948 {.input = &tegra_clk_m, .value = 3},
1949 { 0, 0},
1950};
1951
1952static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
1953 {.input = &tegra_pll_p, .value = 0},
1954 {.input = &tegra_pll_d_out0, .value = 1},
1955 {.input = &tegra_pll_c, .value = 2},
1956 {.input = &tegra_clk_m, .value = 3},
1957 { 0, 0},
1958};
1959
1960static struct clk_mux_sel mux_pllp_pllc_audio_clkm_clk32[] = {
1961 {.input = &tegra_pll_p, .value = 0},
1962 {.input = &tegra_pll_c, .value = 1},
Colin Cross71fc84c2010-06-07 20:49:46 -07001963 {.input = &tegra_clk_audio, .value = 2},
Colin Crossd8611962010-01-28 16:40:29 -08001964 {.input = &tegra_clk_m, .value = 3},
1965 {.input = &tegra_clk_32k, .value = 4},
1966 { 0, 0},
1967};
1968
1969static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
1970 {.input = &tegra_pll_p, .value = 0},
1971 {.input = &tegra_pll_c, .value = 1},
1972 {.input = &tegra_pll_m, .value = 2},
1973 { 0, 0},
1974};
1975
1976static struct clk_mux_sel mux_clk_m[] = {
1977 { .input = &tegra_clk_m, .value = 0},
1978 { 0, 0},
1979};
1980
1981static struct clk_mux_sel mux_pllp_out3[] = {
1982 { .input = &tegra_pll_p_out3, .value = 0},
1983 { 0, 0},
1984};
1985
1986static struct clk_mux_sel mux_plld[] = {
1987 { .input = &tegra_pll_d, .value = 0},
1988 { 0, 0},
1989};
1990
1991static struct clk_mux_sel mux_clk_32k[] = {
1992 { .input = &tegra_clk_32k, .value = 0},
1993 { 0, 0},
1994};
1995
Stephen Warren1ca00342011-01-05 14:32:20 -07001996static struct clk_mux_sel mux_pclk[] = {
1997 { .input = &tegra_clk_pclk, .value = 0},
1998 { 0, 0},
1999};
2000
Colin Cross6d296822010-11-22 18:37:54 -08002001static struct clk tegra_clk_emc = {
2002 .name = "emc",
2003 .ops = &tegra_emc_clk_ops,
2004 .reg = 0x19c,
2005 .max_rate = 800000000,
2006 .inputs = mux_pllm_pllc_pllp_clkm,
2007 .flags = MUX | DIV_U71 | PERIPH_EMC_ENB,
2008 .u.periph = {
2009 .clk_num = 57,
2010 },
2011};
2012
Colin Cross71fc84c2010-06-07 20:49:46 -07002013#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
Colin Crossd8611962010-01-28 16:40:29 -08002014 { \
2015 .name = _name, \
2016 .lookup = { \
2017 .dev_id = _dev, \
2018 .con_id = _con, \
2019 }, \
2020 .ops = &tegra_periph_clk_ops, \
Colin Crossd8611962010-01-28 16:40:29 -08002021 .reg = _reg, \
2022 .inputs = _inputs, \
2023 .flags = _flags, \
Colin Cross71fc84c2010-06-07 20:49:46 -07002024 .max_rate = _max, \
Colin Crossf1519612011-02-12 16:05:31 -08002025 .u.periph = { \
2026 .clk_num = _clk_num, \
2027 }, \
Colin Crossd8611962010-01-28 16:40:29 -08002028 }
2029
Colin Cross310992c2011-02-12 16:14:03 -08002030#define SHARED_CLK(_name, _dev, _con, _parent) \
2031 { \
2032 .name = _name, \
2033 .lookup = { \
2034 .dev_id = _dev, \
2035 .con_id = _con, \
2036 }, \
2037 .ops = &tegra_clk_shared_bus_ops, \
2038 .parent = _parent, \
2039 }
2040
Colin Cross3ec349f2011-02-12 15:52:56 -08002041struct clk tegra_list_clks[] = {
Stephen Warren1ca00342011-01-05 14:32:20 -07002042 PERIPH_CLK("apbdma", "tegra-dma", NULL, 34, 0, 108000000, mux_pclk, 0),
Colin Cross71fc84c2010-06-07 20:49:46 -07002043 PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET),
2044 PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0),
2045 PERIPH_CLK("i2s1", "i2s.0", NULL, 11, 0x100, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
2046 PERIPH_CLK("i2s2", "i2s.1", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
Colin Crossd8611962010-01-28 16:40:29 -08002047 /* FIXME: spdif has 2 clocks but 1 enable */
Colin Cross71fc84c2010-06-07 20:49:46 -07002048 PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
2049 PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71),
2050 PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71),
2051 PERIPH_CLK("spi", "spi", NULL, 43, 0x114, 40000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2052 PERIPH_CLK("xio", "xio", NULL, 45, 0x120, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2053 PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2054 PERIPH_CLK("sbc1", "spi_tegra.0", NULL, 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2055 PERIPH_CLK("sbc2", "spi_tegra.1", NULL, 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2056 PERIPH_CLK("sbc3", "spi_tegra.2", NULL, 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2057 PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2058 PERIPH_CLK("ide", "ide", NULL, 25, 0x144, 100000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
2059 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 -08002060 /* FIXME: vfir shares an enable with uartb */
Colin Cross71fc84c2010-06-07 20:49:46 -07002061 PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2062 PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2063 PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2064 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 -07002065 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 -07002066 PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
2067 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 -08002068 /* FIXME: what is la? */
Colin Cross71fc84c2010-06-07 20:49:46 -07002069 PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2070 PERIPH_CLK("owr", "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2071 PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, 92000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
2072 PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2073 PERIPH_CLK("i2c1", "tegra-i2c.0", NULL, 12, 0x124, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
2074 PERIPH_CLK("i2c2", "tegra-i2c.1", NULL, 54, 0x198, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
2075 PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
2076 PERIPH_CLK("dvc", "tegra-i2c.3", NULL, 47, 0x128, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
2077 PERIPH_CLK("i2c1_i2c", "tegra-i2c.0", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
2078 PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
2079 PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
2080 PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
Colin Crosscea62c82010-10-04 11:49:26 -07002081 PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
2082 PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
2083 PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
2084 PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
2085 PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
Colin Cross71fc84c2010-06-07 20:49:46 -07002086 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 */
2087 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 -08002088 /* FIXME: vi and vi_sensor share an enable */
Colin Crosscea62c82010-10-04 11:49:26 -07002089 PERIPH_CLK("vi", "tegra_camera", "vi", 20, 0x148, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
2090 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 -07002091 PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
2092 PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 250000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
2093 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 -08002094 /* FIXME: cve and tvo share an enable */
Colin Cross71fc84c2010-06-07 20:49:46 -07002095 PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
2096 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 -07002097 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 -07002098 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 -07002099 PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
2100 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 -07002101 PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
2102 PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
2103 PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
Colin Cross71fc84c2010-06-07 20:49:46 -07002104 PERIPH_CLK("dsi", "dsi", NULL, 48, 0, 500000000, mux_plld, 0), /* scales with voltage */
Colin Crosscea62c82010-10-04 11:49:26 -07002105 PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 72000000, mux_pllp_out3, 0),
2106 PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */
2107 PERIPH_CLK("csus", "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET),
Mike Rapoport8d685bc2010-09-27 11:26:32 +02002108 PERIPH_CLK("pex", NULL, "pex", 70, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
2109 PERIPH_CLK("afi", NULL, "afi", 72, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
2110 PERIPH_CLK("pcie_xclk", NULL, "pcie_xclk", 74, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
Colin Crossd8611962010-01-28 16:40:29 -08002111};
2112
2113#define CLK_DUPLICATE(_name, _dev, _con) \
2114 { \
2115 .name = _name, \
2116 .lookup = { \
2117 .dev_id = _dev, \
2118 .con_id = _con, \
2119 }, \
2120 }
2121
2122/* Some clocks may be used by different drivers depending on the board
2123 * configuration. List those here to register them twice in the clock lookup
2124 * table under two names.
2125 */
2126struct clk_duplicate tegra_clk_duplicates[] = {
2127 CLK_DUPLICATE("uarta", "tegra_uart.0", NULL),
2128 CLK_DUPLICATE("uartb", "tegra_uart.1", NULL),
2129 CLK_DUPLICATE("uartc", "tegra_uart.2", NULL),
2130 CLK_DUPLICATE("uartd", "tegra_uart.3", NULL),
2131 CLK_DUPLICATE("uarte", "tegra_uart.4", NULL),
Colin Crosscea62c82010-10-04 11:49:26 -07002132 CLK_DUPLICATE("usbd", "utmip-pad", NULL),
Colin Cross71fc84c2010-06-07 20:49:46 -07002133 CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
Colin Crosscea62c82010-10-04 11:49:26 -07002134 CLK_DUPLICATE("usbd", "tegra-otg", NULL),
2135 CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
2136 CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
2137 CLK_DUPLICATE("pwm", "tegra_pwm.0", NULL),
2138 CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL),
2139 CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL),
2140 CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL),
Colin Crossd8611962010-01-28 16:40:29 -08002141};
2142
2143#define CLK(dev, con, ck) \
2144 { \
2145 .dev_id = dev, \
2146 .con_id = con, \
2147 .clk = ck, \
2148 }
2149
Colin Cross3ec349f2011-02-12 15:52:56 -08002150struct clk *tegra_ptr_clks[] = {
2151 &tegra_clk_32k,
2152 &tegra_pll_s,
2153 &tegra_clk_m,
2154 &tegra_pll_m,
2155 &tegra_pll_m_out1,
2156 &tegra_pll_c,
2157 &tegra_pll_c_out1,
2158 &tegra_pll_p,
2159 &tegra_pll_p_out1,
2160 &tegra_pll_p_out2,
2161 &tegra_pll_p_out3,
2162 &tegra_pll_p_out4,
2163 &tegra_pll_a,
2164 &tegra_pll_a_out0,
2165 &tegra_pll_d,
2166 &tegra_pll_d_out0,
2167 &tegra_pll_u,
2168 &tegra_pll_x,
2169 &tegra_pll_e,
2170 &tegra_clk_cclk,
2171 &tegra_clk_sclk,
2172 &tegra_clk_hclk,
2173 &tegra_clk_pclk,
2174 &tegra_clk_d,
2175 &tegra_dev1_clk,
2176 &tegra_dev2_clk,
2177 &tegra_clk_virtual_cpu,
2178 &tegra_clk_blink,
Colin Cross6d296822010-11-22 18:37:54 -08002179 &tegra_clk_emc,
Colin Crossd8611962010-01-28 16:40:29 -08002180};
2181
Colin Cross3ec349f2011-02-12 15:52:56 -08002182static void tegra2_init_one_clock(struct clk *c)
2183{
2184 clk_init(c);
Colin Cross310992c2011-02-12 16:14:03 -08002185 INIT_LIST_HEAD(&c->shared_bus_list);
Colin Cross3ec349f2011-02-12 15:52:56 -08002186 if (!c->lookup.dev_id && !c->lookup.con_id)
2187 c->lookup.con_id = c->name;
2188 c->lookup.clk = c;
2189 clkdev_add(&c->lookup);
2190}
2191
Colin Crossd8611962010-01-28 16:40:29 -08002192void __init tegra2_init_clocks(void)
2193{
2194 int i;
Colin Crossd8611962010-01-28 16:40:29 -08002195 struct clk *c;
Colin Crossd8611962010-01-28 16:40:29 -08002196
Colin Cross3ec349f2011-02-12 15:52:56 -08002197 for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
2198 tegra2_init_one_clock(tegra_ptr_clks[i]);
Colin Crossd8611962010-01-28 16:40:29 -08002199
Colin Cross3ec349f2011-02-12 15:52:56 -08002200 for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
2201 tegra2_init_one_clock(&tegra_list_clks[i]);
Colin Crossd8611962010-01-28 16:40:29 -08002202
2203 for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
Colin Cross3ec349f2011-02-12 15:52:56 -08002204 c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
2205 if (!c) {
Colin Crossd8611962010-01-28 16:40:29 -08002206 pr_err("%s: Unknown duplicate clock %s\n", __func__,
Colin Cross3ec349f2011-02-12 15:52:56 -08002207 tegra_clk_duplicates[i].name);
2208 continue;
Colin Crossd8611962010-01-28 16:40:29 -08002209 }
Colin Cross3ec349f2011-02-12 15:52:56 -08002210
2211 tegra_clk_duplicates[i].lookup.clk = c;
2212 clkdev_add(&tegra_clk_duplicates[i].lookup);
Colin Crossd8611962010-01-28 16:40:29 -08002213 }
Colin Cross71fc84c2010-06-07 20:49:46 -07002214
2215 init_audio_sync_clock_mux();
Colin Crossd8611962010-01-28 16:40:29 -08002216}
Colin Cross71fc84c2010-06-07 20:49:46 -07002217
2218#ifdef CONFIG_PM
2219static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM +
Colin Crosscea62c82010-10-04 11:49:26 -07002220 PERIPH_CLK_SOURCE_NUM + 19];
Colin Cross71fc84c2010-06-07 20:49:46 -07002221
2222void tegra_clk_suspend(void)
2223{
2224 unsigned long off, i;
2225 u32 *ctx = clk_rst_suspend;
2226
2227 *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK;
Colin Crosscea62c82010-10-04 11:49:26 -07002228 *ctx++ = clk_readl(tegra_pll_p.reg + PLL_BASE);
2229 *ctx++ = clk_readl(tegra_pll_p.reg + PLL_MISC(&tegra_pll_p));
2230 *ctx++ = clk_readl(tegra_pll_c.reg + PLL_BASE);
2231 *ctx++ = clk_readl(tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
2232 *ctx++ = clk_readl(tegra_pll_a.reg + PLL_BASE);
2233 *ctx++ = clk_readl(tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
2234
2235 *ctx++ = clk_readl(tegra_pll_m_out1.reg);
2236 *ctx++ = clk_readl(tegra_pll_p_out1.reg);
2237 *ctx++ = clk_readl(tegra_pll_p_out3.reg);
2238 *ctx++ = clk_readl(tegra_pll_a_out0.reg);
2239 *ctx++ = clk_readl(tegra_pll_c_out1.reg);
2240
2241 *ctx++ = clk_readl(tegra_clk_cclk.reg);
2242 *ctx++ = clk_readl(tegra_clk_cclk.reg + SUPER_CLK_DIVIDER);
2243
2244 *ctx++ = clk_readl(tegra_clk_sclk.reg);
2245 *ctx++ = clk_readl(tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
2246 *ctx++ = clk_readl(tegra_clk_pclk.reg);
Colin Cross71fc84c2010-06-07 20:49:46 -07002247
2248 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
2249 off += 4) {
2250 if (off == PERIPH_CLK_SOURCE_EMC)
2251 continue;
2252 *ctx++ = clk_readl(off);
2253 }
2254
2255 off = RST_DEVICES;
2256 for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
2257 *ctx++ = clk_readl(off);
2258
2259 off = CLK_OUT_ENB;
2260 for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
2261 *ctx++ = clk_readl(off);
2262
2263 *ctx++ = clk_readl(MISC_CLK_ENB);
2264 *ctx++ = clk_readl(CLK_MASK_ARM);
2265}
2266
2267void tegra_clk_resume(void)
2268{
2269 unsigned long off, i;
2270 const u32 *ctx = clk_rst_suspend;
2271 u32 val;
2272
2273 val = clk_readl(OSC_CTRL) & ~OSC_CTRL_MASK;
2274 val |= *ctx++;
2275 clk_writel(val, OSC_CTRL);
2276
Colin Crosscea62c82010-10-04 11:49:26 -07002277 clk_writel(*ctx++, tegra_pll_p.reg + PLL_BASE);
2278 clk_writel(*ctx++, tegra_pll_p.reg + PLL_MISC(&tegra_pll_p));
2279 clk_writel(*ctx++, tegra_pll_c.reg + PLL_BASE);
2280 clk_writel(*ctx++, tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
2281 clk_writel(*ctx++, tegra_pll_a.reg + PLL_BASE);
2282 clk_writel(*ctx++, tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
2283 udelay(300);
2284
2285 clk_writel(*ctx++, tegra_pll_m_out1.reg);
2286 clk_writel(*ctx++, tegra_pll_p_out1.reg);
2287 clk_writel(*ctx++, tegra_pll_p_out3.reg);
2288 clk_writel(*ctx++, tegra_pll_a_out0.reg);
2289 clk_writel(*ctx++, tegra_pll_c_out1.reg);
2290
2291 clk_writel(*ctx++, tegra_clk_cclk.reg);
2292 clk_writel(*ctx++, tegra_clk_cclk.reg + SUPER_CLK_DIVIDER);
2293
2294 clk_writel(*ctx++, tegra_clk_sclk.reg);
2295 clk_writel(*ctx++, tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
2296 clk_writel(*ctx++, tegra_clk_pclk.reg);
2297
Colin Cross71fc84c2010-06-07 20:49:46 -07002298 /* enable all clocks before configuring clock sources */
2299 clk_writel(0xbffffff9ul, CLK_OUT_ENB);
2300 clk_writel(0xfefffff7ul, CLK_OUT_ENB + 4);
2301 clk_writel(0x77f01bfful, CLK_OUT_ENB + 8);
2302 wmb();
2303
2304 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
2305 off += 4) {
2306 if (off == PERIPH_CLK_SOURCE_EMC)
2307 continue;
2308 clk_writel(*ctx++, off);
2309 }
2310 wmb();
2311
2312 off = RST_DEVICES;
2313 for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
2314 clk_writel(*ctx++, off);
2315 wmb();
2316
2317 off = CLK_OUT_ENB;
2318 for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
2319 clk_writel(*ctx++, off);
2320 wmb();
2321
2322 clk_writel(*ctx++, MISC_CLK_ENB);
2323 clk_writel(*ctx++, CLK_MASK_ARM);
2324}
2325#endif