2 * arch/arm/mach-tegra/tegra20_clocks.c
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (c) 2010-2012 NVIDIA CORPORATION. All rights reserved.
8 * Colin Cross <ccross@google.com>
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.
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.
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>
27 #include <linux/clkdev.h>
28 #include <linux/clk.h>
33 #include "tegra2_emc.h"
34 #include "tegra_cpu_car.h"
36 #define RST_DEVICES 0x004
37 #define RST_DEVICES_SET 0x300
38 #define RST_DEVICES_CLR 0x304
39 #define RST_DEVICES_NUM 3
41 #define CLK_OUT_ENB 0x010
42 #define CLK_OUT_ENB_SET 0x320
43 #define CLK_OUT_ENB_CLR 0x324
44 #define CLK_OUT_ENB_NUM 3
46 #define CLK_MASK_ARM 0x44
47 #define MISC_CLK_ENB 0x48
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)
55 #define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
57 #define OSC_FREQ_DET 0x58
58 #define OSC_FREQ_DET_TRIG (1<<31)
60 #define OSC_FREQ_DET_STATUS 0x5C
61 #define OSC_FREQ_DET_BUSY (1<<31)
62 #define OSC_FREQ_DET_CNT_MASK 0xFFFF
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)
70 #define PERIPH_CLK_SOURCE_MASK (3<<30)
71 #define PERIPH_CLK_SOURCE_SHIFT 30
72 #define PERIPH_CLK_SOURCE_PWM_MASK (7<<28)
73 #define PERIPH_CLK_SOURCE_PWM_SHIFT 28
74 #define PERIPH_CLK_SOURCE_ENABLE (1<<28)
75 #define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF
76 #define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF
77 #define PERIPH_CLK_SOURCE_DIV_SHIFT 0
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)
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)
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
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)
101 #define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
103 #define PLL_MISC_DCCON_SHIFT 20
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)
111 #define PLLU_BASE_POST_DIV (1<<20)
113 #define PLLD_MISC_CLKENABLE (1<<30)
114 #define PLLD_MISC_DIV_RST (1<<23)
115 #define PLLD_MISC_DCCON_SHIFT 12
117 #define PLLE_MISC_READY (1 << 15)
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))
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
137 #define SUPER_CLK_DIVIDER 0x04
139 #define BUS_CLK_DISABLE (1<<3)
140 #define BUS_CLK_DIV_MASK 0x3
143 #define PMC_CTRL_BLINK_ENB (1 << 7)
145 #define PMC_DPD_PADS_ORIDE 0x1c
146 #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20)
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
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
159 #define CPU_CLOCK(cpu) (0x1 << (8 + cpu))
160 #define CPU_RESET(cpu) (0x1111ul << (cpu))
162 static void __iomem
*reg_clk_base
= IO_ADDRESS(TEGRA_CLK_RESET_BASE
);
163 static void __iomem
*reg_pmc_base
= IO_ADDRESS(TEGRA_PMC_BASE
);
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.
170 static DEFINE_SPINLOCK(clock_register_lock
);
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
176 static int tegra_periph_clk_enable_refcount
[3 * 32];
178 #define clk_writel(value, reg) \
179 __raw_writel(value, reg_clk_base + (reg))
180 #define clk_readl(reg) \
181 __raw_readl(reg_clk_base + (reg))
182 #define pmc_writel(value, reg) \
183 __raw_writel(value, reg_pmc_base + (reg))
184 #define pmc_readl(reg) \
185 __raw_readl(reg_pmc_base + (reg))
187 static unsigned long clk_measure_input_freq(void)
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) {
195 } else if (clock_autodetect
>= 794 - 3 && clock_autodetect
<= 794 + 3) {
197 } else if (clock_autodetect
>= 1172 - 3 && clock_autodetect
<= 1172 + 3) {
199 } else if (clock_autodetect
>= 1587 - 3 && clock_autodetect
<= 1587 + 3) {
202 pr_err("%s: Unexpected clock autodetect value %d",
203 __func__
, clock_autodetect
);
209 static int clk_div71_get_divider(unsigned long parent_rate
, unsigned long rate
)
211 s64 divider_u71
= parent_rate
* 2;
212 divider_u71
+= rate
- 1;
213 do_div(divider_u71
, rate
);
215 if (divider_u71
- 2 < 0)
218 if (divider_u71
- 2 > 255)
221 return divider_u71
- 2;
224 static int clk_div16_get_divider(unsigned long parent_rate
, unsigned long rate
)
228 divider_u16
= parent_rate
;
229 divider_u16
+= rate
- 1;
230 do_div(divider_u16
, rate
);
232 if (divider_u16
- 1 < 0)
235 if (divider_u16
- 1 > 0xFFFF)
238 return divider_u16
- 1;
241 static unsigned long tegra_clk_fixed_recalc_rate(struct clk_hw
*hw
,
242 unsigned long parent_rate
)
244 return to_clk_tegra(hw
)->fixed_rate
;
247 struct clk_ops tegra_clk_32k_ops
= {
248 .recalc_rate
= tegra_clk_fixed_recalc_rate
,
251 /* clk_m functions */
252 static unsigned long tegra20_clk_m_recalc_rate(struct clk_hw
*hw
,
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
;
260 static void tegra20_clk_m_init(struct clk_hw
*hw
)
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
;
266 switch (c
->fixed_rate
) {
268 auto_clock_control
|= OSC_CTRL_OSC_FREQ_12MHZ
;
271 auto_clock_control
|= OSC_CTRL_OSC_FREQ_13MHZ
;
274 auto_clock_control
|= OSC_CTRL_OSC_FREQ_19_2MHZ
;
277 auto_clock_control
|= OSC_CTRL_OSC_FREQ_26MHZ
;
282 clk_writel(auto_clock_control
, OSC_CTRL
);
285 struct clk_ops tegra_clk_m_ops
= {
286 .init
= tegra20_clk_m_init
,
287 .recalc_rate
= tegra20_clk_m_recalc_rate
,
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.
296 static int tegra20_super_clk_is_enabled(struct clk_hw
*hw
)
298 struct clk_tegra
*c
= to_clk_tegra(hw
);
301 val
= clk_readl(c
->reg
+ SUPER_CLK_MUX
);
302 BUG_ON(((val
& SUPER_STATE_MASK
) != SUPER_STATE_RUN
) &&
303 ((val
& SUPER_STATE_MASK
) != SUPER_STATE_IDLE
));
308 static int tegra20_super_clk_enable(struct clk_hw
*hw
)
310 struct clk_tegra
*c
= to_clk_tegra(hw
);
311 clk_writel(0, c
->reg
+ SUPER_CLK_DIVIDER
);
315 static void tegra20_super_clk_disable(struct clk_hw
*hw
)
317 pr_debug("%s on clock %s\n", __func__
, __clk_get_name(hw
->clk
));
319 /* oops - don't disable the CPU clock! */
323 static u8
tegra20_super_clk_get_parent(struct clk_hw
*hw
)
325 struct clk_tegra
*c
= to_clk_tegra(hw
);
326 int val
= clk_readl(c
->reg
+ SUPER_CLK_MUX
);
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
;
334 source
= (val
>> shift
) & SUPER_SOURCE_MASK
;
338 static int tegra20_super_clk_set_parent(struct clk_hw
*hw
, u8 index
)
340 struct clk_tegra
*c
= to_clk_tegra(hw
);
341 u32 val
= clk_readl(c
->reg
+ SUPER_CLK_MUX
);
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
;
351 clk_writel(val
, c
->reg
);
356 /* FIX ME: Need to switch parents to change the source PLL rate */
357 static unsigned long tegra20_super_clk_recalc_rate(struct clk_hw
*hw
,
363 static long tegra20_super_clk_round_rate(struct clk_hw
*hw
, unsigned long rate
,
364 unsigned long *prate
)
369 static int tegra20_super_clk_set_rate(struct clk_hw
*hw
, unsigned long rate
,
370 unsigned long parent_rate
)
375 struct 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
,
386 static unsigned long tegra20_twd_clk_recalc_rate(struct clk_hw
*hw
,
387 unsigned long parent_rate
)
389 struct clk_tegra
*c
= to_clk_tegra(hw
);
390 u64 rate
= parent_rate
;
392 if (c
->mul
!= 0 && c
->div
!= 0) {
394 rate
+= c
->div
- 1; /* round up */
395 do_div(rate
, c
->div
);
401 struct clk_ops tegra_twd_ops
= {
402 .recalc_rate
= tegra20_twd_clk_recalc_rate
,
405 static u8
tegra20_cop_clk_get_parent(struct clk_hw
*hw
)
410 struct clk_ops tegra_cop_ops
= {
411 .get_parent
= tegra20_cop_clk_get_parent
,
414 /* virtual cop clock functions. Used to acquire the fake 'cop' clock to
415 * reset the COP block (i.e. AVP) */
416 void tegra2_cop_clk_reset(struct clk_hw
*hw
, bool assert)
418 unsigned long reg
= assert ? RST_DEVICES_SET
: RST_DEVICES_CLR
;
420 pr_debug("%s %s\n", __func__
, assert ? "assert" : "deassert");
421 clk_writel(1 << 1, reg
);
424 /* bus clock functions */
425 static int tegra20_bus_clk_is_enabled(struct clk_hw
*hw
)
427 struct clk_tegra
*c
= to_clk_tegra(hw
);
428 u32 val
= clk_readl(c
->reg
);
430 c
->state
= ((val
>> c
->reg_shift
) & BUS_CLK_DISABLE
) ? OFF
: ON
;
434 static int tegra20_bus_clk_enable(struct clk_hw
*hw
)
436 struct clk_tegra
*c
= to_clk_tegra(hw
);
440 spin_lock_irqsave(&clock_register_lock
, flags
);
442 val
= clk_readl(c
->reg
);
443 val
&= ~(BUS_CLK_DISABLE
<< c
->reg_shift
);
444 clk_writel(val
, c
->reg
);
446 spin_unlock_irqrestore(&clock_register_lock
, flags
);
451 static void tegra20_bus_clk_disable(struct clk_hw
*hw
)
453 struct clk_tegra
*c
= to_clk_tegra(hw
);
457 spin_lock_irqsave(&clock_register_lock
, flags
);
459 val
= clk_readl(c
->reg
);
460 val
|= BUS_CLK_DISABLE
<< c
->reg_shift
;
461 clk_writel(val
, c
->reg
);
463 spin_unlock_irqrestore(&clock_register_lock
, flags
);
466 static unsigned long tegra20_bus_clk_recalc_rate(struct clk_hw
*hw
,
469 struct clk_tegra
*c
= to_clk_tegra(hw
);
470 u32 val
= clk_readl(c
->reg
);
473 c
->div
= ((val
>> c
->reg_shift
) & BUS_CLK_DIV_MASK
) + 1;
476 if (c
->mul
!= 0 && c
->div
!= 0) {
478 rate
+= c
->div
- 1; /* round up */
479 do_div(rate
, c
->div
);
484 static int tegra20_bus_clk_set_rate(struct clk_hw
*hw
, unsigned long rate
,
485 unsigned long parent_rate
)
487 struct clk_tegra
*c
= to_clk_tegra(hw
);
493 spin_lock_irqsave(&clock_register_lock
, flags
);
495 val
= clk_readl(c
->reg
);
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
);
508 spin_unlock_irqrestore(&clock_register_lock
, flags
);
513 static long tegra20_bus_clk_round_rate(struct clk_hw
*hw
, unsigned long rate
,
514 unsigned long *prate
)
516 unsigned long parent_rate
= *prate
;
519 if (rate
>= parent_rate
)
522 divider
= parent_rate
;
524 do_div(divider
, rate
);
531 do_div(parent_rate
, divider
);
536 struct clk_ops tegra_bus_ops
= {
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
,
545 /* Blink output functions */
546 static int tegra20_blink_clk_is_enabled(struct clk_hw
*hw
)
548 struct clk_tegra
*c
= to_clk_tegra(hw
);
551 val
= pmc_readl(PMC_CTRL
);
552 c
->state
= (val
& PMC_CTRL_BLINK_ENB
) ? ON
: OFF
;
556 static unsigned long tegra20_blink_clk_recalc_rate(struct clk_hw
*hw
,
559 struct clk_tegra
*c
= to_clk_tegra(hw
);
564 val
= pmc_readl(c
->reg
);
566 if (val
& PMC_BLINK_TIMER_ENB
) {
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
;
574 /* each tick in the blink timer is 4 32KHz clocks */
580 if (c
->mul
!= 0 && c
->div
!= 0) {
582 rate
+= c
->div
- 1; /* round up */
583 do_div(rate
, c
->div
);
588 static int tegra20_blink_clk_enable(struct clk_hw
*hw
)
592 val
= pmc_readl(PMC_DPD_PADS_ORIDE
);
593 pmc_writel(val
| PMC_DPD_PADS_ORIDE_BLINK_ENB
, PMC_DPD_PADS_ORIDE
);
595 val
= pmc_readl(PMC_CTRL
);
596 pmc_writel(val
| PMC_CTRL_BLINK_ENB
, PMC_CTRL
);
601 static void tegra20_blink_clk_disable(struct clk_hw
*hw
)
605 val
= pmc_readl(PMC_CTRL
);
606 pmc_writel(val
& ~PMC_CTRL_BLINK_ENB
, PMC_CTRL
);
608 val
= pmc_readl(PMC_DPD_PADS_ORIDE
);
609 pmc_writel(val
& ~PMC_DPD_PADS_ORIDE_BLINK_ENB
, PMC_DPD_PADS_ORIDE
);
612 static int tegra20_blink_clk_set_rate(struct clk_hw
*hw
, unsigned long rate
,
613 unsigned long parent_rate
)
615 struct clk_tegra
*c
= to_clk_tegra(hw
);
617 if (rate
>= parent_rate
) {
619 pmc_writel(0, c
->reg
);
624 on_off
= DIV_ROUND_UP(parent_rate
/ 8, rate
);
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
;
632 val
|= PMC_BLINK_TIMER_ENB
;
633 pmc_writel(val
, c
->reg
);
639 static long tegra20_blink_clk_round_rate(struct clk_hw
*hw
, unsigned long rate
,
640 unsigned long *prate
)
644 long round_rate
= *prate
;
648 if (rate
>= *prate
) {
651 div
= DIV_ROUND_UP(*prate
/ 8, rate
);
656 round_rate
+= div
- 1;
657 do_div(round_rate
, div
);
662 struct clk_ops tegra_blink_clk_ops
= {
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
,
672 static int tegra20_pll_clk_wait_for_lock(struct clk_tegra
*c
)
674 udelay(c
->u
.pll
.lock_delay
);
678 static int tegra20_pll_clk_is_enabled(struct clk_hw
*hw
)
680 struct clk_tegra
*c
= to_clk_tegra(hw
);
681 u32 val
= clk_readl(c
->reg
+ PLL_BASE
);
683 c
->state
= (val
& PLL_BASE_ENABLE
) ? ON
: OFF
;
687 static unsigned long tegra20_pll_clk_recalc_rate(struct clk_hw
*hw
,
690 struct clk_tegra
*c
= to_clk_tegra(hw
);
691 u32 val
= clk_readl(c
->reg
+ PLL_BASE
);
694 if (c
->flags
& PLL_FIXED
&& !(val
& PLL_BASE_OVERRIDE
)) {
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
) {
700 c
->div
= sel
->m
* sel
->p
;
704 pr_err("Clock %s has unknown fixed frequency\n",
705 __clk_get_name(hw
->clk
));
707 } else if (val
& PLL_BASE_BYPASS
) {
711 c
->mul
= (val
& PLL_BASE_DIVN_MASK
) >> PLL_BASE_DIVN_SHIFT
;
712 c
->div
= (val
& PLL_BASE_DIVM_MASK
) >> PLL_BASE_DIVM_SHIFT
;
714 c
->div
*= (val
& PLLU_BASE_POST_DIV
) ? 1 : 2;
716 c
->div
*= (val
& PLL_BASE_DIVP_MASK
) ? 2 : 1;
719 if (c
->mul
!= 0 && c
->div
!= 0) {
721 rate
+= c
->div
- 1; /* round up */
722 do_div(rate
, c
->div
);
727 static int tegra20_pll_clk_enable(struct clk_hw
*hw
)
729 struct clk_tegra
*c
= to_clk_tegra(hw
);
731 pr_debug("%s on clock %s\n", __func__
, __clk_get_name(hw
->clk
));
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
);
738 tegra20_pll_clk_wait_for_lock(c
);
743 static void tegra20_pll_clk_disable(struct clk_hw
*hw
)
745 struct clk_tegra
*c
= to_clk_tegra(hw
);
747 pr_debug("%s on clock %s\n", __func__
, __clk_get_name(hw
->clk
));
749 val
= clk_readl(c
->reg
);
750 val
&= ~(PLL_BASE_BYPASS
| PLL_BASE_ENABLE
);
751 clk_writel(val
, c
->reg
);
754 static int tegra20_pll_clk_set_rate(struct clk_hw
*hw
, unsigned long rate
,
755 unsigned long parent_rate
)
757 struct clk_tegra
*c
= to_clk_tegra(hw
);
758 unsigned long input_rate
= parent_rate
;
759 const struct clk_pll_freq_table
*sel
;
762 pr_debug("%s: %s %lu\n", __func__
, __clk_get_name(hw
->clk
), rate
);
764 if (c
->flags
& PLL_FIXED
) {
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
);
775 for (sel
= c
->u
.pll
.freq_table
; sel
->input_rate
!= 0; sel
++) {
776 if (sel
->input_rate
== input_rate
&& sel
->output_rate
== rate
) {
778 c
->div
= sel
->m
* sel
->p
;
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
|
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
) {
790 val
|= PLLU_BASE_POST_DIV
;
793 val
|= 1 << PLL_BASE_DIVP_SHIFT
;
795 clk_writel(val
, c
->reg
+ PLL_BASE
);
797 if (c
->flags
& PLL_HAS_CPCON
) {
798 val
= clk_readl(c
->reg
+ PLL_MISC(c
));
799 val
&= ~PLL_MISC_CPCON_MASK
;
800 val
|= sel
->cpcon
<< PLL_MISC_CPCON_SHIFT
;
801 clk_writel(val
, c
->reg
+ PLL_MISC(c
));
805 tegra20_pll_clk_enable(hw
);
812 static long tegra20_pll_clk_round_rate(struct clk_hw
*hw
, unsigned long rate
,
813 unsigned long *prate
)
815 struct clk_tegra
*c
= to_clk_tegra(hw
);
816 const struct clk_pll_freq_table
*sel
;
817 unsigned long input_rate
= *prate
;
818 u64 output_rate
= *prate
;
822 if (c
->flags
& PLL_FIXED
)
823 return c
->u
.pll
.fixed_rate
;
825 for (sel
= c
->u
.pll
.freq_table
; sel
->input_rate
!= 0; sel
++)
826 if (sel
->input_rate
== input_rate
&& sel
->output_rate
== rate
) {
828 div
= sel
->m
* sel
->p
;
832 if (sel
->input_rate
== 0)
836 output_rate
+= div
- 1; /* round up */
837 do_div(output_rate
, div
);
842 struct clk_ops tegra_pll_ops
= {
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
,
851 static void tegra20_pllx_clk_init(struct clk_hw
*hw
)
853 struct clk_tegra
*c
= to_clk_tegra(hw
);
855 if (tegra_sku_id
== 7)
856 c
->max_rate
= 750000000;
859 struct clk_ops tegra_pllx_ops
= {
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
,
869 static int tegra20_plle_clk_enable(struct clk_hw
*hw
)
871 struct clk_tegra
*c
= to_clk_tegra(hw
);
874 pr_debug("%s on clock %s\n", __func__
, __clk_get_name(hw
->clk
));
878 val
= clk_readl(c
->reg
+ PLL_BASE
);
879 if (!(val
& PLLE_MISC_READY
))
882 val
= clk_readl(c
->reg
+ PLL_BASE
);
883 val
|= PLL_BASE_ENABLE
| PLL_BASE_BYPASS
;
884 clk_writel(val
, c
->reg
+ PLL_BASE
);
889 struct clk_ops tegra_plle_ops
= {
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
,
897 /* Clock divider ops */
898 static int tegra20_pll_div_clk_is_enabled(struct clk_hw
*hw
)
900 struct clk_tegra
*c
= to_clk_tegra(hw
);
901 u32 val
= clk_readl(c
->reg
);
903 val
>>= c
->reg_shift
;
904 c
->state
= (val
& PLL_OUT_CLKEN
) ? ON
: OFF
;
905 if (!(val
& PLL_OUT_RESET_DISABLE
))
910 static unsigned long tegra20_pll_div_clk_recalc_rate(struct clk_hw
*hw
,
913 struct clk_tegra
*c
= to_clk_tegra(hw
);
915 u32 val
= clk_readl(c
->reg
);
918 val
>>= c
->reg_shift
;
920 if (c
->flags
& DIV_U71
) {
921 divu71
= (val
& PLL_OUT_RATIO_MASK
) >> PLL_OUT_RATIO_SHIFT
;
922 c
->div
= (divu71
+ 2);
924 } else if (c
->flags
& DIV_2
) {
933 rate
+= c
->div
- 1; /* round up */
934 do_div(rate
, c
->div
);
939 static int tegra20_pll_div_clk_enable(struct clk_hw
*hw
)
941 struct clk_tegra
*c
= to_clk_tegra(hw
);
946 pr_debug("%s: %s\n", __func__
, __clk_get_name(hw
->clk
));
948 if (c
->flags
& DIV_U71
) {
949 spin_lock_irqsave(&clock_register_lock
, flags
);
950 val
= clk_readl(c
->reg
);
951 new_val
= val
>> c
->reg_shift
;
954 new_val
|= PLL_OUT_CLKEN
| PLL_OUT_RESET_DISABLE
;
956 val
&= ~(0xFFFF << c
->reg_shift
);
957 val
|= new_val
<< c
->reg_shift
;
958 clk_writel(val
, c
->reg
);
959 spin_unlock_irqrestore(&clock_register_lock
, flags
);
961 } else if (c
->flags
& DIV_2
) {
962 BUG_ON(!(c
->flags
& PLLD
));
963 spin_lock_irqsave(&clock_register_lock
, flags
);
964 val
= clk_readl(c
->reg
);
965 val
&= ~PLLD_MISC_DIV_RST
;
966 clk_writel(val
, c
->reg
);
967 spin_unlock_irqrestore(&clock_register_lock
, flags
);
973 static void tegra20_pll_div_clk_disable(struct clk_hw
*hw
)
975 struct clk_tegra
*c
= to_clk_tegra(hw
);
980 pr_debug("%s: %s\n", __func__
, __clk_get_name(hw
->clk
));
982 if (c
->flags
& DIV_U71
) {
983 spin_lock_irqsave(&clock_register_lock
, flags
);
984 val
= clk_readl(c
->reg
);
985 new_val
= val
>> c
->reg_shift
;
988 new_val
&= ~(PLL_OUT_CLKEN
| PLL_OUT_RESET_DISABLE
);
990 val
&= ~(0xFFFF << c
->reg_shift
);
991 val
|= new_val
<< c
->reg_shift
;
992 clk_writel(val
, c
->reg
);
993 spin_unlock_irqrestore(&clock_register_lock
, flags
);
994 } else if (c
->flags
& DIV_2
) {
995 BUG_ON(!(c
->flags
& PLLD
));
996 spin_lock_irqsave(&clock_register_lock
, flags
);
997 val
= clk_readl(c
->reg
);
998 val
|= PLLD_MISC_DIV_RST
;
999 clk_writel(val
, c
->reg
);
1000 spin_unlock_irqrestore(&clock_register_lock
, flags
);
1004 static int tegra20_pll_div_clk_set_rate(struct clk_hw
*hw
, unsigned long rate
,
1005 unsigned long parent_rate
)
1007 struct clk_tegra
*c
= to_clk_tegra(hw
);
1008 unsigned long flags
;
1013 pr_debug("%s: %s %lu\n", __func__
, __clk_get_name(hw
->clk
), rate
);
1015 if (c
->flags
& DIV_U71
) {
1016 divider_u71
= clk_div71_get_divider(parent_rate
, rate
);
1017 if (divider_u71
>= 0) {
1018 spin_lock_irqsave(&clock_register_lock
, flags
);
1019 val
= clk_readl(c
->reg
);
1020 new_val
= val
>> c
->reg_shift
;
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
;
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;
1032 spin_unlock_irqrestore(&clock_register_lock
, flags
);
1035 } else if (c
->flags
& DIV_2
) {
1036 if (parent_rate
== rate
* 2)
1042 static long tegra20_pll_div_clk_round_rate(struct clk_hw
*hw
, unsigned long rate
,
1043 unsigned long *prate
)
1045 struct clk_tegra
*c
= to_clk_tegra(hw
);
1046 unsigned long parent_rate
= *prate
;
1049 pr_debug("%s: %s %lu\n", __func__
, __clk_get_name(hw
->clk
), rate
);
1051 if (c
->flags
& DIV_U71
) {
1052 divider
= clk_div71_get_divider(parent_rate
, rate
);
1055 return DIV_ROUND_UP(parent_rate
* 2, divider
+ 2);
1056 } else if (c
->flags
& DIV_2
) {
1057 return DIV_ROUND_UP(parent_rate
, 2);
1062 struct clk_ops tegra_pll_div_ops
= {
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
,
1071 /* Periph clk ops */
1073 static int tegra20_periph_clk_is_enabled(struct clk_hw
*hw
)
1075 struct clk_tegra
*c
= to_clk_tegra(hw
);
1079 if (!c
->u
.periph
.clk_num
)
1082 if (!(clk_readl(CLK_OUT_ENB
+ PERIPH_CLK_TO_ENB_REG(c
)) &
1083 PERIPH_CLK_TO_ENB_BIT(c
)))
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
))
1095 static int tegra20_periph_clk_enable(struct clk_hw
*hw
)
1097 struct clk_tegra
*c
= to_clk_tegra(hw
);
1098 unsigned long flags
;
1101 pr_debug("%s on clock %s\n", __func__
, __clk_get_name(hw
->clk
));
1103 if (!c
->u
.periph
.clk_num
)
1106 tegra_periph_clk_enable_refcount
[c
->u
.periph
.clk_num
]++;
1107 if (tegra_periph_clk_enable_refcount
[c
->u
.periph
.clk_num
] > 1)
1110 spin_lock_irqsave(&clock_register_lock
, flags
);
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
);
1122 clk_writel(val
, c
->reg
);
1125 spin_unlock_irqrestore(&clock_register_lock
, flags
);
1130 static void tegra20_periph_clk_disable(struct clk_hw
*hw
)
1132 struct clk_tegra
*c
= to_clk_tegra(hw
);
1133 unsigned long flags
;
1135 pr_debug("%s on clock %s\n", __func__
, __clk_get_name(hw
->clk
));
1137 if (!c
->u
.periph
.clk_num
)
1140 tegra_periph_clk_enable_refcount
[c
->u
.periph
.clk_num
]--;
1142 if (tegra_periph_clk_enable_refcount
[c
->u
.periph
.clk_num
] > 0)
1145 spin_lock_irqsave(&clock_register_lock
, flags
);
1147 clk_writel(PERIPH_CLK_TO_ENB_BIT(c
),
1148 CLK_OUT_ENB_CLR
+ PERIPH_CLK_TO_ENB_SET_REG(c
));
1150 spin_unlock_irqrestore(&clock_register_lock
, flags
);
1153 void tegra2_periph_clk_reset(struct clk_hw
*hw
, bool assert)
1155 struct clk_tegra
*c
= to_clk_tegra(hw
);
1156 unsigned long base
= assert ? RST_DEVICES_SET
: RST_DEVICES_CLR
;
1158 pr_debug("%s %s on clock %s\n", __func__
,
1159 assert ? "assert" : "deassert", __clk_get_name(hw
->clk
));
1161 BUG_ON(!c
->u
.periph
.clk_num
);
1163 if (!(c
->flags
& PERIPH_NO_RESET
))
1164 clk_writel(PERIPH_CLK_TO_ENB_BIT(c
),
1165 base
+ PERIPH_CLK_TO_ENB_SET_REG(c
));
1168 static int tegra20_periph_clk_set_parent(struct clk_hw
*hw
, u8 index
)
1170 struct clk_tegra
*c
= to_clk_tegra(hw
);
1175 pr_debug("%s: %s %d\n", __func__
, __clk_get_name(hw
->clk
), index
);
1177 if (c
->flags
& MUX_PWM
) {
1178 shift
= PERIPH_CLK_SOURCE_PWM_SHIFT
;
1179 mask
= PERIPH_CLK_SOURCE_PWM_MASK
;
1181 shift
= PERIPH_CLK_SOURCE_SHIFT
;
1182 mask
= PERIPH_CLK_SOURCE_MASK
;
1185 val
= clk_readl(c
->reg
);
1187 val
|= (index
) << shift
;
1189 clk_writel(val
, c
->reg
);
1194 static u8
tegra20_periph_clk_get_parent(struct clk_hw
*hw
)
1196 struct clk_tegra
*c
= to_clk_tegra(hw
);
1197 u32 val
= clk_readl(c
->reg
);
1201 if (c
->flags
& MUX_PWM
) {
1202 shift
= PERIPH_CLK_SOURCE_PWM_SHIFT
;
1203 mask
= PERIPH_CLK_SOURCE_PWM_MASK
;
1205 shift
= PERIPH_CLK_SOURCE_SHIFT
;
1206 mask
= PERIPH_CLK_SOURCE_MASK
;
1210 return (val
& mask
) >> shift
;
1215 static unsigned long tegra20_periph_clk_recalc_rate(struct clk_hw
*hw
,
1216 unsigned long prate
)
1218 struct clk_tegra
*c
= to_clk_tegra(hw
);
1219 unsigned long rate
= prate
;
1220 u32 val
= clk_readl(c
->reg
);
1222 if (c
->flags
& DIV_U71
) {
1223 u32 divu71
= val
& PERIPH_CLK_SOURCE_DIVU71_MASK
;
1224 c
->div
= divu71
+ 2;
1226 } else if (c
->flags
& DIV_U16
) {
1227 u32 divu16
= val
& PERIPH_CLK_SOURCE_DIVU16_MASK
;
1228 c
->div
= divu16
+ 1;
1236 if (c
->mul
!= 0 && c
->div
!= 0) {
1238 rate
+= c
->div
- 1; /* round up */
1239 do_div(rate
, c
->div
);
1245 static int tegra20_periph_clk_set_rate(struct clk_hw
*hw
, unsigned long rate
,
1246 unsigned long parent_rate
)
1248 struct clk_tegra
*c
= to_clk_tegra(hw
);
1252 val
= clk_readl(c
->reg
);
1254 if (c
->flags
& DIV_U71
) {
1255 divider
= clk_div71_get_divider(parent_rate
, rate
);
1258 val
= clk_readl(c
->reg
);
1259 val
&= ~PERIPH_CLK_SOURCE_DIVU71_MASK
;
1261 clk_writel(val
, c
->reg
);
1262 c
->div
= divider
+ 2;
1266 } else if (c
->flags
& DIV_U16
) {
1267 divider
= clk_div16_get_divider(parent_rate
, rate
);
1269 val
= clk_readl(c
->reg
);
1270 val
&= ~PERIPH_CLK_SOURCE_DIVU16_MASK
;
1272 clk_writel(val
, c
->reg
);
1273 c
->div
= divider
+ 1;
1277 } else if (parent_rate
<= rate
) {
1286 static long tegra20_periph_clk_round_rate(struct clk_hw
*hw
,
1287 unsigned long rate
, unsigned long *prate
)
1289 struct clk_tegra
*c
= to_clk_tegra(hw
);
1290 unsigned long parent_rate
= __clk_get_rate(__clk_get_parent(hw
->clk
));
1293 pr_debug("%s: %s %lu\n", __func__
, __clk_get_name(hw
->clk
), rate
);
1296 parent_rate
= *prate
;
1298 if (c
->flags
& DIV_U71
) {
1299 divider
= clk_div71_get_divider(parent_rate
, rate
);
1303 return DIV_ROUND_UP(parent_rate
* 2, divider
+ 2);
1304 } else if (c
->flags
& DIV_U16
) {
1305 divider
= clk_div16_get_divider(parent_rate
, rate
);
1308 return DIV_ROUND_UP(parent_rate
, divider
+ 1);
1313 struct clk_ops tegra_periph_clk_ops
= {
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
,
1324 /* External memory controller clock ops */
1325 static void tegra20_emc_clk_init(struct clk_hw
*hw
)
1327 struct clk_tegra
*c
= to_clk_tegra(hw
);
1328 c
->max_rate
= __clk_get_rate(hw
->clk
);
1331 static long tegra20_emc_clk_round_rate(struct clk_hw
*hw
, unsigned long rate
,
1332 unsigned long *prate
)
1334 struct clk_tegra
*c
= to_clk_tegra(hw
);
1339 * The slowest entry in the EMC clock table that is at least as
1342 emc_rate
= tegra_emc_round_rate(rate
);
1347 * The fastest rate the PLL will generate that is at most the
1350 clk_rate
= tegra20_periph_clk_round_rate(hw
, emc_rate
, NULL
);
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.
1359 WARN_ONCE(emc_rate
!= clk_rate
,
1360 "emc_rate %ld != clk_rate %ld",
1361 emc_rate
, clk_rate
);
1366 static int tegra20_emc_clk_set_rate(struct clk_hw
*hw
, unsigned long rate
,
1367 unsigned long parent_rate
)
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.
1377 ret
= tegra_emc_set_rate(rate
);
1381 ret
= tegra20_periph_clk_set_rate(hw
, rate
, parent_rate
);
1387 struct clk_ops tegra_emc_clk_ops
= {
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
,
1399 /* Clock doubler ops */
1400 static int tegra20_clk_double_is_enabled(struct clk_hw
*hw
)
1402 struct clk_tegra
*c
= to_clk_tegra(hw
);
1406 if (!c
->u
.periph
.clk_num
)
1409 if (!(clk_readl(CLK_OUT_ENB
+ PERIPH_CLK_TO_ENB_REG(c
)) &
1410 PERIPH_CLK_TO_ENB_BIT(c
)))
1417 static unsigned long tegra20_clk_double_recalc_rate(struct clk_hw
*hw
,
1418 unsigned long prate
)
1420 struct clk_tegra
*c
= to_clk_tegra(hw
);
1427 rate
+= c
->div
- 1; /* round up */
1428 do_div(rate
, c
->div
);
1433 static long tegra20_clk_double_round_rate(struct clk_hw
*hw
, unsigned long rate
,
1434 unsigned long *prate
)
1436 unsigned long output_rate
= *prate
;
1438 do_div(output_rate
, 2);
1442 static int tegra20_clk_double_set_rate(struct clk_hw
*hw
, unsigned long rate
,
1443 unsigned long parent_rate
)
1445 if (rate
!= 2 * parent_rate
)
1450 struct clk_ops tegra_clk_double_ops
= {
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
,
1459 /* Audio sync clock ops */
1460 static int tegra20_audio_sync_clk_is_enabled(struct clk_hw
*hw
)
1462 struct clk_tegra
*c
= to_clk_tegra(hw
);
1463 u32 val
= clk_readl(c
->reg
);
1465 c
->state
= (val
& (1<<4)) ? OFF
: ON
;
1469 static int tegra20_audio_sync_clk_enable(struct clk_hw
*hw
)
1471 struct clk_tegra
*c
= to_clk_tegra(hw
);
1473 clk_writel(0, c
->reg
);
1477 static void tegra20_audio_sync_clk_disable(struct clk_hw
*hw
)
1479 struct clk_tegra
*c
= to_clk_tegra(hw
);
1480 clk_writel(1, c
->reg
);
1483 static u8
tegra20_audio_sync_clk_get_parent(struct clk_hw
*hw
)
1485 struct clk_tegra
*c
= to_clk_tegra(hw
);
1486 u32 val
= clk_readl(c
->reg
);
1493 static int tegra20_audio_sync_clk_set_parent(struct clk_hw
*hw
, u8 index
)
1495 struct clk_tegra
*c
= to_clk_tegra(hw
);
1498 val
= clk_readl(c
->reg
);
1502 clk_writel(val
, c
->reg
);
1507 struct clk_ops tegra_audio_sync_clk_ops
= {
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
,
1515 /* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */
1517 static int tegra20_cdev_clk_is_enabled(struct clk_hw
*hw
)
1519 struct clk_tegra
*c
= to_clk_tegra(hw
);
1520 /* We could un-tristate the cdev1 or cdev2 pingroup here; this is
1521 * currently done in the pinmux code. */
1524 BUG_ON(!c
->u
.periph
.clk_num
);
1526 if (!(clk_readl(CLK_OUT_ENB
+ PERIPH_CLK_TO_ENB_REG(c
)) &
1527 PERIPH_CLK_TO_ENB_BIT(c
)))
1532 static int tegra20_cdev_clk_enable(struct clk_hw
*hw
)
1534 struct clk_tegra
*c
= to_clk_tegra(hw
);
1535 BUG_ON(!c
->u
.periph
.clk_num
);
1537 clk_writel(PERIPH_CLK_TO_ENB_BIT(c
),
1538 CLK_OUT_ENB_SET
+ PERIPH_CLK_TO_ENB_SET_REG(c
));
1542 static void tegra20_cdev_clk_disable(struct clk_hw
*hw
)
1544 struct clk_tegra
*c
= to_clk_tegra(hw
);
1545 BUG_ON(!c
->u
.periph
.clk_num
);
1547 clk_writel(PERIPH_CLK_TO_ENB_BIT(c
),
1548 CLK_OUT_ENB_CLR
+ PERIPH_CLK_TO_ENB_SET_REG(c
));
1551 static unsigned long tegra20_cdev_recalc_rate(struct clk_hw
*hw
,
1552 unsigned long prate
)
1554 return to_clk_tegra(hw
)->fixed_rate
;
1557 struct 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
,
1564 /* Tegra20 CPU clock and reset control functions */
1565 static void tegra20_wait_cpu_in_reset(u32 cpu
)
1570 reg
= readl(reg_clk_base
+
1571 TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET
);
1573 } while (!(reg
& (1 << cpu
))); /* check CPU been reset or not */
1578 static void tegra20_put_cpu_in_reset(u32 cpu
)
1580 writel(CPU_RESET(cpu
),
1581 reg_clk_base
+ TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET
);
1585 static void tegra20_cpu_out_of_reset(u32 cpu
)
1587 writel(CPU_RESET(cpu
),
1588 reg_clk_base
+ TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR
);
1592 static void tegra20_enable_cpu_clock(u32 cpu
)
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
);
1600 reg
= readl(reg_clk_base
+ TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX
);
1603 static void tegra20_disable_cpu_clock(u32 cpu
)
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
);
1612 static 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
,
1620 void __init
tegra20_cpu_car_ops_init(void)
1622 tegra_cpu_car_ops
= &tegra20_cpu_car_ops
;