Commit | Line | Data |
---|---|---|
f38b0dd6 TK |
1 | /* |
2 | * OMAP DPLL clock support | |
3 | * | |
4 | * Copyright (C) 2013 Texas Instruments, Inc. | |
5 | * | |
6 | * Tero Kristo <t-kristo@ti.com> | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License version 2 as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | |
13 | * kind, whether express or implied; without even the implied warranty | |
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | */ | |
17 | ||
18 | #include <linux/clk-provider.h> | |
19 | #include <linux/slab.h> | |
20 | #include <linux/err.h> | |
21 | #include <linux/of.h> | |
22 | #include <linux/of_address.h> | |
23 | #include <linux/clk/ti.h> | |
24 | ||
25 | #undef pr_fmt | |
26 | #define pr_fmt(fmt) "%s: " fmt, __func__ | |
27 | ||
28 | #define DPLL_HAS_AUTOIDLE 0x1 | |
29 | ||
30 | #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ | |
31 | defined(CONFIG_SOC_DRA7XX) | |
32 | static const struct clk_ops dpll_m4xen_ck_ops = { | |
33 | .enable = &omap3_noncore_dpll_enable, | |
34 | .disable = &omap3_noncore_dpll_disable, | |
35 | .recalc_rate = &omap4_dpll_regm4xen_recalc, | |
36 | .round_rate = &omap4_dpll_regm4xen_round_rate, | |
37 | .set_rate = &omap3_noncore_dpll_set_rate, | |
38 | .get_parent = &omap2_init_dpll_parent, | |
39 | }; | |
40 | #endif | |
41 | ||
42 | static const struct clk_ops dpll_core_ck_ops = { | |
43 | .recalc_rate = &omap3_dpll_recalc, | |
44 | .get_parent = &omap2_init_dpll_parent, | |
45 | }; | |
46 | ||
47 | #ifdef CONFIG_ARCH_OMAP3 | |
48 | static const struct clk_ops omap3_dpll_core_ck_ops = { | |
49 | .get_parent = &omap2_init_dpll_parent, | |
50 | .recalc_rate = &omap3_dpll_recalc, | |
51 | .round_rate = &omap2_dpll_round_rate, | |
52 | }; | |
53 | #endif | |
54 | ||
55 | static const struct clk_ops dpll_ck_ops = { | |
56 | .enable = &omap3_noncore_dpll_enable, | |
57 | .disable = &omap3_noncore_dpll_disable, | |
58 | .recalc_rate = &omap3_dpll_recalc, | |
59 | .round_rate = &omap2_dpll_round_rate, | |
60 | .set_rate = &omap3_noncore_dpll_set_rate, | |
61 | .get_parent = &omap2_init_dpll_parent, | |
62 | }; | |
63 | ||
64 | static const struct clk_ops dpll_no_gate_ck_ops = { | |
65 | .recalc_rate = &omap3_dpll_recalc, | |
66 | .get_parent = &omap2_init_dpll_parent, | |
67 | .round_rate = &omap2_dpll_round_rate, | |
68 | .set_rate = &omap3_noncore_dpll_set_rate, | |
69 | }; | |
70 | ||
71 | #ifdef CONFIG_ARCH_OMAP3 | |
72 | static const struct clk_ops omap3_dpll_ck_ops = { | |
73 | .enable = &omap3_noncore_dpll_enable, | |
74 | .disable = &omap3_noncore_dpll_disable, | |
75 | .get_parent = &omap2_init_dpll_parent, | |
76 | .recalc_rate = &omap3_dpll_recalc, | |
77 | .set_rate = &omap3_noncore_dpll_set_rate, | |
78 | .round_rate = &omap2_dpll_round_rate, | |
79 | }; | |
80 | ||
81 | static const struct clk_ops omap3_dpll_per_ck_ops = { | |
82 | .enable = &omap3_noncore_dpll_enable, | |
83 | .disable = &omap3_noncore_dpll_disable, | |
84 | .get_parent = &omap2_init_dpll_parent, | |
85 | .recalc_rate = &omap3_dpll_recalc, | |
86 | .set_rate = &omap3_dpll4_set_rate, | |
87 | .round_rate = &omap2_dpll_round_rate, | |
88 | }; | |
89 | #endif | |
90 | ||
91 | static const struct clk_ops dpll_x2_ck_ops = { | |
92 | .recalc_rate = &omap3_clkoutx2_recalc, | |
93 | }; | |
94 | ||
95 | /** | |
96 | * ti_clk_register_dpll - low level registration of a DPLL clock | |
97 | * @hw: hardware clock definition for the clock | |
98 | * @node: device node for the clock | |
99 | * | |
100 | * Finalizes DPLL registration process. In case a failure (clk-ref or | |
101 | * clk-bypass is missing), the clock is added to retry list and | |
102 | * the initialization is retried on later stage. | |
103 | */ | |
104 | static void __init ti_clk_register_dpll(struct clk_hw *hw, | |
105 | struct device_node *node) | |
106 | { | |
107 | struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw); | |
108 | struct dpll_data *dd = clk_hw->dpll_data; | |
109 | struct clk *clk; | |
110 | ||
111 | dd->clk_ref = of_clk_get(node, 0); | |
112 | dd->clk_bypass = of_clk_get(node, 1); | |
113 | ||
114 | if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) { | |
115 | pr_debug("clk-ref or clk-bypass missing for %s, retry later\n", | |
116 | node->name); | |
117 | if (!ti_clk_retry_init(node, hw, ti_clk_register_dpll)) | |
118 | return; | |
119 | ||
120 | goto cleanup; | |
121 | } | |
122 | ||
123 | /* register the clock */ | |
124 | clk = clk_register(NULL, &clk_hw->hw); | |
125 | ||
126 | if (!IS_ERR(clk)) { | |
127 | omap2_init_clk_hw_omap_clocks(clk); | |
128 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | |
129 | kfree(clk_hw->hw.init->parent_names); | |
130 | kfree(clk_hw->hw.init); | |
131 | return; | |
132 | } | |
133 | ||
134 | cleanup: | |
135 | kfree(clk_hw->dpll_data); | |
136 | kfree(clk_hw->hw.init->parent_names); | |
137 | kfree(clk_hw->hw.init); | |
138 | kfree(clk_hw); | |
139 | } | |
140 | ||
141 | #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ | |
142 | defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) | |
143 | /** | |
144 | * ti_clk_register_dpll_x2 - Registers a DPLLx2 clock | |
145 | * @node: device node for this clock | |
146 | * @ops: clk_ops for this clock | |
147 | * @hw_ops: clk_hw_ops for this clock | |
148 | * | |
149 | * Initializes a DPLL x 2 clock from device tree data. | |
150 | */ | |
151 | static void ti_clk_register_dpll_x2(struct device_node *node, | |
152 | const struct clk_ops *ops, | |
153 | const struct clk_hw_omap_ops *hw_ops) | |
154 | { | |
155 | struct clk *clk; | |
156 | struct clk_init_data init = { NULL }; | |
157 | struct clk_hw_omap *clk_hw; | |
158 | const char *name = node->name; | |
159 | const char *parent_name; | |
160 | ||
161 | parent_name = of_clk_get_parent_name(node, 0); | |
162 | if (!parent_name) { | |
163 | pr_err("%s must have parent\n", node->name); | |
164 | return; | |
165 | } | |
166 | ||
167 | clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); | |
168 | if (!clk_hw) | |
169 | return; | |
170 | ||
171 | clk_hw->ops = hw_ops; | |
172 | clk_hw->hw.init = &init; | |
173 | ||
174 | init.name = name; | |
175 | init.ops = ops; | |
176 | init.parent_names = &parent_name; | |
177 | init.num_parents = 1; | |
178 | ||
179 | /* register the clock */ | |
180 | clk = clk_register(NULL, &clk_hw->hw); | |
181 | ||
182 | if (IS_ERR(clk)) { | |
183 | kfree(clk_hw); | |
184 | } else { | |
185 | omap2_init_clk_hw_omap_clocks(clk); | |
186 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | |
187 | } | |
188 | } | |
189 | #endif | |
190 | ||
191 | /** | |
192 | * of_ti_dpll_setup - Setup function for OMAP DPLL clocks | |
193 | * @node: device node containing the DPLL info | |
194 | * @ops: ops for the DPLL | |
195 | * @ddt: DPLL data template to use | |
196 | * @init_flags: flags for controlling init types | |
197 | * | |
198 | * Initializes a DPLL clock from device tree data. | |
199 | */ | |
200 | static void __init of_ti_dpll_setup(struct device_node *node, | |
201 | const struct clk_ops *ops, | |
202 | const struct dpll_data *ddt, | |
203 | u8 init_flags) | |
204 | { | |
205 | struct clk_hw_omap *clk_hw = NULL; | |
206 | struct clk_init_data *init = NULL; | |
207 | const char **parent_names = NULL; | |
208 | struct dpll_data *dd = NULL; | |
209 | int i; | |
210 | u8 dpll_mode = 0; | |
211 | ||
212 | dd = kzalloc(sizeof(*dd), GFP_KERNEL); | |
213 | clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); | |
214 | init = kzalloc(sizeof(*init), GFP_KERNEL); | |
215 | if (!dd || !clk_hw || !init) | |
216 | goto cleanup; | |
217 | ||
218 | memcpy(dd, ddt, sizeof(*dd)); | |
219 | ||
220 | clk_hw->dpll_data = dd; | |
221 | clk_hw->ops = &clkhwops_omap3_dpll; | |
222 | clk_hw->hw.init = init; | |
223 | clk_hw->flags = MEMMAP_ADDRESSING; | |
224 | ||
225 | init->name = node->name; | |
226 | init->ops = ops; | |
227 | ||
228 | init->num_parents = of_clk_get_parent_count(node); | |
229 | if (init->num_parents < 1) { | |
230 | pr_err("%s must have parent(s)\n", node->name); | |
231 | goto cleanup; | |
232 | } | |
233 | ||
234 | parent_names = kzalloc(sizeof(char *) * init->num_parents, GFP_KERNEL); | |
235 | if (!parent_names) | |
236 | goto cleanup; | |
237 | ||
238 | for (i = 0; i < init->num_parents; i++) | |
239 | parent_names[i] = of_clk_get_parent_name(node, i); | |
240 | ||
241 | init->parent_names = parent_names; | |
242 | ||
243 | dd->control_reg = ti_clk_get_reg_addr(node, 0); | |
244 | dd->idlest_reg = ti_clk_get_reg_addr(node, 1); | |
245 | dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2); | |
246 | ||
247 | if (!dd->control_reg || !dd->idlest_reg || !dd->mult_div1_reg) | |
248 | goto cleanup; | |
249 | ||
250 | if (init_flags & DPLL_HAS_AUTOIDLE) { | |
251 | dd->autoidle_reg = ti_clk_get_reg_addr(node, 3); | |
252 | if (!dd->autoidle_reg) | |
253 | goto cleanup; | |
254 | } | |
255 | ||
256 | if (of_property_read_bool(node, "ti,low-power-stop")) | |
257 | dpll_mode |= 1 << DPLL_LOW_POWER_STOP; | |
258 | ||
259 | if (of_property_read_bool(node, "ti,low-power-bypass")) | |
260 | dpll_mode |= 1 << DPLL_LOW_POWER_BYPASS; | |
261 | ||
262 | if (of_property_read_bool(node, "ti,lock")) | |
263 | dpll_mode |= 1 << DPLL_LOCKED; | |
264 | ||
265 | if (dpll_mode) | |
266 | dd->modes = dpll_mode; | |
267 | ||
268 | ti_clk_register_dpll(&clk_hw->hw, node); | |
269 | return; | |
270 | ||
271 | cleanup: | |
272 | kfree(dd); | |
273 | kfree(parent_names); | |
274 | kfree(init); | |
275 | kfree(clk_hw); | |
276 | } | |
277 | ||
278 | #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ | |
279 | defined(CONFIG_SOC_DRA7XX) | |
280 | static void __init of_ti_omap4_dpll_x2_setup(struct device_node *node) | |
281 | { | |
282 | ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, &clkhwops_omap4_dpllmx); | |
283 | } | |
284 | CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock", | |
285 | of_ti_omap4_dpll_x2_setup); | |
286 | #endif | |
287 | ||
288 | #ifdef CONFIG_SOC_AM33XX | |
289 | static void __init of_ti_am3_dpll_x2_setup(struct device_node *node) | |
290 | { | |
291 | ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, NULL); | |
292 | } | |
293 | CLK_OF_DECLARE(ti_am3_dpll_x2_clock, "ti,am3-dpll-x2-clock", | |
294 | of_ti_am3_dpll_x2_setup); | |
295 | #endif | |
296 | ||
297 | #ifdef CONFIG_ARCH_OMAP3 | |
298 | static void __init of_ti_omap3_dpll_setup(struct device_node *node) | |
299 | { | |
300 | const struct dpll_data dd = { | |
301 | .idlest_mask = 0x1, | |
302 | .enable_mask = 0x7, | |
303 | .autoidle_mask = 0x7, | |
304 | .mult_mask = 0x7ff << 8, | |
305 | .div1_mask = 0x7f, | |
306 | .max_multiplier = 2047, | |
307 | .max_divider = 128, | |
308 | .min_divider = 1, | |
309 | .freqsel_mask = 0xf0, | |
310 | .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), | |
311 | }; | |
312 | ||
313 | of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd, DPLL_HAS_AUTOIDLE); | |
314 | } | |
315 | CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock", | |
316 | of_ti_omap3_dpll_setup); | |
317 | ||
318 | static void __init of_ti_omap3_core_dpll_setup(struct device_node *node) | |
319 | { | |
320 | const struct dpll_data dd = { | |
321 | .idlest_mask = 0x1, | |
322 | .enable_mask = 0x7, | |
323 | .autoidle_mask = 0x7, | |
324 | .mult_mask = 0x7ff << 16, | |
325 | .div1_mask = 0x7f << 8, | |
326 | .max_multiplier = 2047, | |
327 | .max_divider = 128, | |
328 | .min_divider = 1, | |
329 | .freqsel_mask = 0xf0, | |
330 | }; | |
331 | ||
332 | of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd, DPLL_HAS_AUTOIDLE); | |
333 | } | |
334 | CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock", | |
335 | of_ti_omap3_core_dpll_setup); | |
336 | ||
337 | static void __init of_ti_omap3_per_dpll_setup(struct device_node *node) | |
338 | { | |
339 | const struct dpll_data dd = { | |
340 | .idlest_mask = 0x1 << 1, | |
341 | .enable_mask = 0x7 << 16, | |
342 | .autoidle_mask = 0x7 << 3, | |
343 | .mult_mask = 0x7ff << 8, | |
344 | .div1_mask = 0x7f, | |
345 | .max_multiplier = 2047, | |
346 | .max_divider = 128, | |
347 | .min_divider = 1, | |
348 | .freqsel_mask = 0xf00000, | |
349 | .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), | |
350 | }; | |
351 | ||
352 | of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd, DPLL_HAS_AUTOIDLE); | |
353 | } | |
354 | CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock", | |
355 | of_ti_omap3_per_dpll_setup); | |
356 | ||
357 | static void __init of_ti_omap3_per_jtype_dpll_setup(struct device_node *node) | |
358 | { | |
359 | const struct dpll_data dd = { | |
360 | .idlest_mask = 0x1 << 1, | |
361 | .enable_mask = 0x7 << 16, | |
362 | .autoidle_mask = 0x7 << 3, | |
363 | .mult_mask = 0xfff << 8, | |
364 | .div1_mask = 0x7f, | |
365 | .max_multiplier = 4095, | |
366 | .max_divider = 128, | |
367 | .min_divider = 1, | |
368 | .sddiv_mask = 0xff << 24, | |
369 | .dco_mask = 0xe << 20, | |
370 | .flags = DPLL_J_TYPE, | |
371 | .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), | |
372 | }; | |
373 | ||
374 | of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd, DPLL_HAS_AUTOIDLE); | |
375 | } | |
376 | CLK_OF_DECLARE(ti_omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock", | |
377 | of_ti_omap3_per_jtype_dpll_setup); | |
378 | #endif | |
379 | ||
380 | static void __init of_ti_omap4_dpll_setup(struct device_node *node) | |
381 | { | |
382 | const struct dpll_data dd = { | |
383 | .idlest_mask = 0x1, | |
384 | .enable_mask = 0x7, | |
385 | .autoidle_mask = 0x7, | |
386 | .mult_mask = 0x7ff << 8, | |
387 | .div1_mask = 0x7f, | |
388 | .max_multiplier = 2047, | |
389 | .max_divider = 128, | |
390 | .min_divider = 1, | |
391 | .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), | |
392 | }; | |
393 | ||
394 | of_ti_dpll_setup(node, &dpll_ck_ops, &dd, DPLL_HAS_AUTOIDLE); | |
395 | } | |
396 | CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock", | |
397 | of_ti_omap4_dpll_setup); | |
398 | ||
399 | static void __init of_ti_omap4_core_dpll_setup(struct device_node *node) | |
400 | { | |
401 | const struct dpll_data dd = { | |
402 | .idlest_mask = 0x1, | |
403 | .enable_mask = 0x7, | |
404 | .autoidle_mask = 0x7, | |
405 | .mult_mask = 0x7ff << 8, | |
406 | .div1_mask = 0x7f, | |
407 | .max_multiplier = 2047, | |
408 | .max_divider = 128, | |
409 | .min_divider = 1, | |
410 | .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), | |
411 | }; | |
412 | ||
413 | of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd, DPLL_HAS_AUTOIDLE); | |
414 | } | |
415 | CLK_OF_DECLARE(ti_omap4_core_dpll_clock, "ti,omap4-dpll-core-clock", | |
416 | of_ti_omap4_core_dpll_setup); | |
417 | ||
418 | #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ | |
419 | defined(CONFIG_SOC_DRA7XX) | |
420 | static void __init of_ti_omap4_m4xen_dpll_setup(struct device_node *node) | |
421 | { | |
422 | const struct dpll_data dd = { | |
423 | .idlest_mask = 0x1, | |
424 | .enable_mask = 0x7, | |
425 | .autoidle_mask = 0x7, | |
426 | .mult_mask = 0x7ff << 8, | |
427 | .div1_mask = 0x7f, | |
428 | .max_multiplier = 2047, | |
429 | .max_divider = 128, | |
430 | .min_divider = 1, | |
431 | .m4xen_mask = 0x800, | |
432 | .lpmode_mask = 1 << 10, | |
433 | .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), | |
434 | }; | |
435 | ||
436 | of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd, DPLL_HAS_AUTOIDLE); | |
437 | } | |
438 | CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock", | |
439 | of_ti_omap4_m4xen_dpll_setup); | |
440 | ||
441 | static void __init of_ti_omap4_jtype_dpll_setup(struct device_node *node) | |
442 | { | |
443 | const struct dpll_data dd = { | |
444 | .idlest_mask = 0x1, | |
445 | .enable_mask = 0x7, | |
446 | .autoidle_mask = 0x7, | |
447 | .mult_mask = 0xfff << 8, | |
448 | .div1_mask = 0xff, | |
449 | .max_multiplier = 4095, | |
450 | .max_divider = 256, | |
451 | .min_divider = 1, | |
452 | .sddiv_mask = 0xff << 24, | |
453 | .flags = DPLL_J_TYPE, | |
454 | .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), | |
455 | }; | |
456 | ||
457 | of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd, DPLL_HAS_AUTOIDLE); | |
458 | } | |
459 | CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock", | |
460 | of_ti_omap4_jtype_dpll_setup); | |
461 | #endif | |
462 | ||
463 | static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node) | |
464 | { | |
465 | const struct dpll_data dd = { | |
466 | .idlest_mask = 0x1, | |
467 | .enable_mask = 0x7, | |
468 | .autoidle_mask = 0x7, | |
469 | .mult_mask = 0x7ff << 8, | |
470 | .div1_mask = 0x7f, | |
471 | .max_multiplier = 2047, | |
472 | .max_divider = 128, | |
473 | .min_divider = 1, | |
474 | .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), | |
475 | }; | |
476 | ||
477 | of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd, 0); | |
478 | } | |
479 | CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock", | |
480 | of_ti_am3_no_gate_dpll_setup); | |
481 | ||
482 | static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node) | |
483 | { | |
484 | const struct dpll_data dd = { | |
485 | .idlest_mask = 0x1, | |
486 | .enable_mask = 0x7, | |
487 | .autoidle_mask = 0x7, | |
488 | .mult_mask = 0x7ff << 8, | |
489 | .div1_mask = 0x7f, | |
490 | .max_multiplier = 4095, | |
491 | .max_divider = 256, | |
492 | .min_divider = 2, | |
493 | .flags = DPLL_J_TYPE, | |
494 | .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), | |
495 | }; | |
496 | ||
497 | of_ti_dpll_setup(node, &dpll_ck_ops, &dd, 0); | |
498 | } | |
499 | CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock", | |
500 | of_ti_am3_jtype_dpll_setup); | |
501 | ||
502 | static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node) | |
503 | { | |
504 | const struct dpll_data dd = { | |
505 | .idlest_mask = 0x1, | |
506 | .enable_mask = 0x7, | |
507 | .autoidle_mask = 0x7, | |
508 | .mult_mask = 0x7ff << 8, | |
509 | .div1_mask = 0x7f, | |
510 | .max_multiplier = 2047, | |
511 | .max_divider = 128, | |
512 | .min_divider = 1, | |
513 | .flags = DPLL_J_TYPE, | |
514 | .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), | |
515 | }; | |
516 | ||
517 | of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd, 0); | |
518 | } | |
519 | CLK_OF_DECLARE(ti_am3_no_gate_jtype_dpll_clock, | |
520 | "ti,am3-dpll-no-gate-j-type-clock", | |
521 | of_ti_am3_no_gate_jtype_dpll_setup); | |
522 | ||
523 | static void __init of_ti_am3_dpll_setup(struct device_node *node) | |
524 | { | |
525 | const struct dpll_data dd = { | |
526 | .idlest_mask = 0x1, | |
527 | .enable_mask = 0x7, | |
528 | .autoidle_mask = 0x7, | |
529 | .mult_mask = 0x7ff << 8, | |
530 | .div1_mask = 0x7f, | |
531 | .max_multiplier = 2047, | |
532 | .max_divider = 128, | |
533 | .min_divider = 1, | |
534 | .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), | |
535 | }; | |
536 | ||
537 | of_ti_dpll_setup(node, &dpll_ck_ops, &dd, 0); | |
538 | } | |
539 | CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup); | |
540 | ||
541 | static void __init of_ti_am3_core_dpll_setup(struct device_node *node) | |
542 | { | |
543 | const struct dpll_data dd = { | |
544 | .idlest_mask = 0x1, | |
545 | .enable_mask = 0x7, | |
546 | .autoidle_mask = 0x7, | |
547 | .mult_mask = 0x7ff << 8, | |
548 | .div1_mask = 0x7f, | |
549 | .max_multiplier = 2047, | |
550 | .max_divider = 128, | |
551 | .min_divider = 1, | |
552 | .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), | |
553 | }; | |
554 | ||
555 | of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd, 0); | |
556 | } | |
557 | CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock", | |
558 | of_ti_am3_core_dpll_setup); |