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