2 * linux/arch/arm/mach-omap2/clock.c
4 * Copyright (C) 2005 Texas Instruments Inc.
5 * Richard Woodruff <r-woodruff2@ti.com>
8 * Cleaned up and modified to use omap shared clock framework by
9 * Tony Lindgren <tony@atomide.com>
11 * Based on omap1 clock.c, Copyright (C) 2004 - 2005 Nokia corporation
12 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/device.h>
21 #include <linux/list.h>
22 #include <linux/errno.h>
23 #include <linux/delay.h>
24 #include <linux/clk.h>
28 #include <asm/arch/clock.h>
29 #include <asm/arch/sram.h>
31 #include "prcm-regs.h"
35 //#define DOWN_VARIABLE_DPLL 1 /* Experimental */
37 static struct prcm_config
*curr_prcm_set
;
38 static u32 curr_perf_level
= PRCM_FULL_SPEED
;
40 /*-------------------------------------------------------------------------
41 * Omap2 specific clock functions
42 *-------------------------------------------------------------------------*/
44 /* Recalculate SYST_CLK */
45 static void omap2_sys_clk_recalc(struct clk
* clk
)
47 u32 div
= PRCM_CLKSRC_CTRL
;
48 div
&= (1 << 7) | (1 << 6); /* Test if ext clk divided by 1 or 2 */
49 div
>>= clk
->rate_offset
;
50 clk
->rate
= (clk
->parent
->rate
/ div
);
54 static u32
omap2_get_dpll_rate(struct clk
* tclk
)
57 int dpll_mult
, dpll_div
, amult
;
59 dpll_mult
= (CM_CLKSEL1_PLL
>> 12) & 0x03ff; /* 10 bits */
60 dpll_div
= (CM_CLKSEL1_PLL
>> 8) & 0x0f; /* 4 bits */
61 dpll_clk
= (long long)tclk
->parent
->rate
* dpll_mult
;
62 do_div(dpll_clk
, dpll_div
+ 1);
63 amult
= CM_CLKSEL2_PLL
& 0x3;
69 static void omap2_followparent_recalc(struct clk
*clk
)
71 followparent_recalc(clk
);
74 static void omap2_propagate_rate(struct clk
* clk
)
76 if (!(clk
->flags
& RATE_FIXED
))
77 clk
->rate
= clk
->parent
->rate
;
82 /* Enable an APLL if off */
83 static void omap2_clk_fixed_enable(struct clk
*clk
)
87 if (clk
->enable_bit
== 0xff) /* Parent will do it */
92 if ((cval
& (0x3 << clk
->enable_bit
)) == (0x3 << clk
->enable_bit
))
95 cval
&= ~(0x3 << clk
->enable_bit
);
96 cval
|= (0x3 << clk
->enable_bit
);
99 if (clk
== &apll96_ck
)
101 else if (clk
== &apll54_ck
)
104 while (!CM_IDLEST_CKGEN
& cval
) { /* Wait for lock */
112 /* Enables clock without considering parent dependencies or use count
113 * REVISIT: Maybe change this to use clk->enable like on omap1?
115 static int _omap2_clk_enable(struct clk
* clk
)
119 if (clk
->flags
& ALWAYS_ENABLED
)
122 if (unlikely(clk
->enable_reg
== 0)) {
123 printk(KERN_ERR
"clock.c: Enable for %s without enable code\n",
128 if (clk
->enable_reg
== (void __iomem
*)&CM_CLKEN_PLL
) {
129 omap2_clk_fixed_enable(clk
);
133 regval32
= __raw_readl(clk
->enable_reg
);
134 regval32
|= (1 << clk
->enable_bit
);
135 __raw_writel(regval32
, clk
->enable_reg
);
141 static void omap2_clk_fixed_disable(struct clk
*clk
)
145 if(clk
->enable_bit
== 0xff) /* let parent off do it */
149 cval
&= ~(0x3 << clk
->enable_bit
);
153 /* Disables clock without considering parent dependencies or use count */
154 static void _omap2_clk_disable(struct clk
*clk
)
158 if (clk
->enable_reg
== 0)
161 if (clk
->enable_reg
== (void __iomem
*)&CM_CLKEN_PLL
) {
162 omap2_clk_fixed_disable(clk
);
166 regval32
= __raw_readl(clk
->enable_reg
);
167 regval32
&= ~(1 << clk
->enable_bit
);
168 __raw_writel(regval32
, clk
->enable_reg
);
171 static int omap2_clk_enable(struct clk
*clk
)
175 if (clk
->usecount
++ == 0) {
176 if (likely((u32
)clk
->parent
))
177 ret
= omap2_clk_enable(clk
->parent
);
179 if (unlikely(ret
!= 0)) {
184 ret
= _omap2_clk_enable(clk
);
186 if (unlikely(ret
!= 0) && clk
->parent
) {
187 omap2_clk_disable(clk
->parent
);
195 static void omap2_clk_disable(struct clk
*clk
)
197 if (clk
->usecount
> 0 && !(--clk
->usecount
)) {
198 _omap2_clk_disable(clk
);
199 if (likely((u32
)clk
->parent
))
200 omap2_clk_disable(clk
->parent
);
205 * Uses the current prcm set to tell if a rate is valid.
206 * You can go slower, but not faster within a given rate set.
208 static u32
omap2_dpll_round_rate(unsigned long target_rate
)
212 if ((CM_CLKSEL2_PLL
& 0x3) == 1) { /* DPLL clockout */
213 high
= curr_prcm_set
->dpll_speed
* 2;
214 low
= curr_prcm_set
->dpll_speed
;
215 } else { /* DPLL clockout x 2 */
216 high
= curr_prcm_set
->dpll_speed
;
217 low
= curr_prcm_set
->dpll_speed
/ 2;
220 #ifdef DOWN_VARIABLE_DPLL
221 if (target_rate
> high
)
226 if (target_rate
> low
)
235 * Used for clocks that are part of CLKSEL_xyz governed clocks.
236 * REVISIT: Maybe change to use clk->enable() functions like on omap1?
238 static void omap2_clksel_recalc(struct clk
* clk
)
240 u32 fixed
= 0, div
= 0;
242 if (clk
== &dpll_ck
) {
243 clk
->rate
= omap2_get_dpll_rate(clk
);
248 if (clk
== &iva1_mpu_int_ifck
) {
253 if ((clk
== &dss1_fck
) && ((CM_CLKSEL1_CORE
& (0x1f << 8)) == 0)) {
254 clk
->rate
= sys_ck
.rate
;
259 div
= omap2_clksel_get_divisor(clk
);
265 if (unlikely(clk
->rate
== clk
->parent
->rate
/ div
))
267 clk
->rate
= clk
->parent
->rate
/ div
;
270 if (unlikely(clk
->flags
& RATE_PROPAGATES
))
275 * Finds best divider value in an array based on the source and target
276 * rates. The divider array must be sorted with smallest divider first.
278 static inline u32
omap2_divider_from_table(u32 size
, u32
*div_array
,
279 u32 src_rate
, u32 tgt_rate
)
283 if (div_array
== NULL
)
286 for (i
=0; i
< size
; i
++) {
287 test_rate
= src_rate
/ *div_array
;
288 if (test_rate
<= tgt_rate
)
293 return ~0; /* No acceptable divider */
297 * Find divisor for the given clock and target rate.
299 * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
300 * they are only settable as part of virtual_prcm set.
302 static u32
omap2_clksel_round_rate(struct clk
*tclk
, u32 target_rate
,
305 u32 gfx_div
[] = {2, 3, 4};
306 u32 sysclkout_div
[] = {1, 2, 4, 8, 16};
307 u32 dss1_div
[] = {1, 2, 3, 4, 5, 6, 8, 9, 12, 16};
308 u32 vylnq_div
[] = {1, 2, 3, 4, 6, 8, 9, 12, 16, 18};
309 u32 best_div
= ~0, asize
= 0;
310 u32
*div_array
= NULL
;
312 switch (tclk
->flags
& SRC_RATE_SEL_MASK
) {
318 return omap2_dpll_round_rate(target_rate
);
319 case CM_SYSCLKOUT_SEL1
:
321 div_array
= sysclkout_div
;
324 if(tclk
== &dss1_fck
){
325 if(tclk
->parent
== &core_ck
){
327 div_array
= dss1_div
;
329 *new_div
= 0; /* fixed clk */
330 return(tclk
->parent
->rate
);
332 } else if((tclk
== &vlynq_fck
) && cpu_is_omap2420()){
333 if(tclk
->parent
== &core_ck
){
335 div_array
= vylnq_div
;
337 *new_div
= 0; /* fixed clk */
338 return(tclk
->parent
->rate
);
344 best_div
= omap2_divider_from_table(asize
, div_array
,
345 tclk
->parent
->rate
, target_rate
);
348 return best_div
; /* signal error */
352 return (tclk
->parent
->rate
/ best_div
);
355 /* Given a clock and a rate apply a clock specific rounding function */
356 static long omap2_clk_round_rate(struct clk
*clk
, unsigned long rate
)
361 if (clk
->flags
& RATE_FIXED
)
364 if (clk
->flags
& RATE_CKCTL
) {
365 valid_rate
= omap2_clksel_round_rate(clk
, rate
, &new_div
);
369 if (clk
->round_rate
!= 0)
370 return clk
->round_rate(clk
, rate
);
376 * Check the DLL lock state, and return tue if running in unlock mode.
377 * This is needed to compenste for the shifted DLL value in unlock mode.
379 static u32
omap2_dll_force_needed(void)
381 u32 dll_state
= SDRC_DLLA_CTRL
; /* dlla and dllb are a set */
383 if ((dll_state
& (1 << 2)) == (1 << 2))
389 static u32
omap2_reprogram_sdrc(u32 level
, u32 force
)
391 u32 slow_dll_ctrl
, fast_dll_ctrl
, m_type
;
392 u32 prev
= curr_perf_level
, flags
;
394 if ((curr_perf_level
== level
) && !force
)
397 m_type
= omap2_memory_get_type();
398 slow_dll_ctrl
= omap2_memory_get_slow_dll_ctrl();
399 fast_dll_ctrl
= omap2_memory_get_fast_dll_ctrl();
401 if (level
== PRCM_HALF_SPEED
) {
402 local_irq_save(flags
);
403 PRCM_VOLTSETUP
= 0xffff;
404 omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED
,
405 slow_dll_ctrl
, m_type
);
406 curr_perf_level
= PRCM_HALF_SPEED
;
407 local_irq_restore(flags
);
409 if (level
== PRCM_FULL_SPEED
) {
410 local_irq_save(flags
);
411 PRCM_VOLTSETUP
= 0xffff;
412 omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED
,
413 fast_dll_ctrl
, m_type
);
414 curr_perf_level
= PRCM_FULL_SPEED
;
415 local_irq_restore(flags
);
421 static int omap2_reprogram_dpll(struct clk
* clk
, unsigned long rate
)
423 u32 flags
, cur_rate
, low
, mult
, div
, valid_rate
, done_rate
;
425 struct prcm_config tmpset
;
428 local_irq_save(flags
);
429 cur_rate
= omap2_get_dpll_rate(&dpll_ck
);
430 mult
= CM_CLKSEL2_PLL
& 0x3;
432 if ((rate
== (cur_rate
/ 2)) && (mult
== 2)) {
433 omap2_reprogram_sdrc(PRCM_HALF_SPEED
, 1);
434 } else if ((rate
== (cur_rate
* 2)) && (mult
== 1)) {
435 omap2_reprogram_sdrc(PRCM_FULL_SPEED
, 1);
436 } else if (rate
!= cur_rate
) {
437 valid_rate
= omap2_dpll_round_rate(rate
);
438 if (valid_rate
!= rate
)
441 if ((CM_CLKSEL2_PLL
& 0x3) == 1)
442 low
= curr_prcm_set
->dpll_speed
;
444 low
= curr_prcm_set
->dpll_speed
/ 2;
446 tmpset
.cm_clksel1_pll
= CM_CLKSEL1_PLL
;
447 tmpset
.cm_clksel1_pll
&= ~(0x3FFF << 8);
448 div
= ((curr_prcm_set
->xtal_speed
/ 1000000) - 1);
449 tmpset
.cm_clksel2_pll
= CM_CLKSEL2_PLL
;
450 tmpset
.cm_clksel2_pll
&= ~0x3;
452 tmpset
.cm_clksel2_pll
|= 0x2;
453 mult
= ((rate
/ 2) / 1000000);
454 done_rate
= PRCM_FULL_SPEED
;
456 tmpset
.cm_clksel2_pll
|= 0x1;
457 mult
= (rate
/ 1000000);
458 done_rate
= PRCM_HALF_SPEED
;
460 tmpset
.cm_clksel1_pll
|= ((div
<< 8) | (mult
<< 12));
463 tmpset
.base_sdrc_rfr
= V24XX_SDRC_RFR_CTRL_BYPASS
;
465 if (rate
== curr_prcm_set
->xtal_speed
) /* If asking for 1-1 */
468 omap2_reprogram_sdrc(PRCM_FULL_SPEED
, 1); /* For init_mem */
470 /* Force dll lock mode */
471 omap2_set_prcm(tmpset
.cm_clksel1_pll
, tmpset
.base_sdrc_rfr
,
474 /* Errata: ret dll entry state */
475 omap2_init_memory_params(omap2_dll_force_needed());
476 omap2_reprogram_sdrc(done_rate
, 0);
478 omap2_clksel_recalc(&dpll_ck
);
482 local_irq_restore(flags
);
486 /* Just return the MPU speed */
487 static void omap2_mpu_recalc(struct clk
* clk
)
489 clk
->rate
= curr_prcm_set
->mpu_speed
;
493 * Look for a rate equal or less than the target rate given a configuration set.
495 * What's not entirely clear is "which" field represents the key field.
496 * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
497 * just uses the ARM rates.
499 static long omap2_round_to_table_rate(struct clk
* clk
, unsigned long rate
)
501 struct prcm_config
* ptr
;
504 if (clk
!= &virt_prcm_set
)
507 highest_rate
= -EINVAL
;
509 for (ptr
= rate_table
; ptr
->mpu_speed
; ptr
++) {
510 if (ptr
->xtal_speed
!= sys_ck
.rate
)
513 highest_rate
= ptr
->mpu_speed
;
515 /* Can check only after xtal frequency check */
516 if (ptr
->mpu_speed
<= rate
)
523 * omap2_convert_field_to_div() - turn field value into integer divider
525 static u32
omap2_clksel_to_divisor(u32 div_sel
, u32 field_val
)
528 u32 clkout_array
[] = {1, 2, 4, 8, 16};
530 if ((div_sel
& SRC_RATE_SEL_MASK
) == CM_SYSCLKOUT_SEL1
) {
531 for (i
= 0; i
< 5; i
++) {
533 return clkout_array
[i
];
541 * Returns the CLKSEL divider register value
542 * REVISIT: This should be cleaned up to work nicely with void __iomem *
544 static u32
omap2_get_clksel(u32
*div_sel
, u32
*field_mask
,
548 u32 reg_val
, div_off
;
552 div_off
= clk
->rate_offset
;
554 switch ((*div_sel
& SRC_RATE_SEL_MASK
)) {
556 div_addr
= (u32
)&CM_CLKSEL_MPU
;
560 div_addr
= (u32
)&CM_CLKSEL_DSP
;
561 if (cpu_is_omap2420()) {
562 if ((div_off
== 0) || (div_off
== 8))
564 else if (div_off
== 5)
566 } else if (cpu_is_omap2430()) {
569 else if (div_off
== 5)
574 div_addr
= (u32
)&CM_CLKSEL_GFX
;
579 div_addr
= (u32
)&CM_CLKSEL_MDM
;
583 case CM_SYSCLKOUT_SEL1
:
584 div_addr
= (u32
)&PRCM_CLKOUT_CTRL
;
585 if ((div_off
== 3) || (div_off
= 11))
589 div_addr
= (u32
)&CM_CLKSEL1_CORE
;
593 case 15: /* vylnc-2420 */
607 if (unlikely(mask
== ~0))
612 if (unlikely(div_addr
== 0))
616 reg_val
= __raw_readl((void __iomem
*)div_addr
) & (mask
<< div_off
);
618 /* Normalize back to divider value */
625 * Return divider to be applied to parent clock.
628 static u32
omap2_clksel_get_divisor(struct clk
*clk
)
631 u32 div
, div_sel
, div_off
, field_mask
, field_val
;
633 /* isolate control register */
634 div_sel
= (SRC_RATE_SEL_MASK
& clk
->flags
);
636 div_off
= clk
->rate_offset
;
637 field_val
= omap2_get_clksel(&div_sel
, &field_mask
, clk
);
641 div_sel
= (SRC_RATE_SEL_MASK
& clk
->flags
);
642 div
= omap2_clksel_to_divisor(div_sel
, field_val
);
647 /* Set the clock rate for a clock source */
648 static int omap2_clk_set_rate(struct clk
*clk
, unsigned long rate
)
653 u32 div_sel
, div_off
, field_mask
, field_val
, reg_val
, validrate
;
656 if (!(clk
->flags
& CONFIG_PARTICIPANT
) && (clk
->flags
& RATE_CKCTL
)) {
658 return omap2_reprogram_dpll(clk
, rate
);
660 /* Isolate control register */
661 div_sel
= (SRC_RATE_SEL_MASK
& clk
->flags
);
662 div_off
= clk
->rate_offset
;
664 validrate
= omap2_clksel_round_rate(clk
, rate
, &new_div
);
665 if (validrate
!= rate
)
668 field_val
= omap2_get_clksel(&div_sel
, &field_mask
, clk
);
672 if (clk
->flags
& CM_SYSCLKOUT_SEL1
) {
693 reg
= (void __iomem
*)div_sel
;
695 reg_val
= __raw_readl(reg
);
696 reg_val
&= ~(field_mask
<< div_off
);
697 reg_val
|= (field_val
<< div_off
);
699 __raw_writel(reg_val
, reg
);
700 clk
->rate
= clk
->parent
->rate
/ field_val
;
702 if (clk
->flags
& DELAYED_APP
)
703 __raw_writel(0x1, (void __iomem
*)&PRCM_CLKCFG_CTRL
);
705 } else if (clk
->set_rate
!= 0)
706 ret
= clk
->set_rate(clk
, rate
);
708 if (unlikely(ret
== 0 && (clk
->flags
& RATE_PROPAGATES
)))
714 /* Converts encoded control register address into a full address */
715 static u32
omap2_get_src_field(u32
*type_to_addr
, u32 reg_offset
,
716 struct clk
*src_clk
, u32
*field_mask
)
718 u32 val
= ~0, src_reg_addr
= 0, mask
= 0;
720 /* Find target control register.*/
721 switch ((*type_to_addr
& SRC_RATE_SEL_MASK
)) {
723 src_reg_addr
= (u32
)&CM_CLKSEL1_CORE
;
724 if (reg_offset
== 13) { /* DSS2_fclk */
726 if (src_clk
== &sys_ck
)
728 if (src_clk
== &func_48m_ck
)
730 } else if (reg_offset
== 8) { /* DSS1_fclk */
732 if (src_clk
== &sys_ck
)
734 else if (src_clk
== &core_ck
) /* divided clock */
735 val
= 0x10; /* rate needs fixing */
736 } else if ((reg_offset
== 15) && cpu_is_omap2420()){ /*vlnyq*/
738 if(src_clk
== &func_96m_ck
)
740 else if (src_clk
== &core_ck
)
745 src_reg_addr
= (u32
)&CM_CLKSEL2_CORE
;
747 if (src_clk
== &func_32k_ck
)
749 if (src_clk
== &sys_ck
)
751 if (src_clk
== &alt_ck
)
755 src_reg_addr
= (u32
)&CM_CLKSEL_WKUP
;
757 if (src_clk
== &func_32k_ck
)
759 if (src_clk
== &sys_ck
)
761 if (src_clk
== &alt_ck
)
765 src_reg_addr
= (u32
)&CM_CLKSEL1_PLL
;
767 if (reg_offset
== 0x3) {
768 if (src_clk
== &apll96_ck
)
770 if (src_clk
== &alt_ck
)
773 else if (reg_offset
== 0x5) {
774 if (src_clk
== &apll54_ck
)
776 if (src_clk
== &alt_ck
)
781 src_reg_addr
= (u32
)&CM_CLKSEL2_PLL
;
783 if (src_clk
== &func_32k_ck
)
785 if (src_clk
== &dpll_ck
)
788 case CM_SYSCLKOUT_SEL1
:
789 src_reg_addr
= (u32
)&PRCM_CLKOUT_CTRL
;
791 if (src_clk
== &dpll_ck
)
793 if (src_clk
== &sys_ck
)
795 if (src_clk
== &func_96m_ck
)
797 if (src_clk
== &func_54m_ck
)
802 if (val
== ~0) /* Catch errors in offset */
805 *type_to_addr
= src_reg_addr
;
811 static int omap2_clk_set_parent(struct clk
*clk
, struct clk
*new_parent
)
814 u32 src_sel
, src_off
, field_val
, field_mask
, reg_val
, rate
;
817 if (unlikely(clk
->flags
& CONFIG_PARTICIPANT
))
820 if (clk
->flags
& SRC_SEL_MASK
) { /* On-chip SEL collection */
821 src_sel
= (SRC_RATE_SEL_MASK
& clk
->flags
);
822 src_off
= clk
->src_offset
;
825 goto set_parent_error
;
827 field_val
= omap2_get_src_field(&src_sel
, src_off
, new_parent
,
830 reg
= (void __iomem
*)src_sel
;
832 if (clk
->usecount
> 0)
833 _omap2_clk_disable(clk
);
835 /* Set new source value (previous dividers if any in effect) */
836 reg_val
= __raw_readl(reg
) & ~(field_mask
<< src_off
);
837 reg_val
|= (field_val
<< src_off
);
838 __raw_writel(reg_val
, reg
);
840 if (clk
->flags
& DELAYED_APP
)
841 __raw_writel(0x1, (void __iomem
*)&PRCM_CLKCFG_CTRL
);
843 if (clk
->usecount
> 0)
844 _omap2_clk_enable(clk
);
846 clk
->parent
= new_parent
;
848 /* SRC_RATE_SEL_MASK clocks follow their parents rates.*/
849 if ((new_parent
== &core_ck
) && (clk
== &dss1_fck
))
850 clk
->rate
= new_parent
->rate
/ 0x10;
852 clk
->rate
= new_parent
->rate
;
854 if (unlikely(clk
->flags
& RATE_PROPAGATES
))
859 clk
->parent
= new_parent
;
860 rate
= new_parent
->rate
;
861 omap2_clk_set_rate(clk
, rate
);
869 /* Sets basic clocks based on the specified rate */
870 static int omap2_select_table_rate(struct clk
* clk
, unsigned long rate
)
872 u32 flags
, cur_rate
, done_rate
, bypass
= 0;
874 struct prcm_config
*prcm
;
875 unsigned long found_speed
= 0;
877 if (clk
!= &virt_prcm_set
)
880 /* FIXME: Change cpu_is_omap2420() to cpu_is_omap242x() */
881 if (cpu_is_omap2420())
882 cpu_mask
= RATE_IN_242X
;
883 else if (cpu_is_omap2430())
884 cpu_mask
= RATE_IN_243X
;
886 for (prcm
= rate_table
; prcm
->mpu_speed
; prcm
++) {
887 if (!(prcm
->flags
& cpu_mask
))
890 if (prcm
->xtal_speed
!= sys_ck
.rate
)
893 if (prcm
->mpu_speed
<= rate
) {
894 found_speed
= prcm
->mpu_speed
;
900 printk(KERN_INFO
"Could not set MPU rate to %luMHz\n",
905 curr_prcm_set
= prcm
;
906 cur_rate
= omap2_get_dpll_rate(&dpll_ck
);
908 if (prcm
->dpll_speed
== cur_rate
/ 2) {
909 omap2_reprogram_sdrc(PRCM_HALF_SPEED
, 1);
910 } else if (prcm
->dpll_speed
== cur_rate
* 2) {
911 omap2_reprogram_sdrc(PRCM_FULL_SPEED
, 1);
912 } else if (prcm
->dpll_speed
!= cur_rate
) {
913 local_irq_save(flags
);
915 if (prcm
->dpll_speed
== prcm
->xtal_speed
)
918 if ((prcm
->cm_clksel2_pll
& 0x3) == 2)
919 done_rate
= PRCM_FULL_SPEED
;
921 done_rate
= PRCM_HALF_SPEED
;
924 CM_CLKSEL_MPU
= prcm
->cm_clksel_mpu
;
926 /* dsp + iva1 div(2420), iva2.1(2430) */
927 CM_CLKSEL_DSP
= prcm
->cm_clksel_dsp
;
929 CM_CLKSEL_GFX
= prcm
->cm_clksel_gfx
;
931 /* Major subsystem dividers */
932 CM_CLKSEL1_CORE
= prcm
->cm_clksel1_core
;
933 if (cpu_is_omap2430())
934 CM_CLKSEL_MDM
= prcm
->cm_clksel_mdm
;
936 /* x2 to enter init_mem */
937 omap2_reprogram_sdrc(PRCM_FULL_SPEED
, 1);
939 omap2_set_prcm(prcm
->cm_clksel1_pll
, prcm
->base_sdrc_rfr
,
942 omap2_init_memory_params(omap2_dll_force_needed());
943 omap2_reprogram_sdrc(done_rate
, 0);
945 local_irq_restore(flags
);
947 omap2_clksel_recalc(&dpll_ck
);
952 /*-------------------------------------------------------------------------
953 * Omap2 clock reset and init functions
954 *-------------------------------------------------------------------------*/
956 static struct clk_functions omap2_clk_functions
= {
957 .clk_enable
= omap2_clk_enable
,
958 .clk_disable
= omap2_clk_disable
,
959 .clk_round_rate
= omap2_clk_round_rate
,
960 .clk_set_rate
= omap2_clk_set_rate
,
961 .clk_set_parent
= omap2_clk_set_parent
,
964 static void __init
omap2_get_crystal_rate(struct clk
*osc
, struct clk
*sys
)
966 u32 div
, aplls
, sclk
= 13000000;
968 aplls
= CM_CLKSEL1_PLL
;
969 aplls
&= ((1 << 23) | (1 << 24) | (1 << 25));
970 aplls
>>= 23; /* Isolate field, 0,2,3 */
979 div
= PRCM_CLKSRC_CTRL
;
980 div
&= ((1 << 7) | (1 << 6));
981 div
>>= sys
->rate_offset
;
983 osc
->rate
= sclk
* div
;
987 #ifdef CONFIG_OMAP_RESET_CLOCKS
988 static void __init
omap2_disable_unused_clocks(void)
993 list_for_each_entry(ck
, &clocks
, node
) {
994 if (ck
->usecount
> 0 || (ck
->flags
& ALWAYS_ENABLED
) ||
998 regval32
= __raw_readl(ck
->enable_reg
);
999 if ((regval32
& (1 << ck
->enable_bit
)) == 0)
1002 printk(KERN_INFO
"Disabling unused clock \"%s\"\n", ck
->name
);
1003 _omap2_clk_disable(ck
);
1006 late_initcall(omap2_disable_unused_clocks
);
1010 * Switch the MPU rate if specified on cmdline.
1011 * We cannot do this early until cmdline is parsed.
1013 static int __init
omap2_clk_arch_init(void)
1018 if (omap2_select_table_rate(&virt_prcm_set
, mpurate
))
1019 printk(KERN_ERR
"Could not find matching MPU rate\n");
1021 propagate_rate(&osc_ck
); /* update main root fast */
1022 propagate_rate(&func_32k_ck
); /* update main root slow */
1024 printk(KERN_INFO
"Switched to new clocking rate (Crystal/DPLL/MPU): "
1025 "%ld.%01ld/%ld/%ld MHz\n",
1026 (sys_ck
.rate
/ 1000000), (sys_ck
.rate
/ 100000) % 10,
1027 (dpll_ck
.rate
/ 1000000), (mpu_ck
.rate
/ 1000000)) ;
1031 arch_initcall(omap2_clk_arch_init
);
1033 int __init
omap2_clk_init(void)
1035 struct prcm_config
*prcm
;
1039 clk_init(&omap2_clk_functions
);
1040 omap2_get_crystal_rate(&osc_ck
, &sys_ck
);
1042 for (clkp
= onchip_clks
; clkp
< onchip_clks
+ ARRAY_SIZE(onchip_clks
);
1045 if ((*clkp
)->flags
& CLOCK_IN_OMAP242X
&& cpu_is_omap2420()) {
1046 clk_register(*clkp
);
1050 if ((*clkp
)->flags
& CLOCK_IN_OMAP243X
&& cpu_is_omap2430()) {
1051 clk_register(*clkp
);
1056 /* Check the MPU rate set by bootloader */
1057 clkrate
= omap2_get_dpll_rate(&dpll_ck
);
1058 for (prcm
= rate_table
; prcm
->mpu_speed
; prcm
++) {
1059 if (prcm
->xtal_speed
!= sys_ck
.rate
)
1061 if (prcm
->dpll_speed
<= clkrate
)
1064 curr_prcm_set
= prcm
;
1066 propagate_rate(&osc_ck
); /* update main root fast */
1067 propagate_rate(&func_32k_ck
); /* update main root slow */
1069 printk(KERN_INFO
"Clocking rate (Crystal/DPLL/MPU): "
1070 "%ld.%01ld/%ld/%ld MHz\n",
1071 (sys_ck
.rate
/ 1000000), (sys_ck
.rate
/ 100000) % 10,
1072 (dpll_ck
.rate
/ 1000000), (mpu_ck
.rate
/ 1000000)) ;
1075 * Only enable those clocks we will need, let the drivers
1076 * enable other clocks as necessary
1078 clk_enable(&sync_32k_ick
);
1079 clk_enable(&omapctrl_ick
);
1080 if (cpu_is_omap2430())
1081 clk_enable(&sdrc_ick
);