Merge tag 'v3.8-rc1' into staging/for_v3.9
[deliverable/linux.git] / arch / arm / mach-tegra / tegra20_clocks.c
CommitLineData
d8611961 1/*
92fe58f0 2 * arch/arm/mach-tegra/tegra20_clocks.c
d8611961
CC
3 *
4 * Copyright (C) 2010 Google, Inc.
92fe58f0 5 * Copyright (c) 2010-2012 NVIDIA CORPORATION. All rights reserved.
d8611961
CC
6 *
7 * Author:
8 * Colin Cross <ccross@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/list.h>
24#include <linux/spinlock.h>
25#include <linux/delay.h>
26#include <linux/io.h>
6d803ba7 27#include <linux/clkdev.h>
4729fd7a 28#include <linux/clk.h>
d8611961 29
d8611961 30#include "clock.h"
71fc84cc 31#include "fuse.h"
2be39c07 32#include "iomap.h"
6d296828 33#include "tegra2_emc.h"
dab403ef 34#include "tegra_cpu_car.h"
d8611961
CC
35
36#define RST_DEVICES 0x004
37#define RST_DEVICES_SET 0x300
38#define RST_DEVICES_CLR 0x304
71fc84cc 39#define RST_DEVICES_NUM 3
d8611961
CC
40
41#define CLK_OUT_ENB 0x010
42#define CLK_OUT_ENB_SET 0x320
43#define CLK_OUT_ENB_CLR 0x324
71fc84cc
CC
44#define CLK_OUT_ENB_NUM 3
45
46#define CLK_MASK_ARM 0x44
47#define MISC_CLK_ENB 0x48
d8611961
CC
48
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)
cea62c87 55#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
d8611961
CC
56
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
71fc84cc
CC
64#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
d8611961
CC
70#define PERIPH_CLK_SOURCE_MASK (3<<30)
71#define PERIPH_CLK_SOURCE_SHIFT 30
bb1dccfc
SQ
72#define PERIPH_CLK_SOURCE_PWM_MASK (7<<28)
73#define PERIPH_CLK_SOURCE_PWM_SHIFT 28
d8611961 74#define PERIPH_CLK_SOURCE_ENABLE (1<<28)
71fc84cc
CC
75#define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF
76#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF
d8611961
CC
77#define PERIPH_CLK_SOURCE_DIV_SHIFT 0
78
9743b389
CC
79#define SDMMC_CLK_INT_FB_SEL (1 << 23)
80#define SDMMC_CLK_INT_FB_DLY_SHIFT 16
81#define SDMMC_CLK_INT_FB_DLY_MASK (0xF << SDMMC_CLK_INT_FB_DLY_SHIFT)
82
d8611961
CC
83#define PLL_BASE 0x0
84#define PLL_BASE_BYPASS (1<<31)
85#define PLL_BASE_ENABLE (1<<30)
86#define PLL_BASE_REF_ENABLE (1<<29)
87#define PLL_BASE_OVERRIDE (1<<28)
d8611961
CC
88#define PLL_BASE_DIVP_MASK (0x7<<20)
89#define PLL_BASE_DIVP_SHIFT 20
90#define PLL_BASE_DIVN_MASK (0x3FF<<8)
91#define PLL_BASE_DIVN_SHIFT 8
92#define PLL_BASE_DIVM_MASK (0x1F)
93#define PLL_BASE_DIVM_SHIFT 0
94
95#define PLL_OUT_RATIO_MASK (0xFF<<8)
96#define PLL_OUT_RATIO_SHIFT 8
97#define PLL_OUT_OVERRIDE (1<<2)
98#define PLL_OUT_CLKEN (1<<1)
99#define PLL_OUT_RESET_DISABLE (1<<0)
100
92fe58f0 101#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
71fc84cc 102
d8611961 103#define PLL_MISC_DCCON_SHIFT 20
d8611961
CC
104#define PLL_MISC_CPCON_SHIFT 8
105#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT)
106#define PLL_MISC_LFCON_SHIFT 4
107#define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT)
108#define PLL_MISC_VCOCON_SHIFT 0
109#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT)
110
71fc84cc
CC
111#define PLLU_BASE_POST_DIV (1<<20)
112
d8611961
CC
113#define PLLD_MISC_CLKENABLE (1<<30)
114#define PLLD_MISC_DIV_RST (1<<23)
115#define PLLD_MISC_DCCON_SHIFT 12
116
8d685bc5
MR
117#define PLLE_MISC_READY (1 << 15)
118
f1519611
CC
119#define PERIPH_CLK_TO_ENB_REG(c) ((c->u.periph.clk_num / 32) * 4)
120#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->u.periph.clk_num / 32) * 8)
121#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->u.periph.clk_num % 32))
d8611961
CC
122
123#define SUPER_CLK_MUX 0x00
124#define SUPER_STATE_SHIFT 28
125#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT)
126#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT)
127#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT)
128#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT)
129#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT)
130#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT)
131#define SUPER_SOURCE_MASK 0xF
132#define SUPER_FIQ_SOURCE_SHIFT 12
133#define SUPER_IRQ_SOURCE_SHIFT 8
134#define SUPER_RUN_SOURCE_SHIFT 4
135#define SUPER_IDLE_SOURCE_SHIFT 0
136
137#define SUPER_CLK_DIVIDER 0x04
138
139#define BUS_CLK_DISABLE (1<<3)
140#define BUS_CLK_DIV_MASK 0x3
141
cea62c87
CC
142#define PMC_CTRL 0x0
143 #define PMC_CTRL_BLINK_ENB (1 << 7)
144
145#define PMC_DPD_PADS_ORIDE 0x1c
146 #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20)
147
148#define PMC_BLINK_TIMER_DATA_ON_SHIFT 0
149#define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff
150#define PMC_BLINK_TIMER_ENB (1 << 15)
151#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
152#define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff
153
dab403ef
JL
154/* Tegra CPU clock and reset control regs */
155#define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c
156#define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340
157#define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR 0x344
158
159#define CPU_CLOCK(cpu) (0x1 << (8 + cpu))
160#define CPU_RESET(cpu) (0x1111ul << (cpu))
161
d8611961 162static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
cea62c87 163static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
d8611961 164
4729fd7a
CC
165/*
166 * Some clocks share a register with other clocks. Any clock op that
167 * non-atomically modifies a register used by another clock must lock
168 * clock_register_lock first.
169 */
170static DEFINE_SPINLOCK(clock_register_lock);
171
78f379b5
CC
172/*
173 * Some peripheral clocks share an enable bit, so refcount the enable bits
174 * in registers CLK_ENABLE_L, CLK_ENABLE_H, and CLK_ENABLE_U
175 */
176static int tegra_periph_clk_enable_refcount[3 * 32];
177
d8611961 178#define clk_writel(value, reg) \
d395935f 179 __raw_writel(value, reg_clk_base + (reg))
d8611961 180#define clk_readl(reg) \
d395935f 181 __raw_readl(reg_clk_base + (reg))
cea62c87 182#define pmc_writel(value, reg) \
d395935f 183 __raw_writel(value, reg_pmc_base + (reg))
cea62c87 184#define pmc_readl(reg) \
d395935f 185 __raw_readl(reg_pmc_base + (reg))
d8611961 186
8e4fab2c 187static unsigned long clk_measure_input_freq(void)
d8611961
CC
188{
189 u32 clock_autodetect;
190 clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
191 do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
192 clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
193 if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
194 return 12000000;
195 } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
196 return 13000000;
197 } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
198 return 19200000;
199 } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
200 return 26000000;
201 } else {
92fe58f0
PG
202 pr_err("%s: Unexpected clock autodetect value %d",
203 __func__, clock_autodetect);
d8611961
CC
204 BUG();
205 return 0;
206 }
207}
208
71fc84cc 209static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate)
d8611961 210{
71fc84cc
CC
211 s64 divider_u71 = parent_rate * 2;
212 divider_u71 += rate - 1;
213 do_div(divider_u71, rate);
d8611961 214
71fc84cc
CC
215 if (divider_u71 - 2 < 0)
216 return 0;
d8611961 217
71fc84cc 218 if (divider_u71 - 2 > 255)
d8611961
CC
219 return -EINVAL;
220
221 return divider_u71 - 2;
222}
223
71fc84cc 224static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
d8611961 225{
71fc84cc 226 s64 divider_u16;
d8611961 227
71fc84cc
CC
228 divider_u16 = parent_rate;
229 divider_u16 += rate - 1;
230 do_div(divider_u16, rate);
d8611961 231
71fc84cc
CC
232 if (divider_u16 - 1 < 0)
233 return 0;
234
eb70e1bd 235 if (divider_u16 - 1 > 0xFFFF)
71fc84cc
CC
236 return -EINVAL;
237
238 return divider_u16 - 1;
239}
d8611961 240
b78c030c
JL
241static unsigned long tegra_clk_fixed_recalc_rate(struct clk_hw *hw,
242 unsigned long parent_rate)
243{
244 return to_clk_tegra(hw)->fixed_rate;
245}
246
247struct clk_ops tegra_clk_32k_ops = {
248 .recalc_rate = tegra_clk_fixed_recalc_rate,
249};
250
d8611961 251/* clk_m functions */
92fe58f0
PG
252static unsigned long tegra20_clk_m_recalc_rate(struct clk_hw *hw,
253 unsigned long prate)
d8611961 254{
92fe58f0
PG
255 if (!to_clk_tegra(hw)->fixed_rate)
256 to_clk_tegra(hw)->fixed_rate = clk_measure_input_freq();
257 return to_clk_tegra(hw)->fixed_rate;
258}
259
260static void tegra20_clk_m_init(struct clk_hw *hw)
261{
262 struct clk_tegra *c = to_clk_tegra(hw);
263 u32 osc_ctrl = clk_readl(OSC_CTRL);
264 u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK;
d8611961 265
92fe58f0 266 switch (c->fixed_rate) {
d8611961
CC
267 case 12000000:
268 auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
269 break;
270 case 13000000:
271 auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
272 break;
273 case 19200000:
274 auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
275 break;
276 case 26000000:
277 auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
278 break;
279 default:
d8611961
CC
280 BUG();
281 }
282 clk_writel(auto_clock_control, OSC_CTRL);
d8611961
CC
283}
284
86edb87a 285struct clk_ops tegra_clk_m_ops = {
92fe58f0
PG
286 .init = tegra20_clk_m_init,
287 .recalc_rate = tegra20_clk_m_recalc_rate,
d8611961
CC
288};
289
290/* super clock functions */
291/* "super clocks" on tegra have two-stage muxes and a clock skipping
292 * super divider. We will ignore the clock skipping divider, since we
293 * can't lower the voltage when using the clock skip, but we can if we
294 * lower the PLL frequency.
295 */
92fe58f0 296static int tegra20_super_clk_is_enabled(struct clk_hw *hw)
d8611961 297{
92fe58f0 298 struct clk_tegra *c = to_clk_tegra(hw);
d8611961 299 u32 val;
92fe58f0 300
d8611961 301 val = clk_readl(c->reg + SUPER_CLK_MUX);
d8611961
CC
302 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
303 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
92fe58f0
PG
304 c->state = ON;
305 return c->state;
d8611961
CC
306}
307
92fe58f0 308static int tegra20_super_clk_enable(struct clk_hw *hw)
d8611961 309{
92fe58f0 310 struct clk_tegra *c = to_clk_tegra(hw);
d8611961
CC
311 clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
312 return 0;
313}
314
92fe58f0 315static void tegra20_super_clk_disable(struct clk_hw *hw)
d8611961 316{
92fe58f0 317 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
d8611961
CC
318
319 /* oops - don't disable the CPU clock! */
320 BUG();
321}
322
92fe58f0 323static u8 tegra20_super_clk_get_parent(struct clk_hw *hw)
d8611961 324{
92fe58f0
PG
325 struct clk_tegra *c = to_clk_tegra(hw);
326 int val = clk_readl(c->reg + SUPER_CLK_MUX);
327 int source;
d8611961 328 int shift;
71fc84cc 329
d8611961
CC
330 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
331 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
332 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
333 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
92fe58f0
PG
334 source = (val >> shift) & SUPER_SOURCE_MASK;
335 return source;
336}
71fc84cc 337
92fe58f0
PG
338static int tegra20_super_clk_set_parent(struct clk_hw *hw, u8 index)
339{
340 struct clk_tegra *c = to_clk_tegra(hw);
341 u32 val = clk_readl(c->reg + SUPER_CLK_MUX);
342 int shift;
71fc84cc 343
92fe58f0
PG
344 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
345 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
346 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
347 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
348 val &= ~(SUPER_SOURCE_MASK << shift);
349 val |= index << shift;
71fc84cc 350
92fe58f0 351 clk_writel(val, c->reg);
71fc84cc 352
92fe58f0 353 return 0;
d8611961
CC
354}
355
92fe58f0
PG
356/* FIX ME: Need to switch parents to change the source PLL rate */
357static unsigned long tegra20_super_clk_recalc_rate(struct clk_hw *hw,
358 unsigned long prate)
9c7dc562 359{
92fe58f0 360 return prate;
9c7dc562
CC
361}
362
92fe58f0
PG
363static long tegra20_super_clk_round_rate(struct clk_hw *hw, unsigned long rate,
364 unsigned long *prate)
71fc84cc 365{
92fe58f0 366 return *prate;
71fc84cc
CC
367}
368
92fe58f0
PG
369static int tegra20_super_clk_set_rate(struct clk_hw *hw, unsigned long rate,
370 unsigned long parent_rate)
71fc84cc
CC
371{
372 return 0;
373}
374
92fe58f0
PG
375struct clk_ops tegra_super_ops = {
376 .is_enabled = tegra20_super_clk_is_enabled,
377 .enable = tegra20_super_clk_enable,
378 .disable = tegra20_super_clk_disable,
379 .set_parent = tegra20_super_clk_set_parent,
380 .get_parent = tegra20_super_clk_get_parent,
381 .set_rate = tegra20_super_clk_set_rate,
382 .round_rate = tegra20_super_clk_round_rate,
383 .recalc_rate = tegra20_super_clk_recalc_rate,
384};
71fc84cc 385
b4350f40
PG
386static unsigned long tegra20_twd_clk_recalc_rate(struct clk_hw *hw,
387 unsigned long parent_rate)
388{
389 struct clk_tegra *c = to_clk_tegra(hw);
390 u64 rate = parent_rate;
391
392 if (c->mul != 0 && c->div != 0) {
393 rate *= c->mul;
394 rate += c->div - 1; /* round up */
395 do_div(rate, c->div);
396 }
397
398 return rate;
399}
400
401struct clk_ops tegra_twd_ops = {
402 .recalc_rate = tegra20_twd_clk_recalc_rate,
403};
404
92fe58f0 405static u8 tegra20_cop_clk_get_parent(struct clk_hw *hw)
71fc84cc 406{
92fe58f0 407 return 0;
71fc84cc
CC
408}
409
92fe58f0
PG
410struct clk_ops tegra_cop_ops = {
411 .get_parent = tegra20_cop_clk_get_parent,
d8611961
CC
412};
413
9c7dc562
CC
414/* virtual cop clock functions. Used to acquire the fake 'cop' clock to
415 * reset the COP block (i.e. AVP) */
92fe58f0 416void tegra2_cop_clk_reset(struct clk_hw *hw, bool assert)
9c7dc562
CC
417{
418 unsigned long reg = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
419
420 pr_debug("%s %s\n", __func__, assert ? "assert" : "deassert");
421 clk_writel(1 << 1, reg);
422}
423
d8611961 424/* bus clock functions */
92fe58f0 425static int tegra20_bus_clk_is_enabled(struct clk_hw *hw)
d8611961 426{
92fe58f0 427 struct clk_tegra *c = to_clk_tegra(hw);
d8611961 428 u32 val = clk_readl(c->reg);
92fe58f0 429
d8611961 430 c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
92fe58f0 431 return c->state;
d8611961
CC
432}
433
92fe58f0 434static int tegra20_bus_clk_enable(struct clk_hw *hw)
d8611961 435{
92fe58f0 436 struct clk_tegra *c = to_clk_tegra(hw);
4729fd7a 437 unsigned long flags;
92fe58f0 438 u32 val;
4729fd7a
CC
439
440 spin_lock_irqsave(&clock_register_lock, flags);
441
442 val = clk_readl(c->reg);
d8611961
CC
443 val &= ~(BUS_CLK_DISABLE << c->reg_shift);
444 clk_writel(val, c->reg);
4729fd7a
CC
445
446 spin_unlock_irqrestore(&clock_register_lock, flags);
447
d8611961
CC
448 return 0;
449}
450
92fe58f0 451static void tegra20_bus_clk_disable(struct clk_hw *hw)
d8611961 452{
92fe58f0 453 struct clk_tegra *c = to_clk_tegra(hw);
4729fd7a 454 unsigned long flags;
92fe58f0 455 u32 val;
4729fd7a
CC
456
457 spin_lock_irqsave(&clock_register_lock, flags);
458
459 val = clk_readl(c->reg);
d8611961
CC
460 val |= BUS_CLK_DISABLE << c->reg_shift;
461 clk_writel(val, c->reg);
4729fd7a
CC
462
463 spin_unlock_irqrestore(&clock_register_lock, flags);
d8611961
CC
464}
465
92fe58f0
PG
466static unsigned long tegra20_bus_clk_recalc_rate(struct clk_hw *hw,
467 unsigned long prate)
d8611961 468{
92fe58f0
PG
469 struct clk_tegra *c = to_clk_tegra(hw);
470 u32 val = clk_readl(c->reg);
471 u64 rate = prate;
472
473 c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
474 c->mul = 1;
475
476 if (c->mul != 0 && c->div != 0) {
477 rate *= c->mul;
478 rate += c->div - 1; /* round up */
479 do_div(rate, c->div);
480 }
481 return rate;
482}
483
484static int tegra20_bus_clk_set_rate(struct clk_hw *hw, unsigned long rate,
485 unsigned long parent_rate)
486{
487 struct clk_tegra *c = to_clk_tegra(hw);
4729fd7a 488 int ret = -EINVAL;
92fe58f0
PG
489 unsigned long flags;
490 u32 val;
d8611961 491 int i;
4729fd7a
CC
492
493 spin_lock_irqsave(&clock_register_lock, flags);
494
495 val = clk_readl(c->reg);
d8611961
CC
496 for (i = 1; i <= 4; i++) {
497 if (rate == parent_rate / i) {
498 val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
499 val |= (i - 1) << c->reg_shift;
500 clk_writel(val, c->reg);
501 c->div = i;
502 c->mul = 1;
4729fd7a
CC
503 ret = 0;
504 break;
d8611961
CC
505 }
506 }
4729fd7a
CC
507
508 spin_unlock_irqrestore(&clock_register_lock, flags);
509
510 return ret;
d8611961
CC
511}
512
92fe58f0
PG
513static long tegra20_bus_clk_round_rate(struct clk_hw *hw, unsigned long rate,
514 unsigned long *prate)
515{
516 unsigned long parent_rate = *prate;
517 s64 divider;
518
519 if (rate >= parent_rate)
520 return rate;
521
522 divider = parent_rate;
523 divider += rate - 1;
524 do_div(divider, rate);
525
526 if (divider < 0)
527 return divider;
528
529 if (divider > 4)
530 divider = 4;
531 do_div(parent_rate, divider);
532
533 return parent_rate;
534}
535
86edb87a 536struct clk_ops tegra_bus_ops = {
92fe58f0
PG
537 .is_enabled = tegra20_bus_clk_is_enabled,
538 .enable = tegra20_bus_clk_enable,
539 .disable = tegra20_bus_clk_disable,
540 .set_rate = tegra20_bus_clk_set_rate,
541 .round_rate = tegra20_bus_clk_round_rate,
542 .recalc_rate = tegra20_bus_clk_recalc_rate,
d8611961
CC
543};
544
cea62c87 545/* Blink output functions */
92fe58f0 546static int tegra20_blink_clk_is_enabled(struct clk_hw *hw)
cea62c87 547{
92fe58f0 548 struct clk_tegra *c = to_clk_tegra(hw);
cea62c87
CC
549 u32 val;
550
551 val = pmc_readl(PMC_CTRL);
552 c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
92fe58f0
PG
553 return c->state;
554}
555
556static unsigned long tegra20_blink_clk_recalc_rate(struct clk_hw *hw,
557 unsigned long prate)
558{
559 struct clk_tegra *c = to_clk_tegra(hw);
560 u64 rate = prate;
561 u32 val;
562
cea62c87
CC
563 c->mul = 1;
564 val = pmc_readl(c->reg);
565
566 if (val & PMC_BLINK_TIMER_ENB) {
567 unsigned int on_off;
568
569 on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
570 PMC_BLINK_TIMER_DATA_ON_MASK;
571 val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
572 val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
573 on_off += val;
574 /* each tick in the blink timer is 4 32KHz clocks */
575 c->div = on_off * 4;
576 } else {
577 c->div = 1;
578 }
92fe58f0
PG
579
580 if (c->mul != 0 && c->div != 0) {
581 rate *= c->mul;
582 rate += c->div - 1; /* round up */
583 do_div(rate, c->div);
584 }
585 return rate;
cea62c87
CC
586}
587
92fe58f0 588static int tegra20_blink_clk_enable(struct clk_hw *hw)
cea62c87
CC
589{
590 u32 val;
591
592 val = pmc_readl(PMC_DPD_PADS_ORIDE);
593 pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
594
595 val = pmc_readl(PMC_CTRL);
596 pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
597
598 return 0;
599}
600
92fe58f0 601static void tegra20_blink_clk_disable(struct clk_hw *hw)
cea62c87
CC
602{
603 u32 val;
604
605 val = pmc_readl(PMC_CTRL);
606 pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
607
608 val = pmc_readl(PMC_DPD_PADS_ORIDE);
609 pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
610}
611
92fe58f0
PG
612static int tegra20_blink_clk_set_rate(struct clk_hw *hw, unsigned long rate,
613 unsigned long parent_rate)
cea62c87 614{
92fe58f0
PG
615 struct clk_tegra *c = to_clk_tegra(hw);
616
4729fd7a 617 if (rate >= parent_rate) {
cea62c87
CC
618 c->div = 1;
619 pmc_writel(0, c->reg);
620 } else {
621 unsigned int on_off;
622 u32 val;
623
4729fd7a 624 on_off = DIV_ROUND_UP(parent_rate / 8, rate);
cea62c87
CC
625 c->div = on_off * 8;
626
627 val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
628 PMC_BLINK_TIMER_DATA_ON_SHIFT;
629 on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
630 on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
631 val |= on_off;
632 val |= PMC_BLINK_TIMER_ENB;
633 pmc_writel(val, c->reg);
634 }
635
636 return 0;
637}
638
92fe58f0
PG
639static long tegra20_blink_clk_round_rate(struct clk_hw *hw, unsigned long rate,
640 unsigned long *prate)
641{
642 int div;
643 int mul;
644 long round_rate = *prate;
645
646 mul = 1;
647
648 if (rate >= *prate) {
649 div = 1;
650 } else {
651 div = DIV_ROUND_UP(*prate / 8, rate);
652 div *= 8;
653 }
654
655 round_rate *= mul;
656 round_rate += div - 1;
657 do_div(round_rate, div);
658
659 return round_rate;
660}
661
86edb87a 662struct clk_ops tegra_blink_clk_ops = {
92fe58f0
PG
663 .is_enabled = tegra20_blink_clk_is_enabled,
664 .enable = tegra20_blink_clk_enable,
665 .disable = tegra20_blink_clk_disable,
666 .set_rate = tegra20_blink_clk_set_rate,
667 .round_rate = tegra20_blink_clk_round_rate,
668 .recalc_rate = tegra20_blink_clk_recalc_rate,
cea62c87
CC
669};
670
d8611961 671/* PLL Functions */
92fe58f0 672static int tegra20_pll_clk_wait_for_lock(struct clk_tegra *c)
d8611961 673{
f1519611 674 udelay(c->u.pll.lock_delay);
d8611961
CC
675 return 0;
676}
677
92fe58f0 678static int tegra20_pll_clk_is_enabled(struct clk_hw *hw)
d8611961 679{
92fe58f0 680 struct clk_tegra *c = to_clk_tegra(hw);
d8611961
CC
681 u32 val = clk_readl(c->reg + PLL_BASE);
682
683 c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
92fe58f0
PG
684 return c->state;
685}
686
687static unsigned long tegra20_pll_clk_recalc_rate(struct clk_hw *hw,
688 unsigned long prate)
689{
690 struct clk_tegra *c = to_clk_tegra(hw);
691 u32 val = clk_readl(c->reg + PLL_BASE);
692 u64 rate = prate;
d8611961
CC
693
694 if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
92fe58f0
PG
695 const struct clk_pll_freq_table *sel;
696 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
697 if (sel->input_rate == prate &&
698 sel->output_rate == c->u.pll.fixed_rate) {
699 c->mul = sel->n;
700 c->div = sel->m * sel->p;
701 break;
702 }
703 }
704 pr_err("Clock %s has unknown fixed frequency\n",
705 __clk_get_name(hw->clk));
706 BUG();
d8611961 707 } else if (val & PLL_BASE_BYPASS) {
71fc84cc
CC
708 c->mul = 1;
709 c->div = 1;
d8611961 710 } else {
71fc84cc
CC
711 c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
712 c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
713 if (c->flags & PLLU)
714 c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
715 else
716 c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
d8611961 717 }
92fe58f0
PG
718
719 if (c->mul != 0 && c->div != 0) {
720 rate *= c->mul;
721 rate += c->div - 1; /* round up */
722 do_div(rate, c->div);
723 }
724 return rate;
d8611961
CC
725}
726
92fe58f0 727static int tegra20_pll_clk_enable(struct clk_hw *hw)
d8611961 728{
92fe58f0 729 struct clk_tegra *c = to_clk_tegra(hw);
d8611961 730 u32 val;
92fe58f0 731 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
d8611961
CC
732
733 val = clk_readl(c->reg + PLL_BASE);
734 val &= ~PLL_BASE_BYPASS;
735 val |= PLL_BASE_ENABLE;
736 clk_writel(val, c->reg + PLL_BASE);
737
92fe58f0 738 tegra20_pll_clk_wait_for_lock(c);
d8611961
CC
739
740 return 0;
741}
742
92fe58f0 743static void tegra20_pll_clk_disable(struct clk_hw *hw)
d8611961 744{
92fe58f0 745 struct clk_tegra *c = to_clk_tegra(hw);
d8611961 746 u32 val;
92fe58f0 747 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
d8611961
CC
748
749 val = clk_readl(c->reg);
750 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
751 clk_writel(val, c->reg);
752}
753
92fe58f0
PG
754static int tegra20_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
755 unsigned long parent_rate)
d8611961 756{
92fe58f0
PG
757 struct clk_tegra *c = to_clk_tegra(hw);
758 unsigned long input_rate = parent_rate;
f1519611 759 const struct clk_pll_freq_table *sel;
92fe58f0 760 u32 val;
d8611961 761
92fe58f0
PG
762 pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
763
764 if (c->flags & PLL_FIXED) {
765 int ret = 0;
766 if (rate != c->u.pll.fixed_rate) {
767 pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
768 __func__, __clk_get_name(hw->clk),
769 c->u.pll.fixed_rate, rate);
770 ret = -EINVAL;
771 }
772 return ret;
773 }
d8611961 774
f1519611 775 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
d8611961 776 if (sel->input_rate == input_rate && sel->output_rate == rate) {
71fc84cc
CC
777 c->mul = sel->n;
778 c->div = sel->m * sel->p;
d8611961
CC
779
780 val = clk_readl(c->reg + PLL_BASE);
781 if (c->flags & PLL_FIXED)
782 val |= PLL_BASE_OVERRIDE;
783 val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK |
784 PLL_BASE_DIVM_MASK);
71fc84cc
CC
785 val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
786 (sel->n << PLL_BASE_DIVN_SHIFT);
787 BUG_ON(sel->p < 1 || sel->p > 2);
788 if (c->flags & PLLU) {
789 if (sel->p == 1)
790 val |= PLLU_BASE_POST_DIV;
791 } else {
792 if (sel->p == 2)
793 val |= 1 << PLL_BASE_DIVP_SHIFT;
794 }
d8611961
CC
795 clk_writel(val, c->reg + PLL_BASE);
796
797 if (c->flags & PLL_HAS_CPCON) {
71fc84cc
CC
798 val = clk_readl(c->reg + PLL_MISC(c));
799 val &= ~PLL_MISC_CPCON_MASK;
800 val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
d8611961
CC
801 clk_writel(val, c->reg + PLL_MISC(c));
802 }
803
804 if (c->state == ON)
92fe58f0 805 tegra20_pll_clk_enable(hw);
d8611961
CC
806 return 0;
807 }
808 }
809 return -EINVAL;
810}
811
92fe58f0
PG
812static long tegra20_pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
813 unsigned long *prate)
814{
815 struct clk_tegra *c = to_clk_tegra(hw);
816 const struct clk_pll_freq_table *sel;
817 unsigned long input_rate = *prate;
7a74a443 818 u64 output_rate = *prate;
92fe58f0
PG
819 int mul;
820 int div;
821
822 if (c->flags & PLL_FIXED)
823 return c->u.pll.fixed_rate;
824
825 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++)
826 if (sel->input_rate == input_rate && sel->output_rate == rate) {
827 mul = sel->n;
828 div = sel->m * sel->p;
829 break;
830 }
831
832 if (sel->input_rate == 0)
833 return -EINVAL;
834
835 output_rate *= mul;
836 output_rate += div - 1; /* round up */
837 do_div(output_rate, div);
838
839 return output_rate;
840}
841
86edb87a 842struct clk_ops tegra_pll_ops = {
92fe58f0
PG
843 .is_enabled = tegra20_pll_clk_is_enabled,
844 .enable = tegra20_pll_clk_enable,
845 .disable = tegra20_pll_clk_disable,
846 .set_rate = tegra20_pll_clk_set_rate,
847 .recalc_rate = tegra20_pll_clk_recalc_rate,
848 .round_rate = tegra20_pll_clk_round_rate,
71fc84cc
CC
849};
850
92fe58f0 851static void tegra20_pllx_clk_init(struct clk_hw *hw)
71fc84cc 852{
92fe58f0 853 struct clk_tegra *c = to_clk_tegra(hw);
71fc84cc 854
9a1086da 855 if (tegra_sku_id == 7)
71fc84cc
CC
856 c->max_rate = 750000000;
857}
858
86edb87a 859struct clk_ops tegra_pllx_ops = {
92fe58f0
PG
860 .init = tegra20_pllx_clk_init,
861 .is_enabled = tegra20_pll_clk_is_enabled,
862 .enable = tegra20_pll_clk_enable,
863 .disable = tegra20_pll_clk_disable,
864 .set_rate = tegra20_pll_clk_set_rate,
865 .recalc_rate = tegra20_pll_clk_recalc_rate,
866 .round_rate = tegra20_pll_clk_round_rate,
d8611961
CC
867};
868
92fe58f0 869static int tegra20_plle_clk_enable(struct clk_hw *hw)
8d685bc5 870{
92fe58f0 871 struct clk_tegra *c = to_clk_tegra(hw);
8d685bc5
MR
872 u32 val;
873
92fe58f0 874 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
8d685bc5
MR
875
876 mdelay(1);
877
878 val = clk_readl(c->reg + PLL_BASE);
879 if (!(val & PLLE_MISC_READY))
880 return -EBUSY;
881
882 val = clk_readl(c->reg + PLL_BASE);
883 val |= PLL_BASE_ENABLE | PLL_BASE_BYPASS;
884 clk_writel(val, c->reg + PLL_BASE);
885
886 return 0;
887}
888
86edb87a 889struct clk_ops tegra_plle_ops = {
92fe58f0
PG
890 .is_enabled = tegra20_pll_clk_is_enabled,
891 .enable = tegra20_plle_clk_enable,
892 .set_rate = tegra20_pll_clk_set_rate,
893 .recalc_rate = tegra20_pll_clk_recalc_rate,
894 .round_rate = tegra20_pll_clk_round_rate,
8d685bc5
MR
895};
896
d8611961 897/* Clock divider ops */
92fe58f0 898static int tegra20_pll_div_clk_is_enabled(struct clk_hw *hw)
d8611961 899{
92fe58f0 900 struct clk_tegra *c = to_clk_tegra(hw);
d8611961 901 u32 val = clk_readl(c->reg);
92fe58f0 902
d8611961
CC
903 val >>= c->reg_shift;
904 c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
905 if (!(val & PLL_OUT_RESET_DISABLE))
906 c->state = OFF;
92fe58f0
PG
907 return c->state;
908}
909
910static unsigned long tegra20_pll_div_clk_recalc_rate(struct clk_hw *hw,
911 unsigned long prate)
912{
913 struct clk_tegra *c = to_clk_tegra(hw);
914 u64 rate = prate;
915 u32 val = clk_readl(c->reg);
916 u32 divu71;
917
918 val >>= c->reg_shift;
d8611961
CC
919
920 if (c->flags & DIV_U71) {
921 divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
922 c->div = (divu71 + 2);
923 c->mul = 2;
924 } else if (c->flags & DIV_2) {
925 c->div = 2;
926 c->mul = 1;
927 } else {
928 c->div = 1;
929 c->mul = 1;
930 }
92fe58f0
PG
931
932 rate *= c->mul;
933 rate += c->div - 1; /* round up */
934 do_div(rate, c->div);
935
936 return rate;
d8611961
CC
937}
938
92fe58f0 939static int tegra20_pll_div_clk_enable(struct clk_hw *hw)
d8611961 940{
92fe58f0 941 struct clk_tegra *c = to_clk_tegra(hw);
4729fd7a 942 unsigned long flags;
92fe58f0
PG
943 u32 new_val;
944 u32 val;
945
946 pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
d8611961 947
d8611961 948 if (c->flags & DIV_U71) {
4729fd7a 949 spin_lock_irqsave(&clock_register_lock, flags);
d8611961
CC
950 val = clk_readl(c->reg);
951 new_val = val >> c->reg_shift;
952 new_val &= 0xFFFF;
953
954 new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
955
956 val &= ~(0xFFFF << c->reg_shift);
957 val |= new_val << c->reg_shift;
958 clk_writel(val, c->reg);
4729fd7a 959 spin_unlock_irqrestore(&clock_register_lock, flags);
d8611961
CC
960 return 0;
961 } else if (c->flags & DIV_2) {
962 BUG_ON(!(c->flags & PLLD));
4729fd7a 963 spin_lock_irqsave(&clock_register_lock, flags);
d8611961
CC
964 val = clk_readl(c->reg);
965 val &= ~PLLD_MISC_DIV_RST;
966 clk_writel(val, c->reg);
4729fd7a 967 spin_unlock_irqrestore(&clock_register_lock, flags);
d8611961
CC
968 return 0;
969 }
970 return -EINVAL;
971}
972
92fe58f0 973static void tegra20_pll_div_clk_disable(struct clk_hw *hw)
d8611961 974{
92fe58f0 975 struct clk_tegra *c = to_clk_tegra(hw);
4729fd7a 976 unsigned long flags;
92fe58f0
PG
977 u32 new_val;
978 u32 val;
979
980 pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
d8611961 981
d8611961 982 if (c->flags & DIV_U71) {
4729fd7a 983 spin_lock_irqsave(&clock_register_lock, flags);
d8611961
CC
984 val = clk_readl(c->reg);
985 new_val = val >> c->reg_shift;
986 new_val &= 0xFFFF;
987
988 new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
989
990 val &= ~(0xFFFF << c->reg_shift);
991 val |= new_val << c->reg_shift;
992 clk_writel(val, c->reg);
4729fd7a 993 spin_unlock_irqrestore(&clock_register_lock, flags);
d8611961
CC
994 } else if (c->flags & DIV_2) {
995 BUG_ON(!(c->flags & PLLD));
4729fd7a 996 spin_lock_irqsave(&clock_register_lock, flags);
d8611961
CC
997 val = clk_readl(c->reg);
998 val |= PLLD_MISC_DIV_RST;
999 clk_writel(val, c->reg);
4729fd7a 1000 spin_unlock_irqrestore(&clock_register_lock, flags);
d8611961
CC
1001 }
1002}
1003
92fe58f0
PG
1004static int tegra20_pll_div_clk_set_rate(struct clk_hw *hw, unsigned long rate,
1005 unsigned long parent_rate)
d8611961 1006{
92fe58f0 1007 struct clk_tegra *c = to_clk_tegra(hw);
4729fd7a 1008 unsigned long flags;
92fe58f0
PG
1009 int divider_u71;
1010 u32 new_val;
1011 u32 val;
1012
1013 pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
4729fd7a 1014
d8611961 1015 if (c->flags & DIV_U71) {
4729fd7a 1016 divider_u71 = clk_div71_get_divider(parent_rate, rate);
d8611961 1017 if (divider_u71 >= 0) {
4729fd7a 1018 spin_lock_irqsave(&clock_register_lock, flags);
d8611961
CC
1019 val = clk_readl(c->reg);
1020 new_val = val >> c->reg_shift;
1021 new_val &= 0xFFFF;
1022 if (c->flags & DIV_U71_FIXED)
1023 new_val |= PLL_OUT_OVERRIDE;
1024 new_val &= ~PLL_OUT_RATIO_MASK;
1025 new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
1026
1027 val &= ~(0xFFFF << c->reg_shift);
1028 val |= new_val << c->reg_shift;
1029 clk_writel(val, c->reg);
1030 c->div = divider_u71 + 2;
1031 c->mul = 2;
4729fd7a 1032 spin_unlock_irqrestore(&clock_register_lock, flags);
d8611961
CC
1033 return 0;
1034 }
1035 } else if (c->flags & DIV_2) {
4729fd7a 1036 if (parent_rate == rate * 2)
d8611961 1037 return 0;
d8611961
CC
1038 }
1039 return -EINVAL;
1040}
1041
92fe58f0
PG
1042static long tegra20_pll_div_clk_round_rate(struct clk_hw *hw, unsigned long rate,
1043 unsigned long *prate)
71fc84cc 1044{
92fe58f0
PG
1045 struct clk_tegra *c = to_clk_tegra(hw);
1046 unsigned long parent_rate = *prate;
71fc84cc 1047 int divider;
92fe58f0
PG
1048
1049 pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
71fc84cc
CC
1050
1051 if (c->flags & DIV_U71) {
4729fd7a 1052 divider = clk_div71_get_divider(parent_rate, rate);
71fc84cc
CC
1053 if (divider < 0)
1054 return divider;
421186e7 1055 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
71fc84cc 1056 } else if (c->flags & DIV_2) {
421186e7 1057 return DIV_ROUND_UP(parent_rate, 2);
71fc84cc
CC
1058 }
1059 return -EINVAL;
1060}
d8611961 1061
86edb87a 1062struct clk_ops tegra_pll_div_ops = {
92fe58f0
PG
1063 .is_enabled = tegra20_pll_div_clk_is_enabled,
1064 .enable = tegra20_pll_div_clk_enable,
1065 .disable = tegra20_pll_div_clk_disable,
1066 .set_rate = tegra20_pll_div_clk_set_rate,
1067 .round_rate = tegra20_pll_div_clk_round_rate,
1068 .recalc_rate = tegra20_pll_div_clk_recalc_rate,
d8611961
CC
1069};
1070
1071/* Periph clk ops */
1072
92fe58f0 1073static int tegra20_periph_clk_is_enabled(struct clk_hw *hw)
d8611961 1074{
92fe58f0 1075 struct clk_tegra *c = to_clk_tegra(hw);
d8611961
CC
1076
1077 c->state = ON;
1be3d053
CC
1078
1079 if (!c->u.periph.clk_num)
92fe58f0 1080 goto out;
1be3d053 1081
d8611961
CC
1082 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1083 PERIPH_CLK_TO_ENB_BIT(c)))
1084 c->state = OFF;
1be3d053 1085
d8611961
CC
1086 if (!(c->flags & PERIPH_NO_RESET))
1087 if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
1088 PERIPH_CLK_TO_ENB_BIT(c))
1089 c->state = OFF;
92fe58f0
PG
1090
1091out:
1092 return c->state;
d8611961
CC
1093}
1094
92fe58f0 1095static int tegra20_periph_clk_enable(struct clk_hw *hw)
d8611961 1096{
92fe58f0 1097 struct clk_tegra *c = to_clk_tegra(hw);
78f379b5 1098 unsigned long flags;
92fe58f0
PG
1099 u32 val;
1100
1101 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
d8611961 1102
1be3d053
CC
1103 if (!c->u.periph.clk_num)
1104 return 0;
1105
92fe58f0
PG
1106 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
1107 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1)
1108 return 0;
78f379b5 1109
92fe58f0 1110 spin_lock_irqsave(&clock_register_lock, flags);
78f379b5 1111
d8611961
CC
1112 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1113 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
1114 if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET))
1115 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1116 RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1117 if (c->flags & PERIPH_EMC_ENB) {
1118 /* The EMC peripheral clock has 2 extra enable bits */
1119 /* FIXME: Do they need to be disabled? */
1120 val = clk_readl(c->reg);
1121 val |= 0x3 << 24;
1122 clk_writel(val, c->reg);
1123 }
78f379b5 1124
78f379b5
CC
1125 spin_unlock_irqrestore(&clock_register_lock, flags);
1126
d8611961
CC
1127 return 0;
1128}
1129
92fe58f0 1130static void tegra20_periph_clk_disable(struct clk_hw *hw)
d8611961 1131{
92fe58f0 1132 struct clk_tegra *c = to_clk_tegra(hw);
78f379b5
CC
1133 unsigned long flags;
1134
92fe58f0 1135 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
d8611961 1136
1be3d053
CC
1137 if (!c->u.periph.clk_num)
1138 return;
1139
92fe58f0 1140 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
78f379b5 1141
92fe58f0
PG
1142 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 0)
1143 return;
78f379b5 1144
92fe58f0
PG
1145 spin_lock_irqsave(&clock_register_lock, flags);
1146
1147 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1148 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
78f379b5
CC
1149
1150 spin_unlock_irqrestore(&clock_register_lock, flags);
d8611961
CC
1151}
1152
92fe58f0 1153void tegra2_periph_clk_reset(struct clk_hw *hw, bool assert)
d8611961 1154{
92fe58f0 1155 struct clk_tegra *c = to_clk_tegra(hw);
2b84cb4f 1156 unsigned long base = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
d8611961 1157
2b84cb4f 1158 pr_debug("%s %s on clock %s\n", __func__,
92fe58f0 1159 assert ? "assert" : "deassert", __clk_get_name(hw->clk));
1be3d053
CC
1160
1161 BUG_ON(!c->u.periph.clk_num);
1162
d8611961
CC
1163 if (!(c->flags & PERIPH_NO_RESET))
1164 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
2b84cb4f 1165 base + PERIPH_CLK_TO_ENB_SET_REG(c));
d8611961
CC
1166}
1167
92fe58f0 1168static int tegra20_periph_clk_set_parent(struct clk_hw *hw, u8 index)
d8611961 1169{
92fe58f0 1170 struct clk_tegra *c = to_clk_tegra(hw);
d8611961 1171 u32 val;
92fe58f0
PG
1172 u32 mask;
1173 u32 shift;
bb1dccfc 1174
92fe58f0 1175 pr_debug("%s: %s %d\n", __func__, __clk_get_name(hw->clk), index);
bb1dccfc
SQ
1176
1177 if (c->flags & MUX_PWM) {
1178 shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
1179 mask = PERIPH_CLK_SOURCE_PWM_MASK;
1180 } else {
1181 shift = PERIPH_CLK_SOURCE_SHIFT;
1182 mask = PERIPH_CLK_SOURCE_MASK;
1183 }
1184
92fe58f0
PG
1185 val = clk_readl(c->reg);
1186 val &= ~mask;
1187 val |= (index) << shift;
71fc84cc 1188
92fe58f0 1189 clk_writel(val, c->reg);
71fc84cc 1190
92fe58f0
PG
1191 return 0;
1192}
71fc84cc 1193
92fe58f0
PG
1194static u8 tegra20_periph_clk_get_parent(struct clk_hw *hw)
1195{
1196 struct clk_tegra *c = to_clk_tegra(hw);
1197 u32 val = clk_readl(c->reg);
1198 u32 mask;
1199 u32 shift;
71fc84cc 1200
92fe58f0
PG
1201 if (c->flags & MUX_PWM) {
1202 shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
1203 mask = PERIPH_CLK_SOURCE_PWM_MASK;
1204 } else {
1205 shift = PERIPH_CLK_SOURCE_SHIFT;
1206 mask = PERIPH_CLK_SOURCE_MASK;
d8611961
CC
1207 }
1208
92fe58f0
PG
1209 if (c->flags & MUX)
1210 return (val & mask) >> shift;
1211 else
1212 return 0;
d8611961
CC
1213}
1214
92fe58f0
PG
1215static unsigned long tegra20_periph_clk_recalc_rate(struct clk_hw *hw,
1216 unsigned long prate)
d8611961 1217{
92fe58f0
PG
1218 struct clk_tegra *c = to_clk_tegra(hw);
1219 unsigned long rate = prate;
1220 u32 val = clk_readl(c->reg);
1221
1222 if (c->flags & DIV_U71) {
1223 u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
1224 c->div = divu71 + 2;
1225 c->mul = 2;
1226 } else if (c->flags & DIV_U16) {
1227 u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
1228 c->div = divu16 + 1;
1229 c->mul = 1;
1230 } else {
1231 c->div = 1;
1232 c->mul = 1;
1233 return rate;
1234 }
1235
1236 if (c->mul != 0 && c->div != 0) {
1237 rate *= c->mul;
1238 rate += c->div - 1; /* round up */
1239 do_div(rate, c->div);
1240 }
1241
1242 return rate;
1243}
1244
1245static int tegra20_periph_clk_set_rate(struct clk_hw *hw, unsigned long rate,
1246 unsigned long parent_rate)
1247{
1248 struct clk_tegra *c = to_clk_tegra(hw);
d8611961 1249 u32 val;
71fc84cc 1250 int divider;
92fe58f0
PG
1251
1252 val = clk_readl(c->reg);
4729fd7a 1253
d8611961 1254 if (c->flags & DIV_U71) {
4729fd7a 1255 divider = clk_div71_get_divider(parent_rate, rate);
92fe58f0 1256
71fc84cc 1257 if (divider >= 0) {
d8611961 1258 val = clk_readl(c->reg);
71fc84cc
CC
1259 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
1260 val |= divider;
d8611961 1261 clk_writel(val, c->reg);
71fc84cc 1262 c->div = divider + 2;
d8611961 1263 c->mul = 2;
d8611961
CC
1264 return 0;
1265 }
71fc84cc 1266 } else if (c->flags & DIV_U16) {
4729fd7a 1267 divider = clk_div16_get_divider(parent_rate, rate);
71fc84cc
CC
1268 if (divider >= 0) {
1269 val = clk_readl(c->reg);
1270 val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
1271 val |= divider;
1272 clk_writel(val, c->reg);
1273 c->div = divider + 1;
1274 c->mul = 1;
1275 return 0;
1276 }
4729fd7a 1277 } else if (parent_rate <= rate) {
71fc84cc
CC
1278 c->div = 1;
1279 c->mul = 1;
1280 return 0;
1281 }
92fe58f0 1282
71fc84cc
CC
1283 return -EINVAL;
1284}
1285
92fe58f0
PG
1286static long tegra20_periph_clk_round_rate(struct clk_hw *hw,
1287 unsigned long rate, unsigned long *prate)
71fc84cc 1288{
92fe58f0
PG
1289 struct clk_tegra *c = to_clk_tegra(hw);
1290 unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
71fc84cc 1291 int divider;
92fe58f0
PG
1292
1293 pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
1294
1295 if (prate)
1296 parent_rate = *prate;
71fc84cc
CC
1297
1298 if (c->flags & DIV_U71) {
4729fd7a 1299 divider = clk_div71_get_divider(parent_rate, rate);
71fc84cc
CC
1300 if (divider < 0)
1301 return divider;
1302
421186e7 1303 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
71fc84cc 1304 } else if (c->flags & DIV_U16) {
4729fd7a 1305 divider = clk_div16_get_divider(parent_rate, rate);
71fc84cc
CC
1306 if (divider < 0)
1307 return divider;
421186e7 1308 return DIV_ROUND_UP(parent_rate, divider + 1);
d8611961
CC
1309 }
1310 return -EINVAL;
1311}
1312
86edb87a 1313struct clk_ops tegra_periph_clk_ops = {
92fe58f0
PG
1314 .is_enabled = tegra20_periph_clk_is_enabled,
1315 .enable = tegra20_periph_clk_enable,
1316 .disable = tegra20_periph_clk_disable,
1317 .set_parent = tegra20_periph_clk_set_parent,
1318 .get_parent = tegra20_periph_clk_get_parent,
1319 .set_rate = tegra20_periph_clk_set_rate,
1320 .round_rate = tegra20_periph_clk_round_rate,
1321 .recalc_rate = tegra20_periph_clk_recalc_rate,
d8611961
CC
1322};
1323
6d296828 1324/* External memory controller clock ops */
92fe58f0 1325static void tegra20_emc_clk_init(struct clk_hw *hw)
6d296828 1326{
92fe58f0
PG
1327 struct clk_tegra *c = to_clk_tegra(hw);
1328 c->max_rate = __clk_get_rate(hw->clk);
6d296828
CC
1329}
1330
92fe58f0
PG
1331static long tegra20_emc_clk_round_rate(struct clk_hw *hw, unsigned long rate,
1332 unsigned long *prate)
6d296828 1333{
92fe58f0 1334 struct clk_tegra *c = to_clk_tegra(hw);
e186ad74
SW
1335 long emc_rate;
1336 long clk_rate;
6d296828 1337
e186ad74
SW
1338 /*
1339 * The slowest entry in the EMC clock table that is at least as
1340 * fast as rate.
1341 */
1342 emc_rate = tegra_emc_round_rate(rate);
1343 if (emc_rate < 0)
6d296828
CC
1344 return c->max_rate;
1345
e186ad74
SW
1346 /*
1347 * The fastest rate the PLL will generate that is at most the
1348 * requested rate.
1349 */
92fe58f0 1350 clk_rate = tegra20_periph_clk_round_rate(hw, emc_rate, NULL);
e186ad74
SW
1351
1352 /*
1353 * If this fails, and emc_rate > clk_rate, it's because the maximum
1354 * rate in the EMC tables is larger than the maximum rate of the EMC
1355 * clock. The EMC clock's max rate is the rate it was running when the
1356 * kernel booted. Such a mismatch is probably due to using the wrong
1357 * BCT, i.e. using a Tegra20 BCT with an EMC table written for Tegra25.
1358 */
1359 WARN_ONCE(emc_rate != clk_rate,
1360 "emc_rate %ld != clk_rate %ld",
1361 emc_rate, clk_rate);
6d296828 1362
e186ad74 1363 return emc_rate;
6d296828
CC
1364}
1365
92fe58f0
PG
1366static int tegra20_emc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
1367 unsigned long parent_rate)
6d296828
CC
1368{
1369 int ret;
92fe58f0 1370
6d296828
CC
1371 /*
1372 * The Tegra2 memory controller has an interlock with the clock
1373 * block that allows memory shadowed registers to be updated,
1374 * and then transfer them to the main registers at the same
1375 * time as the clock update without glitches.
1376 */
1377 ret = tegra_emc_set_rate(rate);
1378 if (ret < 0)
1379 return ret;
1380
92fe58f0 1381 ret = tegra20_periph_clk_set_rate(hw, rate, parent_rate);
6d296828
CC
1382 udelay(1);
1383
1384 return ret;
1385}
1386
86edb87a 1387struct clk_ops tegra_emc_clk_ops = {
92fe58f0
PG
1388 .init = tegra20_emc_clk_init,
1389 .is_enabled = tegra20_periph_clk_is_enabled,
1390 .enable = tegra20_periph_clk_enable,
1391 .disable = tegra20_periph_clk_disable,
1392 .set_parent = tegra20_periph_clk_set_parent,
1393 .get_parent = tegra20_periph_clk_get_parent,
1394 .set_rate = tegra20_emc_clk_set_rate,
1395 .round_rate = tegra20_emc_clk_round_rate,
1396 .recalc_rate = tegra20_periph_clk_recalc_rate,
6d296828
CC
1397};
1398
d8611961 1399/* Clock doubler ops */
92fe58f0 1400static int tegra20_clk_double_is_enabled(struct clk_hw *hw)
d8611961 1401{
92fe58f0
PG
1402 struct clk_tegra *c = to_clk_tegra(hw);
1403
d8611961 1404 c->state = ON;
1be3d053
CC
1405
1406 if (!c->u.periph.clk_num)
92fe58f0 1407 goto out;
1be3d053 1408
d8611961
CC
1409 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1410 PERIPH_CLK_TO_ENB_BIT(c)))
1411 c->state = OFF;
92fe58f0
PG
1412
1413out:
1414 return c->state;
d8611961
CC
1415};
1416
92fe58f0
PG
1417static unsigned long tegra20_clk_double_recalc_rate(struct clk_hw *hw,
1418 unsigned long prate)
71fc84cc 1419{
92fe58f0
PG
1420 struct clk_tegra *c = to_clk_tegra(hw);
1421 u64 rate = prate;
1422
71fc84cc
CC
1423 c->mul = 2;
1424 c->div = 1;
92fe58f0
PG
1425
1426 rate *= c->mul;
1427 rate += c->div - 1; /* round up */
1428 do_div(rate, c->div);
1429
1430 return rate;
1431}
1432
1433static long tegra20_clk_double_round_rate(struct clk_hw *hw, unsigned long rate,
1434 unsigned long *prate)
1435{
1436 unsigned long output_rate = *prate;
1437
1438 do_div(output_rate, 2);
1439 return output_rate;
1440}
1441
1442static int tegra20_clk_double_set_rate(struct clk_hw *hw, unsigned long rate,
1443 unsigned long parent_rate)
1444{
1445 if (rate != 2 * parent_rate)
1446 return -EINVAL;
71fc84cc
CC
1447 return 0;
1448}
1449
86edb87a 1450struct clk_ops tegra_clk_double_ops = {
92fe58f0
PG
1451 .is_enabled = tegra20_clk_double_is_enabled,
1452 .enable = tegra20_periph_clk_enable,
1453 .disable = tegra20_periph_clk_disable,
1454 .set_rate = tegra20_clk_double_set_rate,
1455 .recalc_rate = tegra20_clk_double_recalc_rate,
1456 .round_rate = tegra20_clk_double_round_rate,
71fc84cc
CC
1457};
1458
cea62c87 1459/* Audio sync clock ops */
92fe58f0 1460static int tegra20_audio_sync_clk_is_enabled(struct clk_hw *hw)
71fc84cc 1461{
92fe58f0 1462 struct clk_tegra *c = to_clk_tegra(hw);
71fc84cc 1463 u32 val = clk_readl(c->reg);
92fe58f0 1464
71fc84cc 1465 c->state = (val & (1<<4)) ? OFF : ON;
92fe58f0 1466 return c->state;
71fc84cc
CC
1467}
1468
92fe58f0 1469static int tegra20_audio_sync_clk_enable(struct clk_hw *hw)
71fc84cc 1470{
92fe58f0
PG
1471 struct clk_tegra *c = to_clk_tegra(hw);
1472
71fc84cc
CC
1473 clk_writel(0, c->reg);
1474 return 0;
1475}
1476
92fe58f0 1477static void tegra20_audio_sync_clk_disable(struct clk_hw *hw)
71fc84cc 1478{
92fe58f0 1479 struct clk_tegra *c = to_clk_tegra(hw);
71fc84cc
CC
1480 clk_writel(1, c->reg);
1481}
1482
92fe58f0 1483static u8 tegra20_audio_sync_clk_get_parent(struct clk_hw *hw)
71fc84cc 1484{
92fe58f0
PG
1485 struct clk_tegra *c = to_clk_tegra(hw);
1486 u32 val = clk_readl(c->reg);
1487 int source;
71fc84cc 1488
92fe58f0
PG
1489 source = val & 0xf;
1490 return source;
1491}
71fc84cc 1492
92fe58f0
PG
1493static int tegra20_audio_sync_clk_set_parent(struct clk_hw *hw, u8 index)
1494{
1495 struct clk_tegra *c = to_clk_tegra(hw);
1496 u32 val;
71fc84cc 1497
92fe58f0
PG
1498 val = clk_readl(c->reg);
1499 val &= ~0xf;
1500 val |= index;
71fc84cc 1501
92fe58f0 1502 clk_writel(val, c->reg);
71fc84cc 1503
92fe58f0 1504 return 0;
71fc84cc
CC
1505}
1506
86edb87a 1507struct clk_ops tegra_audio_sync_clk_ops = {
92fe58f0
PG
1508 .is_enabled = tegra20_audio_sync_clk_is_enabled,
1509 .enable = tegra20_audio_sync_clk_enable,
1510 .disable = tegra20_audio_sync_clk_disable,
1511 .set_parent = tegra20_audio_sync_clk_set_parent,
1512 .get_parent = tegra20_audio_sync_clk_get_parent,
d8611961
CC
1513};
1514
cea62c87
CC
1515/* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */
1516
92fe58f0 1517static int tegra20_cdev_clk_is_enabled(struct clk_hw *hw)
cea62c87 1518{
92fe58f0 1519 struct clk_tegra *c = to_clk_tegra(hw);
cea62c87
CC
1520 /* We could un-tristate the cdev1 or cdev2 pingroup here; this is
1521 * currently done in the pinmux code. */
1522 c->state = ON;
1be3d053
CC
1523
1524 BUG_ON(!c->u.periph.clk_num);
1525
cea62c87
CC
1526 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1527 PERIPH_CLK_TO_ENB_BIT(c)))
1528 c->state = OFF;
92fe58f0 1529 return c->state;
cea62c87
CC
1530}
1531
92fe58f0 1532static int tegra20_cdev_clk_enable(struct clk_hw *hw)
cea62c87 1533{
92fe58f0 1534 struct clk_tegra *c = to_clk_tegra(hw);
1be3d053
CC
1535 BUG_ON(!c->u.periph.clk_num);
1536
cea62c87
CC
1537 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1538 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
1539 return 0;
1540}
1541
92fe58f0 1542static void tegra20_cdev_clk_disable(struct clk_hw *hw)
cea62c87 1543{
92fe58f0 1544 struct clk_tegra *c = to_clk_tegra(hw);
1be3d053
CC
1545 BUG_ON(!c->u.periph.clk_num);
1546
cea62c87
CC
1547 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1548 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1549}
1550
92fe58f0
PG
1551static unsigned long tegra20_cdev_recalc_rate(struct clk_hw *hw,
1552 unsigned long prate)
310992ca 1553{
92fe58f0 1554 return to_clk_tegra(hw)->fixed_rate;
310992ca
CC
1555}
1556
92fe58f0
PG
1557struct clk_ops tegra_cdev_clk_ops = {
1558 .is_enabled = tegra20_cdev_clk_is_enabled,
1559 .enable = tegra20_cdev_clk_enable,
1560 .disable = tegra20_cdev_clk_disable,
1561 .recalc_rate = tegra20_cdev_recalc_rate,
310992ca 1562};
dab403ef
JL
1563
1564/* Tegra20 CPU clock and reset control functions */
1565static void tegra20_wait_cpu_in_reset(u32 cpu)
1566{
1567 unsigned int reg;
1568
1569 do {
1570 reg = readl(reg_clk_base +
1571 TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
1572 cpu_relax();
1573 } while (!(reg & (1 << cpu))); /* check CPU been reset or not */
1574
1575 return;
1576}
1577
1578static void tegra20_put_cpu_in_reset(u32 cpu)
1579{
1580 writel(CPU_RESET(cpu),
1581 reg_clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
1582 dmb();
1583}
1584
1585static void tegra20_cpu_out_of_reset(u32 cpu)
1586{
1587 writel(CPU_RESET(cpu),
1588 reg_clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
1589 wmb();
1590}
1591
1592static void tegra20_enable_cpu_clock(u32 cpu)
1593{
1594 unsigned int reg;
1595
1596 reg = readl(reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1597 writel(reg & ~CPU_CLOCK(cpu),
1598 reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1599 barrier();
1600 reg = readl(reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1601}
1602
1603static void tegra20_disable_cpu_clock(u32 cpu)
1604{
1605 unsigned int reg;
1606
1607 reg = readl(reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1608 writel(reg | CPU_CLOCK(cpu),
1609 reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1610}
1611
1612static struct tegra_cpu_car_ops tegra20_cpu_car_ops = {
1613 .wait_for_reset = tegra20_wait_cpu_in_reset,
1614 .put_in_reset = tegra20_put_cpu_in_reset,
1615 .out_of_reset = tegra20_cpu_out_of_reset,
1616 .enable_clock = tegra20_enable_cpu_clock,
1617 .disable_clock = tegra20_disable_cpu_clock,
1618};
1619
1620void __init tegra20_cpu_car_ops_init(void)
1621{
1622 tegra_cpu_car_ops = &tegra20_cpu_car_ops;
1623}
This page took 0.200892 seconds and 5 git commands to generate.