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