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>
30 #include <asm/div64.h>
32 #include "prcm-regs.h"
38 //#define DOWN_VARIABLE_DPLL 1 /* Experimental */
40 static struct prcm_config
*curr_prcm_set
;
41 static u32 curr_perf_level
= PRCM_FULL_SPEED
;
42 static struct clk
*vclk
;
43 static struct clk
*sclk
;
45 /*-------------------------------------------------------------------------
46 * Omap2 specific clock functions
47 *-------------------------------------------------------------------------*/
49 /* Recalculate SYST_CLK */
50 static void omap2_sys_clk_recalc(struct clk
* clk
)
52 u32 div
= PRCM_CLKSRC_CTRL
;
53 div
&= (1 << 7) | (1 << 6); /* Test if ext clk divided by 1 or 2 */
54 div
>>= clk
->rate_offset
;
55 clk
->rate
= (clk
->parent
->rate
/ div
);
59 static u32
omap2_get_dpll_rate(struct clk
* tclk
)
62 int dpll_mult
, dpll_div
, amult
;
64 dpll_mult
= (CM_CLKSEL1_PLL
>> 12) & 0x03ff; /* 10 bits */
65 dpll_div
= (CM_CLKSEL1_PLL
>> 8) & 0x0f; /* 4 bits */
66 dpll_clk
= (long long)tclk
->parent
->rate
* dpll_mult
;
67 do_div(dpll_clk
, dpll_div
+ 1);
68 amult
= CM_CLKSEL2_PLL
& 0x3;
74 static void omap2_followparent_recalc(struct clk
*clk
)
76 followparent_recalc(clk
);
79 static void omap2_propagate_rate(struct clk
* clk
)
81 if (!(clk
->flags
& RATE_FIXED
))
82 clk
->rate
= clk
->parent
->rate
;
87 static void omap2_set_osc_ck(int enable
)
90 PRCM_CLKSRC_CTRL
&= ~(0x3 << 3);
92 PRCM_CLKSRC_CTRL
|= 0x3 << 3;
95 /* Enable an APLL if off */
96 static void omap2_clk_fixed_enable(struct clk
*clk
)
100 if (clk
->enable_bit
== 0xff) /* Parent will do it */
105 if ((cval
& (0x3 << clk
->enable_bit
)) == (0x3 << clk
->enable_bit
))
108 cval
&= ~(0x3 << clk
->enable_bit
);
109 cval
|= (0x3 << clk
->enable_bit
);
112 if (clk
== &apll96_ck
)
114 else if (clk
== &apll54_ck
)
117 while (!(CM_IDLEST_CKGEN
& cval
)) { /* Wait for lock */
121 printk(KERN_ERR
"Clock %s didn't lock\n", clk
->name
);
127 static void omap2_clk_wait_ready(struct clk
*clk
)
129 unsigned long reg
, other_reg
, st_reg
;
133 reg
= (unsigned long) clk
->enable_reg
;
134 if (reg
== (unsigned long) &CM_FCLKEN1_CORE
||
135 reg
== (unsigned long) &CM_FCLKEN2_CORE
)
136 other_reg
= (reg
& ~0xf0) | 0x10;
137 else if (reg
== (unsigned long) &CM_ICLKEN1_CORE
||
138 reg
== (unsigned long) &CM_ICLKEN2_CORE
)
139 other_reg
= (reg
& ~0xf0) | 0x00;
143 /* No check for DSS or cam clocks */
144 if ((reg
& 0x0f) == 0) {
145 if (clk
->enable_bit
<= 1 || clk
->enable_bit
== 31)
149 /* Check if both functional and interface clocks
151 bit
= 1 << clk
->enable_bit
;
152 if (!(__raw_readl(other_reg
) & bit
))
154 st_reg
= (other_reg
& ~0xf0) | 0x20;
156 while (!(__raw_readl(st_reg
) & bit
)) {
159 printk(KERN_ERR
"Timeout enabling clock %s\n", clk
->name
);
164 pr_debug("Clock %s stable after %d loops\n", clk
->name
, i
);
167 /* Enables clock without considering parent dependencies or use count
168 * REVISIT: Maybe change this to use clk->enable like on omap1?
170 static int _omap2_clk_enable(struct clk
* clk
)
174 if (clk
->flags
& ALWAYS_ENABLED
)
177 if (unlikely(clk
== &osc_ck
)) {
182 if (unlikely(clk
->enable_reg
== 0)) {
183 printk(KERN_ERR
"clock.c: Enable for %s without enable code\n",
188 if (clk
->enable_reg
== (void __iomem
*)&CM_CLKEN_PLL
) {
189 omap2_clk_fixed_enable(clk
);
193 regval32
= __raw_readl(clk
->enable_reg
);
194 regval32
|= (1 << clk
->enable_bit
);
195 __raw_writel(regval32
, clk
->enable_reg
);
198 omap2_clk_wait_ready(clk
);
204 static void omap2_clk_fixed_disable(struct clk
*clk
)
208 if(clk
->enable_bit
== 0xff) /* let parent off do it */
212 cval
&= ~(0x3 << clk
->enable_bit
);
216 /* Disables clock without considering parent dependencies or use count */
217 static void _omap2_clk_disable(struct clk
*clk
)
221 if (unlikely(clk
== &osc_ck
)) {
226 if (clk
->enable_reg
== 0)
229 if (clk
->enable_reg
== (void __iomem
*)&CM_CLKEN_PLL
) {
230 omap2_clk_fixed_disable(clk
);
234 regval32
= __raw_readl(clk
->enable_reg
);
235 regval32
&= ~(1 << clk
->enable_bit
);
236 __raw_writel(regval32
, clk
->enable_reg
);
240 static int omap2_clk_enable(struct clk
*clk
)
244 if (clk
->usecount
++ == 0) {
245 if (likely((u32
)clk
->parent
))
246 ret
= omap2_clk_enable(clk
->parent
);
248 if (unlikely(ret
!= 0)) {
253 ret
= _omap2_clk_enable(clk
);
255 if (unlikely(ret
!= 0) && clk
->parent
) {
256 omap2_clk_disable(clk
->parent
);
264 static void omap2_clk_disable(struct clk
*clk
)
266 if (clk
->usecount
> 0 && !(--clk
->usecount
)) {
267 _omap2_clk_disable(clk
);
268 if (likely((u32
)clk
->parent
))
269 omap2_clk_disable(clk
->parent
);
274 * Uses the current prcm set to tell if a rate is valid.
275 * You can go slower, but not faster within a given rate set.
277 static u32
omap2_dpll_round_rate(unsigned long target_rate
)
281 if ((CM_CLKSEL2_PLL
& 0x3) == 1) { /* DPLL clockout */
282 high
= curr_prcm_set
->dpll_speed
* 2;
283 low
= curr_prcm_set
->dpll_speed
;
284 } else { /* DPLL clockout x 2 */
285 high
= curr_prcm_set
->dpll_speed
;
286 low
= curr_prcm_set
->dpll_speed
/ 2;
289 #ifdef DOWN_VARIABLE_DPLL
290 if (target_rate
> high
)
295 if (target_rate
> low
)
304 * Used for clocks that are part of CLKSEL_xyz governed clocks.
305 * REVISIT: Maybe change to use clk->enable() functions like on omap1?
307 static void omap2_clksel_recalc(struct clk
* clk
)
309 u32 fixed
= 0, div
= 0;
311 if (clk
== &dpll_ck
) {
312 clk
->rate
= omap2_get_dpll_rate(clk
);
317 if (clk
== &iva1_mpu_int_ifck
) {
322 if ((clk
== &dss1_fck
) && ((CM_CLKSEL1_CORE
& (0x1f << 8)) == 0)) {
323 clk
->rate
= sys_ck
.rate
;
328 div
= omap2_clksel_get_divisor(clk
);
334 if (unlikely(clk
->rate
== clk
->parent
->rate
/ div
))
336 clk
->rate
= clk
->parent
->rate
/ div
;
339 if (unlikely(clk
->flags
& RATE_PROPAGATES
))
344 * Finds best divider value in an array based on the source and target
345 * rates. The divider array must be sorted with smallest divider first.
347 static inline u32
omap2_divider_from_table(u32 size
, u32
*div_array
,
348 u32 src_rate
, u32 tgt_rate
)
352 if (div_array
== NULL
)
355 for (i
=0; i
< size
; i
++) {
356 test_rate
= src_rate
/ *div_array
;
357 if (test_rate
<= tgt_rate
)
362 return ~0; /* No acceptable divider */
366 * Find divisor for the given clock and target rate.
368 * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
369 * they are only settable as part of virtual_prcm set.
371 static u32
omap2_clksel_round_rate(struct clk
*tclk
, u32 target_rate
,
374 u32 gfx_div
[] = {2, 3, 4};
375 u32 sysclkout_div
[] = {1, 2, 4, 8, 16};
376 u32 dss1_div
[] = {1, 2, 3, 4, 5, 6, 8, 9, 12, 16};
377 u32 vylnq_div
[] = {1, 2, 3, 4, 6, 8, 9, 12, 16, 18};
378 u32 best_div
= ~0, asize
= 0;
379 u32
*div_array
= NULL
;
381 switch (tclk
->flags
& SRC_RATE_SEL_MASK
) {
387 return omap2_dpll_round_rate(target_rate
);
388 case CM_SYSCLKOUT_SEL1
:
390 div_array
= sysclkout_div
;
393 if(tclk
== &dss1_fck
){
394 if(tclk
->parent
== &core_ck
){
396 div_array
= dss1_div
;
398 *new_div
= 0; /* fixed clk */
399 return(tclk
->parent
->rate
);
401 } else if((tclk
== &vlynq_fck
) && cpu_is_omap2420()){
402 if(tclk
->parent
== &core_ck
){
404 div_array
= vylnq_div
;
406 *new_div
= 0; /* fixed clk */
407 return(tclk
->parent
->rate
);
413 best_div
= omap2_divider_from_table(asize
, div_array
,
414 tclk
->parent
->rate
, target_rate
);
417 return best_div
; /* signal error */
421 return (tclk
->parent
->rate
/ best_div
);
424 /* Given a clock and a rate apply a clock specific rounding function */
425 static long omap2_clk_round_rate(struct clk
*clk
, unsigned long rate
)
430 if (clk
->flags
& RATE_FIXED
)
433 if (clk
->flags
& RATE_CKCTL
) {
434 valid_rate
= omap2_clksel_round_rate(clk
, rate
, &new_div
);
438 if (clk
->round_rate
!= 0)
439 return clk
->round_rate(clk
, rate
);
445 * Check the DLL lock state, and return tue if running in unlock mode.
446 * This is needed to compensate for the shifted DLL value in unlock mode.
448 static u32
omap2_dll_force_needed(void)
450 u32 dll_state
= SDRC_DLLA_CTRL
; /* dlla and dllb are a set */
452 if ((dll_state
& (1 << 2)) == (1 << 2))
458 static u32
omap2_reprogram_sdrc(u32 level
, u32 force
)
460 u32 slow_dll_ctrl
, fast_dll_ctrl
, m_type
;
461 u32 prev
= curr_perf_level
, flags
;
463 if ((curr_perf_level
== level
) && !force
)
466 m_type
= omap2_memory_get_type();
467 slow_dll_ctrl
= omap2_memory_get_slow_dll_ctrl();
468 fast_dll_ctrl
= omap2_memory_get_fast_dll_ctrl();
470 if (level
== PRCM_HALF_SPEED
) {
471 local_irq_save(flags
);
472 PRCM_VOLTSETUP
= 0xffff;
473 omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED
,
474 slow_dll_ctrl
, m_type
);
475 curr_perf_level
= PRCM_HALF_SPEED
;
476 local_irq_restore(flags
);
478 if (level
== PRCM_FULL_SPEED
) {
479 local_irq_save(flags
);
480 PRCM_VOLTSETUP
= 0xffff;
481 omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED
,
482 fast_dll_ctrl
, m_type
);
483 curr_perf_level
= PRCM_FULL_SPEED
;
484 local_irq_restore(flags
);
490 static int omap2_reprogram_dpll(struct clk
* clk
, unsigned long rate
)
492 u32 flags
, cur_rate
, low
, mult
, div
, valid_rate
, done_rate
;
494 struct prcm_config tmpset
;
497 local_irq_save(flags
);
498 cur_rate
= omap2_get_dpll_rate(&dpll_ck
);
499 mult
= CM_CLKSEL2_PLL
& 0x3;
501 if ((rate
== (cur_rate
/ 2)) && (mult
== 2)) {
502 omap2_reprogram_sdrc(PRCM_HALF_SPEED
, 1);
503 } else if ((rate
== (cur_rate
* 2)) && (mult
== 1)) {
504 omap2_reprogram_sdrc(PRCM_FULL_SPEED
, 1);
505 } else if (rate
!= cur_rate
) {
506 valid_rate
= omap2_dpll_round_rate(rate
);
507 if (valid_rate
!= rate
)
510 if ((CM_CLKSEL2_PLL
& 0x3) == 1)
511 low
= curr_prcm_set
->dpll_speed
;
513 low
= curr_prcm_set
->dpll_speed
/ 2;
515 tmpset
.cm_clksel1_pll
= CM_CLKSEL1_PLL
;
516 tmpset
.cm_clksel1_pll
&= ~(0x3FFF << 8);
517 div
= ((curr_prcm_set
->xtal_speed
/ 1000000) - 1);
518 tmpset
.cm_clksel2_pll
= CM_CLKSEL2_PLL
;
519 tmpset
.cm_clksel2_pll
&= ~0x3;
521 tmpset
.cm_clksel2_pll
|= 0x2;
522 mult
= ((rate
/ 2) / 1000000);
523 done_rate
= PRCM_FULL_SPEED
;
525 tmpset
.cm_clksel2_pll
|= 0x1;
526 mult
= (rate
/ 1000000);
527 done_rate
= PRCM_HALF_SPEED
;
529 tmpset
.cm_clksel1_pll
|= ((div
<< 8) | (mult
<< 12));
532 tmpset
.base_sdrc_rfr
= V24XX_SDRC_RFR_CTRL_BYPASS
;
534 if (rate
== curr_prcm_set
->xtal_speed
) /* If asking for 1-1 */
537 omap2_reprogram_sdrc(PRCM_FULL_SPEED
, 1); /* For init_mem */
539 /* Force dll lock mode */
540 omap2_set_prcm(tmpset
.cm_clksel1_pll
, tmpset
.base_sdrc_rfr
,
543 /* Errata: ret dll entry state */
544 omap2_init_memory_params(omap2_dll_force_needed());
545 omap2_reprogram_sdrc(done_rate
, 0);
547 omap2_clksel_recalc(&dpll_ck
);
551 local_irq_restore(flags
);
555 /* Just return the MPU speed */
556 static void omap2_mpu_recalc(struct clk
* clk
)
558 clk
->rate
= curr_prcm_set
->mpu_speed
;
562 * Look for a rate equal or less than the target rate given a configuration set.
564 * What's not entirely clear is "which" field represents the key field.
565 * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
566 * just uses the ARM rates.
568 static long omap2_round_to_table_rate(struct clk
* clk
, unsigned long rate
)
570 struct prcm_config
* ptr
;
573 if (clk
!= &virt_prcm_set
)
576 highest_rate
= -EINVAL
;
578 for (ptr
= rate_table
; ptr
->mpu_speed
; ptr
++) {
579 if (ptr
->xtal_speed
!= sys_ck
.rate
)
582 highest_rate
= ptr
->mpu_speed
;
584 /* Can check only after xtal frequency check */
585 if (ptr
->mpu_speed
<= rate
)
592 * omap2_convert_field_to_div() - turn field value into integer divider
594 static u32
omap2_clksel_to_divisor(u32 div_sel
, u32 field_val
)
597 u32 clkout_array
[] = {1, 2, 4, 8, 16};
599 if ((div_sel
& SRC_RATE_SEL_MASK
) == CM_SYSCLKOUT_SEL1
) {
600 for (i
= 0; i
< 5; i
++) {
602 return clkout_array
[i
];
610 * Returns the CLKSEL divider register value
611 * REVISIT: This should be cleaned up to work nicely with void __iomem *
613 static u32
omap2_get_clksel(u32
*div_sel
, u32
*field_mask
,
617 u32 reg_val
, div_off
;
621 div_off
= clk
->rate_offset
;
623 switch ((*div_sel
& SRC_RATE_SEL_MASK
)) {
625 div_addr
= (u32
)&CM_CLKSEL_MPU
;
629 div_addr
= (u32
)&CM_CLKSEL_DSP
;
630 if (cpu_is_omap2420()) {
631 if ((div_off
== 0) || (div_off
== 8))
633 else if (div_off
== 5)
635 } else if (cpu_is_omap2430()) {
638 else if (div_off
== 5)
643 div_addr
= (u32
)&CM_CLKSEL_GFX
;
648 div_addr
= (u32
)&CM_CLKSEL_MDM
;
652 case CM_SYSCLKOUT_SEL1
:
653 div_addr
= (u32
)&PRCM_CLKOUT_CTRL
;
654 if ((div_off
== 3) || (div_off
== 11))
658 div_addr
= (u32
)&CM_CLKSEL1_CORE
;
662 case 15: /* vylnc-2420 */
676 if (unlikely(mask
== ~0))
681 if (unlikely(div_addr
== 0))
685 reg_val
= __raw_readl((void __iomem
*)div_addr
) & (mask
<< div_off
);
687 /* Normalize back to divider value */
694 * Return divider to be applied to parent clock.
697 static u32
omap2_clksel_get_divisor(struct clk
*clk
)
700 u32 div
, div_sel
, div_off
, field_mask
, field_val
;
702 /* isolate control register */
703 div_sel
= (SRC_RATE_SEL_MASK
& clk
->flags
);
705 div_off
= clk
->rate_offset
;
706 field_val
= omap2_get_clksel(&div_sel
, &field_mask
, clk
);
710 div_sel
= (SRC_RATE_SEL_MASK
& clk
->flags
);
711 div
= omap2_clksel_to_divisor(div_sel
, field_val
);
716 /* Set the clock rate for a clock source */
717 static int omap2_clk_set_rate(struct clk
*clk
, unsigned long rate
)
722 u32 div_sel
, div_off
, field_mask
, field_val
, reg_val
, validrate
;
725 if (!(clk
->flags
& CONFIG_PARTICIPANT
) && (clk
->flags
& RATE_CKCTL
)) {
727 return omap2_reprogram_dpll(clk
, rate
);
729 /* Isolate control register */
730 div_sel
= (SRC_RATE_SEL_MASK
& clk
->flags
);
731 div_off
= clk
->rate_offset
;
733 validrate
= omap2_clksel_round_rate(clk
, rate
, &new_div
);
734 if (validrate
!= rate
)
737 field_val
= omap2_get_clksel(&div_sel
, &field_mask
, clk
);
741 if (clk
->flags
& CM_SYSCLKOUT_SEL1
) {
762 reg
= (void __iomem
*)div_sel
;
764 reg_val
= __raw_readl(reg
);
765 reg_val
&= ~(field_mask
<< div_off
);
766 reg_val
|= (field_val
<< div_off
);
767 __raw_writel(reg_val
, reg
);
769 clk
->rate
= clk
->parent
->rate
/ field_val
;
771 if (clk
->flags
& DELAYED_APP
) {
772 __raw_writel(0x1, (void __iomem
*)&PRCM_CLKCFG_CTRL
);
776 } else if (clk
->set_rate
!= 0)
777 ret
= clk
->set_rate(clk
, rate
);
779 if (unlikely(ret
== 0 && (clk
->flags
& RATE_PROPAGATES
)))
785 /* Converts encoded control register address into a full address */
786 static u32
omap2_get_src_field(u32
*type_to_addr
, u32 reg_offset
,
787 struct clk
*src_clk
, u32
*field_mask
)
789 u32 val
= ~0, src_reg_addr
= 0, mask
= 0;
791 /* Find target control register.*/
792 switch ((*type_to_addr
& SRC_RATE_SEL_MASK
)) {
794 src_reg_addr
= (u32
)&CM_CLKSEL1_CORE
;
795 if (reg_offset
== 13) { /* DSS2_fclk */
797 if (src_clk
== &sys_ck
)
799 if (src_clk
== &func_48m_ck
)
801 } else if (reg_offset
== 8) { /* DSS1_fclk */
803 if (src_clk
== &sys_ck
)
805 else if (src_clk
== &core_ck
) /* divided clock */
806 val
= 0x10; /* rate needs fixing */
807 } else if ((reg_offset
== 15) && cpu_is_omap2420()){ /*vlnyq*/
809 if(src_clk
== &func_96m_ck
)
811 else if (src_clk
== &core_ck
)
816 src_reg_addr
= (u32
)&CM_CLKSEL2_CORE
;
818 if (src_clk
== &func_32k_ck
)
820 if (src_clk
== &sys_ck
)
822 if (src_clk
== &alt_ck
)
826 src_reg_addr
= (u32
)&CM_CLKSEL_WKUP
;
828 if (src_clk
== &func_32k_ck
)
830 if (src_clk
== &sys_ck
)
832 if (src_clk
== &alt_ck
)
836 src_reg_addr
= (u32
)&CM_CLKSEL1_PLL
;
838 if (reg_offset
== 0x3) {
839 if (src_clk
== &apll96_ck
)
841 if (src_clk
== &alt_ck
)
844 else if (reg_offset
== 0x5) {
845 if (src_clk
== &apll54_ck
)
847 if (src_clk
== &alt_ck
)
852 src_reg_addr
= (u32
)&CM_CLKSEL2_PLL
;
854 if (src_clk
== &func_32k_ck
)
856 if (src_clk
== &dpll_ck
)
859 case CM_SYSCLKOUT_SEL1
:
860 src_reg_addr
= (u32
)&PRCM_CLKOUT_CTRL
;
862 if (src_clk
== &dpll_ck
)
864 if (src_clk
== &sys_ck
)
866 if (src_clk
== &func_96m_ck
)
868 if (src_clk
== &func_54m_ck
)
873 if (val
== ~0) /* Catch errors in offset */
876 *type_to_addr
= src_reg_addr
;
882 static int omap2_clk_set_parent(struct clk
*clk
, struct clk
*new_parent
)
885 u32 src_sel
, src_off
, field_val
, field_mask
, reg_val
, rate
;
888 if (unlikely(clk
->flags
& CONFIG_PARTICIPANT
))
891 if (clk
->flags
& SRC_SEL_MASK
) { /* On-chip SEL collection */
892 src_sel
= (SRC_RATE_SEL_MASK
& clk
->flags
);
893 src_off
= clk
->src_offset
;
896 goto set_parent_error
;
898 field_val
= omap2_get_src_field(&src_sel
, src_off
, new_parent
,
901 reg
= (void __iomem
*)src_sel
;
903 if (clk
->usecount
> 0)
904 _omap2_clk_disable(clk
);
906 /* Set new source value (previous dividers if any in effect) */
907 reg_val
= __raw_readl(reg
) & ~(field_mask
<< src_off
);
908 reg_val
|= (field_val
<< src_off
);
909 __raw_writel(reg_val
, reg
);
912 if (clk
->flags
& DELAYED_APP
) {
913 __raw_writel(0x1, (void __iomem
*)&PRCM_CLKCFG_CTRL
);
916 if (clk
->usecount
> 0)
917 _omap2_clk_enable(clk
);
919 clk
->parent
= new_parent
;
921 /* SRC_RATE_SEL_MASK clocks follow their parents rates.*/
922 if ((new_parent
== &core_ck
) && (clk
== &dss1_fck
))
923 clk
->rate
= new_parent
->rate
/ 0x10;
925 clk
->rate
= new_parent
->rate
;
927 if (unlikely(clk
->flags
& RATE_PROPAGATES
))
932 clk
->parent
= new_parent
;
933 rate
= new_parent
->rate
;
934 omap2_clk_set_rate(clk
, rate
);
942 /* Sets basic clocks based on the specified rate */
943 static int omap2_select_table_rate(struct clk
* clk
, unsigned long rate
)
945 u32 flags
, cur_rate
, done_rate
, bypass
= 0;
947 struct prcm_config
*prcm
;
948 unsigned long found_speed
= 0;
950 if (clk
!= &virt_prcm_set
)
953 /* FIXME: Change cpu_is_omap2420() to cpu_is_omap242x() */
954 if (cpu_is_omap2420())
955 cpu_mask
= RATE_IN_242X
;
956 else if (cpu_is_omap2430())
957 cpu_mask
= RATE_IN_243X
;
959 for (prcm
= rate_table
; prcm
->mpu_speed
; prcm
++) {
960 if (!(prcm
->flags
& cpu_mask
))
963 if (prcm
->xtal_speed
!= sys_ck
.rate
)
966 if (prcm
->mpu_speed
<= rate
) {
967 found_speed
= prcm
->mpu_speed
;
973 printk(KERN_INFO
"Could not set MPU rate to %luMHz\n",
978 curr_prcm_set
= prcm
;
979 cur_rate
= omap2_get_dpll_rate(&dpll_ck
);
981 if (prcm
->dpll_speed
== cur_rate
/ 2) {
982 omap2_reprogram_sdrc(PRCM_HALF_SPEED
, 1);
983 } else if (prcm
->dpll_speed
== cur_rate
* 2) {
984 omap2_reprogram_sdrc(PRCM_FULL_SPEED
, 1);
985 } else if (prcm
->dpll_speed
!= cur_rate
) {
986 local_irq_save(flags
);
988 if (prcm
->dpll_speed
== prcm
->xtal_speed
)
991 if ((prcm
->cm_clksel2_pll
& 0x3) == 2)
992 done_rate
= PRCM_FULL_SPEED
;
994 done_rate
= PRCM_HALF_SPEED
;
997 CM_CLKSEL_MPU
= prcm
->cm_clksel_mpu
;
999 /* dsp + iva1 div(2420), iva2.1(2430) */
1000 CM_CLKSEL_DSP
= prcm
->cm_clksel_dsp
;
1002 CM_CLKSEL_GFX
= prcm
->cm_clksel_gfx
;
1004 /* Major subsystem dividers */
1005 CM_CLKSEL1_CORE
= prcm
->cm_clksel1_core
;
1006 if (cpu_is_omap2430())
1007 CM_CLKSEL_MDM
= prcm
->cm_clksel_mdm
;
1009 /* x2 to enter init_mem */
1010 omap2_reprogram_sdrc(PRCM_FULL_SPEED
, 1);
1012 omap2_set_prcm(prcm
->cm_clksel1_pll
, prcm
->base_sdrc_rfr
,
1015 omap2_init_memory_params(omap2_dll_force_needed());
1016 omap2_reprogram_sdrc(done_rate
, 0);
1018 local_irq_restore(flags
);
1020 omap2_clksel_recalc(&dpll_ck
);
1025 /*-------------------------------------------------------------------------
1026 * Omap2 clock reset and init functions
1027 *-------------------------------------------------------------------------*/
1029 #ifdef CONFIG_OMAP_RESET_CLOCKS
1030 static void __init
omap2_clk_disable_unused(struct clk
*clk
)
1034 regval32
= __raw_readl(clk
->enable_reg
);
1035 if ((regval32
& (1 << clk
->enable_bit
)) == 0)
1038 printk(KERN_INFO
"Disabling unused clock \"%s\"\n", clk
->name
);
1039 _omap2_clk_disable(clk
);
1042 #define omap2_clk_disable_unused NULL
1045 static struct clk_functions omap2_clk_functions
= {
1046 .clk_enable
= omap2_clk_enable
,
1047 .clk_disable
= omap2_clk_disable
,
1048 .clk_round_rate
= omap2_clk_round_rate
,
1049 .clk_set_rate
= omap2_clk_set_rate
,
1050 .clk_set_parent
= omap2_clk_set_parent
,
1051 .clk_disable_unused
= omap2_clk_disable_unused
,
1054 static void __init
omap2_get_crystal_rate(struct clk
*osc
, struct clk
*sys
)
1056 u32 div
, aplls
, sclk
= 13000000;
1058 aplls
= CM_CLKSEL1_PLL
;
1059 aplls
&= ((1 << 23) | (1 << 24) | (1 << 25));
1060 aplls
>>= 23; /* Isolate field, 0,2,3 */
1064 else if (aplls
== 2)
1066 else if (aplls
== 3)
1069 div
= PRCM_CLKSRC_CTRL
;
1070 div
&= ((1 << 7) | (1 << 6));
1071 div
>>= sys
->rate_offset
;
1073 osc
->rate
= sclk
* div
;
1078 * Set clocks for bypass mode for reboot to work.
1080 void omap2_clk_prepare_for_reboot(void)
1084 if (vclk
== NULL
|| sclk
== NULL
)
1087 rate
= clk_get_rate(sclk
);
1088 clk_set_rate(vclk
, rate
);
1092 * Switch the MPU rate if specified on cmdline.
1093 * We cannot do this early until cmdline is parsed.
1095 static int __init
omap2_clk_arch_init(void)
1100 if (omap2_select_table_rate(&virt_prcm_set
, mpurate
))
1101 printk(KERN_ERR
"Could not find matching MPU rate\n");
1103 propagate_rate(&osc_ck
); /* update main root fast */
1104 propagate_rate(&func_32k_ck
); /* update main root slow */
1106 printk(KERN_INFO
"Switched to new clocking rate (Crystal/DPLL/MPU): "
1107 "%ld.%01ld/%ld/%ld MHz\n",
1108 (sys_ck
.rate
/ 1000000), (sys_ck
.rate
/ 100000) % 10,
1109 (dpll_ck
.rate
/ 1000000), (mpu_ck
.rate
/ 1000000)) ;
1113 arch_initcall(omap2_clk_arch_init
);
1115 int __init
omap2_clk_init(void)
1117 struct prcm_config
*prcm
;
1121 clk_init(&omap2_clk_functions
);
1122 omap2_get_crystal_rate(&osc_ck
, &sys_ck
);
1124 for (clkp
= onchip_clks
; clkp
< onchip_clks
+ ARRAY_SIZE(onchip_clks
);
1127 if ((*clkp
)->flags
& CLOCK_IN_OMAP242X
&& cpu_is_omap2420()) {
1128 clk_register(*clkp
);
1132 if ((*clkp
)->flags
& CLOCK_IN_OMAP243X
&& cpu_is_omap2430()) {
1133 clk_register(*clkp
);
1138 /* Check the MPU rate set by bootloader */
1139 clkrate
= omap2_get_dpll_rate(&dpll_ck
);
1140 for (prcm
= rate_table
; prcm
->mpu_speed
; prcm
++) {
1141 if (prcm
->xtal_speed
!= sys_ck
.rate
)
1143 if (prcm
->dpll_speed
<= clkrate
)
1146 curr_prcm_set
= prcm
;
1148 propagate_rate(&osc_ck
); /* update main root fast */
1149 propagate_rate(&func_32k_ck
); /* update main root slow */
1151 printk(KERN_INFO
"Clocking rate (Crystal/DPLL/MPU): "
1152 "%ld.%01ld/%ld/%ld MHz\n",
1153 (sys_ck
.rate
/ 1000000), (sys_ck
.rate
/ 100000) % 10,
1154 (dpll_ck
.rate
/ 1000000), (mpu_ck
.rate
/ 1000000)) ;
1157 * Only enable those clocks we will need, let the drivers
1158 * enable other clocks as necessary
1160 clk_enable(&sync_32k_ick
);
1161 clk_enable(&omapctrl_ick
);
1163 /* Force the APLLs always active. The clocks are idled
1164 * automatically by hardware. */
1165 clk_enable(&apll96_ck
);
1166 clk_enable(&apll54_ck
);
1168 if (cpu_is_omap2430())
1169 clk_enable(&sdrc_ick
);
1171 /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
1172 vclk
= clk_get(NULL
, "virt_prcm_set");
1173 sclk
= clk_get(NULL
, "sys_ck");