2 * linux/arch/arm/mach-omap2/clock.c
4 * Copyright (C) 2005-2008 Texas Instruments, Inc.
5 * Copyright (C) 2004-2008 Nokia Corporation
8 * Richard Woodruff <r-woodruff2@ti.com>
11 * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
12 * Gordon McNutt and RidgeRun, Inc.
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.
20 #include <linux/module.h>
21 #include <linux/kernel.h>
22 #include <linux/device.h>
23 #include <linux/list.h>
24 #include <linux/errno.h>
25 #include <linux/delay.h>
26 #include <linux/clk.h>
27 #include <linux/bitops.h>
29 #include <linux/cpufreq.h>
31 #include <asm/arch/common.h>
32 #include <asm/arch/clock.h>
33 #include <asm/arch/sram.h>
34 #include <asm/div64.h>
38 #include "clock24xx.h"
40 #include "prm-regbits-24xx.h"
42 #include "cm-regbits-24xx.h"
44 /* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
45 #define EN_APLL_STOPPED 0
46 #define EN_APLL_LOCKED 3
48 /* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
49 #define APLLS_CLKIN_19_2MHZ 0
50 #define APLLS_CLKIN_13MHZ 2
51 #define APLLS_CLKIN_12MHZ 3
53 /* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */
55 static struct prcm_config
*curr_prcm_set
;
56 static struct clk
*vclk
;
57 static struct clk
*sclk
;
59 /*-------------------------------------------------------------------------
60 * Omap24xx specific clock functions
61 *-------------------------------------------------------------------------*/
63 /* This actually returns the rate of core_ck, not dpll_ck. */
64 static u32
omap2_get_dpll_rate_24xx(struct clk
*tclk
)
69 dpll_clk
= omap2_get_dpll_rate(tclk
);
71 amult
= cm_read_mod_reg(PLL_MOD
, CM_CLKSEL2
);
72 amult
&= OMAP24XX_CORE_CLK_SRC_MASK
;
78 static int omap2_enable_osc_ck(struct clk
*clk
)
80 prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK
, 0,
81 OMAP24XX_GR_MOD
, OMAP24XX_PRCM_CLKSRC_CTRL_OFFSET
);
86 static void omap2_disable_osc_ck(struct clk
*clk
)
88 prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK
, OMAP_AUTOEXTCLKMODE_MASK
,
89 OMAP24XX_GR_MOD
, OMAP24XX_PRCM_CLKSRC_CTRL_OFFSET
);
92 /* Enable an APLL if off */
93 static int omap2_clk_fixed_enable(struct clk
*clk
)
98 apll_mask
= EN_APLL_LOCKED
<< clk
->enable_bit
;
100 cval
= cm_read_mod_reg(PLL_MOD
, CM_CLKEN
);
102 if ((cval
& apll_mask
) == apll_mask
)
103 return 0; /* apll already enabled */
107 cm_write_mod_reg(cval
, PLL_MOD
, CM_CLKEN
);
109 if (clk
== &apll96_ck
)
110 cval
= OMAP24XX_ST_96M_APLL
;
111 else if (clk
== &apll54_ck
)
112 cval
= OMAP24XX_ST_54M_APLL
;
114 if (cpu_is_omap242x())
115 idlest
= (__force
void __iomem
*)OMAP2420_CM_REGADDR(PLL_MOD
,
118 idlest
= (__force
void __iomem
*)OMAP2430_CM_REGADDR(PLL_MOD
,
121 omap2_wait_clock_ready(idlest
, cval
, clk
->name
);
124 * REVISIT: Should we return an error code if omap2_wait_clock_ready()
131 static void omap2_clk_fixed_disable(struct clk
*clk
)
135 cval
= cm_read_mod_reg(PLL_MOD
, CM_CLKEN
);
136 cval
&= ~(EN_APLL_LOCKED
<< clk
->enable_bit
);
137 cm_write_mod_reg(cval
, PLL_MOD
, CM_CLKEN
);
141 * Uses the current prcm set to tell if a rate is valid.
142 * You can go slower, but not faster within a given rate set.
144 static long omap2_dpllcore_round_rate(unsigned long target_rate
)
146 u32 high
, low
, core_clk_src
;
148 core_clk_src
= cm_read_mod_reg(PLL_MOD
, CM_CLKSEL2
);
149 core_clk_src
&= OMAP24XX_CORE_CLK_SRC_MASK
;
151 if (core_clk_src
== CORE_CLK_SRC_DPLL
) { /* DPLL clockout */
152 high
= curr_prcm_set
->dpll_speed
* 2;
153 low
= curr_prcm_set
->dpll_speed
;
154 } else { /* DPLL clockout x 2 */
155 high
= curr_prcm_set
->dpll_speed
;
156 low
= curr_prcm_set
->dpll_speed
/ 2;
159 #ifdef DOWN_VARIABLE_DPLL
160 if (target_rate
> high
)
165 if (target_rate
> low
)
173 static void omap2_dpllcore_recalc(struct clk
*clk
)
175 clk
->rate
= omap2_get_dpll_rate_24xx(clk
);
180 static int omap2_reprogram_dpllcore(struct clk
*clk
, unsigned long rate
)
182 u32 cur_rate
, low
, mult
, div
, valid_rate
, done_rate
;
184 struct prcm_config tmpset
;
185 const struct dpll_data
*dd
;
189 local_irq_save(flags
);
190 cur_rate
= omap2_get_dpll_rate_24xx(&dpll_ck
);
191 mult
= cm_read_mod_reg(PLL_MOD
, CM_CLKSEL2
);
192 mult
&= OMAP24XX_CORE_CLK_SRC_MASK
;
194 if ((rate
== (cur_rate
/ 2)) && (mult
== 2)) {
195 omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL
, 1);
196 } else if ((rate
== (cur_rate
* 2)) && (mult
== 1)) {
197 omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2
, 1);
198 } else if (rate
!= cur_rate
) {
199 valid_rate
= omap2_dpllcore_round_rate(rate
);
200 if (valid_rate
!= rate
)
204 low
= curr_prcm_set
->dpll_speed
;
206 low
= curr_prcm_set
->dpll_speed
/ 2;
212 tmpset
.cm_clksel1_pll
= __raw_readl(dd
->mult_div1_reg
);
213 tmpset
.cm_clksel1_pll
&= ~(dd
->mult_mask
|
215 div
= ((curr_prcm_set
->xtal_speed
/ 1000000) - 1);
216 tmpset
.cm_clksel2_pll
= cm_read_mod_reg(PLL_MOD
, CM_CLKSEL2
);
217 tmpset
.cm_clksel2_pll
&= ~OMAP24XX_CORE_CLK_SRC_MASK
;
219 tmpset
.cm_clksel2_pll
|= CORE_CLK_SRC_DPLL_X2
;
220 mult
= ((rate
/ 2) / 1000000);
221 done_rate
= CORE_CLK_SRC_DPLL_X2
;
223 tmpset
.cm_clksel2_pll
|= CORE_CLK_SRC_DPLL
;
224 mult
= (rate
/ 1000000);
225 done_rate
= CORE_CLK_SRC_DPLL
;
227 tmpset
.cm_clksel1_pll
|= (div
<< __ffs(dd
->mult_mask
));
228 tmpset
.cm_clksel1_pll
|= (mult
<< __ffs(dd
->div1_mask
));
231 tmpset
.base_sdrc_rfr
= SDRC_RFR_CTRL_BYPASS
;
233 if (rate
== curr_prcm_set
->xtal_speed
) /* If asking for 1-1 */
236 omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2
, 1); /* For init_mem */
238 /* Force dll lock mode */
239 omap2_set_prcm(tmpset
.cm_clksel1_pll
, tmpset
.base_sdrc_rfr
,
242 /* Errata: ret dll entry state */
243 omap2_init_memory_params(omap2_dll_force_needed());
244 omap2_reprogram_sdrc(done_rate
, 0);
246 omap2_dpllcore_recalc(&dpll_ck
);
250 local_irq_restore(flags
);
255 * omap2_table_mpu_recalc - just return the MPU speed
256 * @clk: virt_prcm_set struct clk
258 * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
260 static void omap2_table_mpu_recalc(struct clk
*clk
)
262 clk
->rate
= curr_prcm_set
->mpu_speed
;
266 * Look for a rate equal or less than the target rate given a configuration set.
268 * What's not entirely clear is "which" field represents the key field.
269 * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
270 * just uses the ARM rates.
272 static long omap2_round_to_table_rate(struct clk
*clk
, unsigned long rate
)
274 struct prcm_config
*ptr
;
277 if (clk
!= &virt_prcm_set
)
280 highest_rate
= -EINVAL
;
282 for (ptr
= rate_table
; ptr
->mpu_speed
; ptr
++) {
283 if (!(ptr
->flags
& cpu_mask
))
285 if (ptr
->xtal_speed
!= sys_ck
.rate
)
288 highest_rate
= ptr
->mpu_speed
;
290 /* Can check only after xtal frequency check */
291 if (ptr
->mpu_speed
<= rate
)
297 /* Sets basic clocks based on the specified rate */
298 static int omap2_select_table_rate(struct clk
*clk
, unsigned long rate
)
300 u32 cur_rate
, done_rate
, bypass
= 0, tmp
;
301 struct prcm_config
*prcm
;
302 unsigned long found_speed
= 0;
305 if (clk
!= &virt_prcm_set
)
308 for (prcm
= rate_table
; prcm
->mpu_speed
; prcm
++) {
309 if (!(prcm
->flags
& cpu_mask
))
312 if (prcm
->xtal_speed
!= sys_ck
.rate
)
315 if (prcm
->mpu_speed
<= rate
) {
316 found_speed
= prcm
->mpu_speed
;
322 printk(KERN_INFO
"Could not set MPU rate to %luMHz\n",
327 curr_prcm_set
= prcm
;
328 cur_rate
= omap2_get_dpll_rate_24xx(&dpll_ck
);
330 if (prcm
->dpll_speed
== cur_rate
/ 2) {
331 omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL
, 1);
332 } else if (prcm
->dpll_speed
== cur_rate
* 2) {
333 omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2
, 1);
334 } else if (prcm
->dpll_speed
!= cur_rate
) {
335 local_irq_save(flags
);
337 if (prcm
->dpll_speed
== prcm
->xtal_speed
)
340 if ((prcm
->cm_clksel2_pll
& OMAP24XX_CORE_CLK_SRC_MASK
) ==
341 CORE_CLK_SRC_DPLL_X2
)
342 done_rate
= CORE_CLK_SRC_DPLL_X2
;
344 done_rate
= CORE_CLK_SRC_DPLL
;
347 cm_write_mod_reg(prcm
->cm_clksel_mpu
, MPU_MOD
, CM_CLKSEL
);
349 /* dsp + iva1 div(2420), iva2.1(2430) */
350 cm_write_mod_reg(prcm
->cm_clksel_dsp
,
351 OMAP24XX_DSP_MOD
, CM_CLKSEL
);
353 cm_write_mod_reg(prcm
->cm_clksel_gfx
, GFX_MOD
, CM_CLKSEL
);
355 /* Major subsystem dividers */
356 tmp
= cm_read_mod_reg(CORE_MOD
, CM_CLKSEL1
) & OMAP24XX_CLKSEL_DSS2_MASK
;
357 cm_write_mod_reg(prcm
->cm_clksel1_core
| tmp
, CORE_MOD
,
360 if (cpu_is_omap2430())
361 cm_write_mod_reg(prcm
->cm_clksel_mdm
,
362 OMAP2430_MDM_MOD
, CM_CLKSEL
);
364 /* x2 to enter init_mem */
365 omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2
, 1);
367 omap2_set_prcm(prcm
->cm_clksel1_pll
, prcm
->base_sdrc_rfr
,
370 omap2_init_memory_params(omap2_dll_force_needed());
371 omap2_reprogram_sdrc(done_rate
, 0);
373 local_irq_restore(flags
);
375 omap2_dpllcore_recalc(&dpll_ck
);
380 #ifdef CONFIG_CPU_FREQ
382 * Walk PRCM rate table and fillout cpufreq freq_table
384 static struct cpufreq_frequency_table freq_table
[ARRAY_SIZE(rate_table
)];
386 void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table
**table
)
388 struct prcm_config
*prcm
;
391 for (prcm
= rate_table
; prcm
->mpu_speed
; prcm
++) {
392 if (!(prcm
->flags
& cpu_mask
))
394 if (prcm
->xtal_speed
!= sys_ck
.rate
)
397 /* don't put bypass rates in table */
398 if (prcm
->dpll_speed
== prcm
->xtal_speed
)
401 freq_table
[i
].index
= i
;
402 freq_table
[i
].frequency
= prcm
->mpu_speed
/ 1000;
407 printk(KERN_WARNING
"%s: failed to initialize frequency "
408 "table\n", __func__
);
412 freq_table
[i
].index
= i
;
413 freq_table
[i
].frequency
= CPUFREQ_TABLE_END
;
415 *table
= &freq_table
[0];
419 static struct clk_functions omap2_clk_functions
= {
420 .clk_enable
= omap2_clk_enable
,
421 .clk_disable
= omap2_clk_disable
,
422 .clk_round_rate
= omap2_clk_round_rate
,
423 .clk_set_rate
= omap2_clk_set_rate
,
424 .clk_set_parent
= omap2_clk_set_parent
,
425 .clk_disable_unused
= omap2_clk_disable_unused
,
426 #ifdef CONFIG_CPU_FREQ
427 .clk_init_cpufreq_table
= omap2_clk_init_cpufreq_table
,
431 static u32
omap2_get_apll_clkin(void)
433 u32 aplls
, srate
= 0;
435 aplls
= cm_read_mod_reg(PLL_MOD
, CM_CLKSEL1
);
436 aplls
&= OMAP24XX_APLLS_CLKIN_MASK
;
437 aplls
>>= OMAP24XX_APLLS_CLKIN_SHIFT
;
439 if (aplls
== APLLS_CLKIN_19_2MHZ
)
441 else if (aplls
== APLLS_CLKIN_13MHZ
)
443 else if (aplls
== APLLS_CLKIN_12MHZ
)
449 static u32
omap2_get_sysclkdiv(void)
453 div
= prm_read_mod_reg(OMAP24XX_GR_MOD
,
454 OMAP24XX_PRCM_CLKSRC_CTRL_OFFSET
);
455 div
&= OMAP_SYSCLKDIV_MASK
;
456 div
>>= OMAP_SYSCLKDIV_SHIFT
;
461 static void omap2_osc_clk_recalc(struct clk
*clk
)
463 clk
->rate
= omap2_get_apll_clkin() * omap2_get_sysclkdiv();
467 static void omap2_sys_clk_recalc(struct clk
*clk
)
469 clk
->rate
= clk
->parent
->rate
/ omap2_get_sysclkdiv();
474 * Set clocks for bypass mode for reboot to work.
476 void omap2_clk_prepare_for_reboot(void)
480 if (vclk
== NULL
|| sclk
== NULL
)
483 rate
= clk_get_rate(sclk
);
484 clk_set_rate(vclk
, rate
);
488 * Switch the MPU rate if specified on cmdline.
489 * We cannot do this early until cmdline is parsed.
491 static int __init
omap2_clk_arch_init(void)
496 if (omap2_select_table_rate(&virt_prcm_set
, mpurate
))
497 printk(KERN_ERR
"Could not find matching MPU rate\n");
499 recalculate_root_clocks();
501 printk(KERN_INFO
"Switched to new clocking rate (Crystal/DPLL/MPU): "
502 "%ld.%01ld/%ld/%ld MHz\n",
503 (sys_ck
.rate
/ 1000000), (sys_ck
.rate
/ 100000) % 10,
504 (dpll_ck
.rate
/ 1000000), (mpu_ck
.rate
/ 1000000)) ;
508 arch_initcall(omap2_clk_arch_init
);
514 * Since we share clock data for 242x and 243x, we need to rewrite some
515 * some register base offsets. Assume offset is at prm_base if flagged,
516 * else assume it's cm_base.
518 static inline void omap2_clk_check_reg(u32 flags
, void __iomem
**reg
)
520 u32 tmp
= (__force u32
)*reg
;
522 if ((tmp
>> 24) != 0)
525 if (flags
& OFFSET_GR_MOD
)
530 *reg
= (__force
void __iomem
*)tmp
;
533 void __init
omap2_clk_rewrite_base(struct clk
*clk
)
535 omap2_clk_check_reg(clk
->flags
, &clk
->clksel_reg
);
536 omap2_clk_check_reg(clk
->flags
, &clk
->enable_reg
);
538 omap2_clk_check_reg(0, &clk
->dpll_data
->mult_div1_reg
);
541 int __init
omap2_clk_init(void)
543 struct prcm_config
*prcm
;
547 if (cpu_is_omap242x())
548 cpu_mask
= RATE_IN_242X
;
549 else if (cpu_is_omap2430())
550 cpu_mask
= RATE_IN_243X
;
552 for (clkp
= onchip_24xx_clks
;
553 clkp
< onchip_24xx_clks
+ ARRAY_SIZE(onchip_24xx_clks
);
555 omap2_clk_rewrite_base(*clkp
);
558 clk_init(&omap2_clk_functions
);
560 omap2_osc_clk_recalc(&osc_ck
);
561 omap2_sys_clk_recalc(&sys_ck
);
563 for (clkp
= onchip_24xx_clks
;
564 clkp
< onchip_24xx_clks
+ ARRAY_SIZE(onchip_24xx_clks
);
567 if ((*clkp
)->flags
& CLOCK_IN_OMAP242X
&& cpu_is_omap2420()) {
572 if ((*clkp
)->flags
& CLOCK_IN_OMAP243X
&& cpu_is_omap2430()) {
578 /* Check the MPU rate set by bootloader */
579 clkrate
= omap2_get_dpll_rate_24xx(&dpll_ck
);
580 for (prcm
= rate_table
; prcm
->mpu_speed
; prcm
++) {
581 if (!(prcm
->flags
& cpu_mask
))
583 if (prcm
->xtal_speed
!= sys_ck
.rate
)
585 if (prcm
->dpll_speed
<= clkrate
)
588 curr_prcm_set
= prcm
;
590 recalculate_root_clocks();
592 printk(KERN_INFO
"Clocking rate (Crystal/DPLL/MPU): "
593 "%ld.%01ld/%ld/%ld MHz\n",
594 (sys_ck
.rate
/ 1000000), (sys_ck
.rate
/ 100000) % 10,
595 (dpll_ck
.rate
/ 1000000), (mpu_ck
.rate
/ 1000000)) ;
598 * Only enable those clocks we will need, let the drivers
599 * enable other clocks as necessary
601 clk_enable_init_clocks();
603 /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
604 vclk
= clk_get(NULL
, "virt_prcm_set");
605 sclk
= clk_get(NULL
, "sys_ck");
610 void __init
omap2_set_globals_clock24xx(struct omap_globals
*omap2_globals
)
612 prm_base
= (__force u32
)omap2_globals
->prm
;
613 cm_base
= (__force u32
)omap2_globals
->cm
;