Commit | Line | Data |
---|---|---|
49214640 PW |
1 | /* |
2 | * OMAP2xxx APLL clock control functions | |
3 | * | |
4 | * Copyright (C) 2005-2008 Texas Instruments, Inc. | |
5 | * Copyright (C) 2004-2010 Nokia Corporation | |
6 | * | |
7 | * Contacts: | |
8 | * Richard Woodruff <r-woodruff2@ti.com> | |
9 | * Paul Walmsley | |
10 | * | |
11 | * Based on earlier work by Tuukka Tikkanen, Tony Lindgren, | |
12 | * Gordon McNutt and RidgeRun, Inc. | |
13 | * | |
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. | |
17 | */ | |
18 | #undef DEBUG | |
19 | ||
20 | #include <linux/kernel.h> | |
21 | #include <linux/clk.h> | |
22 | #include <linux/io.h> | |
23 | ||
49214640 PW |
24 | |
25 | #include "clock.h" | |
26 | #include "clock2xxx.h" | |
ff4ae5d9 | 27 | #include "cm2xxx.h" |
49214640 PW |
28 | #include "cm-regbits-24xx.h" |
29 | ||
30 | /* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */ | |
31 | #define EN_APLL_STOPPED 0 | |
32 | #define EN_APLL_LOCKED 3 | |
33 | ||
34 | /* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */ | |
35 | #define APLLS_CLKIN_19_2MHZ 0 | |
36 | #define APLLS_CLKIN_13MHZ 2 | |
37 | #define APLLS_CLKIN_12MHZ 3 | |
38 | ||
39 | /* Private functions */ | |
40 | ||
7a2bd1cc PW |
41 | /** |
42 | * omap2xxx_clk_apll_locked - is the APLL locked? | |
43 | * @hw: struct clk_hw * of the APLL to check | |
44 | * | |
45 | * If the APLL IP block referred to by @hw indicates that it's locked, | |
46 | * return true; otherwise, return false. | |
47 | */ | |
48 | static bool omap2xxx_clk_apll_locked(struct clk_hw *hw) | |
49 | { | |
50 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); | |
51 | u32 r, apll_mask; | |
52 | ||
53 | apll_mask = EN_APLL_LOCKED << clk->enable_bit; | |
54 | ||
55 | r = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN); | |
56 | ||
57 | return ((r & apll_mask) == apll_mask) ? true : false; | |
58 | } | |
7a2bd1cc | 59 | |
ed1ebc49 | 60 | int omap2_clk_apll96_enable(struct clk_hw *hw) |
49214640 | 61 | { |
b6ffa050 | 62 | return omap2xxx_cm_apll96_enable(); |
49214640 PW |
63 | } |
64 | ||
ed1ebc49 | 65 | int omap2_clk_apll54_enable(struct clk_hw *hw) |
49214640 | 66 | { |
b6ffa050 | 67 | return omap2xxx_cm_apll54_enable(); |
49214640 PW |
68 | } |
69 | ||
ed1ebc49 | 70 | static void _apll96_allow_idle(struct clk_hw_omap *clk) |
92618ff8 PW |
71 | { |
72 | omap2xxx_cm_set_apll96_auto_low_power_stop(); | |
73 | } | |
74 | ||
ed1ebc49 | 75 | static void _apll96_deny_idle(struct clk_hw_omap *clk) |
92618ff8 PW |
76 | { |
77 | omap2xxx_cm_set_apll96_disable_autoidle(); | |
78 | } | |
79 | ||
ed1ebc49 | 80 | static void _apll54_allow_idle(struct clk_hw_omap *clk) |
92618ff8 PW |
81 | { |
82 | omap2xxx_cm_set_apll54_auto_low_power_stop(); | |
83 | } | |
84 | ||
ed1ebc49 | 85 | static void _apll54_deny_idle(struct clk_hw_omap *clk) |
92618ff8 PW |
86 | { |
87 | omap2xxx_cm_set_apll54_disable_autoidle(); | |
88 | } | |
89 | ||
ed1ebc49 | 90 | void omap2_clk_apll96_disable(struct clk_hw *hw) |
49214640 | 91 | { |
b6ffa050 PW |
92 | omap2xxx_cm_apll96_disable(); |
93 | } | |
49214640 | 94 | |
ed1ebc49 | 95 | void omap2_clk_apll54_disable(struct clk_hw *hw) |
b6ffa050 PW |
96 | { |
97 | omap2xxx_cm_apll54_disable(); | |
49214640 PW |
98 | } |
99 | ||
7a2bd1cc PW |
100 | unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw, |
101 | unsigned long parent_rate) | |
102 | { | |
103 | return (omap2xxx_clk_apll_locked(hw)) ? 54000000 : 0; | |
104 | } | |
105 | ||
106 | unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw, | |
107 | unsigned long parent_rate) | |
108 | { | |
109 | return (omap2xxx_clk_apll_locked(hw)) ? 96000000 : 0; | |
110 | } | |
7a2bd1cc | 111 | |
49214640 | 112 | /* Public data */ |
ed1ebc49 RN |
113 | const struct clk_hw_omap_ops clkhwops_apll54 = { |
114 | .allow_idle = _apll54_allow_idle, | |
115 | .deny_idle = _apll54_deny_idle, | |
116 | }; | |
49214640 | 117 | |
ed1ebc49 RN |
118 | const struct clk_hw_omap_ops clkhwops_apll96 = { |
119 | .allow_idle = _apll96_allow_idle, | |
120 | .deny_idle = _apll96_deny_idle, | |
121 | }; | |
49214640 PW |
122 | |
123 | /* Public functions */ | |
124 | ||
125 | u32 omap2xxx_get_apll_clkin(void) | |
126 | { | |
127 | u32 aplls, srate = 0; | |
128 | ||
c4d7e58f | 129 | aplls = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1); |
49214640 PW |
130 | aplls &= OMAP24XX_APLLS_CLKIN_MASK; |
131 | aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT; | |
132 | ||
133 | if (aplls == APLLS_CLKIN_19_2MHZ) | |
134 | srate = 19200000; | |
135 | else if (aplls == APLLS_CLKIN_13MHZ) | |
136 | srate = 13000000; | |
137 | else if (aplls == APLLS_CLKIN_12MHZ) | |
138 | srate = 12000000; | |
139 | ||
140 | return srate; | |
141 | } | |
142 |