Commit | Line | Data |
---|---|---|
543d9378 PW |
1 | /* |
2 | * linux/arch/arm/mach-omap2/clock.h | |
3 | * | |
d8a94458 | 4 | * Copyright (C) 2005-2009 Texas Instruments, Inc. |
530e544f | 5 | * Copyright (C) 2004-2011 Nokia Corporation |
543d9378 | 6 | * |
a16e9703 TL |
7 | * Contacts: |
8 | * Richard Woodruff <r-woodruff2@ti.com> | |
543d9378 PW |
9 | * Paul Walmsley |
10 | * | |
11 | * This program is free software; you can redistribute it and/or modify | |
12 | * it under the terms of the GNU General Public License version 2 as | |
13 | * published by the Free Software Foundation. | |
14 | */ | |
15 | ||
16 | #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H | |
17 | #define __ARCH_ARM_MACH_OMAP2_CLOCK_H | |
18 | ||
12706c54 | 19 | #include <linux/kernel.h> |
a135eaae PW |
20 | #include <linux/list.h> |
21 | ||
e10dd62f | 22 | #include <linux/clkdev.h> |
f9ae32a7 | 23 | #include <linux/clk-provider.h> |
f38b0dd6 | 24 | #include <linux/clk/ti.h> |
e10dd62f PW |
25 | |
26 | struct omap_clk { | |
27 | u16 cpu; | |
28 | struct clk_lookup lk; | |
29 | }; | |
30 | ||
78e52e02 | 31 | #define CLK(dev, con, ck) \ |
e10dd62f | 32 | { \ |
e10dd62f PW |
33 | .lk = { \ |
34 | .dev_id = dev, \ | |
35 | .con_id = con, \ | |
36 | .clk = ck, \ | |
37 | }, \ | |
38 | } | |
39 | ||
b5a2366c | 40 | struct clockdomain; |
b5a2366c | 41 | |
8c725dcd PW |
42 | #define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name) \ |
43 | static struct clk _name = { \ | |
44 | .name = #_name, \ | |
45 | .hw = &_name##_hw.hw, \ | |
46 | .parent_names = _parent_array_name, \ | |
47 | .num_parents = ARRAY_SIZE(_parent_array_name), \ | |
48 | .ops = &_clkops_name, \ | |
49 | }; | |
50 | ||
601155b0 AM |
51 | #define DEFINE_STRUCT_CLK_FLAGS(_name, _parent_array_name, \ |
52 | _clkops_name, _flags) \ | |
53 | static struct clk _name = { \ | |
54 | .name = #_name, \ | |
55 | .hw = &_name##_hw.hw, \ | |
56 | .parent_names = _parent_array_name, \ | |
57 | .num_parents = ARRAY_SIZE(_parent_array_name), \ | |
58 | .ops = &_clkops_name, \ | |
59 | .flags = _flags, \ | |
60 | }; | |
61 | ||
8c725dcd PW |
62 | #define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name) \ |
63 | static struct clk_hw_omap _name##_hw = { \ | |
64 | .hw = { \ | |
65 | .clk = &_name, \ | |
66 | }, \ | |
67 | .clkdm_name = _clkdm_name, \ | |
68 | }; | |
69 | ||
70 | #define DEFINE_CLK_OMAP_MUX(_name, _clkdm_name, _clksel, \ | |
71 | _clksel_reg, _clksel_mask, \ | |
72 | _parent_names, _ops) \ | |
73 | static struct clk _name; \ | |
74 | static struct clk_hw_omap _name##_hw = { \ | |
75 | .hw = { \ | |
76 | .clk = &_name, \ | |
77 | }, \ | |
78 | .clksel = _clksel, \ | |
79 | .clksel_reg = _clksel_reg, \ | |
80 | .clksel_mask = _clksel_mask, \ | |
81 | .clkdm_name = _clkdm_name, \ | |
82 | }; \ | |
83 | DEFINE_STRUCT_CLK(_name, _parent_names, _ops); | |
84 | ||
85 | #define DEFINE_CLK_OMAP_MUX_GATE(_name, _clkdm_name, _clksel, \ | |
86 | _clksel_reg, _clksel_mask, \ | |
87 | _enable_reg, _enable_bit, \ | |
88 | _hwops, _parent_names, _ops) \ | |
89 | static struct clk _name; \ | |
90 | static struct clk_hw_omap _name##_hw = { \ | |
91 | .hw = { \ | |
92 | .clk = &_name, \ | |
93 | }, \ | |
94 | .ops = _hwops, \ | |
95 | .enable_reg = _enable_reg, \ | |
96 | .enable_bit = _enable_bit, \ | |
97 | .clksel = _clksel, \ | |
98 | .clksel_reg = _clksel_reg, \ | |
99 | .clksel_mask = _clksel_mask, \ | |
100 | .clkdm_name = _clkdm_name, \ | |
101 | }; \ | |
102 | DEFINE_STRUCT_CLK(_name, _parent_names, _ops); | |
103 | ||
104 | #define DEFINE_CLK_OMAP_HSDIVIDER(_name, _parent_name, \ | |
105 | _parent_ptr, _flags, \ | |
106 | _clksel_reg, _clksel_mask) \ | |
107 | static const struct clksel _name##_div[] = { \ | |
108 | { \ | |
109 | .parent = _parent_ptr, \ | |
110 | .rates = div31_1to31_rates \ | |
111 | }, \ | |
112 | { .parent = NULL }, \ | |
113 | }; \ | |
114 | static struct clk _name; \ | |
115 | static const char *_name##_parent_names[] = { \ | |
116 | _parent_name, \ | |
117 | }; \ | |
118 | static struct clk_hw_omap _name##_hw = { \ | |
119 | .hw = { \ | |
120 | .clk = &_name, \ | |
121 | }, \ | |
122 | .clksel = _name##_div, \ | |
123 | .clksel_reg = _clksel_reg, \ | |
124 | .clksel_mask = _clksel_mask, \ | |
125 | .ops = &clkhwops_omap4_dpllmx, \ | |
126 | }; \ | |
127 | DEFINE_STRUCT_CLK(_name, _name##_parent_names, omap_hsdivider_ops); | |
128 | ||
a135eaae PW |
129 | /* struct clksel_rate.flags possibilities */ |
130 | #define RATE_IN_242X (1 << 0) | |
131 | #define RATE_IN_243X (1 << 1) | |
132 | #define RATE_IN_3430ES1 (1 << 2) /* 3430ES1 rates only */ | |
133 | #define RATE_IN_3430ES2PLUS (1 << 3) /* 3430 ES >= 2 rates only */ | |
134 | #define RATE_IN_36XX (1 << 4) | |
135 | #define RATE_IN_4430 (1 << 5) | |
136 | #define RATE_IN_TI816X (1 << 6) | |
137 | #define RATE_IN_4460 (1 << 7) | |
138 | #define RATE_IN_AM33XX (1 << 8) | |
139 | #define RATE_IN_TI814X (1 << 9) | |
140 | ||
141 | #define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) | |
142 | #define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS) | |
143 | #define RATE_IN_3XXX (RATE_IN_34XX | RATE_IN_36XX) | |
144 | #define RATE_IN_44XX (RATE_IN_4430 | RATE_IN_4460) | |
145 | ||
146 | /* RATE_IN_3430ES2PLUS_36XX includes 34xx/35xx with ES >=2, and all 36xx/37xx */ | |
147 | #define RATE_IN_3430ES2PLUS_36XX (RATE_IN_3430ES2PLUS | RATE_IN_36XX) | |
148 | ||
149 | ||
150 | /** | |
151 | * struct clksel_rate - register bitfield values corresponding to clk divisors | |
152 | * @val: register bitfield value (shifted to bit 0) | |
153 | * @div: clock divisor corresponding to @val | |
154 | * @flags: (see "struct clksel_rate.flags possibilities" above) | |
155 | * | |
156 | * @val should match the value of a read from struct clk.clksel_reg | |
157 | * AND'ed with struct clk.clksel_mask, shifted right to bit 0. | |
158 | * | |
159 | * @div is the divisor that should be applied to the parent clock's rate | |
160 | * to produce the current clock's rate. | |
161 | */ | |
162 | struct clksel_rate { | |
163 | u32 val; | |
164 | u8 div; | |
165 | u16 flags; | |
166 | }; | |
167 | ||
168 | /** | |
169 | * struct clksel - available parent clocks, and a pointer to their divisors | |
170 | * @parent: struct clk * to a possible parent clock | |
171 | * @rates: available divisors for this parent clock | |
172 | * | |
173 | * A struct clksel is always associated with one or more struct clks | |
174 | * and one or more struct clksel_rates. | |
175 | */ | |
176 | struct clksel { | |
177 | struct clk *parent; | |
178 | const struct clksel_rate *rates; | |
179 | }; | |
180 | ||
b5a2366c RN |
181 | unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw, |
182 | unsigned long parent_rate); | |
543d9378 | 183 | |
c0bf3132 RK |
184 | /* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */ |
185 | #define CORE_CLK_SRC_32K 0x0 | |
186 | #define CORE_CLK_SRC_DPLL 0x1 | |
187 | #define CORE_CLK_SRC_DPLL_X2 0x2 | |
188 | ||
189 | /* OMAP2xxx CM_CLKEN_PLL.EN_DPLL bits - for omap2_get_dpll_rate() */ | |
190 | #define OMAP2XXX_EN_DPLL_LPBYPASS 0x1 | |
191 | #define OMAP2XXX_EN_DPLL_FRBYPASS 0x2 | |
192 | #define OMAP2XXX_EN_DPLL_LOCKED 0x3 | |
193 | ||
194 | /* OMAP3xxx CM_CLKEN_PLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */ | |
195 | #define OMAP3XXX_EN_DPLL_LPBYPASS 0x5 | |
196 | #define OMAP3XXX_EN_DPLL_FRBYPASS 0x6 | |
197 | #define OMAP3XXX_EN_DPLL_LOCKED 0x7 | |
198 | ||
16975a79 RN |
199 | /* OMAP4xxx CM_CLKMODE_DPLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */ |
200 | #define OMAP4XXX_EN_DPLL_MNBYPASS 0x4 | |
201 | #define OMAP4XXX_EN_DPLL_LPBYPASS 0x5 | |
202 | #define OMAP4XXX_EN_DPLL_FRBYPASS 0x6 | |
203 | #define OMAP4XXX_EN_DPLL_LOCKED 0x7 | |
204 | ||
32cc0021 MT |
205 | u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk); |
206 | void omap3_dpll_allow_idle(struct clk_hw_omap *clk); | |
207 | void omap3_dpll_deny_idle(struct clk_hw_omap *clk); | |
32cc0021 MT |
208 | int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk); |
209 | void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk); | |
210 | void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk); | |
543d9378 | 211 | |
12706c54 | 212 | void __init omap2_clk_disable_clkdm_control(void); |
435699db PW |
213 | |
214 | /* clkt_clksel.c public functions */ | |
32cc0021 MT |
215 | u32 omap2_clksel_round_rate_div(struct clk_hw_omap *clk, |
216 | unsigned long target_rate, | |
217 | u32 *new_div); | |
218 | u8 omap2_clksel_find_parent_index(struct clk_hw *hw); | |
219 | unsigned long omap2_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate); | |
220 | long omap2_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate, | |
221 | unsigned long *parent_rate); | |
222 | int omap2_clksel_set_rate(struct clk_hw *hw, unsigned long rate, | |
223 | unsigned long parent_rate); | |
224 | int omap2_clksel_set_parent(struct clk_hw *hw, u8 field_val); | |
435699db | 225 | |
530e544f | 226 | /* clkt_iclk.c public functions */ |
b4777a21 RN |
227 | extern void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk); |
228 | extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk); | |
530e544f | 229 | |
32cc0021 | 230 | unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk); |
435699db | 231 | |
32cc0021 MT |
232 | void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk, |
233 | void __iomem **other_reg, | |
234 | u8 *other_bit); | |
235 | void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, | |
236 | void __iomem **idlest_reg, | |
237 | u8 *idlest_bit, u8 *idlest_val); | |
23fb8ba3 | 238 | int omap2_clk_enable_autoidle_all(void); |
818b40e5 TK |
239 | int omap2_clk_allow_idle(struct clk *clk); |
240 | int omap2_clk_deny_idle(struct clk *clk); | |
4d30e82c PW |
241 | int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name); |
242 | void omap2_clk_print_new_rates(const char *hfclkin_ck_name, | |
243 | const char *core_ck_name, | |
244 | const char *mpu_ck_name); | |
543d9378 | 245 | |
3ada6b10 TK |
246 | u32 omap2_clk_readl(struct clk_hw_omap *clk, void __iomem *reg); |
247 | void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg); | |
248 | ||
99541195 | 249 | extern u16 cpu_mask; |
d8a94458 | 250 | |
b36ee724 | 251 | extern const struct clkops clkops_omap2_dflt_wait; |
7c43d547 | 252 | extern const struct clkops clkops_dummy; |
bc51da4e | 253 | extern const struct clkops clkops_omap2_dflt; |
b36ee724 | 254 | |
82e9bd58 PW |
255 | extern struct clk_functions omap2_clk_functions; |
256 | ||
d8a94458 PW |
257 | extern const struct clksel_rate gpt_32k_rates[]; |
258 | extern const struct clksel_rate gpt_sys_rates[]; | |
259 | extern const struct clksel_rate gfx_l3_rates[]; | |
22411396 | 260 | extern const struct clksel_rate dsp_ick_rates[]; |
cb26867e | 261 | extern struct clk dummy_ck; |
543d9378 | 262 | |
32cc0021 MT |
263 | extern const struct clk_hw_omap_ops clkhwops_iclk_wait; |
264 | extern const struct clk_hw_omap_ops clkhwops_wait; | |
b4777a21 | 265 | extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait; |
b4777a21 | 266 | extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait; |
b4777a21 RN |
267 | extern const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait; |
268 | extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait; | |
b4777a21 RN |
269 | extern const struct clk_hw_omap_ops clkhwops_apll54; |
270 | extern const struct clk_hw_omap_ops clkhwops_apll96; | |
657ebfad | 271 | |
571efa0d PW |
272 | /* clksel_rate blocks shared between OMAP44xx and AM33xx */ |
273 | extern const struct clksel_rate div_1_0_rates[]; | |
cb26867e | 274 | extern const struct clksel_rate div3_1to4_rates[]; |
571efa0d PW |
275 | extern const struct clksel_rate div_1_1_rates[]; |
276 | extern const struct clksel_rate div_1_2_rates[]; | |
277 | extern const struct clksel_rate div_1_3_rates[]; | |
278 | extern const struct clksel_rate div_1_4_rates[]; | |
279 | extern const struct clksel_rate div31_1to31_rates[]; | |
280 | ||
3ada6b10 TK |
281 | extern void __iomem *clk_memmaps[]; |
282 | ||
e30384ab VH |
283 | extern int am33xx_clk_init(void); |
284 | ||
32cc0021 MT |
285 | extern int omap2_clkops_enable_clkdm(struct clk_hw *hw); |
286 | extern void omap2_clkops_disable_clkdm(struct clk_hw *hw); | |
32cc0021 | 287 | |
78e52e02 | 288 | extern void omap_clocks_register(struct omap_clk *oclks, int cnt); |
543d9378 | 289 | #endif |